From 8932cc56fa37708778d0fd211ca25d9c9063e658 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 08:08:42 +0100 Subject: [PATCH 01/22] Update authors --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index ba209e9..92a8dd3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,8 @@ keywords = ["quantum"] authors = [ { name = "Kaonan Micadei", email = "kaonan.micadei@pasqal.com" }, { name = "Eduardo Maschio", email = "eduardo.maschio@pasqal.com" }, + { name = "Roland Guichard", email = "roland.guichard@pasqal.com" }, + { name = "Pim Venderbosch", email = "pim.venderbosch@pasqal.com" }, ] classifiers = [ "Development Status :: 4 - Beta", From 8f5d548658804f6e1d6326ebb7a1781a4fcb6cb8 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 10:03:13 +0100 Subject: [PATCH 02/22] Add test for testing Alloc repr function --- tests/test_types.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/test_types.py diff --git a/tests/test_types.py b/tests/test_types.py new file mode 100644 index 0000000..bc55799 --- /dev/null +++ b/tests/test_types.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +from qadence2_ir.types import Alloc + + +def test_alloc_repr() -> None: + assert Alloc(1, True).__repr__() == "Alloc(1, trainable=True)" + assert Alloc(6, False).__repr__() == "Alloc(6, trainable=False)" + assert ( + Alloc(1, False, attr1=5, attr2=[5, 6, 3]).__repr__() + == "Alloc(1, trainable=False, attrs={'attr1': 5, 'attr2': [5, 6, 3]})" + ) From 99b5a6b2b15b00ea1f1e9a898c31800febfe850a Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 11:27:50 +0100 Subject: [PATCH 03/22] Add test for Alloc.__eq__ --- tests/test_types.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_types.py b/tests/test_types.py index bc55799..2094538 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1,5 +1,7 @@ from __future__ import annotations +from functools import partial + from qadence2_ir.types import Alloc @@ -10,3 +12,10 @@ def test_alloc_repr() -> None: Alloc(1, False, attr1=5, attr2=[5, 6, 3]).__repr__() == "Alloc(1, trainable=False, attrs={'attr1': 5, 'attr2': [5, 6, 3]})" ) + + +def test_alloc_eq() -> None: + init_alloc = partial(Alloc.__init__, 3, True, attributes={"test": 8, "bla": (2, "str", 84.2)}) + assert init_alloc() == init_alloc() + not_implemented = init_alloc().__eq__([]) + assert init_alloc().__eq__([]) is NotImplemented From 0b275195b054826e04bdfcef69b45961e595a19a Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 13:38:15 +0100 Subject: [PATCH 04/22] Fix error in test_alloc_eq --- tests/test_types.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/test_types.py b/tests/test_types.py index 2094538..337c557 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1,7 +1,5 @@ from __future__ import annotations -from functools import partial - from qadence2_ir.types import Alloc @@ -15,7 +13,8 @@ def test_alloc_repr() -> None: def test_alloc_eq() -> None: - init_alloc = partial(Alloc.__init__, 3, True, attributes={"test": 8, "bla": (2, "str", 84.2)}) - assert init_alloc() == init_alloc() - not_implemented = init_alloc().__eq__([]) - assert init_alloc().__eq__([]) is NotImplemented + def create_alloc() -> Alloc: + return Alloc(3, True, attributes={"test": 8, "bla": (2, "str", 84.2)}) + + assert create_alloc() == create_alloc() + assert create_alloc().__eq__([]) is NotImplemented From 751dc66e6832f5191996df014cf64c753dea5dba Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 14:18:43 +0100 Subject: [PATCH 05/22] Configure pytest coverage correctly --- pyproject.toml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 92a8dd3..2b25d6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,11 +59,11 @@ dependencies = [ ] [tool.hatch.envs.default.scripts] -test = "pytest -n auto --cov-config=pyproject.toml --ignore=./tests/test_examples.py {args}" +test = "pytest -n auto --cov-config=pyproject.toml --cov=qadence2_ir {args}" [tool.pytest.ini_options] testpaths = ["tests"] -addopts = """-vvv --cov-report=term-missing --cov-config=pyproject.toml --cov=template_python --cov=tests""" +addopts = """-vvv --cov-config=pyproject.toml --cov=qadence2_ir""" xfail_strict = true filterwarnings = [ "ignore:Call to deprecated create function FieldDescriptor", @@ -110,12 +110,6 @@ packages = ["qadence2_ir"] [tool.coverage.run] branch = true parallel = true -# uncomment to omit any file from the -# coverage. Regexps can be used -# to select all files from a folder -#omit = [ -# "template_python/to_omit.py", -#] [tool.coverage.report] exclude_lines = [ From 2fe0c88c9c485c5cb1206ed6f351f534192fcdee Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 14:23:58 +0100 Subject: [PATCH 06/22] Add tests for Assign --- tests/test_types.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/test_types.py b/tests/test_types.py index 337c557..2b39a25 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1,6 +1,6 @@ from __future__ import annotations -from qadence2_ir.types import Alloc +from qadence2_ir.types import Alloc, Assign def test_alloc_repr() -> None: @@ -18,3 +18,19 @@ def create_alloc() -> Alloc: assert create_alloc() == create_alloc() assert create_alloc().__eq__([]) is NotImplemented + + +def test_assign_repr() -> None: + assert Assign("my-var", 8).__repr__() == "Assign('my-var', 8)" + assert Assign("my-var", 3.14).__repr__() == "Assign('my-var', 3.14)" + assert ( + Assign("var*with@non$standard123characters", [3, 2, 1]).__repr__() + == "Assign('var*with@non$standard123characters', [3, 2, 1])" + ) + + +def test_assign_eq() -> None: + assert Assign("x", 2) == Assign("x", 2) + assert Assign("x", 2) != Assign("y", 2) + assert Assign("x", 1) != Assign("x", 34) + assert Assign("x", 5).__eq__({}) is NotImplemented From f9f58da09741939e6077f3d9522cb7344d5c6db4 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 14:51:13 +0100 Subject: [PATCH 07/22] Add extra failure cases to test_alloc_eq --- tests/test_types.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_types.py b/tests/test_types.py index 2b39a25..3f1847c 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -17,6 +17,8 @@ def create_alloc() -> Alloc: return Alloc(3, True, attributes={"test": 8, "bla": (2, "str", 84.2)}) assert create_alloc() == create_alloc() + assert create_alloc() != Alloc(1, True) + assert create_alloc() != Alloc(1, False) assert create_alloc().__eq__([]) is NotImplemented From a859b09406ae355c290f9e27506ec1ba72b17465 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 14:52:39 +0100 Subject: [PATCH 08/22] Add tests for Load --- tests/test_types.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test_types.py b/tests/test_types.py index 3f1847c..7951ac1 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1,6 +1,6 @@ from __future__ import annotations -from qadence2_ir.types import Alloc, Assign +from qadence2_ir.types import Alloc, Assign, Load def test_alloc_repr() -> None: @@ -36,3 +36,13 @@ def test_assign_eq() -> None: assert Assign("x", 2) != Assign("y", 2) assert Assign("x", 1) != Assign("x", 34) assert Assign("x", 5).__eq__({}) is NotImplemented + + +def test_load_repr() -> None: + assert Load("my-var").__repr__() == "Load('my-var')" + + +def test_load_eq() -> None: + assert Load("my-var") == Load("my-var") + assert Load("x") != Load("y") + assert Load("x") != "x" From e04231fcafd812196f65a1ad2d7c66c0d5d84fbc Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 15:17:17 +0100 Subject: [PATCH 09/22] Fix uncorrect repr of Call when no arguments are given --- qadence2_ir/types.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qadence2_ir/types.py b/qadence2_ir/types.py index 69d6dca..195012d 100644 --- a/qadence2_ir/types.py +++ b/qadence2_ir/types.py @@ -78,8 +78,11 @@ def __init__(self, identifier: str, *args: Any) -> None: self.args = args def __repr__(self) -> str: - args = ", ".join(map(repr, self.args)) - return f"{self.__class__.__name__}({repr(self.identifier)}, {args})" + if not self.args: + return f"{self.__class__.__name__}({repr(self.identifier)})" + else: + args = ", ".join(map(repr, self.args)) + return f"{self.__class__.__name__}({repr(self.identifier)}, {args})" def __eq__(self, value: object) -> bool: if not isinstance(value, Call): From 456d0516c3d51b375670ec24d36b008de430148f Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 15:18:07 +0100 Subject: [PATCH 10/22] Add tests for Call --- tests/test_types.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/test_types.py b/tests/test_types.py index 7951ac1..11ce37a 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1,6 +1,6 @@ from __future__ import annotations -from qadence2_ir.types import Alloc, Assign, Load +from qadence2_ir.types import Alloc, Assign, Call, Load def test_alloc_repr() -> None: @@ -46,3 +46,16 @@ def test_load_eq() -> None: assert Load("my-var") == Load("my-var") assert Load("x") != Load("y") assert Load("x") != "x" + + +def test_call_repr() -> None: + assert Call("my-func").__repr__() == "Call('my-func')" + assert Call("my-func", 9, "str").__repr__() == "Call('my-func', 9, 'str')" + + +def test_call_eq() -> None: + assert Call("my-func") == Call("my-func") + assert Call("my-func", 3) == Call("my-func", 3) + assert Call("my-func") != Call("fibonaci") + assert Call("my-func", 2) != Call("my-func", 4) + assert Call("my-func", []) != Call("my-func", 4) From 9a8bbe50eeb87c377ea609620e8f6bc4a55b6b51 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 15:50:32 +0100 Subject: [PATCH 11/22] Remove possibility to add args to Support --- qadence2_ir/types.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qadence2_ir/types.py b/qadence2_ir/types.py index 195012d..224b69e 100644 --- a/qadence2_ir/types.py +++ b/qadence2_ir/types.py @@ -106,7 +106,6 @@ class Support: def __init__( self, - *, target: tuple[int, ...], control: tuple[int, ...] | None = None, ) -> None: From 032ad8341e646f9cb8cd28d321fb5a114250c894 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 16:33:16 +0100 Subject: [PATCH 12/22] Add tests for Support --- tests/test_types.py | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/test_types.py b/tests/test_types.py index 11ce37a..16bce1a 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1,6 +1,8 @@ from __future__ import annotations -from qadence2_ir.types import Alloc, Assign, Call, Load +import pytest + +from qadence2_ir.types import Alloc, Assign, Call, Load, Support def test_alloc_repr() -> None: @@ -59,3 +61,36 @@ def test_call_eq() -> None: assert Call("my-func") != Call("fibonaci") assert Call("my-func", 2) != Call("my-func", 4) assert Call("my-func", []) != Call("my-func", 4) + + +def test_support_init() -> None: + only_target = Support((0,)) + assert only_target.target == (0,) + assert only_target.control == () + + with pytest.raises(TypeError): + Support(control=(0,)) # type: ignore + + target_and_control = Support((2, 0), (1,)) + assert target_and_control.target == (2, 0) + assert target_and_control.control == (1,) + + target_all = Support.target_all() + assert target_all.target == () + assert target_all.control == () + + +def test_support_repr() -> None: + assert repr(Support((0,))) == "Support(target=(0,))" + assert repr(Support((1,), (0,))) == "Support(target=(1,), control=(0,))" + assert repr(Support(())) == "Support.target_all()" + assert repr(Support.target_all()) == "Support.target_all()" + + +def test_support_eq() -> None: + assert Support((0,)) == Support((0,)) + assert Support((0,), (1, 3)) == Support((0,), (1, 3)) + assert Support((0,)) != Support((1,)) + assert Support((0,), (1,)) != Support((0,)) + assert Support((0,), (1,)) != Support((0,), (3, 0)) + assert Support((3,)) != "Support((3,))" From 491f3e09d32b501e2cc6156fb1d5d6eef08b954d Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Fri, 1 Nov 2024 17:57:04 +0100 Subject: [PATCH 13/22] Add tests for QuInstruct --- tests/test_types.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/test_types.py b/tests/test_types.py index 16bce1a..2ecb45e 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -2,7 +2,7 @@ import pytest -from qadence2_ir.types import Alloc, Assign, Call, Load, Support +from qadence2_ir.types import Alloc, Assign, Call, Load, QuInstruct, Support def test_alloc_repr() -> None: @@ -94,3 +94,28 @@ def test_support_eq() -> None: assert Support((0,), (1,)) != Support((0,)) assert Support((0,), (1,)) != Support((0,), (3, 0)) assert Support((3,)) != "Support((3,))" + + +@pytest.fixture +def support_control_target() -> Support: + return Support((0,), (1,)) + + +def test_qu_instruct_repr(support_control_target: Support) -> None: + assert ( + repr(QuInstruct("CNOT", support_control_target)) + == f"QuInstruct('CNOT', {repr(support_control_target)})" + ) + assert ( + repr(QuInstruct("CNOT", support_control_target, 1, "l", [], one=1, two=2.0)) + == f"QuInstruct('CNOT', {repr(support_control_target)}, 1, 'l', [], " + f"attrs={{'one': 1, 'two': 2.0}})" + ) + + +def test_qu_instruct_eq(support_control_target: Support) -> None: + assert QuInstruct("CNOT", support_control_target) == QuInstruct("CNOT", support_control_target) + assert QuInstruct("CNOT", support_control_target, 1, "a", k=8.0) == QuInstruct( + "CNOT", support_control_target, 1, "a", k=8.0 + ) + assert QuInstruct("CNOT", support_control_target) != "CNOT" From dbdf67dfd0b2ce13ea362d9276a9c0bd753fc264 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Mon, 4 Nov 2024 08:38:14 +0100 Subject: [PATCH 14/22] Use repr() instead of .__repr__() in all tests --- tests/test_types.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_types.py b/tests/test_types.py index 2ecb45e..312d6ac 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -6,10 +6,10 @@ def test_alloc_repr() -> None: - assert Alloc(1, True).__repr__() == "Alloc(1, trainable=True)" - assert Alloc(6, False).__repr__() == "Alloc(6, trainable=False)" + assert repr(Alloc(1, True)) == "Alloc(1, trainable=True)" + assert repr(Alloc(6, False)) == "Alloc(6, trainable=False)" assert ( - Alloc(1, False, attr1=5, attr2=[5, 6, 3]).__repr__() + repr(Alloc(1, False, attr1=5, attr2=[5, 6, 3])) == "Alloc(1, trainable=False, attrs={'attr1': 5, 'attr2': [5, 6, 3]})" ) @@ -25,10 +25,10 @@ def create_alloc() -> Alloc: def test_assign_repr() -> None: - assert Assign("my-var", 8).__repr__() == "Assign('my-var', 8)" - assert Assign("my-var", 3.14).__repr__() == "Assign('my-var', 3.14)" + assert repr(Assign("my-var", 8)) == "Assign('my-var', 8)" + assert repr(Assign("my-var", 3.14)) == "Assign('my-var', 3.14)" assert ( - Assign("var*with@non$standard123characters", [3, 2, 1]).__repr__() + repr(Assign("var*with@non$standard123characters", [3, 2, 1])) == "Assign('var*with@non$standard123characters', [3, 2, 1])" ) @@ -41,7 +41,7 @@ def test_assign_eq() -> None: def test_load_repr() -> None: - assert Load("my-var").__repr__() == "Load('my-var')" + assert repr(Load("my-var")) == "Load('my-var')" def test_load_eq() -> None: @@ -51,8 +51,8 @@ def test_load_eq() -> None: def test_call_repr() -> None: - assert Call("my-func").__repr__() == "Call('my-func')" - assert Call("my-func", 9, "str").__repr__() == "Call('my-func', 9, 'str')" + assert repr(Call("my-func")) == "Call('my-func')" + assert repr(Call("my-func", 9, "str")) == "Call('my-func', 9, 'str')" def test_call_eq() -> None: From 5b0443a68d69410d81dc0dad75a176693bfca0af Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Tue, 5 Nov 2024 13:09:36 +0100 Subject: [PATCH 15/22] Harmonize how arguments and kw-arguments are displayed in repr --- qadence2_ir/types.py | 18 ++++++++++++++---- tests/test_types.py | 6 +++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/qadence2_ir/types.py b/qadence2_ir/types.py index 224b69e..90df8e0 100644 --- a/qadence2_ir/types.py +++ b/qadence2_ir/types.py @@ -120,7 +120,7 @@ def __repr__(self) -> str: if not self.target: return f"{self.__class__.__name__}.target_all()" - subspace = f"target={self.target}" + subspace = f"{self.target}" if self.control: subspace += f", control={self.control}" @@ -158,7 +158,7 @@ def __repr__(self) -> str: if args: params += ", " + args if self.attrs: - params += f", attrs={self.attrs}" + params += f", attributes={self.attrs}" return f"{self.__class__.__name__}({params})" def __eq__(self, value: object) -> bool: @@ -209,8 +209,18 @@ def __init__( self.options = options or dict() def __repr__(self) -> str: - items = ", ".join(f"{k}={v}" for k, v in self.__dict__.items()) - return f"{self.__class__.__name__}({items})" + arguments = f"{self.num_qubits}" + if len(self.qubit_positions) > 0: + arguments += f", qubit_positions={self.qubit_positions}" + if self.grid_type is not None: + arguments += f", grid_type='{self.grid_type}'" + if self.grid_scale: + arguments += f", grid_scale={self.grid_scale}" + if len(self.connectivity) > 0: + arguments += f", connectivity={self.connectivity}" + if len(self.options) > 0: + arguments += f", options={self.options}" + return f"{self.__class__.__name__}({arguments})" def __eq__(self, value: object) -> bool: if not isinstance(value, AllocQubits): diff --git a/tests/test_types.py b/tests/test_types.py index 312d6ac..69cc0be 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -81,8 +81,8 @@ def test_support_init() -> None: def test_support_repr() -> None: - assert repr(Support((0,))) == "Support(target=(0,))" - assert repr(Support((1,), (0,))) == "Support(target=(1,), control=(0,))" + assert repr(Support((0,))) == "Support((0,))" + assert repr(Support((1,), (0,))) == "Support((1,), control=(0,))" assert repr(Support(())) == "Support.target_all()" assert repr(Support.target_all()) == "Support.target_all()" @@ -109,7 +109,7 @@ def test_qu_instruct_repr(support_control_target: Support) -> None: assert ( repr(QuInstruct("CNOT", support_control_target, 1, "l", [], one=1, two=2.0)) == f"QuInstruct('CNOT', {repr(support_control_target)}, 1, 'l', [], " - f"attrs={{'one': 1, 'two': 2.0}})" + f"attributes={{'one': 1, 'two': 2.0}})" ) From 8b09ba6d07d0c96fcfd6046240b72ac216c7d1b6 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Tue, 5 Nov 2024 13:37:59 +0100 Subject: [PATCH 16/22] Add tests for AllocQubits --- qadence2_ir/types.py | 2 +- tests/test_types.py | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/qadence2_ir/types.py b/qadence2_ir/types.py index 90df8e0..50c642b 100644 --- a/qadence2_ir/types.py +++ b/qadence2_ir/types.py @@ -214,7 +214,7 @@ def __repr__(self) -> str: arguments += f", qubit_positions={self.qubit_positions}" if self.grid_type is not None: arguments += f", grid_type='{self.grid_type}'" - if self.grid_scale: + if self.grid_scale != 1.0: arguments += f", grid_scale={self.grid_scale}" if len(self.connectivity) > 0: arguments += f", connectivity={self.connectivity}" diff --git a/tests/test_types.py b/tests/test_types.py index 69cc0be..3a18c0f 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -2,7 +2,7 @@ import pytest -from qadence2_ir.types import Alloc, Assign, Call, Load, QuInstruct, Support +from qadence2_ir.types import Alloc, AllocQubits, Assign, Call, Load, QuInstruct, Support def test_alloc_repr() -> None: @@ -119,3 +119,28 @@ def test_qu_instruct_eq(support_control_target: Support) -> None: "CNOT", support_control_target, 1, "a", k=8.0 ) assert QuInstruct("CNOT", support_control_target) != "CNOT" + + +def test_alloc_qubits_repr() -> None: + assert repr(AllocQubits(4)) == "AllocQubits(4)" + assert ( + repr(AllocQubits(2, [(0, 0), (4, 1), (-1, 5)], grid_type="linear", grid_scale=2.4)) + == "AllocQubits(2, qubit_positions=[(0, 0), (4, 1), (-1, 5)], grid_type='linear', " + "grid_scale=2.4)" + ) + assert ( + repr( + AllocQubits( + 3, connectivity={(0, 1): 1.0, (1, 2): 1.5, (0, 2): 0.8}, options={"option1": True} + ) + ) + == "AllocQubits(3, connectivity={(0, 1): 1.0, (1, 2): 1.5, (0, 2): 0.8}, " + "options={'option1': True})" + ) + + +def test_alloc_qubits_eq() -> None: + assert AllocQubits(1) == AllocQubits(1) + assert AllocQubits(3) != AllocQubits(2) + assert AllocQubits(1, qubit_positions=[(0, 0)]) != AllocQubits(1, qubit_positions=[(2, 1)]) + assert AllocQubits(3).__eq__("3-qubits") is NotImplemented From 098e10fbf027b9ba6b8ef9d3b5af20dc4a8b8501 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Tue, 5 Nov 2024 17:57:05 +0100 Subject: [PATCH 17/22] Change Model repr method to match more closely to the reprs of other classes --- qadence2_ir/types.py | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/qadence2_ir/types.py b/qadence2_ir/types.py index 50c642b..fde8777 100644 --- a/qadence2_ir/types.py +++ b/qadence2_ir/types.py @@ -269,25 +269,29 @@ def __init__( def __repr__(self) -> str: indent = " " - acc = f"{self.__class__.__name__}(" - - for field, value in self.__dict__.items(): - if isinstance(value, AllocQubits): - acc += f"\n{indent}{field}={value.__class__.__name__}(" - items = ",\n".join(f"{indent * 2}{k}={v}" for k, v in value.__dict__.items()) - acc += (f"\n{items},\n{indent}" if items else "") + ")," - - elif isinstance(value, dict): - acc += f"\n{indent}{field}={{" - items = ",\n".join(f"{indent * 2}{repr(k)}: {v}" for k, v in value.items()) - acc += (f"\n{items},\n{indent}" if items else "") + "}," - - elif isinstance(value, list): - acc += f"\n{indent}{field}=[" - items = ",\n".join(f"{indent * 2}{item}" for item in self.instructions) - acc += (f"\n{items},\n{indent}" if items else "") + "]," - - return acc + "\n)" + result = f"{self.__class__.__name__}(\n" + result += f"{indent}{self.register},\n" + result += f"{indent}{'{'}\n" + for key, value in self.inputs.items(): + result += f"{indent}{indent}'{key}': {value},\n" + result += f"{indent}{'}'},\n" + result += f"{indent}[\n" + for item in self.instructions: + result += f"{indent}{indent}{item},\n" + result += f"{indent}]" + + if self.directives != dict(): + result += f",\n{indent}directives={'{'}\n" + for key, value in self.directives.items(): + result += f"{indent}{indent}'{key}': {value},\n" + result += f"{indent}{'}'}" + if self.settings != dict(): + result += f",\n{indent}settings={'{'}\n" + for key, value in self.settings.items(): + result += f"{indent}{indent}'{key}': {value},\n" + result += f"{indent}{'}'}" + result += "\n)" + return result def __eq__(self, value: object) -> bool: if not isinstance(value, Model): From d00436ebbbb2e6e8ae5cf3ee525d963fc77ab93a Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Wed, 6 Nov 2024 09:35:14 +0100 Subject: [PATCH 18/22] Add tests for Model --- tests/test_types.py | 60 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/tests/test_types.py b/tests/test_types.py index 3a18c0f..ca445bb 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1,8 +1,10 @@ from __future__ import annotations +from copy import deepcopy + import pytest -from qadence2_ir.types import Alloc, AllocQubits, Assign, Call, Load, QuInstruct, Support +from qadence2_ir.types import Alloc, AllocQubits, Assign, Call, Load, Model, QuInstruct, Support def test_alloc_repr() -> None: @@ -144,3 +146,59 @@ def test_alloc_qubits_eq() -> None: assert AllocQubits(3) != AllocQubits(2) assert AllocQubits(1, qubit_positions=[(0, 0)]) != AllocQubits(1, qubit_positions=[(2, 1)]) assert AllocQubits(3).__eq__("3-qubits") is NotImplemented + + +@pytest.fixture +def simple_model() -> Model: + register = AllocQubits(3) + inputs = {"input1": Alloc(1, False), "input2": Alloc(4, True)} + instructions: list[Assign | QuInstruct] = [ + Assign("var1", 10), + QuInstruct("CNOT", Support((0,), (1,))), + QuInstruct("RX", Support.target_all(), 3.14), + ] + return Model(register, inputs, instructions) + + +@pytest.fixture +def model_with_directives_settings(simple_model: Model) -> Model: + new_model = deepcopy(simple_model) + new_model.directives = {"option1": 3, "option2": True} + new_model.settings = {"setting1": 18.0} + return new_model + + +def test_model_repr(simple_model: Model, model_with_directives_settings: Model) -> None: + expected = f"""Model( + {simple_model.register}, + {'{'} + 'input1': {simple_model.inputs["input1"]}, + 'input2': {simple_model.inputs["input2"]}, + {'}'}, + [ + {simple_model.instructions[0]}, + {simple_model.instructions[1]}, + {simple_model.instructions[2]}, + ] +)""" + assert repr(simple_model) == expected + expected2 = ( + expected[:-2] + + """, + directives={ + 'option1': 3, + 'option2': True, + }, + settings={ + 'setting1': 18.0, + } +)""" + ) + assert repr(model_with_directives_settings) == expected2 + + +def test_model_eq(simple_model: Model, model_with_directives_settings: Model) -> None: + assert simple_model == deepcopy(simple_model) + assert model_with_directives_settings == deepcopy(model_with_directives_settings) + assert simple_model != model_with_directives_settings + assert simple_model.__eq__("model") is NotImplemented From 4d1794daefcb9e3b1d1586266f661f6a845d5746 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Wed, 6 Nov 2024 09:36:17 +0100 Subject: [PATCH 19/22] Add test for NotImplemented in Call to reach full coverage --- tests/test_types.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_types.py b/tests/test_types.py index ca445bb..351523f 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -63,6 +63,7 @@ def test_call_eq() -> None: assert Call("my-func") != Call("fibonaci") assert Call("my-func", 2) != Call("my-func", 4) assert Call("my-func", []) != Call("my-func", 4) + assert Call("function", 3).__eq__(7) is NotImplemented def test_support_init() -> None: From c0db2416fb9a1401d47143369995dae620370f29 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Wed, 6 Nov 2024 14:52:39 +0100 Subject: [PATCH 20/22] Change test_alloc_eq to use deepcopy instead of nested function --- tests/test_types.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/test_types.py b/tests/test_types.py index 351523f..6b861bb 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -17,13 +17,11 @@ def test_alloc_repr() -> None: def test_alloc_eq() -> None: - def create_alloc() -> Alloc: - return Alloc(3, True, attributes={"test": 8, "bla": (2, "str", 84.2)}) - - assert create_alloc() == create_alloc() - assert create_alloc() != Alloc(1, True) - assert create_alloc() != Alloc(1, False) - assert create_alloc().__eq__([]) is NotImplemented + alloc = Alloc(3, True, attributes={"test": 8, "bla": (2, "str", 84.2)}) + assert alloc == deepcopy(alloc) + assert alloc != Alloc(1, True) + assert alloc != Alloc(1, False) + assert alloc.__eq__([]) is NotImplemented def test_assign_repr() -> None: From c8f4a042cda78a170385c3d7a5263afc2877188a Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Wed, 6 Nov 2024 15:06:33 +0100 Subject: [PATCH 21/22] Move fixtures to confeste.py --- tests/conftest.py | 28 ++++++++++++++++++++++++++++ tests/test_types.py | 25 ------------------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index a891657..da182a9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,9 +2,12 @@ # functions common to every test from __future__ import annotations +from copy import deepcopy + import pytest from qadence2_ir.irast import AST +from qadence2_ir.types import Alloc, AllocQubits, Assign, Model, QuInstruct, Support @pytest.fixture @@ -26,3 +29,28 @@ def quantum_ast() -> AST: q_op = AST.quantum_op("rx", (0,), (1,), fn) return q_op + + +@pytest.fixture +def support_control_target() -> Support: + return Support((0,), (1,)) + + +@pytest.fixture +def simple_model() -> Model: + register = AllocQubits(3) + inputs = {"input1": Alloc(1, False), "input2": Alloc(4, True)} + instructions: list[Assign | QuInstruct] = [ + Assign("var1", 10), + QuInstruct("CNOT", Support((0,), (1,))), + QuInstruct("RX", Support.target_all(), 3.14), + ] + return Model(register, inputs, instructions) + + +@pytest.fixture +def model_with_directives_settings(simple_model: Model) -> Model: + new_model = deepcopy(simple_model) + new_model.directives = {"option1": 3, "option2": True} + new_model.settings = {"setting1": 18.0} + return new_model diff --git a/tests/test_types.py b/tests/test_types.py index 6b861bb..8dbcf92 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -97,11 +97,6 @@ def test_support_eq() -> None: assert Support((3,)) != "Support((3,))" -@pytest.fixture -def support_control_target() -> Support: - return Support((0,), (1,)) - - def test_qu_instruct_repr(support_control_target: Support) -> None: assert ( repr(QuInstruct("CNOT", support_control_target)) @@ -147,26 +142,6 @@ def test_alloc_qubits_eq() -> None: assert AllocQubits(3).__eq__("3-qubits") is NotImplemented -@pytest.fixture -def simple_model() -> Model: - register = AllocQubits(3) - inputs = {"input1": Alloc(1, False), "input2": Alloc(4, True)} - instructions: list[Assign | QuInstruct] = [ - Assign("var1", 10), - QuInstruct("CNOT", Support((0,), (1,))), - QuInstruct("RX", Support.target_all(), 3.14), - ] - return Model(register, inputs, instructions) - - -@pytest.fixture -def model_with_directives_settings(simple_model: Model) -> Model: - new_model = deepcopy(simple_model) - new_model.directives = {"option1": 3, "option2": True} - new_model.settings = {"setting1": 18.0} - return new_model - - def test_model_repr(simple_model: Model, model_with_directives_settings: Model) -> None: expected = f"""Model( {simple_model.register}, From 56f6fee0a34f3eb0be1154bd1af5ffc88b0018f2 Mon Sep 17 00:00:00 2001 From: Pim Venderbosch Date: Tue, 12 Nov 2024 09:34:48 +0100 Subject: [PATCH 22/22] Fix linting --- tests/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 7ed7210..a122369 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -59,4 +59,3 @@ def model_with_directives_settings(simple_model: Model) -> Model: @pytest.fixture def asts_for_arithmetic() -> tuple[AST, AST]: return (AST.numeric(0.5 + 1j), AST.quantum_op("CNOT", (0,), (1,))) -