Qrack  10.0
General classical-emulating-quantum development framework
qhybrid.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017-2023. 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 "qengine.hpp"
15 
16 #if !ENABLE_OPENCL && !ENABLE_CUDA
17 #error OpenCL or CUDA has not been enabled
18 #endif
19 
20 #if ENABLE_OPENCL
21 #define QRACK_GPU_ENGINE QINTERFACE_OPENCL
22 #else
23 #define QRACK_GPU_ENGINE QINTERFACE_CUDA
24 #endif
25 
26 namespace Qrack {
27 
28 class QHybrid;
29 typedef std::shared_ptr<QHybrid> QHybridPtr;
30 
35 class QHybrid : public QEngine {
36 protected:
37  bool isGpu;
38  bool isPager;
39  bool useRDRAND;
40  bool isSparse;
44  int64_t devID;
47  std::vector<int64_t> deviceIDs;
48 
49  using QEngine::Copy;
50  void Copy(QInterfacePtr orig) { Copy(std::dynamic_pointer_cast<QHybrid>(orig)); }
51  void Copy(QHybridPtr orig)
52  {
53  QEngine::Copy(std::dynamic_pointer_cast<QEngine>(orig));
54  isGpu = orig->isGpu;
55  isPager = orig->isPager;
56  useRDRAND = orig->useRDRAND;
57  isSparse = orig->isSparse;
58  gpuThresholdQubits = orig->gpuThresholdQubits;
59  pagerThresholdQubits = orig->pagerThresholdQubits;
60  separabilityThreshold = orig->separabilityThreshold;
61  devID = orig->devID;
62  engine = orig->engine;
63  phaseFactor = orig->phaseFactor;
64  deviceIDs = orig->deviceIDs;
65  }
66 
67 public:
68  QHybrid(bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI, qrack_rand_gen_ptr rgp = nullptr,
69  const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool randomGlobalPhase = true,
70  bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
71  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {}, bitLenInt qubitThreshold = 0U,
72  real1_f ignored2 = _qrack_qunit_sep_thresh);
73 
75  {
76  const bool isHigher = qb > qubitCount;
77  if (isHigher) {
79  }
81  if (!isHigher) {
83  }
84 
85  if (engine->IsZeroAmplitude()) {
86  engine->SetQubitCount(qb);
87  }
88  }
89 
91 
92  bool isOpenCL() { return isGpu; }
93 
94  void SetConcurrency(uint32_t threadCount)
95  {
96  QInterface::SetConcurrency(threadCount);
97  engine->SetConcurrency(GetConcurrencyLevel());
98  }
99 
105  void SwitchGpuMode(bool useGpu)
106  {
107  QEnginePtr nEngine{ nullptr };
108  if (!isGpu && useGpu) {
109  nEngine = MakeEngine(true);
110  } else if (isGpu && !useGpu) {
111  nEngine = MakeEngine(false);
112  }
113 
114  if (nEngine) {
115  nEngine->CopyStateVec(engine);
116  engine = nEngine;
117  }
118 
119  isGpu = useGpu;
120  }
121 
127  void SwitchPagerMode(bool usePager)
128  {
129  if (!isPager && usePager) {
130  std::vector<QInterfaceEngine> engines{ isGpu ? QRACK_GPU_ENGINE : QINTERFACE_CPU };
131  engine = std::make_shared<QPager>(engine, engines, qubitCount, ZERO_BCI, rand_generator, phaseFactor,
134  } else if (isPager && !usePager) {
135  engine = std::dynamic_pointer_cast<QPager>(engine)->ReleaseEngine();
136  }
137 
138  isPager = usePager;
139  }
140 
141  void SwitchModes(bool useGpu, bool usePager)
142  {
143  if (!usePager) {
144  SwitchPagerMode(false);
145  }
146  SwitchGpuMode(useGpu);
147  if (usePager) {
148  SwitchPagerMode(true);
149  }
150  }
151 
152  real1_f GetRunningNorm() { return engine->GetRunningNorm(); }
153 
154  void ZeroAmplitudes() { engine->ZeroAmplitudes(); }
155 
156  bool IsZeroAmplitude() { return engine->IsZeroAmplitude(); }
157 
158  real1_f FirstNonzeroPhase() { return engine->FirstNonzeroPhase(); }
159 
160  void CopyStateVec(QEnginePtr src) { CopyStateVec(std::dynamic_pointer_cast<QHybrid>(src)); }
162  {
163  SwitchModes(src->isGpu, src->isPager);
164  engine->CopyStateVec(src->engine);
165  }
166 
167  void GetAmplitudePage(complex* pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
168  {
169  engine->GetAmplitudePage(pagePtr, offset, length);
170  }
171  void SetAmplitudePage(const complex* pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
172  {
173  engine->SetAmplitudePage(pagePtr, offset, length);
174  }
175  void SetAmplitudePage(QHybridPtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
176  {
177  pageEnginePtr->SwitchModes(isGpu, isPager);
178  engine->SetAmplitudePage(pageEnginePtr->engine, srcOffset, dstOffset, length);
179  }
180  void SetAmplitudePage(QEnginePtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
181  {
182  SetAmplitudePage(std::dynamic_pointer_cast<QHybrid>(pageEnginePtr), srcOffset, dstOffset, length);
183  }
184  void ShuffleBuffers(QEnginePtr oEngine) { ShuffleBuffers(std::dynamic_pointer_cast<QHybrid>(oEngine)); }
186  {
187  oEngine->SwitchModes(isGpu, isPager);
188  engine->ShuffleBuffers(oEngine->engine);
189  }
190  void QueueSetDoNormalize(bool doNorm) { engine->QueueSetDoNormalize(doNorm); }
191  void QueueSetRunningNorm(real1_f runningNrm) { engine->QueueSetRunningNorm(runningNrm); }
192 
193  using QEngine::ApplyM;
194  void ApplyM(const bitCapInt& regMask, const bitCapInt& result, const complex& nrm)
195  {
196  engine->ApplyM(regMask, result, nrm);
197  }
198  real1_f ProbReg(bitLenInt start, bitLenInt length, const bitCapInt& permutation)
199  {
200  return engine->ProbReg(start, length, permutation);
201  }
202  void ProbRegAll(bitLenInt start, bitLenInt length, real1* probsArray)
203  {
204  engine->ProbRegAll(start, length, probsArray);
205  }
206 
207  using QEngine::Compose;
209  {
210  SetQubitCount(qubitCount + toCopy->qubitCount);
211  toCopy->SwitchModes(isGpu, isPager);
212  return engine->Compose(toCopy->engine);
213  }
214  bitLenInt Compose(QInterfacePtr toCopy) { return Compose(std::dynamic_pointer_cast<QHybrid>(toCopy)); }
216  {
217  SetQubitCount(qubitCount + toCopy->qubitCount);
218  toCopy->SwitchModes(isGpu, isPager);
219  return engine->Compose(toCopy->engine, start);
220  }
222  {
223  return Compose(std::dynamic_pointer_cast<QHybrid>(toCopy), start);
224  }
226  {
227  SetQubitCount(qubitCount + toCopy->qubitCount);
228  toCopy->SwitchModes(isGpu, isPager);
229  return engine->ComposeNoClone(toCopy->engine);
230  }
232  {
233  return ComposeNoClone(std::dynamic_pointer_cast<QHybrid>(toCopy));
234  }
235  using QEngine::Decompose;
236  void Decompose(bitLenInt start, QInterfacePtr dest) { Decompose(start, std::dynamic_pointer_cast<QHybrid>(dest)); }
238  {
239  return TryDecompose(start, std::dynamic_pointer_cast<QHybrid>(dest), error_tol);
240  }
241  void Decompose(bitLenInt start, QHybridPtr dest)
242  {
243  dest->SwitchModes(isGpu, isPager);
244  engine->Decompose(start, dest->engine);
245  SetQubitCount(qubitCount - dest->GetQubitCount());
246  }
247  void Dispose(bitLenInt start, bitLenInt length)
248  {
249  engine->Dispose(start, length);
250  SetQubitCount(qubitCount - length);
251  }
252  void Dispose(bitLenInt start, bitLenInt length, const bitCapInt& disposedPerm)
253  {
254  engine->Dispose(start, length, disposedPerm);
255  SetQubitCount(qubitCount - length);
256  }
257 
258  using QEngine::Allocate;
260  {
261  if (!length) {
262  return start;
263  }
264 
265  QHybridPtr nQubits = std::make_shared<QHybrid>(length, ZERO_BCI, rand_generator, phaseFactor, doNormalize,
268  nQubits->SetConcurrency(GetConcurrencyLevel());
269 
270  return Compose(nQubits, start);
271  }
272 
274  {
275  const bitLenInt nQubitCount = qubitCount - dest->GetQubitCount();
276  SwitchModes(nQubitCount >= gpuThresholdQubits, nQubitCount > pagerThresholdQubits);
277  dest->SwitchModes(isGpu, isPager);
278  const bool result = engine->TryDecompose(start, dest->engine, error_tol);
279  if (result) {
280  SetQubitCount(nQubitCount);
281  } else {
283  }
284  return result;
285  }
286 
287  void LossySaveStateVector(std::string f, int p = 6, int b = 4) { engine->LossySaveStateVector(f, p, b); }
288  void LossyLoadStateVector(std::string f) { engine->LossyLoadStateVector(f); }
289  void SetQuantumState(const complex* inputState) { engine->SetQuantumState(inputState); }
290  void GetQuantumState(complex* outputState) { engine->GetQuantumState(outputState); }
291  void GetProbs(real1* outputProbs) { engine->GetProbs(outputProbs); }
292  complex GetAmplitude(const bitCapInt& perm) { return engine->GetAmplitude(perm); }
293  void SetAmplitude(const bitCapInt& perm, const complex& amp) { engine->SetAmplitude(perm, amp); }
294  void SetPermutation(const bitCapInt& perm, const complex& phaseFac = CMPLX_DEFAULT_ARG)
295  {
296  engine->SetPermutation(perm, phaseFac);
297  }
298 
299  using QEngine::X;
300  void X(bitLenInt target) { engine->X(target); }
301  using QEngine::Z;
302  void Z(bitLenInt target) { engine->Z(target); }
303  using QEngine::Invert;
304  void Invert(const complex& topRight, const complex& bottomLeft, bitLenInt qubitIndex)
305  {
306  engine->Invert(topRight, bottomLeft, qubitIndex);
307  }
308  using QEngine::Phase;
309  void Phase(const complex& topLeft, const complex& bottomRight, bitLenInt qubitIndex)
310  {
311  engine->Phase(topLeft, bottomRight, qubitIndex);
312  }
313  void XMask(const bitCapInt& mask) { engine->XMask(mask); }
314  void PhaseParity(real1_f radians, const bitCapInt& mask) { engine->PhaseParity(radians, mask); }
315  void PhaseRootNMask(bitLenInt n, const bitCapInt& mask) { engine->PhaseRootNMask(n, mask); }
316  void Mtrx(const complex mtrx[4U], bitLenInt qubitIndex) { engine->Mtrx(mtrx, qubitIndex); }
317  void MCMtrx(const std::vector<bitLenInt>& controls, const complex mtrx[4U], bitLenInt target)
318  {
319  engine->MCMtrx(controls, mtrx, target);
320  }
321  void MACMtrx(const std::vector<bitLenInt>& controls, const complex mtrx[4U], bitLenInt target)
322  {
323  engine->MACMtrx(controls, mtrx, target);
324  }
325 
327  void UniformlyControlledSingleBit(const std::vector<bitLenInt>& controls, bitLenInt qubitIndex,
328  const complex* mtrxs, const std::vector<bitCapInt> mtrxSkipPowers, const bitCapInt& mtrxSkipValueMask)
329  {
330  engine->UniformlyControlledSingleBit(controls, qubitIndex, mtrxs, mtrxSkipPowers, mtrxSkipValueMask);
331  }
332 
333  real1_f CProb(bitLenInt control, bitLenInt target) { return engine->CProb(control, target); }
334  real1_f ACProb(bitLenInt control, bitLenInt target) { return engine->ACProb(control, target); }
335 
336  void UniformParityRZ(const bitCapInt& mask, real1_f angle) { engine->UniformParityRZ(mask, angle); }
337  void CUniformParityRZ(const std::vector<bitLenInt>& controls, const bitCapInt& mask, real1_f angle)
338  {
339  engine->CUniformParityRZ(controls, mask, angle);
340  }
341 
342  void CSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
343  {
344  engine->CSwap(controls, qubit1, qubit2);
345  }
346  void AntiCSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
347  {
348  engine->AntiCSwap(controls, qubit1, qubit2);
349  }
350  void CSqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
351  {
352  engine->CSqrtSwap(controls, qubit1, qubit2);
353  }
354  void AntiCSqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
355  {
356  engine->AntiCSqrtSwap(controls, qubit1, qubit2);
357  }
358  void CISqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
359  {
360  engine->CISqrtSwap(controls, qubit1, qubit2);
361  }
362  void AntiCISqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
363  {
364  engine->AntiCISqrtSwap(controls, qubit1, qubit2);
365  }
366 
367  bool ForceM(bitLenInt qubit, bool result, bool doForce = true, bool doApply = true)
368  {
369  return engine->ForceM(qubit, result, doForce, doApply);
370  }
371  bitCapInt MAll() { return engine->MAll(); }
372 
373  void ROL(bitLenInt shift, bitLenInt start, bitLenInt length) { engine->ROL(shift, start, length); }
374 
375 #if ENABLE_ALU
376  void INC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length) { engine->INC(toAdd, start, length); }
377  void CINC(const bitCapInt& toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt>& controls)
378  {
379  engine->CINC(toAdd, inOutStart, length, controls);
380  }
381  void INCC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
382  {
383  engine->INCC(toAdd, start, length, carryIndex);
384  }
385  void INCS(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
386  {
387  engine->INCS(toAdd, start, length, overflowIndex);
388  }
389  void INCSC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
390  {
391  engine->INCSC(toAdd, start, length, overflowIndex, carryIndex);
392  }
393  void INCSC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
394  {
395  engine->INCSC(toAdd, start, length, carryIndex);
396  }
397  void DECC(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
398  {
399  engine->DECC(toSub, start, length, carryIndex);
400  }
401  void DECSC(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
402  {
403  engine->DECSC(toSub, start, length, overflowIndex, carryIndex);
404  }
405  void DECSC(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
406  {
407  engine->DECSC(toSub, start, length, carryIndex);
408  }
409 #if ENABLE_BCD
410  void INCBCD(const bitCapInt& toAdd, bitLenInt start, bitLenInt length) { engine->INCBCD(toAdd, start, length); }
411  void INCBCDC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
412  {
413  engine->INCBCDC(toAdd, start, length, carryIndex);
414  }
415  void DECBCDC(const bitCapInt& toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
416  {
417  engine->DECBCDC(toSub, start, length, carryIndex);
418  }
419 #endif
420  void MUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
421  {
422  engine->MUL(toMul, inOutStart, carryStart, length);
423  }
424  void DIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
425  {
426  engine->DIV(toDiv, inOutStart, carryStart, length);
427  }
429  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
430  {
431  engine->MULModNOut(toMul, modN, inStart, outStart, length);
432  }
434  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
435  {
436  engine->IMULModNOut(toMul, modN, inStart, outStart, length);
437  }
439  const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
440  {
441  engine->POWModNOut(base, modN, inStart, outStart, length);
442  }
443  void CMUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
444  const std::vector<bitLenInt>& controls)
445  {
446  engine->CMUL(toMul, inOutStart, carryStart, length, controls);
447  }
448  void CDIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
449  const std::vector<bitLenInt>& controls)
450  {
451  engine->CDIV(toDiv, inOutStart, carryStart, length, controls);
452  }
453  void CMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
454  bitLenInt length, const std::vector<bitLenInt>& controls)
455  {
456  engine->CMULModNOut(toMul, modN, inStart, outStart, length, controls);
457  }
458  void CIMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
459  bitLenInt length, const std::vector<bitLenInt>& controls)
460  {
461  engine->CIMULModNOut(toMul, modN, inStart, outStart, length, controls);
462  }
463  void CPOWModNOut(const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
464  bitLenInt length, const std::vector<bitLenInt>& controls)
465  {
466  engine->CPOWModNOut(base, modN, inStart, outStart, length, controls);
467  }
468 
469  bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
470  const unsigned char* values, bool resetValue = true)
471  {
472  return engine->IndexedLDA(indexStart, indexLength, valueStart, valueLength, values, resetValue);
473  }
474  bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
475  bitLenInt carryIndex, const unsigned char* values)
476  {
477  return engine->IndexedADC(indexStart, indexLength, valueStart, valueLength, carryIndex, values);
478  }
479  bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
480  bitLenInt carryIndex, const unsigned char* values)
481  {
482  return engine->IndexedSBC(indexStart, indexLength, valueStart, valueLength, carryIndex, values);
483  }
484  void Hash(bitLenInt start, bitLenInt length, const unsigned char* values) { engine->Hash(start, length, values); }
485 
486  void CPhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex)
487  {
488  engine->CPhaseFlipIfLess(greaterPerm, start, length, flagIndex);
489  }
490  void PhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length)
491  {
492  engine->PhaseFlipIfLess(greaterPerm, start, length);
493  }
494 #endif
495 
496  void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->Swap(qubitIndex1, qubitIndex2); }
497  void ISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->ISwap(qubitIndex1, qubitIndex2); }
498  void IISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->IISwap(qubitIndex1, qubitIndex2); }
499  void SqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->SqrtSwap(qubitIndex1, qubitIndex2); }
500  void ISqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->ISqrtSwap(qubitIndex1, qubitIndex2); }
501  void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2)
502  {
503  engine->FSim(theta, phi, qubitIndex1, qubitIndex2);
504  }
505 
506  real1_f Prob(bitLenInt qubitIndex) { return engine->Prob(qubitIndex); }
507  real1_f CtrlOrAntiProb(bool controlState, bitLenInt control, bitLenInt target)
508  {
509  return engine->CtrlOrAntiProb(controlState, control, target);
510  }
511  real1_f ProbAll(const bitCapInt& fullRegister) { return engine->ProbAll(fullRegister); }
512  real1_f ProbMask(const bitCapInt& mask, const bitCapInt& permutation)
513  {
514  return engine->ProbMask(mask, permutation);
515  }
516  real1_f ProbParity(const bitCapInt& mask) { return engine->ProbParity(mask); }
517  bool ForceMParity(const bitCapInt& mask, bool result, bool doForce = true)
518  {
519  return engine->ForceMParity(mask, result, doForce);
520  }
521 
522  real1_f SumSqrDiff(QInterfacePtr toCompare) { return SumSqrDiff(std::dynamic_pointer_cast<QHybrid>(toCompare)); }
524  {
525  toCompare->SwitchModes(isGpu, isPager);
526  return engine->SumSqrDiff(toCompare->engine);
527  }
528 
529  void UpdateRunningNorm(real1_f norm_thresh = REAL1_DEFAULT_ARG) { engine->UpdateRunningNorm(norm_thresh); }
531  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1_F)
532  {
533  engine->NormalizeState(nrm, norm_thresh, phaseArg);
534  }
535 
536  real1_f ExpectationBitsAll(const std::vector<bitLenInt>& bits, const bitCapInt& offset = ZERO_BCI)
537  {
538  return engine->ExpectationBitsAll(bits, offset);
539  }
540 
541  void Finish() { engine->Finish(); }
542 
543  bool isFinished() { return engine->isFinished(); }
544 
545  void Dump() { engine->Dump(); }
546 
548  {
549  QHybridPtr c = std::make_shared<QHybrid>(qubitCount, ZERO_BCI, rand_generator, phaseFactor, doNormalize,
552  c->runningNorm = runningNorm;
553  c->SetConcurrency(GetConcurrencyLevel());
554  c->engine->CopyStateVec(engine);
555  return c;
556  }
558  {
559  QHybridPtr c = std::make_shared<QHybrid>(0U, ZERO_BCI, rand_generator, phaseFactor, doNormalize,
562  c->SetQubitCount(qubitCount);
563  return c;
564  }
566  {
567  QHybridPtr c = std::dynamic_pointer_cast<QHybrid>(CloneEmpty());
568  c->engine = std::dynamic_pointer_cast<QEngine>(engine->Copy());
569  return c;
570  }
571 
572  void SetDevice(int64_t dID)
573  {
574  devID = dID;
575  engine->SetDevice(dID);
576  }
577 
578  void SetDeviceList(std::vector<int64_t> dIDs)
579  {
580  deviceIDs = dIDs;
581  engine->SetDeviceList(dIDs);
582  }
583 
584  int64_t GetDevice() { return devID; }
585  std::vector<int64_t> GetDeviceList() { return deviceIDs; }
586 
587  bitCapIntOcl GetMaxSize() { return engine->GetMaxSize(); };
588 
589 protected:
590  real1_f GetExpectation(bitLenInt valueStart, bitLenInt valueLength)
591  {
592  return engine->GetExpectation(valueStart, valueLength);
593  }
594 
595  void Apply2x2(bitCapInt offset1, bitCapInt offset2, const complex mtrx[4U], bitLenInt bitCount,
596  const bitCapInt* qPowersSorted, bool doCalcNorm, real1_f norm_thresh = REAL1_DEFAULT_ARG)
597  {
598  engine->Apply2x2(offset1, offset2, mtrx, bitCount, qPowersSorted, doCalcNorm, norm_thresh);
599  }
600  void ApplyControlled2x2(const std::vector<bitLenInt>& controls, bitLenInt target, const complex mtrx[4U])
601  {
602  engine->ApplyControlled2x2(controls, target, mtrx);
603  }
604  void ApplyAntiControlled2x2(const std::vector<bitLenInt>& controls, bitLenInt target, const complex mtrx[4U])
605  {
606  engine->ApplyAntiControlled2x2(controls, target, mtrx);
607  }
608 
609 #if ENABLE_ALU
610  void INCDECC(const bitCapInt& toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
611  {
612  engine->INCDECC(toMod, inOutStart, length, carryIndex);
613  }
614  void INCDECSC(const bitCapInt& toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
615  {
616  engine->INCDECSC(toMod, inOutStart, length, carryIndex);
617  }
618  void INCDECSC(
619  const bitCapInt& toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
620  {
621  engine->INCDECSC(toMod, inOutStart, length, overflowIndex, carryIndex);
622  }
623 #if ENABLE_BCD
624  void INCDECBCDC(const bitCapInt& toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
625  {
626  engine->INCDECBCDC(toMod, inOutStart, length, carryIndex);
627  }
628 #endif
629 #endif
630 };
631 } // namespace Qrack
unsigned GetConcurrencyLevel()
Definition: parallel_for.hpp:49
Abstract QEngine implementation, for all "Schroedinger method" engines.
Definition: qengine.hpp:31
virtual void SetQubitCount(bitLenInt qb)
Definition: qengine.hpp:105
virtual void Copy(QInterfacePtr orig)
Copy this QInterface.
Definition: qinterface.hpp:222
virtual void ApplyM(const bitCapInt &qPower, bool result, const complex &nrm)
Definition: qengine.hpp:161
real1 runningNorm
The value stored in runningNorm should always be the total probability implied by the norm of all amp...
Definition: qengine.hpp:39
virtual void Decompose(bitLenInt start, QInterfacePtr dest)=0
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
virtual void X(bitLenInt qubit)
X gate.
Definition: qinterface.hpp:1116
bool useHostRam
Definition: qengine.hpp:36
A "Qrack::QHybrid" internally switched between Qrack::QEngineCPU and Qrack::QEngineOCL to maximize qu...
Definition: qhybrid.hpp:35
void CSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a swap with arbitrary control bits.
Definition: qhybrid.hpp:342
void CMULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication modulo N by integer, (out of place)
Definition: qhybrid.hpp:453
bitLenInt Compose(QHybridPtr toCopy)
Definition: qhybrid.hpp:208
void SetConcurrency(uint32_t threadCount)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qhybrid.hpp:94
void MACMtrx(const std::vector< bitLenInt > &controls, const complex mtrx[4U], bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary (anti-)control bits.
Definition: qhybrid.hpp:321
void ISqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Inverse square root of Swap gate.
Definition: qhybrid.hpp:500
real1_f GetRunningNorm()
Get in-flight renormalization factor.
Definition: qhybrid.hpp:152
void SetQuantumState(const complex *inputState)
Set an arbitrary pure quantum state representation.
Definition: qhybrid.hpp:289
void Hash(bitLenInt start, bitLenInt length, const unsigned char *values)
Transform a length of qubit register via lookup through a hash table.
Definition: qhybrid.hpp:484
void GetAmplitudePage(complex *pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
Copy a "page" of amplitudes from this QEngine's internal state, into pagePtr.
Definition: qhybrid.hpp:167
void Dump()
If asynchronous work is still running, let the simulator know that it can be aborted.
Definition: qhybrid.hpp:545
void POWModNOut(const bitCapInt &base, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Raise a classical base to a quantum power, modulo N, (out of place)
Definition: qhybrid.hpp:438
real1_f CtrlOrAntiProb(bool controlState, bitLenInt control, bitLenInt target)
Definition: qhybrid.hpp:507
real1_f ProbParity(const bitCapInt &mask)
Overall probability of any odd permutation of the masked set of bits.
Definition: qhybrid.hpp:516
void INCDECBCDC(const bitCapInt &toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qhybrid.hpp:624
void INCDECSC(const bitCapInt &toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (with overflow flag)
Definition: qhybrid.hpp:618
void QueueSetRunningNorm(real1_f runningNrm)
Add an operation to the (OpenCL) queue, to set the value of runningNorm, which is the normalization c...
Definition: qhybrid.hpp:191
bool useRDRAND
Definition: qhybrid.hpp:39
void CUniformParityRZ(const std::vector< bitLenInt > &controls, const 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: qhybrid.hpp:337
void ShuffleBuffers(QEnginePtr oEngine)
Swap the high half of this engine with the low half of another.
Definition: qhybrid.hpp:184
std::vector< int64_t > GetDeviceList()
Get the device index.
Definition: qhybrid.hpp:585
void CINC(const bitCapInt &toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Add integer (without sign, with controls)
Definition: qhybrid.hpp:377
void Mtrx(const complex mtrx[4U], bitLenInt qubitIndex)
Apply an arbitrary single bit unitary transformation.
Definition: qhybrid.hpp:316
void Copy(QHybridPtr orig)
Definition: qhybrid.hpp:51
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: qhybrid.hpp:469
void INCDECC(const bitCapInt &toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCC and DECC (without sign, with carry)
Definition: qhybrid.hpp:610
void UniformlyControlledSingleBit(const std::vector< bitLenInt > &controls, bitLenInt qubitIndex, const complex *mtrxs, const std::vector< bitCapInt > mtrxSkipPowers, const bitCapInt &mtrxSkipValueMask)
Definition: qhybrid.hpp:327
bool ForceM(bitLenInt qubit, bool result, bool doForce=true, bool doApply=true)
PSEUDO-QUANTUM - Acts like a measurement gate, except with a specified forced result.
Definition: qhybrid.hpp:367
real1_f ProbReg(bitLenInt start, bitLenInt length, const bitCapInt &permutation)
Direct measure of register permutation probability.
Definition: qhybrid.hpp:198
void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qhybrid.hpp:236
void SetAmplitudePage(QEnginePtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
Copy a "page" of amplitudes from another QEngine, pointed to by pageEnginePtr, into this QEngine's in...
Definition: qhybrid.hpp:180
void SetPermutation(const bitCapInt &perm, const complex &phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: qhybrid.hpp:294
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: qhybrid.hpp:474
void ShuffleBuffers(QHybridPtr oEngine)
Definition: qhybrid.hpp:185
QEnginePtr engine
Definition: qhybrid.hpp:45
void INCBCD(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add classical BCD integer (without sign)
Definition: qhybrid.hpp:410
real1_f ACProb(bitLenInt control, bitLenInt target)
Direct measure of bit probability to be in |1> state, if control bit is |0>.
Definition: qhybrid.hpp:334
real1_f CProb(bitLenInt control, bitLenInt target)
Direct measure of bit probability to be in |1> state, if control bit is |1>.
Definition: qhybrid.hpp:333
real1_f Prob(bitLenInt qubitIndex)
Direct measure of bit probability to be in |1> state.
Definition: qhybrid.hpp:506
real1_f separabilityThreshold
Definition: qhybrid.hpp:43
void MULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Multiplication modulo N by integer, (out of place)
Definition: qhybrid.hpp:428
void SwitchGpuMode(bool useGpu)
Switches between CPU and GPU modes.
Definition: qhybrid.hpp:105
bitLenInt Allocate(bitLenInt start, bitLenInt length)
Allocate new "length" count of |0> state qubits at specified qubit index start position.
Definition: qhybrid.hpp:259
complex GetAmplitude(const bitCapInt &perm)
Get the representational amplitude of a full permutation.
Definition: qhybrid.hpp:292
void ApplyM(const bitCapInt &regMask, const bitCapInt &result, const complex &nrm)
Definition: qhybrid.hpp:194
void NormalizeState(real1_f nrm=REAL1_DEFAULT_ARG, real1_f norm_thresh=REAL1_DEFAULT_ARG, real1_f phaseArg=ZERO_R1_F)
Apply the normalization factor found by UpdateRunningNorm() or on the fly by a single bit gate.
Definition: qhybrid.hpp:530
void CDIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled division by power of integer.
Definition: qhybrid.hpp:448
void SwitchModes(bool useGpu, bool usePager)
Definition: qhybrid.hpp:141
void SetQubitCount(bitLenInt qb)
Definition: qhybrid.hpp:74
void INCDECSC(const bitCapInt &toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qhybrid.hpp:614
int64_t devID
Definition: qhybrid.hpp:44
void ProbRegAll(bitLenInt start, bitLenInt length, real1 *probsArray)
Definition: qhybrid.hpp:202
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: qhybrid.hpp:529
void SetDeviceList(std::vector< int64_t > dIDs)
Set the device index list, if more than one device is available.
Definition: qhybrid.hpp:578
void CIMULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Inverse of controlled multiplication modulo N by integer, (out of place)
Definition: qhybrid.hpp:458
void DECSC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract a classical integer from the register, with sign and with carry.
Definition: qhybrid.hpp:405
bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qhybrid.hpp:214
void PhaseRootNMask(bitLenInt n, const bitCapInt &mask)
Masked PhaseRootN gate.
Definition: qhybrid.hpp:315
void Decompose(bitLenInt start, QHybridPtr dest)
Definition: qhybrid.hpp:241
void AntiCSqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary (anti) control bits.
Definition: qhybrid.hpp:354
bool isGpu
Definition: qhybrid.hpp:37
real1_f GetExpectation(bitLenInt valueStart, bitLenInt valueLength)
Definition: qhybrid.hpp:590
void Finish()
If asynchronous work is still running, block until it finishes.
Definition: qhybrid.hpp:541
real1_f FirstNonzeroPhase()
Get phase of lowest permutation nonzero amplitude.
Definition: qhybrid.hpp:158
void CPhaseFlipIfLess(const 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: qhybrid.hpp:486
void INCC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add integer (without sign, with carry)
Definition: qhybrid.hpp:381
void AntiCISqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply an inverse square root of swap with arbitrary (anti) control bits.
Definition: qhybrid.hpp:362
real1_f ExpectationBitsAll(const std::vector< bitLenInt > &bits, const bitCapInt &offset=ZERO_BCI)
Get permutation expectation value of bits.
Definition: qhybrid.hpp:536
bool isSparse
Definition: qhybrid.hpp:40
void DECSC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Subtract a classical integer from the register, with sign and with carry.
Definition: qhybrid.hpp:401
bool ForceMParity(const 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: qhybrid.hpp:517
void CISqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply an inverse square root of swap with arbitrary control bits.
Definition: qhybrid.hpp:358
void ISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Swap values of two bits in register, and apply phase factor of i if bits are different.
Definition: qhybrid.hpp:497
real1_f SumSqrDiff(QInterfacePtr toCompare)
Calculates (1 - <\psi_e|\psi_c>) between states |\psi_c> and |\psi_e>.
Definition: qhybrid.hpp:522
std::vector< int64_t > deviceIDs
Definition: qhybrid.hpp:47
void Phase(const complex &topLeft, const complex &bottomRight, bitLenInt qubitIndex)
Apply a single bit transformation that only effects phase.
Definition: qhybrid.hpp:309
void INCSC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add a classical integer to the register, with sign and with (phase-based) carry.
Definition: qhybrid.hpp:393
void QueueSetDoNormalize(bool doNorm)
Add an operation to the (OpenCL) queue, to set the value of doNormalize, which controls whether to au...
Definition: qhybrid.hpp:190
void SetAmplitudePage(QHybridPtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
Definition: qhybrid.hpp:175
void ApplyAntiControlled2x2(const std::vector< bitLenInt > &controls, bitLenInt target, const complex mtrx[4U])
Definition: qhybrid.hpp:604
bool isOpenCL()
Returns "true" if current simulation is OpenCL-based.
Definition: qhybrid.hpp:92
bool isPager
Definition: qhybrid.hpp:38
complex phaseFactor
Definition: qhybrid.hpp:46
bitLenInt ComposeNoClone(QHybridPtr toCopy)
Definition: qhybrid.hpp:225
bool TryDecompose(bitLenInt start, QInterfacePtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Attempt to Decompose() a bit range.
Definition: qhybrid.hpp:237
bool isFinished()
Returns "false" if asynchronous work is still running, and "true" if all previously dispatched asynch...
Definition: qhybrid.hpp:543
void XMask(const bitCapInt &mask)
Masked X gate.
Definition: qhybrid.hpp:313
void PhaseParity(real1_f radians, const bitCapInt &mask)
Parity phase gate.
Definition: qhybrid.hpp:314
void IISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Inverse ISwap - Swap values of two bits in register, and apply phase factor of -i if bits are differe...
Definition: qhybrid.hpp:498
void MCMtrx(const std::vector< bitLenInt > &controls, const complex mtrx[4U], bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: qhybrid.hpp:317
real1_f ProbAll(const bitCapInt &fullRegister)
Direct measure of full permutation probability.
Definition: qhybrid.hpp:511
void SetDevice(int64_t dID)
Set GPU device ID.
Definition: qhybrid.hpp:572
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: qhybrid.hpp:501
void Copy(QInterfacePtr orig)
Definition: qhybrid.hpp:50
void DIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Divide by integer.
Definition: qhybrid.hpp:424
void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qhybrid.hpp:291
bool TryDecompose(bitLenInt start, QHybridPtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Definition: qhybrid.hpp:273
bitCapIntOcl GetMaxSize()
Definition: qhybrid.hpp:587
QHybrid(bitLenInt qBitCount, const bitCapInt &initState=ZERO_BCI, qrack_rand_gen_ptr rgp=nullptr, const complex &phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool randomGlobalPhase=true, bool useHostMem=false, int64_t deviceId=-1, bool useHardwareRNG=true, bool useSparseStateVec=false, real1_f norm_thresh=REAL1_EPSILON, std::vector< int64_t > devList={}, bitLenInt qubitThreshold=0U, real1_f ignored2=_qrack_qunit_sep_thresh)
Definition: qhybrid.cpp:23
void INC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qhybrid.hpp:376
void Dispose(bitLenInt start, bitLenInt length, const bitCapInt &disposedPerm)
Dispose a a contiguous set of qubits that are already in a permutation eigenstate.
Definition: qhybrid.hpp:252
void INCS(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: qhybrid.hpp:385
void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Swap values of two bits in register.
Definition: qhybrid.hpp:496
void Dispose(bitLenInt start, bitLenInt length)
Minimally decompose a set of contiguous bits from the separably composed unit, and discard the separa...
Definition: qhybrid.hpp:247
void UniformParityRZ(const bitCapInt &mask, real1_f angle)
If the target qubit set parity is odd, this applies a phase factor of .
Definition: qhybrid.hpp:336
bitLenInt gpuThresholdQubits
Definition: qhybrid.hpp:41
void CPOWModNOut(const bitCapInt &base, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled, raise a classical base to a quantum power, modulo N, (out of place)
Definition: qhybrid.hpp:463
void AntiCSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a swap with arbitrary (anti) control bits.
Definition: qhybrid.hpp:346
bitCapInt MAll()
Measure permutation state of all coherent bits.
Definition: qhybrid.hpp:371
void ROL(bitLenInt shift, bitLenInt start, bitLenInt length)
Circular shift left - shift bits left, and carry last bits.
Definition: qhybrid.hpp:373
void PhaseFlipIfLess(const bitCapInt &greaterPerm, bitLenInt start, bitLenInt length)
This is an expedient for an adaptive Grover's search for a function's global minimum.
Definition: qhybrid.hpp:490
QEnginePtr MakeEngine(bool isOpenCL)
Definition: qhybrid.cpp:70
void LossySaveStateVector(std::string f, int p=6, int b=4)
Write the quantum state to disk with lossy compression.
Definition: qhybrid.hpp:287
void X(bitLenInt target)
Definition: qhybrid.hpp:300
real1_f ProbMask(const bitCapInt &mask, const bitCapInt &permutation)
Direct measure of masked permutation probability.
Definition: qhybrid.hpp:512
void SetAmplitudePage(const complex *pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
Copy a "page" of amplitudes from pagePtr into this QEngine's internal state.
Definition: qhybrid.hpp:171
void SwitchPagerMode(bool usePager)
Switches between paged and non-paged modes.
Definition: qhybrid.hpp:127
void Z(bitLenInt target)
Z gate.
Definition: qhybrid.hpp:302
void DECBCDC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract BCD integer (without sign, with carry)
Definition: qhybrid.hpp:415
void DECC(const bitCapInt &toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract classical integer (without sign, with carry)
Definition: qhybrid.hpp:397
bool IsZeroAmplitude()
Returns "true" only if amplitudes are all totally 0.
Definition: qhybrid.hpp:156
void CSqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary control bits.
Definition: qhybrid.hpp:350
real1_f SumSqrDiff(QHybridPtr toCompare)
Definition: qhybrid.hpp:523
bitLenInt ComposeNoClone(QInterfacePtr toCopy)
This is a variant of Compose() for a toCopy argument that will definitely not be reused once "Compose...
Definition: qhybrid.hpp:231
void IMULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Inverse of multiplication modulo N by integer, (out of place)
Definition: qhybrid.hpp:433
void GetQuantumState(complex *outputState)
Get the pure quantum state representation.
Definition: qhybrid.hpp:290
void CopyStateVec(QHybridPtr src)
Definition: qhybrid.hpp:161
void CopyStateVec(QEnginePtr src)
Exactly copy the state vector of a different QEngine instance.
Definition: qhybrid.hpp:160
QInterfacePtr Clone()
Clone this QInterface.
Definition: qhybrid.hpp:547
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: qhybrid.hpp:479
QInterfacePtr Copy()
Copy this QInterface.
Definition: qhybrid.hpp:565
void LossyLoadStateVector(std::string f)
Read the quantum state from disk with lossy compression.
Definition: qhybrid.hpp:288
void ZeroAmplitudes()
Set all amplitudes to 0, and optionally temporarily deallocate state vector RAM.
Definition: qhybrid.hpp:154
void CMUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication by integer.
Definition: qhybrid.hpp:443
bitLenInt pagerThresholdQubits
Definition: qhybrid.hpp:42
void INCSC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Add a classical integer to the register, with sign and with carry.
Definition: qhybrid.hpp:389
void SqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Square root of Swap gate.
Definition: qhybrid.hpp:499
void Invert(const complex &topRight, const complex &bottomLeft, bitLenInt qubitIndex)
Apply a single bit transformation that reverses bit probability and might effect phase.
Definition: qhybrid.hpp:304
void Apply2x2(bitCapInt offset1, bitCapInt offset2, const complex mtrx[4U], bitLenInt bitCount, const bitCapInt *qPowersSorted, bool doCalcNorm, real1_f norm_thresh=REAL1_DEFAULT_ARG)
Definition: qhybrid.hpp:595
void INCBCDC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add classical BCD integer (without sign, with carry)
Definition: qhybrid.hpp:411
bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
Compose() a QInterface peer, inserting its qubit into index order at start index.
Definition: qhybrid.hpp:221
QEnginePtr CloneEmpty()
Clone this QEngine's settings, with a zeroed state vector.
Definition: qhybrid.hpp:557
void SetAmplitude(const bitCapInt &perm, const complex &amp)
Sets the representational amplitude of a full permutation.
Definition: qhybrid.hpp:293
void ApplyControlled2x2(const std::vector< bitLenInt > &controls, bitLenInt target, const complex mtrx[4U])
Definition: qhybrid.hpp:600
bitLenInt Compose(QHybridPtr toCopy, bitLenInt start)
Definition: qhybrid.hpp:215
void MUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Multiply by integer.
Definition: qhybrid.hpp:420
int64_t GetDevice()
Get GPU device ID.
Definition: qhybrid.hpp:584
virtual void SetConcurrency(uint32_t threadsPerEngine)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qinterface.hpp:275
real1 amplitudeFloor
Definition: qinterface.hpp:148
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:488
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:382
qrack_rand_gen_ptr rand_generator
Definition: qinterface.hpp:150
bool randGlobalPhase
Definition: qinterface.hpp:144
bitLenInt qubitCount
Definition: qinterface.hpp:146
bool doNormalize
Definition: qinterface.hpp:143
Half-precision floating-point type.
Definition: half.hpp:2206
virtual void UniformlyControlledSingleBit(const std::vector< bitLenInt > &controls, bitLenInt qubit, const complex *mtrxs)
Apply a "uniformly controlled" arbitrary single bit unitary transformation.
Definition: qinterface.hpp:645
virtual void Phase(const complex &topLeft, const complex &bottomRight, bitLenInt qubit)
Apply a single bit transformation that only effects phase.
Definition: qinterface.hpp:534
virtual void Invert(const complex &topRight, const complex &bottomLeft, bitLenInt qubit)
Apply a single bit transformation that reverses bit probability and might effect phase.
Definition: qinterface.hpp:547
virtual void Z(bitLenInt qubit)
Z gate.
Definition: qinterface.hpp:1149
virtual void U(bitLenInt target, real1_f theta, real1_f phi, real1_f lambda)
General unitary gate.
Definition: rotational.cpp:18
GLOSSARY: bitLenInt - "bit-length integer" - unsigned integer ID of qubit position in register bitCap...
Definition: complex16x2simd.hpp:25
@ QINTERFACE_CPU
Create a QEngineCPU leveraging only local CPU and memory resources.
Definition: qinterface.hpp:42
std::shared_ptr< QEngine > QEnginePtr
Definition: qrack_types.hpp:153
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:29
const real1_f _qrack_qunit_sep_thresh
Definition: qrack_functions.hpp:258
QRACK_CONST real1_f TRYDECOMPOSE_EPSILON
Definition: qrack_types.hpp:265
std::complex< real1 > complex
Definition: qrack_types.hpp:140
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:203
float real1_f
Definition: qrack_types.hpp:107
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:262
std::shared_ptr< QHybrid > QHybridPtr
Definition: qhybrid.hpp:28
const bitCapInt ZERO_BCI
Definition: qrack_types.hpp:142
#define QRACK_GPU_ENGINE
Definition: qhybrid.hpp:23
#define REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:179
#define bitLenInt
Definition: qrack_types.hpp:41
#define ZERO_R1_F
Definition: qrack_types.hpp:162
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:158
#define bitCapInt
Definition: qrack_types.hpp:65
#define bitCapIntOcl
Definition: qrack_types.hpp:53