Qrack  9.9
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;
41  int64_t devID;
46  std::vector<bool> devicesHostPointer;
47  std::vector<int64_t> deviceIDs;
48  std::vector<QInterfaceEngine> engines;
49  std::vector<QEnginePtr> qPages;
50 
52 
54  {
59  }
60 
62  {
63  bitCapInt toRet;
64  bi_div_mod_small(maxQPower, qPages.size(), &toRet, NULL);
65  return (bitCapIntOcl)toRet;
66  }
67  bitLenInt pagedQubitCount() { return log2Ocl(qPages.size()); }
69  int64_t GetPageDevice(bitCapIntOcl page) { return deviceIDs[page % deviceIDs.size()]; }
71 
72  void CombineEngines(bitLenInt thresholdBits);
74  void SeparateEngines(bitLenInt thresholdBits, bool noBaseFloor = false);
76 
77  template <typename Qubit1Fn>
78  void SingleBitGate(bitLenInt target, Qubit1Fn fn, bool isSqiCtrl = false, bool isAnti = false);
79  template <typename Qubit1Fn>
80  void MetaControlled(const bitCapInt& controlPerm, const std::vector<bitLenInt>& controls, bitLenInt target,
81  Qubit1Fn fn, const complex* mtrx, bool isSqiCtrl = false, bool isIntraCtrled = false);
82  template <typename Qubit1Fn>
83  void SemiMetaControlled(
84  const bitCapInt& controlPerm, std::vector<bitLenInt> controls, bitLenInt target, Qubit1Fn fn);
85  void MetaSwap(bitLenInt qubit1, bitLenInt qubit2, bool isIPhaseFac, bool isInverse);
86 
87  template <typename F> void CombineAndOp(F fn, std::vector<bitLenInt> bits);
88  template <typename F>
89  void CombineAndOpControlled(F fn, std::vector<bitLenInt> bits, const std::vector<bitLenInt>& controls);
90 
91  void ApplySingleEither(bool isInvert, const complex& top, const complex& bottom, bitLenInt target);
93  const bitCapInt& controlPerm, const std::vector<bitLenInt>& controls, bitLenInt target, const complex* mtrx);
94  void EitherISwap(bitLenInt qubit1, bitLenInt qubit2, bool isInverse);
95 
96  void Init();
97 
98  void GetSetAmplitudePage(complex* pagePtr, const complex* cPagePtr, bitCapIntOcl offset, bitCapIntOcl length);
99 
100  real1_f ExpVarBitsAll(bool isExp, const std::vector<bitLenInt>& bits, const bitCapInt& offset = ZERO_BCI);
101 
102 public:
103  QPager(std::vector<QInterfaceEngine> eng, bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI,
104  qrack_rand_gen_ptr rgp = nullptr, const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false,
105  bool ignored = false, bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true,
106  bool useSparseStateVec = false, real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {},
107  bitLenInt qubitThreshold = 0U, real1_f separation_thresh = _qrack_qunit_sep_thresh);
108 
109  QPager(bitLenInt qBitCount, const bitCapInt& initState = ZERO_BCI, qrack_rand_gen_ptr rgp = nullptr,
110  const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool ignored = false, bool useHostMem = false,
111  int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
112  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {}, bitLenInt qubitThreshold = 0U,
113  real1_f separation_thresh = _qrack_qunit_sep_thresh)
114 #if ENABLE_OPENCL
115  : QPager({ OCLEngine::Instance().GetDeviceCount() ? QINTERFACE_OPENCL : QINTERFACE_CPU }, qBitCount, initState,
116  rgp, phaseFac, doNorm, ignored, useHostMem, deviceId, useHardwareRNG, useSparseStateVec, norm_thresh,
117  devList, qubitThreshold, separation_thresh)
118 #elif ENABLE_CUDA
119  : QPager({ CUDAEngine::Instance().GetDeviceCount() ? QINTERFACE_CUDA : QINTERFACE_CPU }, qBitCount, initState,
120  rgp, phaseFac, doNorm, ignored, useHostMem, deviceId, useHardwareRNG, useSparseStateVec, norm_thresh,
121  devList, qubitThreshold, separation_thresh)
122 #else
123  : QPager({ QINTERFACE_CPU }, qBitCount, initState, rgp, phaseFac, doNorm, ignored, useHostMem, deviceId,
124  useHardwareRNG, useSparseStateVec, norm_thresh, devList, qubitThreshold, separation_thresh)
125 #endif
126  {
127  }
128 
129  QPager(QEnginePtr enginePtr, std::vector<QInterfaceEngine> eng, bitLenInt qBitCount,
130  const bitCapInt& ignored = ZERO_BCI, qrack_rand_gen_ptr rgp = nullptr,
131  const complex& phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = false, bool ignored2 = false,
132  bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
133  real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devList = {}, bitLenInt qubitThreshold = 0U,
134  real1_f separation_thresh = _qrack_qunit_sep_thresh);
135 
136  void SetConcurrency(uint32_t threadsPerEngine)
137  {
138  QInterface::SetConcurrency(threadsPerEngine);
139  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
140  qPages[i]->SetConcurrency(threadsPerEngine);
141  }
142  }
143  void SetTInjection(bool useGadget)
144  {
145  useTGadget = useGadget;
146  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
147  qPages[i]->SetTInjection(useTGadget);
148  }
149  }
150  bool GetTInjection() { return useTGadget; }
151  bool isOpenCL() { return qPages[0U]->isOpenCL(); }
152 
154  {
155  CombineEngines();
156  return qPages[0U];
157  }
158 
160  {
161  qPages.resize(1U);
162  qPages[0U] = eng;
163  eng->SetDevice(deviceIDs[0]);
164  SeparateEngines();
165  }
166 
168  {
169  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
170  qPages[i]->ZeroAmplitudes();
171  }
172  }
173  void CopyStateVec(QEnginePtr src) { CopyStateVec(std::dynamic_pointer_cast<QPager>(src)); }
175  {
176  bitLenInt qpp = qubitsPerPage();
177  src->CombineEngines(qpp);
178  src->SeparateEngines(qpp, true);
179 
180  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
181  qPages[i]->CopyStateVec(src->qPages[i]);
182  }
183  }
185  {
186  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
187  if (!qPages[i]->IsZeroAmplitude()) {
188  return false;
189  }
190  }
191 
192  return true;
193  }
194  void GetAmplitudePage(complex* pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
195  {
196  GetSetAmplitudePage(pagePtr, NULL, offset, length);
197  }
198  void SetAmplitudePage(const complex* pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
199  {
200  GetSetAmplitudePage(NULL, pagePtr, offset, length);
201  }
202  void SetAmplitudePage(QEnginePtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
203  {
204  SetAmplitudePage(std::dynamic_pointer_cast<QPager>(pageEnginePtr), srcOffset, dstOffset, length);
205  }
206  void SetAmplitudePage(QPagerPtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
207  {
208  CombineEngines();
209  pageEnginePtr->CombineEngines();
210  qPages[0U]->SetAmplitudePage(pageEnginePtr->qPages[0U], srcOffset, dstOffset, length);
211  }
212  void ShuffleBuffers(QEnginePtr engine) { ShuffleBuffers(std::dynamic_pointer_cast<QPager>(engine)); }
214  {
215  bitLenInt qpp = qubitsPerPage();
216  bitLenInt tcqpp = engine->qubitsPerPage();
217  engine->SeparateEngines(qpp, true);
218  SeparateEngines(tcqpp, true);
219 
220  if (qPages.size() == 1U) {
221  qPages[0U]->ShuffleBuffers(engine->qPages[0U]);
222  return;
223  }
224 
225  const bitCapIntOcl offset = qPages.size() >> 1U;
226  for (bitCapIntOcl i = 0U; i < offset; ++i) {
227  qPages[offset + i].swap(engine->qPages[i]);
228  }
229  }
231  void QueueSetDoNormalize(bool doNorm)
232  {
233  Finish();
234  doNormalize = doNorm;
235  }
236  void QueueSetRunningNorm(real1_f runningNrm)
237  {
238  Finish();
239  runningNorm = runningNrm;
240  }
241  real1_f ProbReg(bitLenInt start, bitLenInt length, const bitCapInt& permutation)
242  {
243  CombineEngines();
244  return qPages[0U]->ProbReg(start, length, permutation);
245  }
246  using QEngine::ApplyM;
247  void ApplyM(const bitCapInt& regMask, const bitCapInt& result, const complex& nrm)
248  {
249  CombineEngines();
250  return qPages[0U]->ApplyM(regMask, result, nrm);
251  }
252  real1_f GetExpectation(bitLenInt valueStart, bitLenInt valueLength)
253  {
254  CombineEngines();
255  return qPages[0U]->GetExpectation(valueStart, valueLength);
256  }
257  void Apply2x2(bitCapIntOcl offset1, bitCapIntOcl offset2, const complex* mtrx, bitLenInt bitCount,
258  const bitCapIntOcl* qPowersSorted, bool doCalcNorm, real1_f norm_thresh = REAL1_DEFAULT_ARG)
259  {
260  CombineEngines();
261  qPages[0U]->Apply2x2(offset1, offset2, mtrx, bitCount, qPowersSorted, doCalcNorm, norm_thresh);
262  }
264  {
265  real1_f toRet = ZERO_R1_F;
266  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
267  toRet += qPages[i]->GetRunningNorm();
268  }
269 
270  return toRet;
271  }
272 
274  {
275  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
276  if (!qPages[i]->IsZeroAmplitude()) {
277  return qPages[i]->FirstNonzeroPhase();
278  }
279  }
280 
281  return ZERO_R1_F;
282  }
283 
284  void SetQuantumState(const complex* inputState);
285  void GetQuantumState(complex* outputState);
286  void GetProbs(real1* outputProbs);
288  {
289  bitCapInt p, a;
290  bi_div_mod(perm, pageMaxQPower(), &p, &a);
291  return qPages[(bitCapIntOcl)p]->GetAmplitude(a);
292  }
293  void SetAmplitude(const bitCapInt& perm, const complex& amp)
294  {
295  bitCapInt p, a;
296  bi_div_mod(perm, pageMaxQPower(), &p, &a);
297  qPages[(bitCapIntOcl)p]->SetAmplitude(a, amp);
298  }
299  real1_f ProbAll(const bitCapInt& perm)
300  {
301  bitCapInt p, a;
302  bi_div_mod(perm, pageMaxQPower(), &p, &a);
303  return qPages[(bitCapIntOcl)p]->ProbAll(a);
304  }
305 
306  void SetPermutation(const bitCapInt& perm, const complex& phaseFac = CMPLX_DEFAULT_ARG);
307 
308  using QEngine::Compose;
309  bitLenInt Compose(QPagerPtr toCopy) { return ComposeEither(toCopy, false); }
310  bitLenInt Compose(QInterfacePtr toCopy) { return Compose(std::dynamic_pointer_cast<QPager>(toCopy)); }
311  bitLenInt ComposeNoClone(QPagerPtr toCopy) { return ComposeEither(toCopy, true); }
312  bitLenInt ComposeNoClone(QInterfacePtr toCopy) { return ComposeNoClone(std::dynamic_pointer_cast<QPager>(toCopy)); }
313  bitLenInt ComposeEither(QPagerPtr toCopy, bool willDestroy);
314  void Decompose(bitLenInt start, QInterfacePtr dest) { Decompose(start, std::dynamic_pointer_cast<QPager>(dest)); }
315  void Decompose(bitLenInt start, QPagerPtr dest);
317  void Dispose(bitLenInt start, bitLenInt length);
318  void Dispose(bitLenInt start, bitLenInt length, const bitCapInt& disposedPerm);
319  using QEngine::Allocate;
320  bitLenInt Allocate(bitLenInt start, bitLenInt length);
321 
322  void Mtrx(const complex* mtrx, bitLenInt target);
323  void Phase(const complex& topLeft, const complex& bottomRight, bitLenInt qubitIndex)
324  {
325  ApplySingleEither(false, topLeft, bottomRight, qubitIndex);
326  }
327  void Invert(const complex& topRight, const complex& bottomLeft, bitLenInt qubitIndex)
328  {
329  ApplySingleEither(true, topRight, bottomLeft, qubitIndex);
330  }
331  void MCMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
332  {
333  bitCapInt p = pow2(controls.size());
334  bi_decrement(&p, 1U);
335  ApplyEitherControlledSingleBit(p, controls, target, mtrx);
336  }
337  void MACMtrx(const std::vector<bitLenInt>& controls, const complex* mtrx, bitLenInt target)
338  {
339  ApplyEitherControlledSingleBit(ZERO_BCI, controls, target, mtrx);
340  }
341 
342  void UniformParityRZ(const bitCapInt& mask, real1_f angle);
343  void CUniformParityRZ(const std::vector<bitLenInt>& controls, const bitCapInt& mask, real1_f angle);
344 
345  void XMask(const bitCapInt& mask);
346  void ZMask(const bitCapInt& mask) { PhaseParity(PI_R1, mask); }
347  void PhaseParity(real1_f radians, const bitCapInt& mask);
348 
349  bool ForceM(bitLenInt qubit, bool result, bool doForce = true, bool doApply = true);
351  bitLenInt start, bitLenInt length, const bitCapInt& result, bool doForce = true, bool doApply = true)
352  {
353  // Don't use QEngine::ForceMReg().
354  return QInterface::ForceMReg(start, length, result, doForce, doApply);
355  }
356 
357 #if ENABLE_ALU
358  void INCDECSC(
359  const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex);
360  void INCDECSC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
361 #if ENABLE_BCD
362  void INCBCD(const bitCapInt& toAdd, bitLenInt start, bitLenInt length);
363  void INCDECBCDC(const bitCapInt& toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
364 #endif
365  void MUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length);
366  void DIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length);
367  void MULModNOut(
368  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length);
369  void IMULModNOut(
370  const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length);
371  void POWModNOut(
372  const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart, bitLenInt length);
373  void CMUL(const bitCapInt& toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
374  const std::vector<bitLenInt>& controls);
375  void CDIV(const bitCapInt& toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length,
376  const std::vector<bitLenInt>& controls);
377  void CMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
378  bitLenInt length, const std::vector<bitLenInt>& controls);
379  void CIMULModNOut(const bitCapInt& toMul, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
380  bitLenInt length, const std::vector<bitLenInt>& controls);
381  void CPOWModNOut(const bitCapInt& base, const bitCapInt& modN, bitLenInt inStart, bitLenInt outStart,
382  bitLenInt length, const std::vector<bitLenInt>& controls);
383 
384  bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
385  const unsigned char* values, bool resetValue = true);
386  bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
387  bitLenInt carryIndex, const unsigned char* values);
388  bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength,
389  bitLenInt carryIndex, const unsigned char* values);
390  void Hash(bitLenInt start, bitLenInt length, const unsigned char* values);
391 
392  void CPhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex);
393  void PhaseFlipIfLess(const bitCapInt& greaterPerm, bitLenInt start, bitLenInt length);
394 #endif
395 
396  void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2);
397  void ISwap(bitLenInt qubit1, bitLenInt qubit2) { EitherISwap(qubit1, qubit2, false); }
398  void IISwap(bitLenInt qubit1, bitLenInt qubit2) { EitherISwap(qubit1, qubit2, true); }
399  void FSim(real1_f theta, real1_f phi, bitLenInt qubitIndex1, bitLenInt qubitIndex2);
400 
401  real1_f Prob(bitLenInt qubitIndex);
402  real1_f ProbMask(const bitCapInt& mask, const bitCapInt& permutation);
403  // TODO: QPager not yet used in Q#, but this would need a real implementation:
405  {
406  if (bi_compare_0(mask) == 0) {
407  return ZERO_R1_F;
408  }
409 
410  CombineEngines();
411  return qPages[0U]->ProbParity(mask);
412  }
413  bool ForceMParity(const bitCapInt& mask, bool result, bool doForce = true)
414  {
415  if (bi_compare_0(mask) == 0) {
416  return ZERO_R1_F;
417  }
418 
419  CombineEngines();
420  return qPages[0U]->ForceMParity(mask, result, doForce);
421  }
422 
423  void UpdateRunningNorm(real1_f norm_thresh = REAL1_DEFAULT_ARG);
424  void NormalizeState(
425  real1_f nrm = REAL1_DEFAULT_ARG, real1_f norm_thresh = REAL1_DEFAULT_ARG, real1_f phaseArg = ZERO_R1_F);
426 
427  void Finish()
428  {
429  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
430  qPages[i]->Finish();
431  }
432  };
433 
434  bool isFinished()
435  {
436  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
437  if (!qPages[i]->isFinished()) {
438  return false;
439  }
440  }
441 
442  return true;
443  };
444 
445  void Dump()
446  {
447  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
448  qPages[i]->Dump();
449  }
450  };
451 
453 
454  void SetDevice(int64_t dID)
455  {
456  deviceIDs.clear();
457  deviceIDs.push_back(dID);
458 
459  for (bitCapIntOcl i = 0U; i < qPages.size(); ++i) {
460  qPages[i]->SetDevice(dID);
461  }
462 
463 #if ENABLE_OPENCL || ENABLE_CUDA
464  if (rootEngine != QINTERFACE_CPU) {
465 #if ENABLE_OPENCL
466  maxPageQubits =
467  log2Ocl(OCLEngine::Instance().GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
468 #else
469  maxPageQubits =
470  log2Ocl(CUDAEngine::Instance().GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
471 #endif
474  }
475  }
476 
477  if (!useGpuThreshold) {
478  return;
479  }
480 
481  // Limit at the power of 2 less-than-or-equal-to a full max memory allocation segment, or choose with
482  // environment variable.
484 #endif
485  }
486 
487  int64_t GetDevice() { return qPages[0U]->GetDevice(); }
488 
489  bitCapIntOcl GetMaxSize() { return qPages[0U]->GetMaxSize(); };
490 
491  real1_f SumSqrDiff(QInterfacePtr toCompare) { return SumSqrDiff(std::dynamic_pointer_cast<QPager>(toCompare)); }
492 
493  real1_f SumSqrDiff(QPagerPtr toCompare);
494 };
495 } // 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 ApplyM(const bitCapInt &qPower, bool result, const complex &nrm)
Definition: qengine.hpp:154
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:146
virtual void SetConcurrency(uint32_t threadsPerEngine)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qinterface.hpp:257
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:452
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:346
virtual void SetQubitCount(bitLenInt qb)
Definition: qinterface.hpp:250
bitLenInt qubitCount
Definition: qinterface.hpp:143
bool doNormalize
Definition: qinterface.hpp:140
A "Qrack::QPager" splits a "Qrack::QEngine" implementation into equal-length "pages....
Definition: qpager.hpp:31
void SetQubitCount(bitLenInt qb)
Definition: qpager.hpp:53
QInterfacePtr Clone()
Clone this QInterface.
Definition: qpager.cpp:1585
void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qpager.cpp:872
void CombineAndOp(F fn, std::vector< bitLenInt > bits)
Definition: qpager.cpp:590
void Dump()
If asynchronous work is still running, let the simulator know that it can be aborted.
Definition: qpager.hpp:445
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:1171
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:1257
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:1280
void CombineEngines()
Definition: qpager.hpp:73
bool isFinished()
Returns "false" if asynchronous work is still running, and "true" if all previously dispatched asynch...
Definition: qpager.hpp:434
bitCapIntOcl GetMaxSize()
Definition: qpager.hpp:489
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:1275
bitLenInt pagedQubitCount()
Definition: qpager.hpp:67
bitCapIntOcl basePageMaxQPower
Definition: qpager.hpp:43
real1_f ProbParity(const bitCapInt &mask)
Overall probability of any odd permutation of the masked set of bits.
Definition: qpager.hpp:404
real1_f ProbAll(const bitCapInt &perm)
Direct measure of full permutation probability.
Definition: qpager.hpp:299
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:109
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:337
void DIV(const bitCapInt &toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Divide by integer.
Definition: qpager.cpp:1166
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:1568
void CopyStateVec(QPagerPtr src)
Definition: qpager.hpp:174
void Init()
Definition: qpager.cpp:89
void Mtrx(const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation.
Definition: qpager.cpp:921
real1_f ProbMask(const bitCapInt &mask, const bitCapInt &permutation)
Direct measure of masked permutation probability.
Definition: qpager.cpp:1504
bitLenInt maxQubits
Definition: qpager.hpp:40
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:1237
void MUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Multiply by integer.
Definition: qpager.cpp:1161
real1_f ProbReg(bitLenInt start, bitLenInt length, const bitCapInt &permutation)
Direct measure of register permutation probability.
Definition: qpager.hpp:241
bitCapIntOcl pageMaxQPower()
Definition: qpager.hpp:61
void SemiMetaControlled(const bitCapInt &controlPerm, std::vector< bitLenInt > controls, bitLenInt target, Qubit1Fn fn)
Definition: qpager.cpp:558
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:752
void SetAmplitude(const bitCapInt &perm, const complex &amp)
Sets the representational amplitude of a full permutation.
Definition: qpager.hpp:293
bitCapIntOcl basePageCount
Definition: qpager.hpp:44
void XMask(const bitCapInt &mask)
Masked X gate.
Definition: qpager.cpp:1038
void ApplyEitherControlledSingleBit(const bitCapInt &controlPerm, const std::vector< bitLenInt > &controls, bitLenInt target, const complex *mtrx)
Definition: qpager.cpp:978
void SetQuantumState(const complex *inputState)
Set an arbitrary pure quantum state representation.
Definition: qpager.cpp:806
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:231
void CMUL(const bitCapInt &toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, const std::vector< bitLenInt > &controls)
Controlled multiplication by integer.
Definition: qpager.cpp:1189
void SetAmplitudePage(QPagerPtr pageEnginePtr, bitCapIntOcl srcOffset, bitCapIntOcl dstOffset, bitCapIntOcl length)
Definition: qpager.hpp:206
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:198
void ShuffleBuffers(QPagerPtr engine)
Definition: qpager.hpp:213
void GetSetAmplitudePage(complex *pagePtr, const complex *cPagePtr, bitCapIntOcl offset, bitCapIntOcl length)
Definition: qpager.cpp:291
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:413
real1_f GetExpectation(bitLenInt valueStart, bitLenInt valueLength)
Definition: qpager.hpp:252
void EitherISwap(bitLenInt qubit1, bitLenInt qubit2, bool isInverse)
Definition: qpager.cpp:1348
void GetQuantumState(complex *outputState)
Get the pure quantum state representation.
Definition: qpager.cpp:842
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:257
real1_f FirstNonzeroPhase()
Get phase of lowest permutation nonzero amplitude.
Definition: qpager.hpp:273
bool isSparse
Definition: qpager.hpp:34
void SetTInjection(bool useGadget)
Set the option to use T-injection gadgets (off by default)
Definition: qpager.hpp:143
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:1138
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:1027
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:331
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:1250
void SingleBitGate(bitLenInt target, Qubit1Fn fn, bool isSqiCtrl=false, bool isAnti=false)
Definition: qpager.cpp:366
void SetConcurrency(uint32_t threadsPerEngine)
Set the number of threads in parallel for loops, per component QEngine.
Definition: qpager.hpp:136
void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qpager.hpp:314
std::vector< QInterfaceEngine > engines
Definition: qpager.hpp:48
QEnginePtr CloneEmpty()
Clone this QEngine's settings, with a zeroed state vector.
Definition: qpager.cpp:1600
QEnginePtr ReleaseEngine()
Definition: qpager.hpp:153
bitLenInt Compose(QPagerPtr toCopy)
Definition: qpager.hpp:309
real1_f ExpVarBitsAll(bool isExp, const std::vector< bitLenInt > &bits, const bitCapInt &offset=ZERO_BCI)
Definition: qpager.cpp:1515
bool GetTInjection()
Get the option to use T-injection gadgets.
Definition: qpager.hpp:150
complex phaseFactor
Definition: qpager.hpp:45
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:1201
real1_f SumSqrDiff(QInterfacePtr toCompare)
Calculates (1 - <\psi_e|\psi_c>) between states |\psi_c> and |\psi_e>.
Definition: qpager.hpp:491
bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qpager.hpp:310
void SeparateEngines()
Definition: qpager.hpp:75
void ZMask(const bitCapInt &mask)
Masked Z gate.
Definition: qpager.hpp:346
QInterfaceEngine rootEngine
Definition: qpager.hpp:42
int64_t devID
Definition: qpager.hpp:41
void SetPermutation(const bitCapInt &perm, const complex &phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: qpager.cpp:902
bitLenInt ComposeNoClone(QPagerPtr toCopy)
Definition: qpager.hpp:311
void SetDevice(int64_t dID)
Set GPU device ID.
Definition: qpager.hpp:454
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:173
complex GetAmplitude(const bitCapInt &perm)
Get the representational amplitude of a full permutation.
Definition: qpager.hpp:287
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:1263
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:1213
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:398
bitLenInt Allocate(bitLenInt start, bitLenInt length)
Allocate new "length" count of |0> state qubits at specified qubit index start position.
Definition: qpager.cpp:794
bitLenInt baseQubitsPerPage
Definition: qpager.hpp:39
std::vector< bool > devicesHostPointer
Definition: qpager.hpp:46
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:397
real1_f GetRunningNorm()
Get in-flight renormalization factor.
Definition: qpager.hpp:263
int64_t GetDevice()
Get GPU device ID.
Definition: qpager.hpp:487
void LockEngine(QEnginePtr eng)
Definition: qpager.hpp:159
QEnginePtr MakeEngine(bitLenInt length, bitCapIntOcl pageId)
Definition: qpager.cpp:280
void Finish()
If asynchronous work is still running, block until it finishes.
Definition: qpager.hpp:427
bool GetPageHostPointer(bitCapIntOcl page)
Definition: qpager.hpp:70
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:1269
bitLenInt maxPageQubits
Definition: qpager.hpp:37
void ApplyM(const bitCapInt &regMask, const bitCapInt &result, const complex &nrm)
Definition: qpager.hpp:247
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:202
bitLenInt ComposeEither(QPagerPtr toCopy, bool willDestroy)
Definition: qpager.cpp:616
bitLenInt qubitsPerPage()
Definition: qpager.hpp:68
void PhaseParity(real1_f radians, const bitCapInt &mask)
Parity phase gate.
Definition: qpager.cpp:1057
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:1561
real1_f Prob(bitLenInt qubitIndex)
Direct measure of bit probability to be in |1> state.
Definition: qpager.cpp:1433
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:1032
void ShuffleBuffers(QEnginePtr engine)
Swap the high half of this engine with the low half of another.
Definition: qpager.hpp:212
std::vector< QEnginePtr > qPages
Definition: qpager.hpp:49
void CombineAndOpControlled(F fn, std::vector< bitLenInt > bits, const std::vector< bitLenInt > &controls)
Definition: qpager.cpp:607
int64_t GetPageDevice(bitCapIntOcl page)
Definition: qpager.hpp:69
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:1225
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:1177
bool useGpuThreshold
Definition: qpager.hpp:33
bool IsZeroAmplitude()
Returns "true" only if amplitudes are all totally 0.
Definition: qpager.hpp:184
void ApplySingleEither(bool isInvert, const complex &top, const complex &bottom, bitLenInt target)
Definition: qpager.cpp:934
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:312
void Phase(const complex &topLeft, const complex &bottomRight, bitLenInt qubitIndex)
Apply a single bit transformation that only effects phase.
Definition: qpager.hpp:323
void GetAmplitudePage(complex *pagePtr, bitCapIntOcl offset, bitCapIntOcl length)
Copy a "page" of amplitudes from this QEngine's internal state, into pagePtr.
Definition: qpager.hpp:194
void ZeroAmplitudes()
Set all amplitudes to 0, and optionally temporarily deallocate state vector RAM.
Definition: qpager.hpp:167
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:236
bool isOpenCL()
Returns "true" if current simulation is OpenCL-based.
Definition: qpager.hpp:151
void MetaSwap(bitLenInt qubit1, bitLenInt qubit2, bool isIPhaseFac, bool isInverse)
Definition: qpager.cpp:1287
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:1085
std::vector< int64_t > deviceIDs
Definition: qpager.hpp:47
bitCapInt ForceMReg(bitLenInt start, bitLenInt length, const bitCapInt &result, bool doForce=true, bool doApply=true)
Measure permutation state of a register.
Definition: qpager.hpp:350
bool useTGadget
Definition: qpager.hpp:35
void INCBCD(const bitCapInt &toAdd, bitLenInt start, bitLenInt length)
Add classical BCD integer (without sign)
Definition: qpager.cpp:1150
void INCDECBCDC(const bitCapInt &toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Common driver method behind INCSC and DECSC (without overflow flag)
Definition: qpager.cpp:1155
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:1183
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:448
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:327
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:210
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:147
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:29
const real1_f _qrack_qunit_sep_thresh
Definition: qrack_functions.hpp:213
bitLenInt log2Ocl(bitCapIntOcl n)
Definition: qrack_functions.hpp:83
std::complex< real1 > complex
Definition: qrack_types.hpp:124
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:114
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:187
float real1_f
Definition: qrack_types.hpp:91
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:242
std::shared_ptr< QPager > QPagerPtr
Definition: qpager.hpp:24
QRACK_CONST real1 PI_R1
Definition: qrack_types.hpp:170
const bitCapInt ZERO_BCI
Definition: qrack_types.hpp:126
bitCapIntOcl pow2Ocl(const bitLenInt &p)
Definition: qrack_functions.hpp:115
#define REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:169
#define bitLenInt
Definition: qrack_types.hpp:38
#define ZERO_R1_F
Definition: qrack_types.hpp:156
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:152
#define bitCapInt
Definition: qrack_types.hpp:62
#define bitCapIntOcl
Definition: qrack_types.hpp:50