netqasm.sdk.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)

Bases: ABC

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[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[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: str

Get the application name

property node_name: str

Get the node name

property app_id: int

Get the application ID

property network_info: Type[NetworkInfo]
property builder: Builder
classmethod get_app_ids()
Return type:

Dict[str, List[int]]

classmethod get_app_names()
Return type:

Dict[str, Dict[int, str]]

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: SharedMemory

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.

property active_qubits: List[Qubit]

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.

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:

ContextManager[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 (T_LoopRoutine) – 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 (Optional[Union[operand.Register, str]]) – 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:

ContextManager[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 (T_CValue) – a classical value

  • b (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • b (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • b (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • b (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • body (T_BranchRoutine) – function to execute if condition is true

Return type:

None

try_until_success(max_tries=1)

TODO docstring

Parameters:

max_tries (int)

Return type:

ContextManager[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)
Parameters:
Return type:

None

class netqasm.sdk.connection.DebugConnection(*args, **kwargs)

Bases: BaseNetQASMConnection

Connection that mocks most of the BaseNetQASMConnection logic.

Subroutines that are flushed are simply stored in this object. No actual connection is made.

node_ids: Dict[str, int] = {}
__init__(*args, **kwargs)

A connection that simply stores the subroutine it commits

property shared_memory: SharedMemory

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.

property active_qubits: List[Qubit]

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.

Returns:

list of active qubits

property app_id: int

Get the application ID

property app_name: str

Get the application name

block()

Block until a flushed subroutines finishes.

This should be implemented by subclasses.

:raises NotImplementedError

Return type:

None

property builder: Builder
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

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

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]

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

classmethod get_app_ids()
Return type:

Dict[str, List[int]]

classmethod get_app_names()
Return type:

Dict[str, Dict[int, str]]

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 (T_CValue) – a classical value

  • b (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • b (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • b (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • b (T_CValue) – a classical value

  • body (T_BranchRoutine) – 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 (T_CValue) – a classical value

  • body (T_BranchRoutine) – function to execute if condition is true

Return type:

None

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

None

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:

ContextManager[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 (T_LoopRoutine) – 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 (Optional[Union[operand.Register, str]]) – 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:

ContextManager[SdkLoopUntilContext]

property network_info: Type[NetworkInfo]
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

property node_name: str

Get the node name

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

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]

try_until_success(max_tries=1)

TODO docstring

Parameters:

max_tries (int)

Return type:

ContextManager[None]

class netqasm.sdk.connection.DebugNetworkInfo

Bases: NetworkInfo

classmethod get_node_id_for_app(app_name)

Returns the node id for the app with the given name

Parameters:

app_name (str)

Return type:

int

classmethod get_node_name_for_app(app_name)

Returns the node name for the app with the given name

Parameters:

app_name (str)

Return type:

str