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.
Files changed (29) hide show
  1. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/Makefile +1 -1
  2. {pyqrack_cuda-1.50.1/pyqrack_cuda.egg-info → pyqrack_cuda-1.51.0}/PKG-INFO +1 -1
  3. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_ace_backend.py +46 -43
  4. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_simulator.py +6 -0
  5. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_system/qrack_system.py +3 -0
  6. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0/pyqrack_cuda.egg-info}/PKG-INFO +1 -1
  7. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/setup.py +1 -1
  8. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/LICENSE +0 -0
  9. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/MANIFEST.in +0 -0
  10. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/README.md +0 -0
  11. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyproject.toml +0 -0
  12. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/__init__.py +0 -0
  13. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/neuron_activation_fn.py +0 -0
  14. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/pauli.py +0 -0
  15. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_circuit.py +0 -0
  16. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_neuron.py +0 -0
  17. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
  18. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_stabilizer.py +0 -0
  19. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/qrack_system/__init__.py +0 -0
  20. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/quimb_circuit_type.py +0 -0
  21. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/stats/__init__.py +0 -0
  22. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/stats/load_quantized_data.py +0 -0
  23. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack/stats/quantize_by_range.py +0 -0
  24. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/SOURCES.txt +0 -0
  25. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/dependency_links.txt +0 -0
  26. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/not-zip-safe +0 -0
  27. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/requires.txt +0 -0
  28. {pyqrack_cuda-1.50.1 → pyqrack_cuda-1.51.0}/pyqrack_cuda.egg-info/top_level.txt +0 -0
  29. {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 065d4575ca82be0398ed726de59899c16500581f; cd ..
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-cuda
3
- Version: 1.50.1
3
+ Version: 1.51.0
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -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): Corresponding simulator.
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
- # self._ccx_shadow(hq[single_bit], hq[other_bits[0]], [ancilla_sim, ancilla])
262
- # self.sim[ancilla_sim].mcx([hq[other_bits[1]][1]], ancilla)
263
- # self.sim[ancilla_sim].force_m(ancilla, False)
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._encode_decode(lq1, hq1)
556
- self._encode_decode(lq2, hq2)
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._encode_decode(lq2, hq2)
565
- self._encode_decode(lq1, hq1)
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._encode_decode(lq1, hq1)
569
- self._encode_decode(lq2, hq2)
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._encode_decode(lq2, hq2)
578
- self._encode_decode(lq1, hq1)
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 not self.alternating_codes or not ((lq // self.row_length) & 1):
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
- x_cy = 1 - (1 - x) ** 2
1181
- x_swap = 1 - (1 - x) ** 3
1182
- noise_model.add_quantum_error(depolarizing_error(x, 2), "cx", [a, b])
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyqrack-cuda
3
- Version: 1.50.1
3
+ Version: 1.51.0
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -7,7 +7,7 @@ from setuptools import setup
7
7
  from setuptools.command.build_py import build_py
8
8
 
9
9
 
10
- VERSION = "1.50.1"
10
+ VERSION = "1.51.0"
11
11
 
12
12
  # Read long description from README.
13
13
  README_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md')
File without changes
File without changes
File without changes
File without changes