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

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. 

14 

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) 

25 

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 * 

31 

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) 

39 

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) 

60 

61 

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`""" 

83 

84 if args_wasm is None: 

85 args_wasm = [0] 

86 

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 ) 

92 

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 ) 

98 

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 ) 

105 

106 raise ValueError(f"{funcname} not found, check {repr(filehandler)}") 

107 

108 

109setattr(Circuit, "add_wasm", overload_add_wasm) 

110 

111 

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`""" 

133 

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] 

136 

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 ) 

144 

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 ) 

151 

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 ) 

162 

163 raise ValueError(f"{funcname} not found, check {repr(filehandler)}") 

164 

165 

166setattr(Circuit, "add_wasm_to_reg", overload_add_wasm_to_reg) 

167 

168 

169# overload operators for Bit, BitRegister and expressions over these 

170# such that the operation returns a LogicExp describing the operation 

171 

172BitArgType = Union[LogicExp, Bit, Constant] 

173RegArgType = Union[LogicExp, BitRegister, Constant] 

174 

175 

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

181 

182 return logic_operation 

183 

184 

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

190 

191 return logic_operation 

192 

193 

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