Qrack  1.7
General classical-emulating-quantum development framework
oclengine.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 "config.h"
16 
17 #if !ENABLE_OPENCL
18 #error OpenCL has not been enabled
19 #endif
20 
21 #include <map>
22 #include <mutex>
23 
24 #ifdef __APPLE__
25 #include <OpenCL/cl.hpp>
26 #else
27 #include <CL/cl.hpp>
28 #endif
29 
30 namespace Qrack {
31 
32 class OCLDeviceCall;
33 
35 
36 typedef std::shared_ptr<OCLDeviceContext> DeviceContextPtr;
37 
38 enum OCLAPI {
78 };
79 
81 protected:
82  std::lock_guard<std::recursive_mutex> guard;
83 
84 public:
85  // A cl::Kernel is unique object which should always be taken by reference, or the OCLDeviceContext will lose
86  // ownership.
87  cl::Kernel& call;
89 
90 protected:
91  OCLDeviceCall(std::recursive_mutex& m, cl::Kernel& c)
92  : guard(m)
93  , call(c)
94  {
95  }
96 
97  friend class OCLDeviceContext;
98 
99 private:
100  OCLDeviceCall& operator=(const OCLDeviceCall&) = delete;
101 };
102 
104 public:
105  cl::Platform platform;
106  cl::Device device;
107  cl::Context context;
109  cl::CommandQueue queue;
110 
111 protected:
112  std::recursive_mutex mutex;
113  std::map<OCLAPI, cl::Kernel> calls;
114 
115 public:
116  OCLDeviceContext(cl::Platform& p, cl::Device& d, cl::Context& c, int cntxt_id)
117  : platform(p)
118  , device(d)
119  , context(c)
120  , context_id(cntxt_id)
121  , mutex()
122  {
123  queue = cl::CommandQueue(context, d);
124  }
125  OCLDeviceCall Reserve(OCLAPI call) { return OCLDeviceCall(mutex, calls[call]); }
126  friend class OCLEngine;
127 };
128 
130 class OCLEngine {
131 public:
133  static OCLEngine* Instance();
135  DeviceContextPtr GetDeviceContextPtr(const int& dev = -1);
137  std::vector<DeviceContextPtr> GetDeviceContextPtrVector();
142  void SetDeviceContextPtrVector(std::vector<DeviceContextPtr> vec, DeviceContextPtr dcp = nullptr);
144  int GetDeviceCount() { return all_device_contexts.size(); }
146  void SetDefaultDeviceContext(DeviceContextPtr dcp);
147 
148 private:
149  std::vector<DeviceContextPtr> all_device_contexts;
150  DeviceContextPtr default_device_context;
151 
152  OCLEngine(); // Private so that it can not be called
153  OCLEngine(OCLEngine const&); // copy constructor is private
154  OCLEngine& operator=(OCLEngine const& rhs); // assignment operator is private
156 
157  void InitOCL();
158 
159  unsigned long PowerOf2LessThan(unsigned long number);
160 };
161 
162 } // namespace Qrack
Definition: oclengine.hpp:71
Definition: oclengine.hpp:51
Definition: oclengine.hpp:46
Definition: oclengine.hpp:72
OCLDeviceCall(const OCLDeviceCall &)
Definition: oclengine.hpp:70
Definition: oclengine.hpp:80
Definition: oclengine.hpp:73
Definition: oclengine.hpp:43
cl::Context context
Definition: oclengine.hpp:107
Definition: oclengine.hpp:53
OCLAPI
Definition: oclengine.hpp:38
Definition: oclengine.hpp:66
Definition: oclengine.hpp:45
Definition: oclengine.hpp:44
Definition: oclengine.hpp:41
Definition: oclengine.hpp:62
Definition: oclengine.hpp:40
Definition: oclengine.hpp:59
static OCLEngine * m_pInstance
Definition: oclengine.hpp:155
OCLDeviceCall(std::recursive_mutex &m, cl::Kernel &c)
Definition: oclengine.hpp:91
std::shared_ptr< OCLDeviceContext > DeviceContextPtr
Definition: oclengine.hpp:34
Definition: oclengine.hpp:39
Definition: oclengine.hpp:76
Definition: oclengine.hpp:63
Definition: oclengine.hpp:47
std::vector< DeviceContextPtr > all_device_contexts
Definition: oclengine.hpp:149
OCLDeviceCall & operator=(const OCLDeviceCall &)=delete
Definition: oclengine.hpp:103
Definition: oclengine.hpp:74
Definition: oclengine.hpp:48
std::lock_guard< std::recursive_mutex > guard
Definition: oclengine.hpp:82
Definition: oclengine.hpp:77
Definition: oclengine.hpp:50
int context_id
Definition: oclengine.hpp:108
Definition: oclengine.hpp:60
Definition: oclengine.hpp:68
cl::Device device
Definition: oclengine.hpp:106
Definition: oclengine.hpp:75
Definition: oclengine.hpp:49
Definition: oclengine.hpp:67
Definition: oclengine.hpp:54
std::recursive_mutex mutex
Definition: oclengine.hpp:112
std::map< OCLAPI, cl::Kernel > calls
Definition: oclengine.hpp:113
OCLDeviceCall Reserve(OCLAPI call)
Definition: oclengine.hpp:125
Definition: oclengine.hpp:61
"Qrack::OCLEngine" manages the single OpenCL context.
Definition: oclengine.hpp:130
Definition: oclengine.hpp:65
Definition: oclengine.hpp:56
Definition: oclengine.hpp:42
cl::Platform platform
Definition: oclengine.hpp:105
DeviceContextPtr default_device_context
Definition: oclengine.hpp:150
Definition: oclengine.hpp:64
OCLDeviceContext(cl::Platform &p, cl::Device &d, cl::Context &c, int cntxt_id)
Definition: oclengine.hpp:116
Definition: oclengine.hpp:55
Definition: oclengine.hpp:52
Definition: oclengine.hpp:58
Definition: oclengine.hpp:69
Definition: complex16simd.hpp:21
cl::Kernel & call
Definition: oclengine.hpp:87
Definition: oclengine.hpp:57
cl::CommandQueue queue
Definition: oclengine.hpp:109
int GetDeviceCount()
Get the count of devices in the current list.
Definition: oclengine.hpp:144