Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CQT-141-Qubit-declaration-added-to-simplest-circuit #349

Merged
merged 12 commits into from
Oct 25, 2024
2 changes: 2 additions & 0 deletions opensquirrel/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,11 @@ def replace(self, gate_generator: Callable[..., Gate], f: Callable[..., list[Gat
def export(self, fmt: ExportFormat | None = None) -> Any:
if fmt == ExportFormat.QUANTIFY_SCHEDULER:
from opensquirrel.exporter import quantify_scheduler_exporter

return quantify_scheduler_exporter.export(self)
if fmt == ExportFormat.CQASM_V1:
from opensquirrel.exporter import cqasmv1_exporter

return cqasmv1_exporter.export(self)
msg = "unknown exporter format"
raise ValueError(msg)
7 changes: 4 additions & 3 deletions opensquirrel/circuit_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,16 @@ def _check_generator_f_args(
"""
for i, par in enumerate(inspect.signature(generator_f).parameters.values()):
try:
expected_type = ANNOTATIONS_TO_TYPE_MAP[par.annotation] if isinstance(par.annotation, str) \
else par.annotation
expected_type = (
ANNOTATIONS_TO_TYPE_MAP[par.annotation] if isinstance(par.annotation, str) else par.annotation
)
except KeyError as e:
msg = "unknown annotation type"
raise TypeError(msg) from e

# fix for python39
try:
is_incorrect_type = not isinstance(args[i], expected_type) # type: ignore
is_incorrect_type = not isinstance(args[i], expected_type) # type: ignore
except TypeError:
# expected type is probably a Union, which works differently in python39
is_incorrect_type = not isinstance(args[i], expected_type.__args__) # type: ignore
Expand Down
5 changes: 2 additions & 3 deletions opensquirrel/exporter/cqasmv1_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ def visit_gate(self, gate: Gate) -> None:
raise UnsupportedGateError(gate)
params = []
if any(not isinstance(arg, Qubit) for arg in gate.arguments): # type: ignore[union-attr]
params = [
arg.accept(self) for arg in gate.arguments if not isinstance(arg, Qubit)] # type: ignore[union-attr]
params = [arg.accept(self) for arg in gate.arguments if not isinstance(arg, Qubit)] # type: ignore[union-attr]
qubit_args = (arg.accept(self) for arg in gate.arguments if isinstance(arg, Qubit)) # type: ignore[union-attr]
self.cqasmv1_string += "{} {}{}\n".format(
gate_name, ", ".join(qubit_args), ", " + ", ".join(params) if params else ""
Expand All @@ -61,4 +60,4 @@ def export(circuit: Circuit) -> str:

circuit.ir.accept(cqasmv1_creator)

return cqasmv1_creator.cqasmv1_string.rstrip() + "\n" # remove all trailing lines and leave only one
return cqasmv1_creator.cqasmv1_string.rstrip() + "\n" # remove all trailing lines and leave only one
16 changes: 3 additions & 13 deletions opensquirrel/exporter/quantify_scheduler_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,13 @@ def visit_bloch_sphere_rotation(self, g: BlochSphereRotation) -> None:
math.degrees(math.atan2(g.axis[1], g.axis[0])),
FIXED_POINT_DEG_PRECISION,
)
self.schedule.add(
quantify_scheduler_gates.Rxy(
theta=theta, phi=phi, qubit=self._get_qubit_string(g_qubit)
)
)
self.schedule.add(quantify_scheduler_gates.Rxy(theta=theta, phi=phi, qubit=self._get_qubit_string(g_qubit)))
return

if abs(g.axis[0]) < ATOL and abs(g.axis[1]) < ATOL:
# Rz rotation.
theta = round(math.degrees(g.angle), FIXED_POINT_DEG_PRECISION)
self.schedule.add(
quantify_scheduler_gates.Rz(
theta=theta, qubit=self._get_qubit_string(g.qubit)
)
)
self.schedule.add(quantify_scheduler_gates.Rz(theta=theta, qubit=self._get_qubit_string(g.qubit)))
return

raise UnsupportedGateError(g)
Expand Down Expand Up @@ -115,9 +107,7 @@ def visit_measure(self, g: Measure) -> None:
return

def visit_reset(self, g: Reset) -> Any:
self.schedule.add(
quantify_scheduler_gates.Reset(self._get_qubit_string(g.qubit))
)
self.schedule.add(quantify_scheduler_gates.Reset(self._get_qubit_string(g.qubit)))


def export(circuit: Circuit) -> tuple[quantify_scheduler.Schedule, list[tuple[Any, Any]]]:
Expand Down
13 changes: 12 additions & 1 deletion opensquirrel/writer/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@
from typing import SupportsInt

from opensquirrel.circuit import Circuit
from opensquirrel.ir import Bit, Comment, Float, Gate, Int, IRVisitor, Measure, Qubit, QubitLike, Reset
from opensquirrel.ir import (
Bit,
Comment,
Float,
Gate,
Int,
IRVisitor,
Measure,
Qubit,
QubitLike,
Reset,
)
from opensquirrel.register_manager import RegisterManager


Expand Down
58 changes: 44 additions & 14 deletions test/exporter/test_cqasmv1_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

def test_cqasm_v3_to_cqasm_v1() -> None:
cqasm_v3_string = Circuit.from_string(
"""
"""
version 3.0

qubit[2] q
Expand All @@ -22,9 +22,11 @@ def test_cqasm_v3_to_cqasm_v1() -> None:
Rx(5.123) q[0]
b = measure q
"""
)
)
cqasm_v1_string = cqasm_v3_string.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0

qubits 2

Expand All @@ -37,58 +39,74 @@ def test_cqasm_v3_to_cqasm_v1() -> None:
measure_z q[0]
measure_z q[1]
"""
)


def test_version_statement() -> None:
qc = Circuit.from_string("""version 3.0""")
cqasm_v1_string = qc.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0
"""
)


def test_qubit_statement() -> None:
builder = CircuitBuilder(3)
qc = builder.to_circuit()
cqasm_v1_string = qc.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0

qubits 3
"""
)


def test_circuit_to_string_after_circuit_modification() -> None:
builder = CircuitBuilder(3)
qc = builder.to_circuit()
cqasm_v1_string = qc.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0

qubits 3
"""
)

