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