Useful commands

Here we list some useful methods that can be applied to a CQCConnection object or a qubit object below.

CQCConnection

The CQCConnection is initialized with the name of the node (string) as an argument, an optional application ID (int) (if multiple Connections connect to a single node), and an optional pend_messages (bool) flag for when sending commands in sequence. Additionally one can specify the socket address to the corresponding CQC server. If the socket address is not explicitely specified, this is taken from the cqc config-file (default config/cqcNodes.cfg)

  • sendQubit(): Sends the qubit q (qubit) to the node name (string).

  • recvQubit() Receives a qubit that has been sent to this node.

  • createEPR() Creates an EPR-pair \(\frac{1}{\sqrt{2}}(|00\rangle+|11\rangle)\) with the node name (string).

  • recvEPR() Receives qubit from an EPR-pair created with another node (that called createEPR()).

  • sendClassical() Sends a classical message msg (int in range(0,256) or list of such int s) to the node name (string). Opens a socket connection if not already opened.

  • recvClassical() Receives a classical message sent by another node by sendClassical().

qubit

Here are some useful commands that can be applied to a qubit object. A CQCConnection as input and will be in the state \(|0\rangle\).

  • X(), Y(), Z(), H(), K(), T() Single-qubit gates.

  • rot_X(), rot_Y(), rot_Z() Single-qubit rotations with the angle \(\left(\mathrm{step}\cdot\frac{2\pi}{256}\right)\).

  • cnot(), cphase() Two-qubit gates with q (qubit) as target.

  • measure() Measures the qubit and returns outcome. If inplace (bool) then the post-measurement state is kept afterwards, otherwise the qubit is removed (default).

Factory and Sequences

When the pend_messages flag is set to True in the CQCConnection, ALL commands (on both qubit and CQCConnection) that you create are stored in a list, to be send all at once when flushed for a CQCConnection.

  • set_pending() Set the pend_messages flag to True/False

  • flush() Send all pending messages to the backend at once. If do_sequence == True then it will send CMDSequenceHeaders between the commands, if it is False it will add the ACTION flag to the commands instead.

    Return list. Returns a list with measurement outcomes (int ‘s) and qubit depending if MEASURE and/or NEW commands were used in the sequence.

  • flush_factory() Send all pending messages to the backend at once as a factory, doing the sequence num_iter (int) times. If do_sequence == True then it will send CMDSequenceHeaders between the commands, if it is False it will add the ACTION flag to the commands instead.

    Return list. Returns a list with measurement outcomes (int ‘s) and qubit depending if MEASURE and/or NEW commands were used in the sequence.

Conditional logic

One can of course have conditional logic in the python library and send messages depending on this logic. However this can become inefficient when many messages have to be sent back and fourth between the application and the backend. For this reason, CQC also supports conditional logic natively. For examople:

  • To apply instructions a certain number of times you can now do:

    from cqc.pythonLib import CQCConnection, qubit, CQCMix
    
    with CQCConnection('Alice') as node:
    
       # qubit is created beforehand
       qbit = qubit(node)
    
       # Start of the CQCMix
       with CQCMix(node) as pgrm:
          qbit.X()
    
          # Start of the Factory
          # Apply H three times
          with pgrm.loop(times=3):
            qbit.H()
    
          # Y gate which is not part of
          # the loop (i.e. Factory) above
          qbit.Y()
    
  • Or to perform certain instructions based on a measurement outcome you can do:

    from cqc.pythonLib import CQCConnection, qubit, CQCMix
    
    with CQCConnection('Alice') as node:
    
       # qubits are created beforehand
       qbit1 = qubit(node)
       qbit2 = qubit(node)
    
       # Start of the CQCMix
       with CQCMix(node) as pgrm:
    
          result = qbit1.measure()
    
          # if measurement yielded 1, apply X
          with pgrm.cqc_if(result == 1):
             qbit2.X()
    
          # else, apply H
          with pgrm.cqc_else():
             qbit2.H()