Qrack  1.7
General classical-emulating-quantum development framework
qengine_opencl.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano 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 #if !ENABLE_OPENCL
16 #error OpenCL has not been enabled
17 #endif
18 
19 #ifdef __APPLE__
20 #include <OpenCL/cl.hpp>
21 #else
22 #include <CL/cl.hpp>
23 #endif
24 
25 #include "qengine_cpu.hpp"
26 
27 namespace Qrack {
28 
29 class OCLEngine;
30 
32 class QEngineOCL : public QEngineCPU {
33 protected:
35  cl::CommandQueue queue;
36  cl::Buffer stateBuffer;
37  cl::Buffer cmplxBuffer;
38  cl::Buffer ulongBuffer;
39  cl::Buffer nrmBuffer;
40  cl::Buffer maxBuffer;
41 
42 public:
43  QEngineOCL(bitLenInt qBitCount, bitCapInt initState, std::shared_ptr<std::default_random_engine> rgp = nullptr)
44  : QEngineCPU(qBitCount, initState, rgp)
45  {
46  InitOCL();
47  }
48 
49  /* Operations that have an improved implementation. */
50  virtual void Swap(bitLenInt qubit1, bitLenInt qubit2); // Inherited overload
51  virtual void Swap(bitLenInt start1, bitLenInt start2, bitLenInt length);
52  using QEngineCPU::X;
53  virtual void X(bitLenInt start, bitLenInt length);
54  virtual void ROL(bitLenInt shift, bitLenInt start, bitLenInt length);
55  virtual void ROR(bitLenInt shift, bitLenInt start, bitLenInt length);
56  virtual void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length);
57  virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length);
58  virtual void INCC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
59  virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex);
60  virtual bitCapInt IndexedLDA(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
61  bitLenInt valueLength, unsigned char* values);
62  virtual bitCapInt IndexedADC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
63  bitLenInt valueLength, bitLenInt carryIndex, unsigned char* values);
64  virtual bitCapInt IndexedSBC(bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart,
65  bitLenInt valueLength, bitLenInt carryIndex, unsigned char* values);
66 
67 protected:
68  static const int BCI_ARG_LEN = 10;
69 
70  void InitOCL();
71  void ReInitOCL();
72  void ResetStateVec(complex* nStateVec);
73 
74  void DispatchCall(cl::Kernel* call, bitCapInt (&bciArgs)[BCI_ARG_LEN], complex* nVec = NULL,
75  unsigned char* values = NULL, bitCapInt valuesLength = 0);
76 
77  void Apply2x2(bitCapInt offset1, bitCapInt offset2, const complex* mtrx, const bitLenInt bitCount,
78  const bitCapInt* qPowersSorted, bool doCalcNorm);
79 
80  /* Utility functions used by the operations above. */
81  void ROx(cl::Kernel* call, bitLenInt shift, bitLenInt start, bitLenInt length);
82  void INT(cl::Kernel* call, bitCapInt toAdd, const bitLenInt inOutStart, const bitLenInt length);
83  void INTC(cl::Kernel* call, bitCapInt toAdd, const bitLenInt inOutStart, const bitLenInt length,
84  const bitLenInt carryIndex);
85 
86  bitCapInt OpIndexed(cl::Kernel* call, bitCapInt carryIn, bitLenInt indexStart, bitLenInt indexLength,
87  bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, unsigned char* values);
88 };
89 
90 } // namespace Qrack
cl::Buffer ulongBuffer
Definition: qengine_opencl.hpp:38
cl::Buffer nrmBuffer
Definition: qengine_opencl.hpp:39
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: opencl.cpp:269
virtual void Swap(bitLenInt qubit1, bitLenInt qubit2)
Swap values of two bits in register.
Definition: opencl.cpp:165
void DispatchCall(cl::Kernel *call, bitCapInt(&bciArgs)[BCI_ARG_LEN], complex *nVec=NULL, unsigned char *values=NULL, bitCapInt valuesLength=0)
Definition: opencl.cpp:58
virtual void X(bitLenInt start, bitLenInt length)
Bitwise Pauli X (or logical "NOT") operator.
Definition: opencl.cpp:151
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: opencl.cpp:346
virtual void ROL(bitLenInt shift, bitLenInt start, bitLenInt length)
"Circular shift left" - shift bits left, and carry last bits.
Definition: opencl.cpp:194
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: opencl.cpp:93
cl::Buffer stateBuffer
Definition: qengine_opencl.hpp:36
static const int BCI_ARG_LEN
Definition: qengine_opencl.hpp:68
void INTC(cl::Kernel *call, bitCapInt toAdd, const bitLenInt inOutStart, const bitLenInt length, const bitLenInt carryIndex)
Add or Subtract integer (without sign, with carry)
Definition: opencl.cpp:230
void ReInitOCL()
Definition: opencl.cpp:38
cl::CommandQueue queue
Definition: qengine_opencl.hpp:35
void ResetStateVec(complex *nStateVec)
Definition: opencl.cpp:51
void ROx(cl::Kernel *call, bitLenInt shift, bitLenInt start, bitLenInt length)
Definition: opencl.cpp:183
#define complex
Definition: qinterface.hpp:30
virtual void DEC(bitCapInt toSub, bitLenInt start, bitLenInt length)
Subtract integer (without sign, with carry)
Definition: opencl.cpp:224
void InitOCL()
Definition: opencl.cpp:20
OCLEngine * clObj
Definition: qengine_opencl.hpp:34
OpenCL enhanced QEngineCPU implementation.
Definition: qengine_opencl.hpp:32
virtual void DECC(bitCapInt toSub, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Subtract integer (without sign, with carry)
Definition: opencl.cpp:256
#define bitCapInt
Definition: qinterface.hpp:21
void INT(cl::Kernel *call, bitCapInt toAdd, const bitLenInt inOutStart, const bitLenInt length)
Add or Subtract integer (without sign or carry)
Definition: opencl.cpp:206
#define bitLenInt
Definition: qinterface.hpp:20
"Qrack::OCLEngine" manages the single OpenCL context.
Definition: oclengine.hpp:28
General purpose QEngineCPU implementation.
Definition: qengine_cpu.hpp:38
virtual void INCC(bitCapInt toAdd, bitLenInt start, bitLenInt length, bitLenInt carryIndex)
Increment integer (without sign, with carry)
Definition: opencl.cpp:244
virtual void X(bitLenInt qubitIndex)
NOT gate, which is also Pauli x matrix.
Definition: gates.cpp:114
bitCapInt OpIndexed(cl::Kernel *call, bitCapInt carryIn, bitLenInt indexStart, bitLenInt indexLength, bitLenInt valueStart, bitLenInt valueLength, bitLenInt carryIndex, unsigned char *values)
Add or Subtract based on an indexed load from classical memory.
Definition: opencl.cpp:300
Definition: complex16simd.hpp:21
virtual void ROR(bitLenInt shift, bitLenInt start, bitLenInt length)
"Circular shift right" - shift bits right, and carry first bits.
Definition: opencl.cpp:200
cl::Buffer maxBuffer
Definition: qengine_opencl.hpp:40
cl::Buffer cmplxBuffer
Definition: qengine_opencl.hpp:37
QEngineOCL(bitLenInt qBitCount, bitCapInt initState, std::shared_ptr< std::default_random_engine > rgp=nullptr)
Definition: qengine_opencl.hpp:43
virtual void INC(bitCapInt toAdd, bitLenInt start, bitLenInt length)
Increment integer (without sign, with carry)
Definition: opencl.cpp:218
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: opencl.cpp:353