From ca962044e779e112e5a4a0b89c8bef80718408a5 Mon Sep 17 00:00:00 2001 From: Bart van der Vecht Date: Thu, 2 Dec 2021 18:27:59 +0100 Subject: [PATCH 1/7] Compute fidelities for teleportation app --- examples/stack/teleport/config.yaml | 37 ++++++++++ examples/stack/teleport/example_teleport.py | 76 +++++++++++++-------- 2 files changed, 85 insertions(+), 28 deletions(-) create mode 100644 examples/stack/teleport/config.yaml diff --git a/examples/stack/teleport/config.yaml b/examples/stack/teleport/config.yaml new file mode 100644 index 00000000..7b76245f --- /dev/null +++ b/examples/stack/teleport/config.yaml @@ -0,0 +1,37 @@ +qdevice_cfg: &qdevice_cfg + num_qubits: 2 + num_comm_qubits: 1 + T1: 1.e+10 + T2: 1.e+9 + init_time: 1.e+4 + single_qubit_gate_time: 1.e+3 + two_qubit_gate_time: 1.e+5 + measurement_time: 1.e+4 + single_qubit_gate_depolar_prob: 0 + two_qubit_gate_depolar_prob: 0.01 + +stacks: + - name: sender + qdevice_typ: generic + qdevice_cfg: + <<: *qdevice_cfg + classical_cfg: + host_qnos_latency: 1e5 + - name: receiver + qdevice_typ: generic + qdevice_cfg: + <<: *qdevice_cfg + classical_cfg: + host_qnos_latency: 1e5 + +link_cfg: &link_cfg + fidelity: 0.8 + prob_success: 0.01 + t_cycle: 1.e+6 + +links: + - stack1: sender + stack2: receiver + typ: depolarise + cfg: + <<: *link_cfg \ No newline at end of file diff --git a/examples/stack/teleport/example_teleport.py b/examples/stack/teleport/example_teleport.py index b9dd8a4f..c008d267 100644 --- a/examples/stack/teleport/example_teleport.py +++ b/examples/stack/teleport/example_teleport.py @@ -1,11 +1,14 @@ from __future__ import annotations import math -from typing import Any, Dict, Generator +import os +from typing import Any, Dict, Generator, List +import netsquid as ns from netqasm.lang.ir import BreakpointAction, BreakpointRole from netqasm.sdk.qubit import Qubit from netqasm.sdk.toolbox import set_qubit_state +from netsquid.qubits import ketstates, operators, qubit, qubitapi from pydynaa import EventExpression from squidasm.run.stack.config import ( @@ -15,7 +18,9 @@ StackNetworkConfig, ) from squidasm.run.stack.run import run +from squidasm.sim.stack.common import LogManager from squidasm.sim.stack.csocket import ClassicalSocket +from squidasm.sim.stack.globals import GlobalSimData from squidasm.sim.stack.program import Program, ProgramContext, ProgramMeta @@ -54,9 +59,6 @@ def run( set_qubit_state(q, self._phi, self._theta) e = epr_socket.create_keep()[0] - conn.insert_breakpoint( - BreakpointAction.DUMP_GLOBAL_STATE, BreakpointRole.CREATE - ) q.cnot(e) q.H() m1 = q.measure() @@ -93,9 +95,6 @@ def run( csocket: ClassicalSocket = context.csockets[self.PEER] e = epr_socket.recv_keep()[0] - conn.insert_breakpoint( - BreakpointAction.DUMP_GLOBAL_STATE, BreakpointRole.RECEIVE - ) yield from conn.flush() m1 = yield from csocket.recv_int() @@ -106,33 +105,54 @@ def run( if m1 == 1: e.Z() - # conn.insert_breakpoint(BreakpointAction.DUMP_LOCAL_STATE) + conn.insert_breakpoint(BreakpointAction.DUMP_LOCAL_STATE) + e.measure() yield from conn.flush() + all_states = GlobalSimData.get_last_breakpoint_state() + state = all_states["receiver"][0] + return state -if __name__ == "__main__": - # set_log_level("INFO") - sender_stack = StackConfig( - name="sender", - qdevice_typ="generic", - qdevice_cfg=GenericQDeviceConfig.perfect_config(), - ) - receiver_stack = StackConfig( - name="receiver", - qdevice_typ="generic", - qdevice_cfg=GenericQDeviceConfig.perfect_config(), +def do_teleportation( + cfg: StackNetworkConfig, + num_times: int = 1, + theta: float = 0.0, + phi: float = 0.0, + log_level: str = "WARNING", +) -> List[float]: + LogManager.set_log_level(log_level) + + sender_program = SenderProgram(theta=theta, phi=phi) + receiver_program = ReceiverProgram() + + _, final_states = run( + cfg, + {"sender": sender_program, "receiver": receiver_program}, + num_times=num_times, ) - link = LinkConfig( - stack1="sender", - stack2="receiver", - typ="perfect", + + expected = qubitapi.create_qubits(1)[0] + rot_theta = operators.create_rotation_op(theta, rotation_axis=(0, 1, 0)) + rot_phi = operators.create_rotation_op(phi, rotation_axis=(0, 0, 1)) + qubitapi.operate(expected, rot_theta) + qubitapi.operate(expected, rot_phi) + fidelities = [qubitapi.fidelity(expected, f, squared=True) for f in final_states] + + return fidelities + + +if __name__ == "__main__": + ns.set_qstate_formalism(ns.qubits.qformalism.QFormalism.DM) + + cfg = StackNetworkConfig.from_file( + os.path.join(os.getcwd(), os.path.dirname(__file__), "config.yaml") ) - cfg = StackNetworkConfig(stacks=[sender_stack, receiver_stack], links=[link]) + # link between sender and receiver + link = cfg.links[0] - sender_program = SenderProgram(theta=math.pi, phi=0) - receiver_program = ReceiverProgram() + link.cfg["fidelity"] = 0.8 - results = run(cfg, {"sender": sender_program, "receiver": receiver_program}) - print(results) + fidelities = do_teleportation(cfg, num_times=10, theta=0, phi=0) + print(fidelities) From 2f7849c005c20ceb37bac76dc1f2780460a4133d Mon Sep 17 00:00:00 2001 From: Bart van der Vecht Date: Thu, 2 Dec 2021 20:03:06 +0100 Subject: [PATCH 2/7] Use NV link --- examples/stack/teleport/config.yaml | 16 +++++++++------- examples/stack/teleport/example_teleport.py | 5 +++-- squidasm/sim/stack/netstack.py | 5 +++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/examples/stack/teleport/config.yaml b/examples/stack/teleport/config.yaml index 7b76245f..da558939 100644 --- a/examples/stack/teleport/config.yaml +++ b/examples/stack/teleport/config.yaml @@ -1,5 +1,5 @@ qdevice_cfg: &qdevice_cfg - num_qubits: 2 + num_qubits: 3 num_comm_qubits: 1 T1: 1.e+10 T2: 1.e+9 @@ -12,26 +12,28 @@ qdevice_cfg: &qdevice_cfg stacks: - name: sender - qdevice_typ: generic + qdevice_typ: nv qdevice_cfg: <<: *qdevice_cfg classical_cfg: host_qnos_latency: 1e5 - name: receiver - qdevice_typ: generic + qdevice_typ: nv qdevice_cfg: <<: *qdevice_cfg classical_cfg: host_qnos_latency: 1e5 link_cfg: &link_cfg - fidelity: 0.8 - prob_success: 0.01 - t_cycle: 1.e+6 + length_A: 0.01 + length_B: 0.01 + full_cycle: 1e6 + cycle_time: 1e3 + alpha: 0.9 links: - stack1: sender stack2: receiver - typ: depolarise + typ: nv cfg: <<: *link_cfg \ No newline at end of file diff --git a/examples/stack/teleport/example_teleport.py b/examples/stack/teleport/example_teleport.py index c008d267..7085d487 100644 --- a/examples/stack/teleport/example_teleport.py +++ b/examples/stack/teleport/example_teleport.py @@ -154,5 +154,6 @@ def do_teleportation( link.cfg["fidelity"] = 0.8 - fidelities = do_teleportation(cfg, num_times=10, theta=0, phi=0) - print(fidelities) + for _ in range(2): + fidelities = do_teleportation(cfg, num_times=10, theta=0, phi=0) + print(fidelities) diff --git a/squidasm/sim/stack/netstack.py b/squidasm/sim/stack/netstack.py index c12c17bf..c1877bdb 100644 --- a/squidasm/sim/stack/netstack.py +++ b/squidasm/sim/stack/netstack.py @@ -336,22 +336,27 @@ def handle_create_ck_request( ResCreateAndKeep.__name__, receiver=self ) self._logger.info(f"got result for pair {pair_index}: {result}") + self._logger.warning(f"got result for pair {pair_index}: {result}") # Bell state corrections. Resulting state is always Phi+ (i.e. B00). if result.bell_state == BellIndex.B00: + self._logger.warning("B00") pass elif result.bell_state == BellIndex.B01: prog = QuantumProgram() prog.apply(INSTR_ROT_X, qubit_indices=[0], angle=PI) + self._logger.warning("B01") yield self.qdevice.execute_program(prog) elif result.bell_state == BellIndex.B10: prog = QuantumProgram() prog.apply(INSTR_ROT_Z, qubit_indices=[0], angle=PI) + self._logger.warning("B10") yield self.qdevice.execute_program(prog) elif result.bell_state == BellIndex.B11: prog = QuantumProgram() prog.apply(INSTR_ROT_X, qubit_indices=[0], angle=PI) prog.apply(INSTR_ROT_Z, qubit_indices=[0], angle=PI) + self._logger.warning("B11") yield self.qdevice.execute_program(prog) virt_id = app_mem.get_array_value(req.qubit_array_addr, pair_index) From 66f5d21781159ba9c745397eb4e789b8b687e978 Mon Sep 17 00:00:00 2001 From: Bart van der Vecht Date: Thu, 2 Dec 2021 20:03:40 +0100 Subject: [PATCH 3/7] Remove debug statements --- squidasm/sim/stack/netstack.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/squidasm/sim/stack/netstack.py b/squidasm/sim/stack/netstack.py index c1877bdb..c12c17bf 100644 --- a/squidasm/sim/stack/netstack.py +++ b/squidasm/sim/stack/netstack.py @@ -336,27 +336,22 @@ def handle_create_ck_request( ResCreateAndKeep.__name__, receiver=self ) self._logger.info(f"got result for pair {pair_index}: {result}") - self._logger.warning(f"got result for pair {pair_index}: {result}") # Bell state corrections. Resulting state is always Phi+ (i.e. B00). if result.bell_state == BellIndex.B00: - self._logger.warning("B00") pass elif result.bell_state == BellIndex.B01: prog = QuantumProgram() prog.apply(INSTR_ROT_X, qubit_indices=[0], angle=PI) - self._logger.warning("B01") yield self.qdevice.execute_program(prog) elif result.bell_state == BellIndex.B10: prog = QuantumProgram() prog.apply(INSTR_ROT_Z, qubit_indices=[0], angle=PI) - self._logger.warning("B10") yield self.qdevice.execute_program(prog) elif result.bell_state == BellIndex.B11: prog = QuantumProgram() prog.apply(INSTR_ROT_X, qubit_indices=[0], angle=PI) prog.apply(INSTR_ROT_Z, qubit_indices=[0], angle=PI) - self._logger.warning("B11") yield self.qdevice.execute_program(prog) virt_id = app_mem.get_array_value(req.qubit_array_addr, pair_index) From 434f66b01831638213b70aa2152e742dfd686b66 Mon Sep 17 00:00:00 2001 From: Bart van der Vecht Date: Thu, 2 Dec 2021 21:14:16 +0100 Subject: [PATCH 4/7] Add AnyBell depolarising distributor --- examples/stack/teleport/config.yaml | 10 +-- examples/stack/teleport/example_teleport.py | 15 +--- squidasm/run/stack/config.py | 10 +++ squidasm/run/stack/run.py | 90 +++++++++++++++++++++ 4 files changed, 108 insertions(+), 17 deletions(-) diff --git a/examples/stack/teleport/config.yaml b/examples/stack/teleport/config.yaml index da558939..6326bd1c 100644 --- a/examples/stack/teleport/config.yaml +++ b/examples/stack/teleport/config.yaml @@ -25,15 +25,13 @@ stacks: host_qnos_latency: 1e5 link_cfg: &link_cfg - length_A: 0.01 - length_B: 0.01 - full_cycle: 1e6 - cycle_time: 1e3 - alpha: 0.9 + fidelity: 0.8 + prob_success: 0.01 + t_cycle: 1.e+6 links: - stack1: sender stack2: receiver - typ: nv + typ: depolarise_any_bell cfg: <<: *link_cfg \ No newline at end of file diff --git a/examples/stack/teleport/example_teleport.py b/examples/stack/teleport/example_teleport.py index 7085d487..5d3f4349 100644 --- a/examples/stack/teleport/example_teleport.py +++ b/examples/stack/teleport/example_teleport.py @@ -1,6 +1,5 @@ from __future__ import annotations -import math import os from typing import Any, Dict, Generator, List @@ -8,15 +7,10 @@ from netqasm.lang.ir import BreakpointAction, BreakpointRole from netqasm.sdk.qubit import Qubit from netqasm.sdk.toolbox import set_qubit_state -from netsquid.qubits import ketstates, operators, qubit, qubitapi +from netsquid.qubits import operators, qubitapi from pydynaa import EventExpression -from squidasm.run.stack.config import ( - GenericQDeviceConfig, - LinkConfig, - StackConfig, - StackNetworkConfig, -) +from squidasm.run.stack.config import StackNetworkConfig from squidasm.run.stack.run import run from squidasm.sim.stack.common import LogManager from squidasm.sim.stack.csocket import ClassicalSocket @@ -154,6 +148,5 @@ def do_teleportation( link.cfg["fidelity"] = 0.8 - for _ in range(2): - fidelities = do_teleportation(cfg, num_times=10, theta=0, phi=0) - print(fidelities) + fidelities = do_teleportation(cfg, num_times=10, theta=0, phi=0) + print(fidelities) diff --git a/squidasm/run/stack/config.py b/squidasm/run/stack/config.py index 1ec04180..0087ee64 100644 --- a/squidasm/run/stack/config.py +++ b/squidasm/run/stack/config.py @@ -134,6 +134,16 @@ def from_file(cls, path: str) -> DepolariseLinkConfig: return _from_file(path, DepolariseLinkConfig) # type: ignore +class DepolariseAnyBellLinkConfig(BaseModel): + fidelity: float + prob_success: float + t_cycle: float + + @classmethod + def from_file(cls, path: str) -> DepolariseAnyBellLinkConfig: + return _from_file(path, DepolariseAnyBellLinkConfig) + + class NVLinkConfig(BaseModel): length_A: float length_B: float diff --git a/squidasm/run/stack/run.py b/squidasm/run/stack/run.py index 9770864d..7209ef73 100644 --- a/squidasm/run/stack/run.py +++ b/squidasm/run/stack/run.py @@ -4,6 +4,9 @@ from typing import Any, Dict, List import netsquid as ns +import numpy as np +from netsquid.qubits.ketstates import BellIndex +from netsquid.qubits.state_sampler import StateSampler from netsquid_magic.link_layer import ( MagicLinkLayerProtocol, MagicLinkLayerProtocolWithSignaling, @@ -12,13 +15,16 @@ from netsquid_magic.magic_distributor import ( DepolariseWithFailureMagicDistributor, DoubleClickMagicDistributor, + MagicDistributor, PerfectStateMagicDistributor, ) +from netsquid_magic.state_delivery_sampler import HeraldedStateDeliverySamplerFactory from netsquid_nv.magic_distributor import NVSingleClickMagicDistributor from netsquid_physlayer.heralded_connection import MiddleHeraldedConnection from squidasm.run.stack.build import build_generic_qdevice, build_nv_qdevice from squidasm.run.stack.config import ( + DepolariseAnyBellLinkConfig, DepolariseLinkConfig, GenericQDeviceConfig, HeraldedLinkConfig, @@ -32,6 +38,79 @@ from squidasm.sim.stack.stack import NodeStack, StackNetwork +class DepolariseWithFailureAnyBellStateSamplerFactory( + HeraldedStateDeliverySamplerFactory +): + def __init__(self): + super().__init__(func_delivery=self._delivery_func) + + @staticmethod + def _delivery_func(prob_max_mixed, prob_success, **kwargs): + bell00 = np.array( + [[0.5, 0, 0, 0.5], [0, 0, 0, 0], [0, 0, 0, 0], [0.5, 0, 0, 0.5]], + dtype=np.complex, + ) + bell01 = np.array( + [[0, 0, 0, 0], [0, 0.5, 0.5, 0], [0, 0.5, 0.5, 0], [0, 0, 0, 0]], + dtype=np.complex, + ) + bell10 = np.array( + [[0, 0, 0, 0], [0, 0.5, -0.5, 0], [0, -0.5, 0.5, 0], [0, 0, 0, 0]], + dtype=np.complex, + ) + bell11 = np.array( + [[0.5, 0, 0, -0.5], [0, 0, 0, 0], [0, 0, 0, 0], [-0.5, 0, 0, 0.5]], + dtype=np.complex, + ) + maximally_mixed = np.array( + [[0.25, 0, 0, 0], [0, 0.25, 0, 0], [0, 0, 0.25, 0], [0, 0, 0, 0.25]], + dtype=np.complex, + ) + bell00_noisy = (1 - prob_max_mixed) * bell00 + prob_max_mixed * maximally_mixed + bell01_noisy = (1 - prob_max_mixed) * bell01 + prob_max_mixed * maximally_mixed + bell10_noisy = (1 - prob_max_mixed) * bell10 + prob_max_mixed * maximally_mixed + bell11_noisy = (1 - prob_max_mixed) * bell11 + prob_max_mixed * maximally_mixed + return ( + StateSampler( + qreprs=[bell00_noisy, bell01_noisy, bell10_noisy, bell11_noisy], + probabilities=[0.25, 0.25, 0.25, 0.25], + labels=[ + BellIndex.PHI_PLUS, + BellIndex.PSI_PLUS, + BellIndex.PSI_MINUS, + BellIndex.PHI_MINUS, + ], + ), + prob_success, + ) + + +class DepolariseWithFailureAnyBellMagicDistributor(MagicDistributor): + def __init__(self, nodes, prob_max_mixed, prob_success, **kwargs): + self.prob_max_mixed = prob_max_mixed + self.prob_success = prob_success + super().__init__( + delivery_sampler_factory=DepolariseWithFailureAnyBellStateSamplerFactory(), + nodes=nodes, + **kwargs, + ) + + def add_delivery(self, memory_positions, **kwargs): + return super().add_delivery( + memory_positions=memory_positions, + prob_max_mixed=self.prob_max_mixed, + prob_success=self.prob_success, + **kwargs, + ) + + def get_bell_state(self, midpoint_outcome): + try: + status, label = midpoint_outcome + except ValueError: + raise ValueError("Unknown midpoint outcome {}".format(midpoint_outcome)) + return label + + def fidelity_to_prob_max_mixed(fid: float) -> float: return (1 - fid) * 4.0 / 3.0 @@ -80,6 +159,17 @@ def _setup_network(config: StackNetworkConfig) -> StackNetwork: prob_success=link_cfg.prob_success, t_cycle=link_cfg.t_cycle, ) + elif link.typ == "depolarise_any_bell": + link_cfg = link.cfg + if not isinstance(link_cfg, DepolariseAnyBellLinkConfig): + link_cfg = DepolariseAnyBellLinkConfig(**link.cfg) + prob_max_mixed = fidelity_to_prob_max_mixed(link_cfg.fidelity) + link_dist = DepolariseWithFailureAnyBellMagicDistributor( + nodes=[stack1.node, stack2.node], + prob_max_mixed=prob_max_mixed, + prob_success=link_cfg.prob_success, + t_cycle=link_cfg.t_cycle, + ) elif link.typ == "nv": link_cfg = link.cfg if not isinstance(link_cfg, NVLinkConfig): From 08f54b630b4368a3e95da92997b7e37c12abaaa2 Mon Sep 17 00:00:00 2001 From: Bart van der Vecht Date: Thu, 3 Mar 2022 18:20:09 +0100 Subject: [PATCH 5/7] Fix lint --- examples/stack/teleport/example_teleport.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/stack/teleport/example_teleport.py b/examples/stack/teleport/example_teleport.py index 5d3f4349..2862b371 100644 --- a/examples/stack/teleport/example_teleport.py +++ b/examples/stack/teleport/example_teleport.py @@ -4,7 +4,7 @@ from typing import Any, Dict, Generator, List import netsquid as ns -from netqasm.lang.ir import BreakpointAction, BreakpointRole +from netqasm.lang.ir import BreakpointAction from netqasm.sdk.qubit import Qubit from netqasm.sdk.toolbox import set_qubit_state from netsquid.qubits import operators, qubitapi From 2784f19bd5278006d3b24d33de75a86ded684e23 Mon Sep 17 00:00:00 2001 From: Bart van der Vecht Date: Fri, 25 Mar 2022 16:38:59 +0100 Subject: [PATCH 6/7] Add docstrings --- squidasm/run/stack/run.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/squidasm/run/stack/run.py b/squidasm/run/stack/run.py index 7209ef73..382a3b20 100644 --- a/squidasm/run/stack/run.py +++ b/squidasm/run/stack/run.py @@ -41,6 +41,7 @@ class DepolariseWithFailureAnyBellStateSamplerFactory( HeraldedStateDeliverySamplerFactory ): + """State sampler that samples any of the 4 Bell states with equal probablity.""" def __init__(self): super().__init__(func_delivery=self._delivery_func) @@ -86,6 +87,8 @@ def _delivery_func(prob_max_mixed, prob_success, **kwargs): class DepolariseWithFailureAnyBellMagicDistributor(MagicDistributor): + """Distributor that creates any of the 4 Bell states with equal probablity.""" + def __init__(self, nodes, prob_max_mixed, prob_success, **kwargs): self.prob_max_mixed = prob_max_mixed self.prob_success = prob_success From 1adf5f7e9fe79351fc72613bbf9d45688b5bf11a Mon Sep 17 00:00:00 2001 From: Bart van der Vecht Date: Fri, 25 Mar 2022 19:03:45 +0100 Subject: [PATCH 7/7] Fix lint --- squidasm/run/stack/run.py | 1 + 1 file changed, 1 insertion(+) diff --git a/squidasm/run/stack/run.py b/squidasm/run/stack/run.py index 382a3b20..fb51d665 100644 --- a/squidasm/run/stack/run.py +++ b/squidasm/run/stack/run.py @@ -42,6 +42,7 @@ class DepolariseWithFailureAnyBellStateSamplerFactory( HeraldedStateDeliverySamplerFactory ): """State sampler that samples any of the 4 Bell states with equal probablity.""" + def __init__(self): super().__init__(func_delivery=self._delivery_func)