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 == &registry.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