2 // Copyright (c) 2018 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 ///////////////////////////////////////////////////////////////////////////////////////////////////
18 #include "ocl_builder.h"
19 #include "configuration.h"
20 #include "include/to_string_utils.h"
26 // NOTE: Due to buggy scope transition of warnings we need to disable warning in place of use/instantation
27 // of some types (even though we already disabled them in scope of definition of these types).
28 // Moreover this warning is pretty much now only for annoyance: it is generated due to lack
29 // of proper support for mangling of custom GCC attributes into type name (usually when used
30 // with templates, even from standard library).
31 #if defined __GNUC__ && __GNUC__ >= 6
32 #pragma GCC diagnostic ignored "-Wignored-attributes"
37 static constexpr auto INTEL_PLATFORM_VENDOR = "Intel(R) Corporation";
39 std::map<std::string, device_impl::ptr> ocl_builder::get_available_devices(void* user_context, void* user_device) const {
40 bool host_out_of_order = true; // Change to false, if debug requires in-order queue.
41 if (user_context != nullptr) {
42 return build_device_list_from_user_context(host_out_of_order, user_context);
43 } else if (user_device != nullptr) {
44 return build_device_list_from_user_device(host_out_of_order, user_device);
46 return build_device_list(host_out_of_order);
50 std::map<std::string, device_impl::ptr> ocl_builder::build_device_list(bool out_out_order) const {
52 // Get number of platforms availible
53 cl_int err = clGetPlatformIDs(0, NULL, &n);
54 if (err != CL_SUCCESS) {
55 throw std::runtime_error("[CLDNN ERROR]. clGetPlatformIDs error " + std::to_string(err));
59 std::vector<cl_platform_id> platform_ids(n);
60 err = clGetPlatformIDs(n, platform_ids.data(), NULL);
61 if (err != CL_SUCCESS) {
62 throw std::runtime_error("[CLDNN ERROR]. clGetPlatformIDs error " + std::to_string(err));
66 std::map<std::string, device_impl::ptr> ret;
67 for (auto& id : platform_ids) {
68 cl::Platform platform = cl::Platform(id);
70 if (platform.getInfo<CL_PLATFORM_VENDOR>() != INTEL_PLATFORM_VENDOR)
73 std::vector<cl::Device> devices;
74 platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
75 for (auto& device : devices) {
76 if (!does_device_match_config(out_out_order, device)) continue;
77 ret.insert(get_device(idx++, device, id));
81 throw std::runtime_error("[CLDNN ERROR]. No GPU device was found.");
86 std::map<std::string, device_impl::ptr> ocl_builder::build_device_list_from_user_context(bool out_out_order, void* user_context) const {
87 cl::Context ctx = cl::Context(static_cast<cl_context>(user_context), true);
88 auto all_devices = ctx.getInfo<CL_CONTEXT_DEVICES>();
90 std::map<std::string, device_impl::ptr> ret;
92 for (auto& device : all_devices) {
93 if (!does_device_match_config(out_out_order, device)) continue;
94 ret.insert(get_device(idx++, device, device.getInfo<CL_DEVICE_PLATFORM>()));
98 throw std::runtime_error("[CLDNN ERROR]. User defined context does not have GPU device included!");
103 std::map<std::string, device_impl::ptr> ocl_builder::build_device_list_from_user_device(bool out_out_order, void* user_device) const {
105 // Get number of platforms availible
106 cl_int err = clGetPlatformIDs(0, NULL, &n);
107 if (err != CL_SUCCESS) {
108 throw std::runtime_error("[CLDNN ERROR]. clGetPlatformIDs error " + std::to_string(err));
112 std::vector<cl_platform_id> platform_ids(n);
113 err = clGetPlatformIDs(n, platform_ids.data(), NULL);
114 if (err != CL_SUCCESS) {
115 throw std::runtime_error("[CLDNN ERROR]. clGetPlatformIDs error " + std::to_string(err));
119 std::map<std::string, device_impl::ptr> ret;
120 for (auto& id : platform_ids) {
121 cl::PlatformVA platform = cl::PlatformVA(id);
123 if (platform.getInfo<CL_PLATFORM_VENDOR>() != INTEL_PLATFORM_VENDOR)
126 std::vector<cl::Device> devices;
128 platform.getDevices(CL_D3D11_DEVICE_KHR,
130 CL_PREFERRED_DEVICES_FOR_D3D11_KHR,
132 platform.getDevices(CL_VA_API_DISPLAY_INTEL,
134 CL_PREFERRED_DEVICES_FOR_VA_API_INTEL,
138 for (auto& device : devices) {
139 if (!does_device_match_config(out_out_order, device)) continue;
140 ret.insert(get_device_shared(idx++, device, id, user_device));
144 throw std::runtime_error("[CLDNN ERROR]. No corresponding GPU device was found.");
149 std::pair<std::string, device_impl::ptr> ocl_builder::get_device(const uint32_t index,
150 const cl::Device& dev_to_add,
151 const cl_platform_id platform) const {
153 std::to_string(index),
154 device_impl::ptr{ new device_impl(dev_to_add, cl::Context(dev_to_add), platform, device_info_internal(dev_to_add)),
159 std::pair<std::string, device_impl::ptr> ocl_builder::get_device_shared(const uint32_t index,
160 const cl::Device& dev_to_add,
161 const cl_platform_id platform,
162 void* user_device) const {
163 cl_context_properties props[] = {
165 CL_CONTEXT_D3D11_DEVICE_KHR,
167 CL_CONTEXT_VA_API_DISPLAY_INTEL,
169 (intptr_t)user_device,
170 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
171 CL_CONTEXT_PLATFORM, (cl_context_properties)platform,
175 std::to_string(index),
176 device_impl::ptr{ new device_impl(dev_to_add, cl::Context(dev_to_add, props), platform, device_info_internal(dev_to_add)),
181 bool ocl_builder::does_device_match_config(bool out_of_order, const cl::Device& device) const {
183 if (device.getInfo<CL_DEVICE_TYPE>() != device_type ||
184 device.getInfo<CL_DEVICE_VENDOR_ID>() != device_vendor) {
188 // Does device support OOOQ?
190 auto queue_properties = device.getInfo<CL_DEVICE_QUEUE_PROPERTIES>();
191 using cmp_t = std::common_type<decltype(queue_properties),
192 typename std::underlying_type<cl::QueueProperties>::type>::type;
193 if (!(static_cast<cmp_t>(queue_properties) & static_cast<cmp_t>(cl::QueueProperties::OutOfOrder))) {