SDK objects

Described below are the user-exposed components of the NetQASM SDK.

Note that BaseNetQASMConnection and Socket are abstract base-classes. These are implemented specifically for a runtime, e.g. a simulator or hardware runtime. However, when using the SDK this is handled automatically if these are imported from netqasm.sdk.external. For example one might write an application as follows

from netqasm.sdk.external import NetQASMConnection, Socket

# Setup a classical socket
bob_socket = Socket("alice", "bob")

with NetQASMConnection('alice'):
   # Main application...

The classes NetQASMConnection and Socket will be different subclasses of the abstract classes, depending on which runtime is used. If for example the application is simulated using `SquidASM`_ and NetSquid, then the NetQASMConnection will in fact be the class squidasm.sdk.NetSquidConnection. These different classes expose the same set of functionalities. They only differ in the way they communicate with the underlying simulator. For more details see Running your first app.

NetQASM connection

Interface to quantum node controllers.

This module provides the BaseNetQASMConnection class which represents the connection with a quantum node controller.

class netqasm.sdk.connection.BaseNetQASMConnection(app_name, node_name=None, app_id=None, max_qubits=5, hardware_config=None, log_config=None, epr_sockets=None, compiler=None, return_arrays=True, _init_app=True, _setup_epr_sockets=True)

Base class for representing connections to a quantum node controller.

A BaseNetQASMConnection instance provides an interface for Host programs to interact with a quantum node controller like QNodeOS, which controls the quantum hardware.

The interaction with the quantum node controller includes registering applications, opening EPR sockets, sending NetQASM subroutines, and getting execution results,

A BaseNetQASMConnection instance also provides a ‘context’ for the Host to run its code in. Code within this context is compiled into NetQASM subroutines and then sent to the quantum node controller.

Parameters
  • app_name (str) –

  • node_name (Optional[str]) –

  • app_id (Optional[int]) –

  • max_qubits (int) –

  • hardware_config (Optional[HardwareConfig]) –

  • log_config (Optional[LogConfig]) –

  • epr_sockets (Optional[List[esck.EPRSocket]]) –

  • compiler (Optional[Type[SubroutineTranspiler]]) –

  • return_arrays (bool) –

  • _init_app (bool) –

  • _setup_epr_sockets (bool) –

__init__(app_name, node_name=None, app_id=None, max_qubits=5, hardware_config=None, log_config=None, epr_sockets=None, compiler=None, return_arrays=True, _init_app=True, _setup_epr_sockets=True)

BaseNetQASMConnection constructor.

In most cases, you will want to instantiate a subclass of this.

Parameters
  • app_name (str) – Name of the application. Specifically, this is the name of the program that runs on this particular node. So, app_name can often be seen as the name of the “role” within the multi-party application or protocol. For example, in a Blind Computation protocol, the two roles may be “client” and “server”; the app_name of a particular BaseNetQASMConnection instance may then e.g. be “client”.

  • node_name (Optional[str]) – name of the Node that is controlled by the quantum node controller that we connect to. The Node name may be different from the app_name, and e.g. reflect its geographical location, like a city name. If None, the Node name is obtained by querying the global NetworkInfo by using the app_name.

  • app_id (Optional[int]) – ID of this application. An application registered in the quantum node controller using this connection will use this app ID. If None, a unique ID will be chosen (unique among possible other applications that were registered through other BaseNetQASMConnection instances).

  • max_qubits (int) – maximum number of qubits that can be in use at the same time by applications registered through this connection. Defaults to 5.

  • hardware_config (Optional[HardwareConfig]) – configuration object with info about the underlying hardware. Used by the Builder of this Connection. When None, a generic configuration object is created with the default qubit count of 5.

  • log_config (Optional[LogConfig]) – configuration object specifying what to log.

  • epr_sockets (Optional[List[esck.EPRSocket]]) – list of EPR sockets. If _setup_epr_sockets is True, these EPR sockets are automatically opened upon entering this connection’s context.

  • compiler (Optional[Type[SubroutineTranspiler]]) – the class that is used to instantiate the compiler. If None, a compiler is used that can compile for the hardware of the node this connection is to.

  • return_arrays (bool) – whether to add “return array”-instructions at the end of subroutines. A reason to set this to False could be that a quantum node controller does not support returning arrays back to the Host.

  • _init_app (bool) – whether to immediately send a “register application” message to the quantum node controller upon construction of this connection.

  • _setup_epr_sockets (bool) – whether to immediately send “open EPR socket” messages to the quantum node controller upon construction of this connection. If True, the “open EPR socket” messages are for the EPR sockets defined in the epr_sockets parameter.

property app_name

Get the application name

Return type

str

property node_name

Get the node name

Return type

str

property app_id

Get the application ID

Return type

int

property network_info
Return type

Type[NetworkInfo]

property builder
Return type

Builder

classmethod get_app_ids()
Return type

Dict[str, List[int]]

classmethod get_app_names()
Return type

Dict[str, Dict[int, str]]

__enter__()

Start a context with this connection.

Quantum operations specified within the connection are automatically compiled into NetQASM subroutines. These subroutines are sent to the quantum node controller, over this connection, when either flush() is called or the connection goes out of context which calls __exit__().

# Open the connection
with NetQASMConnection(app_name="alice") as alice:
    # Create a qubit
    q = Qubit(alice)
    # Perform a Hadamard
    q.H()
    # Measure the qubit
    m = q.measure()
    # Flush the subroutine to populate the variable `m` with the outcome
    # Alternatively, this can be done by letting the connection
    # go out of context and move the print to after.
    alice.flush()
    print(m)
__exit__(exc_type, exc_val, exc_tb)

Called automatically when a connection context ends.

Default behavior is to call the close method on the connection.

clear()
Return type

None

close(clear_app=True, stop_backend=False, exception=False)

Close a connection.

By default, this method is automatically called when a connection context ends.

Parameters
  • clear_app (bool) –

  • stop_backend (bool) –

  • exception (bool) –

Return type

None

property shared_memory

Get this connection’s Shared Memory object.

This property should not be accessed before any potential setting-up of shared memories has finished. If it cannot be found, an error is raised.

Return type

SharedMemory

property active_qubits

Get a list of qubits that are currently in use.

“In use” means that the virtual qubit represented by this Qubit instance has been allocated and hence its virtual ID cannot be re-used.

Return type

List[Qubit]

Returns

list of active qubits

flush(block=True, callback=None)

Compile and send all pending operations to the quantum node controller.

All operations that have been added to this connection’s Builder (typically by issuing these operations within a connection context) are collected and compiled into a NetQASM subroutine. This subroutine is then sent over the connection to be executed by the quantum node controller.

