From 05a18ce3b1fb788d4f080b7cdb2df07e76dc2406 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 23 Aug 2024 06:45:24 -0500 Subject: [PATCH 1/8] test: add test for issue 215 --- tests/test_phirgen.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_phirgen.py b/tests/test_phirgen.py index bbaed38..75d9d93 100644 --- a/tests/test_phirgen.py +++ b/tests/test_phirgen.py @@ -10,6 +10,8 @@ import json +from pecos.engines.hybrid_engine import HybridEngine + from pytket.circuit import Bit, Circuit from pytket.circuit.logic_exp import BitWiseOp, create_bit_logic_exp from pytket.phir.api import pytket_to_phir @@ -463,3 +465,12 @@ def test_nullary_ops() -> None: "cop": "==", "args": [["tk_SCRATCH_BIT", 1], 1], # evals to False } + + +def test_condition_multiple_bits() -> None: + """From https://github.com/CQCL/pytket-phir/issues/215 .""" + n_bits = 3 + c = Circuit(1, n_bits) + c.Rz(0.5, 0, condition_bits=list(range(n_bits)), condition_value=0) + phir = pytket_to_phir(c) + HybridEngine(qsim="state-vector").run(program=phir) From a8f56a5eaca4cb332253f16abec2c70df87e78b3 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 4 Sep 2024 14:46:04 -0500 Subject: [PATCH 2/8] build: require pecos for CI --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 0649295..26d6547 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,7 @@ pre-commit==3.8.0 pydata_sphinx_theme==0.15.4 pytest==8.3.2 pytket==1.32.0 +quantum-pecos==v0.6.0.dev4 ruff==0.6.4 setuptools_scm==8.1.0 sphinx==8.0.2 From 9fc484ea9f247c0746b5f6792446c92d9d25093e Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 4 Sep 2024 14:50:18 -0500 Subject: [PATCH 3/8] docs: provide maintainer email ID Closes: #142 --- pyproject.toml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0280127..7647bb5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,8 +8,11 @@ name = "pytket-phir" description = "A circuit analyzer and translator from pytket to PHIR" readme = "README.md" requires-python = ">=3.10, <3.13" -license = {file = "LICENSE"} -authors = [{name = "Quantinuum"}] +license = { file = "LICENSE" } +authors = [{ name = "Quantinuum" }] +maintainers = [ + { name = "Kartik Singhal", email = "Kartik.Singhal@quantinuum.com" }, +] classifiers = [ "Environment :: Console", @@ -50,9 +53,7 @@ where = ["."] [tool.pytest.ini_options] addopts = "-s -vv" -pythonpath = [ - "." -] +pythonpath = ["."] log_cli = true log_cli_level = "INFO" log_level = "DEBUG" From f0ea2e96ec2c538eb3e348efb0b0009e1cb86a29 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Tue, 10 Sep 2024 14:23:59 -0500 Subject: [PATCH 4/8] chore: update deps --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 26d6547..5d083f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ networkx<3 phir==0.3.3 pre-commit==3.8.0 pydata_sphinx_theme==0.15.4 -pytest==8.3.2 +pytest==8.3.3 pytket==1.32.0 quantum-pecos==v0.6.0.dev4 ruff==0.6.4 From 0d7815c3e7a5af8328180db5d5c77ec4a09f3ae9 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Tue, 10 Sep 2024 15:58:09 -0500 Subject: [PATCH 5/8] fix: generate nested multi-bit conditions for pecos support --- pytket/phir/phirgen.py | 30 +++++++++++++++++++++--------- requirements.txt | 2 +- tests/test_phirgen.py | 4 ++-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/pytket/phir/phirgen.py b/pytket/phir/phirgen.py index 5cfb4e0..1d6eca7 100644 --- a/pytket/phir/phirgen.py +++ b/pytket/phir/phirgen.py @@ -11,6 +11,7 @@ import json import logging import sys +from collections import deque from copy import deepcopy from importlib.metadata import version from typing import TYPE_CHECKING, Any, TypeAlias @@ -356,15 +357,26 @@ def convert_classicalevalop(op: tk.ClassicalEvalOp, cmd: tk.Command) -> JsonDict def multi_bit_condition(args: "list[UnitID]", value: int) -> JsonDict: """Construct bitwise condition.""" - return { - "cop": "&", - "args": [ - {"cop": "==", "args": [arg_to_bit(arg), bval]} - for (arg, bval) in zip( - args[::-1], map(int, f"{value:0{len(args)}b}"), strict=True - ) - ], - } + val_bits = deque(map(int, f"{value:0{len(args)}b}")) + + def nested_cop(cop: str, args: "deque[UnitID]", val_bits: deque[int]) -> JsonDict: + if len(args) == 2: # noqa: PLR2004 + return { + "cop": cop, + "args": [ + {"cop": "==", "args": [arg_to_bit(args.popleft()), val_bits.pop()]}, + {"cop": "==", "args": [arg_to_bit(args.popleft()), val_bits.pop()]}, + ], + } + return { + "cop": cop, + "args": [ + {"cop": "==", "args": [arg_to_bit(args.popleft()), val_bits.pop()]}, + nested_cop(cop, args, val_bits), + ], + } + + return nested_cop("&", deque(args), val_bits) def convert_subcmd(op: tk.Op, cmd: tk.Command) -> JsonDict | None: # noqa: PLR0912 diff --git a/requirements.txt b/requirements.txt index 5d083f1..48fe235 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ pre-commit==3.8.0 pydata_sphinx_theme==0.15.4 pytest==8.3.3 pytket==1.32.0 -quantum-pecos==v0.6.0.dev4 +quantum-pecos[simulators]==v0.6.0.dev4 ruff==0.6.4 setuptools_scm==8.1.0 sphinx==8.0.2 diff --git a/tests/test_phirgen.py b/tests/test_phirgen.py index 75d9d93..c7a33c2 100644 --- a/tests/test_phirgen.py +++ b/tests/test_phirgen.py @@ -96,8 +96,8 @@ def test_pytket_classical_only() -> None: "condition": { "cop": "&", "args": [ - {"cop": "==", "args": [["b", 2], 1]}, {"cop": "==", "args": [["b", 1], 0]}, + {"cop": "==", "args": [["b", 2], 1]}, ], }, "true_branch": [ @@ -179,8 +179,8 @@ def test_conditional_barrier() -> None: "condition": { "cop": "&", "args": [ - {"cop": "==", "args": [["m", 1], 0]}, {"cop": "==", "args": [["m", 0], 0]}, + {"cop": "==", "args": [["m", 1], 0]}, ], }, "true_branch": [{"meta": "barrier", "args": [["q", 0], ["q", 1]]}], From a64cec795cafd1b1c1c57f848308800c35d97c97 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Tue, 10 Sep 2024 16:19:31 -0500 Subject: [PATCH 6/8] test: remove dependency on pecos and more granular test --- requirements.txt | 1 - tests/test_phirgen.py | 22 +++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index 48fe235..2e682ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,6 @@ pre-commit==3.8.0 pydata_sphinx_theme==0.15.4 pytest==8.3.3 pytket==1.32.0 -quantum-pecos[simulators]==v0.6.0.dev4 ruff==0.6.4 setuptools_scm==8.1.0 sphinx==8.0.2 diff --git a/tests/test_phirgen.py b/tests/test_phirgen.py index c7a33c2..d4a28b5 100644 --- a/tests/test_phirgen.py +++ b/tests/test_phirgen.py @@ -10,8 +10,6 @@ import json -from pecos.engines.hybrid_engine import HybridEngine - from pytket.circuit import Bit, Circuit from pytket.circuit.logic_exp import BitWiseOp, create_bit_logic_exp from pytket.phir.api import pytket_to_phir @@ -471,6 +469,20 @@ def test_condition_multiple_bits() -> None: """From https://github.com/CQCL/pytket-phir/issues/215 .""" n_bits = 3 c = Circuit(1, n_bits) - c.Rz(0.5, 0, condition_bits=list(range(n_bits)), condition_value=0) - phir = pytket_to_phir(c) - HybridEngine(qsim="state-vector").run(program=phir) + c.Rz(0.5, 0, condition_bits=list(range(n_bits)), condition_value=6) + phir = json.loads(pytket_to_phir(c)) + + assert phir["ops"][2] == {"//": "IF ([c[0], c[1], c[2]] == 6) THEN Rz(0.5) q[0];"} + assert phir["ops"][3]["condition"] == { + "cop": "&", + "args": [ + {"cop": "==", "args": [["c", 0], 0]}, + { + "cop": "&", + "args": [ + {"cop": "==", "args": [["c", 1], 1]}, + {"cop": "==", "args": [["c", 2], 1]}, + ], + }, + ], + } From d511345607624fbe0db105eaf2a6310fd3b06417 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 11 Sep 2024 06:02:58 -0500 Subject: [PATCH 7/8] refactor: raise TypeError on passing less than min_args --- pytket/phir/phirgen.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pytket/phir/phirgen.py b/pytket/phir/phirgen.py index 1d6eca7..a8e6fab 100644 --- a/pytket/phir/phirgen.py +++ b/pytket/phir/phirgen.py @@ -357,10 +357,13 @@ def convert_classicalevalop(op: tk.ClassicalEvalOp, cmd: tk.Command) -> JsonDict def multi_bit_condition(args: "list[UnitID]", value: int) -> JsonDict: """Construct bitwise condition.""" - val_bits = deque(map(int, f"{value:0{len(args)}b}")) + min_args = 2 + if len(args) < min_args: + msg = "multi_bit_condition requires at least two arguments" + raise TypeError(msg) def nested_cop(cop: str, args: "deque[UnitID]", val_bits: deque[int]) -> JsonDict: - if len(args) == 2: # noqa: PLR2004 + if len(args) == min_args: return { "cop": cop, "args": [ @@ -376,7 +379,7 @@ def nested_cop(cop: str, args: "deque[UnitID]", val_bits: deque[int]) -> JsonDic ], } - return nested_cop("&", deque(args), val_bits) + return nested_cop("&", deque(args), deque(map(int, f"{value:0{len(args)}b}"))) def convert_subcmd(op: tk.Op, cmd: tk.Command) -> JsonDict | None: # noqa: PLR0912 From b1105c40743ce4cb3a9de4ee17eeb81e152b2e47 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Wed, 11 Sep 2024 06:23:21 -0500 Subject: [PATCH 8/8] refactor: use `min_args` in the error message Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> --- pytket/phir/phirgen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytket/phir/phirgen.py b/pytket/phir/phirgen.py index a8e6fab..0db08b3 100644 --- a/pytket/phir/phirgen.py +++ b/pytket/phir/phirgen.py @@ -359,7 +359,7 @@ def multi_bit_condition(args: "list[UnitID]", value: int) -> JsonDict: """Construct bitwise condition.""" min_args = 2 if len(args) < min_args: - msg = "multi_bit_condition requires at least two arguments" + msg = f"multi_bit_condition requires at least {min_args} arguments" raise TypeError(msg) def nested_cop(cop: str, args: "deque[UnitID]", val_bits: deque[int]) -> JsonDict: