clutil.cc 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include "common/clutil.h"
  2. #include <cassert>
  3. #include <iostream>
  4. #include <memory>
  5. #include "common/util.h"
  6. namespace { // helper functions
  7. template <typename Func, typename Id, typename Name>
  8. std::string get_info(Func get_info_func, Id id, Name param_name) {
  9. size_t size = 0;
  10. CL_CHECK(get_info_func(id, param_name, 0, NULL, &size));
  11. std::string info(size, '\0');
  12. CL_CHECK(get_info_func(id, param_name, size, info.data(), NULL));
  13. return info;
  14. }
  15. inline std::string get_platform_info(cl_platform_id id, cl_platform_info name) { return get_info(&clGetPlatformInfo, id, name); }
  16. inline std::string get_device_info(cl_device_id id, cl_device_info name) { return get_info(&clGetDeviceInfo, id, name); }
  17. void cl_print_info(cl_platform_id platform, cl_device_id device) {
  18. size_t work_group_size = 0;
  19. cl_device_type device_type = 0;
  20. clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(work_group_size), &work_group_size, NULL);
  21. clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(device_type), &device_type, NULL);
  22. const char *type_str = "Other...";
  23. switch (device_type) {
  24. case CL_DEVICE_TYPE_CPU: type_str ="CL_DEVICE_TYPE_CPU"; break;
  25. case CL_DEVICE_TYPE_GPU: type_str = "CL_DEVICE_TYPE_GPU"; break;
  26. case CL_DEVICE_TYPE_ACCELERATOR: type_str = "CL_DEVICE_TYPE_ACCELERATOR"; break;
  27. }
  28. std::cout << "vendor: " << get_platform_info(platform, CL_PLATFORM_VENDOR) << std::endl
  29. << "platform version: " << get_platform_info(platform, CL_PLATFORM_VERSION) << std::endl
  30. << "profile: " << get_platform_info(platform, CL_PLATFORM_PROFILE) << std::endl
  31. << "extensions: " << get_platform_info(platform, CL_PLATFORM_EXTENSIONS) << std::endl
  32. << "name :" << get_device_info(device, CL_DEVICE_NAME) << std::endl
  33. << "device version :" << get_device_info(device, CL_DEVICE_VERSION) << std::endl
  34. << "max work group size :" << work_group_size << std::endl
  35. << "type = " << device_type << " = " << type_str << std::endl;
  36. }
  37. void cl_print_build_errors(cl_program program, cl_device_id device) {
  38. cl_build_status status;
  39. clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_STATUS, sizeof(status), &status, NULL);
  40. size_t log_size;
  41. clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
  42. std::string log(log_size, '\0');
  43. clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size, &log[0], NULL);
  44. std::cout << "build failed; status=" << status << ", log:" << std::endl << log << std::endl;
  45. }
  46. } // namespace
  47. cl_device_id cl_get_device_id(cl_device_type device_type) {
  48. cl_uint num_platforms = 0;
  49. CL_CHECK(clGetPlatformIDs(0, NULL, &num_platforms));
  50. std::unique_ptr<cl_platform_id[]> platform_ids = std::make_unique<cl_platform_id[]>(num_platforms);
  51. CL_CHECK(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
  52. for (size_t i = 0; i < num_platforms; ++i) {
  53. std::cout << "platform[" << i << "] CL_PLATFORM_NAME: " << get_platform_info(platform_ids[i], CL_PLATFORM_NAME) << std::endl;
  54. // Get first device
  55. if (cl_device_id device_id = NULL; clGetDeviceIDs(platform_ids[i], device_type, 1, &device_id, NULL) == 0 && device_id) {
  56. cl_print_info(platform_ids[i], device_id);
  57. return device_id;
  58. }
  59. }
  60. std::cout << "No valid openCL platform found" << std::endl;
  61. assert(0);
  62. return nullptr;
  63. }
  64. cl_program cl_program_from_file(cl_context ctx, cl_device_id device_id, const char* path, const char* args) {
  65. return cl_program_from_source(ctx, device_id, util::read_file(path), args);
  66. }
  67. cl_program cl_program_from_source(cl_context ctx, cl_device_id device_id, const std::string& src, const char* args) {
  68. const char *csrc = src.c_str();
  69. cl_program prg = CL_CHECK_ERR(clCreateProgramWithSource(ctx, 1, &csrc, NULL, &err));
  70. if (int err = clBuildProgram(prg, 1, &device_id, args, NULL, NULL); err != 0) {
  71. cl_print_build_errors(prg, device_id);
  72. assert(0);
  73. }
  74. return prg;
  75. }
  76. cl_program cl_program_from_binary(cl_context ctx, cl_device_id device_id, const uint8_t* binary, size_t length, const char* args) {
  77. cl_program prg = CL_CHECK_ERR(clCreateProgramWithBinary(ctx, 1, &device_id, &length, &binary, NULL, &err));
  78. if (int err = clBuildProgram(prg, 1, &device_id, args, NULL, NULL); err != 0) {
  79. cl_print_build_errors(prg, device_id);
  80. assert(0);
  81. }
  82. return prg;
  83. }
  84. // Given a cl code and return a string representation
  85. #define CL_ERR_TO_STR(err) case err: return #err
  86. const char* cl_get_error_string(int err) {
  87. switch (err) {
  88. CL_ERR_TO_STR(CL_SUCCESS);
  89. CL_ERR_TO_STR(CL_DEVICE_NOT_FOUND);
  90. CL_ERR_TO_STR(CL_DEVICE_NOT_AVAILABLE);
  91. CL_ERR_TO_STR(CL_COMPILER_NOT_AVAILABLE);
  92. CL_ERR_TO_STR(CL_MEM_OBJECT_ALLOCATION_FAILURE);
  93. CL_ERR_TO_STR(CL_OUT_OF_RESOURCES);
  94. CL_ERR_TO_STR(CL_OUT_OF_HOST_MEMORY);
  95. CL_ERR_TO_STR(CL_PROFILING_INFO_NOT_AVAILABLE);
  96. CL_ERR_TO_STR(CL_MEM_COPY_OVERLAP);
  97. CL_ERR_TO_STR(CL_IMAGE_FORMAT_MISMATCH);
  98. CL_ERR_TO_STR(CL_IMAGE_FORMAT_NOT_SUPPORTED);
  99. CL_ERR_TO_STR(CL_MAP_FAILURE);
  100. CL_ERR_TO_STR(CL_MISALIGNED_SUB_BUFFER_OFFSET);
  101. CL_ERR_TO_STR(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
  102. CL_ERR_TO_STR(CL_COMPILE_PROGRAM_FAILURE);
  103. CL_ERR_TO_STR(CL_LINKER_NOT_AVAILABLE);
  104. CL_ERR_TO_STR(CL_LINK_PROGRAM_FAILURE);
  105. CL_ERR_TO_STR(CL_DEVICE_PARTITION_FAILED);
  106. CL_ERR_TO_STR(CL_KERNEL_ARG_INFO_NOT_AVAILABLE);
  107. CL_ERR_TO_STR(CL_INVALID_VALUE);
  108. CL_ERR_TO_STR(CL_INVALID_DEVICE_TYPE);
  109. CL_ERR_TO_STR(CL_INVALID_PLATFORM);
  110. CL_ERR_TO_STR(CL_INVALID_DEVICE);
  111. CL_ERR_TO_STR(CL_INVALID_CONTEXT);
  112. CL_ERR_TO_STR(CL_INVALID_QUEUE_PROPERTIES);
  113. CL_ERR_TO_STR(CL_INVALID_COMMAND_QUEUE);
  114. CL_ERR_TO_STR(CL_INVALID_HOST_PTR);
  115. CL_ERR_TO_STR(CL_INVALID_MEM_OBJECT);
  116. CL_ERR_TO_STR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
  117. CL_ERR_TO_STR(CL_INVALID_IMAGE_SIZE);
  118. CL_ERR_TO_STR(CL_INVALID_SAMPLER);
  119. CL_ERR_TO_STR(CL_INVALID_BINARY);
  120. CL_ERR_TO_STR(CL_INVALID_BUILD_OPTIONS);
  121. CL_ERR_TO_STR(CL_INVALID_PROGRAM);
  122. CL_ERR_TO_STR(CL_INVALID_PROGRAM_EXECUTABLE);
  123. CL_ERR_TO_STR(CL_INVALID_KERNEL_NAME);
  124. CL_ERR_TO_STR(CL_INVALID_KERNEL_DEFINITION);
  125. CL_ERR_TO_STR(CL_INVALID_KERNEL);
  126. CL_ERR_TO_STR(CL_INVALID_ARG_INDEX);
  127. CL_ERR_TO_STR(CL_INVALID_ARG_VALUE);
  128. CL_ERR_TO_STR(CL_INVALID_ARG_SIZE);
  129. CL_ERR_TO_STR(CL_INVALID_KERNEL_ARGS);
  130. CL_ERR_TO_STR(CL_INVALID_WORK_DIMENSION);
  131. CL_ERR_TO_STR(CL_INVALID_WORK_GROUP_SIZE);
  132. CL_ERR_TO_STR(CL_INVALID_WORK_ITEM_SIZE);
  133. CL_ERR_TO_STR(CL_INVALID_GLOBAL_OFFSET);
  134. CL_ERR_TO_STR(CL_INVALID_EVENT_WAIT_LIST);
  135. CL_ERR_TO_STR(CL_INVALID_EVENT);
  136. CL_ERR_TO_STR(CL_INVALID_OPERATION);
  137. CL_ERR_TO_STR(CL_INVALID_GL_OBJECT);
  138. CL_ERR_TO_STR(CL_INVALID_BUFFER_SIZE);
  139. CL_ERR_TO_STR(CL_INVALID_MIP_LEVEL);
  140. CL_ERR_TO_STR(CL_INVALID_GLOBAL_WORK_SIZE);
  141. CL_ERR_TO_STR(CL_INVALID_PROPERTY);
  142. CL_ERR_TO_STR(CL_INVALID_IMAGE_DESCRIPTOR);
  143. CL_ERR_TO_STR(CL_INVALID_COMPILER_OPTIONS);
  144. CL_ERR_TO_STR(CL_INVALID_LINKER_OPTIONS);
  145. CL_ERR_TO_STR(CL_INVALID_DEVICE_PARTITION_COUNT);
  146. case -69: return "CL_INVALID_PIPE_SIZE";
  147. case -70: return "CL_INVALID_DEVICE_QUEUE";
  148. case -71: return "CL_INVALID_SPEC_ID";
  149. case -72: return "CL_MAX_SIZE_RESTRICTION_EXCEEDED";
  150. case -1002: return "CL_INVALID_D3D10_DEVICE_KHR";
  151. case -1003: return "CL_INVALID_D3D10_RESOURCE_KHR";
  152. case -1004: return "CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR";
  153. case -1005: return "CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR";
  154. case -1006: return "CL_INVALID_D3D11_DEVICE_KHR";
  155. case -1007: return "CL_INVALID_D3D11_RESOURCE_KHR";
  156. case -1008: return "CL_D3D11_RESOURCE_ALREADY_ACQUIRED_KHR";
  157. case -1009: return "CL_D3D11_RESOURCE_NOT_ACQUIRED_KHR";
  158. case -1010: return "CL_INVALID_DX9_MEDIA_ADAPTER_KHR";
  159. case -1011: return "CL_INVALID_DX9_MEDIA_SURFACE_KHR";
  160. case -1012: return "CL_DX9_MEDIA_SURFACE_ALREADY_ACQUIRED_KHR";
  161. case -1013: return "CL_DX9_MEDIA_SURFACE_NOT_ACQUIRED_KHR";
  162. case -1093: return "CL_INVALID_EGL_OBJECT_KHR";
  163. case -1092: return "CL_EGL_RESOURCE_NOT_ACQUIRED_KHR";
  164. case -1001: return "CL_PLATFORM_NOT_FOUND_KHR";
  165. case -1057: return "CL_DEVICE_PARTITION_FAILED_EXT";
  166. case -1058: return "CL_INVALID_PARTITION_COUNT_EXT";
  167. case -1059: return "CL_INVALID_PARTITION_NAME_EXT";
  168. case -1094: return "CL_INVALID_ACCELERATOR_INTEL";
  169. case -1095: return "CL_INVALID_ACCELERATOR_TYPE_INTEL";
  170. case -1096: return "CL_INVALID_ACCELERATOR_DESCRIPTOR_INTEL";
  171. case -1097: return "CL_ACCELERATOR_TYPE_NOT_SUPPORTED_INTEL";
  172. case -1000: return "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR";
  173. case -1098: return "CL_INVALID_VA_API_MEDIA_ADAPTER_INTEL";
  174. case -1099: return "CL_INVALID_VA_API_MEDIA_SURFACE_INTEL";
  175. case -1100: return "CL_VA_API_MEDIA_SURFACE_ALREADY_ACQUIRED_INTEL";
  176. case -1101: return "CL_VA_API_MEDIA_SURFACE_NOT_ACQUIRED_INTEL";
  177. default: return "CL_UNKNOWN_ERROR";
  178. }
  179. }