From 74ddedee4f6b2667e1941b58dd3c3ca760c83cc4 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 5 Nov 2024 11:51:24 +0000 Subject: [PATCH 1/4] reject incomplete registers in pytket to qasm conv --- pytket/docs/changelog.rst | 1 + pytket/pytket/qasm/qasm.py | 6 ++++++ pytket/tests/qasm_test.py | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/pytket/docs/changelog.rst b/pytket/docs/changelog.rst index f057f21f5c..1dcaf780f2 100644 --- a/pytket/docs/changelog.rst +++ b/pytket/docs/changelog.rst @@ -16,6 +16,7 @@ Fixes: * Support converting conditional `RangePredicate`s to QASM. * Fix `maxwidth` parameter of `circuit_from_qasm_str` * Add `scratch_reg_resize_pass` to `circuit_from_qasm_str` +* Reject incompete classical registers in pytket to qasm conversion 1.34.0 (October 2024) --------------------- diff --git a/pytket/pytket/qasm/qasm.py b/pytket/pytket/qasm/qasm.py index 539bf38367..014784fe37 100644 --- a/pytket/pytket/qasm/qasm.py +++ b/pytket/pytket/qasm/qasm.py @@ -1142,6 +1142,12 @@ def check_can_convert_circuit(circ: Circuit, header: str, maxwidth: int) -> None f"Circuit contains a classical register larger than {maxwidth}: try " "setting the `maxwidth` parameter to a higher value." ) + set_circ_register = set([creg.name for creg in circ.c_registers]) + for b in set([b.reg_name for b in circ.bits]): + if b not in set_circ_register: + raise QASMUnsupportedError( + f"Circuit contains a invalid classical register {b}." + ) # Empty CustomGates should have been removed by DecomposeBoxes(). for cmd in circ: assert not is_empty_customgate(cmd.op) diff --git a/pytket/tests/qasm_test.py b/pytket/tests/qasm_test.py index 03d7fa9d07..f8fe0b5895 100644 --- a/pytket/tests/qasm_test.py +++ b/pytket/tests/qasm_test.py @@ -114,6 +114,16 @@ def test_long_registers_2() -> None: assert creg.size <= 100 +def test_incompete_registers() -> None: + c = Circuit(1) + c.add_bit(Bit("d", 1)) + c.add_bit(Bit("d", 2)) + c.Measure(Qubit(0), Bit("d", 1)) + with pytest.raises(QASMUnsupportedError) as errorinfo: + circuit_to_qasm_str(c, header="hqslib1") + assert "Circuit contains a invalid classical register d." in str(errorinfo.value) + + def test_qasm_qubit() -> None: with pytest.raises(RuntimeError) as errorinfo: fname = str(curr_file_path / "qasm_test_files/test2.qasm") @@ -240,6 +250,9 @@ def test_conditional_gates() -> None: def test_named_conditional_barrier() -> None: circ = Circuit(2, 2) + circ.add_bit(Bit("test", 0)) + circ.add_bit(Bit("test", 1)) + circ.add_bit(Bit("test", 2)) circ.add_bit(Bit("test", 3)) circ.Z(0, condition_bits=[0, 1], condition_value=2) circ.add_conditional_barrier( From 402a40d29a7aab041551c06c3d2103bf10342abc Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 5 Nov 2024 11:53:24 +0000 Subject: [PATCH 2/4] fix spelling --- pytket/tests/qasm_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytket/tests/qasm_test.py b/pytket/tests/qasm_test.py index f8fe0b5895..999085c8e0 100644 --- a/pytket/tests/qasm_test.py +++ b/pytket/tests/qasm_test.py @@ -121,7 +121,7 @@ def test_incompete_registers() -> None: c.Measure(Qubit(0), Bit("d", 1)) with pytest.raises(QASMUnsupportedError) as errorinfo: circuit_to_qasm_str(c, header="hqslib1") - assert "Circuit contains a invalid classical register d." in str(errorinfo.value) + assert "Circuit contains an invalid classical register d." in str(errorinfo.value) def test_qasm_qubit() -> None: From c73ed24ca3bcefd8b3c80712cd2fe87af95f3643 Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:02:30 +0000 Subject: [PATCH 3/4] Update pytket/pytket/qasm/qasm.py Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> --- pytket/pytket/qasm/qasm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytket/pytket/qasm/qasm.py b/pytket/pytket/qasm/qasm.py index 014784fe37..a76c25bb0f 100644 --- a/pytket/pytket/qasm/qasm.py +++ b/pytket/pytket/qasm/qasm.py @@ -1146,7 +1146,7 @@ def check_can_convert_circuit(circ: Circuit, header: str, maxwidth: int) -> None for b in set([b.reg_name for b in circ.bits]): if b not in set_circ_register: raise QASMUnsupportedError( - f"Circuit contains a invalid classical register {b}." + f"Circuit contains an invalid classical register {b}." ) # Empty CustomGates should have been removed by DecomposeBoxes(). for cmd in circ: From 56ad98d0ee5fbe6550b2ea24d681bd93170ba342 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 5 Nov 2024 15:07:10 +0000 Subject: [PATCH 4/4] suggestion --- pytket/pytket/qasm/qasm.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pytket/pytket/qasm/qasm.py b/pytket/pytket/qasm/qasm.py index a76c25bb0f..e079f17b3d 100644 --- a/pytket/pytket/qasm/qasm.py +++ b/pytket/pytket/qasm/qasm.py @@ -1143,10 +1143,10 @@ def check_can_convert_circuit(circ: Circuit, header: str, maxwidth: int) -> None "setting the `maxwidth` parameter to a higher value." ) set_circ_register = set([creg.name for creg in circ.c_registers]) - for b in set([b.reg_name for b in circ.bits]): - if b not in set_circ_register: + for b in circ.bits: + if b.reg_name not in set_circ_register: raise QASMUnsupportedError( - f"Circuit contains an invalid classical register {b}." + f"Circuit contains an invalid classical register {b.reg_name}." ) # Empty CustomGates should have been removed by DecomposeBoxes(). for cmd in circ: