1*6467f958SSadaf Ebrahimi //
2*6467f958SSadaf Ebrahimi // Copyright (c) 2017-2019 The Khronos Group Inc.
3*6467f958SSadaf Ebrahimi //
4*6467f958SSadaf Ebrahimi // Licensed under the Apache License, Version 2.0 (the "License");
5*6467f958SSadaf Ebrahimi // you may not use this file except in compliance with the License.
6*6467f958SSadaf Ebrahimi // You may obtain a copy of the License at
7*6467f958SSadaf Ebrahimi //
8*6467f958SSadaf Ebrahimi // http://www.apache.org/licenses/LICENSE-2.0
9*6467f958SSadaf Ebrahimi //
10*6467f958SSadaf Ebrahimi // Unless required by applicable law or agreed to in writing, software
11*6467f958SSadaf Ebrahimi // distributed under the License is distributed on an "AS IS" BASIS,
12*6467f958SSadaf Ebrahimi // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6467f958SSadaf Ebrahimi // See the License for the specific language governing permissions and
14*6467f958SSadaf Ebrahimi // limitations under the License.
15*6467f958SSadaf Ebrahimi //
16*6467f958SSadaf Ebrahimi
17*6467f958SSadaf Ebrahimi #include <sstream>
18*6467f958SSadaf Ebrahimi #include <stdexcept>
19*6467f958SSadaf Ebrahimi #include <vector>
20*6467f958SSadaf Ebrahimi
21*6467f958SSadaf Ebrahimi #include "deviceInfo.h"
22*6467f958SSadaf Ebrahimi #include "errorHelpers.h"
23*6467f958SSadaf Ebrahimi #include "typeWrappers.h"
24*6467f958SSadaf Ebrahimi
25*6467f958SSadaf Ebrahimi /* Helper to return a string containing device information for the specified
26*6467f958SSadaf Ebrahimi * device info parameter. */
get_device_info_string(cl_device_id device,cl_device_info param_name)27*6467f958SSadaf Ebrahimi std::string get_device_info_string(cl_device_id device,
28*6467f958SSadaf Ebrahimi cl_device_info param_name)
29*6467f958SSadaf Ebrahimi {
30*6467f958SSadaf Ebrahimi size_t size = 0;
31*6467f958SSadaf Ebrahimi int err;
32*6467f958SSadaf Ebrahimi
33*6467f958SSadaf Ebrahimi if ((err = clGetDeviceInfo(device, param_name, 0, NULL, &size))
34*6467f958SSadaf Ebrahimi != CL_SUCCESS
35*6467f958SSadaf Ebrahimi || size == 0)
36*6467f958SSadaf Ebrahimi {
37*6467f958SSadaf Ebrahimi throw std::runtime_error("clGetDeviceInfo failed\n");
38*6467f958SSadaf Ebrahimi }
39*6467f958SSadaf Ebrahimi
40*6467f958SSadaf Ebrahimi std::vector<char> info(size);
41*6467f958SSadaf Ebrahimi
42*6467f958SSadaf Ebrahimi if ((err = clGetDeviceInfo(device, param_name, size, info.data(), NULL))
43*6467f958SSadaf Ebrahimi != CL_SUCCESS)
44*6467f958SSadaf Ebrahimi {
45*6467f958SSadaf Ebrahimi throw std::runtime_error("clGetDeviceInfo failed\n");
46*6467f958SSadaf Ebrahimi }
47*6467f958SSadaf Ebrahimi
48*6467f958SSadaf Ebrahimi /* The returned string does not include the null terminator. */
49*6467f958SSadaf Ebrahimi return std::string(info.data(), size - 1);
50*6467f958SSadaf Ebrahimi }
51*6467f958SSadaf Ebrahimi
52*6467f958SSadaf Ebrahimi /* Determines if an extension is supported by a device. */
is_extension_available(cl_device_id device,const char * extensionName)53*6467f958SSadaf Ebrahimi int is_extension_available(cl_device_id device, const char *extensionName)
54*6467f958SSadaf Ebrahimi {
55*6467f958SSadaf Ebrahimi std::string extString = get_device_extensions_string(device);
56*6467f958SSadaf Ebrahimi std::istringstream ss(extString);
57*6467f958SSadaf Ebrahimi while (ss)
58*6467f958SSadaf Ebrahimi {
59*6467f958SSadaf Ebrahimi std::string found;
60*6467f958SSadaf Ebrahimi ss >> found;
61*6467f958SSadaf Ebrahimi if (found == extensionName) return true;
62*6467f958SSadaf Ebrahimi }
63*6467f958SSadaf Ebrahimi return false;
64*6467f958SSadaf Ebrahimi }
65*6467f958SSadaf Ebrahimi
get_extension_version(cl_device_id device,const char * extensionName)66*6467f958SSadaf Ebrahimi cl_version get_extension_version(cl_device_id device, const char *extensionName)
67*6467f958SSadaf Ebrahimi {
68*6467f958SSadaf Ebrahimi cl_int err;
69*6467f958SSadaf Ebrahimi size_t size;
70*6467f958SSadaf Ebrahimi
71*6467f958SSadaf Ebrahimi err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS_WITH_VERSION, 0, nullptr,
72*6467f958SSadaf Ebrahimi &size);
73*6467f958SSadaf Ebrahimi if (err != CL_SUCCESS)
74*6467f958SSadaf Ebrahimi {
75*6467f958SSadaf Ebrahimi throw std::runtime_error("clGetDeviceInfo(CL_DEVICE_EXTENSIONS_WITH_"
76*6467f958SSadaf Ebrahimi "VERSION) failed to return size\n");
77*6467f958SSadaf Ebrahimi }
78*6467f958SSadaf Ebrahimi
79*6467f958SSadaf Ebrahimi std::vector<cl_name_version> extensions(size / sizeof(cl_name_version));
80*6467f958SSadaf Ebrahimi err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS_WITH_VERSION, size,
81*6467f958SSadaf Ebrahimi extensions.data(), &size);
82*6467f958SSadaf Ebrahimi if (err != CL_SUCCESS)
83*6467f958SSadaf Ebrahimi {
84*6467f958SSadaf Ebrahimi throw std::runtime_error("clGetDeviceInfo(CL_DEVICE_EXTENSIONS_WITH_"
85*6467f958SSadaf Ebrahimi "VERSION) failed to return value\n");
86*6467f958SSadaf Ebrahimi }
87*6467f958SSadaf Ebrahimi
88*6467f958SSadaf Ebrahimi for (auto &ext : extensions)
89*6467f958SSadaf Ebrahimi {
90*6467f958SSadaf Ebrahimi if (!strcmp(extensionName, ext.name))
91*6467f958SSadaf Ebrahimi {
92*6467f958SSadaf Ebrahimi return ext.version;
93*6467f958SSadaf Ebrahimi }
94*6467f958SSadaf Ebrahimi }
95*6467f958SSadaf Ebrahimi
96*6467f958SSadaf Ebrahimi throw std::runtime_error("Extension " + std::string(extensionName)
97*6467f958SSadaf Ebrahimi + " not supported by device!");
98*6467f958SSadaf Ebrahimi }
99*6467f958SSadaf Ebrahimi
100*6467f958SSadaf Ebrahimi /* Returns a string containing the supported extensions list for a device. */
get_device_extensions_string(cl_device_id device)101*6467f958SSadaf Ebrahimi std::string get_device_extensions_string(cl_device_id device)
102*6467f958SSadaf Ebrahimi {
103*6467f958SSadaf Ebrahimi return get_device_info_string(device, CL_DEVICE_EXTENSIONS);
104*6467f958SSadaf Ebrahimi }
105*6467f958SSadaf Ebrahimi
106*6467f958SSadaf Ebrahimi /* Returns a string containing the supported IL version(s) for a device. */
get_device_il_version_string(cl_device_id device)107*6467f958SSadaf Ebrahimi std::string get_device_il_version_string(cl_device_id device)
108*6467f958SSadaf Ebrahimi {
109*6467f958SSadaf Ebrahimi return get_device_info_string(device, CL_DEVICE_IL_VERSION);
110*6467f958SSadaf Ebrahimi }
111*6467f958SSadaf Ebrahimi
112*6467f958SSadaf Ebrahimi /* Returns a string containing the supported OpenCL version for a device. */
get_device_version_string(cl_device_id device)113*6467f958SSadaf Ebrahimi std::string get_device_version_string(cl_device_id device)
114*6467f958SSadaf Ebrahimi {
115*6467f958SSadaf Ebrahimi return get_device_info_string(device, CL_DEVICE_VERSION);
116*6467f958SSadaf Ebrahimi }
117*6467f958SSadaf Ebrahimi
118*6467f958SSadaf Ebrahimi /* Returns a string containing the device name. */
get_device_name(cl_device_id device)119*6467f958SSadaf Ebrahimi std::string get_device_name(cl_device_id device)
120*6467f958SSadaf Ebrahimi {
121*6467f958SSadaf Ebrahimi return get_device_info_string(device, CL_DEVICE_NAME);
122*6467f958SSadaf Ebrahimi }
123*6467f958SSadaf Ebrahimi
get_max_param_size(cl_device_id device)124*6467f958SSadaf Ebrahimi size_t get_max_param_size(cl_device_id device)
125*6467f958SSadaf Ebrahimi {
126*6467f958SSadaf Ebrahimi size_t ret(0);
127*6467f958SSadaf Ebrahimi if (clGetDeviceInfo(device, CL_DEVICE_MAX_PARAMETER_SIZE, sizeof(ret), &ret,
128*6467f958SSadaf Ebrahimi nullptr)
129*6467f958SSadaf Ebrahimi != CL_SUCCESS)
130*6467f958SSadaf Ebrahimi {
131*6467f958SSadaf Ebrahimi throw std::runtime_error("clGetDeviceInfo failed\n");
132*6467f958SSadaf Ebrahimi }
133*6467f958SSadaf Ebrahimi return ret;
134*6467f958SSadaf Ebrahimi }
135