Skip to content

Commit

Permalink
Merge pull request #118 from CQCL/add-barrier
Browse files Browse the repository at this point in the history
  • Loading branch information
qartik authored Feb 1, 2024
2 parents a18060f + 787239c commit 6187073
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 74 deletions.
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repos:
- id: debug-statements

- repo: https://github.com/crate-ci/typos
rev: v1.17.2
rev: v1.18.0
hooks:
- id: typos

Expand Down Expand Up @@ -47,6 +47,7 @@ repos:
pytest,
pytket-quantinuum,
pytket,
quantum-pecos>=0.5.0.dev8,
types-setuptools,
wasmtime,
]
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ classifiers = [
]
dynamic = ["version"]
dependencies = [
"phir>=0.2.1",
"phir>=0.3.0",
"pytket>=1.21.0",
"wasmtime>=15.0.0",
]

[project.optional-dependencies]
docs = ["sphinx", "pydata_sphinx_theme"]
phirc = ["projectq", "quantum-pecos>=0.5.0.dev4"]
phirc = ["projectq", "quantum-pecos>=0.5.0.dev8"]
tests = ["pytest"]

[project.scripts]
Expand Down
6 changes: 3 additions & 3 deletions pytket/phir/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
from argparse import ArgumentParser
from importlib.metadata import version

from pecos.engines.hybrid_engine import HybridEngine # type:ignore [import-not-found]
from pecos.foreign_objects.wasmtime import WasmtimeObj # type:ignore [import-not-found]
from pecos.engines.hybrid_engine import HybridEngine
from pecos.foreign_objects.wasmtime import WasmtimeObj

from pytket.qasm.qasm import (
circuit_from_qasm,
Expand Down Expand Up @@ -80,6 +80,6 @@ def main() -> None:
HybridEngine(qsim="state-vector").run(
program=phir,
shots=10,
foreign_object=wasm_pecos_obj if args.wasm_file else None,
foreign_object=wasm_pecos_obj if args.wasm_file else None, # type: ignore[arg-type]
)
)
4 changes: 1 addition & 3 deletions pytket/phir/phirgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,7 @@ def convert_subcmd(op: tk.Op, cmd: tk.Command) -> JsonDict | None:
out: JsonDict | None = None
match op: # non-quantum op
case tk.BarrierOp():
# TODO(kartik): confirm with Ciaran/spec
# https://github.com/CQCL/phir/blob/main/spec.md
logger.debug("Skipping Barrier instruction")
out = {"meta": "barrier", "args": [arg_to_bit(qbit) for qbit in cmd.qubits]}

