Qrack  7.0
General classical-emulating-quantum development framework
qstabilizerhybrid.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017-2022. All rights reserved.
4 //
5 // This is a multithreaded, universal quantum register simulation, allowing
6 // (nonphysical) register cloning and direct measurement of probability and
7 // phase, to leverage what advantages classical emulation of qubits can have.
8 //
9 // Licensed under the GNU Lesser General Public License V3.
10 // See LICENSE.md in the project root or https://www.gnu.org/licenses/lgpl-3.0.en.html
11 // for details.
12 #pragma once
13 
14 #include "common/qrack_types.hpp"
15 
16 #if ENABLE_OPENCL
17 #include "common/oclengine.hpp"
18 #endif
19 
20 #include "mpsshard.hpp"
21 #include "qengine.hpp"
22 #include "qparity.hpp"
23 #include "qstabilizer.hpp"
24 
25 #if ENABLE_ALU
26 #include "qalu.hpp"
27 #endif
28 
29 #define QINTERFACE_TO_QALU(qReg) std::dynamic_pointer_cast<QAlu>(qReg)
30 #define QINTERFACE_TO_QPARITY(qReg) std::dynamic_pointer_cast<QParity>(qReg)
31 
32 namespace Qrack {
33 
35 typedef std::shared_ptr<QStabilizerHybrid> QStabilizerHybridPtr;
36 
41 #if ENABLE_ALU
42 class QStabilizerHybrid : public QAlu, public QParity, public QInterface {
43 #else
44 class QStabilizerHybrid : public QParity, public QInterface {
45 #endif
46 protected:
47  std::vector<QInterfaceEngine> engineTypes;
50  std::vector<MpsShardPtr> shards;
51  int devID;
54  bool useHostRam;
55  bool isSparse;
60  std::vector<int> deviceIDs;
61 
64 
65  void InvertBuffer(bitLenInt qubit)
66  {
67  complex pauliX[4] = { ZERO_CMPLX, ONE_CMPLX, ONE_CMPLX, ZERO_CMPLX };
68  MpsShardPtr pauliShard = std::make_shared<MpsShard>(pauliX);
69  pauliShard->Compose(shards[qubit]->gate);
70  shards[qubit] = pauliShard->IsIdentity() ? NULL : pauliShard;
71  stabilizer->X(qubit);
72  }
73 
74  void FlushIfBlocked(bitLenInt control, bitLenInt target, bool isPhase = false)
75  {
76  if (engine) {
77  return;
78  }
79 
80  if (shards[target] && shards[target]->IsInvert()) {
81  InvertBuffer(target);
82  }
83 
84  if (shards[control] && shards[control]->IsInvert()) {
85  InvertBuffer(control);
86  }
87 
88  bool isBlocked = (shards[target] && (!isPhase || !shards[target]->IsPhase()));
89  isBlocked |= (shards[control] && !shards[control]->IsPhase());
90 
91  if (isBlocked) {
93  }
94  }
95 
96  virtual bool CollapseSeparableShard(bitLenInt qubit)
97  {
98  MpsShardPtr shard = shards[qubit];
99  shards[qubit] = NULL;
100  real1_f prob;
101 
102  const bool isZ1 = stabilizer->M(qubit);
103 
104  if (isZ1) {
105  prob = norm(shard->gate[3]);
106  } else {
107  prob = norm(shard->gate[2]);
108  }
109 
110  bool result;
111  if (prob <= ZERO_R1) {
112  result = false;
113  } else if (prob >= ONE_R1) {
114  result = true;
115  } else {
116  result = (Rand() <= prob);
117  }
118 
119  if (result != isZ1) {
120  stabilizer->X(qubit);
121  }
122 
123  return result;
124  }
125 
126  virtual void FlushBuffers()
127  {
128  if (stabilizer) {
129  for (bitLenInt i = 0; i < qubitCount; i++) {
130  if (shards[i]) {
131  // This will call FlushBuffers() again after no longer stabilizer.
132  SwitchToEngine();
133  return;
134  }
135  }
136  }
137 
138  if (stabilizer) {
139  return;
140  }
141 
142  for (bitLenInt i = 0; i < qubitCount; i++) {
143  MpsShardPtr shard = shards[i];
144  if (shard) {
145  shards[i] = NULL;
146  engine->Mtrx(shard->gate, i);
147  }
148  }
149  }
150 
151  virtual void DumpBuffers()
152  {
153  for (bitLenInt i = 0; i < qubitCount; i++) {
154  shards[i] = NULL;
155  }
156  }
157 
158  virtual bool TrimControls(
159  const bitLenInt* lControls, bitLenInt lControlLen, std::vector<bitLenInt>& output, bool anti = false)
160  {
161  if (engine) {
162  output.insert(output.begin(), lControls, lControls + lControlLen);
163  return false;
164  }
165 
166  for (bitLenInt i = 0; i < lControlLen; i++) {
167  bitLenInt bit = lControls[i];
168 
169  if (!stabilizer->IsSeparableZ(bit)) {
170  output.push_back(bit);
171  continue;
172  }
173 
174  if (shards[bit]) {
175  if (shards[bit]->IsInvert()) {
176  InvertBuffer(bit);
177 
178  if (!shards[bit]) {
179  if (anti == stabilizer->M(bit)) {
180  return true;
181  }
182  continue;
183  }
184  }
185 
186  if (shards[bit]->IsPhase()) {
187  if (anti == stabilizer->M(bit)) {
188  return true;
189  }
190  continue;
191  }
192 
193  output.push_back(bit);
194  } else if (anti == stabilizer->M(bit)) {
195  return true;
196  }
197  }
198 
199  return false;
200  }
201 
202  virtual void CacheEigenstate(bitLenInt target);
203 
204 public:
205  QStabilizerHybrid(std::vector<QInterfaceEngine> eng, bitLenInt qBitCount, bitCapInt initState = 0,
206  qrack_rand_gen_ptr rgp = nullptr, complex phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false,
207  bool randomGlobalPhase = true, bool useHostMem = false, int deviceId = -1, bool useHardwareRNG = true,
208  bool useSparseStateVec = false, real1_f norm_thresh = REAL1_EPSILON, std::vector<int> devList = {},
209  bitLenInt qubitThreshold = 0, real1_f separation_thresh = FP_NORM_EPSILON);
210 
211  QStabilizerHybrid(bitLenInt qBitCount, bitCapInt initState = 0, qrack_rand_gen_ptr rgp = nullptr,
212  complex phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool randomGlobalPhase = true,
213  bool useHostMem = false, int deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
214  real1_f norm_thresh = REAL1_EPSILON, std::vector<int> devList = {}, bitLenInt qubitThreshold = 0,
215  real1_f separation_thresh = FP_NORM_EPSILON)
216  : QStabilizerHybrid({ QINTERFACE_OPTIMAL_BASE }, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase,
217  useHostMem, deviceId, useHardwareRNG, useSparseStateVec, norm_thresh, devList, qubitThreshold,
218  separation_thresh)
219  {
220  }
221 
222  virtual void Finish()
223  {
224  if (stabilizer) {
225  stabilizer->Finish();
226  } else {
227  engine->Finish();
228  }
229  };
230 
231  virtual bool isFinished() { return (!stabilizer || stabilizer->isFinished()) && (!engine || engine->isFinished()); }
232 
233  virtual void Dump()
234  {
235  if (stabilizer) {
236  stabilizer->Dump();
237  } else {
238  engine->Dump();
239  }
240  }
241 
242  virtual void SetConcurrency(uint32_t threadCount)
243  {
244  QInterface::SetConcurrency(threadCount);
245  if (engine) {
247  }
248  }
249 
250  virtual void TurnOnPaging()
251  {
252  if (engineTypes[0] == QINTERFACE_QPAGER) {
253  return;
254  }
255  engineTypes.insert(engineTypes.begin(), QINTERFACE_QPAGER);
256 
257  if (engine) {
258  QPagerPtr nEngine = std::dynamic_pointer_cast<QPager>(MakeEngine());
259  nEngine->LockEngine(std::dynamic_pointer_cast<QEngine>(engine));
260  engine = nEngine;
261  }
262  }
263 
264  virtual void TurnOffPaging()
265  {
266  if (engineTypes[0] != QINTERFACE_QPAGER) {
267  return;
268  }
269  engineTypes.erase(engineTypes.begin());
270  if (!engineTypes.size()) {
271  engineTypes.push_back(QINTERFACE_OPTIMAL_BASE);
272  }
273 
274  if (engine) {
275  engine = std::dynamic_pointer_cast<QPager>(engine)->ReleaseEngine();
276  }
277  }
278 
284  virtual void SwitchToEngine();
285 
286  virtual bool isClifford() { return !engine; }
287 
288  virtual bool isClifford(bitLenInt qubit) { return !engine && !shards[qubit]; };
289 
290  virtual bool isBinaryDecisionTree() { return engine && engine->isBinaryDecisionTree(); };
291 
292  using QInterface::Compose;
293  virtual bitLenInt Compose(QStabilizerHybridPtr toCopy)
294  {
295  const bitLenInt nQubits = qubitCount + toCopy->qubitCount;
296  const bool isPaging = isDefaultPaging && (nQubits > maxPageQubits);
297  bitLenInt toRet;
298 
299  if (isPaging) {
300  TurnOnPaging();
301  }
302 
303  if (engine) {
304  if (isPaging) {
305  toCopy->TurnOnPaging();
306  }
307  toCopy->SwitchToEngine();
308  toRet = engine->Compose(toCopy->engine);
309  } else if (toCopy->engine) {
310  if (isPaging) {
311  toCopy->TurnOnPaging();
312  }
313  SwitchToEngine();
314  toRet = engine->Compose(toCopy->engine);
315  } else {
316  toRet = stabilizer->Compose(toCopy->stabilizer);
317  }
318 
319  shards.insert(shards.end(), toCopy->shards.begin(), toCopy->shards.end());
320 
321  SetQubitCount(nQubits);
322 
323  return toRet;
324  }
326  {
327  return Compose(std::dynamic_pointer_cast<QStabilizerHybrid>(toCopy));
328  }
329  virtual bitLenInt Compose(QStabilizerHybridPtr toCopy, bitLenInt start)
330  {
331  const bitLenInt nQubits = qubitCount + toCopy->qubitCount;
332  const bool isPaging = isDefaultPaging && (nQubits > maxPageQubits);
333  bitLenInt toRet;
334 
335  if (isPaging) {
336  TurnOnPaging();
337  }
338 
339  if (engine) {
340  if (isPaging) {
341  toCopy->TurnOnPaging();
342  }
343  toCopy->SwitchToEngine();
344  toRet = engine->Compose(toCopy->engine, start);
345  } else if (toCopy->engine) {
346  if (isPaging) {
347  toCopy->TurnOnPaging();
348  }
349  SwitchToEngine();
350  toRet = engine->Compose(toCopy->engine, start);
351  } else {
352  toRet = stabilizer->Compose(toCopy->stabilizer, start);
353  }
354 
355  shards.insert(shards.begin() + start, toCopy->shards.begin(), toCopy->shards.end());
356 
357  SetQubitCount(nQubits);
358 
359  return toRet;
360  }
361  virtual bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
362  {
363  return Compose(std::dynamic_pointer_cast<QStabilizerHybrid>(toCopy), start);
364  }
365  virtual void Decompose(bitLenInt start, QInterfacePtr dest)
366  {
367  Decompose(start, std::dynamic_pointer_cast<QStabilizerHybrid>(dest));
368  }
369  virtual void Decompose(bitLenInt start, QStabilizerHybridPtr dest);
370  virtual QInterfacePtr Decompose(bitLenInt start, bitLenInt length);
371  virtual void Dispose(bitLenInt start, bitLenInt length);
372  virtual void Dispose(bitLenInt start, bitLenInt length, bitCapInt disposedPerm);
373 
374  virtual void SetQuantumState(const complex* inputState);
375  virtual void GetQuantumState(complex* outputState)
376  {
377  FlushBuffers();
378 
379  if (stabilizer) {
380  stabilizer->GetQuantumState(outputState);
381  } else {
382  engine->GetQuantumState(outputState);
383  }
384  }
385  virtual void GetProbs(real1* outputProbs);
387  {
388  FlushBuffers();
389 
390  if (stabilizer) {
391  return stabilizer->GetAmplitude(perm);
392  }
393 
394  return engine->GetAmplitude(perm);
395  }
396  virtual void SetAmplitude(bitCapInt perm, complex amp)
397  {
398  SwitchToEngine();
399  engine->SetAmplitude(perm, amp);
400  }
401  virtual void SetPermutation(bitCapInt perm, complex phaseFac = CMPLX_DEFAULT_ARG)
402  {
403  DumpBuffers();
404 
405  engine = NULL;
406 
407  if (stabilizer) {
408  stabilizer->SetPermutation(perm);
409  } else {
410  stabilizer = MakeStabilizer(perm);
411  }
412  }
413 
414  virtual void Swap(bitLenInt qubit1, bitLenInt qubit2)
415  {
416  if (qubit1 == qubit2) {
417  return;
418  }
419 
420  std::swap(shards[qubit1], shards[qubit2]);
421 
422  if (stabilizer) {
423  stabilizer->Swap(qubit1, qubit2);
424  } else {
425  engine->Swap(qubit1, qubit2);
426  }
427  }
428 
429  virtual void ISwap(bitLenInt qubit1, bitLenInt qubit2)
430  {
431  if (qubit1 == qubit2) {
432  return;
433  }
434 
435  if (shards[qubit1] && shards[qubit1]->IsInvert()) {
436  InvertBuffer(qubit1);
437  }
438 
439  if (shards[qubit2] && shards[qubit2]->IsInvert()) {
440  InvertBuffer(qubit2);
441  }
442 
443  if ((shards[qubit1] && !shards[qubit1]->IsPhase()) || (shards[qubit2] && !shards[qubit2]->IsPhase())) {
444  FlushBuffers();
445  }
446 
447  if (stabilizer) {
448  stabilizer->ISwap(qubit1, qubit2);
449  } else {
450  engine->ISwap(qubit1, qubit2);
451  }
452  }
453 
454  virtual real1_f Prob(bitLenInt qubit);
455 
456  virtual bool ForceM(bitLenInt qubit, bool result, bool doForce = true, bool doApply = true);
457 
458  virtual bitCapInt MAll();
459 
460  virtual void Mtrx(const complex* mtrx, bitLenInt target);
461  virtual void MCMtrx(const bitLenInt* controls, bitLenInt controlLen, const complex* mtrx, bitLenInt target);
462  virtual void MCPhase(
463  const bitLenInt* controls, bitLenInt controlLen, complex topLeft, complex bottomRight, bitLenInt target);
464  virtual void MCInvert(
465  const bitLenInt* controls, bitLenInt controlLen, complex topRight, complex bottomLeft, bitLenInt target);
466  virtual void MACMtrx(const bitLenInt* controls, bitLenInt controlLen, const complex* mtrx, bitLenInt target);
467  virtual void MACPhase(
468  const bitLenInt* controls, bitLenInt controlLen, complex topLeft, complex bottomRight, bitLenInt target);
469  virtual void MACInvert(
470  const bitLenInt* controls, bitLenInt controlLen, complex topRight, complex bottomLeft, bitLenInt target);
471 
473  const bitLenInt* controls, bitLenInt controlLen, bitLenInt qubitIndex, const complex* mtrxs)
474  {
475  if (stabilizer) {
476  QInterface::UniformlyControlledSingleBit(controls, controlLen, qubitIndex, mtrxs);
477  return;
478  }
479 
480  engine->UniformlyControlledSingleBit(controls, controlLen, qubitIndex, mtrxs);
481  }
482 
483  virtual void CSqrtSwap(const bitLenInt* controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
484  {
485  if (stabilizer) {
486  QInterface::CSqrtSwap(controls, controlLen, qubit1, qubit2);
487  return;
488  }
489 
490  engine->CSqrtSwap(controls, controlLen, qubit1, qubit2);
491  }
492  virtual void AntiCSqrtSwap(const bitLenInt* controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
493  {
494  if (stabilizer) {
495  QInterface::AntiCSqrtSwap(controls, controlLen, qubit1, qubit2);
496  return;
497  }
498 
499  engine->AntiCSqrtSwap(controls, controlLen, qubit1, qubit2);
500  }
501  virtual void CISqrtSwap(const bitLenInt* controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
502  {
503  if (stabilizer) {
504  QInterface::CISqrtSwap(controls, controlLen, qubit1, qubit2);
505  return;
506  }
507 
508  engine->CISqrtSwap(controls, controlLen, qubit1, qubit2);
509  }
510  virtual void AntiCISqrtSwap(const bitLenInt* controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
511  {
512  if (stabilizer) {
513  QInterface::AntiCISqrtSwap(controls, controlLen, qubit1, qubit2);
514  return;
515  }
516 
517  engine->AntiCISqrtSwap(controls, controlLen, qubit1, qubit2);
518  }
519 
520  virtual void XMask(bitCapInt mask)
521  {
522  if (!stabilizer) {
523  engine->XMask(mask);
524  return;
525  }
526 
527  bitCapInt v = mask;
528  while (mask) {
529  v = v & (v - ONE_BCI);
530  X(log2(mask ^ v));
531  mask = v;
532  }
533  }
534 
535  virtual void YMask(bitCapInt mask)
536  {
537  if (!stabilizer) {
538  engine->YMask(mask);
539  return;
540  }
541 
542  bitCapInt v = mask;
543  while (mask) {
544  v = v & (v - ONE_BCI);
545  Y(log2(mask ^ v));
546  mask = v;
547  }
548  }
549 
550  virtual void ZMask(bitCapInt mask)
551  {
552  if (!stabilizer) {
553  engine->ZMask(mask);
554  return;
555  }
556 
557  bitCapInt v = mask;
558  while (mask) {
559  v = v & (v - ONE_BCI);
560  Z(log2(mask ^ v));
561  mask = v;
562  }
563  }
564 
565  virtual std::map<bitCapInt, int> MultiShotMeasureMask(
566  const bitCapInt* qPowers, bitLenInt qPowerCount, unsigned shots);
567  virtual void MultiShotMeasureMask(
568  const bitCapInt* qPowers, bitLenInt qPowerCount, unsigned shots, unsigned* shotsArray);
569 
571  {
572  if (!mask) {
573  return ZERO_R1;
574  }
575 
576  if (!(mask & (mask - ONE_BCI))) {
577  return Prob(log2(mask));
578  }
579 
580  SwitchToEngine();
581  return QINTERFACE_TO_QPARITY(engine)->ProbParity(mask);
582  }
583  virtual bool ForceMParity(bitCapInt mask, bool result, bool doForce = true)
584  {
585  // If no bits in mask:
586  if (!mask) {
587  return false;
588  }
589 
590  // If only one bit in mask:
591  if (!(mask & (mask - ONE_BCI))) {
592  return ForceM(log2(mask), result, doForce);
593  }
594 
595  SwitchToEngine();
596  return QINTERFACE_TO_QPARITY(engine)->ForceMParity(mask, result, doForce);
597  }
598  virtual void UniformParityRZ(bitCapInt mask, real1_f angle)
599  {
600  SwitchToEngine();
601  QINTERFACE_TO_QPARITY(engine)->UniformParityRZ(mask, angle);
602  }
603  virtual void CUniformParityRZ(const bitLenInt* controls, bitLenInt controlLen, bitCapInt mask, real1_f angle)
604  {
605  SwitchToEngine();
606  QINTERFACE_TO_QPARITY(engine)->CUniformParityRZ(controls, controlLen, mask, angle);
607  }
608 
609 #if ENABLE_ALU
610  virtual bool M(bitLenInt q) { return QInterface::M(q); }
611  virtual void X(bitLenInt q) { QInterface::X(q); }
612  virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length) { QInterface::DEC(toSub, start, length); }
613  virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
614  {
615  QInterface::DECC(toSub, start, length, carryIndex);
616  }
617  virtual void DECS(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
618  {
619  QInterface::DECS(toSub, start, length, overflowIndex);
620  }
621  virtual void CDEC(
622  bitCapInt toSub, bitLenInt inOutStart, bitLenInt length, const bitLenInt* controls, bitLenInt controlLen)
623  {
624  QInterface::CDEC(toSub, inOutStart, length, controls, controlLen);
625  }
626 
627  virtual void CPhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex)
628  {
629  SwitchToEngine();
630  QINTERFACE_TO_QALU(engine)->CPhaseFlipIfLess(greaterPerm, start, length, flagIndex);
631  }
632  virtual void PhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt length)
633  {
634  SwitchToEngine();
635  QINTERFACE_TO_QALU(engine)->PhaseFlipIfLess(greaterPerm, start, length);
636  }
637 
638  virtual void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length)
639  {
640  if (stabilizer) {
641  QInterface::INC(toAdd, start, length);
642  return;
643  }
644 
645  engine->INC(toAdd, start, length);
646  }
647  virtual void CINC(
648  bitCapInt toAdd, bitLenInt inOutStart, bitLenInt length, const bitLenInt* controls, bitLenInt controlLen)
649  {
650  if (stabilizer) {
651  QInterface::CINC(toAdd, inOutStart, length, controls, controlLen);
652  return;
653  }
654 
655  engine->CINC(toAdd, inOutStart, length, controls, controlLen);
656  }
657  virtual void INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
658  {
659  if (stabilizer) {
660  QInterface::INCS(toAdd, start, length, overflowIndex);
661  return;
662  }
663 
664  engine->INCS(toAdd, start, length, overflowIndex);
665  }
666  virtual void INCDECC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
667  {
668  if (stabilizer) {
669  QInterface::INCDECC(toAdd, start, length, carryIndex);
670  return;
671  }
672 
673  engine->INCDECC(toAdd, start, length, carryIndex);
674  }
675  virtual void INCDECSC(
676  bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
677  {
678  SwitchToEngine();
679  QINTERFACE_TO_QALU(engine)->INCDECSC(toAdd, start, length, overflowIndex, carryIndex);
680  }
681  virtual void INCDECSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
682  {
683  SwitchToEngine();
684  QINTERFACE_TO_QALU(engine)->INCDECSC(toAdd, start, length, carryIndex);
685  }
686 #if ENABLE_BCD
687  virtual void INCBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length)
688  {
689  SwitchToEngine();
690  QINTERFACE_TO_QALU(engine)->INCBCD(toAdd, start, length);
691  }
692  virtual void INCDECBCDC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
693  {
694  SwitchToEngine();
695  QINTERFACE_TO_QALU(engine)->INCDECBCDC(toAdd, start, length, carryIndex);
696  }
697 #endif
698  virtual void MUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
699  {
700  SwitchToEngine();
701  QINTERFACE_TO_QALU(engine)->MUL(toMul, inOutStart, carryStart, length);
702  }
703  virtual void DIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
704  {
705  SwitchToEngine();
706  QINTERFACE_TO_QALU(engine)->DIV(toDiv, inOutStart, carryStart, length);
707  }
708  virtual void MULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
709  {
710  SwitchToEngine();
711  QINTERFACE_TO_QALU(engine)->MULModNOut(toMul, modN, inStart, outStart, length);
712  }
713  virtual void IMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
714  {
715  SwitchToEngine();
716  QINTERFACE_TO_QALU(engine)->IMULModNOut(toMul, modN, inStart, outStart, length);
717  }
718  virtual void POWModNOut(bitCapInt base, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
719  {
720  SwitchToEngine();
721  QINTERFACE_TO_QALU(engine)->POWModNOut(base, modN, inStart, outStart, length);
722  }
723  virtual void CMUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
724  const bitLenInt* controls, bitLenInt controlLen)
725  {
726  SwitchToEngine();
727  QINTERFACE_TO_QALU(engine)->CMUL(toMul, inOutStart, carryStart, length, controls, controlLen);
728  }
729  virtual void CDIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
730  const bitLenInt* controls, bitLenInt controlLen)
731  {
732  SwitchToEngine();
733  QINTERFACE_TO_QALU(engine)->CDIV(toDiv, inOutStart, carryStart, length, controls, controlLen);
734  }
735  virtual void CMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length,
736  const bitLenInt* controls, bitLenInt controlLen)
737  {
738  SwitchToEngine();
739  QINTERFACE_TO_QALU(engine)->CMULModNOut(toMul, modN, inStart, outStart, length, controls, controlLen);
740  }
741  virtual void CIMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length,
742  const bitLenInt* controls, bitLenInt controlLen)
743  {
744  SwitchToEngine();
745  QINTERFACE_TO_QALU(engine)->CIMULModNOut(toMul, modN, inStart, outStart, length, controls, controlLen);
746  }
747  virtual void CPOWModNOut(bitCapInt base, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length,
748  const bitLenInt* controls, bitLenInt controlLen)
749  {
750  SwitchToEngine();
751  QINTERFACE_TO_QALU(engine)->CPOWModNOut(base, modN, inStart, outStart, length, controls, controlLen);
752  }
753 
754  virtual bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
755  bitLenInt valueLength, const unsigned char* values, bool resetValue = true)
756  {
757  SwitchToEngine();
758  return QINTERFACE_TO_QALU(engine)->IndexedLDA(
759  indexStart, indexLength, valueStart, valueLength, values, resetValue);
760  }
761  virtual bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
762  bitLenInt valueLength, bitLenInt carryIndex, const unsigned char* values)
763  {
764  SwitchToEngine();
765  return QINTERFACE_TO_QALU(engine)->IndexedADC(
766  indexStart, indexLength, valueStart, valueLength, carryIndex, values);
767  }
768  virtual bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
769  bitLenInt valueLength, bitLenInt carryIndex, const unsigned char* values)
770  {
771  SwitchToEngine();
772  return QINTERFACE_TO_QALU(engine)->IndexedSBC(
773  indexStart, indexLength, valueStart, valueLength, carryIndex, values);
774  }
775  virtual void Hash(bitLenInt start, bitLenInt length, const unsigned char* values)
776  {
777  SwitchToEngine();
778  QINTERFACE_TO_QALU(engine)->Hash(start, length, values);
779  }
780 #endif
781 
782  virtual void PhaseFlip()
783  {
784  if (engine) {
785  engine->PhaseFlip();
786  }
787  }
788  virtual void ZeroPhaseFlip(bitLenInt start, bitLenInt length)
789  {
790  SwitchToEngine();
791  engine->ZeroPhaseFlip(start, length);
792  }
793 
794  virtual void SqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
795  {
796  SwitchToEngine();
797  engine->SqrtSwap(qubitIndex1, qubitIndex2);
798  }
799  virtual void ISqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
800  {
801  SwitchToEngine();
802  engine->ISqrtSwap(qubitIndex1, qubitIndex2);
803  }
804  virtual void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2)
805  {
806  SwitchToEngine();
807  engine->FSim(theta, phi, qubitIndex1, qubitIndex2);
808  }
809 
810  virtual real1_f ProbAll(bitCapInt fullRegister)
811  {
812  SwitchToEngine();
813  return engine->ProbAll(fullRegister);
814  }
815  virtual real1_f ProbMask(bitCapInt mask, bitCapInt permutation)
816  {
817  SwitchToEngine();
818  return engine->ProbMask(mask, permutation);
819  }
820 
821  virtual real1_f SumSqrDiff(QInterfacePtr toCompare)
822  {
823  return SumSqrDiff(std::dynamic_pointer_cast<QStabilizerHybrid>(toCompare));
824  }
825 
826  virtual real1_f SumSqrDiff(QStabilizerHybridPtr toCompare)
827  {
828  // If the qubit counts are unequal, these can't be approximately equal objects.
829  if (qubitCount != toCompare->qubitCount) {
830  // Max square difference:
831  return ONE_R1;
832  }
833 
834  QStabilizerHybridPtr thisClone = stabilizer ? std::dynamic_pointer_cast<QStabilizerHybrid>(Clone()) : NULL;
835  QStabilizerHybridPtr thatClone =
836  toCompare->stabilizer ? std::dynamic_pointer_cast<QStabilizerHybrid>(Clone()) : NULL;
837 
838  if (thisClone) {
839  thisClone->SwitchToEngine();
840  }
841  if (thatClone) {
842  thatClone->SwitchToEngine();
843  }
844 
845  QInterfacePtr thisEngine = thisClone ? thisClone->engine : engine;
846  QInterfacePtr thatEngine = thatClone ? thatClone->engine : toCompare->engine;
847 
848  return thisEngine->SumSqrDiff(thatEngine);
849  }
850 
851  virtual bool ApproxCompare(QInterfacePtr toCompare, real1_f error_tol = TRYDECOMPOSE_EPSILON)
852  {
853  return ApproxCompare(std::dynamic_pointer_cast<QStabilizerHybrid>(toCompare), error_tol);
854  }
855 
856  virtual bool ApproxCompare(QStabilizerHybridPtr toCompare, real1_f error_tol = TRYDECOMPOSE_EPSILON)
857  {
858  FlushBuffers();
859  toCompare->FlushBuffers();
860 
861  if (stabilizer && toCompare->stabilizer) {
862  return stabilizer->ApproxCompare(toCompare->stabilizer);
863  }
864 
865  QStabilizerHybridPtr thisClone = stabilizer ? std::dynamic_pointer_cast<QStabilizerHybrid>(Clone()) : NULL;
866  QStabilizerHybridPtr thatClone =
867  toCompare->stabilizer ? std::dynamic_pointer_cast<QStabilizerHybrid>(Clone()) : NULL;
868 
869  if (thisClone) {
870  thisClone->SwitchToEngine();
871  }
872  if (thatClone) {
873  thatClone->SwitchToEngine();
874  }
875 
876  QInterfacePtr thisEngine = thisClone ? thisClone->engine : engine;
877  QInterfacePtr thatEngine = thatClone ? thatClone->engine : toCompare->engine;
878 
879  return thisEngine->ApproxCompare(thatEngine, error_tol);
880  }
881 
882  virtual void UpdateRunningNorm(real1_f norm_thresh = REAL1_DEFAULT_ARG)
883  {
884  if (engine) {
885  engine->UpdateRunningNorm(norm_thresh);
886  }
887  }
888 
889  virtual void NormalizeState(
890  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1)
891  {
892  if (engine) {
893  engine->NormalizeState(nrm, norm_thresh, phaseArg);
894  }
895  }
896 
897  virtual real1_f ExpectationBitsAll(const bitLenInt* bits, bitLenInt length, bitCapInt offset = 0)
898  {
899  if (stabilizer) {
900  return QInterface::ExpectationBitsAll(bits, length, offset);
901  }
902 
903  return engine->ExpectationBitsAll(bits, length, offset);
904  }
905 
906  virtual bool TrySeparate(bitLenInt qubit)
907  {
908  if (qubitCount == 1U) {
909  return true;
910  }
911 
912  if (stabilizer) {
913  return stabilizer->CanDecomposeDispose(qubit, 1);
914  }
915 
916  return engine->TrySeparate(qubit);
917  }
918  virtual bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2)
919  {
920  if (qubitCount == 2U) {
921  return true;
922  }
923 
924  if (stabilizer) {
925  if (qubit2 < qubit1) {
926  std::swap(qubit1, qubit2);
927  }
928 
929  stabilizer->Swap(qubit1 + 1U, qubit2);
930 
931  const bool toRet = stabilizer->CanDecomposeDispose(qubit1, 2);
932 
933  stabilizer->Swap(qubit1 + 1U, qubit2);
934 
935  return toRet;
936  }
937 
938  return engine->TrySeparate(qubit1, qubit2);
939  }
940  virtual bool TrySeparate(const bitLenInt* qubits, bitLenInt length, real1_f error_tol)
941  {
942  if (stabilizer) {
943  std::vector<bitLenInt> q(length);
944  std::copy(qubits, qubits + length, q.begin());
945  std::sort(q.begin(), q.end());
946 
947  for (bitLenInt i = 1; i < length; i++) {
948  Swap(q[0] + i, q[i]);
949  }
950 
951  const bool toRet = stabilizer->CanDecomposeDispose(q[0], length);
952 
953  for (bitLenInt i = 1; i < length; i++) {
954  Swap(q[0] + i, q[i]);
955  }
956 
957  return toRet;
958  }
959 
960  return engine->TrySeparate(qubits, length, error_tol);
961  }
962 
963  virtual QInterfacePtr Clone();
964 
965  virtual void SetDevice(int dID, bool forceReInit = false)
966  {
967  devID = dID;
968  if (engine) {
969  engine->SetDevice(dID, forceReInit);
970  }
971  }
972 
973  virtual int64_t GetDeviceID() { return devID; }
974 
976  {
977  if (stabilizer) {
978  return QInterface::GetMaxSize();
979  }
980 
981  return engine->GetMaxSize();
982  }
983 };
984 } // namespace Qrack
double norm(const Complex16x2Simd &c)
Definition: complex16x2simd.hpp:127
virtual void AntiCISqrtSwap(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
Apply an inverse square root of swap with arbitrary (anti) control bits.
Definition: qstabilizerhybrid.hpp:510
virtual void CSqrtSwap(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary control bits.
Definition: qstabilizerhybrid.hpp:483
virtual void POWModNOut(bitCapInt base, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Raise a classical base to a quantum power, modulo N, (out of place)
Definition: qstabilizerhybrid.hpp:718
virtual void INCDECSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (with overflow flag)
Definition: qstabilizerhybrid.hpp:675
virtual void GetQuantumState(complex *outputState)
Get the pure quantum state representation.
Definition: qstabilizerhybrid.hpp:375
virtual void UniformlyControlledSingleBit(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubitIndex, const complex *mtrxs)
Apply a "uniformly controlled" arbitrary single bit unitary transformation.
Definition: qstabilizerhybrid.hpp:472
virtual void CINC(bitCapInt toAdd, bitLenInt inOutStart, bitLenInt length, const bitLenInt *controls, bitLenInt controlLen)
Add integer (without sign, with controls)
Definition: arithmetic.cpp:116
virtual void MCMtrx(const bitLenInt *controls, bitLenInt controlLen, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: qstabilizerhybrid.cpp:358
virtual void Y(bitLenInt qubitIndex)
Y gate.
virtual void ISwap(bitLenInt qubit1, bitLenInt qubit2)
Swap values of two bits in register, and apply phase factor of i if bits are different.
Definition: qstabilizerhybrid.hpp:429
complex phaseFactor
Definition: qstabilizerhybrid.hpp:52
std::vector< MpsShardPtr > shards
Definition: qstabilizerhybrid.hpp:50
virtual bool M(bitLenInt qubitIndex)
Measurement gate.
Definition: qinterface.hpp:775
virtual void NormalizeState(real1_f nrm=REAL1_DEFAULT_ARG, real1_f norm_thresh=REAL1_DEFAULT_ARG, real1_f phaseArg=ZERO_R1)
Apply the normalization factor found by UpdateRunningNorm() or on the fly by a single bit gate...
Definition: qstabilizerhybrid.hpp:889
A "Qrack::QPager" splits a "Qrack::QEngine" implementation into equal-length "pages." This helps both optimization and distribution of a single coherent quantum register across multiple devices.
Definition: qpager.hpp:31
virtual complex GetAmplitude(bitCapInt perm)
Get the representational amplitude of a full permutation.
Definition: qstabilizerhybrid.hpp:386
virtual void CMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const bitLenInt *controls, bitLenInt controlLen)
Controlled multiplication modulo N by integer, (out of place)
Definition: qstabilizerhybrid.hpp:735
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qstabilizerhybrid.hpp:325
Definition: qalu.hpp:22
virtual void MULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Multiplication modulo N by integer, (out of place)
Definition: qstabilizerhybrid.hpp:708
virtual real1_f SumSqrDiff(QStabilizerHybridPtr toCompare)
Definition: qstabilizerhybrid.hpp:826
virtual void CDEC(bitCapInt toSub, bitLenInt inOutStart, bitLenInt length, const bitLenInt *controls, bitLenInt controlLen)
Subtract classical integer (without sign, with controls)
Definition: arithmetic.cpp:162
virtual bitCapInt MAll()
Measure permutation state of all coherent bits.
Definition: qstabilizerhybrid.cpp:645
bitCapIntOcl GetMaxSize()
Definition: qstabilizerhybrid.hpp:975
virtual void IMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Inverse of multiplication modulo N by integer, (out of place)
Definition: qstabilizerhybrid.hpp:713
Half-precision floating-point type.
Definition: half.hpp:2221
virtual void MACPhase(const bitLenInt *controls, bitLenInt controlLen, complex topLeft, complex bottomRight, bitLenInt target)
Apply a single bit transformation that only effects phase, with arbitrary (anti-)control bits...
Definition: qstabilizerhybrid.cpp:507
A "Qrack::QStabilizerHybrid" internally switched between Qrack::QEngineCPU and Qrack::QEngineOCL to m...
Definition: qstabilizerhybrid.hpp:42
virtual void CDIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const bitLenInt *controls, bitLenInt controlLen)
Controlled division by power of integer.
Definition: qstabilizerhybrid.hpp:729
void InvertBuffer(bitLenInt qubit)
Definition: qstabilizerhybrid.hpp:65
virtual void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: arithmetic.cpp:24
virtual void CISqrtSwap(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
Apply an inverse square root of swap with arbitrary control bits.
Definition: qstabilizerhybrid.hpp:501
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:73
virtual real1_f Prob(bitLenInt qubit)
Direct measure of bit probability to be in |1> state.
Definition: qstabilizerhybrid.cpp:575
virtual void Mtrx(const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation.
Definition: qstabilizerhybrid.cpp:334
virtual real1_f ProbMask(bitCapInt mask, bitCapInt permutation)
Direct measure of masked permutation probability.
Definition: qstabilizerhybrid.hpp:815
std::shared_ptr< MpsShard > MpsShardPtr
Definition: mpsshard.hpp:6
virtual void XMask(bitCapInt mask)
Masked X gate.
Definition: qstabilizerhybrid.hpp:520
virtual void CSqrtSwap(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary control bits.
Definition: gates.cpp:639
virtual void DIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Divide by integer.
Definition: qstabilizerhybrid.hpp:703
virtual void CINC(bitCapInt toAdd, bitLenInt inOutStart, bitLenInt length, const bitLenInt *controls, bitLenInt controlLen)
Add integer (without sign, with controls)
Definition: qstabilizerhybrid.hpp:647
std::shared_ptr< QPager > QPagerPtr
Definition: qpager.hpp:23
std::shared_ptr< QStabilizerHybrid > QStabilizerHybridPtr
Definition: qstabilizerhybrid.hpp:34
#define ZERO_R1
Definition: qrack_types.hpp:99
virtual void SetConcurrency(uint32_t threadsPerEngine)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qinterface.hpp:248
virtual void CPhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex)
The 6502 uses its carry flag also as a greater-than/less-than flag, for the CMP operation.
Definition: qstabilizerhybrid.hpp:627
virtual void CMUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const bitLenInt *controls, bitLenInt controlLen)
Controlled multiplication by integer.
Definition: qstabilizerhybrid.hpp:723
Definition: qinterface.hpp:128
virtual void Hash(bitLenInt start, bitLenInt length, const unsigned char *values)
Transform a length of qubit register via lookup through a hash table.
Definition: qstabilizerhybrid.hpp:775
virtual void INCDECSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qstabilizerhybrid.hpp:681
virtual void SetPermutation(bitCapInt perm, complex phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: qstabilizerhybrid.hpp:401
virtual void SetQubitCount(bitLenInt qb)
Definition: qinterface.hpp:158
virtual void CDEC(bitCapInt toSub, bitLenInt inOutStart, bitLenInt length, const bitLenInt *controls, bitLenInt controlLen)
Subtract integer (without sign, with controls)
Definition: qstabilizerhybrid.hpp:621
QStabilizerPtr MakeStabilizer(bitCapInt perm=0)
Definition: qstabilizerhybrid.cpp:69
virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length)
Subtract classical integer (without sign)
Definition: arithmetic.cpp:56
virtual void Finish()
If asynchronous work is still running, block until it finishes.
Definition: qstabilizerhybrid.hpp:222
bitLenInt log2(bitCapInt n)
Definition: qrack_types.hpp:205
virtual void INCDECC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCC and DECC.
Definition: arithmetic.cpp:62
virtual real1_f ExpectationBitsAll(const bitLenInt *bits, bitLenInt length, bitCapInt offset=0)
Get permutation expectation value of bits.
Definition: qstabilizerhybrid.hpp:897
virtual void INCDECC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCC and DECC (without sign, with carry)
Definition: qstabilizerhybrid.hpp:666
#define ZERO_CMPLX
Definition: qrack_types.hpp:146
#define FP_NORM_EPSILON
Definition: qrack_types.hpp:108
Create a QPager, which breaks up the work of a QEngine into equally sized "pages.".
Definition: qinterface.hpp:95
virtual void INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: qstabilizerhybrid.hpp:657
virtual void INCDECBCDC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qstabilizerhybrid.hpp:692
bool isDefaultPaging
Definition: qstabilizerhybrid.hpp:56
virtual void YMask(bitCapInt mask)
Masked Y gate.
Definition: qstabilizerhybrid.hpp:535
virtual bool ForceM(bitLenInt qubit, bool result, bool doForce=true, bool doApply=true)
Act as if is a measurement was applied, except force the (usually random) result. ...
Definition: qstabilizerhybrid.cpp:606
virtual void DumpBuffers()
Definition: qstabilizerhybrid.hpp:151
virtual bool TrySeparate(bitLenInt qubit)
Single-qubit TrySeparate()
Definition: qstabilizerhybrid.hpp:906
virtual void AntiCSqrtSwap(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary (anti) control bits.
Definition: qstabilizerhybrid.hpp:492
#define bitCapIntOcl
Definition: qrack_types.hpp:27
virtual bitLenInt Compose(QStabilizerHybridPtr toCopy)
Definition: qstabilizerhybrid.hpp:293
virtual void TurnOnPaging()
Definition: qstabilizerhybrid.hpp:250
bitLenInt maxPageQubits
Definition: qstabilizerhybrid.hpp:59
std::complex< half_float::half > complex
Definition: qrack_types.hpp:96
virtual void ISqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Inverse square root of Swap gate.
Definition: qstabilizerhybrid.hpp:799
virtual void Dispose(bitLenInt start, bitLenInt length)
Minimally decompose a set of contiguous bits from the separably composed unit, and discard the separa...
Definition: qstabilizerhybrid.cpp:227
virtual void PhaseFlip()
Phase flip always - equivalent to Z X Z X on any bit in the QInterface.
Definition: qstabilizerhybrid.hpp:782
virtual void SetQuantumState(const complex *inputState)
Set an arbitrary pure quantum state representation.
Definition: qstabilizerhybrid.cpp:295
virtual void SetConcurrency(uint32_t threadCount)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qstabilizerhybrid.hpp:242
virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract classical integer (without sign, with carry)
Definition: arithmetic.cpp:102
virtual void TurnOffPaging()
Definition: qstabilizerhybrid.hpp:264
virtual bool isFinished()
Returns "false" if asynchronous work is still running, and "true" if all previously dispatched asynch...
Definition: qstabilizerhybrid.hpp:231
virtual void CPOWModNOut(bitCapInt base, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const bitLenInt *controls, bitLenInt controlLen)
Controlled, raise a classical base to a quantum power, modulo N, (out of place)
Definition: qstabilizerhybrid.hpp:747
virtual void AntiCSqrtSwap(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary (anti) control bits.
Definition: gates.cpp:734
virtual bool ForceMParity(bitCapInt mask, bool result, bool doForce=true)
Act as if is a measurement of parity of the masked set of qubits was applied, except force the (usual...
Definition: qstabilizerhybrid.hpp:583
float real1_f
Definition: qrack_types.hpp:98
virtual void CISqrtSwap(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
Apply an inverse square root of swap with arbitrary control bits.
Definition: gates.cpp:689
real1_f Rand()
Generate a random real number between 0 and 1.
Definition: qinterface.hpp:259
bitCapIntOcl GetMaxSize()
Get maximum number of amplitudes that can be allocated on current device.
Definition: qinterface.hpp:2198
virtual void Dump()
If asynchronous work is still running, let the simulator know that it can be aborted.
Definition: qstabilizerhybrid.hpp:233
virtual void MACInvert(const bitLenInt *controls, bitLenInt controlLen, complex topRight, complex bottomLeft, bitLenInt target)
Apply a single bit transformation that reverses bit probability and might effect phase, with arbitrary (anti-)control bits.
Definition: qstabilizerhybrid.cpp:546
virtual QInterfacePtr Clone()
Clone this QInterface.
Definition: qstabilizerhybrid.cpp:126
#define bitLenInt
Definition: qrack_types.hpp:40
QStabilizerPtr stabilizer
Definition: qstabilizerhybrid.hpp:49
unsigned GetConcurrencyLevel()
Definition: parallel_for.hpp:35
virtual void UniformParityRZ(bitCapInt mask, real1_f angle)
If the target qubit set parity is odd, this applies a phase factor of .
Definition: qstabilizerhybrid.hpp:598
virtual void CUniformParityRZ(const bitLenInt *controls, bitLenInt controlLen, bitCapInt mask, real1_f angle)
If the controls are set and the target qubit set parity is odd, this applies a phase factor of ...
Definition: qstabilizerhybrid.hpp:603
virtual bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, const unsigned char *values)
Subtract from an entangled 8 bit register state with a superposed index-offset-based read from classi...
Definition: qstabilizerhybrid.hpp:768
#define ONE_R1
Definition: qrack_types.hpp:100
virtual bool M(bitLenInt q)
Definition: qstabilizerhybrid.hpp:610
virtual void SetAmplitude(bitCapInt perm, complex amp)
Sets the representational amplitude of a full permutation.
Definition: qstabilizerhybrid.hpp:396
virtual real1_f ProbAll(bitCapInt fullRegister)
Direct measure of full permutation probability.
Definition: qstabilizerhybrid.hpp:810
virtual void CacheEigenstate(bitLenInt target)
Definition: qstabilizerhybrid.cpp:84
int devID
Definition: qstabilizerhybrid.hpp:51
#define QINTERFACE_TO_QALU(qReg)
Definition: qstabilizerhybrid.hpp:29
virtual void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qstabilizerhybrid.cpp:323
virtual void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qstabilizerhybrid.hpp:638
virtual void SwitchToEngine()
Switches between CPU and GPU used modes.
Definition: qstabilizerhybrid.cpp:152
virtual bool isBinaryDecisionTree()
Returns "true" if current state representation is definitely a binary decision tree, "false" if it is definitely not, or "true" if it cannot be determined.
Definition: qstabilizerhybrid.hpp:290
virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract classical integer (without sign, with carry)
Definition: qstabilizerhybrid.hpp:613
std::shared_ptr< QStabilizer > QStabilizerPtr
Definition: qstabilizer.hpp:48
virtual void CIMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const bitLenInt *controls, bitLenInt controlLen)
Inverse of controlled multiplication modulo N by integer, (out of place)
Definition: qstabilizerhybrid.hpp:741
virtual void INCBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Add classical BCD integer (without sign)
Definition: qstabilizerhybrid.hpp:687
virtual bitLenInt Compose(QStabilizerHybridPtr toCopy, bitLenInt start)
Definition: qstabilizerhybrid.hpp:329
virtual bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2)
Two-qubit TrySeparate()
Definition: qstabilizerhybrid.hpp:918
#define CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:148
QStabilizerHybrid(std::vector< QInterfaceEngine > eng, bitLenInt qBitCount, bitCapInt initState=0, qrack_rand_gen_ptr rgp=nullptr, complex phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool randomGlobalPhase=true, bool useHostMem=false, int deviceId=-1, bool useHardwareRNG=true, bool useSparseStateVec=false, real1_f norm_thresh=REAL1_EPSILON, std::vector< int > devList={}, bitLenInt qubitThreshold=0, real1_f separation_thresh=FP_NORM_EPSILON)
Definition: qstabilizerhybrid.cpp:28
virtual bool TrimControls(const bitLenInt *lControls, bitLenInt lControlLen, std::vector< bitLenInt > &output, bool anti=false)
Definition: qstabilizerhybrid.hpp:158
virtual bool ApproxCompare(QStabilizerHybridPtr toCompare, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Definition: qstabilizerhybrid.hpp:856
QStabilizerHybrid(bitLenInt qBitCount, bitCapInt initState=0, qrack_rand_gen_ptr rgp=nullptr, complex phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool randomGlobalPhase=true, bool useHostMem=false, int deviceId=-1, bool useHardwareRNG=true, bool useSparseStateVec=false, real1_f norm_thresh=REAL1_EPSILON, std::vector< int > devList={}, bitLenInt qubitThreshold=0, real1_f separation_thresh=FP_NORM_EPSILON)
Definition: qstabilizerhybrid.hpp:211
virtual void Z(bitLenInt qubitIndex)
Z gate.
virtual void PhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt length)
This is an expedient for an adaptive Grover&#39;s search for a function&#39;s global minimum.
Definition: qstabilizerhybrid.hpp:632
virtual void ZMask(bitCapInt mask)
Masked Z gate.
Definition: qstabilizerhybrid.hpp:550
virtual bool isClifford(bitLenInt qubit)
Returns "true" if current qubit state is identifiably within the Clifford set, or "false" if it is no...
Definition: qstabilizerhybrid.hpp:288
virtual void AntiCISqrtSwap(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubit1, bitLenInt qubit2)
Apply an inverse square root of swap with arbitrary (anti) control bits.
Definition: gates.cpp:747
virtual bool isClifford()
Returns "true" if current state is identifiably within the Clifford set, or "false" if it is not or c...
Definition: qstabilizerhybrid.hpp:286
#define REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:104
#define TRYDECOMPOSE_EPSILON
Definition: qrack_types.hpp:149
virtual void INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: arithmetic.cpp:170
std::vector< int > deviceIDs
Definition: qstabilizerhybrid.hpp:60
virtual void UpdateRunningNorm(real1_f norm_thresh=REAL1_DEFAULT_ARG)
Force a calculation of the norm of the state vector, in order to make it unit length before the next ...
Definition: qstabilizerhybrid.hpp:882
void FlushIfBlocked(bitLenInt control, bitLenInt target, bool isPhase=false)
Definition: qstabilizerhybrid.hpp:74
bitLenInt thresholdQubits
Definition: qstabilizerhybrid.hpp:58
virtual int64_t GetDeviceID()
Definition: qstabilizerhybrid.hpp:973
virtual void LockEngine(QEnginePtr eng)
Definition: qpager.hpp:134
virtual bool TrySeparate(const bitLenInt *qubits, bitLenInt length, real1_f error_tol)
Qrack::QUnit types maintain explicit separation of representations of qubits, which reduces memory us...
Definition: qstabilizerhybrid.hpp:940
QInterfacePtr engine
Definition: qstabilizerhybrid.hpp:48
virtual bool ApproxCompare(QInterfacePtr toCompare, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Compare state vectors approximately, component by component, to determine whether this state vector i...
Definition: qstabilizerhybrid.hpp:851
#define REAL1_EPSILON
Definition: qrack_types.hpp:106
virtual void U(bitLenInt target, real1_f theta, real1_f phi, real1_f lambda)
General unitary gate.
Definition: rotational.cpp:18
virtual bool CollapseSeparableShard(bitLenInt qubit)
Definition: qstabilizerhybrid.hpp:96
bool isSparse
Definition: qstabilizerhybrid.hpp:55
virtual void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination"...
Definition: qstabilizerhybrid.hpp:365
virtual bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, const unsigned char *values)
Add to entangled 8 bit register state with a superposed index-offset-based read from classical memory...
Definition: qstabilizerhybrid.hpp:761
virtual void MCInvert(const bitLenInt *controls, bitLenInt controlLen, complex topRight, complex bottomLeft, bitLenInt target)
Apply a single bit transformation that reverses bit probability and might effect phase, with arbitrary control bits.
Definition: qstabilizerhybrid.cpp:439
virtual bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
Definition: qstabilizerhybrid.hpp:361
A "Qrack::QInterface" is an abstract interface exposing qubit permutation state vector with methods t...
Definition: qinterface.hpp:145
bool doNormalize
Definition: qstabilizerhybrid.hpp:53
#define QINTERFACE_TO_QPARITY(qReg)
Definition: qstabilizerhybrid.hpp:30
virtual void X(bitLenInt qubitIndex)
X gate.
std::vector< QInterfaceEngine > engineTypes
Definition: qstabilizerhybrid.hpp:47
QInterfacePtr MakeEngine(bitCapInt perm=0)
Definition: qstabilizerhybrid.cpp:75
virtual void SqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Square root of Swap gate.
Definition: qstabilizerhybrid.hpp:794
virtual void DECS(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: qstabilizerhybrid.hpp:617
bitLenInt qubitCount
Definition: qinterface.hpp:147
virtual void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2)
The 2-qubit "fSim" gate, (useful in the simulation of particles with fermionic statistics) ...
Definition: qstabilizerhybrid.hpp:804
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:337
virtual void FlushBuffers()
Definition: qstabilizerhybrid.hpp:126
virtual void ZeroPhaseFlip(bitLenInt start, bitLenInt length)
Reverse the phase of the state where the register equals zero.
Definition: qstabilizerhybrid.hpp:788
bool useHostRam
Definition: qstabilizerhybrid.hpp:54
#define ONE_BCI
Definition: qrack_types.hpp:26
virtual bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, const unsigned char *values, bool resetValue=true)
Set 8 bit register bits by a superposed index-offset-based read from classical memory.
Definition: qstabilizerhybrid.hpp:754
virtual real1_f ExpectationBitsAll(const bitLenInt *bits, bitLenInt length, bitCapInt offset=0)
Get permutation expectation value of bits.
Definition: qinterface.cpp:383
virtual void DECS(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Subtract a classical integer from the register, with sign and without carry.
Definition: arithmetic.cpp:185
virtual void Swap(bitLenInt qubit1, bitLenInt qubit2)
Swap values of two bits in register.
Definition: qstabilizerhybrid.hpp:414
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:33
virtual std::map< bitCapInt, int > MultiShotMeasureMask(const bitCapInt *qPowers, bitLenInt qPowerCount, unsigned shots)
Statistical measure of masked permutation probability.
Definition: qstabilizerhybrid.cpp:677
virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qstabilizerhybrid.hpp:612
virtual void MCPhase(const bitLenInt *controls, bitLenInt controlLen, complex topLeft, complex bottomRight, bitLenInt target)
Apply a single bit transformation that only effects phase, with arbitrary control bits...
Definition: qstabilizerhybrid.cpp:384
#define bitCapInt
Definition: qrack_types.hpp:51
virtual real1_f ProbParity(bitCapInt mask)
Overall probability of any odd permutation of the masked set of bits.
Definition: qstabilizerhybrid.hpp:570
virtual void MACMtrx(const bitLenInt *controls, bitLenInt controlLen, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary (anti-)control bits...
Definition: qstabilizerhybrid.cpp:480
Definition: complex16x2simd.hpp:25
virtual real1_f SumSqrDiff(QInterfacePtr toCompare)
Definition: qstabilizerhybrid.hpp:821
virtual void X(bitLenInt q)
Definition: qstabilizerhybrid.hpp:611
#define ONE_CMPLX
Definition: qrack_types.hpp:145
Definition: qparity.hpp:22
real1_f separabilityThreshold
Definition: qstabilizerhybrid.hpp:57
virtual void MUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Multiply by integer.
Definition: qstabilizerhybrid.hpp:698
virtual void SetDevice(int dID, bool forceReInit=false)
Set the device index, if more than one device is available.
Definition: qstabilizerhybrid.hpp:965
virtual void UniformlyControlledSingleBit(const bitLenInt *controls, bitLenInt controlLen, bitLenInt qubitIndex, const complex *mtrxs)
Apply a "uniformly controlled" arbitrary single bit unitary transformation.
Definition: qinterface.hpp:498