Coverage for /home/runner/work/tket/tket/pytket/pytket/circuit/__init__.py: 95%
68 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-14 10:02 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-14 10:02 +0000
1# Copyright Quantinuum
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
15"""The circuit module provides an API to interact with the
16tket :py:class:`Circuit` data structure.
17 This module is provided in binary form during the PyPI installation."""
18from typing import (
19 Any,
20 Callable,
21 Optional,
22 Sequence,
23 Union,
24)
26from pytket import wasm
27from pytket._tket.circuit import *
28from pytket._tket.circuit import Circuit
29from pytket._tket.pauli import Pauli
30from pytket._tket.unit_id import *
32# prefixes for assertion bits
33from pytket._tket.unit_id import (
34 _DEBUG_ONE_REG_PREFIX,
35 _DEBUG_ZERO_REG_PREFIX,
36 Bit,
37 BitRegister,
38)
40from .logic_exp import (
41 BinaryOp,
42 BitLogicExp,
43 BitWiseOp,
44 Constant,
45 LogicExp,
46 Ops,
47 RegLogicExp,
48 RegWiseOp,
49 create_bit_logic_exp,
50 create_reg_logic_exp,
51 if_bit,
52 if_not_bit,
53 reg_eq,
54 reg_geq,
55 reg_gt,
56 reg_leq,
57 reg_lt,
58 reg_neq,
59)
62def overload_add_wasm(
63 self: Circuit,
64 funcname: str,
65 filehandler: wasm.WasmModuleHandler,
66 list_i: Sequence[int],
67 list_o: Sequence[int],
68 args: Union[Sequence[int], Sequence[Bit]],
69 args_wasm: Optional[Sequence[int]] = None,
70 **kwargs: Any,
71) -> Circuit:
72 """Add a classical function call from a wasm file to the circuit.
73 \n\n:param funcname: name of the function that is called
74 \n:param filehandler: wasm file or module handler to identify the wasm module
75 \n:param list_i: list of the number of bits in the input variables
76 \n:param list_o: list of the number of bits in the output variables
77 \n:param args: vector of circuit bits the wasm op should be added to
78 \n:param args_wasm: vector of wasmstates the wasm op should be added to
79 \n:param kwargs: additional arguments passed to `add_gate_method` .
80 Allowed parameters are `opgroup`, `condition` , `condition_bits`,
81 `condition_value`
82 \n:return: the new :py:class:`Circuit`"""
84 if args_wasm is None:
85 args_wasm = [0]
87 for x in list_i:
88 if x > filehandler._int_size:
89 raise ValueError(
90 f"only functions with i{filehandler._int_size} type are allowed"
91 )
93 for x in list_o:
94 if x > filehandler._int_size:
95 raise ValueError(
96 f"only functions with i{filehandler._int_size} type are allowed"
97 )
99 if filehandler.check_function(funcname, len(list_i), len(list_o)):
100 if (len(args_wasm)) > 0: 100 ↛ 102line 100 didn't jump to line 102 because the condition on line 100 was always true
101 self._add_w_register(max(args_wasm) + 1)
102 return self._add_wasm(
103 funcname, str(filehandler), list_i, list_o, args, args_wasm, **kwargs
104 )
106 raise ValueError(f"{funcname} not found, check {repr(filehandler)}")
109setattr(Circuit, "add_wasm", overload_add_wasm)
112def overload_add_wasm_to_reg(
113 self: Circuit,
114 funcname: str,
115 filehandler: wasm.WasmModuleHandler,
116 list_i: Sequence[BitRegister],
117 list_o: Sequence[BitRegister],
118 args_wasm: Optional[Sequence[int]] = None,
119 **kwargs: Any,
120) -> Circuit:
121 """Add a classical function call from a wasm file to the circuit.
122 \n\n:param funcname: name of the function that is called
123 \n:param filehandler: wasm file or module handler to identify the wasm module
124 \n:param list_i: list of the classical registers assigned to
125 the input variables of the function call
126 \n:param list_o: list of the classical registers assigned to
127 the output variables of the function call
128 \n:param args_wasm: vector of wasmstates the wasm op should be added to
129 \n:param kwargs: additional arguments passed to `add_gate_method` .
130 Allowed parameters are `opgroup`, `condition` , `condition_bits`,
131 `condition_value`
132 \n:return: the new :py:class:`Circuit`"""
134 if args_wasm is None: 134 ↛ 137line 134 didn't jump to line 137 because the condition on line 134 was always true
135 args_wasm = [0]
137 if filehandler.checked:
138 for reg in list_i:
139 if reg.size > 32:
140 raise ValueError(
141 """wasm is only supporting 32 bit size registers,
142please use only registers of at most 32 bits"""
143 )
145 for reg in list_o:
146 if reg.size > 32: 146 ↛ 147line 146 didn't jump to line 147 because the condition on line 146 was never true
147 raise ValueError(
148 """wasm is only supporting 32 bit size registers,
149please use only registers of at most 32 bits"""
150 )
152 # If the filehandler has not been checked we allow it to
153 # be added without checking the function arity.
154 if not filehandler.checked or filehandler.check_function(
155 funcname, len(list_i), len(list_o)
156 ):
157 if (len(args_wasm)) > 0: 157 ↛ 159line 157 didn't jump to line 159 because the condition on line 157 was always true
158 self._add_w_register(max(args_wasm) + 1)
159 return self._add_wasm(
160 funcname, str(filehandler), list_i, list_o, args_wasm, **kwargs
161 )
163 raise ValueError(f"{funcname} not found, check {repr(filehandler)}")
166setattr(Circuit, "add_wasm_to_reg", overload_add_wasm_to_reg)
169# overload operators for Bit, BitRegister and expressions over these
170# such that the operation returns a LogicExp describing the operation
172BitArgType = Union[LogicExp, Bit, Constant]
173RegArgType = Union[LogicExp, BitRegister, Constant]
176def gen_binary_method_bit(
177 op: BitWiseOp,
178) -> Callable[[BitArgType, BitArgType], BitLogicExp]:
179 def logic_operation(self: BitArgType, other: BitArgType) -> BitLogicExp:
180 return create_bit_logic_exp(op, [self, other])
182 return logic_operation
185def gen_binary_method_reg(
186 op: RegWiseOp,
187) -> Callable[[RegArgType, RegArgType], RegLogicExp]:
188 def logic_operation(self: RegArgType, other: RegArgType) -> RegLogicExp:
189 return create_reg_logic_exp(op, [self, other])
191 return logic_operation
194setattr(Bit, "__and__", gen_binary_method_bit(BitWiseOp.AND))
195setattr(Bit, "__rand__", gen_binary_method_bit(BitWiseOp.AND))
196setattr(Bit, "__or__", gen_binary_method_bit(BitWiseOp.OR))
197setattr(Bit, "__ror__", gen_binary_method_bit(BitWiseOp.OR))
198setattr(Bit, "__xor__", gen_binary_method_bit(BitWiseOp.XOR))
199setattr(Bit, "__rxor__", gen_binary_method_bit(BitWiseOp.XOR))
200setattr(BitRegister, "__and__", gen_binary_method_reg(RegWiseOp.AND))
201setattr(BitRegister, "__rand__", gen_binary_method_reg(RegWiseOp.AND))
202setattr(BitRegister, "__or__", gen_binary_method_reg(RegWiseOp.OR))
203setattr(BitRegister, "__ror__", gen_binary_method_reg(RegWiseOp.OR))
204setattr(BitRegister, "__xor__", gen_binary_method_reg(RegWiseOp.XOR))
205setattr(BitRegister, "__rxor__", gen_binary_method_reg(RegWiseOp.XOR))
206setattr(BitRegister, "__add__", gen_binary_method_reg(RegWiseOp.ADD))
207setattr(BitRegister, "__sub__", gen_binary_method_reg(RegWiseOp.SUB))
208setattr(BitRegister, "__mul__", gen_binary_method_reg(RegWiseOp.MUL))
209setattr(BitRegister, "__floordiv__", gen_binary_method_reg(RegWiseOp.DIV))
210setattr(BitRegister, "__pow__", gen_binary_method_reg(RegWiseOp.POW))
211setattr(BitRegister, "__lshift__", gen_binary_method_reg(RegWiseOp.LSH))
212setattr(BitRegister, "__rshift__", gen_binary_method_reg(RegWiseOp.RSH))