case tk.Conditional(): # where the condition is equality check
out = {
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
build==1.0.3
mypy==1.8.0
networkx==2.8.8
phir==0.2.1
phir==0.3.0
pre-commit==3.6.0
pydata_sphinx_theme==0.15.2
pytest==8.0.0
pytket==1.24.0
ruff==0.1.14
ruff==0.1.15
setuptools_scm==8.0.4
sphinx==7.2.6
wasmtime==17.0.0
Expand Down
11 changes: 11 additions & 0 deletions tests/data/qasm/cond_barrier.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
OPENQASM 2.0;
include "qelib1.inc";

qreg q[2];
creg m[2];

h q[0];
if(m==0) barrier q[0], q[1];
CX q[0], q[1];

measure q -> m;
15 changes: 11 additions & 4 deletions tests/test_parallelization.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,12 @@ def test_single_qubit_circuit_with_parallel() -> None:
# for example Ry gets converted to R1XY
# compare angles and args instead

ops = (3, 5, 7, 11, 13, 15)
ops = (3, 5, 7, 12, 14, 16)

assert phir_with_parallel_phirgen["ops"][9] == {
"meta": "barrier",
"args": [["q", 0]],
}

for i, qop in zip(ops, ("R1XY", "RZ", "R1XY", "R1XY", "RZ", "R1XY"), strict=True):
assert phir_with_parallel_phirgen["ops"][i]["qop"] == qop
Expand All @@ -108,18 +113,20 @@ def test_single_qubit_circuit_with_parallel() -> None:
def test_two_qubit_exec_order_preserved() -> None:
"""Test that the order of gating in preserved in a 2 qubit circuit."""
phir = get_phir_json(QasmFile.exec_order_two_qubits, rebase=True)

assert phir["ops"][16] == {"meta": "barrier", "args": [["q", 0], ["q", 1]]}
# for this test, verify that the RX gates are NOT parallelized
# in the following section of the qasm file (lines 11-13):
# rx(3.5*pi) q[0];
assert phir["ops"][18] == {
assert phir["ops"][19] == {
"qop": "R1XY",
"angles": [[3.5, 0.0], "pi"],
"args": [["q", 0]],
}
# rz(3.5*pi) q[1];
assert phir["ops"][20] == {"qop": "RZ", "angles": [[3.5], "pi"], "args": [["q", 1]]}
assert phir["ops"][21] == {"qop": "RZ", "angles": [[3.5], "pi"], "args": [["q", 1]]}
# rx(1.0*pi) q[1];
assert phir["ops"][24] == {
assert phir["ops"][25] == {
"qop": "R1XY",
"angles": [[1.0, 0.0], "pi"],
"args": [["q", 1]],
Expand Down
133 changes: 74 additions & 59 deletions tests/test_phirgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,63 +13,78 @@
from pytket.circuit import Circuit
from pytket.phir.api import pytket_to_phir

from .test_utils import QasmFile, get_qasm_as_circuit

class TestPhirGen:
def test_classicalexpbox(self) -> None:
"""From https://github.com/CQCL/pytket-phir/issues/86 ."""
circ = Circuit(1)
a = circ.add_c_register("a", 2)
b = circ.add_c_register("b", 2)
c = circ.add_c_register("c", 3)
circ.add_classicalexpbox_register(a + b, c.to_list())

phir = json.loads(pytket_to_phir(circ))
assert phir["ops"][4] == {
"cop": "=",
"returns": ["c"],
"args": [{"cop": "+", "args": ["a", "b"]}],
}

def test_nested_arith(self) -> None:
"""From https://github.com/CQCL/pytket-phir/issues/87 ."""
circ = Circuit(1)
a = circ.add_c_register("a", 2)
b = circ.add_c_register("b", 2)
c = circ.add_c_register("c", 3)
circ.add_classicalexpbox_register(a + b // c, c.to_list())

phir = json.loads(pytket_to_phir(circ))
assert phir["ops"][4] == {
"cop": "=",
"returns": ["c"],
"args": [{"cop": "+", "args": ["a", {"cop": "/", "args": ["b", "c"]}]}],
}

def test_arith_with_int(self) -> None:
"""From https://github.com/CQCL/pytket-phir/issues/88 ."""
circ = Circuit(1)
a = circ.add_c_register("a", 2)
circ.add_classicalexpbox_register(a << 1, a.to_list())

phir = json.loads(pytket_to_phir(circ))
assert phir["ops"][2] == {
"cop": "=",
"returns": ["a"],
"args": [{"cop": "<<", "args": ["a", 1]}],
}

def test_bitwise_ops(self) -> None:
"""From https://github.com/CQCL/pytket-phir/issues/91 ."""
circ = Circuit(1)
a = circ.add_c_register("a", 2)
b = circ.add_c_register("b", 2)
c = circ.add_c_register("c", 1)
expr = a[0] ^ b[0]
circ.add_classicalexpbox_bit(expr, [c[0]])

phir = json.loads(pytket_to_phir(circ))
assert phir["ops"][4] == {
"cop": "=",
"returns": [["c", 0]],
"args": [{"cop": "^", "args": [["a", 0], ["b", 0]]}],
}

def test_classicalexpbox() -> None:
"""From https://github.com/CQCL/pytket-phir/issues/86 ."""
circ = Circuit(1)
a = circ.add_c_register("a", 2)
b = circ.add_c_register("b", 2)
c = circ.add_c_register("c", 3)
circ.add_classicalexpbox_register(a + b, c.to_list())

phir = json.loads(pytket_to_phir(circ))
assert phir["ops"][4] == {
"cop": "=",
"returns": ["c"],
"args": [{"cop": "+", "args": ["a", "b"]}],
}


def test_nested_arith() -> None:
"""From https://github.com/CQCL/pytket-phir/issues/87 ."""
circ = Circuit(1)
a = circ.add_c_register("a", 2)
b = circ.add_c_register("b", 2)
c = circ.add_c_register("c", 3)
circ.add_classicalexpbox_register(a + b // c, c.to_list())

phir = json.loads(pytket_to_phir(circ))
assert phir["ops"][4] == {
"cop": "=",
"returns": ["c"],
"args": [{"cop": "+", "args": ["a", {"cop": "/", "args": ["b", "c"]}]}],
}


def test_arith_with_int() -> None:
"""From https://github.com/CQCL/pytket-phir/issues/88 ."""
circ = Circuit(1)
a = circ.add_c_register("a", 2)
circ.add_classicalexpbox_register(a << 1, a.to_list())

phir = json.loads(pytket_to_phir(circ))
assert phir["ops"][2] == {
"cop": "=",
"returns": ["a"],
"args": [{"cop": "<<", "args": ["a", 1]}],
}


def test_bitwise_ops() -> None:
"""From https://github.com/CQCL/pytket-phir/issues/91 ."""
circ = Circuit(1)
a = circ.add_c_register("a", 2)
b = circ.add_c_register("b", 2)
c = circ.add_c_register("c", 1)
expr = a[0] ^ b[0]
circ.add_classicalexpbox_bit(expr, [c[0]])

phir = json.loads(pytket_to_phir(circ))
assert phir["ops"][4] == {
"cop": "=",
"returns": [["c", 0]],
"args": [{"cop": "^", "args": [["a", 0], ["b", 0]]}],
}


def test_conditional_barrier() -> None:
"""From https://github.com/CQCL/pytket-phir/issues/119 ."""
circ = get_qasm_as_circuit(QasmFile.cond_barrier)
phir = json.loads(pytket_to_phir(circ))
assert phir["ops"][5] == {
"block": "if",
"condition": {"cop": "==", "args": ["m", 0]},
"true_branch": [{"meta": "barrier", "args": [["q", 0], ["q", 1]]}],
}
1 change: 1 addition & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class QasmFile(Enum):
classical_ordering = auto()
single_qubit_parallel_test = auto()
exec_order_two_qubits = auto()
cond_barrier = auto()
arbitrary_qreg_names = auto()


Expand Down

0 comments on commit 6187073

Please sign in to comment.