pyqrack-cuda 1.53.3__tar.gz → 1.54.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.53.3/pyqrack_cuda.egg-info → pyqrack_cuda-1.54.1}/PKG-INFO +1 -1
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/qrack_ace_backend.py +75 -58
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/setup.py +1 -1
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/LICENSE +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/MANIFEST.in +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/Makefile +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/README.md +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyproject.toml +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/__init__.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/pauli.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack_cuda.egg-info/SOURCES.txt +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack_cuda.egg-info/requires.txt +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/pyqrack_cuda.egg-info/top_level.txt +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.1}/setup.cfg +0 -0
@@ -43,16 +43,15 @@ class QrackAceBackend:
|
|
43
43
|
|
44
44
|
Attributes:
|
45
45
|
sim(QrackSimulator): Array of simulators corresponding to "patches" between boundary rows.
|
46
|
-
row_length(int): Qubits per row.
|
47
|
-
col_length(int): Qubits per column.
|
48
46
|
long_range_columns(int): How many ideal rows between QEC boundary rows?
|
47
|
+
is_transpose(bool): Rows are long if False, columns are long if True
|
49
48
|
"""
|
50
49
|
|
51
50
|
def __init__(
|
52
51
|
self,
|
53
52
|
qubit_count=1,
|
54
53
|
long_range_columns=-1,
|
55
|
-
|
54
|
+
is_transpose=False,
|
56
55
|
isTensorNetwork=False,
|
57
56
|
isStabilizerHybrid=False,
|
58
57
|
isBinaryDecisionTree=False,
|
@@ -63,24 +62,26 @@ class QrackAceBackend:
|
|
63
62
|
if toClone:
|
64
63
|
qubit_count = toClone.num_qubits()
|
65
64
|
long_range_columns = toClone.long_range_columns
|
65
|
+
is_transpose = toClone.is_transpose
|
66
66
|
|
67
|
-
self._factor_width(qubit_count,
|
67
|
+
self._factor_width(qubit_count, is_transpose)
|
68
68
|
if long_range_columns < 0:
|
69
|
-
long_range_columns = 3 if (self.
|
69
|
+
long_range_columns = 3 if (self._row_length % 3) == 1 else 2
|
70
70
|
self.long_range_columns = long_range_columns
|
71
|
+
self.is_transpose = is_transpose
|
71
72
|
|
72
73
|
self._coupling_map = None
|
73
74
|
|
74
75
|
# If there's only one or zero "False" columns,
|
75
76
|
# the entire simulator is connected, anyway.
|
76
77
|
len_col_seq = long_range_columns + 1
|
77
|
-
sim_count = (self.
|
78
|
-
if (long_range_columns + 1) >= self.
|
79
|
-
self._is_col_long_range = [True] * self.
|
78
|
+
sim_count = (self._row_length + len_col_seq - 1) // len_col_seq
|
79
|
+
if (long_range_columns + 1) >= self._row_length:
|
80
|
+
self._is_col_long_range = [True] * self._row_length
|
80
81
|
else:
|
81
82
|
col_seq = [True] * long_range_columns + [False]
|
82
|
-
self._is_col_long_range = (col_seq * sim_count)[: self.
|
83
|
-
if long_range_columns < self.
|
83
|
+
self._is_col_long_range = (col_seq * sim_count)[: self._row_length]
|
84
|
+
if long_range_columns < self._row_length:
|
84
85
|
self._is_col_long_range[-1] = False
|
85
86
|
|
86
87
|
self._qubit_dict = {}
|
@@ -89,7 +90,7 @@ class QrackAceBackend:
|
|
89
90
|
sim_counts = [0] * sim_count
|
90
91
|
sim_id = 0
|
91
92
|
tot_qubits = 0
|
92
|
-
for r in range(self.
|
93
|
+
for r in range(self._col_length):
|
93
94
|
for c in self._is_col_long_range:
|
94
95
|
self._hardware_offset.append(tot_qubits)
|
95
96
|
if c:
|
@@ -138,15 +139,21 @@ class QrackAceBackend:
|
|
138
139
|
return QrackAceBackend(toClone=self)
|
139
140
|
|
140
141
|
def num_qubits(self):
|
141
|
-
return self.
|
142
|
+
return self._row_length * self._col_length
|
142
143
|
|
143
|
-
def
|
144
|
+
def get_row_length(self):
|
145
|
+
return self._row_length
|
146
|
+
|
147
|
+
def get_column_length(self):
|
148
|
+
return self._col_length
|
149
|
+
|
150
|
+
def _factor_width(self, width, is_transpose=False):
|
144
151
|
col_len = math.floor(math.sqrt(width))
|
145
152
|
while ((width // col_len) * col_len) != width:
|
146
153
|
col_len -= 1
|
147
154
|
row_len = width // col_len
|
148
155
|
|
149
|
-
self.
|
156
|
+
self._col_length, self._row_length = (row_len, col_len) if is_transpose else (col_len, row_len)
|
150
157
|
|
151
158
|
def _ct_pair_prob(self, q1, q2):
|
152
159
|
p1 = self.sim[q1[0]].prob(q1[1])
|
@@ -210,7 +217,7 @@ class QrackAceBackend:
|
|
210
217
|
def _unpack(self, lq):
|
211
218
|
offset = self._hardware_offset[lq]
|
212
219
|
|
213
|
-
if self._is_col_long_range[lq % self.
|
220
|
+
if self._is_col_long_range[lq % self._row_length]:
|
214
221
|
return [self._qubit_dict[offset]]
|
215
222
|
|
216
223
|
return [
|
@@ -229,7 +236,7 @@ class QrackAceBackend:
|
|
229
236
|
self.sim[b[0]].mcx([b[1]], hq[1][1])
|
230
237
|
|
231
238
|
def _correct(self, lq, phase=False):
|
232
|
-
if self._is_col_long_range[lq % self.
|
239
|
+
if self._is_col_long_range[lq % self._row_length]:
|
233
240
|
return
|
234
241
|
# We can't use true syndrome-based error correction,
|
235
242
|
# because one of the qubits in the code is separated.
|
@@ -503,46 +510,56 @@ class QrackAceBackend:
|
|
503
510
|
return gate, shadow
|
504
511
|
|
505
512
|
def _cpauli(self, lq1, lq2, anti, pauli):
|
506
|
-
lq1_lr = self._is_col_long_range[lq1 % self.
|
507
|
-
lq2_lr = self._is_col_long_range[lq2 % self.
|
513
|
+
lq1_lr = self._is_col_long_range[lq1 % self._row_length]
|
514
|
+
lq2_lr = self._is_col_long_range[lq2 % self._row_length]
|
508
515
|
|
509
|
-
lq1_row = lq1 // self.
|
510
|
-
lq1_col = lq1 % self.
|
511
|
-
lq2_row = lq2 // self.
|
512
|
-
lq2_col = lq2 % self.
|
513
|
-
|
514
|
-
connected_cols = []
|
515
|
-
c = (lq1_col - 1) % self.row_length
|
516
|
-
while self._is_col_long_range[c] and (
|
517
|
-
len(connected_cols) < (self.row_length - 1)
|
518
|
-
):
|
519
|
-
connected_cols.append(c)
|
520
|
-
c = (c - 1) % self.row_length
|
521
|
-
if len(connected_cols) < (self.row_length - 1):
|
522
|
-
connected_cols.append(c)
|
523
|
-
boundary = len(connected_cols)
|
524
|
-
c = (lq1_col + 1) % self.row_length
|
525
|
-
while self._is_col_long_range[c] and (
|
526
|
-
len(connected_cols) < (self.row_length - 1)
|
527
|
-
):
|
528
|
-
connected_cols.append(c)
|
529
|
-
c = (c + 1) % self.row_length
|
530
|
-
if len(connected_cols) < (self.row_length - 1):
|
531
|
-
connected_cols.append(c)
|
516
|
+
lq1_row = lq1 // self._row_length
|
517
|
+
lq1_col = lq1 % self._row_length
|
518
|
+
lq2_row = lq2 // self._row_length
|
519
|
+
lq2_col = lq2 % self._row_length
|
532
520
|
|
533
521
|
hq1 = self._unpack(lq1)
|
534
522
|
hq2 = self._unpack(lq2)
|
535
523
|
|
536
524
|
if lq1_lr and lq2_lr:
|
525
|
+
connected = (lq1_col == lq2_col) or ((self.long_range_columns + 1) >= self._row_length)
|
526
|
+
c = (lq1_col - 1) % self._row_length
|
527
|
+
while not connected and self._is_col_long_range[c]:
|
528
|
+
connected = (lq2_col == c)
|
529
|
+
c = (c - 1) % self._row_length
|
530
|
+
c = (lq1_col + 1) % self._row_length
|
531
|
+
while not connected and self._is_col_long_range[c]:
|
532
|
+
connected = (lq2_col == c)
|
533
|
+
c = (c + 1) % self._row_length
|
534
|
+
|
537
535
|
b1 = hq1[0]
|
538
536
|
b2 = hq2[0]
|
539
537
|
gate, shadow = self._get_gate(pauli, anti, b1[0])
|
540
|
-
if
|
538
|
+
if connected:
|
541
539
|
gate([b1[1]], b2[1])
|
542
540
|
else:
|
543
541
|
shadow(b1, b2)
|
544
542
|
return
|
545
543
|
|
544
|
+
connected_cols = []
|
545
|
+
c = (lq1_col - 1) % self._row_length
|
546
|
+
while self._is_col_long_range[c] and (
|
547
|
+
len(connected_cols) < (self._row_length - 1)
|
548
|
+
):
|
549
|
+
connected_cols.append(c)
|
550
|
+
c = (c - 1) % self._row_length
|
551
|
+
if len(connected_cols) < (self._row_length - 1):
|
552
|
+
connected_cols.append(c)
|
553
|
+
boundary = len(connected_cols)
|
554
|
+
c = (lq1_col + 1) % self._row_length
|
555
|
+
while self._is_col_long_range[c] and (
|
556
|
+
len(connected_cols) < (self._row_length - 1)
|
557
|
+
):
|
558
|
+
connected_cols.append(c)
|
559
|
+
c = (c + 1) % self._row_length
|
560
|
+
if len(connected_cols) < (self._row_length - 1):
|
561
|
+
connected_cols.append(c)
|
562
|
+
|
546
563
|
self._correct(lq1)
|
547
564
|
|
548
565
|
if (lq2_col in connected_cols) and (connected_cols.index(lq2_col) < boundary):
|
@@ -727,22 +744,22 @@ class QrackAceBackend:
|
|
727
744
|
# However, locality of collapse matters:
|
728
745
|
# measure in row pairs, and always across rows,
|
729
746
|
# and by row directionality.
|
730
|
-
row_pairs = list(range((self.
|
747
|
+
row_pairs = list(range((self._col_length + 1) // 2))
|
731
748
|
random.shuffle(row_pairs)
|
732
749
|
for row_pair in row_pairs:
|
733
|
-
col_offset = random.randint(0, self.
|
750
|
+
col_offset = random.randint(0, self._row_length - 1)
|
734
751
|
lq_row = row_pair << 1
|
735
|
-
for c in range(self.
|
736
|
-
lq_col = (c + col_offset) % self.
|
737
|
-
lq = lq_row * self.
|
752
|
+
for c in range(self._row_length):
|
753
|
+
lq_col = (c + col_offset) % self._row_length
|
754
|
+
lq = lq_row * self._row_length + lq_col
|
738
755
|
if self.m(lq):
|
739
756
|
result |= 1 << lq
|
740
757
|
lq_row += 1
|
741
|
-
if lq_row == self.
|
758
|
+
if lq_row == self._col_length:
|
742
759
|
continue
|
743
|
-
for c in range(self.
|
744
|
-
lq_col = ((self.
|
745
|
-
lq = lq_row * self.
|
760
|
+
for c in range(self._row_length):
|
761
|
+
lq_col = ((self._row_length - (c + 1)) + col_offset) % self._row_length
|
762
|
+
lq = lq_row * self._row_length + lq_col
|
746
763
|
if self.m(lq):
|
747
764
|
result |= 1 << lq
|
748
765
|
|
@@ -1123,7 +1140,7 @@ class QrackAceBackend:
|
|
1123
1140
|
return self._coupling_map
|
1124
1141
|
|
1125
1142
|
coupling_map = set()
|
1126
|
-
rows, cols = self.
|
1143
|
+
rows, cols = self._row_length, self._col_length
|
1127
1144
|
|
1128
1145
|
# Map each column index to its full list of logical qubit indices
|
1129
1146
|
def logical_index(row, col):
|
@@ -1133,19 +1150,19 @@ class QrackAceBackend:
|
|
1133
1150
|
connected_cols = [col]
|
1134
1151
|
c = (col - 1) % cols
|
1135
1152
|
while self._is_col_long_range[c] and (
|
1136
|
-
len(connected_cols) < self.
|
1153
|
+
len(connected_cols) < self._row_length
|
1137
1154
|
):
|
1138
1155
|
connected_cols.append(c)
|
1139
1156
|
c = (c - 1) % cols
|
1140
|
-
if len(connected_cols) < self.
|
1157
|
+
if len(connected_cols) < self._row_length:
|
1141
1158
|
connected_cols.append(c)
|
1142
1159
|
c = (col + 1) % cols
|
1143
1160
|
while self._is_col_long_range[c] and (
|
1144
|
-
len(connected_cols) < self.
|
1161
|
+
len(connected_cols) < self._row_length
|
1145
1162
|
):
|
1146
1163
|
connected_cols.append(c)
|
1147
1164
|
c = (c + 1) % cols
|
1148
|
-
if len(connected_cols) < self.
|
1165
|
+
if len(connected_cols) < self._row_length:
|
1149
1166
|
connected_cols.append(c)
|
1150
1167
|
|
1151
1168
|
for row in range(rows):
|
@@ -1169,8 +1186,8 @@ class QrackAceBackend:
|
|
1169
1186
|
noise_model = NoiseModel()
|
1170
1187
|
|
1171
1188
|
for a, b in self.get_logical_coupling_map():
|
1172
|
-
col_a, col_b = a % self.
|
1173
|
-
row_a, row_b = a // self.
|
1189
|
+
col_a, col_b = a % self._row_length, b % self._row_length
|
1190
|
+
row_a, row_b = a // self._row_length, b // self._row_length
|
1174
1191
|
is_long_a = self._is_col_long_range[col_a]
|
1175
1192
|
is_long_b = self._is_col_long_range[col_b]
|
1176
1193
|
|
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
|