Skip to content

Commit f5a4048

Browse files
committed
further small performance upgrades
1 parent 67a029f commit f5a4048

File tree

8 files changed

+56
-69
lines changed

8 files changed

+56
-69
lines changed

src/qrisp/arithmetic/adders/adder_tools.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def ammended_adder(qf2, qf1, *args, ignore_rounding_error = False, ignore_overfl
161161
elif isinstance(qf2, (list, QuantumVariable)):
162162

163163
if len(qf2) < len(qf1):
164-
ancilla_var = QuantumVariable(len(qf1)-len(qf2))
164+
ancilla_var = QuantumVariable(len(qf1)-len(qf2), name = "add_ammend_anc*", qs = qf1[0].qs())
165165
qf2 = list(qf2) + list(ancilla_var)
166166

167167
raw_inpl_adder(qf2, qf1, *args, **kwargs)
@@ -173,7 +173,7 @@ def ammended_adder(qf2, qf1, *args, ignore_rounding_error = False, ignore_overfl
173173

174174
elif isinstance(qf2, int) and ammend_cl_int:
175175

176-
ancilla_var = QuantumFloat(len(qf1))
176+
ancilla_var = QuantumFloat(len(qf1), name = "add_ammend_anc*", qs = qf1[0].qs())
177177

178178
ancilla_var.encode(qf2 % 2**len(qf1))
179179

src/qrisp/arithmetic/adders/gidney/cq_gidney_adder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def cq_gidney_adder(a, b, c_in = None, c_out = None, ctrl = None):
4242
# (doesn't happen automatically with fast_append = 3)
4343
merge(b[0].qs())
4444

45-
with fast_append(1):
45+
with fast_append(3):
4646

4747
if isinstance(a, int):
4848
a = bin_rep(a%2**len(b), len(b))[::-1]

src/qrisp/arithmetic/modular_arithmetic/modular_multiplication.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -317,21 +317,23 @@ def semi_cl_inpl_mult(a, X, ctrl = None, treat_invalid = False):
317317
if X == 1:
318318
return a
319319

320-
# Create the temporary value
321-
tmp = a.duplicate(qs = a.qs)
322320

323-
# If treat_invalid is set to True, the function should leave the invalid values
324-
# invariant. That is, values that are bigger than the modulus N.
325-
326-
# We achieve this by computing a QuantumBool, which indicates wether the value is
327-
# invalid and the controlling the multiplication on this QuantumBool.
328-
if treat_invalid:
329-
a.__class__ = QuantumFloat
330-
reduced = a < a.modulus
331-
a.__class__ = QuantumModulus
332-
ctrl = [ctrl, reduced[0]]
333-
334-
with fast_append():
321+
with fast_append(3):
322+
323+
# Create the temporary value
324+
tmp = a.duplicate(qs = a.qs)
325+
326+
# If treat_invalid is set to True, the function should leave the invalid values
327+
# invariant. That is, values that are bigger than the modulus N.
328+
329+
# We achieve this by computing a QuantumBool, which indicates wether the value is
330+
# invalid and the controlling the multiplication on this QuantumBool.
331+
if treat_invalid:
332+
a.__class__ = QuantumFloat
333+
reduced = a < a.modulus
334+
a.__class__ = QuantumModulus
335+
ctrl = [ctrl, reduced[0]]
336+
335337
# If the controlled version of this function is required, we perform the swapping
336338
# strategy from above.
337339
if ctrl is not None:

src/qrisp/circuit/operation.py

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,8 @@ def __init__(
9393
params = init_op.params
9494
definition = init_op.definition
9595

96-
try:
97-
unitary = init_op.unitary
98-
except AttributeError:
99-
pass
100-
else:
101-
if name is None:
102-
raise Exception("Tried to create a Operation object without name")
96+
elif not isinstance(name, str):
97+
raise Exception("Tried to create a Operation with name of type({type(name)} (required is str)")
10398

10499
# Name of the operation - this is how the backend behind the interface will
105100
# identify the operation
@@ -114,9 +109,20 @@ def __init__(
114109
# List of parameters (also available behind the interface)
115110
self.params = []
116111

117-
# Find abstract parameters (ie. sympy expressions and log them)
118-
self.abstract_params = set([])
112+
# If a definition circuit is given, this means we are supposed to create a
113+
# non-elementary operation
114+
if definition is not None:
115+
# Copy circuit in order to prevent modification
116+
# self.definition = QuantumCircuit(init_qc = definition)
117+
self.definition = definition
118+
119+
self.abstract_params = set(definition.abstract_params)
120+
else:
121+
self.definition = None
122+
self.abstract_params = set()
123+
119124

125+
# Find abstract parameters (ie. sympy expressions and log them)
120126
for par in params:
121127
if isinstance(par, (float, int, np.floating, np.int32)):
122128
pass
@@ -129,20 +135,6 @@ def __init__(
129135

130136
self.params.append(par)
131137

132-
# If a definition circuit is given, this means we are supposed to create a
133-
# non-elementary operation
134-
if definition is not None:
135-
# Copy circuit in order to prevent modification
136-
# self.definition = QuantumCircuit(init_qc = definition)
137-
self.definition = definition
138-
139-
self.abstract_params = self.abstract_params.union(
140-
definition.abstract_params
141-
)
142-
143-
else:
144-
self.definition = None
145-
146138
# These attributes store some information for the uncomputation algorithm
147139
# Qfree basically means that the unitary is a permutation matrix
148140
# (up to local phase shifts). Permeability means that this gate commutes with

src/qrisp/circuit/quantum_circuit.py

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -213,17 +213,12 @@ def __init__(self, num_qubits=0, num_clbits=0, name=None):
213213
object.__setattr__(self, "qubits", [])
214214
object.__setattr__(self, "clbits", [])
215215

216-
self.abstract_params = set([])
217-
218-
if name is None:
219-
self.name = "circuit_" + str(id(self))[-5:]
220-
else:
221-
self.name = name
216+
self.abstract_params = set()
222217

223218
if isinstance(num_qubits, int):
224219
for i in range(num_qubits):
225-
self.qubit_index_counter[0] += 1
226-
self.qubits.append(Qubit("qb_" + str(self.qubit_index_counter[0])))
220+
self.qubits.append(Qubit("qb_" + str(self.qubit_index_counter[0]+i)))
221+
self.qubit_index_counter[0] += num_qubits
227222
else:
228223
raise Exception(
229224
f"Tried to initialize QuantumCircuit with type {type(num_qubits)}"
@@ -237,8 +232,6 @@ def __init__(self, num_qubits=0, num_clbits=0, name=None):
237232
f"Tried to initialize QuantumCircuit with type {type(num_clbits)}"
238233
)
239234

240-
self.last_qubit_count = -1
241-
242235
# Method to add qubit objects to the circuit
243236
def add_qubit(self, qubit=None):
244237
"""
@@ -266,16 +259,19 @@ def add_qubit(self, qubit=None):
266259
"""
267260

268261
self.qubit_index_counter += 1
262+
269263
if qubit is None:
270264
qubit = Qubit("qb_" + str(self.qubit_index_counter[0]))
265+
266+
if self.xla_mode < 2:
267+
for qb in self.qubits:
268+
if qb.identifier == qubit.identifier:
269+
raise Exception(f"Qubit name {qubit.identifier} already exists")
270+
271271

272272
if not isinstance(qubit, Qubit):
273273
raise Exception(f"Tried to add type {type(qubit)} as a qubit")
274274

275-
for qb in self.qubits:
276-
if qb.identifier == qubit.identifier:
277-
raise Exception(f"Qubit name {qubit.identifier} already exists")
278-
279275
self.qubits.append(qubit)
280276

281277
return self.qubits[-1]
@@ -344,7 +340,7 @@ def to_op(self, name=None):
344340
"""
345341

346342
if name is None:
347-
name = self.name
343+
name = "circuit" + str(id(self))[:5]
348344

349345
definition = self.copy()
350346
i = 0
@@ -508,8 +504,6 @@ def copy(self):
508504

509505
return res
510506

511-
return QuantumCircuit(init_qc=self)
512-
513507
# Returns a copy of self but with no instructions
514508
def clearcopy(self):
515509
"""

src/qrisp/core/quantum_session.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import numpy as np
2222

23-
from qrisp.circuit import Clbit, QuantumCircuit, Qubit, QubitAlloc, QubitDealloc
23+
from qrisp.circuit import Clbit, QuantumCircuit, Qubit, QubitAlloc, QubitDealloc, Instruction, Operation
2424
from qrisp.core.session_merging_tools import multi_session_merge
2525
from qrisp.misc import get_depth_dic
2626

@@ -436,16 +436,17 @@ def logic_synth(self, input_qubits, output_qubits, tt, method="best", inv=False)
436436

437437
def __eq__(self, other):
438438
return id(self.data) == id(other.data)
439-
439+
440440
def append(self, operation_or_instruction, qubits=[], clbits=[]):
441441
# Check the type of the instruction/operation
442-
from qrisp.circuit import Instruction, Operation
443-
442+
443+
444444
if issubclass(operation_or_instruction.__class__, Instruction):
445445
instruction = operation_or_instruction
446446
self.append(instruction.op, instruction.qubits, instruction.clbits)
447447
return
448-
448+
449+
449450
elif issubclass(operation_or_instruction.__class__, Operation):
450451
operation = operation_or_instruction
451452

@@ -466,7 +467,7 @@ def append(self, operation_or_instruction, qubits=[], clbits=[]):
466467
if operation.name == "qb_dealloc":
467468
qubits[0].allocated = False
468469
return
469-
470+
470471
# Convert arguments (possibly integers) to list
471472
# The logic here is that the list structure gets preserved ie.
472473
# [[0, 1] ,2] ==> [[qubit_0, qubit_1], qubit_2]

src/qrisp/environments/custom_control_environment.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from qrisp.environments.quantum_environments import QuantumEnvironment
2020
from qrisp.environments.gate_wrap_environment import GateWrapEnvironment
21-
from qrisp.circuit import Operation, QuantumCircuit
21+
from qrisp.circuit import Operation, QuantumCircuit, Instruction
2222
from qrisp.environments.iteration_environment import IterationEnvironment
2323

2424
def custom_control(func):
@@ -219,16 +219,14 @@ def __init__(self, init_op, targeting_control = False):
219219

220220
if not targeting_control:
221221
definition = QuantumCircuit(init_op.num_qubits + 1, init_op.num_clbits)
222-
definition.append(init_op, definition.qubits[1:], definition.clbits)
222+
definition.data.append(Instruction(init_op, definition.qubits[1:], definition.clbits))
223223

224224
Operation.__init__(self, name = "cusc_" + init_op.name, num_qubits = init_op.num_qubits + 1, num_clbits = init_op.num_clbits, definition = definition)
225225

226226
self.init_op = init_op
227227

228-
self.permeability = {}
228+
self.permeability = {i+1 : init_op.permeability[i] for i in range(init_op.num_qubits)}
229229
self.permeability[0] = True
230-
for i in range(init_op.num_qubits):
231-
self.permeability[i+1] = init_op.permeability[i]
232230

233231
self.is_qfree = init_op.is_qfree
234232
else:

src/qrisp/environments/iteration_environment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def __enter__(self):
147147

148148
def __exit__(self, exception_type, exception_value, traceback):
149149

150-
if set(self.env_qs.qv_list) != self.inital_qvs:
150+
if set(self.env_qs.qv_list) != self.inital_qvs and self.iteration_amount > 1:
151151

152152
if exception_value is None:
153153
raise Exception(

0 commit comments

Comments
 (0)