Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix wasm issues #1691

Merged
merged 23 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pytket/binders/circuit/Circuit/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ void def_circuit(py::class_<Circuit, std::shared_ptr<Circuit>> &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 unique wasm uid of the circuit")
cqc-melf marked this conversation as resolved.
Show resolved Hide resolved
.def_property_readonly(
"n_qubits", &Circuit::n_qubits,
":return: the number of qubits in the circuit")
Expand Down
2 changes: 2 additions & 0 deletions pytket/binders/include/unit_downcast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ struct polymorphic_type_hook<tket::UnitID> {
// 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);
}
Expand Down
42 changes: 41 additions & 1 deletion pytket/binders/unitid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_<UnitID>(
Expand All @@ -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_<Qubit, UnitID>(m, "Qubit", "A handle to a qubit")
.def("__copy__", [](const Qubit &id) { return Qubit(id); })
Expand Down Expand Up @@ -231,6 +232,45 @@ PYBIND11_MODULE(unit_id, m) {
"Construct Bit instance from JSON serializable "
"list representation of the Bit.");

py::class_<WasmState, UnitID>(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<unsigned>(),
"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<WasmState>)
.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<std::string>(), t[1].cast<std::vector<unsigned>>());
}))
.def(
"to_list",
[](const WasmState &b) {
return py::object(json(b)).cast<py::list>();
},
"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<WasmState>();
},
"Construct WasmState instance from JSON serializable "
"list representation of the WasmState.");

py::class_<Node, Qubit>(m, "Node", "A handle to a device node")
.def("__copy__", [](const Node &id) { return Node(id); })
.def(
Expand Down
2 changes: 1 addition & 1 deletion pytket/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
12 changes: 12 additions & 0 deletions pytket/docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
Changelog
=========

1.36.0 (unreleased)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer to keep this as "Unreleased" only. We don't know if it will be 1.36.0 or 1.35.1 ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 37f0f1b

-------------------

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)
----------------------

Expand Down
5 changes: 5 additions & 0 deletions pytket/pytket/_tket/circuit.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
45 changes: 42 additions & 3 deletions pytket/pytket/_tket/unit_id.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
"""
Expand All @@ -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': <UnitType.qubit: 0>, 'bit': <UnitType.bit: 1>}
__members__: typing.ClassVar[dict[str, UnitType]] # value = {'qubit': <UnitType.qubit: 0>, 'wasmstate': <UnitType.wasmstate: 2>, 'bit': <UnitType.bit: 1>}
bit: typing.ClassVar[UnitType] # value = <UnitType.bit: 1>
qubit: typing.ClassVar[UnitType] # value = <UnitType.qubit: 0>
wasmstate: typing.ClassVar[UnitType] # value = <UnitType.wasmstate: 2>
@staticmethod
def _pybind11_conduit_v1_(*args, **kwargs): # type: ignore
...
Expand Down Expand Up @@ -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'
Expand Down
6 changes: 1 addition & 5 deletions pytket/pytket/circuit/decompose_classical.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,11 +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.reg_name != "_w" # workaround: this shouldn't be type 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
Loading
Loading