1 //
2 // Copyright 2012 Francisco Jerez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 // SOFTWARE.
21 //
22
23 #include "api/util.hpp"
24 #include "core/device.hpp"
25
26 using namespace clover;
27
28 static device_registry registry;
29
30 PUBLIC cl_int
clGetDeviceIDs(cl_platform_id platform,cl_device_type device_type,cl_uint num_entries,cl_device_id * devices,cl_uint * num_devices)31 clGetDeviceIDs(cl_platform_id platform, cl_device_type device_type,
32 cl_uint num_entries, cl_device_id *devices,
33 cl_uint *num_devices) {
34 std::vector<cl_device_id> devs;
35
36 if (platform != NULL)
37 return CL_INVALID_PLATFORM;
38
39 if ((!num_entries && devices) ||
40 (!num_devices && !devices))
41 return CL_INVALID_VALUE;
42
43 // Collect matching devices
44 for (device &dev : registry) {
45 if (((device_type & CL_DEVICE_TYPE_DEFAULT) &&
46 &dev == ®istry.front()) ||
47 (device_type & dev.type()))
48 devs.push_back(&dev);
49 }
50
51 if (devs.empty())
52 return CL_DEVICE_NOT_FOUND;
53
54 // ...and return the requested data.
55 if (num_devices)
56 *num_devices = devs.size();
57 if (devices)
58 std::copy_n(devs.begin(),
59 std::min((cl_uint)devs.size(), num_entries),
60 devices);
61
62 return CL_SUCCESS;
63 }
64
65 PUBLIC cl_int
clGetDeviceInfo(cl_device_id dev,cl_device_info param,size_t size,void * buf,size_t * size_ret)66 clGetDeviceInfo(cl_device_id dev, cl_device_info param,
67 size_t size, void *buf, size_t *size_ret) {
68 if (!dev)
69 return CL_INVALID_DEVICE;
70
71 switch (param) {
72 case CL_DEVICE_TYPE:
73 return scalar_property<cl_device_type>(buf, size, size_ret, dev->type());
74
75 case CL_DEVICE_VENDOR_ID:
76 return scalar_property<cl_uint>(buf, size, size_ret, dev->vendor_id());
77
78 case CL_DEVICE_MAX_COMPUTE_UNITS:
79 return scalar_property<cl_uint>(buf, size, size_ret, 1);
80
81 case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
82 return scalar_property<cl_uint>(buf, size, size_ret,
83 dev->max_block_size().size());
84
85 case CL_DEVICE_MAX_WORK_ITEM_SIZES:
86 return vector_property<size_t>(buf, size, size_ret,
87 dev->max_block_size());
88
89 case CL_DEVICE_MAX_WORK_GROUP_SIZE:
90 return scalar_property<size_t>(buf, size, size_ret,
91 dev->max_threads_per_block());
92
93 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
94 return scalar_property<cl_uint>(buf, size, size_ret, 16);
95
96 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
97 return scalar_property<cl_uint>(buf, size, size_ret, 8);
98
99 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
100 return scalar_property<cl_uint>(buf, size, size_ret, 4);
101
102 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
103 return scalar_property<cl_uint>(buf, size, size_ret, 2);
104
105 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
106 return scalar_property<cl_uint>(buf, size, size_ret, 4);
107
108 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
109 return scalar_property<cl_uint>(buf, size, size_ret, 2);
110
111 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:
112 return scalar_property<cl_uint>(buf, size, size_ret, 0);
113
114 case CL_DEVICE_MAX_CLOCK_FREQUENCY:
115 return scalar_property<cl_uint>(buf, size, size_ret, 0);
116
117 case CL_DEVICE_ADDRESS_BITS:
118 return scalar_property<cl_uint>(buf, size, size_ret, 32);
119
120 case CL_DEVICE_MAX_READ_IMAGE_ARGS:
121 return scalar_property<cl_uint>(buf, size, size_ret,
122 dev->max_images_read());
123
124 case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
125 return scalar_property<cl_uint>(buf, size, size_ret,
126 dev->max_images_write());
127
128 case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
129 return scalar_property<cl_ulong>(buf, size, size_ret, 0);
130
131 case CL_DEVICE_IMAGE2D_MAX_WIDTH:
132 case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
133 return scalar_property<size_t>(buf, size, size_ret,
134 1 << dev->max_image_levels_2d());
135
136 case CL_DEVICE_IMAGE3D_MAX_WIDTH:
137 case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
138 case CL_DEVICE_IMAGE3D_MAX_DEPTH:
139 return scalar_property<size_t>(buf, size, size_ret,
140 1 << dev->max_image_levels_3d());
141
142 case CL_DEVICE_IMAGE_SUPPORT:
143 return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
144
145 case CL_DEVICE_MAX_PARAMETER_SIZE:
146 return scalar_property<size_t>(buf, size, size_ret,
147 dev->max_mem_input());
148
149 case CL_DEVICE_MAX_SAMPLERS:
150 return scalar_property<cl_uint>(buf, size, size_ret,
151 dev->max_samplers());
152
153 case CL_DEVICE_MEM_BASE_ADDR_ALIGN:
154 case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:
155 return scalar_property<cl_uint>(buf, size, size_ret, 128);
156
157 case CL_DEVICE_SINGLE_FP_CONFIG:
158 return scalar_property<cl_device_fp_config>(buf, size, size_ret,
159 CL_FP_DENORM | CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST);
160
161 case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:
162 return scalar_property<cl_device_mem_cache_type>(buf, size, size_ret,
163 CL_NONE);
164
165 case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:
166 return scalar_property<cl_uint>(buf, size, size_ret, 0);
167
168 case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:
169 return scalar_property<cl_ulong>(buf, size, size_ret, 0);
170
171 case CL_DEVICE_GLOBAL_MEM_SIZE:
172 return scalar_property<cl_ulong>(buf, size, size_ret,
173 dev->max_mem_global());
174
175 case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
176 return scalar_property<cl_ulong>(buf, size, size_ret,
177 dev->max_const_buffer_size());
178
179 case CL_DEVICE_MAX_CONSTANT_ARGS:
180 return scalar_property<cl_uint>(buf, size, size_ret,
181 dev->max_const_buffers());
182
183 case CL_DEVICE_LOCAL_MEM_TYPE:
184 return scalar_property<cl_device_local_mem_type>(buf, size, size_ret,
185 CL_LOCAL);
186
187 case CL_DEVICE_LOCAL_MEM_SIZE:
188 return scalar_property<cl_ulong>(buf, size, size_ret,
189 dev->max_mem_local());
190
191 case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
192 return scalar_property<cl_bool>(buf, size, size_ret, CL_FALSE);
193
194 case CL_DEVICE_PROFILING_TIMER_RESOLUTION:
195 return scalar_property<size_t>(buf, size, size_ret, 0);
196
197 case CL_DEVICE_ENDIAN_LITTLE:
198 return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
199
200 case CL_DEVICE_AVAILABLE:
201 case CL_DEVICE_COMPILER_AVAILABLE:
202 return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
203
204 case CL_DEVICE_EXECUTION_CAPABILITIES:
205 return scalar_property<cl_device_exec_capabilities>(buf, size, size_ret,
206 CL_EXEC_KERNEL);
207
208 case CL_DEVICE_QUEUE_PROPERTIES:
209 return scalar_property<cl_command_queue_properties>(buf, size, size_ret,
210 CL_QUEUE_PROFILING_ENABLE);
211
212 case CL_DEVICE_NAME:
213 return string_property(buf, size, size_ret, dev->device_name());
214
215 case CL_DEVICE_VENDOR:
216 return string_property(buf, size, size_ret, dev->vendor_name());
217
218 case CL_DRIVER_VERSION:
219 return string_property(buf, size, size_ret, MESA_VERSION);
220
221 case CL_DEVICE_PROFILE:
222 return string_property(buf, size, size_ret, "FULL_PROFILE");
223
224 case CL_DEVICE_VERSION:
225 return string_property(buf, size, size_ret, "OpenCL 1.1 MESA " MESA_VERSION);
226
227 case CL_DEVICE_EXTENSIONS:
228 return string_property(buf, size, size_ret, "");
229
230 case CL_DEVICE_PLATFORM:
231 return scalar_property<cl_platform_id>(buf, size, size_ret, NULL);
232
233 case CL_DEVICE_HOST_UNIFIED_MEMORY:
234 return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
235
236 case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:
237 return scalar_property<cl_uint>(buf, size, size_ret, 16);
238
239 case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:
240 return scalar_property<cl_uint>(buf, size, size_ret, 8);
241
242 case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:
243 return scalar_property<cl_uint>(buf, size, size_ret, 4);
244
245 case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:
246 return scalar_property<cl_uint>(buf, size, size_ret, 2);
247
248 case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:
249 return scalar_property<cl_uint>(buf, size, size_ret, 4);
250
251 case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:
252 return scalar_property<cl_uint>(buf, size, size_ret, 2);
253
254 case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:
255 return scalar_property<cl_uint>(buf, size, size_ret, 0);
256
257 case CL_DEVICE_OPENCL_C_VERSION:
258 return string_property(buf, size, size_ret, "OpenCL C 1.1");
259
260 default:
261 return CL_INVALID_VALUE;
262 }
263 }
264