Qrack  1.7
General classical-emulating-quantum development framework
qengine_cpu.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017, 2018. 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 General Public License V3.
10 // See LICENSE.md in the project root or https://www.gnu.org/licenses/gpl-3.0.en.html
11 // for details.
12 
13 #pragma once
14 
15 #include <algorithm>
16 #include <memory>
17 
18 #include "qinterface.hpp"
19 
20 #include "common/parallel_for.hpp"
21 
22 namespace Qrack {
23 
24 class QEngineCPU;
25 typedef std::shared_ptr<QEngineCPU> QEngineCPUPtr;
26 
27 template <class BidirectionalIterator>
28 void reverse(BidirectionalIterator first, BidirectionalIterator last, bitCapInt stride);
29 template <class BidirectionalIterator>
30 void rotate(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, bitCapInt stride);
31 
35 class QEngineCPU : public QInterface, public ParallelFor {
36 protected:
38 
39 public:
40  QEngineCPU(bitLenInt qBitCount, bitCapInt initState, std::shared_ptr<std::default_random_engine> rgp = nullptr,
41  complex phaseFac = complex(-999.0, -999.0), bool partialInit = false);
42  QEngineCPU(QEngineCPUPtr toCopy);
43  ~QEngineCPU() { delete[] stateVec; }
44 
45  virtual void EnableNormalize(bool doN) { doNormalize = doN; }
46 
47  virtual void SetQuantumState(complex* inputState);
48 
49  virtual bitLenInt Cohere(QInterfacePtr toCopy) { return Cohere(std::dynamic_pointer_cast<QEngineCPU>(toCopy)); }
50  std::map<QInterfacePtr, bitLenInt> Cohere(std::vector<QInterfacePtr> toCopy);
51 
52  virtual void Decohere(bitLenInt start, bitLenInt length, QInterfacePtr dest);
53 
54  virtual bitLenInt Cohere(QEngineCPUPtr toCopy);
55  virtual void Dispose(bitLenInt start, bitLenInt length);
56 
68  using QInterface::X;
69  virtual void X(bitLenInt start, bitLenInt length);
70  using QInterface::CNOT;
71  virtual void CNOT(bitLenInt control, bitLenInt target, bitLenInt length);
73  virtual void AntiCNOT(bitLenInt control, bitLenInt target, bitLenInt length);
74  using QInterface::CCNOT;
75  virtual void CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target, bitLenInt length);
77  virtual void AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target, bitLenInt length);
78 
87  virtual void ROL(bitLenInt shift, bitLenInt start, bitLenInt length);
88  virtual void ROR(bitLenInt shift, bitLenInt start, bitLenInt length);
89  virtual void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length);
90  virtual void INCC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
91  virtual void INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex);
92  virtual void INCSC(
93  bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex);
94  virtual void INCSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
95  virtual void INCBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length);
96  virtual void INCBCDC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
97  virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length);
98  virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
99  virtual void DECS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex);
100  virtual void DECSC(
101  bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex);
102  virtual void DECSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
103  virtual void DECBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length);
104  virtual void DECBCDC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
105  virtual void MUL(
106  bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, bool clearCarry = false);
107  virtual void DIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length);
108  virtual void CMUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt controlBit,
109  bitLenInt length, bool clearCarry = false);
110  virtual void CDIV(
111  bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt controlBit, bitLenInt length);
112 
121  virtual void ZeroPhaseFlip(bitLenInt start, bitLenInt length);
122  virtual void CPhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex);
123  virtual void PhaseFlip();
124  virtual void SetPermutation(bitCapInt perm);
125  virtual bitCapInt MReg(bitLenInt start, bitLenInt length);
126  virtual bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
127  bitLenInt valueLength, unsigned char* values);
128  virtual bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
129  bitLenInt valueLength, bitLenInt carryIndex, unsigned char* values);
130  virtual bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
131  bitLenInt valueLength, bitLenInt carryIndex, unsigned char* values);
132  using QInterface::Swap;
133  virtual void Swap(bitLenInt start1, bitLenInt start2, bitLenInt length);
134 
143  virtual complex* GetStateVector();
144  virtual void CopyState(QInterfacePtr orig);
145  virtual real1 Prob(bitLenInt qubitIndex);
146  virtual real1 ProbAll(bitCapInt fullRegister);
147  virtual real1 GetNorm(bool update = true)
148  {
149  if (update) {
151  }
152  return runningNorm;
153  }
154  virtual void SetNorm(real1 n) { runningNorm = n; }
155  virtual void NormalizeState(real1 nrm = -999.0);
156 
159 protected:
160  virtual void ResetStateVec(complex* nStateVec);
161  void DecohereDispose(bitLenInt start, bitLenInt length, QEngineCPUPtr dest);
162  virtual void Apply2x2(bitCapInt offset1, bitCapInt offset2, const complex* mtrx, const bitLenInt bitCount,
163  const bitCapInt* qPowersSorted, bool doCalcNorm);
164  virtual void UpdateRunningNorm();
165  virtual complex* AllocStateVec(bitCapInt elemCount);
166  virtual void ApplyM(bitCapInt qPower, bool result, complex nrm);
167 };
168 } // namespace Qrack
QEngineCPU(bitLenInt qBitCount, bitCapInt initState, std::shared_ptr< std::default_random_engine > rgp=nullptr, complex phaseFac=complex(-999.0,-999.0), bool partialInit=false)
Initialize a coherent unit with qBitCount number of bits, to initState unsigned integer permutation s...
Definition: state.cpp:36
virtual void ROL(bitLenInt shift, bitLenInt start, bitLenInt length)
"Circular shift left" - shift bits left, and carry last bits.
Definition: operators.cpp:18
virtual void INCSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Add an integer to the register, with sign and with carry.
Definition: operators.cpp:349
virtual void ResetStateVec(complex *nStateVec)
Definition: state.cpp:91
Definition: parallel_for.hpp:22
virtual void ZeroPhaseFlip(bitLenInt start, bitLenInt length)
For chips with a zero flag, flip the phase of the state where the register equals zero...
Definition: operators.cpp:897
virtual void AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target, bitLenInt length)
Bitwise "Anti-"CCNOT - NOT operation if both control bits are 0.
Definition: gates.cpp:169
virtual void ApplyM(bitCapInt qPower, bool result, complex nrm)
Definition: gates.cpp:17
virtual void INCBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Add BCD integer (without sign)
Definition: operators.cpp:166
virtual void INCBCDC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add BCD integer (without sign, with carry)
Definition: operators.cpp:217
virtual void Decohere(bitLenInt start, bitLenInt length, QInterfacePtr dest)
Minimally decohere a set of contiguous bits from the full coherent unit, into "destination.".
Definition: state.cpp:397
virtual bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, unsigned char *values)
Subtract based on an indexed load from classical memory.
Definition: operators.cpp:1136
virtual void X(bitLenInt qubitIndex)
X gate.
Definition: gates.cpp:147
virtual real1 GetNorm(bool update=true)
Definition: qengine_cpu.hpp:147
virtual void SetQuantumState(complex *inputState)
Set arbitrary pure quantum state, in unsigned int permutation basis.
Definition: state.cpp:98
virtual void CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target)
Doubly-controlled NOT gate.
Definition: gates.cpp:78
real1 runningNorm
Definition: qinterface.hpp:103
virtual bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, unsigned char *values)
Add based on an indexed load from classical memory.
Definition: operators.cpp:1033
virtual void CopyState(QInterfacePtr orig)
Direct copy of raw state vector to produce a clone.
Definition: state.cpp:81
virtual void EnableNormalize(bool doN)
Definition: qengine_cpu.hpp:45
virtual void INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Add an integer to the register, with sign and without carry.
Definition: operators.cpp:297
#define real1
Definition: qinterface.hpp:36
virtual void DECBCDC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract BCD integer (without sign, with carry)
Definition: operators.cpp:705
virtual void X(bitLenInt start, bitLenInt length)
Bitwise Pauli X (or logical "NOT") operator.
Definition: gates.cpp:31
virtual complex * AllocStateVec(bitCapInt elemCount)
Definition: state.cpp:465
virtual void SetPermutation(bitCapInt perm)
Set to a specific permutation.
Definition: state.cpp:73
virtual bitLenInt Cohere(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qengine_cpu.hpp:49
virtual void INCC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Add integer (without sign, with carry)
Definition: operators.cpp:75
#define complex
Definition: qinterface.hpp:35
virtual bitCapInt MReg(bitLenInt start, bitLenInt length)
Measure permutation state of a register.
Definition: operators.cpp:916
void DecohereDispose(bitLenInt start, bitLenInt length, QEngineCPUPtr dest)
Minimally decohere a set of contigious bits from the full coherent unit.
Definition: state.cpp:328
virtual void MUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length, bool clearCarry=false)
Multiply by integer.
Definition: operators.cpp:778
std::shared_ptr< QEngineCPU > QEngineCPUPtr
Definition: qengine_cpu.hpp:24
virtual void Dispose(bitLenInt start, bitLenInt length)
Minimally decohere a set of contigious bits from the full coherent unit, throwing these qubits away...
Definition: state.cpp:402
virtual bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, unsigned char *values)
Set 8 bit register bits based on read from classical memory.
Definition: operators.cpp:989
virtual real1 ProbAll(bitCapInt fullRegister)
PSEUDO-QUANTUM Direct measure of full register probability to be in permutation state.
Definition: state.cpp:432
virtual void UpdateRunningNorm()
Definition: state.cpp:463
virtual void PhaseFlip()
Phase flip always - equivalent to Z X Z X on any bit in the QEngineCPU.
Definition: gates.cpp:218
~QEngineCPU()
Definition: qengine_cpu.hpp:43
#define bitCapInt
Definition: qinterface.hpp:22
virtual 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: operators.cpp:904
virtual void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Swap values of two bits in register.
Definition: gates.cpp:61
#define bitLenInt
Definition: qinterface.hpp:21
virtual void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Add integer (without sign)
Definition: operators.cpp:144
void rotate(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, bitCapInt stride)
Definition: protected.cpp:30
virtual real1 Prob(bitLenInt qubitIndex)
PSEUDO-QUANTUM Direct measure of bit probability to be in |1> state.
Definition: state.cpp:405
virtual void CNOT(bitLenInt control, bitLenInt target)
Controlled NOT gate.
Definition: gates.cpp:111
virtual void Apply2x2(bitCapInt offset1, bitCapInt offset2, const complex *mtrx, const bitLenInt bitCount, const bitCapInt *qPowersSorted, bool doCalcNorm)
Apply a 2x2 matrix to the state vector.
Definition: state.cpp:182
General purpose QEngineCPU implementation.
Definition: qengine_cpu.hpp:35
A "Qrack::QInterface" is an abstract interface exposing qubit permutation state vector with methods t...
Definition: qinterface.hpp:99
virtual void DECS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex)
Subtract an integer from the register, with sign and without carry.
Definition: operators.cpp:538
bool doNormalize
Definition: qinterface.hpp:104
virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract integer (without sign, with carry)
Definition: operators.cpp:109
virtual void CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target, bitLenInt length)
Bitwise CCNOT.
Definition: gates.cpp:147
virtual void AntiCNOT(bitLenInt control, bitLenInt target)
Anti controlled NOT gate.
Definition: gates.cpp:124
virtual void ROR(bitLenInt shift, bitLenInt start, bitLenInt length)
"Circular shift right" - shift bits right, and carry first bits.
Definition: operators.cpp:46
virtual void CMUL(bitCapInt toMul, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt controlBit, bitLenInt length, bool clearCarry=false)
Controlled multiplication by integer.
Definition: operators.cpp:828
virtual void DECBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Subtract BCD integer (without sign)
Definition: operators.cpp:482
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:46
virtual void NormalizeState(real1 nrm=-999.0)
Definition: state.cpp:441
virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length)
Subtract integer (without sign)
Definition: operators.cpp:461
virtual void DIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt length)
Divide by integer.
Definition: operators.cpp:803
virtual void SetNorm(real1 n)
Definition: qengine_cpu.hpp:154
void reverse(BidirectionalIterator first, BidirectionalIterator last, bitCapInt stride)
Definition: protected.cpp:20
Definition: complex16simd.hpp:21
virtual void CDIV(bitCapInt toDiv, bitLenInt inOutStart, bitLenInt carryStart, bitLenInt controlBit, bitLenInt length)
Controlled division by power of integer.
Definition: operators.cpp:864
complex * stateVec
Definition: qengine_cpu.hpp:37
virtual void DECSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex)
Subtract an integer from the register, with sign and with carry.
Definition: operators.cpp:590
virtual void AntiCNOT(bitLenInt control, bitLenInt target, bitLenInt length)
Bitwise "Anti-"CNOT - NOT operation if control is 0.
Definition: gates.cpp:127
virtual void Swap(bitLenInt start1, bitLenInt start2, bitLenInt length)
Bitwise swap.
Definition: gates.cpp:193
virtual void AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target)
Anti doubly-controlled NOT gate.
Definition: gates.cpp:95
virtual complex * GetStateVector()
Definition: state.cpp:71
virtual void CNOT(bitLenInt control, bitLenInt target, bitLenInt length)
Bitwise CNOT.
Definition: gates.cpp:107