Qrack  9.13
General classical-emulating-quantum development framework
qpager.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 #if ENABLE_OPENCL
16 #include "common/oclengine.hpp"
17 #endif
18 #if ENABLE_CUDA
19 #include "common/cudaengine.cuh"
20 #endif
21 
22 namespace Qrack {
23 
24 class QPager;
25 typedef std::shared_ptr<QPager> QPagerPtr;
26 
31 class QPager : public QEngine, public std::enable_shared_from_this<QPager> {
32 protected:
34  bool isSparse;
35  bool useTGadget;
40  int64_t devID;
45  std::vector<bool> devicesHostPointer;
46  std::vector<int64_t> deviceIDs;
47  std::vector<QInterfaceEngine> engines;
48  std::vector<QEnginePtr> qPages;
49 
51 
53  {
58  }
59 
61  {
62  bitCapInt toRet;
63  bi_div_mod_small(maxQPower, qPages.size(), &toRet, NULL);
64  return (bitCapIntOcl)toRet;
65  }
66  bitLenInt pagedQubitCount() { return log2Ocl(qPages.size()); }
68  int64_t GetPageDevice(bitCapIntOcl page) { return deviceIDs[page % deviceIDs.size()]; }
70 
71  void CombineEngines(bitLenInt thresholdBits);
73  void SeparateEngines(bitLenInt thresholdBits, bool noBaseFloor = false);
75 
76  template <typename Qubit1Fn>
77  void SingleBitGate(bitLenInt target, Qubit1Fn fn, bool isSqiCtrl = false, bool isAnti = false);
78  template <typename Qubit1Fn>
79  void MetaControlled(const bitCapInt& controlPerm, const std::vector<bitLenInt>& controls, bitLenInt target,
80  Qubit1Fn fn, const complex* mtrx, bool isSqiCtrl = false, bool isIntraCtrled = false);
81  template <typename Qubit1Fn>
82  void SemiMetaControlled(
83  const bitCapInt& controlPerm, std::vector<bitLenInt> controls, bitLenInt target, Qubit1Fn fn);
84  void MetaSwap(bitLenInt qubit1, bitLenInt qubit2, bool isIPhaseFac, bool isInverse);
85 
86  template <typename F> void CombineAndOp(F fn, std::vector<bitLenInt> bits);
87  template <typename F>
88  void CombineAndOpControlled(F fn, std::vector<bitLenInt> bits, const std::vector<bitLenInt>& controls);
89 
90  void ApplySingleEither(bool isInvert, const complex& top, const complex& bottom, bitLenInt target);
92  const bitCapInt& controlPerm, const std::vector<bitLenInt>& controls, bitLenInt target, const complex* mtrx);
93  void EitherISwap(bitLenInt qubit1, bitLenInt qubit2, bool isInverse);
94 
95  void Init();
96 
97  void GetSetAmplitudePage(complex* pagePtr, const complex* cPagePtr, bitCapIntOcl offset, bitCapIntOcl length);
98 
99  real1_f ExpVarBitsAll(bool isExp, const std::vector<bitLenInt>& bits, const bitCapInt& offset = ZERO_BCI);
100 
101  using QEngine::Copy;
102  void Copy(QInterfacePtr orig) { Copy(std::dynamic_pointer_cast<QPager>(orig)); }
103  void Copy(QPagerPtr orig)
104  {
105  QEngine::Copy(std::dynamic_pointer_cast<QEngine>(orig));
106  useGpuThreshold = orig->useGpuThreshold;
107  isSparse = orig->isSparse;
108  useTGadget = orig->useTGadget;
109  maxPageSetting = orig->maxPageSetting;
110  maxPageQubits = orig->maxPageQubits;
111  thresholdQubitsPerPage = orig->thresholdQubitsPerPage;
112  baseQubitsPerPage = orig->baseQubitsPerPage;
113  devID = orig->devID;
114  rootEngine = orig->rootEngine;
115  basePageMaxQPower = orig->basePageMaxQPower;
116  basePageCount = orig->basePageCount;
117  phaseFactor = orig->phaseFactor;
118  devicesHostPointer = orig->devicesHostPointer;
119  deviceIDs = orig->deviceIDs;
120  engines = orig->engines;
121  qPages = orig->qPages;
122  }
123 
124 public:
125  QPager(std::vector<QInterfaceEngine> eng, bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI,
126  qrack_rand_gen_ptr rgp = nullptr, const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false,
127  bool ignored = false, bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true,
128  bool useSparseStateVec = false, real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {},
129  bitLenInt qubitThreshold = 0U, real1_f separation_thresh = _qrack_qunit_sep_thresh);
130 
131  QPager(bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI, qrack_rand_gen_ptr rgp = nullptr,
132  const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool ignored = false, bool useHostMem = false,
133  int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
134  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {}, bitLenInt qubitThreshold = 0U,
135  real1_f separation_thresh = _qrack_qunit_sep_thresh)
136 #if ENABLE_OPENCL
137  : QPager({ OCLEngine::Instance().GetDeviceCount() ? QINTERFACE_OPENCL : QINTERFACE_CPU }, qBitCount, initState,
138  rgp, phaseFac, doNorm, ignored, useHostMem, deviceId, useHardwareRNG, useSparseStateVec, norm_thresh,
139  devList, qubitThreshold, separation_thresh)
140 #elif ENABLE_CUDA
141  : QPager({ CUDAEngine::Instance().GetDeviceCount() ? QINTERFACE_CUDA : QINTERFACE_CPU }, qBitCount, initState,
142  rgp, phaseFac, doNorm, ignored, useHostMem, deviceId, useHardwareRNG, useSparseStateVec, norm_thresh,
143  devList, qubitThreshold, separation_thresh)
144 #else
145  : QPager({ QINTERFACE_CPU }, qBitCount, initState, rgp, phaseFac, doNorm, ignored, useHostMem, deviceId,
146  useHardwareRNG, useSparseStateVec, norm_thresh, devList, qubitThreshold, separation_thresh)
147 #endif
148  {
149  }
150 
151  QPager(QEnginePtr enginePtr, std::vector<QInterfaceEngine> eng, bitLenInt qBitCount,
152  const bitCapInt& ignored = ZERO_BCI, qrack_rand_gen_ptr rgp = nullptr,
153  const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool ignored2 = false,
154  bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
155  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {}, bitLenInt qubitThreshold = 0U,
156  real1_f separation_thresh = _qrack_qunit_sep_thresh);
157 
158  void SetConcurrency(uint32_t threadsPerEngine)
159  {
160  QInterface::SetConcurrency(threadsPerEngine);
161  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
162  qPages[i]->SetConcurrency(threadsPerEngine);
163  }
164  }
165  void SetTInjection(bool useGadget)
166  {
167  useTGadget = useGadget;
168  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
169  qPages[i]->SetTInjection(useTGadget);
170  }
171  }
172  bool GetTInjection() { return useTGadget; }
173  bool isOpenCL() { return qPages[0U]->isOpenCL(); }
174 
176  {
177  CombineEngines();
178  return qPages[0U];
179  }
180 
182  {
183  qPages.resize(1U);
184  qPages[0U] = eng;
185  eng->SetDevice(deviceIDs[0]);
186  SeparateEngines();
187  }
188 
190  {
191  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
192  qPages[i]->ZeroAmplitudes();
193  }
194  }
195  void CopyStateVec(QEnginePtr src) { CopyStateVec(std::dynamic_pointer_cast<QPager>(src)); }
197  {
198  bitLenInt qpp = qubitsPerPage();
199  src->CombineEngines(qpp);
200  src->SeparateEngines(qpp, true);
201 
202  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
203  qPages[i]->CopyStateVec(src->qPages[i]);
204  }
205  }
207  {
208  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
209  if (!qPages[i]->IsZeroAmplitude()) {
210  return false;
211  }
212  }
213 
214  return true;
215  }
216  void GetAmplitudePage(complex* pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
217  {
218  GetSetAmplitudePage(pagePtr, NULL, offset, length);
219  }
220  void SetAmplitudePage(const complex* pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
221  {
222  GetSetAmplitudePage(NULL, pagePtr, offset, length);
223  }
224  void SetAmplitudePage(QEnginePtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
225  {
226  SetAmplitudePage(std::dynamic_pointer_cast<QPager>(pageEnginePtr), srcOffset, dstOffset, length);
227  }
228  void SetAmplitudePage(QPagerPtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
229  {
230  CombineEngines();
231  pageEnginePtr->CombineEngines();
232  qPages[0U]->SetAmplitudePage(pageEnginePtr->qPages[0U], srcOffset, dstOffset, length);
233  }
234  void ShuffleBuffers(QEnginePtr engine) { ShuffleBuffers(std::dynamic_pointer_cast<QPager>(engine)); }
236  {
237  bitLenInt qpp = qubitsPerPage();
238  bitLenInt tcqpp = engine->qubitsPerPage();
239  engine->SeparateEngines(qpp, true);
240  SeparateEngines(tcqpp, true);
241 
242  if (qPages.size() == 1U) {
243  qPages[0U]->ShuffleBuffers(engine->qPages[0U]);
244  return;
245  }
246 
247  const bitCapIntOcl offset = qPages.size() >> 1U;
248  for (bitCapIntOcl i = 0U; i < offset; ++i) {
249  qPages[offset + i].swap(engine->qPages[i]);
250  }
251  }
253  void QueueSetDoNormalize(bool doNorm)
254  {
255  Finish();
256  doNormalize = doNorm;
257  }
258  void QueueSetRunningNorm(real1_f runningNrm)
259  {
260  Finish();
261  runningNorm = runningNrm;
262  }
263  real1_f ProbReg(bitLenInt start, bitLenInt length, const bitCapInt& permutation)
264  {
265  CombineEngines();
266  return qPages[0U]->ProbReg(start, length, permutation);
267  }
268  using QEngine::ApplyM;
269  void ApplyM(const bitCapInt& regMask, const bitCapInt& result, const complex& nrm)
270  {
271  CombineEngines();
272  return qPages[0U]->ApplyM(regMask, result, nrm);
273  }
274  real1_f GetExpectation(bitLenInt valueStart, bitLenInt valueLength)
275  {
276  CombineEngines();
277  return qPages[0U]->GetExpectation(valueStart, valueLength);
278  }
279  void Apply2x2(bitCapIntOcl offset1, bitCapIntOcl offset2, const complex* mtrx, bitLenInt bitCount,
280  const bitCapIntOcl* qPowersSorted, bool doCalcNorm, real1_f norm_thresh = REAL1_DEFAULT_ARG)
281  {
282  CombineEngines();
283  qPages[0U]->Apply2x2(offset1, offset2, mtrx, bitCount, qPowersSorted, doCalcNorm, norm_thresh);
284  }
286  {
287  real1_f toRet = ZERO_R1_F;
288  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
289  toRet += qPages[i]->GetRunningNorm();
290  }
291 
292  return toRet;
293  }
294 
296  {
297  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
298  if (!qPages[i]->IsZeroAmplitude()) {
299  return qPages[i]->FirstNonzeroPhase();
300  }
301  }
302 
303  return ZERO_R1_F;
304  }
305 
306  void SetQuantumState(const complex* inputState);
307  void GetQuantumState(complex* outputState);
308  void GetProbs(real1* outputProbs);
310  {
311  bitCapInt p, a;
312  bi_div_mod(perm, pageMaxQPower(), &p, &a);
313  return qPages[(bitCapIntOcl)p]->GetAmplitude(a);
314  }
315  void SetAmplitude(const bitCapInt& perm, const complex& amp)
316  {
317  bitCapInt p, a;
318  bi_div_mod(perm, pageMaxQPower(), &p, &a);
319  qPages[(bitCapIntOcl)p]->SetAmplitude(a, amp);
320  }
321  real1_f ProbAll(const bitCapInt& perm)
322  {
323  bitCapInt p, a;
324  bi_div_mod(perm, pageMaxQPower(), &p, &a);
325  return qPages[(bitCapIntOcl)p]->ProbAll(a);
326  }
327 
328  void SetPermutation(const bitCapInt& perm, const complex& phaseFac = CMPLX_DEFAULT_ARG);
329 
330  using QEngine::Compose;
331  bitLenInt Compose(QPagerPtr toCopy) { return ComposeEither(toCopy, false); }
332  bitLenInt Compose(QInterfacePtr toCopy) { return Compose(std::dynamic_pointer_cast<QPager>(toCopy)); }
333  bitLenInt ComposeNoClone(QPagerPtr toCopy) { return ComposeEither(toCopy, true); }
334  bitLenInt ComposeNoClone(QInterfacePtr toCopy) { return ComposeNoClone(std::dynamic_pointer_cast<QPager>(toCopy)); }
335  bitLenInt ComposeEither(QPagerPtr toCopy, bool willDestroy);
336  void Decompose(bitLenInt start, QInterfacePtr dest) { Decompose(start, std::dynamic_pointer_cast<QPager>(dest)); }
337  void Decompose(bitLenInt start, QPagerPtr dest);
339  void Dispose(bitLenInt start, bitLenInt length);
340  void Dispose(bitLenInt start, bitLenInt length, const bitCapInt& disposedPerm);
341  using QEngine::Allocate;
342  bitLenInt Allocate(bitLenInt start, bitLenInt length);
343 
344  void Mtrx(const complex* mtrx, bitLenInt target);
345  void Phase(const complex& topLeft, const complex& bottomRight, bitLenInt qubitIndex)
346  {
347  ApplySingleEither(false, topLeft, bottomRight, qubitIndex);
348  }
349  void Invert(const complex& topRight, const complex& bottomLeft, bitLenInt qubitIndex)
350  {
351  ApplySingleEither(true, topRight, bottomLeft, qubitIndex);
352  }
353  void MCMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
354  {
355  if (qPages.size() == 1U) {
356  qPages[0U]->MCMtrx(controls, mtrx, target);
357  return;
358  }
359  bitCapInt p = pow2(controls.size());
360  bi_decrement(&p, 1U);
361  ApplyEitherControlledSingleBit(p, controls, target, mtrx);
362  }
363  void MACMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
364  {
365  if (qPages.size() == 1U) {
366  qPages[0U]->MACMtrx(controls, mtrx, target);
367  return;
368  }
369  ApplyEitherControlledSingleBit(ZERO_BCI, controls, target, mtrx);
370  }
371 
372  void UniformParityRZ(const bitCapInt& mask, real1_f angle);
373  void CUniformParityRZ(const std::vector<bitLenInt>& controls, const bitCapInt& mask, real1_f angle);
374 
375  void XMask(const bitCapInt& mask);
376  void ZMask(const bitCapInt& mask) { PhaseParity(PI_R1, mask); }
377  void PhaseParity(real1_f radians, const bitCapInt& mask);
378 
379  bool ForceM(bitLenInt qubit, bool result, bool doForce = true, bool doApply = true);
381  bitLenInt start, bitLenInt length, const bitCapInt& result, bool doForce = true, bool doApply = true)
382  {
383  // Don't use QEngine::ForceMReg().
384  return QInterface::ForceMReg(start, length, result, doForce, doApply);
385  }
386 
387 #if ENABLE_ALU
388  void INCDECSC(
389  const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex);
390  void INCDECSC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
391 #if ENABLE_BCD
392  void INCBCD(const bitCapInt& toAdd, bitLenInt start, bitLenInt length);
393  void INCDECBCDC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
394 #endif
395  void MUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length);
396  void DIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length);
397  void MULModNOut(
398  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length);
399  void IMULModNOut(
400  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length);
401  void POWModNOut(
402  const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length);
403  void CMUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
404  const std::vector<bitLenInt>& controls);
405  void CDIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
406  const std::vector<bitLenInt>& controls);
407  void CMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
408  bitLenInt length, const std::vector<bitLenInt>& controls);
409  void CIMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
410  bitLenInt length, const std::vector<bitLenInt>& controls);
411  void CPOWModNOut(const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
412  bitLenInt length, const std::vector<bitLenInt>& controls);
413 
414  bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
415  const unsigned char* values, bool resetValue = true);
416  bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
417  bitLenInt carryIndex, const unsigned char* values);
418  bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
419  bitLenInt carryIndex, const unsigned char* values);
420  void Hash(bitLenInt start, bitLenInt length, const unsigned char* values);
421 
422  void CPhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex);
423  void PhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length);
424 #endif
425 
426  void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2);
427  void ISwap(bitLenInt qubit1, bitLenInt qubit2) { EitherISwap(qubit1, qubit2, false); }
428  void IISwap(bitLenInt qubit1, bitLenInt qubit2) { EitherISwap(qubit1, qubit2, true); }
429  void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2);
430 
431  real1_f Prob(bitLenInt qubitIndex);
432  real1_f ProbMask(const bitCapInt& mask, const bitCapInt& permutation);
433  // TODO: QPager not yet used in Q#, but this would need a real implementation:
435  {
436  if (bi_compare_0(mask) == 0) {
437  return ZERO_R1_F;
438  }
439 
440  CombineEngines();
441  return qPages[0U]->ProbParity(mask);
442  }
443  bool ForceMParity(const bitCapInt& mask, bool result, bool doForce = true)
444  {
445  if (bi_compare_0(mask) == 0) {
446  return ZERO_R1_F;
447  }
448 
449  CombineEngines();
450  return qPages[0U]->ForceMParity(mask, result, doForce);
451  }
452 
453  void UpdateRunningNorm(real1_f norm_thresh = REAL1_DEFAULT_ARG);
454  void NormalizeState(
455  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1_F);
456 
457  void Finish()
458  {
459  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
460  qPages[i]->Finish();
461  }
462  };
463 
464  bool isFinished()
465  {
466  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
467  if (!qPages[i]->isFinished()) {
468  return false;
469  }
470  }
471 
472  return true;
473  };
474 
475  void Dump()
476  {
477  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
478  qPages[i]->Dump();
479  }
480  };
481 
484 
485  void SetDevice(int64_t dID)
486  {
487  deviceIDs.clear();
488  deviceIDs.push_back(dID);
489 
490  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
491  qPages[i]->SetDevice(dID);
492  }
493 
494 #if ENABLE_OPENCL || ENABLE_CUDA
495  if (rootEngine != QINTERFACE_CPU) {
496 #if ENABLE_OPENCL
497  maxPageQubits =
498  log2Ocl(OCLEngine::Instance().GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
499 #else
500  maxPageQubits =
501  log2Ocl(CUDAEngine::Instance().GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
502 #endif
505  }
506  }
507 
508  if (!useGpuThreshold) {
509  return;
510  }
511 
512  // Limit at the power of 2 less-than-or-equal-to a full max memory allocation segment, or choose with
513  // environment variable.
515 #endif
516  }
517 
518  int64_t GetDevice() { return qPages[0U]->GetDevice(); }
519 
520  bitCapIntOcl GetMaxSize() { return qPages[0U]->GetMaxSize(); };
521 
522  real1_f SumSqrDiff(QInterfacePtr toCompare) { return SumSqrDiff(std::dynamic_pointer_cast<QPager>(toCompare)); }
523 
524  real1_f SumSqrDiff(QPagerPtr toCompare);
525 };
526 } // namespace Qrack
void bi_decrement(BigInteger *pBigInt, const BIG_INTEGER_WORD &value)
Definition: big_integer.hpp:229
void bi_div_mod_small(const BigInteger &left, BIG_INTEGER_HALF_WORD right, BigInteger *quotient, BIG_INTEGER_HALF_WORD *rmndr)
"Schoolbook division" (on half words) Complexity - O(x^2)
Definition: big_integer.cpp:179
int bi_compare_0(const BigInteger &left)
Definition: big_integer.hpp:134
void bi_div_mod(const BigInteger &left, const BigInteger &right, BigInteger *quotient, BigInteger *rmndr)
Adapted from Qrack! (The fundamental algorithm was discovered before.) Complexity - O(log)
Definition: big_integer.cpp:218
int GetDeviceCount()
Get the count of devices in the current list.
Definition: oclengine.hpp:294
static OCLEngine & Instance()
Get a pointer to the Instance of the singleton. (The instance will be instantiated,...
Definition: oclengine.hpp:250
Abstract QEngine implementation, for all "Schroedinger method" engines.
Definition: qengine.hpp:31
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:165
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 FSim(real1_f theta, real1_f phi, bitLenInt qubit1, bitLenInt qubit2)=0
The 2-qubit "fSim" gate, (useful in the simulation of particles with fermionic statistics)
virtual void Decompose(bitLenInt start, QInterfacePtr dest)=0
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
virtual void Swap(bitLenInt qubit1, bitLenInt qubit2)
Swap values of two bits in register.
Definition: gates.cpp:167
bitCapInt maxQPower
Definition: qinterface.hpp:149
virtual void SetConcurrency(uint32_t threadsPerEngine)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qinterface.hpp:275
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:470
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:364
virtual void SetQubitCount(bitLenInt qb)
Definition: qinterface.hpp:268
bitLenInt qubitCount
Definition: qinterface.hpp:146
bool doNormalize
Definition: qinterface.hpp:143
A "Qrack::QPager" splits a "Qrack::QEngine" implementation into equal-length "pages....
Definition: qpager.hpp:31
void SetQubitCount(bitLenInt qb)
Definition: qpager.hpp:52
QInterfacePtr Clone()
Clone this QInterface.
Definition: qpager.cpp:1604
void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qpager.cpp:886
void CombineAndOp(F fn, std::vector< bitLenInt > bits)
Definition: qpager.cpp:594
void Dump()
If asynchronous work is still running, let the simulator know that it can be aborted.
Definition: qpager.hpp:475
void MULModNOut(const bitCapInt &toMul, const bitCapInt &modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length)
Multiplication modulo N by integer, (out of place)
Definition: qpager.cpp:1190
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: qpager.cpp:1276
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: qpager.cpp:1299
void CombineEngines()
Definition: qpager.hpp:72
bool isFinished()
Returns "false" if asynchronous work is still running, and "true" if all previously dispatched asynch...
Definition: qpager.hpp:464
QInterfacePtr Copy()
Copy this QInterface.
Definition: qpager.cpp:1634
bitCapIntOcl GetMaxSize()
Definition: qpager.hpp:520
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: qpager.cpp:1294
bitLenInt pagedQubitCount()
Definition: qpager.hpp:66
bitCapIntOcl basePageMaxQPower
Definition: qpager.hpp:42
real1_f ProbParity(const bitCapInt &mask)
Overall probability of any odd permutation of the masked set of bits.
Definition: qpager.hpp:434
real1_f ProbAll(const bitCapInt &perm)
Direct measure of full permutation probability.
Definition: qpager.hpp:321
bitLenInt thresholdQubitsPerPage
Definition: qpager.hpp:38
QPager(bitLenInt qBitCount, const bitCapInt &initState=ZERO_BCI, qrack_rand_gen_ptr rgp=nullptr, const complex &phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool ignored=false, 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 separation_thresh=_qrack_qunit_sep_thresh)
Definition: qpager.hpp:131
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: qpager.hpp:363
void DIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Divide by integer.
Definition: qpager.cpp:1185
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: qpager.cpp:1587
void CopyStateVec(QPagerPtr src)
Definition: qpager.hpp:196
void Init()
Definition: qpager.cpp:89
void Mtrx(const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation.
Definition: qpager.cpp:940
real1_f ProbMask(const bitCapInt &mask, const bitCapInt &permutation)
Direct measure of masked permutation probability.
Definition: qpager.cpp:1523
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: qpager.cpp:1256
void MUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Multiply by integer.
Definition: qpager.cpp:1180
real1_f ProbReg(bitLenInt start, bitLenInt length, const bitCapInt &permutation)
Direct measure of register permutation probability.
Definition: qpager.hpp:263
bitCapIntOcl pageMaxQPower()
Definition: qpager.hpp:60
void SemiMetaControlled(const bitCapInt &controlPerm, std::vector< bitLenInt > controls, bitLenInt target, Qubit1Fn fn)
Definition: qpager.cpp:562
void Dispose(bitLenInt start, bitLenInt length)
Minimally decompose a set of contiguous bits from the separably composed unit, and discard the separa...
Definition: qpager.cpp:756
void SetAmplitude(const bitCapInt &perm, const complex &amp)
Sets the representational amplitude of a full permutation.
Definition: qpager.hpp:315
bitCapIntOcl basePageCount
Definition: qpager.hpp:43
void XMask(const bitCapInt &mask)
Masked X gate.
Definition: qpager.cpp:1057
void ApplyEitherControlledSingleBit(const bitCapInt &controlPerm, const std::vector< bitLenInt > &controls, bitLenInt target, const complex *mtrx)
Definition: qpager.cpp:997
void SetQuantumState(const complex *inputState)
Set an arbitrary pure quantum state representation.
Definition: qpager.cpp:810
void QueueSetDoNormalize(bool doNorm)
Add an operation to the (OpenCL) queue, to set the value of doNormalize, which controls whether to au...
Definition: qpager.hpp:253
void CMUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication by integer.
Definition: qpager.cpp:1208
void SetAmplitudePage(QPagerPtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
Definition: qpager.hpp:228
void SetAmplitudePage(const complex *pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
Copy a "page" of amplitudes from pagePtr into this QEngine's internal state.
Definition: qpager.hpp:220
void ShuffleBuffers(QPagerPtr engine)
Definition: qpager.hpp:235
void GetSetAmplitudePage(complex *pagePtr, const complex *cPagePtr, bitCapIntOcl offset, bitCapIntOcl length)
Definition: qpager.cpp:295
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: qpager.hpp:443
real1_f GetExpectation(bitLenInt valueStart, bitLenInt valueLength)
Definition: qpager.hpp:274
void EitherISwap(bitLenInt qubit1, bitLenInt qubit2, bool isInverse)
Definition: qpager.cpp:1367
void GetQuantumState(complex *outputState)
Get the pure quantum state representation.
Definition: qpager.cpp:851
void Apply2x2(bitCapIntOcl offset1, bitCapIntOcl offset2, const complex *mtrx, bitLenInt bitCount, const bitCapIntOcl *qPowersSorted, bool doCalcNorm, real1_f norm_thresh=REAL1_DEFAULT_ARG)
Definition: qpager.hpp:279
real1_f FirstNonzeroPhase()
Get phase of lowest permutation nonzero amplitude.
Definition: qpager.hpp:295
bool isSparse
Definition: qpager.hpp:34
void SetTInjection(bool useGadget)
Set the option to use T-injection gadgets (off by default)
Definition: qpager.hpp:165
void INCDECSC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (with overflow flag)
Definition: qpager.cpp:1157
void UniformParityRZ(const bitCapInt &mask, real1_f angle)
If the target qubit set parity is odd, this applies a phase factor of .
Definition: qpager.cpp:1046
void MCMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: qpager.hpp:353
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: qpager.cpp:1269
void Copy(QInterfacePtr orig)
Definition: qpager.hpp:102
void SingleBitGate(bitLenInt target, Qubit1Fn fn, bool isSqiCtrl=false, bool isAnti=false)
Definition: qpager.cpp:370
void SetConcurrency(uint32_t threadsPerEngine)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qpager.hpp:158
void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qpager.hpp:336
std::vector< QInterfaceEngine > engines
Definition: qpager.hpp:47
QEnginePtr CloneEmpty()
Clone this QEngine's settings, with a zeroed state vector.
Definition: qpager.cpp:1619
QEnginePtr ReleaseEngine()
Definition: qpager.hpp:175
bitLenInt Compose(QPagerPtr toCopy)
Definition: qpager.hpp:331
real1_f ExpVarBitsAll(bool isExp, const std::vector< bitLenInt > &bits, const bitCapInt &offset=ZERO_BCI)
Definition: qpager.cpp:1534
bool GetTInjection()
Get the option to use T-injection gadgets.
Definition: qpager.hpp:172
complex phaseFactor
Definition: qpager.hpp:44
void CDIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled division by power of integer.
Definition: qpager.cpp:1220
real1_f SumSqrDiff(QInterfacePtr toCompare)
Calculates (1 - <\psi_e|\psi_c>) between states |\psi_c> and |\psi_e>.
Definition: qpager.hpp:522
bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qpager.hpp:332
void SeparateEngines()
Definition: qpager.hpp:74
void ZMask(const bitCapInt &mask)
Masked Z gate.
Definition: qpager.hpp:376
QInterfaceEngine rootEngine
Definition: qpager.hpp:41
int64_t devID
Definition: qpager.hpp:40
void SetPermutation(const bitCapInt &perm, const complex &phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: qpager.cpp:921
bitLenInt ComposeNoClone(QPagerPtr toCopy)
Definition: qpager.hpp:333
void SetDevice(int64_t dID)
Set GPU device ID.
Definition: qpager.hpp:485
QPager(std::vector< QInterfaceEngine > eng, bitLenInt qBitCount, const bitCapInt &initState=ZERO_BCI, qrack_rand_gen_ptr rgp=nullptr, const complex &phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool ignored=false, 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 separation_thresh=_qrack_qunit_sep_thresh)
Definition: qpager.cpp:33
void CopyStateVec(QEnginePtr src)
Exactly copy the state vector of a different QEngine instance.
Definition: qpager.hpp:195
complex GetAmplitude(const bitCapInt &perm)
Get the representational amplitude of a full permutation.
Definition: qpager.hpp:309
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: qpager.cpp:1282
void Copy(QPagerPtr orig)
Definition: qpager.hpp:103
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: qpager.cpp:1232
void IISwap(bitLenInt qubit1, bitLenInt qubit2)
Inverse ISwap - Swap values of two bits in register, and apply phase factor of -i if bits are differe...
Definition: qpager.hpp:428
bitLenInt Allocate(bitLenInt start, bitLenInt length)
Allocate new "length" count of |0> state qubits at specified qubit index start position.
Definition: qpager.cpp:798
bitLenInt baseQubitsPerPage
Definition: qpager.hpp:39
std::vector< bool > devicesHostPointer
Definition: qpager.hpp:45
void ISwap(bitLenInt qubit1, bitLenInt qubit2)
Swap values of two bits in register, and apply phase factor of i if bits are different.
Definition: qpager.hpp:427
real1_f GetRunningNorm()
Get in-flight renormalization factor.
Definition: qpager.hpp:285
int64_t GetDevice()
Get GPU device ID.
Definition: qpager.hpp:518
void LockEngine(QEnginePtr eng)
Definition: qpager.hpp:181
QEnginePtr MakeEngine(bitLenInt length, bitCapIntOcl pageId)
Definition: qpager.cpp:284
void Finish()
If asynchronous work is still running, block until it finishes.
Definition: qpager.hpp:457
bool GetPageHostPointer(bitCapIntOcl page)
Definition: qpager.hpp:69
void Hash(bitLenInt start, bitLenInt length, const unsigned char *values)
Transform a length of qubit register via lookup through a hash table.
Definition: qpager.cpp:1288
bitLenInt maxPageQubits
Definition: qpager.hpp:37
void ApplyM(const bitCapInt &regMask, const bitCapInt &result, const complex &nrm)
Definition: qpager.hpp:269
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: qpager.hpp:224
bitLenInt ComposeEither(QPagerPtr toCopy, bool willDestroy)
Definition: qpager.cpp:620
bitLenInt qubitsPerPage()
Definition: qpager.hpp:67
void PhaseParity(real1_f radians, const bitCapInt &mask)
Parity phase gate.
Definition: qpager.cpp:1076
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: qpager.cpp:1580
real1_f Prob(bitLenInt qubitIndex)
Direct measure of bit probability to be in |1> state.
Definition: qpager.cpp:1452
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: qpager.cpp:1051
void ShuffleBuffers(QEnginePtr engine)
Swap the high half of this engine with the low half of another.
Definition: qpager.hpp:234
std::vector< QEnginePtr > qPages
Definition: qpager.hpp:48
void CombineAndOpControlled(F fn, std::vector< bitLenInt > bits, const std::vector< bitLenInt > &controls)
Definition: qpager.cpp:611
int64_t GetPageDevice(bitCapIntOcl page)
Definition: qpager.hpp:68
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: qpager.cpp:1244
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: qpager.cpp:1196
bool useGpuThreshold
Definition: qpager.hpp:33
bool IsZeroAmplitude()
Returns "true" only if amplitudes are all totally 0.
Definition: qpager.hpp:206
void ApplySingleEither(bool isInvert, const complex &top, const complex &bottom, bitLenInt target)
Definition: qpager.cpp:953
bitLenInt ComposeNoClone(QInterfacePtr toCopy)
This is a variant of Compose() for a toCopy argument that will definitely not be reused once "Compose...
Definition: qpager.hpp:334
void Phase(const complex &topLeft, const complex &bottomRight, bitLenInt qubitIndex)
Apply a single bit transformation that only effects phase.
Definition: qpager.hpp:345
void GetAmplitudePage(complex *pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
Copy a "page" of amplitudes from this QEngine's internal state, into pagePtr.
Definition: qpager.hpp:216
void ZeroAmplitudes()
Set all amplitudes to 0, and optionally temporarily deallocate state vector RAM.
Definition: qpager.hpp:189
void QueueSetRunningNorm(real1_f runningNrm)
Add an operation to the (OpenCL) queue, to set the value of runningNorm, which is the normalization c...
Definition: qpager.hpp:258
bool isOpenCL()
Returns "true" if current simulation is OpenCL-based.
Definition: qpager.hpp:173
void MetaSwap(bitLenInt qubit1, bitLenInt qubit2, bool isIPhaseFac, bool isInverse)
Definition: qpager.cpp:1306
bitLenInt maxPageSetting
Definition: qpager.hpp:36
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: qpager.cpp:1104
std::vector< int64_t > deviceIDs
Definition: qpager.hpp:46
bitCapInt ForceMReg(bitLenInt start, bitLenInt length, const bitCapInt &result, bool doForce=true, bool doApply=true)
Measure permutation state of a register.
Definition: qpager.hpp:380
bool useTGadget
Definition: qpager.hpp:35
void INCBCD(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add classical BCD integer (without sign)
Definition: qpager.cpp:1169
void INCDECBCDC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qpager.cpp:1174
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: qpager.cpp:1202
void MetaControlled(const bitCapInt &controlPerm, const std::vector< bitLenInt > &controls, bitLenInt target, Qubit1Fn fn, const complex *mtrx, bool isSqiCtrl=false, bool isIntraCtrled=false)
Definition: qpager.cpp:452
void Invert(const complex &topRight, const complex &bottomLeft, bitLenInt qubitIndex)
Apply a single bit transformation that reverses bit probability and might effect phase.
Definition: qpager.hpp:349
Half-precision floating-point type.
Definition: half.hpp:2222
virtual void U(bitLenInt target, real1_f theta, real1_f phi, real1_f lambda)
General unitary gate.
Definition: rotational.cpp:18
virtual bitCapInt ForceMReg(bitLenInt start, bitLenInt length, const bitCapInt &result, bool doForce=true, bool doApply=true)
Act as if is a measurement was applied, except force the (usually random) result.
Definition: qinterface.cpp:215
GLOSSARY: bitLenInt - "bit-length integer" - unsigned integer ID of qubit position in register bitCap...
Definition: complex16x2simd.hpp:25
QInterfaceEngine
Enumerated list of supported engines.
Definition: qinterface.hpp:37
@ QINTERFACE_CUDA
Create a QEngineCUDA, leveraging CUDA hardware to increase the speed of certain calculations.
Definition: qinterface.hpp:52
@ QINTERFACE_OPENCL
Create a QEngineOCL, leveraging OpenCL hardware to increase the speed of certain calculations.
Definition: qinterface.hpp:47
@ 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:151
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:29
const real1_f _qrack_qunit_sep_thresh
Definition: qrack_functions.hpp:235
bitLenInt log2Ocl(bitCapIntOcl n)
Definition: qrack_functions.hpp:88
std::complex< real1 > complex
Definition: qrack_types.hpp:128
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:136
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:200
float real1_f
Definition: qrack_types.hpp:95
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:257
std::shared_ptr< QPager > QPagerPtr
Definition: qpager.hpp:24
QRACK_CONST real1 PI_R1
Definition: qrack_types.hpp:178
const bitCapInt ZERO_BCI
Definition: qrack_types.hpp:130
bitCapIntOcl pow2Ocl(const bitLenInt &p)
Definition: qrack_functions.hpp:137
#define REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:177
#define bitLenInt
Definition: qrack_types.hpp:38
#define ZERO_R1_F
Definition: qrack_types.hpp:160
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:156
#define bitCapInt
Definition: qrack_types.hpp:62
#define bitCapIntOcl
Definition: qrack_types.hpp:50