Qrack  9.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 public:
50  QHybrid(bitLenInt qBitCount, bitCapInt initState = 0U, qrack_rand_gen_ptr rgp = nullptr,
51  complex phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool randomGlobalPhase = true,
52  bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
53  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {}, bitLenInt qubitThreshold = 0U,
54  real1_f ignored2 = FP_NORM_EPSILON_F);
55 
57  {
58  const bool isHigher = qb > qubitCount;
59  if (isHigher) {
61  }
63  if (!isHigher) {
65  }
66 
67  if (engine->IsZeroAmplitude()) {
68  engine->SetQubitCount(qb);
69  }
70  }
71 
73 
74  bool isOpenCL() { return isGpu; }
75 
76  void SetConcurrency(uint32_t threadCount)
77  {
78  QInterface::SetConcurrency(threadCount);
79  engine->SetConcurrency(GetConcurrencyLevel());
80  }
81 
87  void SwitchGpuMode(bool useGpu)
88  {
89  QEnginePtr nEngine = NULL;
90  if (!isGpu && useGpu) {
91  nEngine = MakeEngine(true);
92  } else if (isGpu && !useGpu) {
93  nEngine = MakeEngine(false);
94  }
95 
96  if (nEngine) {
97  nEngine->CopyStateVec(engine);
98  engine = nEngine;
99  }
100 
101  isGpu = useGpu;
102  }
103 
109  void SwitchPagerMode(bool usePager)
110  {
111  if (!isPager && usePager) {
112  std::vector<QInterfaceEngine> engines = { isGpu ? QRACK_GPU_ENGINE : QINTERFACE_CPU };
113  engine = std::make_shared<QPager>(engine, engines, qubitCount, 0U, rand_generator, phaseFactor, doNormalize,
116  } else if (isPager && !usePager) {
117  engine = std::dynamic_pointer_cast<QPager>(engine)->ReleaseEngine();
118  }
119 
120  isPager = usePager;
121  }
122 
123  void SwitchModes(bool useGpu, bool usePager)
124  {
125  if (!usePager) {
126  SwitchPagerMode(false);
127  }
128  SwitchGpuMode(useGpu);
129  if (usePager) {
130  SwitchPagerMode(true);
131  }
132  }
133 
134  real1_f GetRunningNorm() { return engine->GetRunningNorm(); }
135 
136  void ZeroAmplitudes() { engine->ZeroAmplitudes(); }
137 
138  bool IsZeroAmplitude() { return engine->IsZeroAmplitude(); }
139 
140  void CopyStateVec(QEnginePtr src) { CopyStateVec(std::dynamic_pointer_cast<QHybrid>(src)); }
142  {
143  SwitchModes(src->isGpu, src->isPager);
144  engine->CopyStateVec(src->engine);
145  }
146 
147  void GetAmplitudePage(complex* pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
148  {
149  engine->GetAmplitudePage(pagePtr, offset, length);
150  }
151  void SetAmplitudePage(const complex* pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
152  {
153  engine->SetAmplitudePage(pagePtr, offset, length);
154  }
155  void SetAmplitudePage(QHybridPtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
156  {
157  pageEnginePtr->SwitchModes(isGpu, isPager);
158  engine->SetAmplitudePage(pageEnginePtr->engine, srcOffset, dstOffset, length);
159  }
160  void SetAmplitudePage(QEnginePtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
161  {
162  SetAmplitudePage(std::dynamic_pointer_cast<QHybrid>(pageEnginePtr), srcOffset, dstOffset, length);
163  }
164  void ShuffleBuffers(QEnginePtr oEngine) { ShuffleBuffers(std::dynamic_pointer_cast<QHybrid>(oEngine)); }
166  {
167  oEngine->SwitchModes(isGpu, isPager);
168  engine->ShuffleBuffers(oEngine->engine);
169  }
170  QEnginePtr CloneEmpty() { return engine->CloneEmpty(); }
171  void QueueSetDoNormalize(bool doNorm) { engine->QueueSetDoNormalize(doNorm); }
172  void QueueSetRunningNorm(real1_f runningNrm) { engine->QueueSetRunningNorm(runningNrm); }
173 
174  using QEngine::ApplyM;
175  void ApplyM(bitCapInt regMask, bitCapInt result, complex nrm) { engine->ApplyM(regMask, result, nrm); }
176  real1_f ProbReg(bitLenInt start, bitLenInt length, bitCapInt permutation)
177  {
178  return engine->ProbReg(start, length, permutation);
179  }
180 
181  using QEngine::Compose;
183  {
184  SetQubitCount(qubitCount + toCopy->qubitCount);
185  toCopy->SwitchModes(isGpu, isPager);
186  return engine->Compose(toCopy->engine);
187  }
188  bitLenInt Compose(QInterfacePtr toCopy) { return Compose(std::dynamic_pointer_cast<QHybrid>(toCopy)); }
190  {
191  SetQubitCount(qubitCount + toCopy->qubitCount);
192  toCopy->SwitchModes(isGpu, isPager);
193  return engine->Compose(toCopy->engine, start);
194  }
196  {
197  return Compose(std::dynamic_pointer_cast<QHybrid>(toCopy), start);
198  }
200  {
201  SetQubitCount(qubitCount + toCopy->qubitCount);
202  toCopy->SwitchModes(isGpu, isPager);
203  return engine->ComposeNoClone(toCopy->engine);
204  }
206  {
207  return ComposeNoClone(std::dynamic_pointer_cast<QHybrid>(toCopy));
208  }
209  using QEngine::Decompose;
210  void Decompose(bitLenInt start, QInterfacePtr dest) { Decompose(start, std::dynamic_pointer_cast<QHybrid>(dest)); }
212  {
213  return TryDecompose(start, std::dynamic_pointer_cast<QHybrid>(dest), error_tol);
214  }
215  void Decompose(bitLenInt start, QHybridPtr dest)
216  {
217  dest->SwitchModes(isGpu, isPager);
218  engine->Decompose(start, dest->engine);
219  SetQubitCount(qubitCount - dest->GetQubitCount());
220  }
221  void Dispose(bitLenInt start, bitLenInt length)
222  {
223  engine->Dispose(start, length);
224  SetQubitCount(qubitCount - length);
225  }
226  void Dispose(bitLenInt start, bitLenInt length, bitCapInt disposedPerm)
227  {
228  engine->Dispose(start, length, disposedPerm);
229  SetQubitCount(qubitCount - length);
230  }
231 
232  using QEngine::Allocate;
234  {
235  if (!length) {
236  return start;
237  }
238 
239  QHybridPtr nQubits = std::make_shared<QHybrid>(length, 0U, rand_generator, phaseFactor, doNormalize,
242  nQubits->SetConcurrency(GetConcurrencyLevel());
243 
244  return Compose(nQubits, start);
245  }
246 
248  {
249  const bitLenInt nQubitCount = qubitCount - dest->GetQubitCount();
250  SwitchModes(nQubitCount >= gpuThresholdQubits, nQubitCount > pagerThresholdQubits);
251  dest->SwitchModes(isGpu, isPager);
252  const bool result = engine->TryDecompose(start, dest->engine, error_tol);
253  if (result) {
254  SetQubitCount(nQubitCount);
255  } else {
257  }
258  return result;
259  }
260 
261  void SetQuantumState(const complex* inputState) { engine->SetQuantumState(inputState); }
262  void GetQuantumState(complex* outputState) { engine->GetQuantumState(outputState); }
263  void GetProbs(real1* outputProbs) { engine->GetProbs(outputProbs); }
264  complex GetAmplitude(bitCapInt perm) { return engine->GetAmplitude(perm); }
265  void SetAmplitude(bitCapInt perm, complex amp) { engine->SetAmplitude(perm, amp); }
267  {
268  engine->SetPermutation(perm, phaseFac);
269  }
270 
271  void Mtrx(const complex* mtrx, bitLenInt qubitIndex) { engine->Mtrx(mtrx, qubitIndex); }
272  void Phase(complex topLeft, complex bottomRight, bitLenInt qubitIndex)
273  {
274  engine->Phase(topLeft, bottomRight, qubitIndex);
275  }
276  void Invert(complex topRight, complex bottomLeft, bitLenInt qubitIndex)
277  {
278  engine->Invert(topRight, bottomLeft, qubitIndex);
279  }
280  void MCMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
281  {
282  engine->MCMtrx(controls, mtrx, target);
283  }
284  void MACMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
285  {
286  engine->MACMtrx(controls, mtrx, target);
287  }
288 
290  void UniformlyControlledSingleBit(const std::vector<bitLenInt>& controls, bitLenInt qubitIndex,
291  const complex* mtrxs, const std::vector<bitCapInt> mtrxSkipPowers, bitCapInt mtrxSkipValueMask)
292  {
293  engine->UniformlyControlledSingleBit(controls, qubitIndex, mtrxs, mtrxSkipPowers, mtrxSkipValueMask);
294  }
295 
296  void XMask(bitCapInt mask) { engine->XMask(mask); }
297  void PhaseParity(real1_f radians, bitCapInt mask) { engine->PhaseParity(radians, mask); }
298 
299  real1_f CProb(bitLenInt control, bitLenInt target) { return engine->CProb(control, target); }
300  real1_f ACProb(bitLenInt control, bitLenInt target) { return engine->ACProb(control, target); }
301 
302  void UniformParityRZ(bitCapInt mask, real1_f angle) { engine->UniformParityRZ(mask, angle); }
303  void CUniformParityRZ(const std::vector<bitLenInt>& controls, bitCapInt mask, real1_f angle)
304  {
305  engine->CUniformParityRZ(controls, mask, angle);
306  }
307 
308  void CSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
309  {
310  engine->CSwap(controls, qubit1, qubit2);
311  }
312  void AntiCSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
313  {
314  engine->AntiCSwap(controls, qubit1, qubit2);
315  }
316  void CSqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
317  {
318  engine->CSqrtSwap(controls, qubit1, qubit2);
319  }
320  void AntiCSqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
321  {
322  engine->AntiCSqrtSwap(controls, qubit1, qubit2);
323  }
324  void CISqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
325  {
326  engine->CISqrtSwap(controls, qubit1, qubit2);
327  }
328  void AntiCISqrtSwap(const std::vector<bitLenInt>& controls, bitLenInt qubit1, bitLenInt qubit2)
329  {
330  engine->AntiCISqrtSwap(controls, qubit1, qubit2);
331  }
332 
333  bool ForceM(bitLenInt qubit, bool result, bool doForce = true, bool doApply = true)
334  {
335  return engine->ForceM(qubit, result, doForce, doApply);
336  }
337 
338 #if ENABLE_ALU
339  void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length) { engine->INC(toAdd, start, length); }
340  void CINC(bitCapInt toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector<bitLenInt>& controls)
341  {
342  engine->CINC(toAdd, inOutStart, length, controls);
343  }
344  void INCC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
345  {
346  engine->INCC(toAdd, start, length, carryIndex);
347  }
348  void INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
349  {
350  engine->INCS(toAdd, start, length, overflowIndex);
351  }
352  void INCSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
353  {
354  engine->INCSC(toAdd, start, length, overflowIndex, carryIndex);
355  }
356  void INCSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
357  {
358  engine->INCSC(toAdd, start, length, carryIndex);
359  }
360  void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
361  {
362  engine->DECC(toSub, start, length, carryIndex);
363  }
364  void DECSC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
365  {
366  engine->DECSC(toSub, start, length, overflowIndex, carryIndex);
367  }
368  void DECSC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
369  {
370  engine->DECSC(toSub, start, length, carryIndex);
371  }
372 #if ENABLE_BCD
373  void INCBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length) { engine->INCBCD(toAdd, start, length); }
374  void INCBCDC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
375  {
376  engine->INCBCDC(toAdd, start, length, carryIndex);
377  }
378  void DECBCDC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
379  {
380  engine->DECBCDC(toSub, start, length, carryIndex);
381  }
382 #endif
383  void MUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
384  {
385  engine->MUL(toMul, inOutStart, carryStart, length);
386  }
387  void DIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
388  {
389  engine->DIV(toDiv, inOutStart, carryStart, length);
390  }
391  void MULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
392  {
393  engine->MULModNOut(toMul, modN, inStart, outStart, length);
394  }
395  void IMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
396  {
397  engine->IMULModNOut(toMul, modN, inStart, outStart, length);
398  }
399  void POWModNOut(bitCapInt base, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
400  {
401  engine->POWModNOut(base, modN, inStart, outStart, length);
402  }
403  void CMUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
404  const std::vector<bitLenInt>& controls)
405  {
406  engine->CMUL(toMul, inOutStart, carryStart, length, controls);
407  }
408  void CDIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
409  const std::vector<bitLenInt>& controls)
410  {
411  engine->CDIV(toDiv, inOutStart, carryStart, length, controls);
412  }
413  void CMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length,
414  const std::vector<bitLenInt>& controls)
415  {
416  engine->CMULModNOut(toMul, modN, inStart, outStart, length, controls);
417  }
418  void CIMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length,
419  const std::vector<bitLenInt>& controls)
420  {
421  engine->CIMULModNOut(toMul, modN, inStart, outStart, length, controls);
422  }
423  void CPOWModNOut(bitCapInt base, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length,
424  const std::vector<bitLenInt>& controls)
425  {
426  engine->CPOWModNOut(base, modN, inStart, outStart, length, controls);
427  }
428 
429  bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
430  const unsigned char* values, bool resetValue = true)
431  {
432  return engine->IndexedLDA(indexStart, indexLength, valueStart, valueLength, values, resetValue);
433  }
434  bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
435  bitLenInt carryIndex, const unsigned char* values)
436  {
437  return engine->IndexedADC(indexStart, indexLength, valueStart, valueLength, carryIndex, values);
438  }
439  bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
440  bitLenInt carryIndex, const unsigned char* values)
441  {
442  return engine->IndexedSBC(indexStart, indexLength, valueStart, valueLength, carryIndex, values);
443  }
444  void Hash(bitLenInt start, bitLenInt length, const unsigned char* values) { engine->Hash(start, length, values); }
445 
446  void CPhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex)
447  {
448  engine->CPhaseFlipIfLess(greaterPerm, start, length, flagIndex);
449  }
450  void PhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt length)
451  {
452  engine->PhaseFlipIfLess(greaterPerm, start, length);
453  }
454 #endif
455 
456  void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->Swap(qubitIndex1, qubitIndex2); }
457  void ISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->ISwap(qubitIndex1, qubitIndex2); }
458  void IISwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->IISwap(qubitIndex1, qubitIndex2); }
459  void SqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->SqrtSwap(qubitIndex1, qubitIndex2); }
460  void ISqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2) { engine->ISqrtSwap(qubitIndex1, qubitIndex2); }
461  void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2)
462  {
463  engine->FSim(theta, phi, qubitIndex1, qubitIndex2);
464  }
465 
466  real1_f Prob(bitLenInt qubitIndex) { return engine->Prob(qubitIndex); }
467  real1_f CtrlOrAntiProb(bool controlState, bitLenInt control, bitLenInt target)
468  {
469  return engine->CtrlOrAntiProb(controlState, control, target);
470  }
471  real1_f ProbAll(bitCapInt fullRegister) { return engine->ProbAll(fullRegister); }
472  real1_f ProbMask(bitCapInt mask, bitCapInt permutation) { return engine->ProbMask(mask, permutation); }
473  real1_f ProbParity(bitCapInt mask) { return engine->ProbParity(mask); }
474  bool ForceMParity(bitCapInt mask, bool result, bool doForce = true)
475  {
476  return engine->ForceMParity(mask, result, doForce);
477  }
478 
479  real1_f SumSqrDiff(QInterfacePtr toCompare) { return SumSqrDiff(std::dynamic_pointer_cast<QHybrid>(toCompare)); }
481  {
482  toCompare->SwitchModes(isGpu, isPager);
483  return engine->SumSqrDiff(toCompare->engine);
484  }
485 
486  void UpdateRunningNorm(real1_f norm_thresh = REAL1_DEFAULT_ARG) { engine->UpdateRunningNorm(norm_thresh); }
488  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1_F)
489  {
490  engine->NormalizeState(nrm, norm_thresh, phaseArg);
491  }
492 
493  real1_f ExpectationBitsAll(const std::vector<bitLenInt>& bits, bitCapInt offset = 0)
494  {
495  return engine->ExpectationBitsAll(bits, offset);
496  }
497 
498  void Finish() { engine->Finish(); }
499 
500  bool isFinished() { return engine->isFinished(); }
501 
502  void Dump() { engine->Dump(); }
503 
505  {
506  QHybridPtr c = std::make_shared<QHybrid>(qubitCount, 0U, rand_generator, phaseFactor, doNormalize,
509  c->runningNorm = runningNorm;
510  c->SetConcurrency(GetConcurrencyLevel());
511  c->engine->CopyStateVec(engine);
512  return c;
513  }
514 
515  void SetDevice(int64_t dID)
516  {
517  devID = dID;
518  engine->SetDevice(dID);
519  }
520 
521  int64_t GetDevice() { return devID; }
522 
523  bitCapIntOcl GetMaxSize() { return engine->GetMaxSize(); };
524 
525 protected:
526  real1_f GetExpectation(bitLenInt valueStart, bitLenInt valueLength)
527  {
528  return engine->GetExpectation(valueStart, valueLength);
529  }
530 
531  void Apply2x2(bitCapIntOcl offset1, bitCapIntOcl offset2, const complex* mtrx, bitLenInt bitCount,
532  const bitCapIntOcl* qPowersSorted, bool doCalcNorm, real1_f norm_thresh = REAL1_DEFAULT_ARG)
533  {
534  engine->Apply2x2(offset1, offset2, mtrx, bitCount, qPowersSorted, doCalcNorm, norm_thresh);
535  }
536  void ApplyControlled2x2(const std::vector<bitLenInt>& controls, bitLenInt target, const complex* mtrx)
537  {
538  engine->ApplyControlled2x2(controls, target, mtrx);
539  }
540  void ApplyAntiControlled2x2(const std::vector<bitLenInt>& controls, bitLenInt target, const complex* mtrx)
541  {
542  engine->ApplyAntiControlled2x2(controls, target, mtrx);
543  }
544 
545 #if ENABLE_ALU
546  void INCDECC(bitCapInt toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
547  {
548  engine->INCDECC(toMod, inOutStart, length, carryIndex);
549  }
550  void INCDECSC(bitCapInt toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
551  {
552  engine->INCDECSC(toMod, inOutStart, length, carryIndex);
553  }
554  void INCDECSC(
555  bitCapInt toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
556  {
557  engine->INCDECSC(toMod, inOutStart, length, overflowIndex, carryIndex);
558  }
559 #if ENABLE_BCD
560  void INCDECBCDC(bitCapInt toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
561  {
562  engine->INCDECBCDC(toMod, inOutStart, length, carryIndex);
563  }
564 #endif
565 #endif
566 };
567 } // namespace Qrack
unsigned GetConcurrencyLevel()
Definition: parallel_for.hpp:38
Abstract QEngine implementation, for all "Schroedinger method" engines.
Definition: qengine.hpp:31
virtual void SetQubitCount(bitLenInt qb)
Definition: qengine.hpp:98
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".
bool useHostRam
Definition: qengine.hpp:36
virtual void ApplyM(bitCapInt qPower, bool result, complex nrm)
Definition: qengine.hpp:154
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:308
bitLenInt Compose(QHybridPtr toCopy)
Definition: qhybrid.hpp:182
void SetConcurrency(uint32_t threadCount)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qhybrid.hpp:76
void ISqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Inverse square root of Swap gate.
Definition: qhybrid.hpp:460
real1_f GetRunningNorm()
Get in-flight renormalization factor.
Definition: qhybrid.hpp:134
void SetQuantumState(const complex *inputState)
Set an arbitrary pure quantum state representation.
Definition: qhybrid.hpp:261
void MACMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary (anti-)control bits.
Definition: qhybrid.hpp:284
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:444
void GetAmplitudePage(complex *pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
Copy a "page" of amplitudes from this QEngine's internal state, into pagePtr.
Definition: qhybrid.hpp:147
void Dump()
If asynchronous work is still running, let the simulator know that it can be aborted.
Definition: qhybrid.hpp:502
real1_f CtrlOrAntiProb(bool controlState, bitLenInt control, bitLenInt target)
Definition: qhybrid.hpp:467
void MULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Multiplication modulo N by integer, (out of place)
Definition: qhybrid.hpp:391
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: qhybrid.hpp:474
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:172
bool useRDRAND
Definition: qhybrid.hpp:39
void ShuffleBuffers(QEnginePtr oEngine)
Swap the high half of this engine with the low half of another.
Definition: qhybrid.hpp:164
void CINC(bitCapInt toAdd, bitLenInt inOutStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Add integer (without sign, with controls)
Definition: qhybrid.hpp:340
void CMULModNOut(bitCapInt toMul, 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:413
void Mtrx(const complex *mtrx, bitLenInt qubitIndex)
Apply an arbitrary single bit unitary transformation.
Definition: qhybrid.hpp:271
real1_f ProbReg(bitLenInt start, bitLenInt length, bitCapInt permutation)
Direct measure of register permutation probability.
Definition: qhybrid.hpp:176
void PhaseFlipIfLess(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:450
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:429
void DECSC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract a classical integer from the register, with sign and with carry.
Definition: qhybrid.hpp:368
void INCBCDC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add classical BCD integer (without sign, with carry)
Definition: qhybrid.hpp:374
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:333
void CDIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled division by power of integer.
Definition: qhybrid.hpp:408
void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qhybrid.hpp:210
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:160
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:434
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: qhybrid.hpp:399
void ShuffleBuffers(QHybridPtr oEngine)
Definition: qhybrid.hpp:165
QEnginePtr engine
Definition: qhybrid.hpp:45
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: qhybrid.hpp:446
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:300
real1_f ProbMask(bitCapInt mask, bitCapInt permutation)
Direct measure of masked permutation probability.
Definition: qhybrid.hpp:472
void IMULModNOut(bitCapInt toMul, bitCapInt modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Inverse of multiplication modulo N by integer, (out of place)
Definition: qhybrid.hpp:395
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:299
void Dispose(bitLenInt start, bitLenInt length, bitCapInt disposedPerm)
Dispose a a contiguous set of qubits that are already in a permutation eigenstate.
Definition: qhybrid.hpp:226
real1_f Prob(bitLenInt qubitIndex)
Direct measure of bit probability to be in |1> state.
Definition: qhybrid.hpp:466
real1_f separabilityThreshold
Definition: qhybrid.hpp:43
void MUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Multiply by integer.
Definition: qhybrid.hpp:383
void SwitchGpuMode(bool useGpu)
Switches between CPU and GPU modes.
Definition: qhybrid.hpp:87
bitLenInt Allocate(bitLenInt start, bitLenInt length)
Allocate new "length" count of |0> state qubits at specified qubit index start position.
Definition: qhybrid.hpp:233
void Phase(complex topLeft, complex bottomRight, bitLenInt qubitIndex)
Apply a single bit transformation that only effects phase.
Definition: qhybrid.hpp:272
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:487
void SwitchModes(bool useGpu, bool usePager)
Definition: qhybrid.hpp:123
void SetQubitCount(bitLenInt qb)
Definition: qhybrid.hpp:56
int64_t devID
Definition: qhybrid.hpp:44
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:486
bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qhybrid.hpp:188
void Decompose(bitLenInt start, QHybridPtr dest)
Definition: qhybrid.hpp:215
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:320
bool isGpu
Definition: qhybrid.hpp:37
void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: qhybrid.hpp:339
real1_f GetExpectation(bitLenInt valueStart, bitLenInt valueLength)
Definition: qhybrid.hpp:526
void Apply2x2(bitCapIntOcl offset1, bitCapIntOcl offset2, const complex *mtrx, bitLenInt bitCount, const bitCapIntOcl *qPowersSorted, bool doCalcNorm, real1_f norm_thresh=REAL1_DEFAULT_ARG)
Definition: qhybrid.hpp:531
void INCDECSC(bitCapInt toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (with overflow flag)
Definition: qhybrid.hpp:554
void SetPermutation(bitCapInt perm, complex phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: qhybrid.hpp:266
void Finish()
If asynchronous work is still running, block until it finishes.
Definition: qhybrid.hpp:498
void DIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Divide by integer.
Definition: qhybrid.hpp:387
void DECBCDC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract BCD integer (without sign, with carry)
Definition: qhybrid.hpp:378
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:328
void INCSC(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:352
bool isSparse
Definition: qhybrid.hpp:40
void Invert(complex topRight, complex bottomLeft, bitLenInt qubitIndex)
Apply a single bit transformation that reverses bit probability and might effect phase.
Definition: qhybrid.hpp:276
void XMask(bitCapInt mask)
Masked X gate.
Definition: qhybrid.hpp:296
void ApplyAntiControlled2x2(const std::vector< bitLenInt > &controls, bitLenInt target, const complex *mtrx)
Definition: qhybrid.hpp:540
real1_f ExpectationBitsAll(const std::vector< bitLenInt > &bits, bitCapInt offset=0)
Get permutation expectation value of bits.
Definition: qhybrid.hpp:493
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:324
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:457
void MCMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: qhybrid.hpp:280
real1_f SumSqrDiff(QInterfacePtr toCompare)
Definition: qhybrid.hpp:479
std::vector< int64_t > deviceIDs
Definition: qhybrid.hpp:47
void INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add a classical integer to the register, with sign and without carry.
Definition: qhybrid.hpp:348
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:171
void SetAmplitudePage(QHybridPtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
Definition: qhybrid.hpp:155
bool isOpenCL()
Returns "true" if current simulation is OpenCL-based.
Definition: qhybrid.hpp:74
void ApplyM(bitCapInt regMask, bitCapInt result, complex nrm)
Definition: qhybrid.hpp:175
bool isPager
Definition: qhybrid.hpp:38
complex phaseFactor
Definition: qhybrid.hpp:46
void INCC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add integer (without sign, with carry)
Definition: qhybrid.hpp:344
bitLenInt ComposeNoClone(QHybridPtr toCopy)
Definition: qhybrid.hpp:199
bool TryDecompose(bitLenInt start, QInterfacePtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Definition: qhybrid.hpp:211
void SetAmplitude(bitCapInt perm, complex amp)
Sets the representational amplitude of a full permutation.
Definition: qhybrid.hpp:265
bool isFinished()
Returns "false" if asynchronous work is still running, and "true" if all previously dispatched asynch...
Definition: qhybrid.hpp:500
real1_f ProbParity(bitCapInt mask)
Overall probability of any odd permutation of the masked set of bits.
Definition: qhybrid.hpp:473
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:458
void INCSC(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:356
void SetDevice(int64_t dID)
Set GPU device ID.
Definition: qhybrid.hpp:515
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:461
void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qhybrid.hpp:263
bool TryDecompose(bitLenInt start, QHybridPtr dest, real1_f error_tol=TRYDECOMPOSE_EPSILON)
Definition: qhybrid.hpp:247
bitCapIntOcl GetMaxSize()
Definition: qhybrid.hpp:523
void CPOWModNOut(bitCapInt base, 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:423
void PhaseParity(real1_f radians, bitCapInt mask)
Parity phase gate.
Definition: qhybrid.hpp:297
void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Swap values of two bits in register.
Definition: qhybrid.hpp:456
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:221
void CUniformParityRZ(const std::vector< bitLenInt > &controls, 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:303
void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract classical integer (without sign, with carry)
Definition: qhybrid.hpp:360
bitLenInt gpuThresholdQubits
Definition: qhybrid.hpp:41
void INCDECSC(bitCapInt toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qhybrid.hpp:550
void AntiCSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a swap with arbitrary (anti) control bits.
Definition: qhybrid.hpp:312
QHybrid(bitLenInt qBitCount, bitCapInt initState=0U, qrack_rand_gen_ptr rgp=nullptr, 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=FP_NORM_EPSILON_F)
Definition: qhybrid.cpp:23
QEnginePtr MakeEngine(bool isOpenCL)
Definition: qhybrid.cpp:70
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:151
void SwitchPagerMode(bool usePager)
Switches between paged and non-paged modes.
Definition: qhybrid.hpp:109
complex GetAmplitude(bitCapInt perm)
Get the representational amplitude of a full permutation.
Definition: qhybrid.hpp:264
bool IsZeroAmplitude()
Returns "true" only if amplitudes are all totally 0.
Definition: qhybrid.hpp:138
real1_f ProbAll(bitCapInt fullRegister)
Direct measure of full permutation probability.
Definition: qhybrid.hpp:471
void CSqrtSwap(const std::vector< bitLenInt > &controls, bitLenInt qubit1, bitLenInt qubit2)
Apply a square root of swap with arbitrary control bits.
Definition: qhybrid.hpp:316
real1_f SumSqrDiff(QHybridPtr toCompare)
Definition: qhybrid.hpp:480
bitLenInt ComposeNoClone(QInterfacePtr toCopy)
Definition: qhybrid.hpp:205
void INCDECC(bitCapInt toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCC and DECC (without sign, with carry)
Definition: qhybrid.hpp:546
void ApplyControlled2x2(const std::vector< bitLenInt > &controls, bitLenInt target, const complex *mtrx)
Definition: qhybrid.hpp:536
void GetQuantumState(complex *outputState)
Get the pure quantum state representation.
Definition: qhybrid.hpp:262
void UniformParityRZ(bitCapInt mask, real1_f angle)
If the target qubit set parity is odd, this applies a phase factor of .
Definition: qhybrid.hpp:302
void CopyStateVec(QHybridPtr src)
Definition: qhybrid.hpp:141
void CopyStateVec(QEnginePtr src)
Exactly copy the state vector of a different QEngine instance.
Definition: qhybrid.hpp:140
QInterfacePtr Clone()
Clone this QInterface.
Definition: qhybrid.hpp:504
void UniformlyControlledSingleBit(const std::vector< bitLenInt > &controls, bitLenInt qubitIndex, const complex *mtrxs, const std::vector< bitCapInt > mtrxSkipPowers, bitCapInt mtrxSkipValueMask)
Definition: qhybrid.hpp:290
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:439
void ZeroAmplitudes()
Set all amplitudes to 0, and optionally temporarily deallocate state vector RAM.
Definition: qhybrid.hpp:136
bitLenInt pagerThresholdQubits
Definition: qhybrid.hpp:42
void SqrtSwap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Square root of Swap gate.
Definition: qhybrid.hpp:459
void CIMULModNOut(bitCapInt toMul, 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:418
void INCBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Add classical BCD integer (without sign)
Definition: qhybrid.hpp:373
void DECSC(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:364
void INCDECBCDC(bitCapInt toMod, bitLenInt inOutStart, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qhybrid.hpp:560
bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
Definition: qhybrid.hpp:195
QEnginePtr CloneEmpty()
Clone this QEngine's settings, with a zeroed state vector.
Definition: qhybrid.hpp:170
bitLenInt Compose(QHybridPtr toCopy, bitLenInt start)
Definition: qhybrid.hpp:189
int64_t GetDevice()
Get GPU device ID.
Definition: qhybrid.hpp:521
void CMUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication by integer.
Definition: qhybrid.hpp:403
virtual void SetConcurrency(uint32_t threadsPerEngine)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qinterface.hpp:249
real1 amplitudeFloor
Definition: qinterface.hpp:153
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:434
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:338
qrack_rand_gen_ptr rand_generator
Definition: qinterface.hpp:155
bool randGlobalPhase
Definition: qinterface.hpp:149
bitLenInt qubitCount
Definition: qinterface.hpp:151
bool doNormalize
Definition: qinterface.hpp:148
Half-precision floating-point type.
Definition: half.hpp:2222
virtual void UniformlyControlledSingleBit(const std::vector< bitLenInt > &controls, bitLenInt qubitIndex, const complex *mtrxs)
Apply a "uniformly controlled" arbitrary single bit unitary transformation.
Definition: qinterface.hpp:590
virtual void U(bitLenInt target, real1_f theta, real1_f phi, real1_f lambda)
General unitary gate.
Definition: rotational.cpp:18
Definition: complex16x2simd.hpp:25
std::complex< half_float::half > complex
Definition: qrack_types.hpp:62
@ QINTERFACE_CPU
Create a QEngineCPU leveraging only local CPU and memory resources.
Definition: qinterface.hpp:55
std::shared_ptr< QEngine > QEnginePtr
Definition: qrack_types.hpp:141
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:28
QRACK_CONST real1_f TRYDECOMPOSE_EPSILON
Definition: qrack_types.hpp:244
constexpr real1_f ZERO_R1_F
Definition: qrack_types.hpp:152
constexpr real1_f FP_NORM_EPSILON_F
Definition: qrack_types.hpp:245
const real1 REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:155
float real1_f
Definition: qrack_types.hpp:64
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:242
std::shared_ptr< QHybrid > QHybridPtr
Definition: qhybrid.hpp:28
const real1 REAL1_EPSILON
Definition: qrack_types.hpp:157
#define QRACK_GPU_ENGINE
Definition: qhybrid.hpp:23
#define bitLenInt
Definition: qrack_types.hpp:44
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:146
#define bitCapInt
Definition: qrack_types.hpp:105
#define bitCapIntOcl
Definition: qrack_types.hpp:91