Loading [MathJax]/extensions/tex2jax.js
Parallel numerical verification of the σ_odd problem  October 6, 2018
All Classes Namespaces Files Functions Variables Typedefs Macros
helper.cpp
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 /** \file opencl/opencl/helper.cpp (January 8, 2018)
3  *
4  * GPLv3 --- Copyright (C) 2017, 2018 Olivier Pirson
5  * http://www.opimedia.be/
6  */
7 
8 // \cond
9 #include <cassert>
10 
11 #include <fstream>
12 #include <iostream>
13 #include <string>
14 #include <vector>
15 // \endcond
16 
17 #include "../../common/helper/helper.hpp"
18 
19 #include "helper.hpp"
20 
21 
22 namespace opencl {
23 
24  /* **********
25  * Constant *
26  ************/
27 
28  const std::map<int32_t, std::string> errors_map {
29  // Extracted from /usr/include/CL/cl.h
30 #include "errors_map.txt"
31  };
32 
33 
34 
35  /* ***********
36  * Functions *
37  *************/
38 
39  // Define function to get device information for each type.
40  // https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html
41 #ifdef __CL_ENABLE_EXCEPTIONS
42 #define GET_DEVICE_INFO_NAME_TYPE(NAME, TYPE) \
43  TYPE \
44  get_device_info_##NAME(const cl::Device &device, cl_device_info info) { \
45  TYPE value; \
46  \
47  try { \
48  const cl_int error = device.getInfo(info, &value); \
49  \
50  if (error != CL_SUCCESS) { \
51  std::cerr << "! Device::getInfo(" << info << ") error in get " \
52  << #TYPE << ": \"" \
53  << error_name(error) << '"' <<std::endl; \
54  } \
55  } \
56  catch (const cl::Error &e) { \
57  std::cerr << "! Device::getInfo(" << info << ") exception in get " \
58  << #TYPE << ": \"" \
59  << e.what() << '"' << std::endl; \
60  } \
61  \
62  return value; \
63  }
64 #else
65 #define GET_DEVICE_INFO_NAME_TYPE(NAME, TYPE) \
66  TYPE \
67  get_device_info_##NAME(const cl::Device &device, cl_device_info info) { \
68  TYPE value; \
69  \
70  const cl_int error = device.getInfo(info, &value); \
71  \
72  if (error != CL_SUCCESS) { \
73  std::cerr << "! Device::getInfo(" << info << ") error in get " \
74  << #TYPE << ": \"" \
75  << error_name(error) << '"' <<std::endl; \
76  } \
77  \
78  return value; \
79  }
80 #endif
81 
82 #define GET_DEVICE_INFO_TYPE(TYPE) GET_DEVICE_INFO_NAME_TYPE(TYPE, TYPE)
83 
84  GET_DEVICE_INFO_TYPE(cl_bool)
85 
86  GET_DEVICE_INFO_TYPE(cl_device_fp_config)
87 
88  GET_DEVICE_INFO_TYPE(cl_device_local_mem_type)
89 
90  GET_DEVICE_INFO_TYPE(cl_device_mem_cache_type)
91 
92  GET_DEVICE_INFO_TYPE(cl_device_type)
93 
94  GET_DEVICE_INFO_TYPE(cl_uint)
95 
96  GET_DEVICE_INFO_TYPE(cl_ulong)
97 
98  GET_DEVICE_INFO_TYPE(size_t)
99 
100  GET_DEVICE_INFO_NAME_TYPE(vector_size_t, VECTOR_CLASS<::size_t>)
101 
102 #undef GET_DEVICE_INFO_NAME_TYPE
103 #undef GET_DEVICE_INFO_TYPE
104 
105 
106  std::string
107  get_device_info_string(const cl::Device &device, cl_device_info info) {
108  std::string value;
109 
110 #ifdef __CL_ENABLE_EXCEPTIONS
111  try {
112 #endif
113  const cl_int error = device.getInfo(info, &value);
114 
115  if (error != CL_SUCCESS) {
116  std::cerr << "! Device::getInfo(" << info << ") error in get string: \""
117  << error_name(error) << '"' << std::endl;
118  }
119 #ifdef __CL_ENABLE_EXCEPTIONS
120  }
121  catch (const cl::Error &e) {
122  std::cerr << "! Device::getInfo(" << info << ") exception to get string: \""
123  << e.what() << '"' << std::endl;
124  }
125 #endif
126 
128  }
129 
130 
131  cl::Device
133  std::vector<cl::Platform> platforms;
134 
135  cl::Platform::get(&platforms);
136  for (cl::Platform platform : platforms) {
137  std::vector<cl::Device> devices;
138 
139  platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
140 
141  if (!devices.empty()) {
142  return devices[0];
143  }
144  }
145 
146  std::cerr << "! No GPU found!" << std::endl;
147 
148  exit(EXIT_FAILURE);
149  }
150 
151 
152  std::string
153  error_name(cl_int code) {
154  const auto it = errors_map.find(code);
155 
156  return (it == errors_map.cend()
157  ? "unknow"
158  : it->second);
159  }
160 
161 
162  void
163  print_device(const cl::Device &device) {
164  std::cout << " Driver version: \"";
165  std::cout << get_device_info_string(device, CL_DRIVER_VERSION) << '"' << std::endl;
166 
167  std::cout << " Device name: \"";
168  std::cout << get_device_info_string(device, CL_DEVICE_NAME) << '"' << std::endl;
170  std::cout << " address_bits: ";
171  std::cout << get_device_info_cl_uint(device, CL_DEVICE_ADDRESS_BITS) << std::endl;
172 
173  std::cout << " available?: ";
174  std::cout << helper::to_string(get_device_info_cl_bool(device, CL_DEVICE_AVAILABLE)) << std::endl;
175 
176  std::cout << " built in kernels: \"";
177  std::cout << get_device_info_string(device, CL_DEVICE_BUILT_IN_KERNELS) << '"' << std::endl;
178 
179  std::cout << " compiler available?: ";
180  std::cout << helper::to_string(get_device_info_cl_bool(device, CL_DEVICE_COMPILER_AVAILABLE)) << std::endl;
181 
182  std::cout << " double fp config: ";
183  std::cout << helper::to_string(get_device_info_cl_device_fp_config(device, CL_DEVICE_DOUBLE_FP_CONFIG)) << std::endl;
184 
185  std::cout << " endian little? ";
186  std::cout << helper::to_string(get_device_info_cl_bool(device, CL_DEVICE_ENDIAN_LITTLE)) << std::endl;
187 
188  std::cout << " extensions: \"";
189  std::cout << get_device_info_string(device, CL_DEVICE_EXTENSIONS) << '"' << std::endl;
190 
191  std::cout << " global mem cache size: ";
192  std::cout << get_device_info_cl_ulong(device, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE) << std::endl;
193 
194  std::cout << " global mem cache type: ";
195  std::cout << get_device_info_cl_device_mem_cache_type(device, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE) << std::endl;
196 
197  std::cout << " global mem cacheline size: ";
198  std::cout << get_device_info_cl_uint(device, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE) << std::endl;
199 
200  std::cout << " global mem size: ";
201  std::cout << get_device_info_cl_ulong(device, CL_DEVICE_GLOBAL_MEM_SIZE) << std::endl;
202 
203  std::cout << " image max array size: ";
204  std::cout << get_device_info_size_t(device, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE) << std::endl;
205 
206  std::cout << " image max buffer size: ";
207  std::cout << get_device_info_size_t(device, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE) << std::endl;
208 
209  std::cout << " image support? ";
210  std::cout << helper::to_string(get_device_info_cl_bool(device, CL_DEVICE_IMAGE_SUPPORT)) << std::endl;
211 
212  std::cout << " linker available?: ";
213  std::cout << helper::to_string(get_device_info_cl_bool(device, CL_DEVICE_LINKER_AVAILABLE)) << std::endl;
214 
215  std::cout << " local mem size: ";
216  std::cout << get_device_info_cl_ulong(device, CL_DEVICE_LOCAL_MEM_SIZE) << std::endl;
217 
218  std::cout << " local mem type: ";
219  std::cout << get_device_info_cl_device_local_mem_type(device, CL_DEVICE_LOCAL_MEM_TYPE) << std::endl;
220 
221  std::cout << " max clock frequency: ";
222  std::cout << get_device_info_cl_uint(device, CL_DEVICE_MAX_CLOCK_FREQUENCY) << std::endl;
223 
224  std::cout << " max compute units: ";
225  std::cout << get_device_info_cl_uint(device, CL_DEVICE_MAX_COMPUTE_UNITS) << std::endl;
226 
227  std::cout << " max constant buffer size: ";
228  std::cout << get_device_info_cl_ulong(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE) << std::endl;
229 
230  std::cout << " max mem alloc size: ";
231  std::cout << get_device_info_cl_ulong(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE) << std::endl;
232 
233  std::cout << " max work group size: ";
234  std::cout << get_device_info_size_t(device, CL_DEVICE_MAX_WORK_GROUP_SIZE) << std::endl;
235 
236  std::cout << " max work item sizes:";
237  for (size_t item_size : get_device_info_vector_size_t(device, CL_DEVICE_MAX_WORK_ITEM_SIZES)) {
238  std::cout << ' ' << item_size;
239  }
240  std::cout << std::endl;
241 
242  std::cout << " mem base addr align: ";
243  std::cout << get_device_info_cl_uint(device, CL_DEVICE_MEM_BASE_ADDR_ALIGN) << std::endl;
244 
245  std::cout << " min_data_type_align_size: ";
246  std::cout << get_device_info_cl_uint(device, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE) << std::endl;
247 
248  std::cout << " OpenCL C version: \"";
249  std::cout << get_device_info_string(device, CL_DEVICE_OPENCL_C_VERSION) << '"' << std::endl;
250 
251  std::cout << " Profile: \"";
252  std::cout << get_device_info_string(device, CL_DEVICE_PROFILE) << '"' << std::endl;
253 
254  std::cout << " SPIR versions: \"";
255  std::cout << get_device_info_string(device, CL_DEVICE_SPIR_VERSIONS) << '"' << std::endl;
256 
257  std::cout << " type: ";
258  std::cout << get_device_info_cl_device_type(device, CL_DEVICE_TYPE) << std::endl;
259 
260  std::cout << " version: \"";
261  std::cout << get_device_info_string(device, CL_DEVICE_VERSION) << '"' << std::endl;
262 
263 #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
264  // https://www.khronos.org/registry/OpenCL/extensions/nv/cl_nv_device_attribute_query.txt
265  std::cout << " compute capability major NV: ";
266  std::cout << get_device_info_cl_uint(device, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV) << std::endl;
267 
268  std::cout << " compute capability minor NV: ";
269  std::cout << get_device_info_cl_uint(device, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV) << std::endl;
270 
271  std::cout << " registers per block NV: ";
272  std::cout << get_device_info_cl_uint(device, CL_DEVICE_REGISTERS_PER_BLOCK_NV) << std::endl;
273 
274  std::cout << " warp size NV: ";
275  std::cout << get_device_info_cl_uint(device, CL_DEVICE_WARP_SIZE_NV) << std::endl;
276 
277  std::cout << " GPU overlap NV: ";
278  std::cout << helper::to_string(get_device_info_cl_bool(device, CL_DEVICE_GPU_OVERLAP_NV)) << std::endl;
279 
280  std::cout << " kernel exec timeout NV: ";
281  std::cout << helper::to_string(get_device_info_cl_bool(device, CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV)) << std::endl;
282 
283  std::cout << " integrated memory NV: ";
284  std::cout << helper::to_string(get_device_info_cl_bool(device, CL_DEVICE_INTEGRATED_MEMORY_NV)) << std::endl;
285 #endif
286  }
287 
288 
289  void
290  print_error(cl_int code, std::string message,
291  bool only_if_error, bool exit_if_error) {
292  if ((code != 0) || !only_if_error) {
293  if (!message.empty()) {
294  message = " " + message;
295  }
296 
297  std::cerr << "! OpenCL error "
298  << code << ' ' << error_name(code)
299  << message
300  << std::endl;
301  std::cerr.flush();
302 
303  if (exit_if_error) {
304  exit(EXIT_FAILURE);
305  }
306  }
307  }
308 
309 
310  void
311  print_platform(const cl::Platform &platform) {
312  std::cout << std::string(30, '=') << std::endl;
313 
314  std::string platform_name;
315  std::string platform_vendor;
316  std::string platform_version;
317  std::string platform_profile;
318  std::string platform_extensions;
319 
320  platform.getInfo(CL_PLATFORM_NAME, &platform_name);
321  platform.getInfo(CL_PLATFORM_VENDOR, &platform_vendor);
322  platform.getInfo(CL_PLATFORM_VERSION, &platform_version);
323  platform.getInfo(CL_PLATFORM_PROFILE, &platform_profile);
324  platform.getInfo(CL_PLATFORM_EXTENSIONS, &platform_extensions);
325 
326  std::cout
327  << "Platform name: \"" << helper::remove_last_if_null(platform_name) << '"' << std::endl
328  << " vendor: \"" << helper::remove_last_if_null(platform_vendor) << '"' << std::endl
329  << " version: \"" << helper::remove_last_if_null(platform_version) << '"' << std::endl
330  << " profile: \"" << helper::remove_last_if_null(platform_profile) << '"' << std::endl
331  << " extensions: \"" << helper::remove_last_if_null(platform_extensions) << '"' << std::endl
332  << std::endl;
333 
334  std::vector<cl::Device> devices;
335 
336  // https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/clGetDeviceIDs.html
337  platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
338  for (cl::Device device : devices) {
339  print_device(device);
340  }
341  }
342 
343 
344  void
345  print_platforms() {
346  std::vector<cl::Platform> platforms;
347 
348  // https://www.khronos.org/registry/OpenCL/sdk/1.1/docs/man/xhtml/clGetPlatformIDs.html
349  cl::Platform::get(&platforms);
350  for (cl::Platform platform : platforms) {
351  print_platform(platform);
352  }
353  }
354 
355 } // namespace opencl
cl_ulong get_device_info_cl_ulong(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.
cl::Device get_first_device_gpu()
Return the first GPU device found. If not found then print an error message and exit.
Definition: helper.cpp:194
cl_device_type get_device_info_cl_device_type(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.
std::string remove_last_if_null(const std::string &s)
If s terminates by a null character then return a copy of s without this last character, else return s.
Definition: helper.cpp:169
std::string get_device_info_string(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.
Definition: helper.cpp:169
#define GET_DEVICE_INFO_NAME_TYPE(NAME, TYPE)
Definition: helper.cpp:127
cl_uint get_device_info_cl_uint(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.
std::string error_name(cl_int code)
Return the error name corresponding to the error code.
Definition: helper.cpp:215
cl_device_local_mem_type get_device_info_cl_device_local_mem_type(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.
cl_device_fp_config get_device_info_cl_device_fp_config(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.
void print_device(const cl::Device &device)
Print information on this device.
Definition: helper.cpp:225
Some generic helper functions for programs.
void print_platform(const cl::Platform &platform)
Print information on this platform.
Definition: helper.cpp:373
void print_error(cl_int code, std::string message, bool only_if_error, bool exit_if_error)
Print an error message corresponding to the error code.
Definition: helper.cpp:352
size_t get_device_info_size_t(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.
#define GET_DEVICE_INFO_TYPE(TYPE)
Definition: helper.cpp:144
void print_platforms()
Print information on all platforms.
Definition: helper.cpp:407
cl_bool get_device_info_cl_bool(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.
cl_device_mem_cache_type get_device_info_cl_device_mem_cache_type(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.
const std::map< int32_t, std::string > errors_map
Table associating error codes to error names.
Definition: helper.cpp:28
std::string to_string(bool b)
Return the string "true" if b, else "false".
Definition: helper.cpp:177
VECTOR_CLASS<::size_t > get_device_info_vector_size_t(const cl::Device &device, cl_device_info info)
Return the corresponding information about the device.