BioDynaMo  v1.05.120-25dc9790
opencl_state.cc
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------
2 //
3 // Copyright (C) 2021 CERN & University of Surrey for the benefit of the
4 // BioDynaMo collaboration. All Rights Reserved.
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 //
9 // See the LICENSE file distributed with this work for details.
10 // See the NOTICE file distributed with this work for additional information
11 // regarding copyright ownership.
12 //
13 // -----------------------------------------------------------------------------
14 
15 #include "core/gpu/opencl_state.h"
16 
17 #ifdef USE_OPENCL
18 
19 #ifdef __APPLE__
20 #define CL_HPP_ENABLE_EXCEPTIONS
21 #define CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY
22 #define CL_HPP_MINIMUM_OPENCL_VERSION 120
23 #define CL_HPP_TARGET_OPENCL_VERSION 120
24 #include "cl2.hpp"
25 #else
26 #define CL_HPP_ENABLE_EXCEPTIONS
27 #define CL_HPP_MINIMUM_OPENCL_VERSION 210
28 #define CL_HPP_TARGET_OPENCL_VERSION 210
29 #include <CL/cl2.hpp>
30 #endif // __APPLE__
31 
32 #endif // USE_OPENCL
33 
34 namespace bdm {
35 
36 #ifdef USE_OPENCL
37 struct OpenCLState::OpenCLImpl {
38  cl::Context opencl_context_;
39  cl::CommandQueue opencl_command_queue_;
40  // Currently only support for one GPU device
41  std::vector<cl::Device> opencl_devices_;
42  std::vector<cl::Program> opencl_programs_;
43  std::vector<bool> fp64_support_;
44  int selected_gpu_ = -1;
45 };
46 
48  impl_ = std::unique_ptr<OpenCLState::OpenCLImpl,
49  OpenCLState::OpenCLImplDestructor>(
50  new OpenCLState::OpenCLImpl());
51 }
52 
54 cl::Context* OpenCLState::GetOpenCLContext() { return &impl_->opencl_context_; }
55 
57 cl::CommandQueue* OpenCLState::GetOpenCLCommandQueue() {
58  return &impl_->opencl_command_queue_;
59 }
60 
62 std::vector<cl::Device>* OpenCLState::GetOpenCLDeviceList() {
63  return &impl_->opencl_devices_;
64 }
65 
66 void OpenCLState::SelectGpu(int gpu) { impl_->selected_gpu_ = gpu; }
67 
68 std::vector<bool>* OpenCLState::GetFp64Support() {
69  return &impl_->fp64_support_;
70 }
71 
73 std::vector<cl::Program>* OpenCLState::GetOpenCLProgramList() {
74  return &impl_->opencl_programs_;
75 }
76 
77 // Returns if the `Param::preferred_gpu` has support for double
79  return impl_->fp64_support_[impl_->selected_gpu_];
80 }
81 
83  impl_->fp64_support_.push_back(false);
84 }
85 
87  impl_->fp64_support_.push_back(true);
88 }
89 
90 const char* OpenCLState::GetErrorString(int error) {
91  switch (error) {
92  // run-time and JIT compiler errors
93  case 0:
94  return "CL_SUCCESS";
95  case -1:
96  return "CL_DEVICE_NOT_FOUND";
97  case -2:
98  return "CL_DEVICE_NOT_AVAILABLE";
99  case -3:
100  return "CL_COMPILER_NOT_AVAILABLE";
101  case -4:
102  return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
103  case -5:
104  return "CL_OUT_OF_RESOURCES";
105  case -6:
106  return "CL_OUT_OF_HOST_MEMORY";
107  case -7:
108  return "CL_PROFILING_INFO_NOT_AVAILABLE";
109  case -8:
110  return "CL_MEM_COPY_OVERLAP";
111  case -9:
112  return "CL_IMAGE_FORMAT_MISMATCH";
113  case -10:
114  return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
115  case -11:
116  return "CL_BUILD_PROGRAM_FAILURE";
117  case -12:
118  return "CL_MAP_FAILURE";
119  case -13:
120  return "CL_MISALIGNED_SUB_BUFFER_OFFSET";
121  case -14:
122  return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST";
123  case -15:
124  return "CL_COMPILE_PROGRAM_FAILURE";
125  case -16:
126  return "CL_LINKER_NOT_AVAILABLE";
127  case -17:
128  return "CL_LINK_PROGRAM_FAILURE";
129  case -18:
130  return "CL_DEVICE_PARTITION_FAILED";
131  case -19:
132  return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE";
133 
134  // compile-time errors
135  case -30:
136  return "CL_INVALID_VALUE";
137  case -31:
138  return "CL_INVALID_DEVICE_TYPE";
139  case -32:
140  return "CL_INVALID_PLATFORM";
141  case -33:
142  return "CL_INVALID_DEVICE";
143  case -34:
144  return "CL_INVALID_CONTEXT";
145  case -35:
146  return "CL_INVALID_QUEUE_PROPERTIES";
147  case -36:
148  return "CL_INVALID_COMMAND_QUEUE";
149  case -37:
150  return "CL_INVALID_HOST_PTR";
151  case -38:
152  return "CL_INVALID_MEM_OBJECT";
153  case -39:
154  return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
155  case -40:
156  return "CL_INVALID_IMAGE_SIZE";
157  case -41:
158  return "CL_INVALID_SAMPLER";
159  case -42:
160  return "CL_INVALID_BINARY";
161  case -43:
162  return "CL_INVALID_BUILD_OPTIONS";
163  case -44:
164  return "CL_INVALID_PROGRAM";
165  case -45:
166  return "CL_INVALID_PROGRAM_EXECUTABLE";
167  case -46:
168  return "CL_INVALID_KERNEL_NAME";
169  case -47:
170  return "CL_INVALID_KERNEL_DEFINITION";
171  case -48:
172  return "CL_INVALID_KERNEL";
173  case -49:
174  return "CL_INVALID_ARG_INDEX";
175  case -50:
176  return "CL_INVALID_ARG_VALUE";
177  case -51:
178  return "CL_INVALID_ARG_SIZE";
179  case -52:
180  return "CL_INVALID_KERNEL_ARGS";
181  case -53:
182  return "CL_INVALID_WORK_DIMENSION";
183  case -54:
184  return "CL_INVALID_WORK_GROUP_SIZE";
185  case -55:
186  return "CL_INVALID_WORK_ITEM_SIZE";
187  case -56:
188  return "CL_INVALID_GLOBAL_OFFSET";
189  case -57:
190  return "CL_INVALID_EVENT_WAIT_LIST";
191  case -58:
192  return "CL_INVALID_EVENT";
193  case -59:
194  return "CL_INVALID_OPERATION";
195  case -60:
196  return "CL_INVALID_GL_OBJECT";
197  case -61:
198  return "CL_INVALID_BUFFER_SIZE";
199  case -62:
200  return "CL_INVALID_MIP_LEVEL";
201  case -63:
202  return "CL_INVALID_GLOBAL_WORK_SIZE";
203  case -64:
204  return "CL_INVALID_PROPERTY";
205  case -65:
206  return "CL_INVALID_IMAGE_DESCRIPTOR";
207  case -66:
208  return "CL_INVALID_COMPILER_OPTIONS";
209  case -67:
210  return "CL_INVALID_LINKER_OPTIONS";
211  case -68:
212  return "CL_INVALID_DEVICE_PARTITION_COUNT";
213 
214  // extension errors
215  case -1000:
216  return "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR";
217  case -1001:
218  return "CL_PLATFORM_NOT_FOUND_KHR";
219  case -1002:
220  return "CL_INVALID_D3D10_DEVICE_KHR";
221  case -1003:
222  return "CL_INVALID_D3D10_RESOURCE_KHR";
223  case -1004:
224  return "CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR";
225  case -1005:
226  return "CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR";
227  default:
228  return "Unknown OpenCL error";
229  }
230 }
231 
232 int OpenCLState::ClAssert(int const code, char const* const file,
233  int const line, bool const abort) {
234  if (code != CL_SUCCESS) {
235  char const* const err_str = GetErrorString(code);
236 
237  fprintf(stderr, "\"%s\", line %d: ClAssert (%d) = \"%s\"", file, line, code,
238  err_str);
239 
240  if (abort) {
241  // stop profiling and reset device here if necessary
242  exit(code);
243  }
244  }
245 
246  return code;
247 }
248 
249 #else
250 
251 // Empty implementation to avoid linking errors
253 OpenCLState::OpenCLState() = default;
254 cl::Context* OpenCLState::GetOpenCLContext() { return nullptr; }
255 cl::CommandQueue* OpenCLState::GetOpenCLCommandQueue() { return nullptr; }
256 std::vector<cl::Device>* OpenCLState::GetOpenCLDeviceList() { return nullptr; }
257 std::vector<cl::Program>* OpenCLState::GetOpenCLProgramList() {
258  return nullptr;
259 }
260 const char* OpenCLState::GetErrorString(int error) { return nullptr; }
261 int OpenCLState::ClAssert(int const code, char const* const file,
262  int const line, bool const abort) {
263  return 0;
264 }
265 
266 #endif // USE_OPENCL
267 
269 
270 } // namespace bdm
bdm::OpenCLState::OpenCLImplDestructor::operator()
void operator()(OpenCLImpl *p)
Definition: opencl_state.cc:268
opencl_state.h
bdm
Definition: agent.cc:39
bdm::OpenCLState::impl_
std::unique_ptr< OpenCLImpl, OpenCLImplDestructor > impl_
Definition: opencl_state.h:74
bdm::OpenCLState::GetOpenCLProgramList
std::vector< cl::Program > * GetOpenCLProgramList()
Returns the OpenCL program (kernel) list.
Definition: opencl_state.cc:257
bdm::OpenCLState::GetOpenCLContext
cl::Context * GetOpenCLContext()
Returns the OpenCL Context.
Definition: opencl_state.cc:254
bdm::OpenCLState::GetOpenCLDeviceList
std::vector< cl::Device > * GetOpenCLDeviceList()
Returns the OpenCL device (GPU) list.
Definition: opencl_state.cc:256
bdm::OpenCLState::HasSupportForDouble
bool HasSupportForDouble()
bdm::OpenCLState::DisableSupportForDouble
void DisableSupportForDouble()
Disable support for double-precision floating point operations.
bdm::OpenCLState::SelectGpu
void SelectGpu(int gpu)
bdm::OpenCLState::GetErrorString
const char * GetErrorString(int error)
Definition: opencl_state.cc:260
bdm::OpenCLState::GetFp64Support
std::vector< bool > * GetFp64Support()
bdm::OpenCLState::OpenCLImpl
Definition: opencl_state.cc:252
bdm::OpenCLState::EnableSupportForDouble
void EnableSupportForDouble()
Enable support for double-precision floating point operations.
bdm::OpenCLState::OpenCLState
OpenCLState()
bdm::OpenCLState::GetOpenCLCommandQueue
cl::CommandQueue * GetOpenCLCommandQueue()
Returns the OpenCL command queue.
Definition: opencl_state.cc:255
bdm::OpenCLState::ClAssert
int ClAssert(int const code, char const *const file, int const line, bool const abort)
Definition: opencl_state.cc:261