1 /* OpenCL runtime library: clGetDeviceInfo()
2 
3    Copyright (c) 2011-2012 Kalle Raiskila and Pekka Jääskeläinen
4 
5    Permission is hereby granted, free of charge, to any person obtaining a copy
6    of this software and associated documentation files (the "Software"), to deal
7    in the Software without restriction, including without limitation the rights
8    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9    copies of the Software, and to permit persons to whom the Software is
10    furnished to do so, subject to the following conditions:
11 
12    The above copyright notice and this permission notice shall be included in
13    all copies or substantial portions of the Software.
14 
15    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21    THE SOFTWARE.
22 */
23 
24 #include "pocl_util.h"
25 
26 /* A version for querying the info and in case the device returns
27    a zero, assume the device info query hasn't been implemented
28    for the device driver at hand. Warns about an incomplete
29    implementation. */
30 #define POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(__TYPE__, __VALUE__)          \
31   if (__VALUE__ == (__TYPE__)0)                                               \
32     POCL_WARN_INCOMPLETE ();                                                  \
33   POCL_RETURN_GETINFO (__TYPE__, __VALUE__);
34 
35 #define POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK(__TYPE__, __VALUE__)           \
36   if ((device->image_support) && (__VALUE__ == (__TYPE__)0))                  \
37     POCL_WARN_INCOMPLETE ();                                                  \
38   POCL_RETURN_GETINFO (__TYPE__, __VALUE__);
39 
40 #define POCL_RETURN_DEVICE_INFO_WITH_EXT_CHECK(__TYPE__, __VALUE__, __EXT__)  \
41   if ((strstr(#__EXT__, device->extensions)) && (__VALUE__ == (__TYPE__)0))     \
42     POCL_WARN_INCOMPLETE ();                                                  \
43   POCL_RETURN_GETINFO (__TYPE__, __VALUE__);
44 
45 #define STRINGIFY_(x) #x
46 #define STRINGIFY(x) STRINGIFY_ (x)
47 #define HOST_DEVICE_CL_VERSION_MAJOR_STR                                      \
48   STRINGIFY (HOST_DEVICE_CL_VERSION_MAJOR)
49 #define HOST_DEVICE_CL_VERSION_MINOR_STR                                      \
50   STRINGIFY (HOST_DEVICE_CL_VERSION_MINOR)
51 #define HOST_CL_VERSION                                                       \
52   "OpenCL C " HOST_DEVICE_CL_VERSION_MAJOR_STR                                \
53   "." HOST_DEVICE_CL_VERSION_MINOR_STR " pocl"
54 
55 CL_API_ENTRY cl_int CL_API_CALL
POname(clGetDeviceInfo)56 POname(clGetDeviceInfo)(cl_device_id   device,
57                 cl_device_info param_name,
58                 size_t         param_value_size,
59                 void *         param_value,
60                 size_t *       param_value_size_ret) CL_API_SUFFIX__VERSION_1_0
61 {
62   POCL_RETURN_ERROR_COND ((!IS_CL_OBJECT_VALID (device)), CL_INVALID_DEVICE);
63 
64   switch (param_name)
65   {
66   case CL_DEVICE_IMAGE_SUPPORT:
67     POCL_RETURN_GETINFO(cl_bool, device->image_support);
68   case CL_DEVICE_TYPE:
69     POCL_RETURN_GETINFO(cl_device_type, device->type);
70   case CL_DEVICE_VENDOR_ID:
71     POCL_RETURN_GETINFO(cl_uint, device->vendor_id);
72   case CL_DEVICE_MAX_COMPUTE_UNITS:
73     POCL_RETURN_GETINFO(cl_uint, device->max_compute_units);
74   case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS          :
75     POCL_RETURN_GETINFO(cl_uint, device->max_work_item_dimensions);
76   case CL_DEVICE_MAX_WORK_GROUP_SIZE               :
77     /* There is no "preferred WG size" device query, so we probably should
78        return something more sensible than the CL_INT_MAX that seems
79        to be the default in the pthread device. It should be computed from
80        the machine's vector width or issue width.
81 
82        Some OpenCL programs (e.g. the Dijkstra book sample) seem to scale
83        the work groups using this.
84 
85        There's a kernel query CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE
86        that can yield better heuristics for the good WG size and forms
87        a basis for a higher level performance portability layer.
88 
89        Basically the size is now limited by the absence of work item
90        loops. A huge unrolling factor explodes the instruction memory size (and
91        compilation time) with usually no benefits.
92     */
93     {
94       size_t max_wg_size = device->max_work_group_size;
95       POCL_RETURN_GETINFO(size_t, max_wg_size);
96     }
97   case CL_DEVICE_MAX_WORK_ITEM_SIZES:
98     {
99       /* We allocate a 3-element array for this in pthread.c */
100       typedef struct { size_t size[3]; } size_t_3;
101       POCL_RETURN_GETINFO(size_t_3, *(size_t_3 const *)device->max_work_item_sizes);
102     }
103   case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
104     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK (cl_ulong,
105                                              device->max_mem_alloc_size);
106   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
107     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->preferred_vector_width_char);
108   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
109     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->preferred_vector_width_short);
110   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
111     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->preferred_vector_width_int);
112   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
113     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->preferred_vector_width_long);
114   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
115     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->preferred_vector_width_float);
116   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
117     POCL_RETURN_DEVICE_INFO_WITH_EXT_CHECK(cl_uint, device->preferred_vector_width_double, cl_khr_fp64);
118   case CL_DEVICE_MAX_CLOCK_FREQUENCY               :
119     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->max_clock_frequency);
120   case CL_DEVICE_ADDRESS_BITS                      :
121     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->address_bits);
122 
123   case CL_DEVICE_MAX_READ_IMAGE_ARGS:
124     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (cl_uint,
125                                             device->max_read_image_args);
126   case CL_DEVICE_MAX_WRITE_IMAGE_ARGS              :
127     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (cl_uint,
128                                             device->max_write_image_args);
129   case CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS         :
130     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (cl_uint,
131                                             device->max_read_write_image_args);
132   case CL_DEVICE_IMAGE2D_MAX_WIDTH:
133     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (size_t, device->image2d_max_width);
134   case CL_DEVICE_IMAGE2D_MAX_HEIGHT                :
135     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (size_t,
136                                             device->image2d_max_height);
137   case CL_DEVICE_IMAGE3D_MAX_WIDTH:
138     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (size_t, device->image3d_max_width);
139   case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
140     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (size_t,
141                                             device->image3d_max_height);
142   case CL_DEVICE_IMAGE3D_MAX_DEPTH                 :
143     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (size_t, device->image3d_max_depth);
144   case CL_DEVICE_IMAGE_MAX_BUFFER_SIZE             :
145     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (size_t,
146                                             device->image_max_buffer_size);
147   case CL_DEVICE_IMAGE_MAX_ARRAY_SIZE              :
148     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (size_t,
149                                             device->image_max_array_size);
150   case CL_DEVICE_MAX_SAMPLERS:
151     POCL_RETURN_DEVICE_INFO_WITH_IMG_CHECK (cl_uint, device->max_samplers);
152 
153   case CL_DEVICE_MAX_PARAMETER_SIZE:
154     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(size_t, device->max_parameter_size);
155   case CL_DEVICE_MEM_BASE_ADDR_ALIGN               :
156     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK (
157         cl_uint, (device->mem_base_addr_align * 8));
158   case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE          :
159     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->min_data_type_align_size);
160   case CL_DEVICE_SINGLE_FP_CONFIG                  :
161     POCL_RETURN_GETINFO (cl_ulong, device->single_fp_config);
162   case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE             :
163     POCL_RETURN_GETINFO(cl_uint, device->global_mem_cache_type);
164   case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE         :
165     POCL_RETURN_GETINFO(cl_uint, device->global_mem_cacheline_size);
166   case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE             :
167     POCL_RETURN_GETINFO(cl_ulong, device->global_mem_cache_size);
168   case CL_DEVICE_GLOBAL_MEM_SIZE:
169     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_ulong, device->global_mem_size);
170   case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE          :
171     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_ulong, device->max_constant_buffer_size);
172   case CL_DEVICE_MAX_CONSTANT_ARGS                 :
173     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->max_constant_args);
174   case CL_DEVICE_LOCAL_MEM_TYPE                    :
175     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->local_mem_type);
176   case CL_DEVICE_LOCAL_MEM_SIZE:
177     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_ulong, device->local_mem_size);
178   case CL_DEVICE_ERROR_CORRECTION_SUPPORT          :
179     POCL_RETURN_GETINFO(cl_bool, device->error_correction_support);
180   case CL_DEVICE_PROFILING_TIMER_RESOLUTION        :
181     POCL_RETURN_GETINFO(size_t, device->profiling_timer_resolution);
182   case CL_DEVICE_ENDIAN_LITTLE                     :
183     POCL_RETURN_GETINFO(cl_uint, device->endian_little);
184   case CL_DEVICE_AVAILABLE                         :
185     POCL_RETURN_GETINFO(cl_bool, device->available);
186   case CL_DEVICE_COMPILER_AVAILABLE                :
187     POCL_RETURN_GETINFO(cl_bool, device->compiler_available);
188   case CL_DEVICE_LINKER_AVAILABLE                  :
189     POCL_RETURN_GETINFO (cl_bool, device->linker_available);
190   case CL_DEVICE_EXECUTION_CAPABILITIES            :
191     POCL_RETURN_GETINFO(cl_device_exec_capabilities, device->execution_capabilities);
192 
193   case CL_DEVICE_NAME:
194     POCL_RETURN_GETINFO_STR(device->long_name);
195 
196   case CL_DEVICE_VENDOR                            :
197     POCL_RETURN_GETINFO_STR(device->vendor);
198 
199   case CL_DRIVER_VERSION:
200     POCL_RETURN_GETINFO_STR(device->driver_version);
201   case CL_DEVICE_PROFILE                           :
202     POCL_RETURN_GETINFO_STR(device->profile);
203   case CL_DEVICE_VERSION                           :
204     {
205       char res[1000];
206       char *hash = device->ops->build_hash(device);
207       snprintf(res, 1000, "%s HSTR: %s", device->version, hash);
208       free(hash);
209       POCL_RETURN_GETINFO_STR(res);
210     }
211   case CL_DEVICE_EXTENSIONS                        :
212     POCL_RETURN_GETINFO_STR(device->extensions);
213   case CL_DEVICE_PLATFORM                          :
214     {
215       /* Return the first platform id, assuming this is the only
216          platform id (which is currently always the case for pocl) */
217       cl_platform_id platform_id;
218       POname(clGetPlatformIDs)(1, &platform_id, NULL);
219       POCL_RETURN_GETINFO(cl_platform_id, platform_id);
220     }
221   case CL_DEVICE_DOUBLE_FP_CONFIG                  :
222     POCL_RETURN_GETINFO (cl_ulong, device->double_fp_config);
223   case CL_DEVICE_HALF_FP_CONFIG                    :
224     POCL_RETURN_GETINFO (cl_ulong, device->half_fp_config);
225   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF       :
226     POCL_RETURN_DEVICE_INFO_WITH_EXT_CHECK(cl_uint, device->preferred_vector_width_half, cl_khr_fp16);
227   case CL_DEVICE_HOST_UNIFIED_MEMORY               :
228     POCL_RETURN_GETINFO(cl_bool, device->host_unified_memory);
229   case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR          :
230     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->native_vector_width_char);
231   case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT         :
232     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->native_vector_width_short);
233   case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT           :
234     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->native_vector_width_int);
235   case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG          :
236     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->native_vector_width_long);
237   case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT         :
238     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint, device->native_vector_width_float);
239   case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE        :
240     POCL_RETURN_DEVICE_INFO_WITH_EXT_CHECK(cl_uint, device->native_vector_width_double, cl_khr_fp64);
241   case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF          :
242     POCL_RETURN_DEVICE_INFO_WITH_EXT_CHECK(cl_uint, device->native_vector_width_half, cl_khr_fp16);
243   case CL_DEVICE_OPENCL_C_VERSION                  :
244     POCL_RETURN_GETINFO_STR (HOST_CL_VERSION);
245   case CL_DEVICE_BUILT_IN_KERNELS                  :
246     if (device->builtin_kernel_list)
247       POCL_RETURN_GETINFO_STR (device->builtin_kernel_list);
248     else
249       POCL_RETURN_GETINFO_STR ("");
250 
251   case CL_DEVICE_PARENT_DEVICE                     :
252     POCL_RETURN_GETINFO(cl_device_id, device->parent_device);
253 
254   case CL_DEVICE_PARTITION_MAX_SUB_DEVICES         :
255     POCL_RETURN_GETINFO(cl_uint, device->max_sub_devices);
256 
257   case CL_DEVICE_PARTITION_PROPERTIES              :
258     if (device->num_partition_properties)
259       POCL_RETURN_GETINFO_ARRAY (cl_device_partition_property,
260                                  device->num_partition_properties,
261                                  device->partition_properties);
262     else
263       POCL_RETURN_GETINFO (cl_device_partition_property, 0);
264 
265   case CL_DEVICE_PARTITION_TYPE                    :
266     if (device->num_partition_types)
267       POCL_RETURN_GETINFO_ARRAY (cl_device_partition_property,
268                                  device->num_partition_types,
269                                  device->partition_type);
270     else
271       POCL_RETURN_GETINFO (cl_device_partition_property, 0);
272 
273   case CL_DEVICE_PARTITION_AFFINITY_DOMAIN         :
274     POCL_RETURN_GETINFO(cl_device_affinity_domain, 0);
275 
276   case CL_DEVICE_PREFERRED_INTEROP_USER_SYNC       :
277     POCL_RETURN_GETINFO(cl_bool, CL_TRUE);
278 
279   case CL_DEVICE_PRINTF_BUFFER_SIZE                :
280     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(size_t, device->printf_buffer_size);
281 
282   case CL_DEVICE_REFERENCE_COUNT:
283     POCL_RETURN_DEVICE_INFO_WITH_IMPL_CHECK(cl_uint,
284                                             (cl_uint)device->pocl_refcount)
285 
286   case CL_DEVICE_SVM_CAPABILITIES:
287     POCL_RETURN_GETINFO(cl_device_svm_capabilities, device->svm_caps);
288   case CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES:
289     POCL_RETURN_GETINFO(cl_device_atomic_capabilities, device->atomic_memory_capabilities);
290   case CL_DEVICE_ATOMIC_FENCE_CAPABILITIES:
291     POCL_RETURN_GETINFO(cl_device_atomic_capabilities, device->atomic_fence_capabilities);
292   case CL_DEVICE_MAX_ON_DEVICE_EVENTS:
293     POCL_RETURN_GETINFO(cl_uint, device->max_events);
294   case CL_DEVICE_MAX_ON_DEVICE_QUEUES:
295     POCL_RETURN_GETINFO(cl_uint, device->max_queues);
296   case CL_DEVICE_MAX_PIPE_ARGS:
297     POCL_RETURN_GETINFO(cl_uint, device->max_pipe_args);
298   case CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS:
299     POCL_RETURN_GETINFO(cl_uint, device->max_pipe_active_res);
300   case CL_DEVICE_PIPE_MAX_PACKET_SIZE:
301     POCL_RETURN_GETINFO(cl_uint, device->max_pipe_packet_size);
302   case CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE:
303     POCL_RETURN_GETINFO(cl_uint, device->dev_queue_pref_size);
304   case CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE:
305     POCL_RETURN_GETINFO(cl_uint, device->dev_queue_max_size);
306   case CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT:
307     POCL_RETURN_GETINFO(cl_uint, 0);
308   case CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT:
309     POCL_RETURN_GETINFO(cl_uint, 0);
310   case CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT:
311     POCL_RETURN_GETINFO(cl_uint, 0);
312   case CL_DEVICE_SPIR_VERSIONS:
313     if (strstr (device->extensions, "cl_khr_spir"))
314       POCL_RETURN_GETINFO_STR ("1.2");
315     else
316       POCL_RETURN_GETINFO_STR ("");
317   case CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES:
318     POCL_RETURN_GETINFO(cl_command_queue_properties, device->on_dev_queue_props);
319   case CL_DEVICE_QUEUE_ON_HOST_PROPERTIES:
320     POCL_RETURN_GETINFO(cl_command_queue_properties, device->on_host_queue_props);
321 
322   case CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE:
323     POCL_RETURN_GETINFO(size_t, device->global_var_pref_size);
324   case CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE:
325     POCL_RETURN_GETINFO(size_t, device->global_var_max_size);
326   case CL_DEVICE_IL_VERSION:
327     if (device->spirv_version)
328       POCL_RETURN_GETINFO_STR (device->spirv_version);
329     else
330       POCL_RETURN_GETINFO_STR ("");
331   }
332 
333   if(device->ops->get_device_info_ext != NULL) {
334     return device->ops->get_device_info_ext(device, param_name, param_value_size,
335                                             param_value, param_value_size_ret);
336   }
337 
338   return CL_INVALID_VALUE;
339 }
340 POsym(clGetDeviceInfo)
341