pyqrack-cpu 1.44.1__py3-none-manylinux_2_35_x86_64.whl → 1.44.3__py3-none-manylinux_2_35_x86_64.whl

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.

Potentially problematic release.


This version of pyqrack-cpu might be problematic. Click here for more details.

@@ -11,6 +11,15 @@ from .qrack_simulator import QrackSimulator
11
11
  from .pauli import Pauli
12
12
 
13
13
 
14
+ _IS_QISKIT_AVAILABLE = True
15
+ try:
16
+ from qiskit.circuit.quantumcircuit import QuantumCircuit
17
+ from qiskit.compiler import transpile
18
+ from qiskit.quantum_info.operators.symplectic.clifford import Clifford
19
+ except ImportError:
20
+ _IS_QISKIT_AVAILABLE = False
21
+
22
+
14
23
  class QrackAceBackend:
15
24
  """A back end for elided quantum error correction
16
25
 
@@ -28,8 +37,9 @@ class QrackAceBackend:
28
37
  def __init__(
29
38
  self,
30
39
  qubit_count=-1,
40
+ toClone=None
31
41
  ):
32
- self.sim = QrackSimulator(3 * qubit_count)
42
+ self.sim = toClone.sim.clone() if toClone else QrackSimulator(3 * qubit_count)
33
43
 
34
44
 
35
45
  def _ct_pair_prob(self, q1, q2):
@@ -107,6 +117,13 @@ class QrackAceBackend:
107
117
  self._encode(hq)
108
118
 
109
119
 
120
+ def r(self, p, th, lq):
121
+ hq = self._unpack(lq)
122
+ self._decode(hq)
123
+ self.sim.r(p, th, hq[0])
124
+ self._encode(hq)
125
+
126
+
110
127
  def s(self, lq):
111
128
  hq = self._unpack(lq)
112
129
  self._decode(hq)
@@ -174,7 +191,7 @@ class QrackAceBackend:
174
191
  else:
175
192
  return
176
193
 
177
- if (lq2 == (lq1 + 1)) or (lq1 == (lq2 + 1)):
194
+ if lq2 == (lq1 + 1):
178
195
  hq1 = self._unpack(lq1, True)
179
196
  hq2 = self._unpack(lq2, False)
180
197
  self._decode(hq1, True)
@@ -182,6 +199,14 @@ class QrackAceBackend:
182
199
  gate([hq1[0]], hq2[0])
183
200
  self._encode(hq2, False)
184
201
  self._encode(hq1, True)
202
+ elif lq1 == (lq2 + 1):
203
+ hq2 = self._unpack(lq2, True)
204
+ hq1 = self._unpack(lq1, False)
205
+ self._decode(hq2, True)
206
+ self._decode(hq1, False)
207
+ gate([hq1[0]], hq2[0])
208
+ self._encode(hq1, False)
209
+ self._encode(hq2, True)
185
210
  else:
186
211
  hq1 = self._unpack(lq1)
187
212
  hq2 = self._unpack(lq2)
@@ -285,3 +310,301 @@ class QrackAceBackend:
285
310
 
286
311
  return results
287
312
 
313
+
314
+ def _apply_op(self, operation):
315
+ name = operation.name
316
+
317
+ if (name == 'id') or (name == 'barrier'):
318
+ # Skip measurement logic
319
+ return
320
+
321
+ conditional = getattr(operation, 'conditional', None)
322
+ if isinstance(conditional, int):
323
+ conditional_bit_set = (self._classical_register >> conditional) & 1
324
+ if not conditional_bit_set:
325
+ return
326
+ elif conditional is not None:
327
+ mask = int(conditional.mask, 16)
328
+ if mask > 0:
329
+ value = self._classical_memory & mask
330
+ while (mask & 0x1) == 0:
331
+ mask >>= 1
332
+ value >>= 1
333
+ if value != int(conditional.val, 16):
334
+ return
335
+
336
+ if (name == 'u1') or (name == 'p'):
337
+ self._sim.u(0, 0, float(operation.params[0]), operation.qubits[0]._index)
338
+ elif name == 'u2':
339
+ self._sim.u(
340
+ math.pi / 2,
341
+ float(operation.params[0]),
342
+ float(operation.params[1]),
343
+ operation.qubits[0]._index
344
+ )
345
+ elif (name == 'u3') or (name == 'u'):
346
+ self._sim.u(
347
+ float(operation.params[0]),
348
+ float(operation.params[1]),
349
+ float(operation.params[2]),
350
+ operation.qubits[0]._index
351
+ )
352
+ elif name == 'r':
353
+ self._sim.u(
354
+ float(operation.params[0]),
355
+ float(operation.params[1]) - math.pi / 2,
356
+ (-1 * float(operation.params[1])) + math.pi / 2,
357
+ operation.qubits[0]._index
358
+ )
359
+ elif name == 'rx':
360
+ self._sim.r(Pauli.PauliX, float(operation.params[0]), operation.qubits[0]._index)
361
+ elif name == 'ry':
362
+ self._sim.r(Pauli.PauliY, float(operation.params[0]), operation.qubits[0]._index)
363
+ elif name == 'rz':
364
+ self._sim.r(Pauli.PauliZ, float(operation.params[0]), operation.qubits[0]._index)
365
+ elif name == 'h':
366
+ self._sim.h(operation.qubits[0]._index)
367
+ elif name == 'x':
368
+ self._sim.x(operation.qubits[0]._index)
369
+ elif name == 'y':
370
+ self._sim.y(operation.qubits[0]._index)
371
+ elif name == 'z':
372
+ self._sim.z(operation.qubits[0]._index)
373
+ elif name == 's':
374
+ self._sim.s(operation.qubits[0]._index)
375
+ elif name == 'sdg':
376
+ self._sim.adjs(operation.qubits[0]._index)
377
+ elif name == 't':
378
+ self._sim.t(operation.qubits[0]._index)
379
+ elif name == 'tdg':
380
+ self._sim.adjt(operation.qubits[0]._index)
381
+ elif name == 'cx':
382
+ self._sim.cx(operation.qubits[0]._index, operation.qubits[1]._index)
383
+ elif name == 'cy':
384
+ self._sim.cy(operation.qubits[0]._index, operation.qubits[1]._index)
385
+ elif name == 'cz':
386
+ self._sim.cz(operation.qubits[0]._index, operation.qubits[1]._index)
387
+ elif name == 'dcx':
388
+ self._sim.mcx(operation.qubits[0]._index, operation.qubits[1]._index)
389
+ self._sim.mcx(operation.qubits[1]._index, operation.qubits[0]._index)
390
+ elif name == 'swap':
391
+ self._sim.swap(operation.qubits[0]._index, operation.qubits[1]._index)
392
+ elif name == 'iswap':
393
+ self._sim.iswap(operation.qubits[0]._index, operation.qubits[1]._index)
394
+ elif name == 'iswap_dg':
395
+ self._sim.adjiswap(operation.qubits[0]._index, operation.qubits[1]._index)
396
+ elif name == 'reset':
397
+ qubits = operation.qubits
398
+ for qubit in qubits:
399
+ if self._sim.m(qubit._index):
400
+ self._sim.x(qubit._index)
401
+ elif name == 'measure':
402
+ qubits = operation.qubits
403
+ clbits = operation.clbits
404
+ cregbits = (
405
+ operation.register
406
+ if hasattr(operation, 'register')
407
+ else len(operation.qubits) * [-1]
408
+ )
409
+
410
+ self._sample_qubits += qubits
411
+ self._sample_clbits += clbits
412
+ self._sample_cregbits += cregbits
413
+
414
+ if not self._sample_measure:
415
+ for index in range(len(qubits)):
416
+ qubit_outcome = self._sim.m(qubits[index]._index)
417
+
418
+ clbit = clbits[index]
419
+ clmask = 1 << clbit
420
+ self._classical_memory = (self._classical_memory & (~clmask)) | (
421
+ qubit_outcome << clbit
422
+ )
423
+
424
+ cregbit = cregbits[index]
425
+ if cregbit < 0:
426
+ cregbit = clbit
427
+
428
+ regbit = 1 << cregbit
429
+ self._classical_register = (
430
+ self._classical_register & (~regbit)
431
+ ) | (qubit_outcome << cregbit)
432
+
433
+ elif name == 'bfunc':
434
+ mask = int(operation.mask, 16)
435
+ relation = operation.relation
436
+ val = int(operation.val, 16)
437
+
438
+ cregbit = operation.register
439
+ cmembit = operation.memory if hasattr(operation, 'memory') else None
440
+
441
+ compared = (self._classical_register & mask) - val
442
+
443
+ if relation == '==':
444
+ outcome = compared == 0
445
+ elif relation == '!=':
446
+ outcome = compared != 0
447
+ elif relation == '<':
448
+ outcome = compared < 0
449
+ elif relation == '<=':
450
+ outcome = compared <= 0
451
+ elif relation == '>':
452
+ outcome = compared > 0
453
+ elif relation == '>=':
454
+ outcome = compared >= 0
455
+ else:
456
+ raise QrackError('Invalid boolean function relation.')
457
+
458
+ # Store outcome in register and optionally memory slot
459
+ regbit = 1 << cregbit
460
+ self._classical_register = (self._classical_register & (~regbit)) | (
461
+ int(outcome) << cregbit
462
+ )
463
+ if cmembit is not None:
464
+ membit = 1 << cmembit
465
+ self._classical_memory = (self._classical_memory & (~membit)) | (
466
+ int(outcome) << cmembit
467
+ )
468
+ else:
469
+ err_msg = 'QrackAceBackend encountered unrecognized operation "{0}"'
470
+ raise RuntimeError(err_msg.format(operation))
471
+
472
+ def _add_sample_measure(self, sample_qubits, sample_clbits, num_samples):
473
+ """Generate data samples from current statevector.
474
+
475
+ Taken almost straight from the terra source code.
476
+
477
+ Args:
478
+ measure_params (list): List of (qubit, clbit) values for
479
+ measure instructions to sample.
480
+ num_samples (int): The number of data samples to generate.
481
+
482
+ Returns:
483
+ list: A list of data values in hex format.
484
+ """
485
+ # Get unique qubits that are actually measured
486
+ measure_qubit = [qubit for qubit in sample_qubits]
487
+ measure_clbit = [clbit for clbit in sample_clbits]
488
+
489
+ # Sample and convert to bit-strings
490
+ if num_samples == 1:
491
+ sample = self._sim.m_all()
492
+ result = 0
493
+ for index in range(len(measure_qubit)):
494
+ qubit = measure_qubit[index]._index
495
+ qubit_outcome = (sample >> qubit) & 1
496
+ result |= qubit_outcome << index
497
+ measure_results = [result]
498
+ else:
499
+ measure_results = self._sim.measure_shots([q._index for q in measure_qubit], num_samples)
500
+
501
+ data = []
502
+ for sample in measure_results:
503
+ for index in range(len(measure_qubit)):
504
+ qubit_outcome = (sample >> index) & 1
505
+ clbit = measure_clbit[index]._index
506
+ clmask = 1 << clbit
507
+ self._classical_memory = (self._classical_memory & (~clmask)) | (
508
+ qubit_outcome << clbit
509
+ )
510
+
511
+ data.append(bin(self._classical_memory)[2:].zfill(self.num_qubits()))
512
+
513
+ return data
514
+
515
+ def run_qiskit_circuit(self, experiment, shots=1):
516
+ if not _IS_QISKIT_AVAILABLE:
517
+ raise RuntimeError(
518
+ "Before trying to run_qiskit_circuit() with QrackAceBackend, you must install Qiskit!"
519
+ )
520
+
521
+ instructions = []
522
+ if isinstance(experiment, QuantumCircuit):
523
+ instructions = experiment.data
524
+ else:
525
+ raise RuntimeError('Unrecognized "run_input" argument specified for run().')
526
+
527
+ self._shots = shots
528
+ self._sample_qubits = []
529
+ self._sample_clbits = []
530
+ self._sample_cregbits = []
531
+ self._sample_measure = True
532
+ _data = []
533
+ shotLoopMax = 1
534
+
535
+ is_initializing = True
536
+ boundary_start = -1
537
+
538
+ for opcount in range(len(instructions)):
539
+ operation = instructions[opcount]
540
+
541
+ if operation.name == 'id' or operation.name == 'barrier':
542
+ continue
543
+
544
+ if is_initializing and (
545
+ (operation.name == 'measure') or (operation.name == 'reset')
546
+ ):
547
+ continue
548
+
549
+ is_initializing = False
550
+
551
+ if (operation.name == 'measure') or (operation.name == 'reset'):
552
+ if boundary_start == -1:
553
+ boundary_start = opcount
554
+
555
+ if (boundary_start != -1) and (operation.name != 'measure'):
556
+ shotsPerLoop = 1
557
+ shotLoopMax = self._shots
558
+ self._sample_measure = False
559
+ break
560
+
561
+ preamble_memory = 0
562
+ preamble_register = 0
563
+ preamble_sim = None
564
+
565
+ if self._sample_measure or boundary_start <= 0:
566
+ boundary_start = 0
567
+ self._sample_measure = True
568
+ shotsPerLoop = self._shots
569
+ shotLoopMax = 1
570
+ else:
571
+ boundary_start -= 1
572
+ if boundary_start > 0:
573
+ self._sim = self
574
+ self._classical_memory = 0
575
+ self._classical_register = 0
576
+
577
+ for operation in instructions[:boundary_start]:
578
+ self._apply_op(operation)
579
+
580
+ preamble_memory = self._classical_memory
581
+ preamble_register = self._classical_register
582
+ preamble_sim = self._sim
583
+
584
+ for shot in range(shotLoopMax):
585
+ if preamble_sim is None:
586
+ self._sim = self
587
+ self._classical_memory = 0
588
+ self._classical_register = 0
589
+ else:
590
+ self._sim = QrackAceBackend(toClone=preamble_sim)
591
+ self._classical_memory = preamble_memory
592
+ self._classical_register = preamble_register
593
+
594
+ for operation in instructions[boundary_start:]:
595
+ self._apply_op(operation)
596
+
597
+ if not self._sample_measure and (len(self._sample_qubits) > 0):
598
+ _data += [bin(self._classical_memory)[2:].zfill(self.num_qubits())]
599
+ self._sample_qubits = []
600
+ self._sample_clbits = []
601
+ self._sample_cregbits = []
602
+
603
+ if self._sample_measure and (len(self._sample_qubits) > 0):
604
+ _data = self._add_sample_measure(
605
+ self._sample_qubits, self._sample_clbits, self._shots
606
+ )
607
+
608
+ del self._sim
609
+
610
+ return _data
@@ -3843,7 +3843,7 @@ class QrackSimulator:
3843
3843
 
3844
3844
  if not self._sample_measure:
3845
3845
  for index in range(len(qubits)):
3846
- qubit_outcome = self._sim.m(qubits[index])
3846
+ qubit_outcome = self._sim.m(qubits[index]._index)
3847
3847
 
3848
3848
  clbit = clbits[index]
3849
3849
  clmask = 1 << clbit
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyqrack-cpu
3
- Version: 1.44.1
3
+ Version: 1.44.3
4
4
  Summary: pyqrack - Pure Python vm6502q/qrack Wrapper
5
5
  Home-page: https://github.com/vm6502q/pyqrack
6
6
  Author: Daniel Strano
@@ -1,11 +1,11 @@
1
1
  pyqrack/__init__.py,sha256=yH4CMEDLk59IphSl9303zTP8Pmj3usIQMSDCOb42KCc,768
2
2
  pyqrack/neuron_activation_fn.py,sha256=NYG78IFCiJ586E9oA6lJl38Rl18_WFfcdL6I2NYfiPs,594
3
3
  pyqrack/pauli.py,sha256=wg500wDOwdIU4lEVJoMmjtbAdmtakZYzLPjdzC2rwUQ,654
4
- pyqrack/qrack_ace_backend.py,sha256=tyky2zZDKI4BfoepbV5cffQquftO96P8CTRldALc78Q,6783
4
+ pyqrack/qrack_ace_backend.py,sha256=ykDnNIKrPUbmfyhmH7gt1DUxY2x-HCYCfsdHPlxNZc0,18822
5
5
  pyqrack/qrack_circuit.py,sha256=TyppOMNk_0nolChMRewf4CfQGuYiEUJ8qUWWN6y03PE,19093
6
6
  pyqrack/qrack_neuron.py,sha256=oEvMnkFFOUBXFbIXYYY-Nir3yTo0nyw_xoRdNXeSEgk,8843
7
7
  pyqrack/qrack_neuron_torch_layer.py,sha256=Xn6MF1hSLT0bFequx4AJTsxFdg3gO01WB9rmDE7sP9w,5824
8
- pyqrack/qrack_simulator.py,sha256=6nMSg0vQwBg9syuu9lhCpBcB0x-CAD-XNA9zc53mcQY,135707
8
+ pyqrack/qrack_simulator.py,sha256=KeLEW49mkifX0C0caux9l3HHcF73YF6iewTBqWzv0Go,135714
9
9
  pyqrack/qrack_stabilizer.py,sha256=CJhj8GLPH-ZM38joHr9ZL-6_IY2JC8Zql7COoePJC0U,2129
10
10
  pyqrack/quimb_circuit_type.py,sha256=Sk-Tmn38kUYmAkJJ75btWuhYZyTXOOezmowFhfdiGDc,621
11
11
  pyqrack/qrack_system/__init__.py,sha256=-oZ9dsb1hixsnrkUJRY_C5DzQ_l6MtifF_Z465BgqV4,334
@@ -15,8 +15,8 @@ pyqrack/qrack_system/qrack_lib/libqrack_pinvoke.so.9.19.1,sha256=xCkv9fSt8o7umqp
15
15
  pyqrack/stats/__init__.py,sha256=Hla85my2fY_roR9lIjGBVpEG7ySOTMwjWa8D6-kgCnY,276
16
16
  pyqrack/stats/load_quantized_data.py,sha256=10-ZULlnSX45br7fDtJuiCzcMTAL4eI3QyhSENXZjgM,1162
17
17
  pyqrack/stats/quantize_by_range.py,sha256=OjY0I8PGbellrRfdIyiC0RLdpdbbJex3C2D_bapNIqE,2211
18
- pyqrack_cpu-1.44.1.dist-info/LICENSE,sha256=HxB-7SaWTuewAk1nz-3_3FUD6QhgX73kNT_taKVUTq8,1069
19
- pyqrack_cpu-1.44.1.dist-info/METADATA,sha256=yDm0NcKxSeie6TxUpPW3kuDfja5TqO-vJopuPWM_VbA,6492
20
- pyqrack_cpu-1.44.1.dist-info/WHEEL,sha256=AMMNaGlKLEICDqgnxZojk7k8N6wUjQQ3X9tPjxJ2sOc,110
21
- pyqrack_cpu-1.44.1.dist-info/top_level.txt,sha256=YE_3q9JTGRLMilNg2tGP1y7uU-Dx8PDao2OhwoIbv8E,8
22
- pyqrack_cpu-1.44.1.dist-info/RECORD,,
18
+ pyqrack_cpu-1.44.3.dist-info/LICENSE,sha256=HxB-7SaWTuewAk1nz-3_3FUD6QhgX73kNT_taKVUTq8,1069
19
+ pyqrack_cpu-1.44.3.dist-info/METADATA,sha256=fwhf2tIyS8olEB6x2eCi29NGTkGMw8hR9Xt4TqYAsQM,6492
20
+ pyqrack_cpu-1.44.3.dist-info/WHEEL,sha256=AMMNaGlKLEICDqgnxZojk7k8N6wUjQQ3X9tPjxJ2sOc,110
21
+ pyqrack_cpu-1.44.3.dist-info/top_level.txt,sha256=YE_3q9JTGRLMilNg2tGP1y7uU-Dx8PDao2OhwoIbv8E,8
22
+ pyqrack_cpu-1.44.3.dist-info/RECORD,,