Skip to content

Commit

Permalink
Revert PR 76 and PR 78 after discussion.
Browse files Browse the repository at this point in the history
  • Loading branch information
dieriver committed Nov 13, 2024
1 parent 3e94ebd commit 5e7b33e
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 92 deletions.
7 changes: 3 additions & 4 deletions netqasm/lang/encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class Metadata(ctypes.Structure):
# Num bits in register index
REG_INDEX_BITS = 4

COMMAND_BYTES = 8
COMMAND_BYTES = 7

PADDING_FIELD = "padding"

Expand Down Expand Up @@ -192,7 +192,7 @@ class RegRegImmImmCommand(Command):
)


class RegRegImm5Command(Command):
class RegRegImm4Command(Command):
_fields_ = add_padding(
[
("reg0", Register),
Expand All @@ -201,7 +201,6 @@ class RegRegImm5Command(Command):
("imm1", IMMEDIATE),
("imm2", IMMEDIATE),
("imm3", IMMEDIATE),
("imm4", IMMEDIATE),
]
)

Expand Down Expand Up @@ -351,7 +350,7 @@ class RecvEPRCommand(Command):
MeasCommand,
RegImmImmCommand,
RegRegImmImmCommand,
RegRegImm5Command,
RegRegImm4Command,
RegRegRegCommand,
ImmCommand,
ImmImmCommand,
Expand Down
38 changes: 10 additions & 28 deletions netqasm/lang/instr/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,9 @@ def _pretty_print(self):


@dataclass
class RegRegImm5Instruction(NetQASMInstruction):
class RegRegImm4Instruction(NetQASMInstruction):
"""
An instruction with 2 Register operands followed by 5 Immediate operands.
An instruction with 2 Register operands followed by 4 Immediate operands.
"""

reg0: Register = None # type: ignore
Expand All @@ -297,52 +297,39 @@ class RegRegImm5Instruction(NetQASMInstruction):
imm1: Immediate = None # type: ignore
imm2: Immediate = None # type: ignore
imm3: Immediate = None # type: ignore
imm4: Immediate = None # type: ignore

@property
def operands(self) -> List[Operand]:
return [
self.reg0,
self.reg1,
self.imm0,
self.imm1,
self.imm2,
self.imm3,
self.imm4,
]
return [self.reg0, self.reg1, self.imm0, self.imm1, self.imm2, self.imm3]

@classmethod
def deserialize_from(cls, raw: bytes):
c_struct = encoding.RegRegImm5Command.from_buffer_copy(raw)
c_struct = encoding.RegRegImm4Command.from_buffer_copy(raw)
assert c_struct.id == cls.id
reg0 = Register.from_raw(c_struct.reg0)
reg1 = Register.from_raw(c_struct.reg1)
imm0 = Immediate(value=c_struct.imm0)
imm1 = Immediate(value=c_struct.imm1)
imm2 = Immediate(value=c_struct.imm2)
imm3 = Immediate(value=c_struct.imm3)
imm4 = Immediate(value=c_struct.imm4)
return cls(
reg0=reg0, reg1=reg1, imm0=imm0, imm1=imm1, imm2=imm2, imm3=imm3, imm4=imm4
)
return cls(reg0=reg0, reg1=reg1, imm0=imm0, imm1=imm1, imm2=imm2, imm3=imm3)

