SDK objects¶
Described below are the user-exposed components of the NetQASM SDK.
Qubit
Futures:
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
-
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
-
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 1init_values (
Optional
[List
[Optional
[int
]]]) – list of initial values of the array. If not None, must have the same length as length.
- Return type
- 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 0step (
int
) – step size of iteration range, defaults to 1loop_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 loopstop (
int
) – end of iteration range (exluding)start (
int
) – start of iteration range (including), defaults to 0step (
int
) – step size of iteration range, defaults to 1loop_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 valueb (
Union
[int
,ForwardRef
,ForwardRef
]) – a classical valuebody (
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 valueb (
Union
[int
,ForwardRef
,ForwardRef
]) – a classical valuebody (
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 valueb (
Union
[int
,ForwardRef
,ForwardRef
]) – a classical valuebody (
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 valueb (
Union
[int
,ForwardRef
,ForwardRef
]) – a classical valuebody (
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 valuebody (
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 valuebody (
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
preparation (
Callable
[[BaseNetQASMConnection
],Qubit
]) –iterations (
int
) –progress (
bool
) –
- 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
action (
BreakpointAction
) –role (
BreakpointRole
) –
- 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
-
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
- 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 0remote_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
-
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 1post_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 Falsetime_unit (
TimeUnit
) – which time unit to use for the max_time parametermax_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 1post_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 1time_unit (
TimeUnit
) – which time unit to use for the max_time parametermax_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 requestsbasis_remote (
Optional
[EprMeasBasis
]) – basis to measure in on the remote node for M-type requestsrotations_local (
Tuple
[int
,int
,int
]) – rotations to apply before measuring on this noderotations_remote (
Tuple
[int
,int
,int
]) – rotations to apply before measuring on remote noderandom_basis_local (
Optional
[RandomBasis
]) – random bases to choose from when measuring on this noderandom_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 1time_unit (
TimeUnit
) – which time unit to use for the max_time parametermax_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 requestsrotations_local (
Tuple
[int
,int
,int
]) – rotations to apply before measuring on this noderandom_basis_local (
Optional
[RandomBasis
]) – random bases to choose from when measuring on this nodemin_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 1post_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 Falsetp (
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 parametermax_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 requestsbasis_remote (
Optional
[EprMeasBasis
]) – basis to measure in on the remote node for M-type requestsrotations_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 1sequential (
bool
) – whether to generate pairs sequentially, defaults to Falsetime_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 1post_routine (
Optional
[Callable
]) – callback function used when sequential is Truesequential (
bool
) – whether to call the callback after each pair generation, defaults to Falseexpect_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 1post_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 1expect_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 1expect_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 1expect_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 1post_routine (
Optional
[Callable
]) – callback function used when sequential is Truesequential (
bool
) – whether to call the callback after each pair generation, defaults to Falsetp (
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
connection (sdkconn.BaseNetQASMConnection) –
address (int) –
index (Union[int, Future, operand.Register, RegFuture]) –
-
__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 valuemod (
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
-
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
-
get_future_index
(index) Get a Future representing a particular array element
-
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
-
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
-
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 valuemod (
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
-
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