32 #ifndef VSMC_UTILITY_OPENCL_HPP 33 #define VSMC_UTILITY_OPENCL_HPP 38 #include <OpenCL/opencl.h> 40 #include <CL/opencl.h> 43 #ifndef CL_VERSION_1_2 44 #error OpenCL 1.2 support required 48 #pragma clang diagnostic push 49 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 53 #pragma GCC diagnostic push 54 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 59 #pragma warning(disable : 1478) 62 #define VSMC_DEFINE_UTILITY_OPENCL_GET_INFO(Class, type, name, Name) \ 63 ::cl_int name##_info(::cl_##type##_info param_name, \ 64 std::size_t param_value_size, void *param_value, \ 65 std::size_t *param_value_size_ret) const \ 67 return internal::cl_error_check( \ 68 ::clGet##Name##Info(get(), param_name, param_value_size, \ 69 param_value, param_value_size_ret), \ 70 "CL" #Class "::" #name "_info", "::clGet" #Name "Info"); \ 73 template <typename ParamType> \ 74 ::cl_int name##_info( \ 75 ::cl_##type##_info param_name, ParamType ¶m_value) const \ 79 name##_info(param_name, sizeof(ParamType), &v, nullptr); \ 80 if (status == CL_SUCCESS) \ 86 template <typename ParamType> \ 87 ::cl_int name##_info(::cl_##type##_info param_name, \ 88 std::vector<ParamType> ¶m_value) const \ 90 ::cl_int status = CL_SUCCESS; \ 92 std::size_t param_value_size = 0; \ 93 status = name##_info(param_name, 0, nullptr, ¶m_value_size); \ 94 if (status != CL_SUCCESS) \ 97 std::vector<ParamType> v(param_value_size / sizeof(ParamType)); \ 99 name##_info(param_name, param_value_size, v.data(), nullptr); \ 100 if (status == CL_SUCCESS) \ 101 param_value = std::move(v); \ 106 ::cl_int name##_info( \ 107 ::cl_##type##_info param_name, std::string ¶m_value) const \ 109 std::vector<char> v; \ 110 ::cl_int status = name##_info(param_name, v); \ 112 if (status == CL_SUCCESS) \ 113 param_value = static_cast<const char *>(v.data()); \ 124 #if VSMC_NO_RUNTIME_ASSERT 125 inline ::cl_int
cl_error_check(::cl_int status,
const char *,
const char *)
129 #else // VSMC_NO_RUNTIME_ASSERT 132 if (status == CL_SUCCESS)
140 msg +=
"; OpenCL function: ";
142 msg +=
"; Error code: ";
143 msg += std::to_string(status);
149 #endif // VSMC_NO_RUNTIME_ASSERT 151 template <
typename CLType>
153 ::cl_uint n,
const CLType *ptr)
155 std::vector<typename CLType::pointer> vec;
156 for (::cl_uint i = 0; i != n; ++i)
157 vec.push_back(ptr[i].get());
162 template <
typename CLType>
164 ::cl_uint n,
const typename CLType::pointer *ptr)
166 std::vector<CLType> vec;
167 for (::cl_uint i = 0; i != n; ++i)
168 vec.push_back(CLType(ptr[i]));
188 template <
typename CLPtr,
typename Derived>
199 if (ptr != ptr_.get())
200 ptr_.reset(ptr, [](
pointer p) { Derived::release(p); });
209 bool unique()
const {
return ptr_.unique(); }
211 explicit operator bool()
const {
return bool(ptr_); }
217 std::shared_ptr<element_type> ptr_;
222 template <
typename CLPtr,
typename Derived>
226 return ptr1.
get() == ptr2.
get();
231 template <
typename CLPtr,
typename Derived>
235 return ptr1.
get() != ptr2.
get();
240 template <
typename CLPtr,
typename Derived>
254 explicit CLNDRange(std::size_t x) : dim_(1), range_({x, 0, 0}) {}
256 CLNDRange(std::size_t x, std::size_t y) : dim_(2), range_({x, y, 0}) {}
259 : dim_(3), range_({x, y, z})
263 std::size_t
dim()
const {
return dim_; }
265 const std::size_t *
data()
const 267 return dim_ == 0 ?
nullptr : range_.data();
271 const std::size_t dim_;
272 const std::array<std::size_t, 3> range_;
280 explicit CLDevice(::cl_device_id ptr =
nullptr) { reset_ptr(ptr); }
284 const ::cl_device_partition_property *properties)
const 288 ::clCreateSubDevices(
get(), properties, 0,
nullptr, &n),
289 "CLDevice::sub_devices",
290 "::clCreateSubDevices") != CL_SUCCESS) {
291 return std::vector<CLDevice>();
294 std::vector<::cl_device_id> vec(n);
296 vec.data(),
nullptr),
297 "CLDevice::sub_devices",
298 "::clCreateSubDevices") != CL_SUCCESS) {
299 return std::vector<CLDevice>();
302 return internal::cl_vec_c2cpp<CLDevice>(n, vec.data());
309 static ::cl_int release(::cl_device_id ptr)
315 ::clReleaseDevice(ptr),
"CLDevice::release",
"::clReleaseDevice");
324 explicit CLPlatform(::cl_platform_id ptr =
nullptr) { reset_ptr(ptr); }
327 std::vector<CLDevice>
get_device(::cl_device_type device_type)
const 331 ::clGetDeviceIDs(
get(), device_type, 0,
nullptr, &n),
332 "CLPlatform::get_device",
"::clGetDeviceIDs") != CL_SUCCESS) {
333 return std::vector<CLDevice>();
336 std::vector<::cl_device_id> vec(n);
338 ::clGetDeviceIDs(
get(), device_type, n, vec.data(),
nullptr),
339 "CLPlatform::get_device",
"::clGetDeviceIDs") != CL_SUCCESS) {
340 return std::vector<CLDevice>();
343 return internal::cl_vec_c2cpp<CLDevice>(n, vec.data());
350 "CLPlatform::unload_compiler",
"::clUnloadPlatformCompiler");
356 static ::cl_int release(::cl_platform_id) {
return CL_SUCCESS; }
365 "CLPlatform::get_platform",
"::clGetPlatformIDs") != CL_SUCCESS) {
366 return std::vector<CLPlatform>();
369 std::vector<::cl_platform_id> vec(n);
371 "CLPlatform::get_platform",
"::clGetPlatformIDs") != CL_SUCCESS) {
372 return std::vector<CLPlatform>();
375 return internal::cl_vec_c2cpp<CLPlatform>(n, vec.data());
384 : properties_({CL_CONTEXT_PLATFORM,
385 reinterpret_cast<::cl_context_properties
>(platform.
get()), 0, 0,
391 const CLPlatform &platform, ::cl_bool interop_user_sync)
392 : properties_({CL_CONTEXT_PLATFORM,
393 reinterpret_cast<::cl_context_properties
>(platform.
get()),
394 CL_CONTEXT_INTEROP_USER_SYNC, interop_user_sync, 0})
398 const ::cl_context_properties *
data()
const {
return properties_.data(); }
401 const std::array<::cl_context_properties, 5> properties_;
410 const char *,
const void *, std::size_t,
void *);
412 explicit CLContext(::cl_context ptr =
nullptr) { reset_ptr(ptr); }
417 void *user_data =
nullptr)
420 ::cl_int status = CL_SUCCESS;
421 ::cl_context ptr = ::clCreateContext(properties.
data(), num_devices,
422 vec.data(), pfn_notify, user_data, &status);
424 "::clCreateContext") == CL_SUCCESS) {
432 void *user_data =
nullptr)
434 ::cl_int status = CL_SUCCESS;
435 ::cl_context ptr = ::clCreateContextFromType(
436 properties.
data(), device_type, pfn_notify, user_data, &status);
438 "::clCreateContextFromType") == CL_SUCCESS) {
446 std::vector<::cl_device_id> vec;
447 if (get_info(CL_CONTEXT_DEVICES, vec) != CL_SUCCESS)
448 return std::vector<CLDevice>();
450 return internal::cl_vec_c2cpp<CLDevice>(
451 static_cast<::cl_uint
>(vec.size()), vec.data());
458 static ::cl_int release(::cl_context ptr)
464 "CLContext::release",
"::clReleaseContext");
473 explicit CLEvent(::cl_event ptr =
nullptr) { reset_ptr(ptr); }
478 ::cl_int status = CL_SUCCESS;
479 ::cl_event ptr = ::clCreateUserEvent(context.
get(), &status);
481 "::clCreateUserEvent") == CL_SUCCESS) {
490 ::clSetUserEventStatus(
get(), execution_status),
491 "CLEvent::set_status",
"::clSetUserEventStatus");
497 ::cl_context ptr =
nullptr;
498 return get_info(CL_EVENT_CONTEXT, ptr) == CL_SUCCESS ?
CLContext(ptr) :
508 ::cl_event ptr =
get();
510 ::clWaitForEvents(1, &ptr),
"CLEvent::wait",
"::clWaitForEvents");
521 ::clWaitForEvents(num_events, vec.data()),
"CLEvent::wait",
522 "::clWaitForEvents");
530 Event, profiling, get_profiling, EventProfiling)
533 static ::cl_int release(::cl_event ptr)
539 ::clReleaseEvent(ptr),
"CLEvent::release",
"::clReleaseEvent");
548 explicit CLMemory(::cl_mem ptr =
nullptr) { reset_ptr(ptr); }
552 void *host_ptr =
nullptr)
554 ::cl_int status = CL_SUCCESS;
556 ::clCreateBuffer(context.
get(), flags, size, host_ptr, &status);
558 "::clCreateBuffer") == CL_SUCCESS) {
565 ::cl_buffer_create_type buffer_create_type,
566 const void *buffer_create_info =
nullptr)
568 ::cl_int status = CL_SUCCESS;
569 ::cl_mem ptr = ::clCreateSubBuffer(
570 get(), flags, buffer_create_type, buffer_create_info, &status);
572 "::clCreateSubBuffer") == CL_SUCCESS ?
581 static ::cl_int release(::cl_mem ptr)
587 "CLMemory::release",
"::clReleaseMemObject");
598 explicit CLProgram(::cl_program ptr =
nullptr) { reset_ptr(ptr); }
602 const CLContext &context, ::cl_uint count,
const std::string *strings)
604 std::vector<const char *> str;
605 std::vector<std::size_t> len;
606 for (::cl_uint i = 0; i != count; ++i) {
607 str.push_back(strings[i].c_str());
608 len.push_back(strings[i].size());
611 ::cl_int status = CL_SUCCESS;
612 ::cl_program ptr = ::clCreateProgramWithSource(
613 context.
get(), count, str.data(), len.data(), &status);
615 "::clCreateProgramWithSource") == CL_SUCCESS) {
622 const CLDevice *devices,
const std::vector<unsigned char> *binaries)
625 std::vector<const unsigned char *> bin;
626 std::vector<std::size_t> len;
627 for (::cl_uint i = 0; i != num_devices; ++i) {
628 bin.push_back(binaries[i].data());
629 len.push_back(binaries[i].size());
632 ::cl_int status = CL_SUCCESS;
633 std::vector<::cl_int> binary_status(num_devices, CL_SUCCESS);
635 ::clCreateProgramWithBinary(context.
get(), num_devices, vec.data(),
636 len.data(), bin.data(), binary_status.data(), &status);
637 bool binary_success =
true;
638 for (
auto bs : binary_status) {
640 "::clCreateProgramWithBinary") != CL_SUCCESS) {
641 binary_success =
false;
645 if (binary_success &&
647 "::clCreateProgramWithBinary") == CL_SUCCESS) {
654 const CLDevice *devices,
const std::string &kernel_names)
657 ::cl_int status = CL_SUCCESS;
658 ::cl_program ptr = ::clCreateProgramWithBuiltInKernels(context.
get(),
659 num_devices, vec.data(), kernel_names.c_str(), &status);
661 "::clCreateProgramWithBuiltInKernels") == CL_SUCCESS) {
668 const CLDevice *devices,
const std::string &options = std::string(),
669 ::cl_uint num_input_programs = 0,
670 const CLProgram *input_programs =
nullptr,
675 ::cl_int status = CL_SUCCESS;
676 ::cl_program ptr = ::clLinkProgram(context.
get(), num_devices,
677 dvec.data(), options.c_str(), num_input_programs, pvec.data(),
678 pfn_notify, user_data, &status);
680 "::clLinkProgram") == CL_SUCCESS) {
687 const std::string &options = std::string(),
691 ::cl_int status = ::clBuildProgram(
get(), num_devices, vec.data(),
692 options.c_str(), pfn_notify, user_data);
693 #if !VSMC_NO_RUNTIME_ASSERT 694 if (status != CL_SUCCESS) {
695 for (::cl_uint i = 0; i != num_devices; ++i) {
696 std::cerr << std::string(80,
'=');
698 devices[i].
get_info(CL_DEVICE_NAME, name);
699 std::cerr <<
"Device: " << name << std::endl;
700 std::cerr << std::string(80,
'-');
701 std::cerr <<
"Status: ";
702 switch (build_status(devices[i])) {
704 std::cerr <<
"CL_BUILD_NONE" << std::endl;
707 std::cerr <<
"CL_BUILD_ERROR" << std::endl;
709 case CL_BUILD_SUCCESS:
710 std::cerr <<
"CL_BUILD_SUCCESS" << std::endl;
712 case CL_BUILD_IN_PROGRESS:
713 std::cerr <<
"CL_BUILD_IN_PROGRESS" << std::endl;
717 std::cerr << std::string(80,
'-');
718 std::cerr <<
"Options: " << build_options(devices[i])
720 std::cerr << std::string(80,
'-');
721 std::cerr << build_log(devices[i]) << std::endl;
722 std::cerr << std::string(80,
'-');
728 status,
"CLProgram::build",
"::clBuildProgram");
733 const std::string &options = std::string(),
734 ::cl_uint num_input_headers = 0,
735 const CLProgram *input_headers =
nullptr,
736 const std::string *header_include_names =
nullptr,
741 std::vector<const char *> inc_names;
742 for (::cl_uint i = 0; i != num_input_headers; ++i)
743 inc_names.push_back(header_include_names[i].c_str());
746 ::clCompileProgram(
get(), num_devices, dvec.data(),
747 options.c_str(), num_input_headers, pvec.data(),
748 inc_names.data(), pf_notify, user_data),
749 "CLProgram::compile",
"::clCompileProgram");
756 get_build_info(device, CL_PROGRAM_BUILD_STATUS, v);
765 get_build_info(device, CL_PROGRAM_BUILD_OPTIONS, v);
774 get_build_info(device, CL_PROGRAM_BUILD_LOG, v);
780 inline std::vector<CLKernel> create_kernels()
const;
785 ::cl_context ptr =
nullptr;
786 return get_info(CL_PROGRAM_CONTEXT, ptr) == CL_SUCCESS ?
794 std::vector<::cl_device_id> vec;
795 if (get_info(CL_PROGRAM_DEVICES, vec) != CL_SUCCESS)
796 return std::vector<CLDevice>();
798 return internal::cl_vec_c2cpp<CLDevice>(
799 static_cast<::cl_uint
>(vec.size()), vec.data());
807 ::cl_program_build_info param_name,
std::size_t param_value_size,
808 void *param_value,
std::size_t *param_value_size_ret) const
811 ::clGetProgramBuildInfo(
get(), device.get(), param_name,
812 param_value_size, param_value, param_value_size_ret),
813 "CLKernel::get_build_info",
"::clGetProgramBuildInfo");
816 template <
typename ParamType>
818 ::cl_program_build_info param_name, ParamType ¶m_value)
const 822 get_build_info(device, param_name,
sizeof(ParamType), &v,
nullptr);
823 if (status == CL_SUCCESS)
829 template <
typename ParamType>
831 ::cl_program_build_info param_name,
832 std::vector<ParamType> ¶m_value)
const 834 ::cl_int status = CL_SUCCESS;
836 std::size_t param_value_size = 0;
838 get_build_info(device, param_name, 0,
nullptr, ¶m_value_size);
839 if (status != CL_SUCCESS)
842 std::vector<ParamType> v(param_value_size /
sizeof(ParamType));
843 status = get_build_info(
844 device, param_name, param_value_size, v.data(),
nullptr);
845 if (status == CL_SUCCESS)
846 param_value = std::move(v);
852 ::cl_program_build_info param_name, std::string ¶m_value)
const 855 ::cl_int status = get_build_info(device, param_name, v);
857 if (status == CL_SUCCESS)
858 param_value =
static_cast<const char *
>(v.data());
870 "CLProgram::release",
"::clReleaseProgram");
879 explicit CLKernel(::cl_kernel ptr =
nullptr) { reset_ptr(ptr); }
884 ::cl_int status = CL_SUCCESS;
886 ::clCreateKernel(program.
get(), kernel_name.c_str(), &status);
888 "::clCreateKernel") == CL_SUCCESS) {
894 template <
typename T>
895 ::cl_int
set_arg(::cl_uint arg_index,
const T &arg)
const 898 ::clSetKernelArg(
get(), arg_index,
sizeof(T), &arg),
899 "CLKernel::set_arg",
"::clSetKernelArgs");
905 ::cl_mem mem = arg.
get();
907 ::clSetKernelArg(
get(), arg_index,
sizeof(::cl_mem), &mem),
908 "CLKernel::set_arg",
"::clSetKernelArgs");
914 ::cl_ulong get_work_group_info(const
CLDevice &device,
915 ::cl_kernel_work_group_info param_name,
std::size_t param_value_size,
916 void *param_value,
std::size_t *param_value_size_ret) const
919 ::clGetKernelWorkGroupInfo(
get(), device.get(), param_name,
920 param_value_size, param_value, param_value_size_ret),
921 "CLKernel::get_work_group_info",
"::clGetKernelWorkGroupInfo");
924 template <
typename ParamType>
926 ::cl_kernel_work_group_info param_name, ParamType ¶m_value)
const 929 ::cl_int status = get_work_group_info(
930 device, param_name,
sizeof(ParamType), &v,
nullptr);
931 if (status == CL_SUCCESS)
937 template <
typename ParamType>
939 ::cl_kernel_work_group_info param_name,
940 std::vector<ParamType> ¶m_value)
const 942 ::cl_int status = CL_SUCCESS;
944 std::size_t param_value_size = 0;
945 status = get_work_group_info(
946 device, param_name, 0,
nullptr, ¶m_value_size);
947 if (status != CL_SUCCESS)
950 std::vector<ParamType> v(param_value_size /
sizeof(ParamType));
951 status = get_work_group_info(
952 device, param_name, param_value_size, v.data(),
nullptr);
953 if (status == CL_SUCCESS)
954 param_value = std::move(v);
960 ::cl_kernel_work_group_info param_name, std::string ¶m_value)
const 963 ::cl_int status = get_work_group_info(device, param_name, v);
965 if (status == CL_SUCCESS)
966 param_value =
static_cast<const char *
>(v.data());
973 ::cl_kernel_arg_info param_name, std::size_t param_value_size,
974 void *param_value, std::size_t *param_value_size_ret)
const 977 ::clGetKernelArgInfo(
get(), arg_indx, param_name, param_value_size,
978 param_value, param_value_size_ret),
979 "CLKernel::get_arg_info",
"::clGetKernelArgInfo");
982 template <
typename ParamType>
983 ::cl_int
get_arg_info(::cl_uint arg_indx, ::cl_kernel_arg_info param_name,
984 ParamType ¶m_value)
const 988 get_arg_info(arg_indx, param_name,
sizeof(ParamType), &v,
nullptr);
989 if (status == CL_SUCCESS)
995 template <
typename ParamType>
996 ::cl_int
get_arg_info(::cl_uint arg_indx, ::cl_kernel_arg_info param_name,
997 std::vector<ParamType> ¶m_value)
const 999 ::cl_int status = CL_SUCCESS;
1001 std::size_t param_value_size = 0;
1003 get_arg_info(arg_indx, param_name, 0,
nullptr, ¶m_value_size);
1004 if (status != CL_SUCCESS)
1007 std::vector<ParamType> v(param_value_size /
sizeof(ParamType));
1008 status = get_arg_info(
1009 arg_indx, param_name, param_value_size, v.data(),
nullptr);
1010 if (status == CL_SUCCESS)
1011 param_value = std::move(v);
1017 std::string ¶m_value)
const 1019 std::vector<char> v;
1020 ::cl_int status = get_arg_info(arg_indx, param_name, v);
1022 if (status == CL_SUCCESS)
1023 param_value =
static_cast<const char *
>(v.data());
1035 ::clReleaseKernel(ptr),
"CLKernel::release",
"::clReleaseKernel");
1051 ::cl_command_queue_properties properties = 0)
1053 ::cl_int status = CL_SUCCESS;
1054 ::cl_command_queue ptr = ::clCreateCommandQueue(
1055 context.
get(), device.
get(), properties, &status);
1057 "::clCreateCommandQueue") == CL_SUCCESS) {
1065 ::cl_context ptr =
nullptr;
1066 return get_info(CL_QUEUE_CONTEXT, ptr) == CL_SUCCESS ?
CLContext(ptr) :
1073 ::cl_device_id ptr =
nullptr;
1074 return get_info(CL_QUEUE_DEVICE, ptr) == CL_SUCCESS ?
CLDevice(ptr) :
1080 ::cl_uint work_dim,
const CLNDRange &global_work_offset,
1082 ::cl_uint num_events_in_wait_list = 0,
1083 const CLEvent *event_wait_list =
nullptr,
1084 CLEvent *event =
nullptr)
const 1088 ::cl_event eptr =
nullptr;
1090 ::cl_int status = ::clEnqueueNDRangeKernel(
get(), kernel.
get(),
1091 work_dim, global_work_offset.
data(), global_work_size.
data(),
1092 local_work_size.
data(), num_events_in_wait_list, eptrs.data(),
1095 "CLCommandQueue::enqueue_nd_range_kernel",
1096 "::clEnqueueNDRangeKernel");
1097 if (status == CL_SUCCESS && event !=
nullptr)
1105 ::cl_bool blocking_read, std::size_t offset, std::size_t size,
1106 void *ptr, ::cl_uint num_events_in_wait_list = 0,
1107 const CLEvent *event_wait_list =
nullptr,
1108 CLEvent *event =
nullptr)
const 1112 ::cl_event eptr =
nullptr;
1115 ::clEnqueueReadBuffer(
get(), buffer.
get(), blocking_read, offset,
1116 size, ptr, num_events_in_wait_list, eptrs.data(), &eptr);
1118 "::clEnqueueReadBuffer");
1119 if (status == CL_SUCCESS && event !=
nullptr)
1127 ::cl_bool blocking_write, std::size_t offset, std::size_t size,
1128 void *ptr, ::cl_uint num_events_in_wait_list = 0,
1129 const CLEvent *event_wait_list =
nullptr,
1130 CLEvent *event =
nullptr)
const 1134 ::cl_event eptr =
nullptr;
1137 ::clEnqueueWriteBuffer(
get(), buffer.
get(), blocking_write, offset,
1138 size, ptr, num_events_in_wait_list, eptrs.data(), &eptr);
1140 "CLCommandQueue::enqueue_write_buffer",
"::clEnqueueWriteBuffer");
1141 if (status == CL_SUCCESS && event !=
nullptr)
1149 ::cl_bool blocking_read,
1150 const std::array<std::size_t, 3> &buffer_origin,
1151 const std::array<std::size_t, 3> &host_origin,
1152 const std::array<std::size_t, 3> ®ion, std::size_t buffer_row_pitch,
1153 std::size_t buffer_slice_pitch, std::size_t host_row_pitch,
1154 std::size_t host_slice_pitch,
void *ptr,
1155 ::cl_uint num_events_in_wait_list = 0,
1156 const CLEvent *event_wait_list =
nullptr,
1157 CLEvent *event =
nullptr)
const 1161 ::cl_event eptr =
nullptr;
1163 ::cl_int status = ::clEnqueueReadBufferRect(
get(), buffer.
get(),
1164 blocking_read, buffer_origin.data(), host_origin.data(),
1165 region.data(), buffer_row_pitch, buffer_slice_pitch,
1166 host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list,
1167 eptrs.data(), &eptr);
1169 "CLCommandQueue::enqueue_read_buffer_rect",
1170 "::clEnqueueReadBufferRect");
1171 if (status == CL_SUCCESS && event !=
nullptr)
1179 ::cl_bool blocking_write,
1180 const std::array<std::size_t, 3> &buffer_origin,
1181 const std::array<std::size_t, 3> &host_origin,
1182 const std::array<std::size_t, 3> ®ion, std::size_t buffer_row_pitch,
1183 std::size_t buffer_slice_pitch, std::size_t host_row_pitch,
1184 std::size_t host_slice_pitch,
const void *ptr,
1185 ::cl_uint num_events_in_wait_list = 0,
1186 const CLEvent *event_wait_list =
nullptr,
1187 CLEvent *event =
nullptr)
const 1191 ::cl_event eptr =
nullptr;
1193 ::cl_int status = ::clEnqueueWriteBufferRect(
get(), buffer.
get(),
1194 blocking_write, buffer_origin.data(), host_origin.data(),
1195 region.data(), buffer_row_pitch, buffer_slice_pitch,
1196 host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list,
1197 eptrs.data(), &eptr);
1199 "CLCommandQueue::enqueue_write_buffer_rect",
1200 "::clEnqueueWriteBufferRect");
1201 if (status == CL_SUCCESS && event !=
nullptr)
1209 const CLMemory &dst_buffer, std::size_t src_offset,
1210 std::size_t dst_offset, std::size_t size,
1211 ::cl_uint num_events_in_wait_list = 0,
1212 const CLEvent *event_wait_list =
nullptr,
1213 CLEvent *event =
nullptr)
const 1217 ::cl_event eptr =
nullptr;
1219 ::cl_int status = ::clEnqueueCopyBuffer(
get(), src_buffer.
get(),
1220 dst_buffer.
get(), src_offset, dst_offset, size,
1221 num_events_in_wait_list, eptrs.data(), &eptr);
1223 "CLCommandQeueue::enqueue_copy_buffer",
"::clEnqueueCopyBuffer");
1224 if (status == CL_SUCCESS && event !=
nullptr)
1233 const std::array<std::size_t, 3> &src_origin,
1234 const std::array<std::size_t, 3> &dst_origin,
1235 const std::array<std::size_t, 3> ®ion, std::size_t src_row_pitch,
1236 std::size_t src_slice_pitch, std::size_t dst_row_pitch,
1237 std::size_t dst_slice_pitch, ::cl_uint num_events_in_wait_list = 0,
1238 const CLEvent *event_wait_list =
nullptr,
1239 CLEvent *event =
nullptr)
const 1243 ::cl_event eptr =
nullptr;
1245 ::cl_int status = ::clEnqueueCopyBufferRect(
get(), src_buffer.
get(),
1246 dst_buffer.
get(), src_origin.data(), dst_origin.data(),
1247 region.data(), src_row_pitch, src_slice_pitch, dst_row_pitch,
1248 dst_slice_pitch, num_events_in_wait_list, eptrs.data(), &eptr);
1250 "CLCommandQueue::enqueue_copy_buffer_rect",
1251 "::clEnqueueCopyBufferRect");
1252 if (status == CL_SUCCESS && event !=
nullptr)
1260 std::size_t pattern_size, std::size_t offset, std::size_t size,
1261 ::cl_uint num_events_in_wait_list = 0,
1262 const CLEvent *event_wait_list =
nullptr,
1263 CLEvent *event =
nullptr)
const 1267 ::cl_event eptr =
nullptr;
1270 ::clEnqueueFillBuffer(
get(), buffer.
get(), pattern, pattern_size,
1271 offset, size, num_events_in_wait_list, eptrs.data(), &eptr);
1273 "::clEnqueueFillBuffer");
1274 if (status == CL_SUCCESS && event !=
nullptr)
1282 ::cl_map_flags map_flags, std::size_t offset, std::size_t size,
1283 ::cl_uint num_events_in_wait_list = 0,
1284 const CLEvent *event_wait_list =
nullptr,
1285 CLEvent *event =
nullptr)
const 1289 ::cl_event eptr =
nullptr;
1291 ::cl_int status = CL_SUCCESS;
1292 void *ptr = ::clEnqueueMapBuffer(
get(), buffer.
get(), blocking_map,
1293 map_flags, offset, size, num_events_in_wait_list, eptrs.data(),
1296 "::clEnqueueMapBuffer");
1297 if (status == CL_SUCCESS && event !=
nullptr)
1305 ::cl_uint num_events_in_wait_list = 0,
1306 const CLEvent *event_wait_list =
nullptr,
1307 CLEvent *event =
nullptr)
const 1311 ::cl_event eptr =
nullptr;
1313 ::cl_int status = ::clEnqueueUnmapMemObject(
get(), memobj.
get(),
1314 mapped_ptr, num_events_in_wait_list, eptrs.data(), &eptr);
1316 "CLCommandQueue::enqueue_unmap_mem_object",
1317 "::clEnqueueUnmapMemObject");
1318 if (status == CL_SUCCESS && event !=
nullptr)
1326 const CLMemory *mem_objects, ::cl_mem_migration_flags flags,
1327 ::cl_uint num_events_in_wait_list = 0,
1328 const CLEvent *event_wait_list =
nullptr,
1329 CLEvent *event =
nullptr)
const 1334 ::cl_event eptr =
nullptr;
1336 ::cl_int status = ::clEnqueueMigrateMemObjects(
get(), num_mem_objects,
1337 mptrs.data(), flags, num_events_in_wait_list, eptrs.data(), &eptr);
1339 "CLCommandQueue::enqueue_migrate_mem_objects",
1340 "::clEnqueueMigrateMemObjects");
1341 if (status == CL_SUCCESS && event !=
nullptr)
1349 ::cl_uint num_events_in_wait_list = 0,
1350 const CLEvent *event_wait_list =
nullptr,
1351 CLEvent *event =
nullptr)
const 1355 ::cl_event eptr =
nullptr;
1357 ::cl_int status = ::clEnqueueMarkerWithWaitList(
1358 get(), num_events_in_wait_list, eptrs.data(), &eptr);
1360 "CLCommandQueue::enqueue_marker_with_wait_list",
1361 "::clEnqueueMarkerWithWaitList");
1362 if (status == CL_SUCCESS && event !=
nullptr)
1370 ::cl_uint num_events_in_wait_list = 0,
1371 const CLEvent *event_wait_list =
nullptr,
1372 CLEvent *event =
nullptr)
const 1376 ::cl_event eptr =
nullptr;
1378 ::cl_int status = ::clEnqueueBarrierWithWaitList(
1379 get(), num_events_in_wait_list, eptrs.data(), &eptr);
1381 "CLCommandQueue::enqueue_barrier_with_wait_list",
1382 "::clEnqueueBarrierWithWaitList");
1383 if (status == CL_SUCCESS && event !=
nullptr)
1393 ::clFlush(
get()),
"CLCommandQueue::flush",
"::clFlush");
1400 ::clFinish(
get()),
"CLCommandQueue::finish",
"::clFinish");
1405 CommandQueue, command_queue,
get, CommandQueue)
1408 static ::cl_int release(::cl_command_queue ptr)
1413 ::cl_int status = ::clReleaseCommandQueue(ptr);
1415 status,
"CLCommandQueue::release",
"::clReleaseCommandQueue");
1423 ::cl_command_queue ptr =
nullptr;
1424 return get_info(CL_EVENT_COMMAND_QUEUE, ptr) == CL_SUCCESS ?
1431 ::cl_int status = CL_SUCCESS;
1435 ::clCreateKernelsInProgram(
get(), 0,
nullptr, &n),
1436 "CLProgram::create_kernels",
1437 "::clCreateKernelsInProgram") != CL_SUCCESS) {
1438 return std::vector<CLKernel>();
1441 std::vector<::cl_kernel> vec(n);
1443 ::clCreateKernelsInProgram(
get(), n, vec.data(),
nullptr),
1444 "CLProgram::create_kernels",
1445 "::clCreateKernelsInProgram") != CL_SUCCESS) {
1446 return std::vector<CLKernel>();
1449 return internal::cl_vec_c2cpp<CLKernel>(n, vec.data());
1455 #pragma clang diagnostic pop 1459 #pragma GCC diagnostic pop 1463 #pragma warning(pop) 1466 #endif // VSMC_UTILITY_OPENCL_HPP
CLMemory(const CLContext &context,::cl_mem_flags flags, std::size_t size, void *host_ptr=nullptr)
clCreateBuffer
::cl_int enqueue_copy_buffer(const CLMemory &src_buffer, const CLMemory &dst_buffer, std::size_t src_offset, std::size_t dst_offset, std::size_t size,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueCopyBuffer
::cl_int get_work_group_info(const CLDevice &device,::cl_kernel_work_group_info param_name, ParamType ¶m_value) const
::cl_int enqueue_read_buffer(const CLMemory &buffer,::cl_bool blocking_read, std::size_t offset, std::size_t size, void *ptr,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueReadBuffer
CLEvent(const CLContext &context)
clCreateUserEvent
std::vector< CLPlatform > cl_get_platform()
clGetPlatformIDs
CLMemory(::cl_mem ptr=nullptr)
CLKernel(::cl_kernel ptr=nullptr)
::cl_int get_arg_info(::cl_uint arg_indx,::cl_kernel_arg_info param_name, std::vector< ParamType > ¶m_value) const
::cl_ulong get_arg_info(::cl_uint arg_indx,::cl_kernel_arg_info param_name, std::size_t param_value_size, void *param_value, std::size_t *param_value_size_ret) const
clGetKernelArgInfo
::cl_int enqueue_write_buffer(const CLMemory &buffer,::cl_bool blocking_write, std::size_t offset, std::size_t size, void *ptr,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueWriteBuffer
std::vector< typename CLType::pointer > cl_vec_cpp2c(::cl_uint n, const CLType *ptr)
CLContext get_context() const
CL_EVENT_CONTEXT
::cl_int finish() const
clFinish
::cl_int enqueue_fill_buffer(const CLMemory &buffer, const void *pattern, std::size_t pattern_size, std::size_t offset, std::size_t size,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueFillBuffer
::cl_build_status build_status(const CLDevice &device) const
CL_PROGRAM_BUILD_STATUS
CLNDRange(std::size_t x, std::size_t y)
::cl_int wait() const
clWaitForEvents
::cl_int flush() const
clFlush
const std::size_t * data() const
::cl_int enqueue_read_buffer_rect(const CLMemory &buffer,::cl_bool blocking_read, const std::array< std::size_t, 3 > &buffer_origin, const std::array< std::size_t, 3 > &host_origin, const std::array< std::size_t, 3 > ®ion, std::size_t buffer_row_pitch, std::size_t buffer_slice_pitch, std::size_t host_row_pitch, std::size_t host_slice_pitch, void *ptr,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueReadBufferRect
#define VSMC_RUNTIME_ASSERT(cond, msg)
::cl_int compile(::cl_uint num_devices, const CLDevice *devices, const std::string &options=std::string(),::cl_uint num_input_headers=0, const CLProgram *input_headers=nullptr, const std::string *header_include_names=nullptr, pfn_notify_type pf_notify=nullptr, void *user_data=nullptr)
clCompileProgram
void reset_ptr(pointer ptr)
OpenCL resource management base class.
CLContext(::cl_context ptr=nullptr)
CLNDRange(std::size_t x, std::size_t y, std::size_t z)
::cl_int set_arg(::cl_uint arg_index, const CLMemory &arg) const
clSetKernelArg
CLProgram(const CLContext &context,::cl_uint count, const std::string *strings)
clCreateProgramWithSource
::cl_int enqueue_migrate_mem_objects(::cl_uint num_mem_objects, const CLMemory *mem_objects,::cl_mem_migration_flags flags,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueMigrateMemObjects
bool operator!=(const SingleParticle< T > &sp1, const SingleParticle< T > &sp2)
CLDevice(::cl_device_id ptr=nullptr)
::cl_int build(::cl_uint num_devices, const CLDevice *devices, const std::string &options=std::string(), pfn_notify_type pfn_notify=nullptr, void *user_data=nullptr) const
clBuildProgram
::cl_int enqueue_copy_buffer_rect(const CLMemory &src_buffer, const CLMemory &dst_buffer, const std::array< std::size_t, 3 > &src_origin, const std::array< std::size_t, 3 > &dst_origin, const std::array< std::size_t, 3 > ®ion, std::size_t src_row_pitch, std::size_t src_slice_pitch, std::size_t dst_row_pitch, std::size_t dst_slice_pitch,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueCopyBufferRect
std::string build_log(const CLDevice &device) const
CL_PROGRAM_BUILD_LOG
CLContext get_context() const
CL_PROGRAM_CONTEXT
std::vector< CLType > cl_vec_c2cpp(::cl_uint n, const typename CLType::pointer *ptr)
::cl_int wait(::cl_uint num_events, CLEvent *events)
clWaitForEvents
CLContext get_context() const
CL_QUEUE_CONTEXT
void * enqueue_map_buffer(const CLMemory &buffer,::cl_bool blocking_map,::cl_map_flags map_flags, std::size_t offset, std::size_t size,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueMapBuffer
::cl_int set_status(::cl_int execution_status) const
clSetUserEventStatus
inline::cl_int cl_error_check(::cl_int status, const char *cpp, const char *c)
CLCommandQueue(::cl_command_queue ptr=nullptr)
::cl_int enqueue_barrier_with_wait_list(::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueBarrierWithWaitList
::cl_int enqueue_nd_range_kernel(const CLKernel &kernel,::cl_uint work_dim, const CLNDRange &global_work_offset, const CLNDRange &global_work_size, const CLNDRange &local_work_size,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueNDRangeKernel
::cl_int enqueue_marker_with_wait_list(::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueMarkerWithWaitList
std::vector< CLDevice > creat_sub_devices(const ::cl_device_partition_property *properties) const
clCreateSubDevices
OpenCL cl_context_properties
CLKernel(const CLProgram &program, const std::string &kernel_name)
clCreateKernel
std::vector< CLDevice > get_device() const
CL_PROGRAM_DEVICES
::cl_int get_info(::cl_device_info param_name, std::size_t param_value_size, void *param_value, std::size_t *param_value_size_ret) const
clGetDeviceInfo
::cl_int get_build_info(const CLDevice &device,::cl_program_build_info param_name, std::vector< ParamType > ¶m_value) const
bool operator==(const SingleParticle< T > &sp1, const SingleParticle< T > &sp2)
::cl_int set_arg(::cl_uint arg_index, const T &arg) const
clSetKernelArg
CLProgram(const CLContext &context,::cl_uint num_devices, const CLDevice *devices, const std::vector< unsigned char > *binaries)
clCreateProgramWithBinary
std::string build_options(const CLDevice &device) const
CL_PROGRAM_BUILD_OPTIONS
void(CL_CALLBACK *)(const char *, const void *, std::size_t, void *) pfn_notify_type
::cl_int enqueue_unmap_mem_object(const CLMemory &memobj, void *mapped_ptr,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueUnmapMemObject
CLContextProperties(const CLPlatform &platform,::cl_bool interop_user_sync)
CLContext(const CLContextProperties &properties,::cl_device_type device_type, pfn_notify_type pfn_notify=nullptr, void *user_data=nullptr)
clCreateContextFromType
CLCommandQueue get_command_queue() const
CL_EVENT_COMMAND_QUEUE
CLProgram(::cl_program ptr=nullptr)
::cl_int release(::cl_program ptr)
clReleaseProgram
CLMemory sub_buffer(::cl_mem_flags flags,::cl_buffer_create_type buffer_create_type, const void *buffer_create_info=nullptr)
clCreateSubBuffer
::cl_int get_arg_info(::cl_uint arg_indx,::cl_kernel_arg_info param_name, std::string ¶m_value) const
::cl_int get_build_info(const CLDevice &device,::cl_program_build_info param_name, ParamType ¶m_value) const
::cl_int get_build_info(const CLDevice &device,::cl_program_build_info param_name, std::string ¶m_value) const
const ::cl_context_properties * data() const
std::vector< CLDevice > get_device() const
CL_CONTEXT_DEVICES
CLEvent(::cl_event ptr=nullptr)
void(CL_CALLBACK *)(::cl_program, void *) pfn_notify_type
CLProgram(const CLContext &context,::cl_uint num_devices, const CLDevice *devices, const std::string &kernel_names)
clCreateProgramWithBuiltInKernels
::cl_int release(::cl_kernel ptr)
clReleaseKernel
CLContext(const CLContextProperties &properties,::cl_uint num_devices, const CLDevice *devices, pfn_notify_type pfn_notify=nullptr, void *user_data=nullptr)
clCreateContext
CLCommandQueue(const CLContext &context, const CLDevice &device,::cl_command_queue_properties properties=0)
clCreateCommandQueue
void swap(CLBase< CLPtr, Derived > &other)
CLDevice get_device() const
CL_QUEUE_DEVICE
typename std::remove_pointer< ::cl_kernel >::type element_type
::cl_int enqueue_write_buffer_rect(const CLMemory &buffer,::cl_bool blocking_write, const std::array< std::size_t, 3 > &buffer_origin, const std::array< std::size_t, 3 > &host_origin, const std::array< std::size_t, 3 > ®ion, std::size_t buffer_row_pitch, std::size_t buffer_slice_pitch, std::size_t host_row_pitch, std::size_t host_slice_pitch, const void *ptr,::cl_uint num_events_in_wait_list=0, const CLEvent *event_wait_list=nullptr, CLEvent *event=nullptr) const
clEnqueueWriteBufferRect
::cl_int get_work_group_info(const CLDevice &device,::cl_kernel_work_group_info param_name, std::string ¶m_value) const
CLProgram(const CLContext &context,::cl_uint num_devices, const CLDevice *devices, const std::string &options=std::string(),::cl_uint num_input_programs=0, const CLProgram *input_programs=nullptr, pfn_notify_type pfn_notify=nullptr, void *user_data=nullptr)
clLinkProgram
std::vector< CLKernel > create_kernels() const
clCreateKernelsInProgram
#define VSMC_DEFINE_UTILITY_OPENCL_GET_INFO(Class, type, name, Name)
::cl_int get_work_group_info(const CLDevice &device,::cl_kernel_work_group_info param_name, std::vector< ParamType > ¶m_value) const
CLContextProperties(const CLPlatform &platform)
::cl_int get_arg_info(::cl_uint arg_indx,::cl_kernel_arg_info param_name, ParamType ¶m_value) const
void swap(StateMatrixBase< Layout, Dim, T > &state1, StateMatrixBase< Layout, Dim, T > &state2) noexcept
Swap two StateMatrixBase objects.