netqasm.sdk.epr_socket

EPR Socket interface.

class netqasm.sdk.epr_socket.EPRMeasBasis(value)

Bases: enum.Enum

An enumeration.

X = 0
Y = 1
Z = 2
MX = 3
MY = 4
MZ = 5
class netqasm.sdk.epr_socket.EPRSocket(remote_app_name, epr_socket_id=0, remote_epr_socket_id=0, min_fidelity=100)

Bases: abc.ABC

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 (int) –

__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(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[LinkLayerOKTypeK], List[LinkLayerOKTypeM], List[LinkLayerOKTypeR]]

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) –

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[LinkLayerOKTypeK], List[LinkLayerOKTypeM], 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) –