|
4 | 4 | from typing import TYPE_CHECKING, Dict, Generator, Optional, Union |
5 | 5 |
|
6 | 6 | import netsquid as ns |
7 | | -from netqasm.lang.instr import NetQASMInstruction, core, nv, vanilla |
| 7 | +from netqasm.lang.instr import ( |
| 8 | + NetQASMInstruction, |
| 9 | + core, |
| 10 | + nv, |
| 11 | + trapped_ion_individual, |
| 12 | + vanilla, |
| 13 | +) |
8 | 14 | from netqasm.lang.operand import Register |
9 | 15 | from netqasm.lang.subroutine import Subroutine |
10 | 16 | from netsquid.components import QuantumProcessor |
|
31 | 37 | from netsquid.components.qprogram import QuantumProgram |
32 | 38 | from netsquid.nodes import Node |
33 | 39 | from netsquid.qubits import qubitapi |
| 40 | +from netsquid_trappedions.instructions import INSTR_MS_INDIVIDUAL |
34 | 41 |
|
35 | 42 | from pydynaa import EventExpression |
36 | 43 | from squidasm.sim.stack.common import ( |
@@ -883,3 +890,78 @@ def _interpret_controlled_rotation_instr( |
883 | 890 | yield from self._do_controlled_rotation(app_id, instr, INSTR_CYDIR) |
884 | 891 | else: |
885 | 892 | raise RuntimeError(f"Unsupported instruction {instr}") |
| 893 | + |
| 894 | + |
| 895 | +class TIProcessor(Processor): |
| 896 | + """A `Processor` for nodes with a TI hardware.""" |
| 897 | + |
| 898 | + def _interpret_qalloc(self, app_id: int, instr: core.QAllocInstruction) -> None: |
| 899 | + app_mem = self.app_memories[app_id] |
| 900 | + |
| 901 | + virt_id = app_mem.get_reg_value(instr.reg) |
| 902 | + if virt_id is None: |
| 903 | + raise RuntimeError(f"qubit address in register {instr.reg} is not defined") |
| 904 | + self._logger.debug(f"Allocating qubit with virtual ID {virt_id}") |
| 905 | + |
| 906 | + # All qubits are communication qubits in TI |
| 907 | + phys_id = self.physical_memory.allocate_comm() |
| 908 | + app_mem.map_virt_id(virt_id, phys_id) |
| 909 | + |
| 910 | + def _interpret_init( |
| 911 | + self, app_id: int, instr: core.InitInstruction |
| 912 | + ) -> Generator[EventExpression, None, None]: |
| 913 | + app_mem = self.app_memories[app_id] |
| 914 | + virt_id = app_mem.get_reg_value(instr.reg) |
| 915 | + phys_id = app_mem.phys_id_for(virt_id) |
| 916 | + self._logger.debug( |
| 917 | + f"Performing {instr} on virtual qubit " |
| 918 | + f"{virt_id} (physical ID: {phys_id})" |
| 919 | + ) |
| 920 | + prog = QuantumProgram() |
| 921 | + prog.apply(INSTR_INIT, qubit_indices=[phys_id]) |
| 922 | + yield self.qdevice.execute_program(prog) |
| 923 | + |
| 924 | + def _interpret_meas( |
| 925 | + self, app_id: int, instr: core.MeasInstruction |
| 926 | + ) -> Generator[EventExpression, None, None]: |
| 927 | + app_mem = self.app_memories[app_id] |
| 928 | + virt_id = app_mem.get_reg_value(instr.qreg) |
| 929 | + phys_id = app_mem.phys_id_for(virt_id) |
| 930 | + |
| 931 | + self._logger.debug( |
| 932 | + f"Measuring qubit {virt_id} (physical ID: {phys_id}), " |
| 933 | + f"placing the outcome in register {instr.creg}" |
| 934 | + ) |
| 935 | + |
| 936 | + prog = QuantumProgram() |
| 937 | + prog.apply(INSTR_MEASURE, qubit_indices=[phys_id]) |
| 938 | + yield self.qdevice.execute_program(prog) |
| 939 | + outcome: int = prog.output["last"][0] |
| 940 | + app_mem.set_reg_value(instr.creg, outcome) |
| 941 | + |
| 942 | + def _interpret_single_rotation_instr( |
| 943 | + self, app_id: int, instr: trapped_ion_individual.RotXInstruction |
| 944 | + ) -> Generator[EventExpression, None, None]: |
| 945 | + if isinstance(instr, trapped_ion_individual.RotXInstruction): |
| 946 | + yield from self._do_single_rotation(app_id, instr, INSTR_ROT_X) |
| 947 | + elif isinstance(instr, trapped_ion_individual.RotYInstruction): |
| 948 | + yield from self._do_single_rotation(app_id, instr, INSTR_ROT_Y) |
| 949 | + elif isinstance(instr, trapped_ion_individual.RotZInstruction): |
| 950 | + yield from self._do_single_rotation(app_id, instr, INSTR_ROT_Z) |
| 951 | + else: |
| 952 | + raise RuntimeError(f"Unsupported instruction {instr}") |
| 953 | + |
| 954 | + def _interpret_two_qubit_instr( |
| 955 | + self, app_id: int, instr: core.TwoQubitRotationInstruction |
| 956 | + ) -> Generator[EventExpression, None, None]: |
| 957 | + assert isinstance(instr, trapped_ion_individual.MSGateInstruction) |
| 958 | + |
| 959 | + app_mem = self.app_memories[app_id] |
| 960 | + virt_id0 = app_mem.get_reg_value(instr.reg0) |
| 961 | + phys_id0 = app_mem.phys_id_for(virt_id0) |
| 962 | + virt_id1 = app_mem.get_reg_value(instr.reg1) |
| 963 | + phys_id1 = app_mem.phys_id_for(virt_id1) |
| 964 | + |
| 965 | + prog = QuantumProgram() |
| 966 | + prog.apply(INSTR_MS_INDIVIDUAL, qubit_indices=[phys_id0, phys_id1]) |
| 967 | + yield self.qdevice.execute_program(prog) |
0 commit comments