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