pyqrack-cuda 1.46.7__tar.gz → 1.47.1__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.7/pyqrack_cuda.egg-info → pyqrack_cuda-1.47.1}/PKG-INFO +1 -1
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/qrack_ace_backend.py +223 -93
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/setup.py +1 -1
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/LICENSE +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/MANIFEST.in +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/Makefile +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/README.md +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyproject.toml +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/__init__.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/pauli.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack_cuda.egg-info/SOURCES.txt +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack_cuda.egg-info/requires.txt +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/pyqrack_cuda.egg-info/top_level.txt +0 -0
- {pyqrack_cuda-1.46.7 → pyqrack_cuda-1.47.1}/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,29 +42,56 @@ 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,
|
49
52
|
toClone=None,
|
50
53
|
):
|
54
|
+
if long_range_rows < 0:
|
55
|
+
long_range_rows = 0
|
56
|
+
if qubit_count < 0:
|
57
|
+
qubit_count = 0
|
51
58
|
if toClone:
|
52
59
|
qubit_count = toClone.num_qubits()
|
53
60
|
recursive_stack_depth = toClone.recursive_stack_depth
|
54
61
|
if recursive_stack_depth < 1:
|
55
62
|
recursive_stack_depth = 1
|
63
|
+
|
56
64
|
self.recursive_stack_depth = recursive_stack_depth
|
57
|
-
self.
|
58
|
-
self._factor_width(qubit_count)
|
65
|
+
self._factor_width(qubit_count, reverse_row_and_col)
|
59
66
|
self.alternating_codes = alternating_codes
|
60
67
|
self._is_init = [False] * qubit_count
|
68
|
+
|
69
|
+
col_seq = [False] + [True] * long_range_rows
|
70
|
+
len_col_seq = len(col_seq)
|
71
|
+
self._is_col_long_range = (col_seq * ((self.row_length + len_col_seq - 1) // len_col_seq))[:self.row_length]
|
72
|
+
self._hardware_offset = []
|
73
|
+
tot_qubits = 0
|
74
|
+
for _ in range(self.col_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
|
+
|
61
81
|
if recursive_stack_depth > 1:
|
62
82
|
recursive_stack_depth -= 1
|
63
83
|
self.sim = (
|
64
84
|
toClone.sim
|
65
85
|
if toClone
|
66
|
-
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
|
+
)
|
67
95
|
)
|
68
96
|
# This leaves an "odd-man-out" ancillary qubit.
|
69
97
|
self.sim.row_length = 3 * self.row_length
|
@@ -72,23 +100,28 @@ class QrackAceBackend:
|
|
72
100
|
self.sim = (
|
73
101
|
toClone.sim.clone()
|
74
102
|
if toClone
|
75
|
-
else QrackSimulator(
|
103
|
+
else QrackSimulator(
|
104
|
+
tot_qubits,
|
105
|
+
isTensorNetwork=isTensorNetwork,
|
106
|
+
isStabilizerHybrid=isStabilizerHybrid,
|
107
|
+
isBinaryDecisionTree=isBinaryDecisionTree,
|
108
|
+
)
|
76
109
|
)
|
77
110
|
|
78
111
|
def clone(self):
|
79
112
|
return QrackAceBackend(toClone=self)
|
80
113
|
|
81
114
|
def num_qubits(self):
|
82
|
-
return self.
|
115
|
+
return self.row_length * self.col_length
|
83
116
|
|
84
|
-
def _factor_width(self, width):
|
117
|
+
def _factor_width(self, width, reverse=False):
|
85
118
|
col_len = math.floor(math.sqrt(width))
|
86
119
|
while ((width // col_len) * col_len) != width:
|
87
120
|
col_len -= 1
|
88
121
|
row_len = width // col_len
|
89
122
|
|
90
|
-
self.col_length = col_len
|
91
|
-
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
|
92
125
|
|
93
126
|
def _ct_pair_prob(self, q1, q2):
|
94
127
|
p1 = self.sim.prob(q1)
|
@@ -130,14 +163,18 @@ class QrackAceBackend:
|
|
130
163
|
self.sim.x(t)
|
131
164
|
|
132
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
|
+
|
133
171
|
return (
|
134
|
-
[
|
172
|
+
[offset + 2, offset + 1, offset]
|
135
173
|
if reverse
|
136
|
-
else [
|
174
|
+
else [offset, offset + 1, offset + 2]
|
137
175
|
)
|
138
176
|
|
139
|
-
def _encode(self, hq, reverse=False):
|
140
|
-
lq = hq[0] // 3
|
177
|
+
def _encode(self, lq, hq, reverse=False):
|
141
178
|
even_row = not ((lq // self.row_length) & 1)
|
142
179
|
# Encode shadow-first
|
143
180
|
if self._is_init[lq]:
|
@@ -148,8 +185,7 @@ class QrackAceBackend:
|
|
148
185
|
self.sim.mcx([hq[0]], hq[1])
|
149
186
|
self._is_init[lq] = True
|
150
187
|
|
151
|
-
def _decode(self, hq, reverse=False):
|
152
|
-
lq = hq[0] // 3
|
188
|
+
def _decode(self, lq, hq, reverse=False):
|
153
189
|
if not self._is_init[lq]:
|
154
190
|
return
|
155
191
|
even_row = not ((lq // self.row_length) & 1)
|
@@ -266,6 +302,11 @@ class QrackAceBackend:
|
|
266
302
|
self._correct(lq)
|
267
303
|
|
268
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
|
+
|
269
310
|
while ph > math.pi:
|
270
311
|
ph -= 2 * math.pi
|
271
312
|
while ph <= -math.pi:
|
@@ -274,85 +315,121 @@ class QrackAceBackend:
|
|
274
315
|
lm -= 2 * math.pi
|
275
316
|
while lm <= -math.pi:
|
276
317
|
lm += 2 * math.pi
|
277
|
-
|
318
|
+
|
278
319
|
if not math.isclose(ph, -lm) and not math.isclose(abs(ph), math.pi / 2):
|
279
320
|
# Produces/destroys superposition
|
280
321
|
self._correct_if_like_h(th, lq)
|
281
|
-
self._decode(hq)
|
322
|
+
self._decode(lq, hq)
|
282
323
|
self.sim.u(hq[0], th, ph, lm)
|
283
324
|
if not self._is_init[lq]:
|
284
325
|
self.sim.u(hq[2], th, ph, lm)
|
285
|
-
self._encode(hq)
|
326
|
+
self._encode(lq, hq)
|
286
327
|
else:
|
287
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):
|
300
346
|
# Doesn't produce/destroy superposition
|
301
347
|
for b in hq:
|
302
348
|
self.sim.r(p, th, b)
|
303
349
|
else:
|
304
350
|
# Produces/destroys superposition
|
305
|
-
self._decode(hq)
|
351
|
+
self._decode(lq, hq)
|
306
352
|
self.sim.r(p, th, hq[0])
|
307
353
|
if not self._is_init[lq]:
|
308
354
|
self.sim.r(p, th, hq[2])
|
309
|
-
self._encode(hq)
|
355
|
+
self._encode(lq, hq)
|
310
356
|
|
311
357
|
def h(self, lq):
|
312
358
|
hq = self._unpack(lq)
|
313
|
-
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)
|
314
364
|
self.sim.h(hq[0])
|
315
365
|
if not self._is_init[lq]:
|
316
366
|
self.sim.h(hq[2])
|
317
|
-
self._encode(hq)
|
367
|
+
self._encode(lq, hq)
|
318
368
|
|
319
369
|
def s(self, lq):
|
320
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
|
+
|
321
375
|
for b in hq:
|
322
376
|
self.sim.s(b)
|
323
377
|
|
324
378
|
def adjs(self, lq):
|
325
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
|
+
|
326
384
|
for b in hq:
|
327
385
|
self.sim.adjs(b)
|
328
386
|
|
329
387
|
def x(self, lq):
|
330
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
|
+
|
331
393
|
for b in hq:
|
332
394
|
self.sim.x(b)
|
333
395
|
|
334
396
|
def y(self, lq):
|
335
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
|
+
|
336
402
|
for b in hq:
|
337
403
|
self.sim.y(b)
|
338
404
|
|
339
405
|
def z(self, lq):
|
340
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
|
+
|
341
411
|
for b in hq:
|
342
412
|
self.sim.z(b)
|
343
413
|
|
344
414
|
def t(self, lq):
|
345
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
|
+
|
346
420
|
for b in hq:
|
347
421
|
self.sim.t(b)
|
348
422
|
|
349
423
|
def adjt(self, lq):
|
350
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
|
+
|
351
429
|
for b in hq:
|
352
430
|
self.sim.adjt(b)
|
353
431
|
|
354
432
|
def _cpauli(self, lq1, lq2, anti, pauli):
|
355
|
-
self._correct(lq1)
|
356
433
|
gate = None
|
357
434
|
shadow = None
|
358
435
|
if pauli == Pauli.PauliX:
|
@@ -367,12 +444,29 @@ class QrackAceBackend:
|
|
367
444
|
else:
|
368
445
|
return
|
369
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
|
+
|
370
455
|
if not self._is_init[lq1]:
|
371
456
|
hq1 = self._unpack(lq1)
|
372
457
|
hq2 = self._unpack(lq2)
|
373
|
-
|
374
|
-
|
375
|
-
|
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])
|
376
470
|
|
377
471
|
return
|
378
472
|
|
@@ -384,32 +478,70 @@ class QrackAceBackend:
|
|
384
478
|
hq1 = None
|
385
479
|
hq2 = None
|
386
480
|
if (lq2_row == lq1_row) and (((lq1_col + 1) % self.row_length) == lq2_col):
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
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)
|
395
503
|
elif (lq1_row == lq2_row) and (((lq2_col + 1) % self.row_length) == lq1_col):
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
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)
|
404
526
|
else:
|
405
527
|
hq1 = self._unpack(lq1)
|
406
528
|
hq2 = self._unpack(lq2)
|
407
|
-
|
408
|
-
|
409
|
-
|
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)
|
410
538
|
else:
|
411
|
-
gate([hq1[
|
412
|
-
|
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])
|
413
545
|
|
414
546
|
def cx(self, lq1, lq2):
|
415
547
|
self._cpauli(lq1, lq2, False, Pauli.PauliX)
|
@@ -431,32 +563,44 @@ class QrackAceBackend:
|
|
431
563
|
|
432
564
|
def mcx(self, lq1, lq2):
|
433
565
|
if len(lq1) > 1:
|
434
|
-
raise RuntimeError(
|
566
|
+
raise RuntimeError(
|
567
|
+
"QrackAceBackend.mcx() is provided for syntax convenience and only supports 1 control qubit!"
|
568
|
+
)
|
435
569
|
self._cpauli(lq1[0], lq2, False, Pauli.PauliX)
|
436
570
|
|
437
571
|
def mcy(self, lq1, lq2):
|
438
572
|
if len(lq1) > 1:
|
439
|
-
raise RuntimeError(
|
573
|
+
raise RuntimeError(
|
574
|
+
"QrackAceBackend.mcy() is provided for syntax convenience and only supports 1 control qubit!"
|
575
|
+
)
|
440
576
|
self._cpauli(lq1[0], lq2, False, Pauli.PauliY)
|
441
577
|
|
442
578
|
def mcz(self, lq1, lq2):
|
443
579
|
if len(lq1) > 1:
|
444
|
-
raise RuntimeError(
|
580
|
+
raise RuntimeError(
|
581
|
+
"QrackAceBackend.mcz() is provided for syntax convenience and only supports 1 control qubit!"
|
582
|
+
)
|
445
583
|
self._cpauli(lq1[0], lq2, False, Pauli.PauliZ)
|
446
584
|
|
447
585
|
def macx(self, lq1, lq2):
|
448
586
|
if len(lq1) > 1:
|
449
|
-
raise RuntimeError(
|
587
|
+
raise RuntimeError(
|
588
|
+
"QrackAceBackend.macx() is provided for syntax convenience and only supports 1 control qubit!"
|
589
|
+
)
|
450
590
|
self._cpauli(lq1[0], lq2, True, Pauli.PauliX)
|
451
591
|
|
452
592
|
def macy(self, lq1, lq2):
|
453
593
|
if len(lq1) > 1:
|
454
|
-
raise RuntimeError(
|
594
|
+
raise RuntimeError(
|
595
|
+
"QrackAceBackend.macy() is provided for syntax convenience and only supports 1 control qubit!"
|
596
|
+
)
|
455
597
|
self._cpauli(lq1[0], lq2, True, Pauli.PauliY)
|
456
598
|
|
457
599
|
def macz(self, lq1, lq2):
|
458
600
|
if len(lq1) > 1:
|
459
|
-
raise RuntimeError(
|
601
|
+
raise RuntimeError(
|
602
|
+
"QrackAceBackend.macz() is provided for syntax convenience and only supports 1 control qubit!"
|
603
|
+
)
|
460
604
|
self._cpauli(lq1[0], lq2, True, Pauli.PauliZ)
|
461
605
|
|
462
606
|
def swap(self, lq1, lq2):
|
@@ -477,7 +621,11 @@ class QrackAceBackend:
|
|
477
621
|
self.swap(lq1, lq2)
|
478
622
|
|
479
623
|
def m(self, lq):
|
624
|
+
self._is_init[lq] = False
|
480
625
|
hq = self._unpack(lq)
|
626
|
+
if self._is_col_long_range[lq % self.row_length]:
|
627
|
+
return self.sim.m(hq[0])
|
628
|
+
|
481
629
|
if not self.alternating_codes or not ((lq // self.row_length) & 1):
|
482
630
|
single_bit = 2
|
483
631
|
other_bits = [0, 1]
|
@@ -492,16 +640,18 @@ class QrackAceBackend:
|
|
492
640
|
# but not non-locally, via entanglement.
|
493
641
|
# Collapse the other separable part toward agreement.
|
494
642
|
syndrome += self.sim.force_m(hq[single_bit], bool(syndrome))
|
495
|
-
self._is_init[lq] = False
|
496
643
|
|
497
644
|
return True if (syndrome > 1) else False
|
498
645
|
|
499
646
|
def force_m(self, lq, c):
|
500
647
|
hq = self._unpack(lq)
|
648
|
+
self._is_init[lq] = False
|
649
|
+
if self._is_col_long_range[lq % self.row_length]:
|
650
|
+
return self.sim.force_m(hq[0])
|
651
|
+
|
501
652
|
self._correct(lq)
|
502
653
|
for q in hq:
|
503
654
|
self.sim.force_m(q, c)
|
504
|
-
self._is_init[lq] = False
|
505
655
|
|
506
656
|
return c
|
507
657
|
|
@@ -516,54 +666,34 @@ class QrackAceBackend:
|
|
516
666
|
col_offset = random.randint(0, self.row_length - 1)
|
517
667
|
col_reverse = self.alternating_codes and (lq_row & 1)
|
518
668
|
for c in range(self.row_length):
|
519
|
-
lq_col = (
|
669
|
+
lq_col = (
|
670
|
+
((self.row_length - (c + 1)) if col_reverse else c) + col_offset
|
671
|
+
) % self.row_length
|
520
672
|
lq = lq_row * self.row_length + lq_col
|
521
673
|
if self.m(lq):
|
522
674
|
result |= 1 << lq
|
523
675
|
|
524
676
|
return result
|
525
677
|
|
526
|
-
def measure_shots(self, q, s
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
sample = 0
|
533
|
-
for i in range(len(q)):
|
534
|
-
if (_sample >> q[i]) & 1:
|
535
|
-
sample |= 1 << i
|
536
|
-
samples.append(sample)
|
537
|
-
|
538
|
-
return samples
|
539
|
-
|
540
|
-
_q = []
|
541
|
-
for i in q:
|
542
|
-
_q.append(3 * i)
|
543
|
-
_q.append(3 * i + 1)
|
544
|
-
_q.append(3 * i + 2)
|
545
|
-
|
546
|
-
samples = self.sim.measure_shots(_q, s)
|
547
|
-
|
548
|
-
results = []
|
549
|
-
for sample in samples:
|
550
|
-
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
|
551
684
|
for i in range(len(q)):
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
sample >>= 1
|
558
|
-
if bit_count > 1:
|
559
|
-
logical_sample |= 1
|
560
|
-
results.append(logical_sample)
|
561
|
-
|
562
|
-
return results
|
685
|
+
if (_sample >> q[i]) & 1:
|
686
|
+
sample |= 1 << i
|
687
|
+
samples.append(sample)
|
688
|
+
|
689
|
+
return samples
|
563
690
|
|
564
691
|
def prob(self, lq):
|
565
|
-
self._correct(lq)
|
566
692
|
hq = self._unpack(lq)
|
693
|
+
if self._is_col_long_range[lq % self.row_length]:
|
694
|
+
return self.sim.prob(hq[0])
|
695
|
+
|
696
|
+
self._correct(lq)
|
567
697
|
if not self.alternating_codes or not ((lq // self.row_length) & 1):
|
568
698
|
other_bits = [0, 1]
|
569
699
|
else:
|
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
|