builder.H(Qubit(0))
builder.CNOT(Qubit(0), Qubit(1))
qc = builder.to_circuit()
cqasm_v1_string = qc.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0

qubits 3

h q[0]
cnot q[0], q[1]
"""
)


def test_float_precision() -> None:
builder = CircuitBuilder(3)
builder.Rx(Qubit(0), Float(1.6546514861321684321654))
qc = builder.to_circuit()
cqasm_v1_string = qc.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0

qubits 3

rx q[0], 1.6546515
"""
)


def test_measure() -> None:
Expand All @@ -97,13 +115,16 @@ def test_measure() -> None:
builder.measure(Qubit(0), Bit(0))
qc = builder.to_circuit()
cqasm_v1_string = qc.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0

qubits 1

h q[0]
measure_z q[0]
"""
)


def test_reset() -> None:
Expand All @@ -112,17 +133,20 @@ def test_reset() -> None:
builder.reset(Qubit(0))
qc = builder.to_circuit()
cqasm_v1_string = qc.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0

qubits 1

h q[0]
prep_z q[0]
"""
)


def test_all_supported_gates() -> None:
builder = CircuitBuilder(2,2)
builder = CircuitBuilder(2, 2)
builder.reset(Qubit(0)).reset(Qubit(1))
builder.I(Qubit(0)).X(Qubit(0)).Y(Qubit(0)).Z(Qubit(0))
builder.Rx(Qubit(0), Float(1.234)).Ry(Qubit(0), Float(-1.234)).Rz(Qubit(0), Float(1.234))
Expand All @@ -133,7 +157,9 @@ def test_all_supported_gates() -> None:
builder.measure(Qubit(0), Bit(0)).measure(Qubit(1), Bit(1))
qc = builder.to_circuit()
cqasm_v1_string = qc.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0

qubits 2

Expand All @@ -159,6 +185,7 @@ def test_all_supported_gates() -> None:
measure_z q[0]
measure_z q[1]
"""
)


@pytest.mark.parametrize(
Expand All @@ -167,7 +194,7 @@ def test_all_supported_gates() -> None:
BlochSphereRotation(Qubit(0), axis=(1, 1, 1), angle=1.23),
ControlledGate(Qubit(0), BlochSphereRotation(Qubit(1), axis=(1, 1, 1), angle=1.23)),
MatrixGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]), [Qubit(0), Qubit(1)]),
]
],
)
def test_anonymous_gates(gate: Gate) -> None:
builder = CircuitBuilder(2)
Expand All @@ -184,7 +211,9 @@ def test_comment() -> None:
builder.Rx(Qubit(0), Float(1.234))
qc = builder.to_circuit()
cqasm_v1_string = qc.export(fmt=ExportFormat.CQASM_V1)
assert cqasm_v1_string == """version 1.0
assert (
cqasm_v1_string
== """version 1.0

qubits 3

Expand All @@ -194,3 +223,4 @@ def test_comment() -> None:

rx q[0], 1.234
"""
)
Loading