Parameters
  • block (bool) – block on receiving the result of executing the compiled subroutine from the quantum node controller.

  • callback (Optional[Callable]) – if block is False, this callback is called when the quantum node controller sends the subroutine results.

Return type

None

compile()

Compile the previous SDK commands into a NetQASM subroutine.

This does this the same as calling flush(), except it does not send the subroutine to the quantum node controller for execution. This method can hence be used to pre-compile a subroutine and send it later, possibly after filling in concrete values for templates.

Return type

Optional[Subroutine]

commit_protosubroutine(protosubroutine, block=True, callback=None)

Send a protosubroutine to the quantum node controller.

Takes a ProtoSubroutine, i.e. an intermediate representation of the subroutine that comes from the Builder. The ProtoSubroutine is compiled into a Subroutine instance.

Parameters
  • protosubroutine (ProtoSubroutine) –

  • block (bool) –

  • callback (Optional[Callable]) –

Return type

None

commit_subroutine(subroutine, block=True, callback=None)
Parameters
  • subroutine (Subroutine) –

  • block (bool) –

  • callback (Optional[Callable]) –

Return type

None

block()

Block until a flushed subroutines finishes.

This should be implemented by subclasses.

:raises NotImplementedError

Return type

None

new_array(length=1, init_values=None)

Allocate a new array in the shared memory.

This operation is handled by the connection’s Builder. The Builder make sures the relevant NetQASM instructions end up in the subroutine.

Parameters
  • length (int) – length of the array, defaults to 1

  • init_values (Optional[List[Optional[int]]]) – list of initial values of the array. If not None, must have the same length as length.

Return type

Array

Returns

a handle to the array that can be used in application code

loop(stop, start=0, step=1, loop_register=None)

Create a context for code that gets looped.

Each iteration of the loop is associated with an index, which starts at 0 by default. Each iteration the index is increased by step (default 1). Looping stops when the index reaches stop.

Code inside the context must be compilable to NetQASM, that is, it should only contain quantum operations and/or classical values that are are stored in shared memory (arrays and registers). No classical communication is allowed.

This operation is handled by the connection’s Builder. The Builder make sures the NetQASM subroutine contains a loop around the (compiled) code that is inside the context.

Example:

with NetQASMConnection(app_name="alice") as alice:
    outcomes = alice.new_array(10)
    with alice.loop(10) as i:
        q = Qubit(alice)
        q.H()
        outcome = outcomes.get_future_index(i)
        q.measure(outcome)
Parameters
  • stop (int) – end of iteration range (exluding)

  • start (int) – start of iteration range (including), defaults to 0

  • step (int) – step size of iteration range, defaults to 1

  • loop_register (Optional[Register]) – specific register to be used for holding the loop index. In most cases there is no need to explicitly specify this.

Return type

AbstractContextManager[Register]

Returns

the context object (to be used in a with … expression)

loop_body(body, stop, start=0, step=1, loop_register=None)

Loop code that is defined in a Python function (body).

The function to loop should have a single argument with that has the BaseNetQASMConnection type.

Parameters
  • body (Callable[[ForwardRef, RegFuture], None]) – function to loop

  • stop (int) – end of iteration range (exluding)

  • start (int) – start of iteration range (including), defaults to 0

  • step (int) – step size of iteration range, defaults to 1

  • loop_register (Union[Register, str, None]) – specific register to be used for holding the loop index.

Return type

None

loop_until(max_iterations)

Create a context with code to be looped until the exit condition is met, or the maximum number of tries has been reached.

The code inside the context is automatically looped (re-run). At the end of each iteration, the exit_condition of the context object is checked. If the condition holds, the loop exits. Otherwise the loop does another iteration. If max_iterations iterations have been reached, the loop exits anyway.

Make sure you set the loop_condition on the context object, like e.g.


with connection.loop_until(max_iterations=10) as loop:

q = Qubit(conn) m = q.measure() constraint = ValueAtMostConstraint(m, 0) loop.set_exit_condition(constraint)

Parameters

max_iterations (int) – the maximum number of times to loop

Return type

AbstractContextManager[SdkLoopUntilContext]

if_eq(a, b, body)

Execute a function if a == b.

Code inside the callback function must be compilable to NetQASM, that is, it should only contain quantum operations and/or classical values that are are stored in shared memory (arrays and registers). No classical communication is allowed.

Parameters
  • a (Union[int, ForwardRef, ForwardRef]) – a classical value

  • b (Union[int, ForwardRef, ForwardRef]) – a classical value

  • body (Callable[[ForwardRef], None]) – function to execute if condition is true

Return type

None

if_ne(a, b, body)

Execute a function if a != b.

Code inside the callback function must be compilable to NetQASM, that is, it should only contain quantum operations and/or classical values that are are stored in shared memory (arrays and registers). No classical communication is allowed.

Parameters
  • a (Union[int, ForwardRef, ForwardRef]) – a classical value

  • b (Union[int, ForwardRef, ForwardRef]) – a classical value

  • body (Callable[[ForwardRef], None]) – function to execute if condition is true

Return type

None

if_lt(a, b, body)

Execute a function if a < b.

Code inside the callback function must be compilable to NetQASM, that is, it should only contain quantum operations and/or classical values that are are stored in shared memory (arrays and registers). No classical communication is allowed.

Parameters
  • a (Union[int, ForwardRef, ForwardRef]) – a classical value

  • b (Union[int, ForwardRef, ForwardRef]) – a classical value

  • body (Callable[[ForwardRef], None]) – function to execute if condition is true

Return type

None

if_ge(a, b, body)

Execute a function if a > b.

Code inside the callback function must be compilable to NetQASM, that is, it should only contain quantum operations and/or classical values that are are stored in shared memory (arrays and registers). No classical communication is allowed.

Parameters
  • a (Union[int, ForwardRef, ForwardRef]) – a classical value

  • b (Union[int, ForwardRef, ForwardRef]) – a classical value

  • body (Callable[[ForwardRef], None]) – function to execute if condition is true

Return type

None

if_ez(a, body)

Execute a function if a == 0.

Code inside the callback function must be compilable to NetQASM, that is, it should only contain quantum operations and/or classical values that are are stored in shared memory (arrays and registers). No classical communication is allowed.

Parameters
  • a (Union[int, ForwardRef, ForwardRef]) – a classical value

  • body (Callable[[ForwardRef], None]) – function to execute if condition is true

Return type

None

if_nz(a, body)

Execute a function if a != 0.

Code inside the callback function must be compilable to NetQASM, that is, it should only contain quantum operations and/or classical values that are are stored in shared memory (arrays and registers). No classical communication is allowed.

Parameters
  • a (Union[int, ForwardRef, ForwardRef]) – a classical value

  • body (Callable[[ForwardRef], None]) – function to execute if condition is true

