device.cpp revision c6db1b3396384186aab5b685fe1fd540e17b3a62
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
26using namespace clover;
27
28static device_registry registry;
29
30PUBLIC cl_int
31clGetDeviceIDs(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
65PUBLIC cl_int
66clGetDeviceInfo(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, SIZE_MAX);
91
92   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
93      return scalar_property<cl_uint>(buf, size, size_ret, 16);
94
95   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
96      return scalar_property<cl_uint>(buf, size, size_ret, 8);
97
98   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
99      return scalar_property<cl_uint>(buf, size, size_ret, 4);
100
101   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
102      return scalar_property<cl_uint>(buf, size, size_ret, 2);
103
104   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
105      return scalar_property<cl_uint>(buf, size, size_ret, 4);
106
107   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
108      return scalar_property<cl_uint>(buf, size, size_ret, 2);
109
110   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:
111      return scalar_property<cl_uint>(buf, size, size_ret, 0);
112
113   case CL_DEVICE_MAX_CLOCK_FREQUENCY:
114      return scalar_property<cl_uint>(buf, size, size_ret, 0);
115
116   case CL_DEVICE_ADDRESS_BITS:
117      return scalar_property<cl_uint>(buf, size, size_ret, 32);
118
119   case CL_DEVICE_MAX_READ_IMAGE_ARGS:
120      return scalar_property<cl_uint>(buf, size, size_ret,
121                                      dev->max_images_read());
122
123   case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
124      return scalar_property<cl_uint>(buf, size, size_ret,
125                                      dev->max_images_write());
126
127   case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
128      return scalar_property<cl_ulong>(buf, size, size_ret, 0);
129
130   case CL_DEVICE_IMAGE2D_MAX_WIDTH:
131   case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
132      return scalar_property<size_t>(buf, size, size_ret,
133                                     1 << dev->max_image_levels_2d());
134
135   case CL_DEVICE_IMAGE3D_MAX_WIDTH:
136   case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
137   case CL_DEVICE_IMAGE3D_MAX_DEPTH:
138      return scalar_property<size_t>(buf, size, size_ret,
139                                     1 << dev->max_image_levels_3d());
140
141   case CL_DEVICE_IMAGE_SUPPORT:
142      return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
143
144   case CL_DEVICE_MAX_PARAMETER_SIZE:
145      return scalar_property<size_t>(buf, size, size_ret,
146                                     dev->max_mem_input());
147
148   case CL_DEVICE_MAX_SAMPLERS:
149      return scalar_property<cl_uint>(buf, size, size_ret,
150                                      dev->max_samplers());
151
152   case CL_DEVICE_MEM_BASE_ADDR_ALIGN:
153   case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:
154      return scalar_property<cl_uint>(buf, size, size_ret, 128);
155
156   case CL_DEVICE_SINGLE_FP_CONFIG:
157      return scalar_property<cl_device_fp_config>(buf, size, size_ret,
158         CL_FP_DENORM | CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST);
159
160   case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:
161      return scalar_property<cl_device_mem_cache_type>(buf, size, size_ret,
162                                                       CL_NONE);
163
164   case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:
165      return scalar_property<cl_uint>(buf, size, size_ret, 0);
166
167   case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:
168      return scalar_property<cl_ulong>(buf, size, size_ret, 0);
169
170   case CL_DEVICE_GLOBAL_MEM_SIZE:
171      return scalar_property<cl_ulong>(buf, size, size_ret,
172                                       dev->max_mem_global());
173
174   case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
175      return scalar_property<cl_ulong>(buf, size, size_ret,
176                                       dev->max_const_buffer_size());
177
178   case CL_DEVICE_MAX_CONSTANT_ARGS:
179      return scalar_property<cl_uint>(buf, size, size_ret,
180                                      dev->max_const_buffers());
181
182   case CL_DEVICE_LOCAL_MEM_TYPE:
183      return scalar_property<cl_device_local_mem_type>(buf, size, size_ret,
184                                                       CL_LOCAL);
185
186   case CL_DEVICE_LOCAL_MEM_SIZE:
187      return scalar_property<cl_ulong>(buf, size, size_ret,
188                                       dev->max_mem_local());
189
190   case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
191      return scalar_property<cl_bool>(buf, size, size_ret, CL_FALSE);
192
193   case CL_DEVICE_PROFILING_TIMER_RESOLUTION:
194      return scalar_property<size_t>(buf, size, size_ret, 0);
195
196   case CL_DEVICE_ENDIAN_LITTLE:
197      return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
198
199   case CL_DEVICE_AVAILABLE:
200   case CL_DEVICE_COMPILER_AVAILABLE:
201      return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
202
203   case CL_DEVICE_EXECUTION_CAPABILITIES:
204      return scalar_property<cl_device_exec_capabilities>(buf, size, size_ret,
205                                                          CL_EXEC_KERNEL);
206
207   case CL_DEVICE_QUEUE_PROPERTIES:
208      return scalar_property<cl_command_queue_properties>(buf, size, size_ret,
209         CL_QUEUE_PROFILING_ENABLE);
210
211   case CL_DEVICE_NAME:
212      return string_property(buf, size, size_ret, dev->device_name());
213
214   case CL_DEVICE_VENDOR:
215      return string_property(buf, size, size_ret, dev->vendor_name());
216
217   case CL_DRIVER_VERSION:
218      return string_property(buf, size, size_ret, MESA_VERSION);
219
220   case CL_DEVICE_PROFILE:
221      return string_property(buf, size, size_ret, "FULL_PROFILE");
222
223   case CL_DEVICE_VERSION:
224      return string_property(buf, size, size_ret, "OpenCL 1.1 MESA " MESA_VERSION);
225
226   case CL_DEVICE_EXTENSIONS:
227      return string_property(buf, size, size_ret, "");
228
229   case CL_DEVICE_PLATFORM:
230      return scalar_property<cl_platform_id>(buf, size, size_ret, NULL);
231
232   case CL_DEVICE_HOST_UNIFIED_MEMORY:
233      return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE);
234
235   case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:
236      return scalar_property<cl_uint>(buf, size, size_ret, 16);
237
238   case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:
239      return scalar_property<cl_uint>(buf, size, size_ret, 8);
240
241   case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:
242      return scalar_property<cl_uint>(buf, size, size_ret, 4);
243
244   case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:
245      return scalar_property<cl_uint>(buf, size, size_ret, 2);
246
247   case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:
248      return scalar_property<cl_uint>(buf, size, size_ret, 4);
249
250   case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:
251      return scalar_property<cl_uint>(buf, size, size_ret, 2);
252
253   case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:
254      return scalar_property<cl_uint>(buf, size, size_ret, 0);
255
256   case CL_DEVICE_OPENCL_C_VERSION:
257      return string_property(buf, size, size_ret, "OpenCL C 1.1");
258
259   default:
260      return CL_INVALID_VALUE;
261   }
262}
263