pyqrack-cuda 1.46.6__tar.gz → 1.47.0__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.46.6/pyqrack_cuda.egg-info → pyqrack_cuda-1.47.0}/PKG-INFO +1 -1
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/qrack_ace_backend.py +252 -122
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/setup.py +1 -1
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/LICENSE +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/MANIFEST.in +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/Makefile +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/README.md +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyproject.toml +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/__init__.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/pauli.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack_cuda.egg-info/SOURCES.txt +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack_cuda.egg-info/requires.txt +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/pyqrack_cuda.egg-info/top_level.txt +0 -0
- {pyqrack_cuda-1.46.6 → pyqrack_cuda-1.47.0}/setup.cfg +0 -0
@@ -34,6 +34,7 @@ class QrackAceBackend:
|
|
34
34
|
Attributes:
|
35
35
|
sim(QrackSimulator): Corresponding simulator.
|
36
36
|
alternating_codes(bool): Alternate repetition code elision by index?
|
37
|
+
recursive_stack_depth(int): How many recursive nestings?
|
37
38
|
row_length(int): Qubits per row.
|
38
39
|
col_length(int): Qubits per column.
|
39
40
|
"""
|
@@ -41,8 +42,10 @@ class QrackAceBackend:
|
|
41
42
|
def __init__(
|
42
43
|
self,
|
43
44
|
qubit_count=1,
|
45
|
+
long_range_rows=0,
|
44
46
|
recursive_stack_depth=1,
|
45
47
|
alternating_codes=True,
|
48
|
+
reverse_row_and_col=False,
|
46
49
|
isTensorNetwork=False,
|
47
50
|
isStabilizerHybrid=False,
|
48
51
|
isBinaryDecisionTree=False,
|
@@ -53,39 +56,72 @@ class QrackAceBackend:
|
|
53
56
|
recursive_stack_depth = toClone.recursive_stack_depth
|
54
57
|
if recursive_stack_depth < 1:
|
55
58
|
recursive_stack_depth = 1
|
59
|
+
if long_range_rows < 0:
|
60
|
+
long_range_rows = 0
|
61
|
+
|
56
62
|
self.recursive_stack_depth = recursive_stack_depth
|
63
|
+
self._factor_width(qubit_count, reverse_row_and_col)
|
64
|
+
self.alternating_codes = alternating_codes
|
65
|
+
self._is_init = [False] * qubit_count
|
66
|
+
|
67
|
+
col_seq = [False] + [True] * long_range_rows
|
68
|
+
self._is_col_long_range = col_seq * (self.row_length // len(col_seq))
|
69
|
+
self._is_col_long_range += [True] * (
|
70
|
+
self.row_length - len(self._is_col_long_range)
|
71
|
+
)
|
72
|
+
self._hardware_offset = []
|
73
|
+
tot_qubits = 0
|
74
|
+
for _ in range(self.row_length):
|
75
|
+
for c in self._is_col_long_range:
|
76
|
+
self._hardware_offset.append(tot_qubits)
|
77
|
+
tot_qubits += 1 if c else 3
|
78
|
+
self._ancilla = tot_qubits
|
79
|
+
tot_qubits += 1
|
80
|
+
|
57
81
|
if recursive_stack_depth > 1:
|
58
82
|
recursive_stack_depth -= 1
|
59
83
|
self.sim = (
|
60
84
|
toClone.sim
|
61
85
|
if toClone
|
62
|
-
else QrackAceBackend(
|
86
|
+
else QrackAceBackend(
|
87
|
+
tot_qubits,
|
88
|
+
recursive_stack_depth,
|
89
|
+
alternating_codes,
|
90
|
+
reverse_row_and_col,
|
91
|
+
isTensorNetwork,
|
92
|
+
isStabilizerHybrid,
|
93
|
+
isBinaryDecisionTree,
|
94
|
+
)
|
63
95
|
)
|
96
|
+
# This leaves an "odd-man-out" ancillary qubit.
|
97
|
+
self.sim.row_length = 3 * self.row_length
|
98
|
+
self.sim.col_length = self.col_length
|
64
99
|
else:
|
65
100
|
self.sim = (
|
66
101
|
toClone.sim.clone()
|
67
102
|
if toClone
|
68
|
-
else QrackSimulator(
|
103
|
+
else QrackSimulator(
|
104
|
+
tot_qubits,
|
105
|
+
isTensorNetwork=isTensorNetwork,
|
106
|
+
isStabilizerHybrid=isStabilizerHybrid,
|
107
|
+
isBinaryDecisionTree=isBinaryDecisionTree,
|
108
|
+
)
|
69
109
|
)
|
70
|
-
self._ancilla = 3 * qubit_count
|
71
|
-
self._factor_width(qubit_count)
|
72
|
-
self.alternating_codes = alternating_codes
|
73
|
-
self._is_init = [False] * qubit_count
|
74
110
|
|
75
111
|
def clone(self):
|
76
112
|
return QrackAceBackend(toClone=self)
|
77
113
|
|
78
114
|
def num_qubits(self):
|
79
|
-
return self.
|
115
|
+
return self.row_length * self.col_length
|
80
116
|
|
81
|
-
def _factor_width(self, width):
|
117
|
+
def _factor_width(self, width, reverse=False):
|
82
118
|
col_len = math.floor(math.sqrt(width))
|
83
119
|
while ((width // col_len) * col_len) != width:
|
84
120
|
col_len -= 1
|
85
121
|
row_len = width // col_len
|
86
122
|
|
87
|
-
self.col_length = col_len
|
88
|
-
self.row_length = row_len
|
123
|
+
self.col_length = row_len if reverse else col_len
|
124
|
+
self.row_length = col_len if reverse else row_len
|
89
125
|
|
90
126
|
def _ct_pair_prob(self, q1, q2):
|
91
127
|
p1 = self.sim.prob(q1)
|
@@ -127,44 +163,39 @@ class QrackAceBackend:
|
|
127
163
|
self.sim.x(t)
|
128
164
|
|
129
165
|
def _unpack(self, lq, reverse=False):
|
166
|
+
offset = self._hardware_offset[lq]
|
167
|
+
|
168
|
+
if self._is_col_long_range[lq % self.row_length]:
|
169
|
+
return [offset]
|
170
|
+
|
130
171
|
return (
|
131
|
-
[
|
172
|
+
[offset + 2, offset + 1, offset]
|
132
173
|
if reverse
|
133
|
-
else [
|
174
|
+
else [offset, offset + 1, offset + 2]
|
134
175
|
)
|
135
176
|
|
136
|
-
def _encode(self, hq, reverse=False):
|
137
|
-
|
138
|
-
|
139
|
-
|
177
|
+
def _encode(self, lq, hq, reverse=False):
|
178
|
+
even_row = not ((lq // self.row_length) & 1)
|
179
|
+
# Encode shadow-first
|
180
|
+
if self._is_init[lq]:
|
181
|
+
self._cx_shadow(hq[0], hq[2])
|
140
182
|
if ((not self.alternating_codes) and reverse) or (even_row == reverse):
|
141
|
-
|
142
|
-
# Encode shadow-first
|
143
|
-
self._cx_shadow(hq[0], hq[1])
|
144
|
-
self.sim.mcx([hq[1]], hq[2])
|
145
|
-
else:
|
146
|
-
self.sim.mcx([hq[2]], hq[1])
|
183
|
+
self.sim.mcx([hq[2]], hq[1])
|
147
184
|
else:
|
148
|
-
if self._is_init[lq]:
|
149
|
-
# Encode shadow-first
|
150
|
-
self._cx_shadow(hq[0], hq[2])
|
151
185
|
self.sim.mcx([hq[0]], hq[1])
|
152
186
|
self._is_init[lq] = True
|
153
187
|
|
154
|
-
def _decode(self, hq, reverse=False):
|
155
|
-
lq = hq[0] // 3
|
188
|
+
def _decode(self, lq, hq, reverse=False):
|
156
189
|
if not self._is_init[lq]:
|
157
190
|
return
|
158
|
-
|
159
|
-
even_row = not (row & 1)
|
191
|
+
even_row = not ((lq // self.row_length) & 1)
|
160
192
|
if ((not self.alternating_codes) and reverse) or (even_row == reverse):
|
161
193
|
# Decode entangled-first
|
162
|
-
self.sim.mcx([hq[
|
163
|
-
self._cx_shadow(hq[0], hq[1])
|
194
|
+
self.sim.mcx([hq[2]], hq[1])
|
164
195
|
else:
|
165
196
|
# Decode entangled-first
|
166
197
|
self.sim.mcx([hq[0]], hq[1])
|
167
|
-
|
198
|
+
self._cx_shadow(hq[0], hq[2])
|
168
199
|
|
169
200
|
def _correct(self, lq):
|
170
201
|
if not self._is_init[lq]:
|
@@ -172,20 +203,23 @@ class QrackAceBackend:
|
|
172
203
|
# We can't use true syndrome-based error correction,
|
173
204
|
# because one of the qubits in the code is separated.
|
174
205
|
# However, we can get pretty close!
|
175
|
-
shots =
|
176
|
-
|
206
|
+
shots = 512
|
207
|
+
|
177
208
|
single_bit = 0
|
178
209
|
other_bits = []
|
179
|
-
if not self.alternating_codes or
|
210
|
+
if not self.alternating_codes or not ((lq // self.row_length) & 1):
|
180
211
|
single_bit = 2
|
181
212
|
other_bits = [0, 1]
|
182
213
|
else:
|
183
214
|
single_bit = 0
|
184
215
|
other_bits = [1, 2]
|
216
|
+
|
185
217
|
hq = self._unpack(lq)
|
218
|
+
|
186
219
|
single_bit_value = self.sim.prob(hq[single_bit])
|
187
220
|
single_bit_polarization = max(single_bit_value, 1 - single_bit_value)
|
188
221
|
samples = self.sim.measure_shots([hq[other_bits[0]], hq[other_bits[1]]], shots)
|
222
|
+
|
189
223
|
syndrome_indices = (
|
190
224
|
[other_bits[1], other_bits[0]]
|
191
225
|
if (single_bit_value >= 0.5)
|
@@ -268,6 +302,11 @@ class QrackAceBackend:
|
|
268
302
|
self._correct(lq)
|
269
303
|
|
270
304
|
def u(self, lq, th, ph, lm):
|
305
|
+
hq = self._unpack(lq)
|
306
|
+
if self._is_col_long_range[lq % self.row_length]:
|
307
|
+
self.sim.u(hq[0], th, ph, lm)
|
308
|
+
return
|
309
|
+
|
271
310
|
while ph > math.pi:
|
272
311
|
ph -= 2 * math.pi
|
273
312
|
while ph <= -math.pi:
|
@@ -276,81 +315,121 @@ class QrackAceBackend:
|
|
276
315
|
lm -= 2 * math.pi
|
277
316
|
while lm <= -math.pi:
|
278
317
|
lm += 2 * math.pi
|
279
|
-
|
318
|
+
|
280
319
|
if not math.isclose(ph, -lm) and not math.isclose(abs(ph), math.pi / 2):
|
320
|
+
# Produces/destroys superposition
|
281
321
|
self._correct_if_like_h(th, lq)
|
282
|
-
self._decode(hq)
|
322
|
+
self._decode(lq, hq)
|
283
323
|
self.sim.u(hq[0], th, ph, lm)
|
284
324
|
if not self._is_init[lq]:
|
285
325
|
self.sim.u(hq[2], th, ph, lm)
|
286
|
-
self._encode(hq)
|
326
|
+
self._encode(lq, hq)
|
287
327
|
else:
|
328
|
+
# Shouldn't produce/destroy superposition
|
288
329
|
for b in hq:
|
289
330
|
self.sim.u(b, th, ph, lm)
|
290
331
|
|
291
332
|
def r(self, p, th, lq):
|
333
|
+
hq = self._unpack(lq)
|
334
|
+
if self._is_col_long_range[lq % self.row_length]:
|
335
|
+
self.sim.r(p, th, hq[0])
|
336
|
+
return
|
337
|
+
|
292
338
|
while th > math.pi:
|
293
339
|
th -= 2 * math.pi
|
294
340
|
while th <= -math.pi:
|
295
341
|
th += 2 * math.pi
|
296
342
|
if p == Pauli.PauliY:
|
297
343
|
self._correct_if_like_h(th, lq)
|
298
|
-
|
344
|
+
|
299
345
|
if (p == Pauli.PauliZ) or math.isclose(abs(th), math.pi):
|
346
|
+
# Doesn't produce/destroy superposition
|
300
347
|
for b in hq:
|
301
348
|
self.sim.r(p, th, b)
|
302
349
|
else:
|
303
|
-
|
350
|
+
# Produces/destroys superposition
|
351
|
+
self._decode(lq, hq)
|
304
352
|
self.sim.r(p, th, hq[0])
|
305
353
|
if not self._is_init[lq]:
|
306
354
|
self.sim.r(p, th, hq[2])
|
307
|
-
self._encode(hq)
|
355
|
+
self._encode(lq, hq)
|
308
356
|
|
309
357
|
def h(self, lq):
|
310
358
|
hq = self._unpack(lq)
|
311
|
-
self.
|
359
|
+
if self._is_col_long_range[lq % self.row_length]:
|
360
|
+
self.sim.h(hq[0])
|
361
|
+
return
|
362
|
+
|
363
|
+
self._decode(lq, hq)
|
312
364
|
self.sim.h(hq[0])
|
313
365
|
if not self._is_init[lq]:
|
314
366
|
self.sim.h(hq[2])
|
315
|
-
self._encode(hq)
|
367
|
+
self._encode(lq, hq)
|
316
368
|
|
317
369
|
def s(self, lq):
|
318
370
|
hq = self._unpack(lq)
|
371
|
+
if self._is_col_long_range[lq % self.row_length]:
|
372
|
+
self.sim.s(hq[0])
|
373
|
+
return
|
374
|
+
|
319
375
|
for b in hq:
|
320
376
|
self.sim.s(b)
|
321
377
|
|
322
378
|
def adjs(self, lq):
|
323
379
|
hq = self._unpack(lq)
|
380
|
+
if self._is_col_long_range[lq % self.row_length]:
|
381
|
+
self.sim.adjs(hq[0])
|
382
|
+
return
|
383
|
+
|
324
384
|
for b in hq:
|
325
385
|
self.sim.adjs(b)
|
326
386
|
|
327
387
|
def x(self, lq):
|
328
388
|
hq = self._unpack(lq)
|
389
|
+
if self._is_col_long_range[lq % self.row_length]:
|
390
|
+
self.sim.x(hq[0])
|
391
|
+
return
|
392
|
+
|
329
393
|
for b in hq:
|
330
394
|
self.sim.x(b)
|
331
395
|
|
332
396
|
def y(self, lq):
|
333
397
|
hq = self._unpack(lq)
|
398
|
+
if self._is_col_long_range[lq % self.row_length]:
|
399
|
+
self.sim.y(hq[0])
|
400
|
+
return
|
401
|
+
|
334
402
|
for b in hq:
|
335
403
|
self.sim.y(b)
|
336
404
|
|
337
405
|
def z(self, lq):
|
338
406
|
hq = self._unpack(lq)
|
407
|
+
if self._is_col_long_range[lq % self.row_length]:
|
408
|
+
self.sim.z(hq[0])
|
409
|
+
return
|
410
|
+
|
339
411
|
for b in hq:
|
340
412
|
self.sim.z(b)
|
341
413
|
|
342
414
|
def t(self, lq):
|
343
415
|
hq = self._unpack(lq)
|
416
|
+
if self._is_col_long_range[lq % self.row_length]:
|
417
|
+
self.sim.t(hq[0])
|
418
|
+
return
|
419
|
+
|
344
420
|
for b in hq:
|
345
421
|
self.sim.t(b)
|
346
422
|
|
347
423
|
def adjt(self, lq):
|
348
424
|
hq = self._unpack(lq)
|
425
|
+
if self._is_col_long_range[lq % self.row_length]:
|
426
|
+
self.sim.adjt(hq[0])
|
427
|
+
return
|
428
|
+
|
349
429
|
for b in hq:
|
350
430
|
self.sim.adjt(b)
|
351
431
|
|
352
432
|
def _cpauli(self, lq1, lq2, anti, pauli):
|
353
|
-
self._correct(lq1)
|
354
433
|
gate = None
|
355
434
|
shadow = None
|
356
435
|
if pauli == Pauli.PauliX:
|
@@ -365,49 +444,104 @@ class QrackAceBackend:
|
|
365
444
|
else:
|
366
445
|
return
|
367
446
|
|
447
|
+
lq1_lr = self._is_col_long_range[lq1 % self.row_length]
|
448
|
+
lq2_lr = self._is_col_long_range[lq2 % self.row_length]
|
449
|
+
if lq1_lr and lq2_lr:
|
450
|
+
gate(self._unpack(lq1), self._unpack(lq2)[0])
|
451
|
+
return
|
452
|
+
|
453
|
+
self._correct(lq1)
|
454
|
+
|
368
455
|
if not self._is_init[lq1]:
|
369
456
|
hq1 = self._unpack(lq1)
|
370
457
|
hq2 = self._unpack(lq2)
|
371
|
-
|
372
|
-
|
373
|
-
|
458
|
+
if lq1_lr:
|
459
|
+
self._decode(lq2, hq2)
|
460
|
+
gate(hq1, hq2[0])
|
461
|
+
self._encode(lq2, hq2)
|
462
|
+
elif lq1_lr:
|
463
|
+
self._decode(lq1, hq1)
|
464
|
+
gate([hq1[0]], hq2[0])
|
465
|
+
self._encode(lq1, hq1)
|
466
|
+
else:
|
467
|
+
gate([hq1[0]], hq2[0])
|
468
|
+
gate([hq1[1]], hq2[1])
|
469
|
+
gate([hq1[2]], hq2[2])
|
374
470
|
|
375
471
|
return
|
376
472
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
473
|
+
lq1_row = lq1 // self.row_length
|
474
|
+
lq1_col = lq1 % self.row_length
|
475
|
+
lq2_row = lq2 // self.row_length
|
476
|
+
lq2_col = lq2 % self.row_length
|
381
477
|
|
382
478
|
hq1 = None
|
383
479
|
hq2 = None
|
384
|
-
if (
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
480
|
+
if (lq2_row == lq1_row) and (((lq1_col + 1) % self.row_length) == lq2_col):
|
481
|
+
if lq1_lr:
|
482
|
+
self._correct(lq2)
|
483
|
+
hq1 = self._unpack(lq1)
|
484
|
+
hq2 = self._unpack(lq2, False)
|
485
|
+
self._decode(lq2, hq2, False)
|
486
|
+
gate(hq1, hq2[0])
|
487
|
+
self._encode(lq2, hq2, False)
|
488
|
+
elif lq2_lr:
|
489
|
+
hq1 = self._unpack(lq1, True)
|
490
|
+
hq2 = self._unpack(lq2)
|
491
|
+
self._decode(lq1, hq1, True)
|
492
|
+
gate([hq1[0]], hq2[0])
|
493
|
+
self._encode(lq1, hq1, True)
|
494
|
+
else:
|
495
|
+
self._correct(lq2)
|
496
|
+
hq1 = self._unpack(lq1, True)
|
497
|
+
hq2 = self._unpack(lq2, False)
|
498
|
+
self._decode(lq1, hq1, True)
|
499
|
+
self._decode(lq2, hq2, False)
|
500
|
+
gate([hq1[0]], hq2[0])
|
501
|
+
self._encode(lq2, hq2, False)
|
502
|
+
self._encode(lq1, hq1, True)
|
503
|
+
elif (lq1_row == lq2_row) and (((lq2_col + 1) % self.row_length) == lq1_col):
|
504
|
+
if lq1_lr:
|
505
|
+
self._correct(lq2)
|
506
|
+
hq2 = self._unpack(lq2, True)
|
507
|
+
hq1 = self._unpack(lq1)
|
508
|
+
self._decode(lq2, hq2, True)
|
509
|
+
gate(hq1, hq2[0])
|
510
|
+
self._encode(lq2, hq2, True)
|
511
|
+
elif lq2_lr:
|
512
|
+
hq2 = self._unpack(lq2)
|
513
|
+
hq1 = self._unpack(lq1, False)
|
514
|
+
self._decode(lq1, hq1, False)
|
515
|
+
gate([hq1[0]], hq2[0])
|
516
|
+
self._encode(lq1, hq1, False)
|
517
|
+
else:
|
518
|
+
self._correct(lq2)
|
519
|
+
hq2 = self._unpack(lq2, True)
|
520
|
+
hq1 = self._unpack(lq1, False)
|
521
|
+
self._decode(lq2, hq2, True)
|
522
|
+
self._decode(lq1, hq1, False)
|
523
|
+
gate([hq1[0]], hq2[0])
|
524
|
+
self._encode(lq1, hq1, False)
|
525
|
+
self._encode(lq2, hq2, True)
|
402
526
|
else:
|
403
527
|
hq1 = self._unpack(lq1)
|
404
528
|
hq2 = self._unpack(lq2)
|
405
|
-
|
406
|
-
|
407
|
-
|
529
|
+
if lq1_lr:
|
530
|
+
self._correct(lq2)
|
531
|
+
self._decode(lq2, hq2)
|
532
|
+
gate(hq1, hq2[0])
|
533
|
+
self._encode(lq2, hq2)
|
534
|
+
elif lq2_lr:
|
535
|
+
self._decode(lq1, hq1)
|
536
|
+
gate([hq1[0]], hq2[0])
|
537
|
+
self._encode(lq1, hq1)
|
408
538
|
else:
|
409
|
-
gate([hq1[
|
410
|
-
|
539
|
+
gate([hq1[0]], hq2[0])
|
540
|
+
if self.alternating_codes and ((lq2_row & 1) != (lq1_row & 1)):
|
541
|
+
shadow(hq1[1], hq2[1])
|
542
|
+
else:
|
543
|
+
gate([hq1[1]], hq2[1])
|
544
|
+
gate([hq1[2]], hq2[2])
|
411
545
|
|
412
546
|
def cx(self, lq1, lq2):
|
413
547
|
self._cpauli(lq1, lq2, False, Pauli.PauliX)
|
@@ -429,32 +563,44 @@ class QrackAceBackend:
|
|
429
563
|
|
430
564
|
def mcx(self, lq1, lq2):
|
431
565
|
if len(lq1) > 1:
|
432
|
-
raise RuntimeError(
|
566
|
+
raise RuntimeError(
|
567
|
+
"QrackAceBackend.mcx() is provided for syntax convenience and only supports 1 control qubit!"
|
568
|
+
)
|
433
569
|
self._cpauli(lq1[0], lq2, False, Pauli.PauliX)
|
434
570
|
|
435
571
|
def mcy(self, lq1, lq2):
|
436
572
|
if len(lq1) > 1:
|
437
|
-
raise RuntimeError(
|
573
|
+
raise RuntimeError(
|
574
|
+
"QrackAceBackend.mcy() is provided for syntax convenience and only supports 1 control qubit!"
|
575
|
+
)
|
438
576
|
self._cpauli(lq1[0], lq2, False, Pauli.PauliY)
|
439
577
|
|
440
578
|
def mcz(self, lq1, lq2):
|
441
579
|
if len(lq1) > 1:
|
442
|
-
raise RuntimeError(
|
580
|
+
raise RuntimeError(
|
581
|
+
"QrackAceBackend.mcz() is provided for syntax convenience and only supports 1 control qubit!"
|
582
|
+
)
|
443
583
|
self._cpauli(lq1[0], lq2, False, Pauli.PauliZ)
|
444
584
|
|
445
585
|
def macx(self, lq1, lq2):
|
446
586
|
if len(lq1) > 1:
|
447
|
-
raise RuntimeError(
|
587
|
+
raise RuntimeError(
|
588
|
+
"QrackAceBackend.macx() is provided for syntax convenience and only supports 1 control qubit!"
|
589
|
+
)
|
448
590
|
self._cpauli(lq1[0], lq2, True, Pauli.PauliX)
|
449
591
|
|
450
592
|
def macy(self, lq1, lq2):
|
451
593
|
if len(lq1) > 1:
|
452
|
-
raise RuntimeError(
|
594
|
+
raise RuntimeError(
|
595
|
+
"QrackAceBackend.macy() is provided for syntax convenience and only supports 1 control qubit!"
|
596
|
+
)
|
453
597
|
self._cpauli(lq1[0], lq2, True, Pauli.PauliY)
|
454
598
|
|
455
599
|
def macz(self, lq1, lq2):
|
456
600
|
if len(lq1) > 1:
|
457
|
-
raise RuntimeError(
|
601
|
+
raise RuntimeError(
|
602
|
+
"QrackAceBackend.macz() is provided for syntax convenience and only supports 1 control qubit!"
|
603
|
+
)
|
458
604
|
self._cpauli(lq1[0], lq2, True, Pauli.PauliZ)
|
459
605
|
|
460
606
|
def swap(self, lq1, lq2):
|
@@ -476,8 +622,10 @@ class QrackAceBackend:
|
|
476
622
|
|
477
623
|
def m(self, lq):
|
478
624
|
hq = self._unpack(lq)
|
479
|
-
|
480
|
-
|
625
|
+
if self._is_col_long_range[lq % self.row_length]:
|
626
|
+
return self.sim.m(hq[0])
|
627
|
+
|
628
|
+
if not self.alternating_codes or not ((lq // self.row_length) & 1):
|
481
629
|
single_bit = 2
|
482
630
|
other_bits = [0, 1]
|
483
631
|
else:
|
@@ -497,6 +645,9 @@ class QrackAceBackend:
|
|
497
645
|
|
498
646
|
def force_m(self, lq, c):
|
499
647
|
hq = self._unpack(lq)
|
648
|
+
if self._is_col_long_range[lq % self.row_length]:
|
649
|
+
return self.sim.force_m(hq[0])
|
650
|
+
|
500
651
|
self._correct(lq)
|
501
652
|
for q in hq:
|
502
653
|
self.sim.force_m(q, c)
|
@@ -515,56 +666,35 @@ class QrackAceBackend:
|
|
515
666
|
col_offset = random.randint(0, self.row_length - 1)
|
516
667
|
col_reverse = self.alternating_codes and (lq_row & 1)
|
517
668
|
for c in range(self.row_length):
|
518
|
-
lq_col = (
|
669
|
+
lq_col = (
|
670
|
+
((self.row_length - (c + 1)) if col_reverse else c) + col_offset
|
671
|
+
) % self.row_length
|
519
672
|
lq = lq_row * self.row_length + lq_col
|
520
673
|
if self.m(lq):
|
521
674
|
result |= 1 << lq
|
522
675
|
|
523
676
|
return result
|
524
677
|
|
525
|
-
def measure_shots(self, q, s
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
sample = 0
|
532
|
-
for i in range(len(q)):
|
533
|
-
if (_sample >> q[i]) & 1:
|
534
|
-
sample |= 1 << i
|
535
|
-
samples.append(sample)
|
536
|
-
|
537
|
-
return samples
|
538
|
-
|
539
|
-
_q = []
|
540
|
-
for i in q:
|
541
|
-
_q.append(3 * i)
|
542
|
-
_q.append(3 * i + 1)
|
543
|
-
_q.append(3 * i + 2)
|
544
|
-
|
545
|
-
samples = self.sim.measure_shots(_q, s)
|
546
|
-
|
547
|
-
results = []
|
548
|
-
for sample in samples:
|
549
|
-
logical_sample = 0
|
678
|
+
def measure_shots(self, q, s):
|
679
|
+
samples = []
|
680
|
+
for _ in range(s):
|
681
|
+
clone = self.clone()
|
682
|
+
_sample = clone.m_all()
|
683
|
+
sample = 0
|
550
684
|
for i in range(len(q)):
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
sample >>= 1
|
557
|
-
if bit_count > 1:
|
558
|
-
logical_sample |= 1
|
559
|
-
results.append(logical_sample)
|
560
|
-
|
561
|
-
return results
|
685
|
+
if (_sample >> q[i]) & 1:
|
686
|
+
sample |= 1 << i
|
687
|
+
samples.append(sample)
|
688
|
+
|
689
|
+
return samples
|
562
690
|
|
563
691
|
def prob(self, lq):
|
564
|
-
self._correct(lq)
|
565
692
|
hq = self._unpack(lq)
|
566
|
-
|
567
|
-
|
693
|
+
if self._is_col_long_range[lq % self.row_length]:
|
694
|
+
return self.sim.prob(hq[0])
|
695
|
+
|
696
|
+
self._correct(lq)
|
697
|
+
if not self.alternating_codes or not ((lq // self.row_length) & 1):
|
568
698
|
other_bits = [0, 1]
|
569
699
|
else:
|
570
700
|
other_bits = [1, 2]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|