pyqrack-cuda 1.45.1__tar.gz → 1.46.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.45.1/pyqrack_cuda.egg-info → pyqrack_cuda-1.46.0}/PKG-INFO +1 -1
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/qrack_ace_backend.py +92 -15
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/setup.py +1 -1
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/LICENSE +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/MANIFEST.in +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/Makefile +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/README.md +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyproject.toml +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/__init__.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/pauli.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/SOURCES.txt +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/requires.txt +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/top_level.txt +0 -0
- {pyqrack_cuda-1.45.1 → pyqrack_cuda-1.46.0}/setup.cfg +0 -0
@@ -41,20 +41,41 @@ class QrackAceBackend:
|
|
41
41
|
def __init__(
|
42
42
|
self,
|
43
43
|
qubit_count=1,
|
44
|
+
recursive_stack_depth=1,
|
44
45
|
alternating_codes=True,
|
45
46
|
isTensorNetwork=False,
|
47
|
+
isStabilizerHybrid=False,
|
48
|
+
isBinaryDecisionTree=False,
|
46
49
|
toClone=None,
|
47
50
|
):
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
if recursive_stack_depth < 1:
|
52
|
+
recursive_stack_depth = 1
|
53
|
+
if toClone:
|
54
|
+
qubit_count = toClone.num_qubits()
|
55
|
+
if recursive_stack_depth > 1:
|
56
|
+
recursive_stack_depth -= 1
|
57
|
+
self.sim = (
|
58
|
+
toClone.sim
|
59
|
+
if toClone
|
60
|
+
else QrackAceBackend(3 * qubit_count + 1, recursive_stack_depth=recursive_stack_depth, alternating_codes=alternating_codes, isTensorNetwork=isTensorNetwork, isStabilizerHybrid=isStabilizerHybrid, isBinaryDecisionTree=isBinaryDecisionTree)
|
61
|
+
)
|
62
|
+
else:
|
63
|
+
self.sim = (
|
64
|
+
toClone.sim.clone()
|
65
|
+
if toClone
|
66
|
+
else QrackSimulator(3 * qubit_count + 1, isTensorNetwork=isTensorNetwork, isStabilizerHybrid=isStabilizerHybrid, isBinaryDecisionTree=isBinaryDecisionTree)
|
67
|
+
)
|
53
68
|
self._ancilla = 3 * qubit_count
|
54
69
|
self._factor_width(qubit_count)
|
55
70
|
self.alternating_codes = alternating_codes
|
56
71
|
self._is_init = [False] * qubit_count
|
57
72
|
|
73
|
+
def clone(self):
|
74
|
+
return QrackAceBackend(toClone=self)
|
75
|
+
|
76
|
+
def num_qubits(self):
|
77
|
+
return self.sim.num_qubits() // 3
|
78
|
+
|
58
79
|
def _factor_width(self, width):
|
59
80
|
col_len = math.floor(math.sqrt(width))
|
60
81
|
while ((width // col_len) * col_len) != width:
|
@@ -244,7 +265,7 @@ class QrackAceBackend:
|
|
244
265
|
if not math.isclose(th, 0):
|
245
266
|
self._correct(lq)
|
246
267
|
|
247
|
-
def u(self, th, ph, lm
|
268
|
+
def u(self, lq, th, ph, lm):
|
248
269
|
while ph > math.pi:
|
249
270
|
ph -= 2 * math.pi
|
250
271
|
while ph <= -math.pi:
|
@@ -404,6 +425,36 @@ class QrackAceBackend:
|
|
404
425
|
def acz(self, lq1, lq2):
|
405
426
|
self._cpauli(lq1, lq2, True, Pauli.PauliZ)
|
406
427
|
|
428
|
+
def mcx(self, lq1, lq2):
|
429
|
+
if len(lq1) > 1:
|
430
|
+
raise RuntimeError("QrackAceBackend.mcx() is provided for syntax convenience and only supports 1 control qubit!")
|
431
|
+
self._cpauli(lq1[0], lq2, False, Pauli.PauliX)
|
432
|
+
|
433
|
+
def mcy(self, lq1, lq2):
|
434
|
+
if len(lq1) > 1:
|
435
|
+
raise RuntimeError("QrackAceBackend.mcy() is provided for syntax convenience and only supports 1 control qubit!")
|
436
|
+
self._cpauli(lq1[0], lq2, False, Pauli.PauliY)
|
437
|
+
|
438
|
+
def mcz(self, lq1, lq2):
|
439
|
+
if len(lq1) > 1:
|
440
|
+
raise RuntimeError("QrackAceBackend.mcz() is provided for syntax convenience and only supports 1 control qubit!")
|
441
|
+
self._cpauli(lq1[0], lq2, False, Pauli.PauliZ)
|
442
|
+
|
443
|
+
def macx(self, lq1, lq2):
|
444
|
+
if len(lq1) > 1:
|
445
|
+
raise RuntimeError("QrackAceBackend.macx() is provided for syntax convenience and only supports 1 control qubit!")
|
446
|
+
self._cpauli(lq1[0], lq2, True, Pauli.PauliX)
|
447
|
+
|
448
|
+
def macy(self, lq1, lq2):
|
449
|
+
if len(lq1) > 1:
|
450
|
+
raise RuntimeError("QrackAceBackend.macy() is provided for syntax convenience and only supports 1 control qubit!")
|
451
|
+
self._cpauli(lq1[0], lq2, True, Pauli.PauliY)
|
452
|
+
|
453
|
+
def macz(self, lq1, lq2):
|
454
|
+
if len(lq1) > 1:
|
455
|
+
raise RuntimeError("QrackAceBackend.macz() is provided for syntax convenience and only supports 1 control qubit!")
|
456
|
+
self._cpauli(lq1[0], lq2, True, Pauli.PauliZ)
|
457
|
+
|
407
458
|
def swap(self, lq1, lq2):
|
408
459
|
self.cx(lq1, lq2)
|
409
460
|
self.cx(lq2, lq1)
|
@@ -437,7 +488,7 @@ class QrackAceBackend:
|
|
437
488
|
syndrome += self.sim.m(hq[q])
|
438
489
|
# The two separable parts of the code are correlated,
|
439
490
|
# but not non-locally, via entanglement.
|
440
|
-
#
|
491
|
+
# Collapse the other separable part toward agreement.
|
441
492
|
if syndrome == 0:
|
442
493
|
self.sim.force_m(hq[single_bit], False)
|
443
494
|
elif syndrome == 2:
|
@@ -448,12 +499,22 @@ class QrackAceBackend:
|
|
448
499
|
|
449
500
|
return True if (syndrome > 1) else False
|
450
501
|
|
502
|
+
def force_m(self, lq, c):
|
503
|
+
hq = self._unpack(lq)
|
504
|
+
self._correct(lq)
|
505
|
+
for q in hq:
|
506
|
+
self.sim.force_m(q, c)
|
507
|
+
self._is_init[lq] = False
|
508
|
+
|
509
|
+
return c
|
510
|
+
|
451
511
|
def m_all(self):
|
452
512
|
result = 0
|
453
513
|
# Whenever a nonzero syndrome occurs (so the code has an error),
|
454
514
|
# we insert the more-probable results and collapse towards it.
|
455
515
|
# Randomize the order of post-selection to amortize error.
|
456
|
-
lqubits =
|
516
|
+
lqubits = list(range(self.sim.num_qubits() // 3))
|
517
|
+
random.shuffle(lqubits)
|
457
518
|
for lq in lqubits:
|
458
519
|
if self.m(lq):
|
459
520
|
result |= 1 << lq
|
@@ -463,12 +524,14 @@ class QrackAceBackend:
|
|
463
524
|
def measure_shots(self, q, s, high_accuracy=True):
|
464
525
|
if high_accuracy:
|
465
526
|
samples = []
|
527
|
+
_q = q.copy()
|
466
528
|
for _ in range(s):
|
467
529
|
clone = self.sim.clone()
|
468
530
|
sample = 0
|
469
|
-
|
470
|
-
|
471
|
-
|
531
|
+
random.shuffle(_q)
|
532
|
+
for b in _q:
|
533
|
+
if clone.m(b):
|
534
|
+
sample |= 1 << q.index(b)
|
472
535
|
samples.append(sample)
|
473
536
|
|
474
537
|
return samples
|
@@ -497,6 +560,20 @@ class QrackAceBackend:
|
|
497
560
|
|
498
561
|
return results
|
499
562
|
|
563
|
+
def prob(self, lq):
|
564
|
+
self._correct(lq)
|
565
|
+
hq = self._unpack(lq)
|
566
|
+
even_row = not ((lq // self.row_length) & 1)
|
567
|
+
if not self.alternating_codes or even_row:
|
568
|
+
other_bits = [0, 1]
|
569
|
+
else:
|
570
|
+
other_bits = [1, 2]
|
571
|
+
self.sim.mcx([other_bits[0]], other_bits[1])
|
572
|
+
result = self.sim.prob(hq[1])
|
573
|
+
self.sim.mcx([other_bits[0]], other_bits[1])
|
574
|
+
|
575
|
+
return result
|
576
|
+
|
500
577
|
def _apply_op(self, operation):
|
501
578
|
name = operation.name
|
502
579
|
|
@@ -520,27 +597,27 @@ class QrackAceBackend:
|
|
520
597
|
return
|
521
598
|
|
522
599
|
if (name == "u1") or (name == "p"):
|
523
|
-
self._sim.u(0, 0, float(operation.params[0])
|
600
|
+
self._sim.u(operation.qubits[0]._index, 0, 0, float(operation.params[0]))
|
524
601
|
elif name == "u2":
|
525
602
|
self._sim.u(
|
603
|
+
operation.qubits[0]._index,
|
526
604
|
math.pi / 2,
|
527
605
|
float(operation.params[0]),
|
528
606
|
float(operation.params[1]),
|
529
|
-
operation.qubits[0]._index,
|
530
607
|
)
|
531
608
|
elif (name == "u3") or (name == "u"):
|
532
609
|
self._sim.u(
|
610
|
+
operation.qubits[0]._index,
|
533
611
|
float(operation.params[0]),
|
534
612
|
float(operation.params[1]),
|
535
613
|
float(operation.params[2]),
|
536
|
-
operation.qubits[0]._index,
|
537
614
|
)
|
538
615
|
elif name == "r":
|
539
616
|
self._sim.u(
|
617
|
+
operation.qubits[0]._index,
|
540
618
|
float(operation.params[0]),
|
541
619
|
float(operation.params[1]) - math.pi / 2,
|
542
620
|
(-1 * float(operation.params[1])) + math.pi / 2,
|
543
|
-
operation.qubits[0]._index,
|
544
621
|
)
|
545
622
|
elif name == "rx":
|
546
623
|
self._sim.r(
|
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
|