pyqrack-cuda 1.45.2__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.2/pyqrack_cuda.egg-info → pyqrack_cuda-1.46.0}/PKG-INFO +1 -1
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/qrack_ace_backend.py +85 -11
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/setup.py +1 -1
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/LICENSE +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/MANIFEST.in +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/Makefile +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/README.md +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyproject.toml +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/__init__.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/pauli.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/SOURCES.txt +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/requires.txt +0 -0
- {pyqrack_cuda-1.45.2 → pyqrack_cuda-1.46.0}/pyqrack_cuda.egg-info/top_level.txt +0 -0
- {pyqrack_cuda-1.45.2 → 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,6 +499,15 @@ 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),
|
@@ -500,6 +560,20 @@ class QrackAceBackend:
|
|
500
560
|
|
501
561
|
return results
|
502
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
|
+
|
503
577
|
def _apply_op(self, operation):
|
504
578
|
name = operation.name
|
505
579
|
|
@@ -523,27 +597,27 @@ class QrackAceBackend:
|
|
523
597
|
return
|
524
598
|
|
525
599
|
if (name == "u1") or (name == "p"):
|
526
|
-
self._sim.u(0, 0, float(operation.params[0])
|
600
|
+
self._sim.u(operation.qubits[0]._index, 0, 0, float(operation.params[0]))
|
527
601
|
elif name == "u2":
|
528
602
|
self._sim.u(
|
603
|
+
operation.qubits[0]._index,
|
529
604
|
math.pi / 2,
|
530
605
|
float(operation.params[0]),
|
531
606
|
float(operation.params[1]),
|
532
|
-
operation.qubits[0]._index,
|
533
607
|
)
|
534
608
|
elif (name == "u3") or (name == "u"):
|
535
609
|
self._sim.u(
|
610
|
+
operation.qubits[0]._index,
|
536
611
|
float(operation.params[0]),
|
537
612
|
float(operation.params[1]),
|
538
613
|
float(operation.params[2]),
|
539
|
-
operation.qubits[0]._index,
|
540
614
|
)
|
541
615
|
elif name == "r":
|
542
616
|
self._sim.u(
|
617
|
+
operation.qubits[0]._index,
|
543
618
|
float(operation.params[0]),
|
544
619
|
float(operation.params[1]) - math.pi / 2,
|
545
620
|
(-1 * float(operation.params[1])) + math.pi / 2,
|
546
|
-
operation.qubits[0]._index,
|
547
621
|
)
|
548
622
|
elif name == "rx":
|
549
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
|