Return type

None

try_until_success(max_tries=1)

TODO docstring

Parameters

max_tries (int) –

Return type

AbstractContextManager[None]

tomography(preparation, iterations, progress=True)

Does a tomography on the output from the preparation specified. The frequencies from X, Y and Z measurements are returned as a tuple (f_X,f_Y,f_Z).

  • Arguments

    preparation

    A function that takes a NetQASMConnection as input and prepares a qubit and returns this

    iterations

    Number of measurements in each basis.

    progress_bar

    Displays a progress bar

Parameters
Return type

Dict[str, float]

test_preparation(preparation, exp_values, conf=2, iterations=100, progress=True)

Test the preparation of a qubit. Returns True if the expected values are inside the confidence interval produced from the data received from the tomography function

  • Arguments

    preparation

    A function that takes a NetQASMConnection as input and prepares a qubit and returns this

    exp_values

    The expected values for measurements in the X, Y and Z basis.

    conf

    Determines the confidence region (+/- conf/sqrt(iterations) )

    iterations

    Number of measurements in each basis.

    progress_bar

    Displays a progress bar

Parameters
  • preparation (Callable[[BaseNetQASMConnection], Qubit]) –

  • exp_values (Tuple[float, float, float]) –

  • conf (float) –

  • iterations (int) –

  • progress (bool) –

Return type

bool

insert_breakpoint(action, role=<BreakpointRole.CREATE: 0>)
Parameters
Return type

None

Qubit

Qubit representation.

This module contains the Qubit class, which are used by application scripts as handles to in-memory qubits.

class netqasm.sdk.qubit.Qubit(conn, add_new_command=True, ent_info=None, virtual_address=None)

Representation of a qubit that has been allocated in the quantum node.

A Qubit instance represents a quantum state that is stored in a physical qubit somewhere in the quantum node. The particular qubit is identified by its virtual qubit ID. To which physical qubit ID this is mapped (at a given time), is handled completely by the quantum node controller and is not known to the Qubit itself.

A Qubit object can be instantiated in an application script. Such an instantiation is automatically compiled into NetQASM instructions that allocate and initialize a new qubit in the quantum node controller.

A Qubit object may also be obtained by SDK functions that return them, like the create() method on an EPRSocket, which returns the object as a handle to the qubit that is now entangled with one in another node.

Qubit operations like applying gates and measuring them are done by calling methods on a Qubit instance.

Parameters
  • conn (sdkconn.BaseNetQASMConnection) –

  • add_new_command (bool) –

  • ent_info (Optional[qlink_compat.LinkLayerOKTypeK]) –

  • virtual_address (Optional[int]) –

__init__(conn, add_new_command=True, ent_info=None, virtual_address=None)

Qubit constructor. This is the standard way to allocate a new qubit in an application.

Parameters
  • conn (sdkconn.BaseNetQASMConnection) – connection of the application in which to allocate the qubit

  • add_new_command (bool) – whether to automatically add NetQASM instructions to the current subroutine to allocate and initialize the qubit

  • ent_info (Optional[qlink_compat.LinkLayerOKTypeK]) – entanglement generation information in case this qubit is the result of an entanglement generation request

  • virtual_address (Optional[int]) – explicit virtual ID to use for this qubit. If None, a free ID is automatically chosen.

property connection

Get the NetQASM connection of this qubit

Return type

sdkconn.BaseNetQASMConnection

property builder

Get the Builder of this qubit’s connection

Return type

Builder

property qubit_id

Get the qubit ID

Return type

int

property active
Return type

bool

property entanglement_info

Get information about the successful link layer request that resulted in this qubit.

Return type

Optional[qlink_compat.LinkLayerOKTypeK]

property remote_entangled_node

Get the name of the remote node the qubit is entangled with.

If not entanled, None is returned.

Return type

Optional[str]

assert_active()

Assert that the qubit is active, i.e. allocated.

Return type

None

measure(future=None, inplace=False, store_array=True, basis=<QubitMeasureBasis.Z: 2>, basis_rotations=None)

Measure the qubit in the standard basis and get the measurement outcome.

Parameters
  • future (Union[Future, RegFuture, None]) – the Future to place the outcome in. If None, a Future is created automatically.

  • inplace (bool) – If False, the measurement is destructive and the qubit is removed from memory. If True, the qubit is left in the post-measurement state.

  • store_array (bool) – whether to store the outcome in an array. If not, it is placed in a register. Only used if future is None.

  • basis (QubitMeasureBasis) – in which of the Pauli bases (X, Y or Z) to measure. Default is Z. Ignored if basis_rotations is not None.

  • basis_rotations (Optional[Tuple[int, int, int]]) – rotations to apply before measuring in the Z-basis. This can be used to specify arbitrary measurement bases. The 3 values are interpreted as 3 rotation angles, for an X- Y-, and another X-rotation, respectively. Each angle is interpreted as a multiple of pi/16. For example, if basis_rotations is (8, 0, 0), an X-rotation is applied with angle 8*pi/16 = pi/2 radians, followed by a Y-rotation of angle 0 and an X-rotation of angle 0. Finally, the measurement is done in the Z-basis.

Return type

Union[Future, RegFuture]

Returns

the Future representing the measurement outcome. It is a Future if

the result is in an array (default) or RegFuture if the result is in a register.

X()

Apply an X gate on the qubit.

Return type

None

Y()

Apply a Y gate on the qubit.

Return type

None

Z()

Apply a Z gate on the qubit.

Return type

None

T()

Apply a T gate on the qubit.

A T gate is a Z-rotation with angle pi/4.

Return type

None

H()

Apply a Hadamard gate on the qubit.

Return type

None

K()

Apply a K gate on the qubit.

A K gate moves the |0> state to +|i> (positive Y) and vice versa.

Return type

None

S()

Apply an S gate on the qubit.

An S gate is a Z-rotation with angle pi/2.

Return type

None

rot_X(n=0, d=0, angle=None)

Do a rotation around the X-axis of the specified angle.

The angle is interpreted as ǹ * pi / 2 ^d` radians. For example, (n, d) = (1, 2) represents an angle of pi/4 radians. If angle is specified, n and d are ignored and this instruction is automatically converted into a sequence of (n, d) rotations such that the discrete (n, d) values approximate the original angle.

Parameters
  • n (Union[int, Template]) – numerator of discrete angle specification. Can be a Template, in which case the subroutine containing this command should first be instantiated before flushing.

  • d (int) – denomerator of discrete angle specification

  • angle (Optional[float]) – exact floating-point angle, defaults to None

rot_Y(n=0, d=0, angle=None)

Do a rotation around the Y-axis of the specified angle.

The angle is interpreted as ǹ * pi / 2 ^d` radians. For example, (n, d) = (1, 2) represents an angle of pi/4 radians. If angle is specified, n and d are ignored and this instruction is automatically converted into a sequence of (n, d) rotations such that the discrete (n, d) values approximate the original angle.

