From c63a96a51586ed21f3b1eb81a1fde319e13e0e99 Mon Sep 17 00:00:00 2001 From: Melf Date: Thu, 21 Nov 2024 17:35:58 +0000 Subject: [PATCH 01/19] fix wasm issues --- pytket/binders/circuit/Circuit/main.cpp | 3 + pytket/binders/include/unit_downcast.hpp | 2 + pytket/binders/unitid.cpp | 42 ++++++++- pytket/pytket/_tket/circuit.pyi | 5 + pytket/pytket/_tket/unit_id.pyi | 45 ++++++++- pytket/tests/classical_test.py | 111 +++++++++++++++++++++++ tket/include/tket/Circuit/Circuit.hpp | 1 + tket/src/Circuit/macro_manipulation.cpp | 3 + tket/src/Circuit/setters_and_getters.cpp | 24 ++++- tket/src/Ops/ClassicalOps.cpp | 4 +- tket/test/src/test_wasm.cpp | 98 ++++++++++++++++++++ 11 files changed, 331 insertions(+), 7 deletions(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index 38c6f7c2bb..a1ad362666 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -413,6 +413,9 @@ void def_circuit(py::class_> &pyCircuit) { .def_property_readonly( "n_gates", &Circuit::n_gates, ":return: the number of gates in the Circuit") + .def_property_readonly( + "wasm_uid", &Circuit::get_wasm_file_uid, + ":return: the wasm uid of the first wasmop found in the circuit") .def_property_readonly( "n_qubits", &Circuit::n_qubits, ":return: the number of qubits in the circuit") diff --git a/pytket/binders/include/unit_downcast.hpp b/pytket/binders/include/unit_downcast.hpp index 0674bbdf6f..09ec3a332b 100644 --- a/pytket/binders/include/unit_downcast.hpp +++ b/pytket/binders/include/unit_downcast.hpp @@ -29,6 +29,8 @@ struct polymorphic_type_hook { // Node has no additional info but is more specific // If Qubit is needed, then subtyping is sufficient type = &typeid(tket::Node); + } else if (src->type() == tket::UnitType::WasmState) { + type = &typeid(tket::WasmState); } else { type = &typeid(tket::Bit); } diff --git a/pytket/binders/unitid.cpp b/pytket/binders/unitid.cpp index eb6c3eb83b..f4865eeda7 100644 --- a/pytket/binders/unitid.cpp +++ b/pytket/binders/unitid.cpp @@ -92,6 +92,7 @@ PYBIND11_MODULE(unit_id, m) { m, "UnitType", "Enum for data types of units in circuits (e.g. Qubits vs Bits).") .value("qubit", UnitType::Qubit, "A single Qubit") + .value("wasmstate", UnitType::WasmState, "A single WasmState") .value("bit", UnitType::Bit, "A single classical Bit"); py::class_( @@ -114,7 +115,7 @@ PYBIND11_MODULE(unit_id, m) { .def_property_readonly( "type", &UnitID::type, "Type of unit, either ``UnitType.qubit`` or " - "``UnitType.bit``"); + "``UnitType.bit`` or ``UnitType.wasmstate``"); py::class_(m, "Qubit", "A handle to a qubit") .def("__copy__", [](const Qubit &id) { return Qubit(id); }) @@ -231,6 +232,45 @@ PYBIND11_MODULE(unit_id, m) { "Construct Bit instance from JSON serializable " "list representation of the Bit."); + py::class_(m, "WasmState", "A handle to a wasmstate") + .def("__copy__", [](const WasmState &id) { return WasmState(id); }) + .def( + "__deepcopy__", + [](const WasmState &id, const py::dict &) { return WasmState(id); }) + .def( + py::init(), + "Constructs an id for some index in the default wasm " + "register\n\n:param index: The index in the register", + py::arg("index")) + .def("__eq__", &py_equals) + .def("__hash__", [](const WasmState &b) { return hash_value(b); }) + .def(py::pickle( + [](const WasmState &b) { + return py::make_tuple(b.reg_name(), b.index()); + }, + [](const py::tuple &t) { + if (t.size() != 2) + throw std::runtime_error( + "Invalid state: tuple size: " + std::to_string(t.size())); + return WasmState( + t[0].cast(), t[1].cast>()); + })) + .def( + "to_list", + [](const WasmState &b) { + return py::object(json(b)).cast(); + }, + "Return a JSON serializable list representation of " + "the WasmState." + "\n\n:return: list containing register name and index") + .def_static( + "from_list", + [](const py::list &py_list) { + return json(py_list).get(); + }, + "Construct WasmState instance from JSON serializable " + "list representation of the WasmState."); + py::class_(m, "Node", "A handle to a device node") .def("__copy__", [](const Node &id) { return Node(id); }) .def( diff --git a/pytket/pytket/_tket/circuit.pyi b/pytket/pytket/_tket/circuit.pyi index 6105ee6703..e5c2a1a76b 100644 --- a/pytket/pytket/_tket/circuit.pyi +++ b/pytket/pytket/_tket/circuit.pyi @@ -2571,6 +2571,11 @@ class Circuit: """ A list of all qubit ids in the circuit """ + @property + def wasm_uid(self) -> str: + """ + :return: the wasm uid of the first wasmop found in the circuit + """ class ClBitVar: """ A bit variable within an expression diff --git a/pytket/pytket/_tket/unit_id.pyi b/pytket/pytket/_tket/unit_id.pyi index d268a5065d..d472fc9cdd 100644 --- a/pytket/pytket/_tket/unit_id.pyi +++ b/pytket/pytket/_tket/unit_id.pyi @@ -2,7 +2,7 @@ from typing import Any from __future__ import annotations import pytket.circuit.logic_exp import typing -__all__ = ['Bit', 'BitRegister', 'Node', 'Qubit', 'QubitRegister', 'UnitID', 'UnitType'] +__all__ = ['Bit', 'BitRegister', 'Node', 'Qubit', 'QubitRegister', 'UnitID', 'UnitType', 'WasmState'] class Bit(UnitID): """ A handle to a bit @@ -397,7 +397,7 @@ class UnitID: @property def type(self) -> UnitType: """ - Type of unit, either ``UnitType.qubit`` or ``UnitType.bit`` + Type of unit, either ``UnitType.qubit`` or ``UnitType.bit`` or ``UnitType.wasmstate`` """ class UnitType: """ @@ -407,11 +407,14 @@ class UnitType: qubit : A single Qubit + wasmstate : A single WasmState + bit : A single classical Bit """ - __members__: typing.ClassVar[dict[str, UnitType]] # value = {'qubit': , 'bit': } + __members__: typing.ClassVar[dict[str, UnitType]] # value = {'qubit': , 'wasmstate': , 'bit': } bit: typing.ClassVar[UnitType] # value = qubit: typing.ClassVar[UnitType] # value = + wasmstate: typing.ClassVar[UnitType] # value = @staticmethod def _pybind11_conduit_v1_(*args, **kwargs): # type: ignore ... @@ -441,6 +444,42 @@ class UnitType: @property def value(self) -> int: ... +class WasmState(UnitID): + """ + A handle to a wasmstate + """ + @staticmethod + def _pybind11_conduit_v1_(*args, **kwargs): # type: ignore + ... + @staticmethod + def from_list(arg0: list) -> WasmState: + """ + Construct WasmState instance from JSON serializable list representation of the WasmState. + """ + def __copy__(self) -> WasmState: + ... + def __deepcopy__(self, arg0: dict) -> WasmState: + ... + def __eq__(self, arg0: typing.Any) -> bool: + ... + def __getstate__(self) -> tuple: + ... + def __hash__(self) -> int: + ... + def __init__(self, index: int) -> None: + """ + Constructs an id for some index in the default wasm register + + :param index: The index in the register + """ + def __setstate__(self, arg0: tuple) -> None: + ... + def to_list(self) -> list: + """ + Return a JSON serializable list representation of the WasmState. + + :return: list containing register name and index + """ _DEBUG_ONE_REG_PREFIX: str = 'tk_DEBUG_ONE_REG' _DEBUG_ZERO_REG_PREFIX: str = 'tk_DEBUG_ZERO_REG' _TEMP_BIT_NAME: str = 'tk_SCRATCH_BIT' diff --git a/pytket/tests/classical_test.py b/pytket/tests/classical_test.py index 8364e11115..6e3ecc7150 100644 --- a/pytket/tests/classical_test.py +++ b/pytket/tests/classical_test.py @@ -27,6 +27,7 @@ from pytket import wasm from pytket._tket.unit_id import _TEMP_BIT_NAME, _TEMP_BIT_REG_BASE +from pytket._tket import unit_id from pytket.circuit import ( Bit, BitRegister, @@ -481,6 +482,109 @@ def test_add_wasm_to_reg() -> None: assert c.depth() == 4 +def test_wasm_argtypes() -> None: + w = wasm.WasmFileHandler("testfile.wasm") + + with open("testfile.wasm", "rb") as f: + bytecode = f.read() + assert w.bytecode() == bytecode + + c = Circuit(0, 6) + + c.add_wasm("add_one", w, [1], [1], [Bit(0), Bit(1)]) + + assert c.depth() == 1 + + cmd = c.get_commands()[0] + + assert type(cmd.args[0]) == unit_id.Bit + assert type(cmd.args[1]) == unit_id.Bit + assert type(cmd.args[2]) == unit_id.WasmState + + +def test_wasm_uid_from_circuit() -> None: + w = wasm.WasmFileHandler("testfile.wasm") + + with open("testfile.wasm", "rb") as f: + bytecode = f.read() + assert w.bytecode() == bytecode + + c = Circuit(0, 6) + + c.add_wasm("add_one", w, [1], [1], [Bit(0), Bit(1)]) + + assert c.depth() == 1 + + assert ( + c.wasm_uid == "6a0a29e235cd5c60353254bc2b459e631d381cdd0bded7ae6cb44afb784bd2de" + ) + + +def test_wasm_uid_from_circuit_2() -> None: + w = wasm.WasmFileHandler("testfile.wasm") + + with open("testfile.wasm", "rb") as f: + bytecode = f.read() + assert w.bytecode() == bytecode + + c = Circuit(0, 6) + + c.add_wasm("add_one", w, [1], [1], [Bit(0), Bit(1)], condition=Bit(3)) + + assert c.depth() == 1 + + assert ( + c.wasm_uid == "6a0a29e235cd5c60353254bc2b459e631d381cdd0bded7ae6cb44afb784bd2de" + ) + + +def test_wasm_uid_from_circuit_3() -> None: + w = wasm.WasmFileHandler("testfile.wasm") + + with open("testfile.wasm", "rb") as f: + bytecode = f.read() + assert w.bytecode() == bytecode + + c = Circuit(0, 6) + + assert c.depth() == 0 + with pytest.raises(ValueError): + c.wasm_uid + + +def test_wasm_append() -> None: + wasmfile = wasm.WasmFileHandler("testfile.wasm") + c = Circuit(1) + a = c.add_c_register("a", 8) + c.add_wasm_to_reg("add_one", wasmfile, [a], [a]) + assert c.depth() == 1 + + d = Circuit() + for bit in c.bits: + d.add_bit(bit) + d.add_c_setbits([False], [bit]) + + d.append(c) + assert d.depth() == 2 + + +def test_wasm_append_2() -> None: + wasmfile = wasm.WasmFileHandler("testfile.wasm") + c = Circuit(1) + a = c.add_c_register("a", 8) + c.add_wasm_to_reg("add_one", wasmfile, [a], [a]) + assert c.depth() == 1 + + d = Circuit() + for bit in c.bits: + d.add_bit(bit) + d.add_c_setbits([False], [bit]) + d.add_wasm_to_reg("no_return", wasmfile, [a], []) + + d.append(c) + assert d.depth() == 3 + + def test_wasmfilehandler_without_init() -> None: with pytest.raises(ValueError): _ = wasm.WasmFileHandler("testfile-without-init.wasm") @@ -737,6 +841,13 @@ def test_wasmfilehandler_cpp_clang() -> None: ) +def test_wasm_circuit_bits() -> None: + w = wasm.WasmFileHandler("testfile.wasm") + c = Circuit(0, 6) + with pytest.raises(ValueError): + c.add_wasm("add_one", w, [1], [1], c.bits) + + T = TypeVar("T") DrawType = Callable[[SearchStrategy[T]], T] diff --git a/tket/include/tket/Circuit/Circuit.hpp b/tket/include/tket/Circuit/Circuit.hpp index 606c2c3b0f..98a4b8e988 100644 --- a/tket/include/tket/Circuit/Circuit.hpp +++ b/tket/include/tket/Circuit/Circuit.hpp @@ -464,6 +464,7 @@ class Circuit { UnitID get_id_from_out(const Vertex &out) const; opt_reg_info_t get_reg_info(std::string reg_name) const; + std::string get_wasm_file_uid() const; register_t get_reg(std::string reg_name) const; // returns the total number of vertices in dag diff --git a/tket/src/Circuit/macro_manipulation.cpp b/tket/src/Circuit/macro_manipulation.cpp index 8b77cab4d5..23dea01d6c 100644 --- a/tket/src/Circuit/macro_manipulation.cpp +++ b/tket/src/Circuit/macro_manipulation.cpp @@ -139,6 +139,9 @@ void Circuit::append_with_map(const Circuit& c2, const unit_map_t& qm) { Circuit copy = c2; copy.rename_units(qm); + copy.add_wasm_register(_number_of_wasm_wires); + add_wasm_register(copy._number_of_wasm_wires); + // Check what we need to do at the joins: // Output --- Input ==> ------------- // Output --- Create ==> --- Reset --- diff --git a/tket/src/Circuit/setters_and_getters.cpp b/tket/src/Circuit/setters_and_getters.cpp index 5662d0f1b3..6881ec50c2 100644 --- a/tket/src/Circuit/setters_and_getters.cpp +++ b/tket/src/Circuit/setters_and_getters.cpp @@ -25,6 +25,7 @@ #include "tket/Circuit/DAGDefs.hpp" #include "tket/OpType/OpDesc.hpp" #include "tket/OpType/OpType.hpp" +#include "tket/Ops/ClassicalOps.hpp" #include "tket/Ops/OpPtr.hpp" namespace tket { @@ -290,6 +291,25 @@ opt_reg_info_t Circuit::get_reg_info(std::string reg_name) const { return found->reg_info(); } +std::string Circuit::get_wasm_file_uid() const { + BGL_FORALL_VERTICES(v, dag, DAG) { + if (get_OpType_from_Vertex(v) == OpType::WASM) { + return (static_cast(*get_Op_ptr_from_Vertex(v))) + .get_wasm_file_uid(); + } else if ( + (get_OpType_from_Vertex(v) == OpType::Conditional) && + (static_cast(*get_Op_ptr_from_Vertex(v)) + .get_op() + ->get_type() == OpType::WASM)) { + return static_cast( + *(static_cast(*get_Op_ptr_from_Vertex(v))) + .get_op()) + .get_wasm_file_uid(); + } + } + throw std::domain_error("Can't find WASM Op in circuit"); +} + register_t Circuit::get_reg(std::string reg_name) const { register_t reg; for (auto [it, end] = boundary.get().equal_range(reg_name); it != end; @@ -621,8 +641,8 @@ unsigned Circuit::n_ports(const Vertex &vert) const { } // there are no checks to ensure the vertex exists in the graph -// returns a pointer to the op, try not to dereference and do anything with the -// op +// returns a pointer to the op, try not to dereference and do anything with +// the op const Op_ptr Circuit::get_Op_ptr_from_Vertex(const Vertex &vert) const { return this->dag[vert].op; } diff --git a/tket/src/Ops/ClassicalOps.cpp b/tket/src/Ops/ClassicalOps.cpp index cee77a7b39..b99674a4c1 100644 --- a/tket/src/Ops/ClassicalOps.cpp +++ b/tket/src/Ops/ClassicalOps.cpp @@ -263,7 +263,9 @@ WASMOp::WASMOp( std::accumulate(width_i_parameter_.begin(), width_i_parameter_.end(), 0) + std::accumulate(width_o_parameter_.begin(), width_o_parameter_.end(), 0); - TKET_ASSERT(sum_of_i32 == n_); + if (sum_of_i32 != n_) { + throw std::domain_error("number of given args unexpected"); + } // add wasm edge to signature of this op. for (unsigned i = 0; i < ww_n_; ++i) { diff --git a/tket/test/src/test_wasm.cpp b/tket/test/src/test_wasm.cpp index 1def6cda0c..4fa695cbc0 100644 --- a/tket/test/src/test_wasm.cpp +++ b/tket/test/src/test_wasm.cpp @@ -116,6 +116,15 @@ SCENARIO("generating circ with wasm") { REQUIRE(wop.is_equal(wop_2)); } + GIVEN("compare wasmop 6") { + WASMOp wop = WASMOp(4, 0, uv, uv_2, wasm_func, wasm_file); + + WASMOp wop_2 = WASMOp(4, 0, uv, uv_2, wasm_func, wasm_file); + + REQUIRE(wop.is_equal(wop_2)); + REQUIRE(wop.get_ww_n() == 0); + REQUIRE(wop_2.get_ww_n() == 0); + } GIVEN("wasmop is_extern") { const std::shared_ptr wop_ptr = std::make_shared(4, 1, uv, uv_2, wasm_func, wasm_file); @@ -183,6 +192,95 @@ SCENARIO("generating circ with wasm") { REQUIRE(u.w_inputs().size() == 3); REQUIRE(u.w_outputs().size() == 3); } + GIVEN("circuit get wasm uid") { + Circuit u(1, 1); + + const std::shared_ptr wop_ptr = + std::make_shared(2, 1, uv_2, uv_2, wasm_func, wasm_file); + + const std::shared_ptr wop_ptr_2 = + std::make_shared(1, 3, uv_2, uv_3, wasm_func, wasm_file); + + u.add_op(wop_ptr, {Bit(0), Bit(0), WasmState(0)}); + u.add_op( + wop_ptr_2, {Bit(0), WasmState(0), WasmState(1), WasmState(2)}); + + u.assert_valid(); + REQUIRE(u.depth() == 2); + REQUIRE(u.get_wasm_file_uid() == wasm_file); + } + GIVEN("circuit with wasm append") { + Circuit u(1, 1); + Circuit u2(1, 1); + + const std::shared_ptr wop_ptr = + std::make_shared(2, 1, uv_2, uv_2, wasm_func, wasm_file); + + const std::shared_ptr wop_ptr_2 = + std::make_shared(1, 3, uv_2, uv_3, wasm_func, wasm_file); + + u.add_op(wop_ptr, {Bit(0), Bit(0), WasmState(0)}); + u.add_op( + wop_ptr_2, {Bit(0), WasmState(0), WasmState(1), WasmState(2)}); + + u.assert_valid(); + REQUIRE(u.depth() == 2); + REQUIRE(u.w_inputs().size() == 3); + REQUIRE(u.w_outputs().size() == 3); + REQUIRE(u2.depth() == 0); + REQUIRE(u2.w_inputs().size() == 0); + REQUIRE(u2.w_outputs().size() == 0); + u2.append(u); + REQUIRE(u2.depth() == 2); + REQUIRE(u2.w_inputs().size() == 3); + REQUIRE(u2.w_outputs().size() == 3); + } + GIVEN("circuit with wasm append 2 ") { + Circuit u(1, 1); + Circuit u2(1, 1); + + const std::shared_ptr wop_ptr = + std::make_shared(2, 1, uv_2, uv_2, wasm_func, wasm_file); + + const std::shared_ptr wop_ptr_2 = + std::make_shared(1, 1, uv_2, uv_3, wasm_func, wasm_file); + + u.add_op(wop_ptr, {Bit(0), Bit(0), WasmState(0)}); + u.add_op(wop_ptr_2, {Bit(0), WasmState(0)}); + + u.assert_valid(); + REQUIRE(u.depth() == 2); + REQUIRE(u.w_inputs().size() == 1); + REQUIRE(u.w_outputs().size() == 1); + REQUIRE(u2.depth() == 0); + REQUIRE(u2.w_inputs().size() == 0); + REQUIRE(u2.w_outputs().size() == 0); + u2.append(u); + REQUIRE(u2.depth() == 2); + REQUIRE(u2.w_inputs().size() == 1); + REQUIRE(u2.w_outputs().size() == 1); + } + GIVEN("circuit with wasm append 3 ") { + Circuit u(1, 1); + Circuit u2(1, 1); + + const std::shared_ptr wop_ptr = + std::make_shared(1, 1, uv_2, uv_3, wasm_func, wasm_file); + + u.add_op(wop_ptr, {Bit(0), WasmState(0)}); + + u.assert_valid(); + REQUIRE(u.depth() == 1); + REQUIRE(u.w_inputs().size() == 1); + REQUIRE(u.w_outputs().size() == 1); + REQUIRE(u2.depth() == 0); + REQUIRE(u2.w_inputs().size() == 0); + REQUIRE(u2.w_outputs().size() == 0); + u2.append(u); + REQUIRE(u2.depth() == 1); + REQUIRE(u2.w_inputs().size() == 1); + REQUIRE(u2.w_outputs().size() == 1); + } } SCENARIO("test wasm uid") { From 1081eedaf7e3d448268286546804a0045785f049 Mon Sep 17 00:00:00 2001 From: Melf Date: Thu, 21 Nov 2024 17:39:42 +0000 Subject: [PATCH 02/19] update changelog --- pytket/docs/changelog.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pytket/docs/changelog.rst b/pytket/docs/changelog.rst index bd7a814086..f5cdac117b 100644 --- a/pytket/docs/changelog.rst +++ b/pytket/docs/changelog.rst @@ -1,6 +1,18 @@ Changelog ========= +1.36.0 (unreleased) +------------------- + +Features: + +* Add `Circuit.wasm_uid` property to get the wasm UID from the circuit + +Fixes: + +* Fix `Circuit.append` for circuits containing wasm +* Fix issue with wrong parameters at `add_wasm` + 1.35.0 (November 2024) ---------------------- From ee75a76daa2a5338398620e3c59449a7aba2f75f Mon Sep 17 00:00:00 2001 From: Melf Date: Thu, 21 Nov 2024 17:42:40 +0000 Subject: [PATCH 03/19] update tket version --- pytket/conanfile.py | 2 +- tket/conanfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pytket/conanfile.py b/pytket/conanfile.py index 123ac8339a..86c6f590b0 100644 --- a/pytket/conanfile.py +++ b/pytket/conanfile.py @@ -38,7 +38,7 @@ def requirements(self): self.requires("pybind11_json/0.2.14") self.requires("symengine/0.13.0") self.requires("tkassert/0.3.4@tket/stable") - self.requires("tket/1.3.48@tket/stable") + self.requires("tket/1.3.49@tket/stable") self.requires("tklog/0.3.3@tket/stable") self.requires("tkrng/0.3.3@tket/stable") self.requires("tktokenswap/0.3.9@tket/stable") diff --git a/tket/conanfile.py b/tket/conanfile.py index fa46ab76f8..01a68205a5 100644 --- a/tket/conanfile.py +++ b/tket/conanfile.py @@ -23,7 +23,7 @@ class TketConan(ConanFile): name = "tket" - version = "1.3.48" + version = "1.3.49" package_type = "library" license = "Apache 2" homepage = "https://github.com/CQCL/tket" From db9cdd6a47f969d4530a137b78b905f95dca6c2b Mon Sep 17 00:00:00 2001 From: Melf Date: Thu, 21 Nov 2024 18:39:27 +0000 Subject: [PATCH 04/19] fix ci --- pytket/binders/include/unit_downcast.hpp | 2 +- pytket/conanfile.py | 2 +- pytket/tests/classical_test.py | 8 ++++---- tket/conanfile.py | 2 +- tket/test/src/test_wasm.cpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pytket/binders/include/unit_downcast.hpp b/pytket/binders/include/unit_downcast.hpp index 09ec3a332b..42715c4930 100644 --- a/pytket/binders/include/unit_downcast.hpp +++ b/pytket/binders/include/unit_downcast.hpp @@ -29,7 +29,7 @@ struct polymorphic_type_hook { // Node has no additional info but is more specific // If Qubit is needed, then subtyping is sufficient type = &typeid(tket::Node); - } else if (src->type() == tket::UnitType::WasmState) { + } else if (src->type() == tket::UnitType::WasmState) { type = &typeid(tket::WasmState); } else { type = &typeid(tket::Bit); diff --git a/pytket/conanfile.py b/pytket/conanfile.py index 86c6f590b0..9bdd4157ce 100644 --- a/pytket/conanfile.py +++ b/pytket/conanfile.py @@ -38,7 +38,7 @@ def requirements(self): self.requires("pybind11_json/0.2.14") self.requires("symengine/0.13.0") self.requires("tkassert/0.3.4@tket/stable") - self.requires("tket/1.3.49@tket/stable") + self.requires("tket/1.3.50@tket/stable") self.requires("tklog/0.3.3@tket/stable") self.requires("tkrng/0.3.3@tket/stable") self.requires("tktokenswap/0.3.9@tket/stable") diff --git a/pytket/tests/classical_test.py b/pytket/tests/classical_test.py index 6e3ecc7150..c3b38c4672 100644 --- a/pytket/tests/classical_test.py +++ b/pytket/tests/classical_test.py @@ -26,8 +26,8 @@ from sympy import Symbol from pytket import wasm -from pytket._tket.unit_id import _TEMP_BIT_NAME, _TEMP_BIT_REG_BASE from pytket._tket import unit_id +from pytket._tket.unit_id import _TEMP_BIT_NAME, _TEMP_BIT_REG_BASE from pytket.circuit import ( Bit, BitRegister, @@ -497,9 +497,9 @@ def test_wasm_argtypes() -> None: cmd = c.get_commands()[0] - assert type(cmd.args[0]) == unit_id.Bit - assert type(cmd.args[1]) == unit_id.Bit - assert type(cmd.args[2]) == unit_id.WasmState + assert isinstance(cmd.args[0], unit_id.Bit) + assert isinstance(cmd.args[1], unit_id.Bit) + assert isinstance(cmd.args[2], unit_id.WasmState) def test_wasm_uid_from_circuit() -> None: diff --git a/tket/conanfile.py b/tket/conanfile.py index 01a68205a5..da3643e863 100644 --- a/tket/conanfile.py +++ b/tket/conanfile.py @@ -23,7 +23,7 @@ class TketConan(ConanFile): name = "tket" - version = "1.3.49" + version = "1.3.50" package_type = "library" license = "Apache 2" homepage = "https://github.com/CQCL/tket" diff --git a/tket/test/src/test_wasm.cpp b/tket/test/src/test_wasm.cpp index 4fa695cbc0..1985b0cea1 100644 --- a/tket/test/src/test_wasm.cpp +++ b/tket/test/src/test_wasm.cpp @@ -208,7 +208,7 @@ SCENARIO("generating circ with wasm") { u.assert_valid(); REQUIRE(u.depth() == 2); REQUIRE(u.get_wasm_file_uid() == wasm_file); - } + } GIVEN("circuit with wasm append") { Circuit u(1, 1); Circuit u2(1, 1); From 5d833d6cad28edd1b337ba22b8f5743dfc670f12 Mon Sep 17 00:00:00 2001 From: Melf Date: Fri, 22 Nov 2024 10:54:20 +0000 Subject: [PATCH 05/19] remove decompose_classical --- pytket/pytket/circuit/decompose_classical.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pytket/pytket/circuit/decompose_classical.py b/pytket/pytket/circuit/decompose_classical.py index 11a7f1a71c..4da597ce0a 100644 --- a/pytket/pytket/circuit/decompose_classical.py +++ b/pytket/pytket/circuit/decompose_classical.py @@ -510,7 +510,6 @@ def _decompose_expressions(circ: Circuit) -> tuple[Circuit, bool]: for arg in args: if ( isinstance(arg, Bit) - and arg.reg_name != "_w" # workaround: this shouldn't be type Bit and arg not in newcirc.bits ): newcirc.add_bit(arg) From d9e6dac86a83164fd2ddcfca2e383fc3f472b995 Mon Sep 17 00:00:00 2001 From: Melf Date: Fri, 22 Nov 2024 11:22:40 +0000 Subject: [PATCH 06/19] add testcase for appending two filled circuits --- tket/test/src/test_wasm.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tket/test/src/test_wasm.cpp b/tket/test/src/test_wasm.cpp index 1985b0cea1..f97eebf4c7 100644 --- a/tket/test/src/test_wasm.cpp +++ b/tket/test/src/test_wasm.cpp @@ -281,6 +281,37 @@ SCENARIO("generating circ with wasm") { REQUIRE(u2.w_inputs().size() == 1); REQUIRE(u2.w_outputs().size() == 1); } + GIVEN("circuit with wasm append 4") { + Circuit u(1, 1); + Circuit u2(1, 1); + + const std::shared_ptr wop_ptr = + std::make_shared(2, 1, uv_2, uv_2, wasm_func, wasm_file); + + const std::shared_ptr wop_ptr_2 = + std::make_shared(1, 1, uv_2, uv_3, wasm_func, wasm_file); + + const std::shared_ptr wop_ptr_3 = + std::make_shared(1, 3, uv_3, uv_2, wasm_func, wasm_file); + + u.add_op(wop_ptr, {Bit(0), Bit(0), WasmState(0)}); + u.add_op(wop_ptr_2, {Bit(0), WasmState(0)}); + u2.add_op( + wop_ptr_3, {Bit(0), WasmState(0), WasmState(1), WasmState(2)}); + + u.assert_valid(); + u2.assert_valid(); + REQUIRE(u.depth() == 2); + REQUIRE(u.w_inputs().size() == 1); + REQUIRE(u.w_outputs().size() == 1); + REQUIRE(u2.depth() == 1); + REQUIRE(u2.w_inputs().size() == 3); + REQUIRE(u2.w_outputs().size() == 3); + u2.append(u); + REQUIRE(u2.depth() == 3); + REQUIRE(u2.w_inputs().size() == 3); + REQUIRE(u2.w_outputs().size() == 3); + } } SCENARIO("test wasm uid") { From a27a7d8541935b85c9553f615452a2d177b159f5 Mon Sep 17 00:00:00 2001 From: Melf Date: Fri, 22 Nov 2024 11:38:04 +0000 Subject: [PATCH 07/19] add check for appending two wasm files with differen uid --- tket/src/Circuit/macro_manipulation.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tket/src/Circuit/macro_manipulation.cpp b/tket/src/Circuit/macro_manipulation.cpp index 23dea01d6c..134fe7e2c0 100644 --- a/tket/src/Circuit/macro_manipulation.cpp +++ b/tket/src/Circuit/macro_manipulation.cpp @@ -139,6 +139,14 @@ void Circuit::append_with_map(const Circuit& c2, const unit_map_t& qm) { Circuit copy = c2; copy.rename_units(qm); + if ((_number_of_wasm_wires > 0) && (copy._number_of_wasm_wires > 0)) { + if (copy.get_wasm_file_uid() != get_wasm_file_uid()) { + throw Unsupported( + "Cannot append circuits with different wasm uids: " + + get_wasm_file_uid() + " and " + copy.get_wasm_file_uid()); + } + } + copy.add_wasm_register(_number_of_wasm_wires); add_wasm_register(copy._number_of_wasm_wires); From 8c28202d1fe3a770f63b7dc13b43cf127b808762 Mon Sep 17 00:00:00 2001 From: Melf Date: Fri, 22 Nov 2024 11:39:40 +0000 Subject: [PATCH 08/19] add test for different wasm uid --- pytket/pytket/circuit/decompose_classical.py | 5 +---- pytket/tests/classical_test.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pytket/pytket/circuit/decompose_classical.py b/pytket/pytket/circuit/decompose_classical.py index 4da597ce0a..058a9f2b3b 100644 --- a/pytket/pytket/circuit/decompose_classical.py +++ b/pytket/pytket/circuit/decompose_classical.py @@ -508,10 +508,7 @@ def _decompose_expressions(circ: Circuit) -> tuple[Circuit, bool]: newcirc.add_barrier(args) else: for arg in args: - if ( - isinstance(arg, Bit) - and arg not in newcirc.bits - ): + if isinstance(arg, Bit) and arg not in newcirc.bits: newcirc.add_bit(arg) newcirc.add_gate(op, args, **kwargs) return newcirc, modified diff --git a/pytket/tests/classical_test.py b/pytket/tests/classical_test.py index c3b38c4672..81e3da2b01 100644 --- a/pytket/tests/classical_test.py +++ b/pytket/tests/classical_test.py @@ -585,6 +585,25 @@ def test_wasm_append_2() -> None: assert d.depth() == 3 +def test_wasm_append_3() -> None: + wfh = wasm.WasmFileHandler("testfile.wasm") + wfh2 = wasm.WasmFileHandler("testfile-without-init.wasm", check_file=False) + + c = Circuit(1) + a = c.add_c_register("a", 8) + c.add_wasm_to_reg("add_one", wfh, [a], [a]) + assert c.depth() == 1 + + d = Circuit() + for bit in c.bits: + d.add_bit(bit) + d.add_c_setbits([False], [bit]) + d.add_wasm_to_reg("no_return", wfh2, [a], []) + + with pytest.raises(ValueError): + d.append(c) + + def test_wasmfilehandler_without_init() -> None: with pytest.raises(ValueError): _ = wasm.WasmFileHandler("testfile-without-init.wasm") From 14b51462f6328f618036f2e1f5297a48c3faa69a Mon Sep 17 00:00:00 2001 From: Melf Date: Fri, 22 Nov 2024 13:56:24 +0000 Subject: [PATCH 09/19] add handling of circuit box --- pytket/binders/circuit/Circuit/main.cpp | 2 +- pytket/tests/classical_test.py | 39 +++++++++++++++++++++++- tket/src/Circuit/setters_and_getters.cpp | 22 +++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index a1ad362666..c7fa955a14 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -415,7 +415,7 @@ void def_circuit(py::class_> &pyCircuit) { ":return: the number of gates in the Circuit") .def_property_readonly( "wasm_uid", &Circuit::get_wasm_file_uid, - ":return: the wasm uid of the first wasmop found in the circuit") + ":return: the unique wasm uid of the circuit") .def_property_readonly( "n_qubits", &Circuit::n_qubits, ":return: the number of qubits in the circuit") diff --git a/pytket/tests/classical_test.py b/pytket/tests/classical_test.py index 81e3da2b01..69e1f99a49 100644 --- a/pytket/tests/classical_test.py +++ b/pytket/tests/classical_test.py @@ -31,6 +31,7 @@ from pytket.circuit import ( Bit, BitRegister, + CircBox, Circuit, ClassicalExpBox, Conditional, @@ -539,6 +540,42 @@ def test_wasm_uid_from_circuit_2() -> None: def test_wasm_uid_from_circuit_3() -> None: + wfh = wasm.WasmFileHandler("testfile.wasm") + + c = Circuit(0) + a = c.add_c_register("c", 8) + c.add_wasm_to_reg("add_one", wfh, [a], [a]) + assert c.depth() == 1 + + cbox = CircBox(c) + d = Circuit(0, 8) + + d.add_circbox(cbox, [0, 1, 2, 3, 4, 5, 6, 7]) + + assert ( + d.wasm_uid == "6a0a29e235cd5c60353254bc2b459e631d381cdd0bded7ae6cb44afb784bd2de" + ) + + +def test_wasm_uid_from_circuit_4() -> None: + wfh = wasm.WasmFileHandler("testfile.wasm") + + c = Circuit(0) + a = c.add_c_register("c", 8) + c.add_wasm_to_reg("add_one", wfh, [a], [a]) + assert c.depth() == 1 + + cbox = CircBox(c) + d = Circuit(0, 8) + + d.add_circbox(cbox, [0, 1, 2, 3, 4, 5, 6, 7], condition=Bit(0)) + + assert ( + d.wasm_uid == "6a0a29e235cd5c60353254bc2b459e631d381cdd0bded7ae6cb44afb784bd2de" + ) + + +def test_wasm_uid_from_circuit_5() -> None: w = wasm.WasmFileHandler("testfile.wasm") with open("testfile.wasm", "rb") as f: @@ -600,7 +637,7 @@ def test_wasm_append_3() -> None: d.add_c_setbits([False], [bit]) d.add_wasm_to_reg("no_return", wfh2, [a], []) - with pytest.raises(ValueError): + with pytest.raises(RuntimeError): d.append(c) diff --git a/tket/src/Circuit/setters_and_getters.cpp b/tket/src/Circuit/setters_and_getters.cpp index 6881ec50c2..3977170505 100644 --- a/tket/src/Circuit/setters_and_getters.cpp +++ b/tket/src/Circuit/setters_and_getters.cpp @@ -305,6 +305,28 @@ std::string Circuit::get_wasm_file_uid() const { *(static_cast(*get_Op_ptr_from_Vertex(v))) .get_op()) .get_wasm_file_uid(); + } else if (get_OpType_from_Vertex(v) == OpType::CircBox) { + try { + return (static_cast(*get_Op_ptr_from_Vertex(v))) + .to_circuit() + ->get_wasm_file_uid(); + } catch (std::domain_error const &) { + continue; + } + } else if ( + (get_OpType_from_Vertex(v) == OpType::Conditional) && + (static_cast(*get_Op_ptr_from_Vertex(v)) + .get_op() + ->get_type() == OpType::CircBox)) { + try { + return (static_cast(*(static_cast( + *get_Op_ptr_from_Vertex(v))) + .get_op())) + .to_circuit() + ->get_wasm_file_uid(); + } catch (std::domain_error const &) { + continue; + } } } throw std::domain_error("Can't find WASM Op in circuit"); From 82ed8c587240780488b990024b94494bce19e08a Mon Sep 17 00:00:00 2001 From: Melf Date: Fri, 22 Nov 2024 14:01:14 +0000 Subject: [PATCH 10/19] fix ruff --- pytket/tests/zx_diagram_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytket/tests/zx_diagram_test.py b/pytket/tests/zx_diagram_test.py index ac8e7aebea..4309a66472 100644 --- a/pytket/tests/zx_diagram_test.py +++ b/pytket/tests/zx_diagram_test.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from math import isclose, pow +from math import isclose, pow # noqa: A004 from typing import Tuple import numpy as np From de111a1ebe625886ebbcb8cb15c82129a3ccf61c Mon Sep 17 00:00:00 2001 From: Melf Date: Fri, 22 Nov 2024 15:19:08 +0000 Subject: [PATCH 11/19] make wasm uid option in python --- pytket/binders/circuit/Circuit/main.cpp | 10 +++++++++- pytket/pytket/_tket/circuit.pyi | 4 ++-- pytket/tests/classical_test.py | 3 +-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index c7fa955a14..9459cb860f 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -414,7 +414,15 @@ void def_circuit(py::class_> &pyCircuit) { "n_gates", &Circuit::n_gates, ":return: the number of gates in the Circuit") .def_property_readonly( - "wasm_uid", &Circuit::get_wasm_file_uid, + "wasm_uid", + [](const Circuit &circ) { + std::optional result; + try { + result = circ.get_wasm_file_uid(); + } catch (const std::exception &) { + } + return result; + }, ":return: the unique wasm uid of the circuit") .def_property_readonly( "n_qubits", &Circuit::n_qubits, diff --git a/pytket/pytket/_tket/circuit.pyi b/pytket/pytket/_tket/circuit.pyi index e5c2a1a76b..4b52134831 100644 --- a/pytket/pytket/_tket/circuit.pyi +++ b/pytket/pytket/_tket/circuit.pyi @@ -2572,9 +2572,9 @@ class Circuit: A list of all qubit ids in the circuit """ @property - def wasm_uid(self) -> str: + def wasm_uid(self) -> str | None: """ - :return: the wasm uid of the first wasmop found in the circuit + :return: the unique wasm uid of the circuit """ class ClBitVar: """ diff --git a/pytket/tests/classical_test.py b/pytket/tests/classical_test.py index 69e1f99a49..d45c1c052c 100644 --- a/pytket/tests/classical_test.py +++ b/pytket/tests/classical_test.py @@ -585,8 +585,7 @@ def test_wasm_uid_from_circuit_5() -> None: c = Circuit(0, 6) assert c.depth() == 0 - with pytest.raises(ValueError): - c.wasm_uid + assert c.wasm_uid is None def test_wasm_append() -> None: From 00c3b307346d3d7b91dc36d0fef2158835227bbb Mon Sep 17 00:00:00 2001 From: Melf Date: Fri, 22 Nov 2024 17:02:57 +0000 Subject: [PATCH 12/19] make git_wasm_file_uid optional in c++ --- pytket/binders/circuit/Circuit/main.cpp | 9 +---- tket/include/tket/Circuit/Circuit.hpp | 2 +- tket/src/Circuit/macro_manipulation.cpp | 3 +- tket/src/Circuit/setters_and_getters.cpp | 47 ++++++++++++------------ tket/test/src/test_wasm.cpp | 44 ++++++++++++++++++++++ 5 files changed, 71 insertions(+), 34 deletions(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index 9459cb860f..5ccab4a773 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -415,14 +415,7 @@ void def_circuit(py::class_> &pyCircuit) { ":return: the number of gates in the Circuit") .def_property_readonly( "wasm_uid", - [](const Circuit &circ) { - std::optional result; - try { - result = circ.get_wasm_file_uid(); - } catch (const std::exception &) { - } - return result; - }, + [](const Circuit &circ) { return circ.get_wasm_file_uid(); }, ":return: the unique wasm uid of the circuit") .def_property_readonly( "n_qubits", &Circuit::n_qubits, diff --git a/tket/include/tket/Circuit/Circuit.hpp b/tket/include/tket/Circuit/Circuit.hpp index 98a4b8e988..362d75ecd9 100644 --- a/tket/include/tket/Circuit/Circuit.hpp +++ b/tket/include/tket/Circuit/Circuit.hpp @@ -464,7 +464,7 @@ class Circuit { UnitID get_id_from_out(const Vertex &out) const; opt_reg_info_t get_reg_info(std::string reg_name) const; - std::string get_wasm_file_uid() const; + std::optional get_wasm_file_uid() const; register_t get_reg(std::string reg_name) const; // returns the total number of vertices in dag diff --git a/tket/src/Circuit/macro_manipulation.cpp b/tket/src/Circuit/macro_manipulation.cpp index 134fe7e2c0..ec53f20b64 100644 --- a/tket/src/Circuit/macro_manipulation.cpp +++ b/tket/src/Circuit/macro_manipulation.cpp @@ -143,7 +143,8 @@ void Circuit::append_with_map(const Circuit& c2, const unit_map_t& qm) { if (copy.get_wasm_file_uid() != get_wasm_file_uid()) { throw Unsupported( "Cannot append circuits with different wasm uids: " + - get_wasm_file_uid() + " and " + copy.get_wasm_file_uid()); + get_wasm_file_uid().emplace(" - ") + " and " + + copy.get_wasm_file_uid().emplace(" - ")); } } diff --git a/tket/src/Circuit/setters_and_getters.cpp b/tket/src/Circuit/setters_and_getters.cpp index 3977170505..aa82b1bddc 100644 --- a/tket/src/Circuit/setters_and_getters.cpp +++ b/tket/src/Circuit/setters_and_getters.cpp @@ -291,45 +291,44 @@ opt_reg_info_t Circuit::get_reg_info(std::string reg_name) const { return found->reg_info(); } -std::string Circuit::get_wasm_file_uid() const { +std::optional Circuit::get_wasm_file_uid() const { + std::optional result = std::nullopt; BGL_FORALL_VERTICES(v, dag, DAG) { if (get_OpType_from_Vertex(v) == OpType::WASM) { - return (static_cast(*get_Op_ptr_from_Vertex(v))) - .get_wasm_file_uid(); + result = (static_cast(*get_Op_ptr_from_Vertex(v))) + .get_wasm_file_uid(); + return result; } else if ( (get_OpType_from_Vertex(v) == OpType::Conditional) && (static_cast(*get_Op_ptr_from_Vertex(v)) .get_op() ->get_type() == OpType::WASM)) { - return static_cast( - *(static_cast(*get_Op_ptr_from_Vertex(v))) - .get_op()) - .get_wasm_file_uid(); + result = + static_cast( + *(static_cast(*get_Op_ptr_from_Vertex(v))) + .get_op()) + .get_wasm_file_uid(); + return result; } else if (get_OpType_from_Vertex(v) == OpType::CircBox) { - try { - return (static_cast(*get_Op_ptr_from_Vertex(v))) - .to_circuit() - ->get_wasm_file_uid(); - } catch (std::domain_error const &) { - continue; - } + result = (static_cast(*get_Op_ptr_from_Vertex(v))) + .to_circuit() + ->get_wasm_file_uid(); + if (result != std::nullopt) return result; } else if ( (get_OpType_from_Vertex(v) == OpType::Conditional) && (static_cast(*get_Op_ptr_from_Vertex(v)) .get_op() ->get_type() == OpType::CircBox)) { - try { - return (static_cast(*(static_cast( - *get_Op_ptr_from_Vertex(v))) - .get_op())) - .to_circuit() - ->get_wasm_file_uid(); - } catch (std::domain_error const &) { - continue; - } + result = + (static_cast( + *(static_cast(*get_Op_ptr_from_Vertex(v))) + .get_op())) + .to_circuit() + ->get_wasm_file_uid(); + if (result != std::nullopt) return result; } } - throw std::domain_error("Can't find WASM Op in circuit"); + return result; } register_t Circuit::get_reg(std::string reg_name) const { diff --git a/tket/test/src/test_wasm.cpp b/tket/test/src/test_wasm.cpp index f97eebf4c7..5cbcfc00d0 100644 --- a/tket/test/src/test_wasm.cpp +++ b/tket/test/src/test_wasm.cpp @@ -209,6 +209,50 @@ SCENARIO("generating circ with wasm") { REQUIRE(u.depth() == 2); REQUIRE(u.get_wasm_file_uid() == wasm_file); } + GIVEN("circuit get wasm uid 2") { + Circuit u(0, 1); + + const std::shared_ptr wop_ptr = + std::make_shared(2, 1, uv_2, uv_2, wasm_func, wasm_file); + + const std::shared_ptr wop_ptr_2 = + std::make_shared(1, 3, uv_2, uv_3, wasm_func, wasm_file); + + u.add_op(wop_ptr, {Bit(0), Bit(0), WasmState(0)}); + u.add_op( + wop_ptr_2, {Bit(0), WasmState(0), WasmState(1), WasmState(2)}); + + u.assert_valid(); + REQUIRE(u.depth() == 2); + REQUIRE(u.get_wasm_file_uid() == wasm_file); + + CircBox circbox(u); + Circuit major_circ(0, 1); + major_circ.add_box(circbox, {0}); + + REQUIRE(major_circ.depth() == 1); + REQUIRE(major_circ.get_wasm_file_uid() == wasm_file); + } + GIVEN("circuit get wasm uid 3") { + Circuit u(0, 1); + + const std::shared_ptr wop_ptr = + std::make_shared(2, 1, uv_2, uv_2, wasm_func, wasm_file); + + const std::shared_ptr wop_ptr_2 = + std::make_shared(1, 3, uv_2, uv_3, wasm_func, wasm_file); + + u.assert_valid(); + REQUIRE(u.depth() == 0); + REQUIRE(u.get_wasm_file_uid() == std::nullopt); + + CircBox circbox(u); + Circuit major_circ(0, 1); + major_circ.add_box(circbox, {0}); + + REQUIRE(major_circ.depth() == 1); + REQUIRE(major_circ.get_wasm_file_uid() == std::nullopt); + } GIVEN("circuit with wasm append") { Circuit u(1, 1); Circuit u2(1, 1); From 0985f0551e265e5deb2e7b97ac8edd86155655e0 Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:14:56 +0000 Subject: [PATCH 13/19] Update tket/src/Circuit/macro_manipulation.cpp Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> --- tket/src/Circuit/macro_manipulation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tket/src/Circuit/macro_manipulation.cpp b/tket/src/Circuit/macro_manipulation.cpp index ec53f20b64..8ea980791e 100644 --- a/tket/src/Circuit/macro_manipulation.cpp +++ b/tket/src/Circuit/macro_manipulation.cpp @@ -143,8 +143,8 @@ void Circuit::append_with_map(const Circuit& c2, const unit_map_t& qm) { if (copy.get_wasm_file_uid() != get_wasm_file_uid()) { throw Unsupported( "Cannot append circuits with different wasm uids: " + - get_wasm_file_uid().emplace(" - ") + " and " + - copy.get_wasm_file_uid().emplace(" - ")); + get_wasm_file_uid().emplace("(none)") + " and " + + copy.get_wasm_file_uid().emplace("(none)")); } } From 01eeba4e8d4993ee10182178aafa64ac9fdc09db Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:15:08 +0000 Subject: [PATCH 14/19] Update pytket/binders/circuit/Circuit/main.cpp Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> --- pytket/binders/circuit/Circuit/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index 5ccab4a773..736e0bffed 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -415,7 +415,7 @@ void def_circuit(py::class_> &pyCircuit) { ":return: the number of gates in the Circuit") .def_property_readonly( "wasm_uid", - [](const Circuit &circ) { return circ.get_wasm_file_uid(); }, + &Circuit.get_wasm_file_uid, ":return: the unique wasm uid of the circuit") .def_property_readonly( "n_qubits", &Circuit::n_qubits, From 3ae10260f8ed3c7a3e51a17f57f6a1b7ffbc57c5 Mon Sep 17 00:00:00 2001 From: cqc-melf <70640934+cqc-melf@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:15:19 +0000 Subject: [PATCH 15/19] Update pytket/binders/circuit/Circuit/main.cpp Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> --- pytket/binders/circuit/Circuit/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index 736e0bffed..433d6e040f 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -416,7 +416,7 @@ void def_circuit(py::class_> &pyCircuit) { .def_property_readonly( "wasm_uid", &Circuit.get_wasm_file_uid, - ":return: the unique wasm uid of the circuit") + ":return: the unique WASM UID of the circuit, or `None` if the circuit has none") .def_property_readonly( "n_qubits", &Circuit::n_qubits, ":return: the number of qubits in the circuit") From 37f0f1bef4fd7cda549be65d849e3b5af21282b4 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Nov 2024 10:29:35 +0000 Subject: [PATCH 16/19] fix changelog --- pytket/docs/changelog.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pytket/docs/changelog.rst b/pytket/docs/changelog.rst index 2e7de4fe40..c382708170 100644 --- a/pytket/docs/changelog.rst +++ b/pytket/docs/changelog.rst @@ -1,8 +1,8 @@ Changelog ========= -1.36.0 (unreleased) -------------------- +Unreleased +---------- Features: From a42e38106281db36ecb5cb149c3baf6e8398f0a4 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Nov 2024 10:35:54 +0000 Subject: [PATCH 17/19] fix suggestion --- pytket/binders/circuit/Circuit/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index 433d6e040f..f4ba2d0d72 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -414,9 +414,9 @@ void def_circuit(py::class_> &pyCircuit) { "n_gates", &Circuit::n_gates, ":return: the number of gates in the Circuit") .def_property_readonly( - "wasm_uid", - &Circuit.get_wasm_file_uid, - ":return: the unique WASM UID of the circuit, or `None` if the circuit has none") + "wasm_uid", &Circuit.get_wasm_file_uid, + ":return: the unique WASM UID of the circuit, or `None` if the " + "circuit has none") .def_property_readonly( "n_qubits", &Circuit::n_qubits, ":return: the number of qubits in the circuit") From 417348fd885572756451ded1fea02d029df1a0e7 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Nov 2024 10:50:08 +0000 Subject: [PATCH 18/19] fix suggestion II --- pytket/binders/circuit/Circuit/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index f4ba2d0d72..7c2c8fff26 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -414,7 +414,7 @@ void def_circuit(py::class_> &pyCircuit) { "n_gates", &Circuit::n_gates, ":return: the number of gates in the Circuit") .def_property_readonly( - "wasm_uid", &Circuit.get_wasm_file_uid, + "wasm_uid", &Circuit.get_wasm_file_uid(), ":return: the unique WASM UID of the circuit, or `None` if the " "circuit has none") .def_property_readonly( From 218ccd5586b33aea0bd646fb9a71cdd2100ba565 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Nov 2024 12:00:20 +0000 Subject: [PATCH 19/19] fix suggestion III --- pytket/binders/circuit/Circuit/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pytket/binders/circuit/Circuit/main.cpp b/pytket/binders/circuit/Circuit/main.cpp index 7c2c8fff26..6ef222d4b3 100644 --- a/pytket/binders/circuit/Circuit/main.cpp +++ b/pytket/binders/circuit/Circuit/main.cpp @@ -414,7 +414,8 @@ void def_circuit(py::class_> &pyCircuit) { "n_gates", &Circuit::n_gates, ":return: the number of gates in the Circuit") .def_property_readonly( - "wasm_uid", &Circuit.get_wasm_file_uid(), + "wasm_uid", + [](const Circuit &circ) { return circ.get_wasm_file_uid(); }, ":return: the unique WASM UID of the circuit, or `None` if the " "circuit has none") .def_property_readonly(