string platform::platform_info(cl_platform_id platform_id, unsigned info_flag) { size_t size; auto err = clGetPlatformInfo(platform_id, info_flag, 0, nullptr, &size); throwcl("clGetPlatformInfo", err); vector<char> buffer(size); v2callcl(CAF_CLF(clGetPlatformInfo), platform_id, info_flag, sizeof(char) * size, buffer.data()); return string(buffer.data()); }
platform_ptr platform::create(cl_platform_id platform_id, unsigned start_id) { vector<unsigned> device_types = {CL_DEVICE_TYPE_GPU, CL_DEVICE_TYPE_ACCELERATOR, CL_DEVICE_TYPE_CPU}; vector<cl_device_id> ids; for (cl_device_type device_type : device_types) { auto known = ids.size(); cl_uint discoverd; auto err = clGetDeviceIDs(platform_id, device_type, 0, nullptr, &discoverd); if (err == CL_DEVICE_NOT_FOUND) { continue; // no devices of the type found } else if (err != CL_SUCCESS) { throwcl("clGetDeviceIDs", err); } ids.resize(known + discoverd); v2callcl(CAF_CLF(clGetDeviceIDs), platform_id, device_type, discoverd, (ids.data() + known)); } vector<detail::raw_device_ptr> devices; devices.resize(ids.size()); auto lift = [](cl_device_id ptr) { return detail::raw_device_ptr{ptr, false}; }; transform(ids.begin(), ids.end(), devices.begin(), lift); detail::raw_context_ptr context; context.reset(v2get(CAF_CLF(clCreateContext), nullptr, static_cast<unsigned>(ids.size()), ids.data(), pfn_notify, nullptr), false); vector<device_ptr> device_information; for (auto& device_id : devices) { device_information.push_back(device::create(context, device_id, start_id++)); } if (device_information.empty()) CAF_RAISE_ERROR("no devices for the platform found"); auto name = platform_info(platform_id, CL_PLATFORM_NAME); auto vendor = platform_info(platform_id, CL_PLATFORM_VENDOR); auto version = platform_info(platform_id, CL_PLATFORM_VERSION); return make_counted<platform>(platform_id, move(context), move(name), move(vendor), move(version), move(device_information)); }
R v1get(const char* fname, F f, Ts&&... vs) { R result; throwcl(fname, f(std::forward<Ts>(vs)..., cl_uint{0}, nullptr, &result)); return result; }
R v3get(const char* fname, F f, Ts&&... vs) { R result; throwcl(fname, f(std::forward<Ts>(vs)..., sizeof(R), &result, nullptr)); return result; }
void v2callcl(const char* fname, F f, Ts&&... vs) { throwcl(fname, f(std::forward<Ts>(vs)..., nullptr)); }