diff --git a/CHANGELOG.md b/CHANGELOG.md index 074e140..311f38e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2024-12-16 (0.13.4) +------------------ +- Bugfix for simulation time not resetting between different calls of the `squidasm.run.stack.run.run` method +- Add support for S and T gates in generic qdevice + 2024-11-18 (0.13.3) ------------------ - Relax scipy requirement to from <1.9 to <2.0 diff --git a/squidasm/run/stack/run.py b/squidasm/run/stack/run.py index 4b075c0..dfd9b0c 100644 --- a/squidasm/run/stack/run.py +++ b/squidasm/run/stack/run.py @@ -23,6 +23,7 @@ def _setup_network(config: NetworkConfig) -> StackNetwork: NetSquidContext.reset() + ns.sim_reset() builder = create_stack_network_builder() network = builder.build(config) diff --git a/squidasm/sim/stack/processor.py b/squidasm/sim/stack/processor.py index 9a3d66b..3180b59 100644 --- a/squidasm/sim/stack/processor.py +++ b/squidasm/sim/stack/processor.py @@ -21,6 +21,8 @@ INSTR_ROT_X, INSTR_ROT_Y, INSTR_ROT_Z, + INSTR_S, + INSTR_T, INSTR_X, INSTR_Y, INSTR_Z, @@ -684,6 +686,14 @@ def _interpret_single_qubit_instr( prog = QuantumProgram() prog.apply(INSTR_K, qubit_indices=[phys_id]) yield self.qdevice.execute_program(prog) + elif isinstance(instr, vanilla.GateSInstruction): + prog = QuantumProgram() + prog.apply(INSTR_S, qubit_indices=[phys_id]) + yield self.qdevice.execute_program(prog) + elif isinstance(instr, vanilla.GateTInstruction): + prog = QuantumProgram() + prog.apply(INSTR_T, qubit_indices=[phys_id]) + yield self.qdevice.execute_program(prog) else: raise RuntimeError(f"Unsupported instruction {instr}") diff --git a/tests/stack/test_single_node.py b/tests/stack/test_single_node.py index 2816154..516ace2 100644 --- a/tests/stack/test_single_node.py +++ b/tests/stack/test_single_node.py @@ -7,6 +7,7 @@ from netqasm.lang.parsing import parse_text_subroutine from netsquid.components import QuantumProcessor from netsquid.qubits import ketstates, qubitapi +from netsquid_netbuilder.modules.qdevices.generic import GenericQDeviceConfig from netsquid_netbuilder.modules.qdevices.nv import NVQDeviceConfig from netsquid_netbuilder.util.network_generation import create_single_node_network @@ -16,7 +17,7 @@ from squidasm.sim.stack.host import Host -class TestSingleNode(unittest.TestCase): +class TestSingleNodeNV(unittest.TestCase): def setUp(self) -> None: ns.sim_reset() config = NVQDeviceConfig.perfect_config() @@ -155,5 +156,57 @@ def check_qmem(qdevice: QuantumProcessor) -> None: self._check_qmem = check_qmem +class TestSingleNodeGeneric(unittest.TestCase): + def setUp(self) -> None: + ns.sim_reset() + config = GenericQDeviceConfig.perfect_config() + network_cfg = create_single_node_network( + qdevice_typ="generic", qdevice_cfg=config + ) + self.network = _setup_network(network_cfg) + self._node = self.network.stacks["Alice"] + + self._host: Optional[Type[Host]] = None + + def tearDown(self) -> None: + self._node.subprotocols[f"{self._node.name}_host_protocol"] = self._host( + self._node.host_comp + ) + _run(self.network) + + def test_quantum_instructions(self): + SUBRT_1 = """ + # NETQASM 1.0 + # APPID 0 + set Q0 0 + qalloc Q0 + init Q0 + x Q0 + y Q0 + z Q0 + h Q0 + s Q0 + k Q0 + t Q0 + rot_x Q0 16 4 + rot_y Q0 8 1 + rot_z Q0 16 2 + """ + + class TestHost(Host): + def run(self) -> Generator[EventExpression, None, None]: + self.send_qnos_msg(bytes(InitNewAppMessage(max_qubits=2))) + app_id = yield from self.receive_qnos_msg() + assert app_id == 0 + subroutine = parse_text_subroutine(SUBRT_1) + subroutine.app_id = app_id + self.send_qnos_msg(bytes(SubroutineMessage(subroutine))) + app_mem = yield from self.receive_qnos_msg() + assert isinstance(app_mem, AppMemory) + assert app_mem.get_reg_value("Q0") == 0 + + self._host = TestHost + + if __name__ == "__main__": unittest.main() diff --git a/tests/stack/test_stack_run.py b/tests/stack/test_stack_run.py new file mode 100644 index 0000000..60b4610 --- /dev/null +++ b/tests/stack/test_stack_run.py @@ -0,0 +1,104 @@ +import unittest + +import netsquid as ns +from netqasm.sdk import Qubit +from netsquid_netbuilder.modules.qdevices.generic import GenericQDeviceConfig +from netsquid_netbuilder.modules.qlinks.depolarise import DepolariseQLinkConfig +from netsquid_netbuilder.util.network_generation import create_2_node_network + +from squidasm.run.stack.run import run +from squidasm.sim.stack.program import Program, ProgramContext, ProgramMeta +from squidasm.util.routines import teleport_recv, teleport_send + + +class TeleportSenderProgram(Program): + def __init__(self, peer_name: str): + self.peer_name = peer_name + self.complete = False + + @property + def meta(self) -> ProgramMeta: + return ProgramMeta( + name="sender_program", + csockets=[self.peer_name], + epr_sockets=[self.peer_name], + max_qubits=2, + ) + + def run(self, context: ProgramContext): + q = Qubit(context.connection) + yield from teleport_send(q, context, peer_name=self.peer_name) + self.complete = True + + +class TeleportReceiverProgram(Program): + def __init__(self, peer_name: str): + self.peer_name = peer_name + self.complete = False + + @property + def meta(self) -> ProgramMeta: + return ProgramMeta( + name="receiver_program", + csockets=[self.peer_name], + epr_sockets=[self.peer_name], + max_qubits=2, + ) + + def run(self, context: ProgramContext): + yield from teleport_recv(context, peer_name=self.peer_name) + self.complete = True + + +class TestRun(unittest.TestCase): + def test_run(self): + t_cycle = 100 + + network_cfg = create_2_node_network( + qlink_typ="depolarise", + qlink_cfg=DepolariseQLinkConfig( + fidelity=1, prob_success=1, t_cycle=t_cycle + ), + qdevice_typ="generic", + qdevice_cfg=GenericQDeviceConfig.perfect_config(), + ) + send_prot = TeleportSenderProgram(peer_name="Bob") + recv_prot = TeleportReceiverProgram(peer_name="Alice") + + run(network_cfg, programs={"Alice": send_prot, "Bob": recv_prot}) + + assert send_prot.complete + assert recv_prot.complete + self.assertAlmostEqual(ns.sim_time(), t_cycle, delta=t_cycle * 0.01) + + def test_run_twice(self) -> None: + t_cycle = 100 + + network_cfg = create_2_node_network( + qlink_typ="depolarise", + qlink_cfg=DepolariseQLinkConfig( + fidelity=1, prob_success=1, t_cycle=t_cycle + ), + qdevice_typ="generic", + qdevice_cfg=GenericQDeviceConfig.perfect_config(), + ) + send_prot = TeleportSenderProgram(peer_name="Bob") + recv_prot = TeleportReceiverProgram(peer_name="Alice") + + run(network_cfg, programs={"Alice": send_prot, "Bob": recv_prot}) + + self.assertAlmostEqual(ns.sim_time(), t_cycle, delta=t_cycle * 0.01) + assert send_prot.complete + assert recv_prot.complete + send_prot.complete = False + recv_prot.complete = False + + run(network_cfg, programs={"Alice": send_prot, "Bob": recv_prot}) + + self.assertAlmostEqual(ns.sim_time(), t_cycle, delta=t_cycle * 0.01) + assert send_prot.complete + assert recv_prot.complete + + +if __name__ == "__main__": + unittest.main()