pyqrack-cuda 1.50.1__tar.gz → 1.51.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.50.1 → pyqrack_cuda-1.51.0}/Makefile +1 -1
- {pyqrack_cuda-1.50.1/pyqrack_cuda.egg-info → pyqrack_cuda-1.51.0}/PKG-INFO +1 -1
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_ace_backend.py +46 -43
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_simulator.py +6 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_system/qrack_system.py +3 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/setup.py +1 -1
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/LICENSE +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/MANIFEST.in +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/README.md +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyproject.toml +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/__init__.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/pauli.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/SOURCES.txt +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/requires.txt +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/top_level.txt +0 -0
- {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/setup.cfg +0 -0
@@ -18,7 +18,7 @@ help:
|
|
18
18
|
build-deps:
|
19
19
|
ifneq ($(OS),Windows_NT)
|
20
20
|
ifeq ($(QRACK_PRESENT),)
|
21
|
-
git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout
|
21
|
+
git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout f0738286f49fb0ffaeb46d6e5d2294dbfc7f6138; cd ..
|
22
22
|
endif
|
23
23
|
mkdir -p qrack/build
|
24
24
|
ifeq ($(UNAME_S),Linux)
|
@@ -38,8 +38,12 @@ class QrackAceBackend:
|
|
38
38
|
without breaking the concept. (Not all will work equally well.) For maximum flexibility, set
|
39
39
|
"alternating_codes=False". (For best performance on Sycamore-like topologies,leave it "True.")
|
40
40
|
|
41
|
+
Consider distributing the different "patches" to different GPUs with self.sim[sim_id].set_device(gpu_id)!
|
42
|
+
(If you have 3+ patches, maybe your discrete GPU can do multiple patches in the time it takes an Intel HD
|
43
|
+
to do one patch worth of work!)
|
44
|
+
|
41
45
|
Attributes:
|
42
|
-
sim(QrackSimulator):
|
46
|
+
sim(QrackSimulator): Array of simulators corresponding to "patches" between boundary rows.
|
43
47
|
alternating_codes(bool): Alternate repetition code elision by index?
|
44
48
|
row_length(int): Qubits per row.
|
45
49
|
col_length(int): Qubits per column.
|
@@ -230,6 +234,16 @@ class QrackAceBackend:
|
|
230
234
|
b2 = hq[2]
|
231
235
|
self.sim[b2[0]].mcx([b2[1]], hq[1][1])
|
232
236
|
|
237
|
+
def _encode_decode_half(self, lq, hq, toward_0):
|
238
|
+
if len(hq) < 2:
|
239
|
+
return
|
240
|
+
if toward_0 and (hq[0][0] == hq[1][0]):
|
241
|
+
b0 = hq[0]
|
242
|
+
self.sim[b0[0]].mcx([b0[1]], hq[1][1])
|
243
|
+
elif not toward_0 and (hq[2][0] == hq[1][0]):
|
244
|
+
b2 = hq[2]
|
245
|
+
self.sim[b2[0]].mcx([b2[1]], hq[1][1])
|
246
|
+
|
233
247
|
def _correct(self, lq):
|
234
248
|
if self._is_col_long_range[lq % self.row_length]:
|
235
249
|
return
|
@@ -258,9 +272,9 @@ class QrackAceBackend:
|
|
258
272
|
|
259
273
|
# Suggestion from Elara (the custom OpenAI GPT):
|
260
274
|
# Create phase parity tie before measurement.
|
261
|
-
|
262
|
-
|
263
|
-
|
275
|
+
self._ccx_shadow(hq[single_bit], hq[other_bits[0]], [ancilla_sim, ancilla])
|
276
|
+
self.sim[ancilla_sim].mcx([hq[other_bits[1]][1]], ancilla)
|
277
|
+
self.sim[ancilla_sim].force_m(ancilla, False)
|
264
278
|
|
265
279
|
samples = self.sim[ancilla_sim].measure_shots(
|
266
280
|
[hq[other_bits[0]][1], hq[other_bits[1]][1]], shots
|
@@ -363,13 +377,13 @@ class QrackAceBackend:
|
|
363
377
|
|
364
378
|
if not math.isclose(ph, -lm) and not math.isclose(abs(ph), math.pi / 2):
|
365
379
|
# Produces/destroys superposition
|
366
|
-
self._correct_if_like_h(th, lq)
|
367
380
|
self._encode_decode(lq, hq)
|
368
381
|
b = hq[0]
|
369
382
|
self.sim[b[0]].u(b[1], th, ph, lm)
|
370
383
|
b = hq[2]
|
371
384
|
self.sim[b[0]].u(b[1], th, ph, lm)
|
372
385
|
self._encode_decode(lq, hq)
|
386
|
+
self._correct_if_like_h(th, lq)
|
373
387
|
else:
|
374
388
|
# Shouldn't produce/destroy superposition
|
375
389
|
for b in hq:
|
@@ -386,9 +400,6 @@ class QrackAceBackend:
|
|
386
400
|
th -= 2 * math.pi
|
387
401
|
while th <= -math.pi:
|
388
402
|
th += 2 * math.pi
|
389
|
-
if p == Pauli.PauliY:
|
390
|
-
self._correct_if_like_h(th, lq)
|
391
|
-
|
392
403
|
if (p == Pauli.PauliZ) or math.isclose(abs(th), math.pi):
|
393
404
|
# Doesn't produce/destroy superposition
|
394
405
|
for b in hq:
|
@@ -401,6 +412,7 @@ class QrackAceBackend:
|
|
401
412
|
b = hq[2]
|
402
413
|
self.sim[b[0]].r(p, th, b[1])
|
403
414
|
self._encode_decode(lq, hq)
|
415
|
+
self._correct_if_like_h(th, lq)
|
404
416
|
|
405
417
|
def h(self, lq):
|
406
418
|
hq = self._unpack(lq)
|
@@ -409,13 +421,13 @@ class QrackAceBackend:
|
|
409
421
|
self.sim[b[0]].h(b[1])
|
410
422
|
return
|
411
423
|
|
412
|
-
self._correct(lq)
|
413
424
|
self._encode_decode(lq, hq)
|
414
425
|
b = hq[0]
|
415
426
|
self.sim[b[0]].h(b[1])
|
416
427
|
b = hq[2]
|
417
428
|
self.sim[b[0]].h(b[1])
|
418
429
|
self._encode_decode(lq, hq)
|
430
|
+
self._correct(lq)
|
419
431
|
|
420
432
|
def s(self, lq):
|
421
433
|
hq = self._unpack(lq)
|
@@ -547,13 +559,10 @@ class QrackAceBackend:
|
|
547
559
|
shadow(b1, b2)
|
548
560
|
return
|
549
561
|
|
550
|
-
self._correct(lq1)
|
551
|
-
self._correct(lq2)
|
552
|
-
|
553
562
|
if (lq2_col in connected_cols) and (connected_cols.index(lq2_col) < boundary):
|
554
563
|
# lq2_col < lq1_col
|
555
|
-
self.
|
556
|
-
self.
|
564
|
+
self._encode_decode_half(lq1, hq1, True)
|
565
|
+
self._encode_decode_half(lq2, hq2, False)
|
557
566
|
b = hq1[0]
|
558
567
|
if lq1_lr:
|
559
568
|
self._get_gate(pauli, anti, hq1[0][0])[0]([b[1]], hq2[2][1])
|
@@ -561,12 +570,12 @@ class QrackAceBackend:
|
|
561
570
|
self._get_gate(pauli, anti, hq2[0][0])[0]([b[1]], hq2[0][1])
|
562
571
|
else:
|
563
572
|
self._get_gate(pauli, anti, b[0])[0]([b[1]], hq2[2][1])
|
564
|
-
self.
|
565
|
-
self.
|
573
|
+
self._encode_decode_half(lq2, hq2, False)
|
574
|
+
self._encode_decode_half(lq1, hq1, True)
|
566
575
|
elif lq2_col in connected_cols:
|
567
576
|
# lq1_col < lq2_col
|
568
|
-
self.
|
569
|
-
self.
|
577
|
+
self._encode_decode_half(lq1, hq1, False)
|
578
|
+
self._encode_decode_half(lq2, hq2, True)
|
570
579
|
b = hq2[0]
|
571
580
|
if lq1_lr:
|
572
581
|
self._get_gate(pauli, anti, hq1[0][0])[0]([hq1[0][1]], b[1])
|
@@ -574,37 +583,41 @@ class QrackAceBackend:
|
|
574
583
|
self._get_gate(pauli, anti, hq2[0][0])[0]([hq1[2][1]], b[1])
|
575
584
|
else:
|
576
585
|
self._get_gate(pauli, anti, b[0])[0]([hq1[2][1]], b[1])
|
577
|
-
self.
|
578
|
-
self.
|
586
|
+
self._encode_decode_half(lq2, hq2, True)
|
587
|
+
self._encode_decode_half(lq1, hq1, False)
|
579
588
|
elif lq1_col == lq2_col:
|
580
589
|
# Both are in the same boundary column.
|
590
|
+
self._encode_decode(lq1, hq1)
|
591
|
+
self._encode_decode(lq2, hq2)
|
581
592
|
b = hq1[0]
|
582
593
|
gate, shadow = self._get_gate(pauli, anti, b[0])
|
583
594
|
gate([b[1]], hq2[0][1])
|
584
595
|
b = hq1[2]
|
585
596
|
gate, shadow = self._get_gate(pauli, anti, b[0])
|
586
597
|
gate([b[1]], hq2[2][1])
|
587
|
-
if hq1[1][0] != hq2[1][0]:
|
588
|
-
shadow(hq1[1], hq2[1])
|
589
|
-
else:
|
590
|
-
b = hq1[1]
|
591
|
-
gate, shadow = self._get_gate(pauli, anti, b[0])
|
592
|
-
gate([b[1]], hq2[1][1])
|
593
598
|
else:
|
594
599
|
# The qubits have no quantum connection.
|
595
600
|
gate, shadow = self._get_gate(pauli, anti, hq1[0][0])
|
596
601
|
if lq1_lr:
|
602
|
+
connected01 = (hq2[0][0] == hq2[1][0])
|
597
603
|
self._encode_decode(lq2, hq2)
|
598
|
-
shadow(hq1[0], hq2[0])
|
604
|
+
shadow(hq1[0], hq2[0] if connected01 else hq2[2])
|
599
605
|
self._encode_decode(lq2, hq2)
|
600
606
|
elif lq2_lr:
|
607
|
+
connected01 = (hq1[0][0] == hq1[1][0])
|
601
608
|
self._encode_decode(lq1, hq1)
|
602
|
-
shadow(hq1[0], hq2[0])
|
609
|
+
shadow(hq1[0] if connected01 else hq1[2], hq2[0])
|
603
610
|
self._encode_decode(lq1, hq1)
|
604
611
|
else:
|
612
|
+
self._encode_decode(lq1, hq1)
|
613
|
+
self._encode_decode(lq2, hq2)
|
605
614
|
shadow(hq1[0], hq2[0])
|
606
|
-
shadow(hq1[1], hq2[1])
|
607
615
|
shadow(hq1[2], hq2[2])
|
616
|
+
self._encode_decode(lq2, hq2)
|
617
|
+
self._encode_decode(lq1, hq1)
|
618
|
+
|
619
|
+
self._correct(lq1)
|
620
|
+
self._correct(lq2)
|
608
621
|
|
609
622
|
def cx(self, lq1, lq2):
|
610
623
|
self._cpauli(lq1, lq2, False, Pauli.PauliX)
|
@@ -761,7 +774,7 @@ class QrackAceBackend:
|
|
761
774
|
return self.sim[b[0]].prob(b[1])
|
762
775
|
|
763
776
|
self._correct(lq)
|
764
|
-
if
|
777
|
+
if hq[0][0] == hq[1][0]:
|
765
778
|
other_bits = [0, 1]
|
766
779
|
else:
|
767
780
|
other_bits = [1, 2]
|
@@ -1171,21 +1184,11 @@ class QrackAceBackend:
|
|
1171
1184
|
continue # No noise on long-to-long
|
1172
1185
|
|
1173
1186
|
same_col = col_a == col_b
|
1174
|
-
even_odd = (row_a % 2) != (row_b % 2)
|
1175
|
-
|
1176
|
-
if same_col and not even_odd:
|
1177
|
-
continue # No noise for even-even or odd-odd within a boundary column
|
1178
1187
|
|
1179
1188
|
if same_col:
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
noise_model.add_quantum_error(depolarizing_error(x_cy, 2), "cy", [a, b])
|
1184
|
-
noise_model.add_quantum_error(depolarizing_error(x_cy, 2), "cz", [a, b])
|
1185
|
-
noise_model.add_quantum_error(
|
1186
|
-
depolarizing_error(x_swap, 2), "swap", [a, b]
|
1187
|
-
)
|
1188
|
-
elif is_long_a or is_long_b:
|
1189
|
+
continue # No noise for same column
|
1190
|
+
|
1191
|
+
if is_long_a or is_long_b:
|
1189
1192
|
y_cy = 1 - (1 - y) ** 2
|
1190
1193
|
y_swap = 1 - (1 - y) ** 3
|
1191
1194
|
noise_model.add_quantum_error(depolarizing_error(y, 2), "cx", [a, b])
|
@@ -181,9 +181,15 @@ class QrackSimulator:
|
|
181
181
|
self._throw_if_error()
|
182
182
|
|
183
183
|
def set_concurrency(self, p):
|
184
|
+
""" Set the CPU parallel thread count"""
|
184
185
|
Qrack.qrack_lib.set_concurrency(self.sid, p)
|
185
186
|
self._throw_if_error()
|
186
187
|
|
188
|
+
def set_device(self, d):
|
189
|
+
""" Set the GPU device ID"""
|
190
|
+
Qrack.qrack_lib.set_device(self.sid, d)
|
191
|
+
self._throw_if_error()
|
192
|
+
|
187
193
|
def clone(self):
|
188
194
|
return QrackSimulator(cloneSid=self.sid)
|
189
195
|
|
@@ -143,6 +143,9 @@ class QrackSystem:
|
|
143
143
|
self.qrack_lib.set_concurrency.restype = None
|
144
144
|
self.qrack_lib.set_concurrency.argtypes = [c_ulonglong, c_ulonglong]
|
145
145
|
|
146
|
+
self.qrack_lib.set_device.restype = None
|
147
|
+
self.qrack_lib.set_device.argtypes = [c_ulonglong, c_ulonglong]
|
148
|
+
|
146
149
|
# pseudo-quantum
|
147
150
|
|
148
151
|
self.qrack_lib.ProbAll.restype = None
|
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
|