pyqrack-cuda 1.53.3__tar.gz → 1.54.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.53.3/pyqrack_cuda.egg-info → pyqrack_cuda-1.54.0}/PKG-INFO +1 -1
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/qrack_ace_backend.py +53 -46
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/setup.py +1 -1
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/LICENSE +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/MANIFEST.in +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/Makefile +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/README.md +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyproject.toml +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/__init__.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/pauli.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/qrack_simulator.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/qrack_system/qrack_system.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack_cuda.egg-info/SOURCES.txt +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack_cuda.egg-info/requires.txt +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/pyqrack_cuda.egg-info/top_level.txt +0 -0
- {pyqrack_cuda-1.53.3 → pyqrack_cuda-1.54.0}/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,31 +510,31 @@ 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.
|
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
|
513
520
|
|
514
521
|
connected_cols = []
|
515
|
-
c = (lq1_col - 1) % self.
|
522
|
+
c = (lq1_col - 1) % self._row_length
|
516
523
|
while self._is_col_long_range[c] and (
|
517
|
-
len(connected_cols) < (self.
|
524
|
+
len(connected_cols) < (self._row_length - 1)
|
518
525
|
):
|
519
526
|
connected_cols.append(c)
|
520
|
-
c = (c - 1) % self.
|
521
|
-
if len(connected_cols) < (self.
|
527
|
+
c = (c - 1) % self._row_length
|
528
|
+
if len(connected_cols) < (self._row_length - 1):
|
522
529
|
connected_cols.append(c)
|
523
530
|
boundary = len(connected_cols)
|
524
|
-
c = (lq1_col + 1) % self.
|
531
|
+
c = (lq1_col + 1) % self._row_length
|
525
532
|
while self._is_col_long_range[c] and (
|
526
|
-
len(connected_cols) < (self.
|
533
|
+
len(connected_cols) < (self._row_length - 1)
|
527
534
|
):
|
528
535
|
connected_cols.append(c)
|
529
|
-
c = (c + 1) % self.
|
530
|
-
if len(connected_cols) < (self.
|
536
|
+
c = (c + 1) % self._row_length
|
537
|
+
if len(connected_cols) < (self._row_length - 1):
|
531
538
|
connected_cols.append(c)
|
532
539
|
|
533
540
|
hq1 = self._unpack(lq1)
|
@@ -727,22 +734,22 @@ class QrackAceBackend:
|
|
727
734
|
# However, locality of collapse matters:
|
728
735
|
# measure in row pairs, and always across rows,
|
729
736
|
# and by row directionality.
|
730
|
-
row_pairs = list(range((self.
|
737
|
+
row_pairs = list(range((self._col_length + 1) // 2))
|
731
738
|
random.shuffle(row_pairs)
|
732
739
|
for row_pair in row_pairs:
|
733
|
-
col_offset = random.randint(0, self.
|
740
|
+
col_offset = random.randint(0, self._row_length - 1)
|
734
741
|
lq_row = row_pair << 1
|
735
|
-
for c in range(self.
|
736
|
-
lq_col = (c + col_offset) % self.
|
737
|
-
lq = lq_row * self.
|
742
|
+
for c in range(self._row_length):
|
743
|
+
lq_col = (c + col_offset) % self._row_length
|
744
|
+
lq = lq_row * self._row_length + lq_col
|
738
745
|
if self.m(lq):
|
739
746
|
result |= 1 << lq
|
740
747
|
lq_row += 1
|
741
|
-
if lq_row == self.
|
748
|
+
if lq_row == self._col_length:
|
742
749
|
continue
|
743
|
-
for c in range(self.
|
744
|
-
lq_col = ((self.
|
745
|
-
lq = lq_row * self.
|
750
|
+
for c in range(self._row_length):
|
751
|
+
lq_col = ((self._row_length - (c + 1)) + col_offset) % self._row_length
|
752
|
+
lq = lq_row * self._row_length + lq_col
|
746
753
|
if self.m(lq):
|
747
754
|
result |= 1 << lq
|
748
755
|
|
@@ -1123,7 +1130,7 @@ class QrackAceBackend:
|
|
1123
1130
|
return self._coupling_map
|
1124
1131
|
|
1125
1132
|
coupling_map = set()
|
1126
|
-
rows, cols = self.
|
1133
|
+
rows, cols = self._row_length, self._col_length
|
1127
1134
|
|
1128
1135
|
# Map each column index to its full list of logical qubit indices
|
1129
1136
|
def logical_index(row, col):
|
@@ -1133,19 +1140,19 @@ class QrackAceBackend:
|
|
1133
1140
|
connected_cols = [col]
|
1134
1141
|
c = (col - 1) % cols
|
1135
1142
|
while self._is_col_long_range[c] and (
|
1136
|
-
len(connected_cols) < self.
|
1143
|
+
len(connected_cols) < self._row_length
|
1137
1144
|
):
|
1138
1145
|
connected_cols.append(c)
|
1139
1146
|
c = (c - 1) % cols
|
1140
|
-
if len(connected_cols) < self.
|
1147
|
+
if len(connected_cols) < self._row_length:
|
1141
1148
|
connected_cols.append(c)
|
1142
1149
|
c = (col + 1) % cols
|
1143
1150
|
while self._is_col_long_range[c] and (
|
1144
|
-
len(connected_cols) < self.
|
1151
|
+
len(connected_cols) < self._row_length
|
1145
1152
|
):
|
1146
1153
|
connected_cols.append(c)
|
1147
1154
|
c = (c + 1) % cols
|
1148
|
-
if len(connected_cols) < self.
|
1155
|
+
if len(connected_cols) < self._row_length:
|
1149
1156
|
connected_cols.append(c)
|
1150
1157
|
|
1151
1158
|
for row in range(rows):
|
@@ -1169,8 +1176,8 @@ class QrackAceBackend:
|
|
1169
1176
|
noise_model = NoiseModel()
|
1170
1177
|
|
1171
1178
|
for a, b in self.get_logical_coupling_map():
|
1172
|
-
col_a, col_b = a % self.
|
1173
|
-
row_a, row_b = a // self.
|
1179
|
+
col_a, col_b = a % self._row_length, b % self._row_length
|
1180
|
+
row_a, row_b = a // self._row_length, b // self._row_length
|
1174
1181
|
is_long_a = self._is_col_long_range[col_a]
|
1175
1182
|
is_long_b = self._is_col_long_range[col_b]
|
1176
1183
|
|
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
|