Parameters
  • n (Union[int, Template]) – numerator of discrete angle specification. Can be a Template, in which case the subroutine containing this command should first be instantiated before flushing.

  • d (int) – denomerator of discrete angle specification

  • angle (Optional[float]) – exact floating-point angle, defaults to None

rot_Z(n=0, d=0, angle=None)

Do a rotation around the Z-axis of the specified angle.

The angle is interpreted as ǹ * pi / 2 ^d` radians. For example, (n, d) = (1, 2) represents an angle of pi/4 radians. If angle is specified, n and d are ignored and this instruction is automatically converted into a sequence of (n, d) rotations such that the discrete (n, d) values approximate the original angle.

Parameters
  • n (Union[int, Template]) – numerator of discrete angle specification. Can be a Template, in which case the subroutine containing this command should first be instantiated before flushing.

  • d (int) – denomerator of discrete angle specification

  • angle (Optional[float]) – exact floating-point angle, defaults to None

cnot(target)

Apply a CNOT gate between this qubit (control) and a target qubit.

Parameters

target (Qubit) – target qubit. Should have the same connection as this qubit.

Return type

None

cphase(target)

Apply a CPHASE (CZ) gate between this qubit (control) and a target qubit.

Parameters

target (Qubit) – target qubit. Should have the same connection as this qubit.

Return type

None

reset()

Reset the qubit to the state |0>.

Return type

None

free()

Free the qubit and its virtual ID.

After freeing, the underlying physical qubit can be used to store another state.

Return type

None

EPR socket

EPR Socket interface.

class netqasm.sdk.epr_socket.EPRSocket(remote_app_name, epr_socket_id=0, remote_epr_socket_id=0, min_fidelity=100)

EPR socket class. Used to generate entanglement with a remote node.

An EPR socket represents a connection with a single remote node through which EPR pairs can be generated. Its main interfaces are the create and recv methods. A typical use case for two nodes is that they both create an EPR socket to the other node, and during the protocol, one of the nodes does create operations on its socket while the other node does recv operations.

A create operation asks the network stack to initiate generation of EPR pairs with the remote node. Depending on the type of generation, the result of this operation can be qubit objects or measurement outcomes. A recv operation asks the network stack to wait for the remote node to initiate generation of EPR pairs. Again, the result can be qubit objects or measurement outcomes.

Each create operation on one node must be matched by a recv operation on the other node. Since “creating” and “receiving” must happen at the same time, a node that is doing a create operation on its socket cannot advance until the other node does the corresponding recv. This is different from classical network sockets where a “send” operation (roughly anologous to create in an EPR socket) does not block on the remote node receiving it.

An EPR socket is identified by a triple consisting of (1) the remote node ID, (2) the local socket ID and (3) the remote socket ID. Two nodes that want to generate EPR pairs with each other should make sure that the IDs in their local sockets match.

Parameters
  • remote_app_name (str) –

  • epr_socket_id (int) –

  • remote_epr_socket_id (int) –

  • min_fidelity () –

__init__(remote_app_name, epr_socket_id=0, remote_epr_socket_id=0, min_fidelity=100)

Create an EPR socket. It still needs to be registered with the network stack separately.

Registering and opening the EPR socket is currently done automatically by the connection that uses this EPR socket, specifically when a context is opened with that connection.

Parameters
  • remote_app_name (str) – name of the remote party (i.e. the role, like “client”, not necessarily the node name like “delft”)

  • epr_socket_id (int) – local socket ID, defaults to 0

  • remote_epr_socket_id (int) – remote socket ID, defaults to 0. Note that this must match with the local socket ID of the remote node’s EPR socket.

  • min_fidelity (int) – minimum desired fidelity for EPR pairs generated over this socket, in percentages (i.e. range 0-100). Defaults to 100.

property conn

Get the underlying NetQASMConnection

Return type

connection.BaseNetQASMConnection

property remote_app_name

Get the remote application name

Return type

str

property remote_node_id

Get the remote node ID

Return type

int

property epr_socket_id

Get the EPR socket ID

Return type

int

property remote_epr_socket_id

Get the remote EPR socket ID

Return type

int

property min_fidelity

Get the desired minimum fidelity

Return type

int

create_keep(number=1, post_routine=None, sequential=False, time_unit=<TimeUnit.MICRO_SECONDS: 0>, max_time=0, min_fidelity_all_at_end=None, max_tries=None)

Ask the network stack to generate EPR pairs with the remote node and keep them in memory.

A create_keep operation must always be matched by a recv_keep operation on the remote node.

If sequential is False (default), this operation returns a list of Qubit objects representing the local qubits that are each one half of the generated pairs. These qubits can then be manipulated locally just like locally initialized qubits, by e.g. applying gates or measuring them. Each qubit also contains information about the entanglement generation that lead to its creation, and can be accessed by its entanglement_info property.

A typical example for just generating one pair with another node would be:

q = epr_socket.create_keep()[0]
# `q` can now be used as a normal qubit

If sequential is False (default), the all requested EPR pairs are generated at once, before returning the results (qubits or entanglement info objects).

If sequential is True, a callback function (post_routine) should be specified. After generating one EPR pair, this callback will be called, before generating the next pair. This method can e.g. be used to generate many EPR pairs (more than the number of physical qubits available), by measuring (and freeing up) each qubit before the next pair is generated.

For example:

outcomes = alice.new_array(num)

def post_create(conn, q, pair):
    q.H()
    outcome = outcomes.get_future_index(pair)
    q.measure(outcome)
epr_socket.create_keep(number=num, post_routine=post_create, sequential=True)
Parameters
  • number (int) – number of EPR pairs to generate, defaults to 1

  • post_routine (Optional[Callable]) – callback function for each genated pair. Only used if sequential is True. The callback should take three arguments (conn, q, pair) where * conn is the connection (e.g. self) * q is the entangled qubit (of type FutureQubit) * pair is a register holding which pair is handled (0, 1, …)

  • sequential (bool) – whether to use callbacks after each pair, defaults to False

  • time_unit (TimeUnit) – which time unit to use for the max_time parameter

  • max_time (int) – maximum number of time units (see time_unit) the Host is willing to wait for entanglement generation of a single pair. If generation does not succeed within this time, the whole subroutine that this request is part of is reset and run again by the quantum node controller.

  • min_fidelity_all_at_end (Optional[int]) – the minimum fidelity that all entangled qubits should ideally still have at the moment the last qubit has been generated. For example, when specifying number=2 and min_fidelity_all_at_end=80, the the program will automatically try to make sure that both qubits have a fidelity of at least 80% when the second qubit has been generated. It will attempt to do this by automatically re-trying the entanglement generation if the fidelity constraint is not satisfied. This is however an attempt, and not a guarantee!.

  • max_tries (Optional[int]) – maximum number of re-tries should be made to try and achieve the min_fidelity_all_at_end constraint.

Return type

List[Qubit]

Returns

list of qubits created

create_keep_with_info(number=1, post_routine=None, sequential=False, time_unit=<TimeUnit.MICRO_SECONDS: 0>, max_time=0, min_fidelity_all_at_end=None)

Same as create_keep but also return the EPR generation information coming from the network stack.

For more information see the documentation of create_keep.

Parameters
  • number (int) – number of pairs to generate, defaults to 1

  • post_routine (Optional[Callable]) –

  • sequential (bool) –

  • time_unit (TimeUnit) –

  • max_time (int) –

  • min_fidelity_all_at_end (Optional[int]) –

Return type

Tuple[List[Qubit], List[EprKeepResult]]

Returns

tuple with (1) list of qubits created, (2) list of EprKeepResult objects

create_measure(number=1, time_unit=<TimeUnit.MICRO_SECONDS: 0>, max_time=0, basis_local=None, basis_remote=None, rotations_local=(0, 0, 0), rotations_remote=(0, 0, 0), random_basis_local=None, random_basis_remote=None)

Ask the network stack to generate EPR pairs with the remote node and measure them immediately (on both nodes).

A create_measure operation must always be matched by a recv_measure operation on the remote node.

This operation returns a list of Linklayer response objects. These objects contain information about the entanglement generation and includes the measurement outcome and basis used. Note that all values are Future objects. This means that the current subroutine must be flushed before the values become defined.

An example for generating 10 pairs with another node that are immediately measured:

# list of Futures that become defined when subroutine is flushed
outcomes = []
with NetQASMConnection("alice", epr_sockets=[epr_socket]):
    ent_infos = epr_socket.create(number=10, tp=EPRType.M)
    for ent_info in ent_infos:
        outcomes.append(ent_info.measurement_outcome)

The basis to measure in can also be specified. There are 3 ways to specify a basis:

  • using one of the EprMeasBasis variants

  • by specifying 3 rotation angles, interpreted as an X-rotation, a Y-rotation and another X-rotation. For example, setting rotations_local to (8, 0, 0) means that before measuring, an X-rotation of 8*pi/16 = pi/2 radians is applied to the qubit.

  • using one of the RandomBasis variants, in which case one of the bases of that variant is chosen at random just before measuring

NOTE: the node that initiates the entanglement generation, i.e. the one that calls create on its EPR socket, also controls the measurement bases of the receiving node (by setting e.g. rotations_remote). The receiving node cannot change this.

Parameters
  • number (int) – number of EPR pairs to generate, defaults to 1

  • time_unit (TimeUnit) – which time unit to use for the max_time parameter

  • max_time (int) – maximum number of time units (see time_unit) the Host is willing to wait for entanglement generation of a single pair. If generation does not succeed within this time, the whole subroutine that this request is part of is reset and run again by the quantum node controller.

  • basis_local (Optional[EprMeasBasis]) – basis to measure in on this node for M-type requests

  • basis_remote (Optional[EprMeasBasis]) – basis to measure in on the remote node for M-type requests

  • rotations_local (Tuple[int, int, int]) – rotations to apply before measuring on this node

  • rotations_remote (Tuple[int, int, int]) – rotations to apply before measuring on remote node

  • random_basis_local (Optional[RandomBasis]) – random bases to choose from when measuring on this node

  • random_basis_remote (Optional[RandomBasis]) – random bases to choose from when measuring on the remote node

Return type

List[EprMeasureResult]

Returns

list of entanglement info objects per created pair.

create_rsp(number=1, time_unit=<TimeUnit.MICRO_SECONDS: 0>, max_time=0, basis_local=None, rotations_local=(0, 0, 0), random_basis_local=None, min_fidelity_all_at_end=None, max_tries=None)

Ask the network stack to do remote preparation with the remote node.

A create_rsp operation must always be matched by a recv_epr operation on the remote node.

This operation returns a list of Linklayer response objects. These objects contain information about the entanglement generation and includes the measurement outcome and basis used. Note that all values are Future objects. This means that the current subroutine must be flushed before the values become defined.

An example for generating 10 pairs with another node that are immediately measured:

m: LinkLayerOKTypeM = epr_socket.create_rsp(tp=EPRType.R)[0]
print(m.measurement_outcome)
# remote node now has a prepared qubit

The basis to measure in can also be specified. There are 3 ways to specify a basis:

  • using one of the EprMeasBasis variants

  • by specifying 3 rotation angles, interpreted as an X-rotation, a Y-rotation and another X-rotation. For example, setting rotations_local to (8, 0, 0) means that before measuring, an X-rotation of 8*pi/16 = pi/2 radians is applied to the qubit.

  • using one of the RandomBasis variants, in which case one of the bases of that variant is chosen at random just before measuring

Parameters
  • number (int) – number of EPR pairs to generate, defaults to 1

  • time_unit (TimeUnit) – which time unit to use for the max_time parameter

  • max_time (int) – maximum number of time units (see time_unit) the Host is willing to wait for entanglement generation of a single pair. If generation does not succeed within this time, the whole subroutine that this request is part of is reset and run again by the quantum node controller.

  • basis_local (Optional[EprMeasBasis]) – basis to measure in on this node for M-type requests

  • rotations_local (Tuple[int, int, int]) – rotations to apply before measuring on this node

  • random_basis_local (Optional[RandomBasis]) – random bases to choose from when measuring on this node

  • min_fidelity_all_at_end (Optional[int]) – the minimum fidelity that all entangled qubits should ideally still have at the moment the last qubit has been generated. For example, when specifying number=2 and min_fidelity_all_at_end=80, the the program will automatically try to make sure that both qubits have a fidelity of at least 80% when the second qubit has been generated. It will attempt to do this by automatically re-trying the entanglement generation if the fidelity constraint is not satisfied. This is however an attempt, and not a guarantee!.

  • max_tries (Optional[int]) – maximum number of re-tries should be made to try and achieve the min_fidelity_all_at_end constraint.

Return type

List[EprMeasureResult]

Returns

list of entanglement info objects per created pair.

create(number=1, post_routine=None, sequential=False, tp=<EPRType.K: 0>, time_unit=<TimeUnit.MICRO_SECONDS: 0>, max_time=0, basis_local=None, basis_remote=None, rotations_local=(0, 0, 0), rotations_remote=(0, 0, 0), random_basis_local=None, random_basis_remote=None)

Ask the network stack to generate EPR pairs with the remote node.

A create operation must always be matched by a recv operation on the remote node.

If the type of request is Create and Keep (CK, or just K) and if sequential is False (default), this operation returns a list of Qubit objects representing the local qubits that are each one half of the generated pairs. These qubits can then be manipulated locally just like locally initialized qubits, by e.g. applying gates or measuring them. Each qubit also contains information about the entanglement generation that lead to its creation, and can be accessed by its entanglement_info property.

A typical example for just generating one pair with another node would be:

q = epr_socket.create()[0]
# `q` can now be used as a normal qubit

If the type of request is Measure Directly (MD, or just M), this operation returns a list of Linklayer response objects. These objects contain information about the entanglement generation and includes the measurement outcome and basis used. Note that all values are Future objects. This means that the current subroutine must be flushed before the values become defined.

An example for generating 10 pairs with another node that are immediately measured:

# list of Futures that become defined when subroutine is flushed
outcomes = []
with NetQASMConnection("alice", epr_sockets=[epr_socket]):
    ent_infos = epr_socket.create(number=10, tp=EPRType.M)
    for ent_info in ent_infos:
        outcomes.append(ent_info.measurement_outcome)

For “Measure Directly”-type requests, the basis to measure in can also be specified. There are 3 ways to specify a basis:

  • using one of the EprMeasBasis variants

  • by specifying 3 rotation angles, interpreted as an X-rotation, a Y-rotation and another X-rotation. For example, setting rotations_local to (8, 0, 0) means that before measuring, an X-rotation of 8*pi/16 = pi/2 radians is applied to the qubit.

  • using one of the RandomBasis variants, in which case one of the bases of that variant is chosen at random just before measuring

NOTE: the node that initiates the entanglement generation, i.e. the one that calls create on its EPR socket, also controls the measurement bases of the receiving node (by setting e.g. rotations_remote). The receiving node cannot change this.

If sequential is False (default), the all requested EPR pairs are generated at once, before returning the results (qubits or entanglement info objects).

If sequential is True, a callback function (post_routine) should be specified. After generating one EPR pair, this callback will be called, before generating the next pair. This method can e.g. be used to generate many EPR pairs (more than the number of physical qubits available), by measuring (and freeing up) each qubit before the next pair is generated.

For example:

outcomes = alice.new_array(num)

def post_create(conn, q, pair):
    q.H()
    outcome = outcomes.get_future_index(pair)
    q.measure(outcome)
epr_socket.create(number=num, post_routine=post_create, sequential=True)
Parameters
  • number (int) – number of EPR pairs to generate, defaults to 1

  • post_routine (Optional[Callable]) – callback function for each genated pair. Only used if sequential is True. The callback should take three arguments (conn, q, pair) where * conn is the connection (e.g. self) * q is the entangled qubit (of type FutureQubit) * pair is a register holding which pair is handled (0, 1, …)

  • sequential (bool) – whether to use callbacks after each pair, defaults to False

  • tp (EPRType) – type of entanglement generation, defaults to EPRType.K. Note that corresponding recv of the remote node’s EPR socket must specify the same type.

  • time_unit (TimeUnit) – which time unit to use for the max_time parameter

  • max_time (int) – maximum number of time units (see time_unit) the Host is willing to wait for entanglement generation of a single pair. If generation does not succeed within this time, the whole subroutine that this request is part of is reset and run again by the quantum node controller.

  • basis_local (Optional[EprMeasBasis]) – basis to measure in on this node for M-type requests

  • basis_remote (Optional[EprMeasBasis]) – basis to measure in on the remote node for M-type requests

  • rotations_local (Tuple[int, int, int]) – rotations to apply before measuring on this node (for M-type requests)

  • rotations_remote (Tuple[int, int, int]) – rotations to apply before measuring on remote node (for M-type requests)

  • random_basis_local (Optional[RandomBasis]) – random bases to choose from when measuring on this node (for M-type requests)

  • random_basis_remote (Optional[RandomBasis]) – random bases to choose from when measuring on the remote node (for M-type requests)

Return type

Union[List[Qubit], List[EprMeasureResult], List[LinkLayerOKTypeM]]

Returns

For K-type requests: list of qubits created. For M-type requests: list of entanglement info objects per created pair.

create_context(number=1, sequential=False, time_unit=<TimeUnit.MICRO_SECONDS: 0>, max_time=0)

Create a context that is executed for each generated EPR pair consecutively.

Creates EPR pairs with a remote node and handles each pair by the operations defined in a subsequent context. See the example below.

with epr_socket.create_context(number=10) as (q, pair):
    q.H()
    m = q.measure()

NOTE: even though all pairs are handled consecutively, they are still generated concurrently by the network stack. By setting sequential to True, the network stack only generates the next pair after the context for the previous pair has been executed, similar to using a callback (post_routine) in the create method.

Parameters
  • number (int) – number of EPR pairs to generate, defaults to 1

  • sequential (bool) – whether to generate pairs sequentially, defaults to False

  • time_unit (TimeUnit) –

  • max_time (int) –

Return type

AbstractContextManager[Tuple[FutureQubit, RegFuture]]

recv_keep(number=1, post_routine=None, sequential=False, expect_phi_plus=True, min_fidelity_all_at_end=None, max_tries=None)

Ask the network stack to wait for the remote node to generate EPR pairs, which are kept in memory.

A recv_keep operation must always be matched by a create_keep operation on the remote node. The number of generated pairs must also match.

For more information see the documentation of create_keep.

Parameters
  • number (int) – number of pairs to generate, defaults to 1

  • post_routine (Optional[Callable]) – callback function used when sequential is True

  • sequential (bool) – whether to call the callback after each pair generation, defaults to False

  • expect_phi_plus (bool) – whether to assume that the EPR pairs that are created are in the Phi+ (or Phi_00) state. Defaults to True. If True, the compiler will make sure that if the physical link actually produced another Bell state, the behavior seen by the application is still as if a Phi+ state was actually produced.

  • min_fidelity_all_at_end (Optional[int]) – the minimum fidelity that all entangled qubits should ideally still have at the moment the last qubit has been generated. For example, when specifying number=2 and min_fidelity_all_at_end=80, the the program will automatically try to make sure that both qubits have a fidelity of at least 80% when the second qubit has been generated. It will attempt to do this by automatically re-trying the entanglement generation if the fidelity constraint is not satisfied. This is however an attempt, and not a guarantee!.

  • max_tries (Optional[int]) – maximum number of re-tries should be made to try and achieve the min_fidelity_all_at_end constraint.

Return type

List[Qubit]

Returns

list of qubits created

recv_keep_with_info(number=1, post_routine=None, sequential=False, expect_phi_plus=True, min_fidelity_all_at_end=None, max_tries=None)

Same as recv_keep but also return the EPR generation information coming from the network stack.

For more information see the documentation of recv_keep.

Parameters
  • number (int) – number of pairs to generate, defaults to 1

  • post_routine (Optional[Callable]) –

  • sequential (bool) –

  • expect_phi_plus (bool) –

  • min_fidelity_all_at_end (Optional[int]) –

  • max_tries (Optional[int]) –

Return type

Tuple[List[Qubit], List[EprKeepResult]]

Returns

tuple with (1) list of qubits created, (2) list of EprKeepResult objects

recv_measure(number=1, expect_phi_plus=True)

Ask the network stack to wait for the remote node to generate EPR pairs, which are immediately measured (on both nodes).

A recv_measure operation must always be matched by a create_measure operation on the remote node. The number and type of generation must also match.

For more information see the documentation of create_measure.

Parameters
  • number (int) – number of pairs to generate, defaults to 1

  • expect_phi_plus (bool) – whether to assume that the EPR pairs that are created are in the Phi+ (or Phi_00) state. Defaults to True. If True, the compiler will make sure that if the physical link actually produced another Bell state, the behavior seen by the application is still as if a Phi+ state was actually produced.

Return type

List[EprMeasureResult]

Returns

list of entanglement info objects per created pair.

recv_rsp(number=1, expect_phi_plus=True, min_fidelity_all_at_end=None, max_tries=None)

Ask the network stack to wait for remote state preparation from another node.

A recv_rsp operation must always be matched by a create_rsp operation on the remote node. The number and type of generation must also match.

For more information see the documentation of create_rsp.

Parameters
  • number (int) – number of pairs to generate, defaults to 1

  • expect_phi_plus (bool) – whether to assume that the EPR pairs that are created are in the Phi+ (or Phi_00) state. Defaults to True. If True, the compiler will make sure that if the physical link actually produced another Bell state, the behavior seen by the application is still as if a Phi+ state was actually produced.

  • min_fidelity_all_at_end (Optional[int]) – the minimum fidelity that all entangled qubits should ideally still have at the moment the last qubit has been generated. For example, when specifying number=2 and min_fidelity_all_at_end=80, the the program will automatically try to make sure that both qubits have a fidelity of at least 80% when the second qubit has been generated. It will attempt to do this by automatically re-trying the entanglement generation if the fidelity constraint is not satisfied. This is however an attempt, and not a guarantee!.

  • max_tries (Optional[int]) – maximum number of re-tries should be made to try and achieve the min_fidelity_all_at_end constraint.

Return type

List[Qubit]

Returns

list of qubits created

recv_rsp_with_info(number=1, expect_phi_plus=True, min_fidelity_all_at_end=None, max_tries=None)

Same as recv_rsp but also return the EPR generation information coming from the network stack.

For more information see the documentation of recv_rsp.

Parameters
  • number (int) – number of pairs to generate, defaults to 1

  • expect_phi_plus (bool) –

  • min_fidelity_all_at_end (Optional[int]) –

  • max_tries (Optional[int]) –

Return type

Tuple[List[Qubit], List[EprKeepResult]]

Returns

tuple with (1) list of qubits created, (2) list of EprKeepResult objects

recv(number=1, post_routine=None, sequential=False, tp=<EPRType.K: 0>)

Ask the network stack to wait for the remote node to generate EPR pairs.

A recv operation must always be matched by a create operation on the remote node. See also the documentation of create. The number and type of generation must also match.

In case of Measure Directly requests, it is the initiating node (that calls create) which specifies the measurement bases. This should not and cannot be done in recv.

For more information see the documentation of create.

Parameters
  • number (int) – number of pairs to generate, defaults to 1

  • post_routine (Optional[Callable]) – callback function used when sequential is True

  • sequential (bool) – whether to call the callback after each pair generation, defaults to False

  • tp (EPRType) – type of entanglement generation, defaults to EPRType.K

Return type

Union[List[Qubit], List[EprMeasureResult], List[LinkLayerOKTypeR]]

Returns

For K-type requests: list of qubits created. For M-type requests: list of entanglement info objects per created pair.

recv_context(number=1, sequential=False)

Receives EPR pair with a remote node (see doc of create_context())

Parameters
  • number (int) –

  • sequential (bool) –

Futures

Abstractions for classical runtime values.

This module contains the BaseFuture class and its subclasses.

class netqasm.sdk.futures.Future(connection, address, index)

Represents a single array entry value that will become available in the future.

See BaseFuture for more explanation about Futures.

Parameters
__init__(connection, address, index)

Future constructor. Typically not used directly.

Parameters
  • connection (sdkconn.BaseNetQASMConnection) – connection through which subroutines are sent that contain the array entry corresponding to this Future

  • address (int) – address of the array

  • index (Union[int, Future, operand.Register, RegFuture]) – index in the array

add(other, mod=None)

Add another value to this Future’s value.

The result is stored in this Future.

Let the quantum node controller add a value to the value represented by this Future. The addition operation is compiled into a subroutine and is fully executed by the quantum node controller. This avoids the need to wait for a subroutine result (which resolves the Future’s value) and then doing the addition on the Host.

Parameters
  • other (Union[int, str, Register, BaseFuture]) – value to add to this Future’s value

  • mod (Optional[int]) – do the addition modulo mod

Return type

None

get_load_commands(register)

Return a list of ProtoSubroutine commands for loading this Future into the specified register.

Parameters

register (Register) –

Return type

List[Union[ICmd, BranchLabel]]

get_address_entry()

Convert this Future to an ArrayEntry object to be used an instruction operand.

Return type

ArrayEntry

class netqasm.sdk.futures.Array(connection, length, address, init_values=None, lineno=None)

Wrapper around an array in Shared Memory.

An Array instance provides methods to inspect and operate on an array that exists in shared memory. They are typically obtained as return values to certain SDK methods.

Elements or slices of the array can be captured as Futures.

Parameters
  • connection (sdkconn.BaseNetQASMConnection) –

  • length (int) –

  • address (int) –

  • init_values (Optional[List[Optional[int]]]) –

  • lineno (Optional[HostLine]) –

__init__(connection, length, address, init_values=None, lineno=None)

Array constructor. Typically not used directly.

Parameters
  • connection (sdkconn.BaseNetQASMConnection) – connection of the application this array is part of

  • length (int) – length of the array

  • address (int) – address of the array

  • init_values (Optional[List[Optional[int]]]) – initial values of the array. Must have length length.

  • lineno (Optional[HostLine]) – line number where the array is created in the Python source code

property lineno

What line in host application file initiated this array

Return type

Optional[HostLine]

property address
Return type

int

property builder
Return type

Builder

get_future_index(index)

Get a Future representing a particular array element

Parameters

index (Union[int, str, Register, RegFuture]) –

Return type

Future

get_future_slice(s)

Get a list of Futures each representing one element in a particular array slice

Parameters

s (slice) –

Return type

List[Future]

foreach()

Create a context of code that gets called for each element in the array.

Returns a future of the array value at the current index.

Code inside the context must be compilable to NetQASM, that is, it should only contain quantum operations and/or classical values that are are stored in shared memory (arrays and registers). No classical communication is allowed.

Example:

with NetQASMConnection(app_name="alice") as alice:
    outcomes = alice.new_array(10)
    values = alice.new_array(
        10,
        init_values=[random.randint(0, 1) for _ in range(10)]
    )
    with values.foreach() as v:
        q = Qubit(alice)
        with v.if_eq(1):
            q.H()
        q.measure(future=outcomes.get_future_index(i))
Return type

SdkForEachContext

enumerate()

Create a context of code that gets called for each element in the array and includes a counter.

Returns a tuple (index, future) where future is a Future of the array value at the current index.

Code inside the context must be compilable to NetQASM, that is, it should only contain quantum operations and/or classical values that are are stored in shared memory (arrays and registers). No classical communication is allowed.

Example:

with NetQASMConnection(app_name="alice") as alice:
    outcomes = alice.new_array(10)
    values = alice.new_array(
        10,
        init_values=[random.randint(0, 1) for _ in range(10)]
    )
    with values.enumerate() as (i, v):
        q = Qubit(alice)
        with v.if_eq(1):
            q.H()
        q.measure(future=outcomes.get_future_index(i))
Return type

SdkForEachContext

undefine()

Undefine (i.e. set to ‘None’) all elements in the array.

Return type

None

class netqasm.sdk.futures.RegFuture(connection, reg=None)

Represents a single register value that will become available in the future.

See BaseFuture for more explanation about Futures.

Parameters
  • connection (sdkconn.BaseNetQASMConnection) –

  • reg (Optional[operand.Register]) –

__init__(connection, reg=None)

RegFuture constructor. Typically not used directly.

Parameters
  • connection (sdkconn.BaseNetQASMConnection) – connection through which subroutines are sent that contain the array entry corresponding to this Future

  • reg (Optional[operand.Register]) – specific NetQASM register that will hold the Future’s value. If None, a suitable register is automatically used.

property reg
Return type

Optional[Register]

add(other, mod=None)

Add another value to this Future’s value.

The result is stored in this Future.

Let the quantum node controller add a value to the value represented by this Future. The addition operation is compiled into a subroutine and is fully executed by the quantum node controller. This avoids the need to wait for a subroutine result (which resolves the Future’s value) and then doing the addition on the Host.

Parameters
  • other (Union[int, str, Register, BaseFuture]) – value to add to this Future’s value

  • mod (Optional[int]) – do the addition modulo mod

Return type

None

Classical communication

Interface for classical communication between Hosts.

This module contains the Socket class which is a base for representing classical communication (sending and receiving classical messages) between Hosts.

class netqasm.sdk.classical_communication.socket.Socket(app_name, remote_app_name, socket_id=0, timeout=None, use_callbacks=False, log_config=None)

Base class for classical sockets.

Classical communication is modelled by sockets, which are also widely used in purely classical applications involving communication.

If a node wants to communicate arbitrary classical messages with another node, this communication must be done between the Hosts of these nodes. Both Hosts should instantiate a Socket object with the other Host as ‘remote’. Upon creation, the Socket objects try to connect to each other. Only after this has succeeded, the sockets can be used.

The main methods of a Socket are send and recv, which are used to send a message to the remote Host, and wait to receive a message from the other Host, respectively. Messages are str (string) objects. To send a number, convert it to a string before sending, and convert it back after receiving.

There are some variations on the send and recv methods which may be useful in specific scenarios. See their own documentation for their use.

NOTE: At the moment, Sockets are not part of the compilation process yet. Therefore, they don’t need to be part of a Connection, and operations on Sockets do not need to be flushed before they are executed (they are executed immediately). This also means that e.g. a recv operation, which is blocking by default, acutally blocks the whole application script. So, if any quantum operations should be executed before such a `recv` statement, make sure that these operations are flushed before blocking on `recv`.

Implementations (subclasses) of Sockets may be quite different, depending on the runtime environment. A physical setup (with real hardware) may implement this as TCP sockets. A simulator might use inter-thread communication (see e.g. ThreadSocket), or another custom object type.

Parameters
  • app_name (str) –

  • remote_app_name (str) –

  • socket_id (int) –

  • timeout (Optional[float]) –

  • use_callbacks (bool) –

  • log_config (Optional[config.LogConfig]) –

__init__(app_name, remote_app_name, socket_id=0, timeout=None, use_callbacks=False, log_config=None)

Socket constructor.

Parameters
  • app_name (str) – application/Host name of this socket’s owner

  • remote_app_name (str) – application/Host name of this socket’s remote

  • socket_id (int) – local ID to use for this socket

  • timeout (Optional[float]) – maximum amount of real time to try to connect to the remote socket

  • use_callbacks (bool) – whether to call the recv_callback method upon receiving a message

  • log_config (Optional[config.LogConfig]) – logging configuration for this socket

abstract send(msg)

Send a message to the remote node.

Parameters

msg (str) –

Return type

None

abstract recv(block=True, timeout=None, maxsize=None)

Receive a message from the remote node.

Parameters
  • block (bool) –

  • timeout (Optional[float]) –

  • maxsize (Optional[int]) –

Return type

str

send_structured(msg)

Sends a structured message (with header and payload) to the remote node.

Parameters

msg (StructuredMessage) –

Return type

None

recv_structured(block=True, timeout=None, maxsize=None)

Receive a message (with header and payload) from the remote node.

Parameters
  • block (bool) –

  • timeout (Optional[float]) –

  • maxsize (Optional[int]) –

Return type

StructuredMessage

send_silent(msg)

Sends a message without logging

Parameters

msg (str) –

Return type

None

recv_silent(block=True, timeout=None, maxsize=None)

Receive a message without logging

Parameters
  • block (bool) –

  • timeout (Optional[float]) –

  • maxsize (Optional[int]) –

Return type

str

recv_callback(msg)

This method gets called when a message is received.

Subclass to define behaviour.

NOTE: This only happens if self.use_callbacks is set to True.

Parameters

msg (str) –

Return type

None

conn_lost_callback()

This method gets called when the connection is lost.

Subclass to define behaviour.

NOTE: This only happens if self.use_callbacks is set to True.

Return type

None