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 #define ALIGN_SIZE 64
23 
24 namespace Qrack {
25 
26 class QEngineCPU;
27 typedef std::shared_ptr<QEngineCPU> QEngineCPUPtr;
28 
29 template <class BidirectionalIterator>
30 void reverse(BidirectionalIterator first, BidirectionalIterator last, bitCapInt stride);
31 template <class BidirectionalIterator>
32 void rotate(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, bitCapInt stride);
33 
37 class QEngineCPU : public QInterface, public ParallelFor {
38 protected:
42 
43 public:
44  QEngineCPU(bitLenInt qBitCount, bitCapInt initState, std::shared_ptr<std::default_random_engine> rgp = nullptr,
45  complex phaseFac = complex(-999.0, -999.0), bool partialInit = false);
46  QEngineCPU(QEngineCPUPtr toCopy);
47  ~QEngineCPU() { delete[] stateVec; }
48 
49  virtual void EnableNormalize(bool doN) { doNormalize = doN; }
50 
51  virtual void SetQuantumState(complex* inputState);
52  virtual void SetPermutation(bitCapInt perm) { SetReg(0, qubitCount, perm); }
53 
54  virtual bitLenInt Cohere(QInterfacePtr toCopy) { return Cohere(std::dynamic_pointer_cast<QEngineCPU>(toCopy)); }
55  std::map<QInterfacePtr, bitLenInt> Cohere(std::vector<QInterfacePtr> toCopy);
56 
57  virtual void Decohere(bitLenInt start, bitLenInt length, QInterfacePtr dest);
58 
59  virtual bitLenInt Cohere(QEngineCPUPtr toCopy);
60  virtual void Dispose(bitLenInt start, bitLenInt length);
61 
67  virtual void ApplySingleBit(const complex* mtrx, bool doCalcNorm, bitLenInt qubitIndex);
68  virtual void CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target);
69  virtual void AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target);
70  virtual void CNOT(bitLenInt control, bitLenInt target);
71  virtual void AntiCNOT(bitLenInt control, bitLenInt target);
72  virtual void H(bitLenInt qubitIndex);
73  virtual bool M(bitLenInt qubitIndex);
74  virtual void X(bitLenInt qubitIndex);
75  virtual void Y(bitLenInt qubitIndex);
76  virtual void Z(bitLenInt qubitIndex);
77  virtual void CY(bitLenInt control, bitLenInt target);
78  virtual void CZ(bitLenInt control, bitLenInt target);
79 
91  virtual void RT(real1 radians, bitLenInt qubitIndex);
92  virtual void RX(real1 radians, bitLenInt qubitIndex);
93  virtual void RY(real1 radians, bitLenInt qubitIndex);
94  virtual void RZ(real1 radians, bitLenInt qubitIndex);
95  virtual void Exp(real1 radians, bitLenInt qubitIndex);
96  virtual void ExpX(real1 radians, bitLenInt qubitIndex);
97  virtual void ExpY(real1 radians, bitLenInt qubitIndex);
98  virtual void ExpZ(real1 radians, bitLenInt qubitIndex);
99  virtual void CRX(real1 radians, bitLenInt control, bitLenInt target);
100  virtual void CRY(real1 radians, bitLenInt control, bitLenInt target);
101  virtual void CRZ(real1 radians, bitLenInt control, bitLenInt target);
102  virtual void CRT(real1 radians, bitLenInt control, bitLenInt target);
103 
115  using QInterface::H;
116  virtual void X(bitLenInt start, bitLenInt length);
117  virtual void CNOT(bitLenInt control, bitLenInt target, bitLenInt length);
118  virtual void AntiCNOT(bitLenInt control, bitLenInt target, bitLenInt length);
119  virtual void CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target, bitLenInt length);
120  virtual void AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target, bitLenInt length);
121  virtual void AND(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit, bitLenInt length);
122  virtual void OR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit, bitLenInt length);
123  virtual void XOR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit, bitLenInt length);
124 
133  virtual void ROL(bitLenInt shift, bitLenInt start, bitLenInt length);
134  virtual void ROR(bitLenInt shift, bitLenInt start, bitLenInt length);
135  virtual void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length);
136  virtual void INCC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
137  virtual void INCS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex);
138  virtual void INCSC(
139  bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex);
140  virtual void INCSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
141  virtual void INCBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length);
142  virtual void INCBCDC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
143  virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length);
144  virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
145  virtual void DECS(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex);
146  virtual void DECSC(
147  bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt overflowIndex, bitLenInt carryIndex);
148  virtual void DECSC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
149  virtual void DECBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length);
150  virtual void DECBCDC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
151 
160  virtual void ZeroPhaseFlip(bitLenInt start, bitLenInt length);
161  virtual void CPhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt length, bitLenInt flagIndex);
162  virtual void PhaseFlip();
163  virtual void SetReg(bitLenInt start, bitLenInt length, bitCapInt value);
164  virtual bitCapInt MReg(bitLenInt start, bitLenInt length);
165  virtual bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
166  bitLenInt valueLength, unsigned char* values);
167  virtual bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
168  bitLenInt valueLength, bitLenInt carryIndex, unsigned char* values);
169  virtual bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
170  bitLenInt valueLength, bitLenInt carryIndex, unsigned char* values);
171  virtual void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2);
172  virtual void Swap(bitLenInt start1, bitLenInt start2, bitLenInt length);
173 
182  virtual complex* GetState();
183  virtual void CopyState(QInterfacePtr orig);
184  virtual real1 Prob(bitLenInt qubitIndex);
185  virtual real1 ProbAll(bitCapInt fullRegister);
186  virtual void SetBit(bitLenInt qubitIndex1, bool value);
187  virtual real1 GetNorm(bool update = true)
188  {
189  if (update) {
191  }
192  return runningNorm;
193  }
194  virtual void SetNorm(real1 n) { runningNorm = n; }
195  virtual void NormalizeState(real1 nrm = -999.0);
196  virtual bool ForceM(bitLenInt qubitIndex, bool result, bool doForce = true, real1 nrmlzr = 1.0);
197 
200 protected:
201  virtual void ResetStateVec(complex* nStateVec);
202  void DecohereDispose(bitLenInt start, bitLenInt length, QEngineCPUPtr dest);
203  virtual void Apply2x2(bitCapInt offset1, bitCapInt offset2, const complex* mtrx, const bitLenInt bitCount,
204  const bitCapInt* qPowersSorted, bool doCalcNorm);
205  virtual void ApplyControlled2x2(bitLenInt control, bitLenInt target, const complex* mtrx, bool doCalcNorm);
206  virtual void ApplyAntiControlled2x2(bitLenInt control, bitLenInt target, const complex* mtrx, bool doCalcNorm);
207  virtual void ApplyDoublyControlled2x2(
208  bitLenInt control1, bitLenInt control2, bitLenInt target, const complex* mtrx, bool doCalcNorm);
209  virtual void ApplyDoublyAntiControlled2x2(
210  bitLenInt control1, bitLenInt control2, bitLenInt target, const complex* mtrx, bool doCalcNorm);
211  virtual void UpdateRunningNorm();
212  virtual complex* AllocStateVec(bitCapInt elemCount);
213 };
214 } // namespace Qrack
virtual void Y(bitLenInt qubitIndex)
Apply Pauli Y matrix to bit.
Definition: gates.cpp:123
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 H(bitLenInt qubitIndex)=0
Hadamard gate.
virtual void ExpZ(real1 radians, bitLenInt qubitIndex)
Exponentiate Pauli Z operator.
Definition: rotational.cpp:79
virtual void H(bitLenInt qubitIndex)
Hadamard gate.
Definition: gates.cpp:104
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 CY(bitLenInt control, bitLenInt target)
Apply controlled Pauli Y matrix to bit.
Definition: gates.cpp:141
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:81
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:779
virtual void AntiCCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target)
"Anti-doubly-controlled not" - Apply "not" if control bits are both zero, do not apply if either cont...
Definition: gates.cpp:62
virtual void INCBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Add BCD integer (without sign)
Definition: operators.cpp:166
virtual void Exp(real1 radians, bitLenInt qubitIndex)
Exponentiate identity operator.
Definition: rotational.cpp:54
virtual void ExpX(real1 radians, bitLenInt qubitIndex)
Exponentiate Pauli X operator.
Definition: rotational.cpp:62
virtual void ExpY(real1 radians, bitLenInt qubitIndex)
Exponentiate Pauli Y operator.
Definition: rotational.cpp:70
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:387
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:1041
virtual real1 GetNorm(bool update=true)
Definition: qengine_cpu.hpp:187
virtual void CZ(bitLenInt control, bitLenInt target)
Apply controlled Pauli Z matrix to bit.
Definition: gates.cpp:152
virtual void SetQuantumState(complex *inputState)
Set arbitrary pure quantum state, in unsigned int permutation basis.
Definition: state.cpp:88
virtual void CRZ(real1 radians, bitLenInt control, bitLenInt target)
Controlled z axis rotation - if control bit is true, rotates as e^(-i*) around Pauli z axis...
Definition: rotational.cpp:122
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:938
virtual void CopyState(QInterfacePtr orig)
Direct copy of raw state vector to produce a clone.
Definition: state.cpp:71
virtual void EnableNormalize(bool doN)
Definition: qengine_cpu.hpp:49
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:35
virtual void CRT(real1 radians, bitLenInt control, bitLenInt target)
Controlled "phase shift gate" - if control bit is true, rotates target bit as e^(-i*/2) around |1> st...
Definition: rotational.cpp:87
virtual void ApplyDoublyAntiControlled2x2(bitLenInt control1, bitLenInt control2, bitLenInt target, const complex *mtrx, bool doCalcNorm)
Definition: qengine.cpp:79
virtual void CCNOT(bitLenInt control1, bitLenInt control2, bitLenInt target)
Doubly-controlled not.
Definition: gates.cpp:45
virtual void DECBCDC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract BCD integer (without sign, with carry)
Definition: operators.cpp:705
virtual void ApplySingleBit(const complex *mtrx, bool doCalcNorm, bitLenInt qubitIndex)
Apply an arbitrary single bit unitary transformation.
Definition: qengine.cpp:37
virtual void ApplyDoublyControlled2x2(bitLenInt control1, bitLenInt control2, bitLenInt target, const complex *mtrx, bool doCalcNorm)
Definition: qengine.cpp:66
virtual complex * AllocStateVec(bitCapInt elemCount)
Definition: state.cpp:455
virtual void RX(real1 radians, bitLenInt qubitIndex)
x axis rotation gate - Rotates as e^(-i*/2) around Pauli x axis
Definition: rotational.cpp:27
virtual void RY(real1 radians, bitLenInt qubitIndex)
y axis rotation gate - Rotates as e^(-i*/2) around Pauli y axis
Definition: rotational.cpp:36
virtual bitLenInt Cohere(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qengine_cpu.hpp:54
bool doNormalize
Definition: qengine_cpu.hpp:39
virtual void ApplyAntiControlled2x2(bitLenInt control, bitLenInt target, const complex *mtrx, bool doCalcNorm)
Definition: qengine.cpp:55
virtual void RZ(real1 radians, bitLenInt qubitIndex)
z axis rotation gate - Rotates as e^(-i*/2) around Pauli z axis
Definition: rotational.cpp:45
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:34
virtual bitCapInt MReg(bitLenInt start, bitLenInt length)
Measure permutation state of a register.
Definition: operators.cpp:821
void DecohereDispose(bitLenInt start, bitLenInt length, QEngineCPUPtr dest)
Minimally decohere a set of contigious bits from the full coherent unit.
Definition: state.cpp:318
virtual void RT(real1 radians, bitLenInt qubitIndex)
"Phase shift gate" - Rotates as e^(-i*/2) around |1> state
Definition: rotational.cpp:18
std::shared_ptr< QEngineCPU > QEngineCPUPtr
Definition: qengine_cpu.hpp:26
virtual void SetBit(bitLenInt qubitIndex1, bool value)
Set individual bit to pure |0> (false) or |1> (true) state.
Definition: gates.cpp:20
virtual void ApplyControlled2x2(bitLenInt control, bitLenInt target, const complex *mtrx, bool doCalcNorm)
Definition: qengine.cpp:44
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:392
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:894
virtual void Z(bitLenInt qubitIndex)
Apply Pauli Z matrix to bit.
Definition: gates.cpp:132
virtual real1 ProbAll(bitCapInt fullRegister)
PSEUDO-QUANTUM Direct measure of full register probability to be in permutation state.
Definition: state.cpp:422
virtual void CNOT(bitLenInt control, bitLenInt target)
Controlled not.
Definition: gates.cpp:78
virtual void UpdateRunningNorm()
Definition: state.cpp:453
virtual void PhaseFlip()
Phase flip always - equivalent to Z X Z X on any bit in the QEngineCPU.
Definition: gates.cpp:255
~QEngineCPU()
Definition: qengine_cpu.hpp:47
#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:786
#define bitLenInt
Definition: qinterface.hpp:21
virtual void AND(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit, bitLenInt length)
"AND" compare two bits in QEngineCPU, and store result in outputBit
Definition: operators.cpp:20
virtual void XOR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit, bitLenInt length)
"XOR" compare two bits in QEngineCPU, and store result in outputBit
Definition: operators.cpp:60
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: qengine.cpp:28
virtual real1 Prob(bitLenInt qubitIndex)
PSEUDO-QUANTUM Direct measure of bit probability to be in |1> state.
Definition: state.cpp:395
virtual void CRX(real1 radians, bitLenInt control, bitLenInt target)
Controlled x axis rotation - if control bit is true, rotates as e^(-i*/2) around Pauli x axis...
Definition: rotational.cpp:100
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:172
General purpose QEngineCPU implementation.
Definition: qengine_cpu.hpp:37
virtual complex * GetState()
Definition: state.cpp:69
virtual bool M(bitLenInt qubitIndex)
Measurement gate.
Definition: gates.cpp:18
A "Qrack::QInterface" is an abstract interface exposing qubit permutation state vector with methods t...
Definition: qinterface.hpp:94
virtual void Swap(bitLenInt qubitIndex1, bitLenInt qubitIndex2)
Swap values of two bits in register.
Definition: gates.cpp:28
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
virtual void X(bitLenInt qubitIndex)
NOT gate, which is also Pauli x matrix.
Definition: gates.cpp:114
virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract integer (without sign, with carry)
Definition: operators.cpp:109
virtual void SetReg(bitLenInt start, bitLenInt length, bitCapInt value)
Set register bits to given permutation.
Definition: operators.cpp:798
bitLenInt qubitCount
Definition: qinterface.hpp:96
virtual void CRY(real1 radians, bitLenInt control, bitLenInt target)
Controlled y axis rotation - if control bit is true, rotates as e^(-i*) around Pauli y axis...
Definition: rotational.cpp:111
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 DECBCD(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Subtract BCD integer (without sign)
Definition: operators.cpp:482
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:41
virtual void NormalizeState(real1 nrm=-999.0)
Definition: state.cpp:431
virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length)
Subtract integer (without sign)
Definition: operators.cpp:461
virtual void SetNorm(real1 n)
Definition: qengine_cpu.hpp:194
void reverse(BidirectionalIterator first, BidirectionalIterator last, bitCapInt stride)
Definition: qengine.cpp:18
virtual void AntiCNOT(bitLenInt control, bitLenInt target)
"Anti-controlled not" - Apply "not" if control bit is zero, do not apply if control bit is one...
Definition: gates.cpp:91
Definition: complex16simd.hpp:21
complex * stateVec
Definition: qengine_cpu.hpp:41
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 bool ForceM(bitLenInt qubitIndex, bool result, bool doForce=true, real1 nrmlzr=1.0)
PSEUDO-QUANTUM - Acts like a measurement gate, except with a specified forced result.
Definition: gates.cpp:21
virtual void SetPermutation(bitCapInt perm)
Set to a specific permutation.
Definition: qengine_cpu.hpp:52
virtual void OR(bitLenInt inputBit1, bitLenInt inputBit2, bitLenInt outputBit, bitLenInt length)
"OR" compare two bits in QEngineCPU, and store result in outputBit
Definition: operators.cpp:40
real1 runningNorm
Definition: qengine_cpu.hpp:40