pyqrack-cuda 1.44.7__tar.gz → 1.44.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/Makefile +1 -1
- {pyqrack_cuda-1.44.7/pyqrack_cuda.egg-info → pyqrack_cuda-1.44.9}/PKG-INFO +1 -1
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/__init__.py +5 -1
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/neuron_activation_fn.py +1 -1
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/qrack_ace_backend.py +77 -100
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/qrack_circuit.py +67 -39
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/qrack_neuron.py +25 -8
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/qrack_neuron_torch_layer.py +46 -19
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/qrack_simulator.py +547 -211
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/qrack_stabilizer.py +1 -2
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/qrack_system/qrack_system.py +161 -119
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/stats/load_quantized_data.py +3 -1
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/stats/quantize_by_range.py +9 -4
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/setup.py +1 -1
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/LICENSE +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/MANIFEST.in +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/README.md +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyproject.toml +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/pauli.py +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/qrack_system/qrack_lib/libqrack_pinvoke.so +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack_cuda.egg-info/SOURCES.txt +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack_cuda.egg-info/requires.txt +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/pyqrack_cuda.egg-info/top_level.txt +0 -0
- {pyqrack_cuda-1.44.7 → pyqrack_cuda-1.44.9}/setup.cfg +0 -0
@@ -18,7 +18,7 @@ help:
|
|
18
18
|
build-deps:
|
19
19
|
ifneq ($(OS),Windows_NT)
|
20
20
|
ifeq ($(QRACK_PRESENT),)
|
21
|
-
git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout
|
21
|
+
git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout ce668dd0177a28b52da4fb66380cd51fafd39a56; cd ..
|
22
22
|
endif
|
23
23
|
mkdir -p qrack/build
|
24
24
|
ifeq ($(UNAME_S),Linux)
|
@@ -9,7 +9,11 @@ from .quimb_circuit_type import QuimbCircuitType
|
|
9
9
|
from .qrack_ace_backend import QrackAceBackend
|
10
10
|
from .qrack_circuit import QrackCircuit
|
11
11
|
from .qrack_neuron import QrackNeuron
|
12
|
-
from .qrack_neuron_torch_layer import
|
12
|
+
from .qrack_neuron_torch_layer import (
|
13
|
+
QrackTorchNeuron,
|
14
|
+
QrackNeuronFunction,
|
15
|
+
QrackNeuronTorchLayer,
|
16
|
+
)
|
13
17
|
from .qrack_simulator import QrackSimulator
|
14
18
|
from .qrack_stabilizer import QrackStabilizer
|
15
19
|
from .qrack_system import QrackSystem, Qrack
|
@@ -26,11 +26,10 @@ class QrackAceBackend:
|
|
26
26
|
This back end uses elided repetition code on a nearest-neighbor topology to emulate
|
27
27
|
a utility-scale superconducting chip quantum computer in very little memory.4
|
28
28
|
|
29
|
-
The backend was originally designed assuming
|
30
|
-
However, it quickly became apparent that users can basically design their own
|
31
|
-
|
32
|
-
|
33
|
-
Sycamore-like topologies, leave it "True.")
|
29
|
+
The backend was originally designed assuming an (orbifolded) 2D qubit grid like 2019 Sycamore.
|
30
|
+
However, it quickly became apparent that users can basically design their own connectivity topologies,
|
31
|
+
without breaking the concept. (Not all will work equally well.) For maximum flexibility, set
|
32
|
+
"alternating_codes=False". (For best performance on Sycamore-like topologies,leave it "True.")
|
34
33
|
|
35
34
|
Attributes:
|
36
35
|
sim(QrackSimulator): Corresponding simulator.
|
@@ -39,20 +38,14 @@ class QrackAceBackend:
|
|
39
38
|
col_length(int): Qubits per column.
|
40
39
|
"""
|
41
40
|
|
42
|
-
def __init__(
|
43
|
-
self,
|
44
|
-
qubit_count=-1,
|
45
|
-
alternating_codes=True,
|
46
|
-
toClone=None
|
47
|
-
):
|
41
|
+
def __init__(self, qubit_count=-1, alternating_codes=True, toClone=None):
|
48
42
|
self.sim = toClone.sim.clone() if toClone else QrackSimulator(3 * qubit_count)
|
49
43
|
self._factor_width(qubit_count)
|
50
44
|
self.alternating_codes = alternating_codes
|
51
45
|
|
52
|
-
|
53
46
|
def _factor_width(self, width):
|
54
47
|
col_len = math.floor(math.sqrt(width))
|
55
|
-
while ((
|
48
|
+
while ((width // col_len) * col_len) != width:
|
56
49
|
col_len -= 1
|
57
50
|
row_len = width // col_len
|
58
51
|
|
@@ -68,48 +61,44 @@ class QrackAceBackend:
|
|
68
61
|
|
69
62
|
return p1, q2
|
70
63
|
|
71
|
-
|
72
64
|
def _cz_shadow(self, q1, q2):
|
73
65
|
prob_max, t = self._ct_pair_prob(q1, q2)
|
74
66
|
if prob_max > 0.5:
|
75
67
|
self.sim.z(t)
|
76
68
|
|
77
|
-
|
78
69
|
def _anti_cz_shadow(self, q1, q2):
|
79
70
|
self.sim.x(q1)
|
80
71
|
self._cz_shadow(q1, q2)
|
81
72
|
self.sim.x(q1)
|
82
73
|
|
83
|
-
|
84
74
|
def _cx_shadow(self, c, t):
|
85
75
|
self.sim.h(t)
|
86
76
|
self._cz_shadow(c, t)
|
87
77
|
self.sim.h(t)
|
88
78
|
|
89
|
-
|
90
79
|
def _anti_cx_shadow(self, c, t):
|
91
80
|
self.sim.x(t)
|
92
81
|
self._cx_shadow(c, t)
|
93
82
|
self.sim.x(t)
|
94
83
|
|
95
|
-
|
96
84
|
def _cy_shadow(self, c, t):
|
97
85
|
self.sim.adjs(t)
|
98
86
|
self._cx_shadow(c, t)
|
99
87
|
self.sim.s(t)
|
100
88
|
|
101
|
-
|
102
89
|
def _anti_cy_shadow(self, c, t):
|
103
90
|
self.sim.x(t)
|
104
91
|
self._cy_shadow(c, t)
|
105
92
|
self.sim.x(t)
|
106
93
|
|
94
|
+
def _unpack(self, lq, reverse=False):
|
95
|
+
return (
|
96
|
+
[3 * lq + 2, 3 * lq + 1, 3 * lq]
|
97
|
+
if reverse
|
98
|
+
else [3 * lq, 3 * lq + 1, 3 * lq + 2]
|
99
|
+
)
|
107
100
|
|
108
|
-
def
|
109
|
-
return [3 * lq + 2, 3 * lq + 1, 3 * lq] if reverse else [3 * lq, 3 * lq + 1, 3 * lq + 2]
|
110
|
-
|
111
|
-
|
112
|
-
def _encode(self, hq, reverse = False):
|
101
|
+
def _encode(self, hq, reverse=False):
|
113
102
|
row = (hq[0] // 3) // self.row_length
|
114
103
|
even_row = not (row & 1)
|
115
104
|
if ((not self.alternating_codes) and reverse) or (even_row == reverse):
|
@@ -119,8 +108,7 @@ class QrackAceBackend:
|
|
119
108
|
self.sim.mcx([hq[0]], hq[1])
|
120
109
|
self._cx_shadow(hq[1], hq[2])
|
121
110
|
|
122
|
-
|
123
|
-
def _decode(self, hq, reverse = False):
|
111
|
+
def _decode(self, hq, reverse=False):
|
124
112
|
row = (hq[0] // 3) // self.row_length
|
125
113
|
even_row = not (row & 1)
|
126
114
|
if ((not self.alternating_codes) and reverse) or (even_row == reverse):
|
@@ -130,77 +118,66 @@ class QrackAceBackend:
|
|
130
118
|
self._cx_shadow(hq[1], hq[2])
|
131
119
|
self.sim.mcx([hq[0]], hq[1])
|
132
120
|
|
133
|
-
|
134
121
|
def u(self, th, ph, lm, lq):
|
135
122
|
hq = self._unpack(lq)
|
136
123
|
self._decode(hq)
|
137
124
|
self.sim.u(hq[0], th, ph, lm)
|
138
125
|
self._encode(hq)
|
139
126
|
|
140
|
-
|
141
127
|
def r(self, p, th, lq):
|
142
128
|
hq = self._unpack(lq)
|
143
129
|
self._decode(hq)
|
144
130
|
self.sim.r(p, th, hq[0])
|
145
131
|
self._encode(hq)
|
146
132
|
|
147
|
-
|
148
133
|
def s(self, lq):
|
149
134
|
hq = self._unpack(lq)
|
150
135
|
self._decode(hq)
|
151
136
|
self.sim.s(hq[0])
|
152
137
|
self._encode(hq)
|
153
138
|
|
154
|
-
|
155
139
|
def adjs(self, lq):
|
156
140
|
hq = self._unpack(lq)
|
157
141
|
self._decode(hq)
|
158
142
|
self.sim.adjs(hq[0])
|
159
143
|
self._encode(hq)
|
160
144
|
|
161
|
-
|
162
145
|
def x(self, lq):
|
163
146
|
hq = self._unpack(lq)
|
164
147
|
self._decode(hq)
|
165
148
|
self.sim.x(hq[0])
|
166
149
|
self._encode(hq)
|
167
150
|
|
168
|
-
|
169
151
|
def y(self, lq):
|
170
152
|
hq = self._unpack(lq)
|
171
153
|
self._decode(hq)
|
172
154
|
self.sim.y(hq[0])
|
173
155
|
self._encode(hq)
|
174
156
|
|
175
|
-
|
176
157
|
def z(self, lq):
|
177
158
|
hq = self._unpack(lq)
|
178
159
|
self._decode(hq)
|
179
160
|
self.sim.z(hq[0])
|
180
161
|
self._encode(hq)
|
181
162
|
|
182
|
-
|
183
163
|
def h(self, lq):
|
184
164
|
hq = self._unpack(lq)
|
185
165
|
self._decode(hq)
|
186
166
|
self.sim.h(hq[0])
|
187
167
|
self._encode(hq)
|
188
168
|
|
189
|
-
|
190
169
|
def t(self, lq):
|
191
170
|
hq = self._unpack(lq)
|
192
171
|
self._decode(hq)
|
193
172
|
self.sim.t(hq[0])
|
194
173
|
self._encode(hq)
|
195
174
|
|
196
|
-
|
197
175
|
def adjt(self, lq):
|
198
176
|
hq = self._unpack(lq)
|
199
177
|
self._decode(hq)
|
200
178
|
self.sim.adjt(hq[0])
|
201
179
|
self._encode(hq)
|
202
180
|
|
203
|
-
|
204
181
|
def _cpauli(self, lq1, lq2, anti, pauli):
|
205
182
|
gate = None
|
206
183
|
shadow = None
|
@@ -216,7 +193,12 @@ class QrackAceBackend:
|
|
216
193
|
else:
|
217
194
|
return
|
218
195
|
|
219
|
-
|
196
|
+
lq1_col = lq1 // self.row_length
|
197
|
+
lq1_row = lq1 % self.row_length
|
198
|
+
lq2_col = lq2 // self.row_length
|
199
|
+
lq2_row = lq2 % self.row_length
|
200
|
+
|
201
|
+
if (lq2_col == lq1_col) and (((lq1_row + 1) % self.row_length) == lq2_row):
|
220
202
|
hq1 = self._unpack(lq1, True)
|
221
203
|
hq2 = self._unpack(lq2, False)
|
222
204
|
self._decode(hq1, True)
|
@@ -224,7 +206,7 @@ class QrackAceBackend:
|
|
224
206
|
gate([hq1[0]], hq2[0])
|
225
207
|
self._encode(hq2, False)
|
226
208
|
self._encode(hq1, True)
|
227
|
-
elif
|
209
|
+
elif (lq1_col == lq2_col) and (((lq2_row + 1) % self.row_length) == lq1_row):
|
228
210
|
hq2 = self._unpack(lq2, True)
|
229
211
|
hq1 = self._unpack(lq1, False)
|
230
212
|
self._decode(hq2, True)
|
@@ -242,51 +224,41 @@ class QrackAceBackend:
|
|
242
224
|
gate([hq1[1]], hq2[1])
|
243
225
|
gate([hq1[2]], hq2[2])
|
244
226
|
|
245
|
-
|
246
227
|
def cx(self, lq1, lq2):
|
247
228
|
self._cpauli(lq1, lq2, False, Pauli.PauliX)
|
248
229
|
|
249
|
-
|
250
230
|
def cy(self, lq1, lq2):
|
251
231
|
self._cpauli(lq1, lq2, False, Pauli.PauliY)
|
252
232
|
|
253
|
-
|
254
233
|
def cz(self, lq1, lq2):
|
255
234
|
self._cpauli(lq1, lq2, False, Pauli.PauliZ)
|
256
235
|
|
257
|
-
|
258
236
|
def acx(self, lq1, lq2):
|
259
237
|
self._cpauli(lq1, lq2, True, Pauli.PauliX)
|
260
238
|
|
261
|
-
|
262
239
|
def acy(self, lq1, lq2):
|
263
240
|
self._cpauli(lq1, lq2, True, Pauli.PauliY)
|
264
241
|
|
265
|
-
|
266
242
|
def acz(self, lq1, lq2):
|
267
243
|
self._cpauli(lq1, lq2, True, Pauli.PauliZ)
|
268
244
|
|
269
|
-
|
270
245
|
def swap(self, lq1, lq2):
|
271
246
|
self.cx(lq1, lq2)
|
272
247
|
self.cx(lq2, lq1)
|
273
248
|
self.cx(lq1, lq2)
|
274
249
|
|
275
|
-
|
276
250
|
def iswap(self, lq1, lq2):
|
277
251
|
self.swap(lq1, lq2)
|
278
252
|
self.cz(lq1, lq2)
|
279
253
|
self.s(lq1)
|
280
254
|
self.s(lq2)
|
281
255
|
|
282
|
-
|
283
256
|
def adjiswap(self, lq1, lq2):
|
284
257
|
self.adjs(lq2)
|
285
258
|
self.adjs(lq1)
|
286
259
|
self.cz(lq1, lq2)
|
287
260
|
self.swap(lq1, lq2)
|
288
261
|
|
289
|
-
|
290
262
|
def m(self, lq):
|
291
263
|
hq = self._unpack(lq)
|
292
264
|
syndrome = 0
|
@@ -296,13 +268,12 @@ class QrackAceBackend:
|
|
296
268
|
if bits[-1]:
|
297
269
|
syndrome += 1
|
298
270
|
result = True if (syndrome > 1) else False
|
299
|
-
for i in range(len(hq)):
|
271
|
+
for i in range(len(hq)):
|
300
272
|
if bits[i] != result:
|
301
273
|
self.sim.x(hq[i])
|
302
274
|
|
303
275
|
return result
|
304
276
|
|
305
|
-
|
306
277
|
def m_all(self):
|
307
278
|
result = 0
|
308
279
|
for lq in range(self.sim.num_qubits() // 3):
|
@@ -312,7 +283,6 @@ class QrackAceBackend:
|
|
312
283
|
|
313
284
|
return result
|
314
285
|
|
315
|
-
|
316
286
|
def measure_shots(self, q, s):
|
317
287
|
_q = []
|
318
288
|
for i in q:
|
@@ -338,15 +308,14 @@ class QrackAceBackend:
|
|
338
308
|
|
339
309
|
return results
|
340
310
|
|
341
|
-
|
342
311
|
def _apply_op(self, operation):
|
343
312
|
name = operation.name
|
344
313
|
|
345
|
-
if (name ==
|
314
|
+
if (name == "id") or (name == "barrier"):
|
346
315
|
# Skip measurement logic
|
347
316
|
return
|
348
317
|
|
349
|
-
conditional = getattr(operation,
|
318
|
+
conditional = getattr(operation, "conditional", None)
|
350
319
|
if isinstance(conditional, int):
|
351
320
|
conditional_bit_set = (self._classical_register >> conditional) & 1
|
352
321
|
if not conditional_bit_set:
|
@@ -361,77 +330,83 @@ class QrackAceBackend:
|
|
361
330
|
if value != int(conditional.val, 16):
|
362
331
|
return
|
363
332
|
|
364
|
-
if (name ==
|
333
|
+
if (name == "u1") or (name == "p"):
|
365
334
|
self._sim.u(0, 0, float(operation.params[0]), operation.qubits[0]._index)
|
366
|
-
elif name ==
|
335
|
+
elif name == "u2":
|
367
336
|
self._sim.u(
|
368
337
|
math.pi / 2,
|
369
338
|
float(operation.params[0]),
|
370
339
|
float(operation.params[1]),
|
371
|
-
operation.qubits[0]._index
|
340
|
+
operation.qubits[0]._index,
|
372
341
|
)
|
373
|
-
elif (name ==
|
342
|
+
elif (name == "u3") or (name == "u"):
|
374
343
|
self._sim.u(
|
375
344
|
float(operation.params[0]),
|
376
345
|
float(operation.params[1]),
|
377
346
|
float(operation.params[2]),
|
378
|
-
operation.qubits[0]._index
|
347
|
+
operation.qubits[0]._index,
|
379
348
|
)
|
380
|
-
elif name ==
|
349
|
+
elif name == "r":
|
381
350
|
self._sim.u(
|
382
351
|
float(operation.params[0]),
|
383
352
|
float(operation.params[1]) - math.pi / 2,
|
384
353
|
(-1 * float(operation.params[1])) + math.pi / 2,
|
385
|
-
operation.qubits[0]._index
|
354
|
+
operation.qubits[0]._index,
|
386
355
|
)
|
387
|
-
elif name ==
|
388
|
-
self._sim.r(
|
389
|
-
|
390
|
-
|
391
|
-
elif name ==
|
392
|
-
self._sim.r(
|
393
|
-
|
356
|
+
elif name == "rx":
|
357
|
+
self._sim.r(
|
358
|
+
Pauli.PauliX, float(operation.params[0]), operation.qubits[0]._index
|
359
|
+
)
|
360
|
+
elif name == "ry":
|
361
|
+
self._sim.r(
|
362
|
+
Pauli.PauliY, float(operation.params[0]), operation.qubits[0]._index
|
363
|
+
)
|
364
|
+
elif name == "rz":
|
365
|
+
self._sim.r(
|
366
|
+
Pauli.PauliZ, float(operation.params[0]), operation.qubits[0]._index
|
367
|
+
)
|
368
|
+
elif name == "h":
|
394
369
|
self._sim.h(operation.qubits[0]._index)
|
395
|
-
elif name ==
|
370
|
+
elif name == "x":
|
396
371
|
self._sim.x(operation.qubits[0]._index)
|
397
|
-
elif name ==
|
372
|
+
elif name == "y":
|
398
373
|
self._sim.y(operation.qubits[0]._index)
|
399
|
-
elif name ==
|
374
|
+
elif name == "z":
|
400
375
|
self._sim.z(operation.qubits[0]._index)
|
401
|
-
elif name ==
|
376
|
+
elif name == "s":
|
402
377
|
self._sim.s(operation.qubits[0]._index)
|
403
|
-
elif name ==
|
378
|
+
elif name == "sdg":
|
404
379
|
self._sim.adjs(operation.qubits[0]._index)
|
405
|
-
elif name ==
|
380
|
+
elif name == "t":
|
406
381
|
self._sim.t(operation.qubits[0]._index)
|
407
|
-
elif name ==
|
382
|
+
elif name == "tdg":
|
408
383
|
self._sim.adjt(operation.qubits[0]._index)
|
409
|
-
elif name ==
|
384
|
+
elif name == "cx":
|
410
385
|
self._sim.cx(operation.qubits[0]._index, operation.qubits[1]._index)
|
411
|
-
elif name ==
|
386
|
+
elif name == "cy":
|
412
387
|
self._sim.cy(operation.qubits[0]._index, operation.qubits[1]._index)
|
413
|
-
elif name ==
|
388
|
+
elif name == "cz":
|
414
389
|
self._sim.cz(operation.qubits[0]._index, operation.qubits[1]._index)
|
415
|
-
elif name ==
|
390
|
+
elif name == "dcx":
|
416
391
|
self._sim.mcx(operation.qubits[0]._index, operation.qubits[1]._index)
|
417
392
|
self._sim.mcx(operation.qubits[1]._index, operation.qubits[0]._index)
|
418
|
-
elif name ==
|
393
|
+
elif name == "swap":
|
419
394
|
self._sim.swap(operation.qubits[0]._index, operation.qubits[1]._index)
|
420
|
-
elif name ==
|
395
|
+
elif name == "iswap":
|
421
396
|
self._sim.iswap(operation.qubits[0]._index, operation.qubits[1]._index)
|
422
|
-
elif name ==
|
397
|
+
elif name == "iswap_dg":
|
423
398
|
self._sim.adjiswap(operation.qubits[0]._index, operation.qubits[1]._index)
|
424
|
-
elif name ==
|
399
|
+
elif name == "reset":
|
425
400
|
qubits = operation.qubits
|
426
401
|
for qubit in qubits:
|
427
402
|
if self._sim.m(qubit._index):
|
428
403
|
self._sim.x(qubit._index)
|
429
|
-
elif name ==
|
404
|
+
elif name == "measure":
|
430
405
|
qubits = operation.qubits
|
431
406
|
clbits = operation.clbits
|
432
407
|
cregbits = (
|
433
408
|
operation.register
|
434
|
-
if hasattr(operation,
|
409
|
+
if hasattr(operation, "register")
|
435
410
|
else len(operation.qubits) * [-1]
|
436
411
|
)
|
437
412
|
|
@@ -458,30 +433,30 @@ class QrackAceBackend:
|
|
458
433
|
self._classical_register & (~regbit)
|
459
434
|
) | (qubit_outcome << cregbit)
|
460
435
|
|
461
|
-
elif name ==
|
436
|
+
elif name == "bfunc":
|
462
437
|
mask = int(operation.mask, 16)
|
463
438
|
relation = operation.relation
|
464
439
|
val = int(operation.val, 16)
|
465
440
|
|
466
441
|
cregbit = operation.register
|
467
|
-
cmembit = operation.memory if hasattr(operation,
|
442
|
+
cmembit = operation.memory if hasattr(operation, "memory") else None
|
468
443
|
|
469
444
|
compared = (self._classical_register & mask) - val
|
470
445
|
|
471
|
-
if relation ==
|
446
|
+
if relation == "==":
|
472
447
|
outcome = compared == 0
|
473
|
-
elif relation ==
|
448
|
+
elif relation == "!=":
|
474
449
|
outcome = compared != 0
|
475
|
-
elif relation ==
|
450
|
+
elif relation == "<":
|
476
451
|
outcome = compared < 0
|
477
|
-
elif relation ==
|
452
|
+
elif relation == "<=":
|
478
453
|
outcome = compared <= 0
|
479
|
-
elif relation ==
|
454
|
+
elif relation == ">":
|
480
455
|
outcome = compared > 0
|
481
|
-
elif relation ==
|
456
|
+
elif relation == ">=":
|
482
457
|
outcome = compared >= 0
|
483
458
|
else:
|
484
|
-
raise QrackError(
|
459
|
+
raise QrackError("Invalid boolean function relation.")
|
485
460
|
|
486
461
|
# Store outcome in register and optionally memory slot
|
487
462
|
regbit = 1 << cregbit
|
@@ -524,7 +499,9 @@ class QrackAceBackend:
|
|
524
499
|
result |= qubit_outcome << index
|
525
500
|
measure_results = [result]
|
526
501
|
else:
|
527
|
-
measure_results = self._sim.measure_shots(
|
502
|
+
measure_results = self._sim.measure_shots(
|
503
|
+
[q._index for q in measure_qubit], num_samples
|
504
|
+
)
|
528
505
|
|
529
506
|
data = []
|
530
507
|
for sample in measure_results:
|
@@ -566,21 +543,21 @@ class QrackAceBackend:
|
|
566
543
|
for opcount in range(len(instructions)):
|
567
544
|
operation = instructions[opcount]
|
568
545
|
|
569
|
-
if operation.name ==
|
546
|
+
if operation.name == "id" or operation.name == "barrier":
|
570
547
|
continue
|
571
548
|
|
572
549
|
if is_initializing and (
|
573
|
-
(operation.name ==
|
550
|
+
(operation.name == "measure") or (operation.name == "reset")
|
574
551
|
):
|
575
552
|
continue
|
576
553
|
|
577
554
|
is_initializing = False
|
578
555
|
|
579
|
-
if (operation.name ==
|
556
|
+
if (operation.name == "measure") or (operation.name == "reset"):
|
580
557
|
if boundary_start == -1:
|
581
558
|
boundary_start = opcount
|
582
559
|
|
583
|
-
if (boundary_start != -1) and (operation.name !=
|
560
|
+
if (boundary_start != -1) and (operation.name != "measure"):
|
584
561
|
shotsPerLoop = 1
|
585
562
|
shotLoopMax = self._shots
|
586
563
|
self._sample_measure = False
|