vSMC
vSMC: Scalable Monte Carlo
cl_query.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/opencl/cl_query.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_OPENCL_CL_QUERY_HPP
33 #define VSMC_OPENCL_CL_QUERY_HPP
34 
35 #include <vsmc/internal/common.hpp>
37 
38 namespace vsmc {
39 
43 {
46 };
47 
50 class CLQuery
51 {
52  public :
53 
66  static int opencl_version (const ::cl::Device &dev)
67  {
68  std::string version;
69  dev.getInfo(CL_DEVICE_VERSION, &version);
70 
71  return check_opencl_version(version.substr(7, 3));
72  }
73 
77  static int opencl_c_version (const ::cl::Device &dev)
78  {
79  std::string version;
80  dev.getInfo(CL_DEVICE_OPENCL_C_VERSION, &version);
81 
82  return check_opencl_version(version.substr(9, 3));
83  }
84 
86  template <OpenCLDeviceFeature feat>
87  static bool has_feature (const ::cl::Device &dev)
88  {
89  return check_feature(dev,
91  }
92 
94  template < ::cl_device_type DevType>
95  static bool has_device (const ::cl::Platform &plat)
96  {
97  std::vector< ::cl::Device> device;
98  plat.getDevices(CL_DEVICE_TYPE_ALL, &device);
99  for (std::size_t i = 0; i != device.size(); ++i) {
100  ::cl_device_type type;
101  device[i].getInfo(CL_DEVICE_TYPE, &type);
102  if ((type & DevType) != 0)
103  return true;
104  }
105 
106  return false;
107  }
108 
110  template < ::cl_device_type DevType>
111  static bool has_device ()
112  {
113  std::vector< ::cl::Platform> platform;
114  ::cl::Platform::get(&platform);
115  for (std::size_t i = 0; i != platform.size(); ++i)
116  if (has_device<DevType>(platform[i]))
117  return true;
118 
119  return false;
120  }
121 
123  static std::vector<std::string> program_binary (
124  const ::cl::Program &program)
125  {
126  ::cl_uint num;
127  program.getInfo(CL_PROGRAM_NUM_DEVICES, &num);
128 
129  std::vector<std::size_t> bin_size(num);
130  program.getInfo(CL_PROGRAM_BINARY_SIZES, &bin_size);
131 
132  std::vector<std::vector<char> > bin_vec(num);
133  std::vector<char *> bin_ptr(num);
134  for (std::size_t i = 0; i != bin_vec.size(); ++i) {
135  bin_vec[i].resize(bin_size[i]);
136  bin_ptr[i] = &bin_vec[i][0];
137  }
138  program.getInfo(CL_PROGRAM_BINARIES, &bin_ptr);
139 
140  std::vector<std::string> bin(num);
141  for (std::size_t i = 0; i != bin_vec.size(); ++i)
142  bin[i] = std::string(bin_vec[i].begin(), bin_vec[i].end());
143 
144  return bin;
145  }
146 
148  static std::vector< ::cl::Device> program_device (
149  const ::cl::Program program)
150  {
151  ::cl_uint num;
152  program.getInfo(CL_PROGRAM_NUM_DEVICES, &num);
153 
154  std::vector< ::cl::Device> devices(num);
155  program.getInfo(CL_PROGRAM_DEVICES, &devices);
156 
157  return devices;
158  }
159 
161  static std::string program_source (const ::cl::Program &program)
162  {
163  std::string src;
164  program.getInfo(CL_PROGRAM_SOURCE, &src);
165 
166  return src;
167  }
168 
170  static std::vector<std::pair< ::cl_build_status, std::string> >
171  program_build_log (const ::cl::Program &program)
172  {
173  std::string log;
174  ::cl_build_status status = CL_BUILD_SUCCESS;
175  std::vector< ::cl::Device> devices(program_device(program));
176  std::vector<std::pair< ::cl_build_status, std::string> > build_log;
177  for (std::size_t i = 0; i != devices.size(); ++i) {
178  program.getBuildInfo(devices[i], CL_PROGRAM_BUILD_STATUS, &status);
179  program.getBuildInfo(devices[i], CL_PROGRAM_BUILD_LOG, &log);
180  build_log.push_back(std::make_pair(status, log));
181  }
182 
183  return build_log;
184  }
185 
187  template <typename CharT, typename Traits>
188  static std::vector<std::pair< ::cl_build_status, std::string> >
189  program_build_log (const ::cl::Program &program,
190  std::basic_ostream<CharT, Traits> &os)
191  {
192  std::string line(78, '=');
193  line += "\n";
194 
195  std::string dname;
196  std::vector< ::cl::Device> devices(program_device(program));
197  std::vector<std::pair< ::cl_build_status, std::string> > build_log(
198  program_build_log(program));
199  for (std::size_t i = 0; i != build_log.size(); ++i) {
200  devices[i].getInfo(CL_DEVICE_NAME, &dname);
201  if (build_log[i].first == CL_BUILD_SUCCESS)
202  os << line << "Build successed for : " << dname << std::endl;
203  else
204  os << line << "Build failed for : " << dname << std::endl;
205  os << line << build_log[i].second << '\n' << line << std::endl;
206  }
207 
208  return build_log;
209  }
210 
212  template <typename CharT, typename Traits>
213  static std::basic_ostream<CharT, Traits> &info (
214  std::basic_ostream<CharT, Traits> &os)
215  {
216  if (!os.good())
217  return os;
218 
219  std::vector< ::cl::Platform> platform;
220  ::cl::Platform::get(&platform);
221  for (std::size_t i = 0; i != platform.size(); ++i)
222  info(os, platform[i]);
223  print_equal(os);
224 
225  return os;
226  }
227 
229  template <typename CharT, typename Traits>
230  static std::basic_ostream<CharT, Traits> &info (
231  std::basic_ostream<CharT, Traits> &os, const ::cl::Platform &plat)
232  {
233  if (!os.good())
234  return os;
235 
236  print_equal(os);
237 
238  print_info_val<std::string, ::cl_platform_info>(os, plat,
239  CL_PLATFORM_NAME, "CL_PLATFORM_NAME");
240  print_info_val<std::string, ::cl_platform_info>(os, plat,
241  CL_PLATFORM_VENDOR, "CL_PLATFORM_VENDOR");
242  print_info_val<std::string, ::cl_platform_info>(os, plat,
243  CL_PLATFORM_VERSION, "CL_PLATFORM_VERSION");
244  print_info_val<std::string, ::cl_platform_info>(os, plat,
245  CL_PLATFORM_PROFILE, "CL_PLATFORM_PROFILE");
246  print_plat_extensions(os, plat);
247 
248  std::vector< ::cl::Device> device;
249  plat.getDevices(CL_DEVICE_TYPE_ALL, &device);
250  for (std::size_t i = 0; i != device.size(); ++i)
251  info(os, device[i]);
252 
253  return os;
254  }
255 
257  template <typename CharT, typename Traits>
258  static std::basic_ostream<CharT, Traits> &info (
259  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
260  {
261  if (!os.good())
262  return os;
263 
264  print_dash(os);
265  print_dev_version(os, dev);
266  os << '\n';
267  print_dev_extensions(os, dev);
268  os << '\n';
269  print_dev_processor(os, dev);
270  os << '\n';
271  print_dev_memory(os, dev);
272  os << '\n';
273  print_dev_vector(os, dev);
274 #if VSMC_OPENCL_VERSION >= 120
275  os << '\n';
276  print_dev_single_fp_config(os, dev);
277  os << '\n';
278  print_dev_double_fp_config(os, dev);
279  if (opencl_version(dev) >= 120) {
280  os << '\n';
281  print_info_val<std::string, ::cl_device_info>(os, dev,
282  CL_DEVICE_BUILT_IN_KERNELS,
283  "CL_DEVICE_BUILT_IN_KERNELS");
284  os << '\n';
285  print_dev_image_support(os, dev);
286  }
287 #endif // VSMC_OPENCL_VERSION >= 120
288 
289  return os;
290  }
291 
293  template <typename CharT, typename Traits>
294  static std::basic_ostream<CharT, Traits> &info (
295  std::basic_ostream<CharT, Traits> &os, const ::cl::Context &ctx)
296  {
297  if (!os.good())
298  return os;
299 
300  std::vector< ::cl::Device> device;
301  ctx.getInfo(CL_CONTEXT_DEVICES, &device);
302  for (std::size_t i = 0; i != device.size(); ++i)
303  info(os, device[i]);
304 
305  return os;
306  }
307 
309  template <typename CharT, typename Traits>
310  static std::basic_ostream<CharT, Traits> &info (
311  std::basic_ostream<CharT, Traits> &os, const ::cl::Program &prog)
312  {
313  if (!os.good())
314  return os;
315 
316  print_info_val< ::cl_uint, ::cl_program_info>(os, prog,
317  CL_PROGRAM_NUM_DEVICES, "CL_PROGRAM_NUM_DEVICES");
318  print_info_val<std::size_t, ::cl_program_info>(os, prog,
319  CL_PROGRAM_BINARY_SIZES, "CL_PROGRAM_BINARY_SIZES", "byte");
320 
321  return os;
322  }
323 
325  template <typename CharT, typename Traits>
326  static std::basic_ostream<CharT, Traits> &info (
327  std::basic_ostream<CharT, Traits> &os, const ::cl::Kernel &kern)
328  {
329  if (!os.good())
330  return os;
331 
332  ::cl::Context ctx;
333  kern.getInfo(CL_KERNEL_CONTEXT, &ctx);
334  std::vector< ::cl::Device> device;
335  ctx.getInfo(CL_CONTEXT_DEVICES, &device);
336  for (std::size_t i = 0; i != device.size(); ++i) {
337  print_info_val<std::string, ::cl_device_info>(os, device[i],
338  CL_DEVICE_NAME,
339  "CL_DEVICE_NAME");
340  print_info_val<std::string, ::cl_kernel_info>(os, kern,
341  CL_KERNEL_FUNCTION_NAME,
342  "CL_KERNEL_FUNCTION_NAME");
343  print_info_val< ::cl_uint, ::cl_kernel_info>(os, kern,
344  CL_KERNEL_NUM_ARGS,
345  "CL_KERNEL_NUM_ARGS");
346  print_kernwginfo_val<std::size_t>(os, kern, device[i],
347  CL_KERNEL_WORK_GROUP_SIZE,
348  "CL_KERNEL_WORK_GROUP_SIZE");
349  print_kernwginfo_val<std::size_t>(os, kern, device[i],
350  CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE,
351  "CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE");
352  print_kernwginfo_val< ::cl_ulong>(os, kern, device[i],
353  CL_KERNEL_LOCAL_MEM_SIZE,
354  "CL_KERNEL_LOCAL_MEM_SIZE", "byte");
355  print_kernwginfo_val< ::cl_ulong>(os, kern, device[i],
356  CL_KERNEL_PRIVATE_MEM_SIZE,
357  "CL_KERNEL_PRIVATE_MEM_SIZE", "byte");
358  }
359 
360  return os;
361  }
362 
365  template <typename CharT, typename Traits>
366  static std::basic_ostream<CharT, Traits> &info (
367  std::basic_ostream<CharT, Traits> &os,
368  const ::cl::Program &prog, const std::string &kname)
369  {
370  if (!os.good())
371  return os;
372 
373  ::cl::Kernel kern(prog, kname.c_str());
374  info(os, kern);
375 
376  return os;
377  }
378 
379  private :
380 
381  static int check_opencl_version (const std::string &version)
382  {
383 #if VSMC_OPENCL_VERSION >= 200
384  if (version == std::string("2.0"))
385  return 200;
386 #endif
387 #if VSMC_OPENCL_VERSION >= 120
388  if (version == std::string("1.2"))
389  return 120;
390 #endif
391 #if VSMC_OPENCL_VERSION >= 110
392  if (version == std::string("1.1"))
393  return 110;
394 #endif
395  return 100;
396  }
397 
398  static bool check_feature (const ::cl::Device &dev,
399  cxx11::integral_constant<OpenCLDeviceFeature,
401  {
402  std::string info;
403  dev.getInfo(CL_DEVICE_EXTENSIONS, &info);
404  if (info.find("cl_khr_fp64") != std::string::npos)
405  return true;
406 #if VSMC_OPENCL_VERSION >= 120
407  ::cl_device_fp_config config;
408  dev.getInfo(CL_DEVICE_DOUBLE_FP_CONFIG, &config);
409  if (config != 0)
410  return true;
411 #endif
412  return false;
413  }
414 
415  static bool check_feature (const ::cl::Device &dev,
416  cxx11::integral_constant<OpenCLDeviceFeature,
418  {
419 #if VSMC_OPENCL_VERSION >= 120
420  ::cl_bool support;
421  dev.getInfo(CL_DEVICE_IMAGE_SUPPORT, &support);
422  if (support != 0)
423  return true;
424 #endif
425  return false;
426  }
427 
428  template <typename CharT, typename Traits>
429  static void print_equal (std::basic_ostream<CharT, Traits> &os)
430  {os << std::string(90, '=') << '\n';}
431 
432  template <typename CharT, typename Traits>
433  static void print_dash (std::basic_ostream<CharT, Traits> &os)
434  {os << std::string(90, '-') << '\n';}
435 
436  template <typename CharT, typename Traits>
437  static void print_plat_extensions (
438  std::basic_ostream<CharT, Traits> &os, const ::cl::Platform &plat)
439  {
440  std::string info;
441  plat.getInfo(CL_PLATFORM_EXTENSIONS, &info);
442  print_name(os, "CL_PLATFORM_EXTENSIONS");
443  print_val(os, split_string(info));
444  os << '\n';
445  }
446 
447  template <typename CharT, typename Traits>
448  static void print_dev_version (
449  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
450  {
451  print_info_val<std::string, ::cl_device_info>(os, dev,
452  CL_DEVICE_NAME, "CL_DEVICE_NAME");
453  print_dev_type(os, dev);
454  print_info_val<std::string, ::cl_device_info>(os, dev,
455  CL_DEVICE_VENDOR, "CL_DEVICE_VENDOR");
456  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
457  CL_DEVICE_VENDOR_ID, "CL_DEVICE_VENDOR_ID");
458  print_info_val<std::string, ::cl_device_info>(os, dev,
459  CL_DRIVER_VERSION, "CL_DRIVER_VERSION");
460  print_info_val<std::string, ::cl_device_info>(os, dev,
461  CL_DEVICE_PROFILE, "CL_DEVICE_PROFILE");
462  print_info_val<std::string, ::cl_device_info>(os, dev,
463  CL_DEVICE_VERSION, "CL_DEVICE_VERSION");
464  print_info_val<std::string, ::cl_device_info>(os, dev,
465  CL_DEVICE_OPENCL_C_VERSION, "CL_DEVICE_OPENCL_C_VERSION");
466  }
467 
468  template <typename CharT, typename Traits>
469  static void print_dev_extensions (
470  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
471  {
472  std::string info;
473  dev.getInfo(CL_DEVICE_EXTENSIONS, &info);
474  print_name(os, "CL_DEVICE_EXTENSIONS");
475  print_val(os, split_string(info));
476  os << '\n';
477  }
478 
479  template <typename CharT, typename Traits>
480  static void print_dev_type (
481  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
482  {
483  ::cl_device_type type;
484  std::vector<std::string> info;
485  dev.getInfo(CL_DEVICE_TYPE, &type);
486 
487  append_bit_field< ::cl_device_type>(CL_DEVICE_TYPE_CPU,
488  type, "CL_DEVICE_TYPE_CPU", info);
489  append_bit_field< ::cl_device_type>(CL_DEVICE_TYPE_GPU,
490  type, "CL_DEVICE_TYPE_GPU", info);
491  append_bit_field< ::cl_device_type>(CL_DEVICE_TYPE_ACCELERATOR,
492  type, "CL_DEVICE_TYPE_ACCELERATOR", info);
493  append_bit_field< ::cl_device_type>(CL_DEVICE_TYPE_DEFAULT,
494  type, "CL_DEVICE_TYPE_DEFAULT", info);
495  append_bit_field< ::cl_device_type>(CL_DEVICE_TYPE_CUSTOM,
496  type, "CL_DEVICE_TYPE_CUSTOM", info);
497 
498  print_name(os, "CL_DEVICE_TYPE");
499  print_val(os, info);
500  os << '\n';
501  }
502 
503  template <typename CharT, typename Traits>
504  static void print_dev_processor (
505  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
506  {
507  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
508  CL_DEVICE_MAX_CLOCK_FREQUENCY,
509  "CL_DEVICE_MAX_CLOCK_FREQUENCY", "MHz");
510  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
511  CL_DEVICE_MAX_COMPUTE_UNITS,
512  "CL_DEVICE_MAX_COMPUTE_UNITS");
513  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
514  CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS,
515  "CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS");
516  print_info_val<std::vector<std::size_t>, ::cl_device_info>(os, dev,
517  CL_DEVICE_MAX_WORK_ITEM_SIZES,
518  "CL_DEVICE_MAX_WORK_ITEM_SIZES");
519  print_info_val<std::size_t, ::cl_device_info>(os, dev,
520  CL_DEVICE_MAX_WORK_GROUP_SIZE,
521  "CL_DEVICE_MAX_WORK_GROUP_SIZE");
522  print_info_val<std::size_t, ::cl_device_info>(os, dev,
523  CL_DEVICE_PROFILING_TIMER_RESOLUTION,
524  "CL_DEVICE_PROFILING_TIMER_RESOLUTION", "ns");
525  }
526 
527  template <typename CharT, typename Traits>
528  static void print_dev_memory (
529  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
530  {
531  print_info_val<std::size_t, ::cl_device_info>(os, dev,
532  CL_DEVICE_MAX_PARAMETER_SIZE,
533  "CL_DEVICE_MAX_PARAMETER_SIZE", "byte");
534  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
535  CL_DEVICE_ADDRESS_BITS,
536  "CL_DEVICE_ADDRESS_BITS", "bit");
537  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
538  CL_DEVICE_MEM_BASE_ADDR_ALIGN,
539  "CL_DEVICE_MEM_BASE_ADDR_ALIGN", "bit");
540  print_info_val< ::cl_ulong, ::cl_device_info>(os, dev,
541  CL_DEVICE_MAX_MEM_ALLOC_SIZE,
542  "CL_DEVICE_MAX_MEM_ALLOC_SIZE", "byte");
543  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
544  CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE,
545  "CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE", "byte");
546  print_info_val< ::cl_ulong, ::cl_device_info>(os, dev,
547  CL_DEVICE_GLOBAL_MEM_CACHE_SIZE,
548  "CL_DEVICE_GLOBAL_MEM_CACHE_SIZE", "byte");
549  print_info_val< ::cl_ulong, ::cl_device_info>(os, dev,
550  CL_DEVICE_GLOBAL_MEM_SIZE,
551  "CL_DEVICE_GLOBAL_MEM_SIZE", "byte");
552  print_info_val< ::cl_ulong, ::cl_device_info>(os, dev,
553  CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,
554  "CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE", "byte");
555  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
556  CL_DEVICE_MAX_CONSTANT_ARGS,
557  "CL_DEVICE_MAX_CONSTANT_ARGS");
558  print_info_val< ::cl_ulong, ::cl_device_info>(os, dev,
559  CL_DEVICE_LOCAL_MEM_SIZE,
560  "CL_DEVICE_LOCAL_MEM_SIZE", "byte");
561  print_info_val< ::cl_bool, ::cl_device_info>(os, dev,
562  CL_DEVICE_ERROR_CORRECTION_SUPPORT,
563  "CL_DEVICE_ERROR_CORRECTION_SUPPORT");
564  }
565 
566  template <typename CharT, typename Traits>
567  static void print_dev_vector (
568  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
569  {
570  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
571  CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR,
572  "CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR");
573  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
574  CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT,
575  "CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT");
576  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
577  CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT,
578  "CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT");
579  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
580  CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG,
581  "CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG");
582  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
583  CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT,
584  "CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT");
585  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
586  CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE,
587  "CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE");
588  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
589  CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF,
590  "CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF");
591 #if VSMC_OPENCL_VERSION >= 110
592  if (opencl_version(dev) >= 110) {
593  os << '\n';
594  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
595  CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR,
596  "CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR");
597  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
598  CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT,
599  "CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT");
600  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
601  CL_DEVICE_NATIVE_VECTOR_WIDTH_INT,
602  "CL_DEVICE_NATIVE_VECTOR_WIDTH_INT");
603  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
604  CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG,
605  "CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG");
606  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
607  CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT,
608  "CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT");
609  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
610  CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE,
611  "CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE");
612  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
613  CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF,
614  "CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF");
615  }
616 #endif // VSMC_OPENCL_VERSION >= 110
617  }
618 
619 #if VSMC_OPENCL_VERSION >= 120
620  template <typename CharT, typename Traits>
621  static void print_dev_single_fp_config (
622  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
623  {
624  ::cl_device_fp_config config;
625  std::vector<std::string> info;
626  dev.getInfo(CL_DEVICE_SINGLE_FP_CONFIG, &config);
627 
628  append_bit_field< ::cl_device_fp_config>(CL_FP_DENORM,
629  config, "CL_FP_DENORM", info);
630  append_bit_field< ::cl_device_fp_config>(CL_FP_INF_NAN,
631  config, "CL_FP_INF_NAN", info);
632  append_bit_field< ::cl_device_fp_config>(CL_FP_ROUND_TO_NEAREST,
633  config, "CL_FP_ROUND_TO_NEAREST", info);
634  append_bit_field< ::cl_device_fp_config>(CL_FP_ROUND_TO_ZERO,
635  config, "CL_FP_ROUND_TO_ZERO", info);
636  append_bit_field< ::cl_device_fp_config>(CL_FP_ROUND_TO_INF,
637  config, "CL_FP_ROUND_TO_INF", info);
638  append_bit_field< ::cl_device_fp_config>(CL_FP_FMA,
639  config, "CL_FP_FMA", info);
640  append_bit_field< ::cl_device_fp_config>(CL_FP_SOFT_FLOAT,
641  config, "CL_FP_SOFT_FLOAT", info);
642  append_bit_field< ::cl_device_fp_config>(
643  CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT,
644  config, "CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT", info);
645 
646  print_name(os, "CL_DEVICE_SINGLE_FP_CONFIG");
647  print_val(os, info);
648  os << '\n';
649  }
650 
651  template <typename CharT, typename Traits>
652  static void print_dev_double_fp_config (
653  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
654  {
655  if (!has_feature<OpenCLDeviceDoubleFP>(dev))
656  return;
657 
658  ::cl_device_fp_config config;
659  std::vector<std::string> info;
660  dev.getInfo(CL_DEVICE_DOUBLE_FP_CONFIG, &config);
661 
662  append_bit_field< ::cl_device_fp_config>(CL_FP_DENORM,
663  config, "CL_FP_DENORM", info);
664  append_bit_field< ::cl_device_fp_config>(CL_FP_INF_NAN,
665  config, "CL_FP_INF_NAN", info);
666  append_bit_field< ::cl_device_fp_config>(CL_FP_ROUND_TO_NEAREST,
667  config, "CL_FP_ROUND_TO_NEAREST", info);
668  append_bit_field< ::cl_device_fp_config>(CL_FP_ROUND_TO_ZERO,
669  config, "CL_FP_ROUND_TO_ZERO", info);
670  append_bit_field< ::cl_device_fp_config>(CL_FP_ROUND_TO_INF,
671  config, "CL_FP_ROUND_TO_INF", info);
672  append_bit_field< ::cl_device_fp_config>(CL_FP_FMA,
673  config, "CL_FP_FMA", info);
674  append_bit_field< ::cl_device_fp_config>(CL_FP_SOFT_FLOAT,
675  config, "CL_FP_SOFT_FLOAT", info);
676 
677  print_name(os, "CL_DEVICE_DOUBLE_FP_CONFIG");
678  print_val(os, info);
679  os << '\n';
680  }
681 
682  template <typename CharT, typename Traits>
683  static void print_dev_image_support (
684  std::basic_ostream<CharT, Traits> &os, const ::cl::Device &dev)
685  {
686  if (!has_feature<OpenCLDeviceImageSupport>(dev))
687  return;
688 
689  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
690  CL_DEVICE_MAX_READ_IMAGE_ARGS,
691  "CL_DEVICE_MAX_READ_IMAGE_ARGS");
692  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
693  CL_DEVICE_MAX_WRITE_IMAGE_ARGS,
694  "CL_DEVICE_MAX_WRITE_IMAGE_ARGS");
695  print_info_val<std::size_t, ::cl_device_info>(os, dev,
696  CL_DEVICE_IMAGE2D_MAX_WIDTH,
697  "CL_DEVICE_IMAGE2D_MAX_WIDTH", "pixel");
698  print_info_val<std::size_t, ::cl_device_info>(os, dev,
699  CL_DEVICE_IMAGE2D_MAX_HEIGHT,
700  "CL_DEVICE_IMAGE2D_MAX_HEIGHT", "pixel");
701  print_info_val<std::size_t, ::cl_device_info>(os, dev,
702  CL_DEVICE_IMAGE3D_MAX_WIDTH,
703  "CL_DEVICE_IMAGE3D_MAX_WIDTH", "pixel");
704  print_info_val<std::size_t, ::cl_device_info>(os, dev,
705  CL_DEVICE_IMAGE3D_MAX_HEIGHT,
706  "CL_DEVICE_IMAGE3D_MAX_HEIGHT", "pixel");
707  print_info_val<std::size_t, ::cl_device_info>(os, dev,
708  CL_DEVICE_IMAGE3D_MAX_DEPTH,
709  "CL_DEVICE_IMAGE3D_MAX_DEPTH", "pixel");
710  print_info_val<std::size_t, ::cl_device_info>(os, dev,
711  CL_DEVICE_IMAGE_MAX_BUFFER_SIZE,
712  "CL_DEVICE_IMAGE_MAX_BUFFER_SIZE", "pixel");
713  print_info_val<std::size_t, ::cl_device_info>(os, dev,
714  CL_DEVICE_IMAGE_MAX_ARRAY_SIZE,
715  "CL_DEVICE_IMAGE_MAX_ARRAY_SIZE");
716  print_info_val< ::cl_uint, ::cl_device_info>(os, dev,
717  CL_DEVICE_MAX_SAMPLERS,
718  "CL_DEVICE_MAX_SAMPLERS");
719  }
720 #endif // VSMC_OPENCL_VERSION >= 120
721 
722  template <typename T>
723  static void append_bit_field (T info, T val,
724  const std::string &name, std::vector<std::string> &strvec)
725  {if ((info & val) != 0) strvec.push_back(name);}
726 
727  template <typename T>
728  static std::string byte_string (const T &val, cxx11::true_type)
729  {
730  std::size_t B = static_cast<std::size_t>(val);
731  std::size_t K = 1024;
732  std::size_t M = 1024 * K;
733  std::size_t G = 1024 * M;
734  std::stringstream ss;
735  if (B >= G)
736  ss << (B % G == 0 ? B / G : static_cast<double>(B) / G) << 'G';
737  else if (B >= M)
738  ss << (B % M == 0 ? B / M : static_cast<double>(B) / M) << 'M';
739  else if (B >= K)
740  ss << (B % K == 0 ? B / K : static_cast<double>(B) / K) << 'K';
741  else
742  ss << B;
743 
744  return ss.str();
745  }
746 
747  template <typename T>
748  static std::string byte_string (const T &, cxx11::false_type)
749  {return std::string();}
750 
751  static std::vector<std::string> split_string (const std::string &str)
752  {
753  std::istringstream ss(str);
754  return std::vector<std::string>(
755  std::istream_iterator<std::string>(ss),
756  std::istream_iterator<std::string>());
757  }
758 
759  template <typename T, typename CLInfoType,
760  typename ObjType, typename InfoType, typename CharT, typename Traits>
761  static void print_info_val (std::basic_ostream<CharT, Traits> &os,
762  const ObjType &obj, InfoType info,
763  const std::string &name, const std::string &unit = "")
764  {
765  T val;
766  obj.getInfo(static_cast<CLInfoType>(info), &val);
767  print_name(os, name);
768  if (cxx11::is_integral<T>::value && unit == std::string("byte"))
769  print_val(os, byte_string(val, cxx11::is_integral<T>()));
770  else
771  print_val(os, val);
772  os << ' ' << unit << '\n';
773  }
774 
775  template <typename T, typename CharT, typename Traits>
776  static void print_kernwginfo_val (std::basic_ostream<CharT, Traits> &os,
777  const ::cl::Kernel &kern, const ::cl::Device &dev,
778  cl_kernel_work_group_info info,
779  const std::string &name, const std::string &unit = "")
780  {
781  T val;
782  kern.getWorkGroupInfo(dev,
783  static_cast< ::cl_kernel_work_group_info>(info), &val);
784  print_name(os, name);
785  print_val(os, val);
786  os << ' ' << unit << '\n';
787  }
788 
789  template <typename CharT, typename Traits>
790  static void print_name (
791  std::basic_ostream<CharT, Traits> &os, const std::string &name)
792  {
793  if (name.size() <= 40) {
794  char buffer[41];
795  std::memset(buffer, ' ', 40);
796  for (std::size_t i = 0; i != name.size(); ++i)
797  buffer[i] = name[i];
798  buffer[40] = '\0';
799  os << const_cast<const char *>(buffer) << ' ';
800  } else {
801  os << name << ' ';
802  }
803  }
804 
805  template <typename T, typename CharT, typename Traits>
806  static void print_val (std::basic_ostream<CharT, Traits> &os, const T &val)
807  {os << val;}
808 
809  template <typename T, typename CharT, typename Traits>
810  static void print_val (std::basic_ostream<CharT, Traits> &os,
811  const std::vector<T> &val)
812  {
813  for (std::size_t i = 0; i != val.size(); ++i)
814  os << val[i] << ' ';
815  }
816 
817  template <typename CharT, typename Traits>
818  static void print_val (std::basic_ostream<CharT, Traits> &os,
819  const std::vector<std::string> &val)
820  {
821  if (val.size() == 0)
822  return;
823 
824  if (val.size() == 1) {
825  os << val[0];
826  return;
827  }
828 
829  os << val[0] << '\n';
830  for (std::size_t i = 1; i != val.size() - 1; ++i) {
831  os << std::string(41, ' ') << val[i] << '\n';
832  }
833  os << std::string(41, ' ') << val.back();
834  }
835 }; //class CLQuery
836 
839 template <typename CharT, typename Traits>
840 inline std::basic_ostream<CharT, Traits> &operator<< (
841  std::basic_ostream<CharT, Traits> &os, const CLQuery &)
842 {return CLQuery::info(os);}
843 
844 } // namespace vsmc
845 
846 namespace cl {
847 
850 template <typename CharT, typename Traits>
851 inline std::basic_ostream<CharT, Traits> &operator<< (
852  std::basic_ostream<CharT, Traits> &os, const Platform &plat)
853 {return vsmc::CLQuery::info(os, plat);}
854 
857 template <typename CharT, typename Traits>
858 inline std::basic_ostream<CharT, Traits> &operator<< (
859  std::basic_ostream<CharT, Traits> &os, const Context &ctx)
860 {return vsmc::CLQuery::info(os, ctx);}
861 
864 template <typename CharT, typename Traits>
865 inline std::basic_ostream<CharT, Traits> &operator<< (
866  std::basic_ostream<CharT, Traits> &os, const Device &dev)
867 {return vsmc::CLQuery::info(os, dev);}
868 
871 template <typename CharT, typename Traits>
872 inline std::basic_ostream<CharT, Traits> &operator<< (
873  std::basic_ostream<CharT, Traits> &os, const Program &prog)
874 {return vsmc::CLQuery::info(os, prog);}
875 
878 template <typename CharT, typename Traits>
879 inline std::basic_ostream<CharT, Traits> &operator<< (
880  std::basic_ostream<CharT, Traits> &os, const Kernel &kern)
881 {return vsmc::CLQuery::info(os, kern);}
882 
883 } // namespace cl
884 
885 #endif // VSMC_OPENCL_CL_QUERY_HPP
Definition: adapter.hpp:37
static std::basic_ostream< CharT, Traits > & info(std::basic_ostream< CharT, Traits > &os, const ::cl::Program &prog, const std::string &kname)
Query kernel information given a program the name of kernel and a program.
Definition: cl_query.hpp:366
Definition: cl_query.hpp:846
static std::vector< std::pair< ::cl_build_status, std::string > > program_build_log(const ::cl::Program &program)
Program build log and status.
Definition: cl_query.hpp:171
Query OpenCL information.
Definition: cl_query.hpp:50
static std::basic_ostream< CharT, Traits > & info(std::basic_ostream< CharT, Traits > &os, const ::cl::Kernel &kern)
Query kernel information.
Definition: cl_query.hpp:326
integral_constant< bool, false > false_type
void * memset(void *dst, int ch, std::size_t n)
SIMD optimized memset with non-temporal store for large buffers.
Definition: cstring.hpp:906
static bool has_feature(const ::cl::Device &dev)
Check if a device feature exists.
Definition: cl_query.hpp:87
static std::basic_ostream< CharT, Traits > & info(std::basic_ostream< CharT, Traits > &os, const ::cl::Platform &plat)
Query platform information.
Definition: cl_query.hpp:230
T & get(Array< T, N > &ary)
Array ADL of get.
Definition: array.hpp:322
static std::basic_ostream< CharT, Traits > & info(std::basic_ostream< CharT, Traits > &os, const ::cl::Program &prog)
Query program informaiton.
Definition: cl_query.hpp:310
static int opencl_c_version(const ::cl::Device &dev)
Return the OpenCL C version of a device.
Definition: cl_query.hpp:77
static bool has_device()
Check if a device type exists in any platform.
Definition: cl_query.hpp:111
static std::basic_ostream< CharT, Traits > & info(std::basic_ostream< CharT, Traits > &os)
Query all information.
Definition: cl_query.hpp:213
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Sampler< T > &sampler)
Definition: sampler.hpp:884
static bool has_device(const ::cl::Platform &plat)
Check if a device type exists in a platform.
Definition: cl_query.hpp:95
OpenCLDeviceFeature
OpenCL device features.
Definition: cl_query.hpp:42
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Platform &plat)
Query device information in a given platform.
Definition: cl_query.hpp:851
integral_constant< bool, true > true_type
static std::vector< std::pair< ::cl_build_status, std::string > > program_build_log(const ::cl::Program &program, std::basic_ostream< CharT, Traits > &os)
Print program build log and status.
Definition: cl_query.hpp:189
static int opencl_version(const ::cl::Device &dev)
Return the OpenCL version of a device.
Definition: cl_query.hpp:66
static std::basic_ostream< CharT, Traits > & info(std::basic_ostream< CharT, Traits > &os, const ::cl::Device &dev)
Query device information.
Definition: cl_query.hpp:258
static std::basic_ostream< CharT, Traits > & info(std::basic_ostream< CharT, Traits > &os, const ::cl::Context &ctx)
Query context information.
Definition: cl_query.hpp:294
static std::string program_source(const ::cl::Program &program)
Program source.
Definition: cl_query.hpp:161
static std::vector< std::string > program_binary(const ::cl::Program &program)
Program binary vector.
Definition: cl_query.hpp:123
static std::vector< ::cl::Device > program_device(const ::cl::Program program)
Program device vector.
Definition: cl_query.hpp:148
Double precision floating points.
Definition: cl_query.hpp:44