def serialize(self) -> bytes:
c_struct = encoding.RegRegImm5Command(
c_struct = encoding.RegRegImm4Command(
id=self.id,
reg0=self.reg0.cstruct,
reg1=self.reg1.cstruct,
imm0=self.imm0.value,
imm1=self.imm1.value,
imm2=self.imm2.value,
imm3=self.imm3.value,
imm4=self.imm4.value,
)
return bytes(c_struct)

@classmethod
def from_operands(cls, operands: List[Union[Operand, int]]):
assert len(operands) == 7
reg0, reg1, imm0, imm1, imm2, imm3, imm4 = operands
assert len(operands) == 6
reg0, reg1, imm0, imm1, imm2, imm3 = operands
assert isinstance(reg0, Register)
assert isinstance(reg1, Register)
assert isinstance(imm0, int) or isinstance(imm0, Immediate)
Expand All @@ -357,17 +344,12 @@ def from_operands(cls, operands: List[Union[Operand, int]]):
assert isinstance(imm3, int) or isinstance(imm3, Immediate)
if isinstance(imm3, int):
imm3 = Immediate(value=imm3)
assert isinstance(imm4, int) or isinstance(imm4, Immediate)
if isinstance(imm4, int):
imm4 = Immediate(value=imm4)
return cls(
reg0=reg0, reg1=reg1, imm0=imm0, imm1=imm1, imm2=imm2, imm3=imm3, imm4=imm4
)
return cls(reg0=reg0, reg1=reg1, imm0=imm0, imm1=imm1, imm2=imm2, imm3=imm3)

def _pretty_print(self):
return (
f"{self.mnemonic} {str(self.reg0)} {str(self.reg1)} {str(self.imm0)} "
f"{str(self.imm1)} {str(self.imm2)} {str(self.imm3)} {str(self.imm4)}"
f"{str(self.imm1)} {str(self.imm2)} {str(self.imm3)}"
)


Expand Down
10 changes: 1 addition & 9 deletions netqasm/lang/instr/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ def creg(self, new_val: Register):


@dataclass
class MeasBasisInstruction(base.RegRegImm5Instruction):
class MeasBasisInstruction(base.RegRegImm4Instruction):
id: int = 41
mnemonic: str = "meas_basis"

Expand Down Expand Up @@ -510,14 +510,6 @@ def angle_denom(self):
def angle_denom(self, new_val: Immediate):
self.imm3 = new_val

@property
def rotation_axes(self):
return self.imm4

@rotation_axes.setter
def rotation_axes(self, new_val: Immediate):
self.imm4 = new_val


@dataclass
class CreateEPRInstruction(base.Reg5Instruction):
Expand Down
2 changes: 1 addition & 1 deletion netqasm/lang/parsing/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ def _make_args_operands(subroutine):
for index in [2, 3]:
_REPLACE_CONSTANTS_EXCEPTION.append((instr, index))

for index in [2, 3, 4, 5, 6]:
for index in [2, 3, 4, 5]:
_REPLACE_CONSTANTS_EXCEPTION.append((GenericInstr.MEAS_BASIS, index))


Expand Down
41 changes: 7 additions & 34 deletions netqasm/sdk/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
from netqasm.sdk.constraint import SdkConstraint, ValueAtMostConstraint
from netqasm.sdk.futures import Array, Future, RegFuture, T_CValue
from netqasm.sdk.memmgr import MemoryManager
from netqasm.sdk.qubit import FutureQubit, Qubit, QubitMeasureAxes, QubitMeasureBasis
from netqasm.sdk.qubit import FutureQubit, Qubit, QubitMeasureBasis
from netqasm.sdk.toolbox import get_angle_spec_from_float
from netqasm.sdk.transpile import NVSubroutineTranspiler, SubroutineTranspiler
from netqasm.typedefs import T_Cmd
Expand Down Expand Up @@ -1131,7 +1131,6 @@ def _build_cmds_measure(
inplace: bool,
basis: QubitMeasureBasis = QubitMeasureBasis.Z,
rotations: Optional[Tuple[int, int, int]] = None,
axes: QubitMeasureAxes = QubitMeasureAxes.XYX,
) -> None:
if isinstance(self._hardware_config, NVHardwareConfig):
# If compiling for NV, only virtual ID 0 can be used to measure a qubit.
Expand All @@ -1147,48 +1146,20 @@ def _build_cmds_measure(
denom = 4

if rotations is not None:
first, second, third = rotations
x1, y, x2 = rotations
meas_command = ICmd(
instruction=GenericInstr.MEAS_BASIS,
operands=[qubit_reg, outcome_reg, first, second, third, denom, axes],
operands=[qubit_reg, outcome_reg, x1, y, x2, denom],
)
elif basis == QubitMeasureBasis.X:
first, second, third = {
QubitMeasureAxes.XYX: (0, 24, 0),
QubitMeasureAxes.YZY: (24, 0, 0),
QubitMeasureAxes.ZXZ: (24, 24, 8),
}[axes]

meas_command = ICmd(
instruction=GenericInstr.MEAS_BASIS,
operands=[
qubit_reg,
outcome_reg,
first,
second,
third,
denom,
axes,
], # -pi/2 Y rotation
operands=[qubit_reg, outcome_reg, 0, 24, 0, denom], # -pi/2 Y rotation
)
elif basis == QubitMeasureBasis.Y:
first, second, third = {
QubitMeasureAxes.XYX: (8, 0, 0),
QubitMeasureAxes.YZY: (8, 24, 24),
QubitMeasureAxes.ZXZ: (0, 8, 0),
}[axes]

meas_command = ICmd(
instruction=GenericInstr.MEAS_BASIS,
operands=[
qubit_reg,
outcome_reg,
first,
second,
third,
denom,
axes,
], # pi/2 X rotation
operands=[qubit_reg, outcome_reg, 8, 0, 0, denom], # pi/2 X rotation
)
else:
meas_command = ICmd(
Expand Down Expand Up @@ -1928,6 +1899,8 @@ def sdk_epr_keep(
else:
wait_all = True

self._connection._logger.info(f"wait_all = {wait_all}")

if reset_results_array:
self._build_cmds_undefine_array(ent_results_array)

Expand Down
18 changes: 5 additions & 13 deletions netqasm/sdk/qubit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""
from __future__ import annotations

from enum import Enum, IntEnum, auto
from enum import Enum, auto
from typing import TYPE_CHECKING, Optional, Tuple, Union

from netqasm.lang.ir import GenericInstr
Expand All @@ -28,12 +28,6 @@ class QubitMeasureBasis(Enum):
Z = auto()


class QubitMeasureAxes(IntEnum):
XYX = 0
YZY = 1
ZXZ = 2


class Qubit:
"""Representation of a qubit that has been allocated in the quantum node.
Expand Down Expand Up @@ -180,7 +174,6 @@ def measure(
store_array: bool = True,
basis: QubitMeasureBasis = QubitMeasureBasis.Z,
basis_rotations: Optional[Tuple[int, int, int]] = None,
basis_rotation_axes: QubitMeasureAxes = QubitMeasureAxes.XYX,
) -> Union[Future, RegFuture]:
"""
Measure the qubit in the standard basis and get the measurement outcome.
Expand All @@ -196,12 +189,12 @@ def measure(
Default is Z. Ignored if `basis_rotations` is not None.
:param basis_rotations: rotations to apply before measuring in the
Z-basis. This can be used to specify arbitrary measurement bases.
The 3 values are interpreted as 3 rotation angles, around the axes specified by basis_rotation_axes.
Each angle is interpreted as a multiple of pi/16. For example, if `basis_rotations` is (8, 0, 0) and
basis_rotation_axes is XYX, an X-rotation is applied with angle 8*pi/16 = pi/2 radians, followed
The 3 values are interpreted as 3 rotation angles, for an X- Y-, and
another X-rotation, respectively. Each angle is interpreted as a
multiple of pi/16. For example, if `basis_rotations` is (8, 0, 0),
an X-rotation is applied with angle 8*pi/16 = pi/2 radians, followed
by a Y-rotation of angle 0 and an X-rotation of angle 0. Finally,
the measurement is done in the Z-basis.
:param basis_rotation_axes: Axes around which the rotations from basis_rotations should be performed, in order.
:return: the Future representing the measurement outcome. It is a
`Future` if
the result is in an array (default) or `RegFuture` if the result is in a
Expand All @@ -222,7 +215,6 @@ def measure(
inplace=inplace,
basis=basis,
rotations=basis_rotations,
axes=basis_rotation_axes,
)

if not inplace:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,7 @@ def test_measure_basis():

[meas_basis] = inspector.find_instr(GenericInstr.MEAS_BASIS)
# check if rotations are correct
assert meas_basis.operands[2:] == [0, 24, 0, 4, 0] # skip register operands
assert meas_basis.operands[2:] == [0, 24, 0, 4] # skip register operands

compiled_subroutine = conn.builder.subrt_compile_subroutine(presubroutine)
print(compiled_subroutine)
Expand All @@ -1062,7 +1062,7 @@ def test_measure_basis_rotation():

[meas_basis] = inspector.find_instr(GenericInstr.MEAS_BASIS)
# check if rotations are correct
assert meas_basis.operands[2:] == [3, 4, 5, 4, 0] # skip register operands
assert meas_basis.operands[2:] == [3, 4, 5, 4] # skip register operands

compiled_subroutine = conn.builder.subrt_compile_subroutine(presubroutine)
print(compiled_subroutine)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_parsing/test_binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def test_rotations():

def test_deserialize_subroutine():
metadata = b"\x00\x00\x00\x00"
cphase_gate = b"\x1F\x00\x00\x00\x00\x00\x00\x00"
cphase_gate = b"\x1F\x00\x00\x00\x00\x00\x00"
raw = bytes(metadata + cphase_gate)
print(raw)
subroutine = deserialize(raw)
Expand Down

0 comments on commit 5e7b33e

Please sign in to comment.