2 // Copyright 2012 Francisco Jerez
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:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
23 #include "api/util.hpp"
24 #include "core/platform.hpp"
25 #include "core/device.hpp"
28 using namespace clover
;
31 clGetDeviceIDs(cl_platform_id d_platform
, cl_device_type device_type
,
32 cl_uint num_entries
, cl_device_id
*rd_devices
,
33 cl_uint
*rnum_devices
) try {
34 auto &platform
= obj(d_platform
);
35 std::vector
<cl_device_id
> d_devs
;
37 if ((!num_entries
&& rd_devices
) ||
38 (!rnum_devices
&& !rd_devices
))
39 throw error(CL_INVALID_VALUE
);
41 // Collect matching devices
42 for (device
&dev
: platform
) {
43 if (((device_type
& CL_DEVICE_TYPE_DEFAULT
) &&
44 dev
== platform
.front()) ||
45 (device_type
& dev
.type()))
46 d_devs
.push_back(desc(dev
));
50 throw error(CL_DEVICE_NOT_FOUND
);
52 // ...and return the requested data.
54 *rnum_devices
= d_devs
.size();
56 copy(range(d_devs
.begin(),
57 std::min((unsigned)d_devs
.size(), num_entries
)),
67 clCreateSubDevices(cl_device_id d_dev
,
68 const cl_device_partition_property
*props
,
69 cl_uint num_devs
, cl_device_id
*rd_devs
,
71 // There are no currently supported partitioning schemes.
72 return CL_INVALID_VALUE
;
76 clRetainDevice(cl_device_id d_dev
) try {
79 // The reference count doesn't change for root devices.
87 clReleaseDevice(cl_device_id d_dev
) try {
90 // The reference count doesn't change for root devices.
98 clGetDeviceInfo(cl_device_id d_dev
, cl_device_info param
,
99 size_t size
, void *r_buf
, size_t *r_size
) try {
100 property_buffer buf
{ r_buf
, size
, r_size
};
101 auto &dev
= obj(d_dev
);
105 buf
.as_scalar
<cl_device_type
>() = dev
.type();
108 case CL_DEVICE_VENDOR_ID
:
109 buf
.as_scalar
<cl_uint
>() = dev
.vendor_id();
112 case CL_DEVICE_MAX_COMPUTE_UNITS
:
113 buf
.as_scalar
<cl_uint
>() = dev
.max_compute_units();
116 case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
:
117 buf
.as_scalar
<cl_uint
>() = dev
.max_block_size().size();
120 case CL_DEVICE_MAX_WORK_ITEM_SIZES
:
121 buf
.as_vector
<size_t>() = dev
.max_block_size();
124 case CL_DEVICE_MAX_WORK_GROUP_SIZE
:
125 buf
.as_scalar
<size_t>() = dev
.max_threads_per_block();
128 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR
:
129 buf
.as_scalar
<cl_uint
>() = 16;
132 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT
:
133 buf
.as_scalar
<cl_uint
>() = 8;
136 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT
:
137 buf
.as_scalar
<cl_uint
>() = 4;
140 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG
:
141 buf
.as_scalar
<cl_uint
>() = 2;
144 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT
:
145 buf
.as_scalar
<cl_uint
>() = 4;
148 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE
:
149 buf
.as_scalar
<cl_uint
>() = dev
.has_doubles() ? 2 : 0;
152 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF
:
153 buf
.as_scalar
<cl_uint
>() = dev
.has_halves() ? 8 : 0;
156 case CL_DEVICE_MAX_CLOCK_FREQUENCY
:
157 buf
.as_scalar
<cl_uint
>() = dev
.max_clock_frequency();
160 case CL_DEVICE_ADDRESS_BITS
:
161 buf
.as_scalar
<cl_uint
>() = dev
.address_bits();
164 case CL_DEVICE_MAX_READ_IMAGE_ARGS
:
165 buf
.as_scalar
<cl_uint
>() = dev
.max_images_read();
168 case CL_DEVICE_MAX_WRITE_IMAGE_ARGS
:
169 buf
.as_scalar
<cl_uint
>() = dev
.max_images_write();
172 case CL_DEVICE_MAX_MEM_ALLOC_SIZE
:
173 buf
.as_scalar
<cl_ulong
>() = dev
.max_mem_alloc_size();
176 case CL_DEVICE_IMAGE2D_MAX_WIDTH
:
177 case CL_DEVICE_IMAGE2D_MAX_HEIGHT
:
178 buf
.as_scalar
<size_t>() = 1 << dev
.max_image_levels_2d();
181 case CL_DEVICE_IMAGE3D_MAX_WIDTH
:
182 case CL_DEVICE_IMAGE3D_MAX_HEIGHT
:
183 case CL_DEVICE_IMAGE3D_MAX_DEPTH
:
184 buf
.as_scalar
<size_t>() = 1 << dev
.max_image_levels_3d();
187 case CL_DEVICE_IMAGE_MAX_BUFFER_SIZE
:
188 buf
.as_scalar
<size_t>() = dev
.max_image_buffer_size();
191 case CL_DEVICE_IMAGE_MAX_ARRAY_SIZE
:
192 buf
.as_scalar
<size_t>() = dev
.max_image_array_number();
195 case CL_DEVICE_IMAGE_SUPPORT
:
196 buf
.as_scalar
<cl_bool
>() = dev
.image_support();
199 case CL_DEVICE_MAX_PARAMETER_SIZE
:
200 buf
.as_scalar
<size_t>() = dev
.max_mem_input();
203 case CL_DEVICE_MAX_SAMPLERS
:
204 buf
.as_scalar
<cl_uint
>() = dev
.max_samplers();
207 case CL_DEVICE_MEM_BASE_ADDR_ALIGN
:
208 buf
.as_scalar
<cl_uint
>() = 8 *
209 std::max(dev
.mem_base_addr_align(), (cl_uint
) sizeof(cl_long
) * 16);
212 case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE
:
213 buf
.as_scalar
<cl_uint
>() = 128;
216 case CL_DEVICE_HALF_FP_CONFIG
:
217 // This is the "mandated minimum half precision floating-point
218 // capability" for OpenCL 1.x.
219 buf
.as_scalar
<cl_device_fp_config
>() =
220 CL_FP_INF_NAN
| CL_FP_ROUND_TO_NEAREST
;
223 case CL_DEVICE_SINGLE_FP_CONFIG
:
224 // This is the "mandated minimum single precision floating-point
225 // capability" for OpenCL 1.1. In OpenCL 1.2, nothing is required for
227 buf
.as_scalar
<cl_device_fp_config
>() =
228 CL_FP_INF_NAN
| CL_FP_ROUND_TO_NEAREST
;
231 case CL_DEVICE_DOUBLE_FP_CONFIG
:
232 if (dev
.has_doubles())
233 // This is the "mandated minimum double precision floating-point
235 buf
.as_scalar
<cl_device_fp_config
>() =
237 | CL_FP_ROUND_TO_NEAREST
238 | CL_FP_ROUND_TO_ZERO
243 buf
.as_scalar
<cl_device_fp_config
>() = 0;
246 case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE
:
247 buf
.as_scalar
<cl_device_mem_cache_type
>() = CL_NONE
;
250 case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE
:
251 buf
.as_scalar
<cl_uint
>() = 0;
254 case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE
:
255 buf
.as_scalar
<cl_ulong
>() = 0;
258 case CL_DEVICE_GLOBAL_MEM_SIZE
:
259 buf
.as_scalar
<cl_ulong
>() = dev
.max_mem_global();
262 case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE
:
263 buf
.as_scalar
<cl_ulong
>() = dev
.max_const_buffer_size();
266 case CL_DEVICE_MAX_CONSTANT_ARGS
:
267 buf
.as_scalar
<cl_uint
>() = dev
.max_const_buffers();
270 case CL_DEVICE_LOCAL_MEM_TYPE
:
271 buf
.as_scalar
<cl_device_local_mem_type
>() = CL_LOCAL
;
274 case CL_DEVICE_LOCAL_MEM_SIZE
:
275 buf
.as_scalar
<cl_ulong
>() = dev
.max_mem_local();
278 case CL_DEVICE_ERROR_CORRECTION_SUPPORT
:
279 buf
.as_scalar
<cl_bool
>() = CL_FALSE
;
282 case CL_DEVICE_PROFILING_TIMER_RESOLUTION
:
283 buf
.as_scalar
<size_t>() = 0;
286 case CL_DEVICE_ENDIAN_LITTLE
:
287 buf
.as_scalar
<cl_bool
>() = (dev
.endianness() == PIPE_ENDIAN_LITTLE
);
290 case CL_DEVICE_AVAILABLE
:
291 case CL_DEVICE_COMPILER_AVAILABLE
:
292 case CL_DEVICE_LINKER_AVAILABLE
:
293 buf
.as_scalar
<cl_bool
>() = CL_TRUE
;
296 case CL_DEVICE_EXECUTION_CAPABILITIES
:
297 buf
.as_scalar
<cl_device_exec_capabilities
>() = CL_EXEC_KERNEL
;
300 case CL_DEVICE_QUEUE_PROPERTIES
:
301 buf
.as_scalar
<cl_command_queue_properties
>() = CL_QUEUE_PROFILING_ENABLE
;
304 case CL_DEVICE_BUILT_IN_KERNELS
:
305 buf
.as_string() = "";
309 buf
.as_string() = dev
.device_name();
312 case CL_DEVICE_VENDOR
:
313 buf
.as_string() = dev
.vendor_name();
316 case CL_DRIVER_VERSION
:
317 buf
.as_string() = PACKAGE_VERSION
;
320 case CL_DEVICE_PROFILE
:
321 buf
.as_string() = "FULL_PROFILE";
324 case CL_DEVICE_VERSION
:
325 buf
.as_string() = "OpenCL " + dev
.device_version() + " Mesa " PACKAGE_VERSION MESA_GIT_SHA1
;
328 case CL_DEVICE_EXTENSIONS
:
329 buf
.as_string() = dev
.supported_extensions();
332 case CL_DEVICE_PLATFORM
:
333 buf
.as_scalar
<cl_platform_id
>() = desc(dev
.platform
);
336 case CL_DEVICE_HOST_UNIFIED_MEMORY
:
337 buf
.as_scalar
<cl_bool
>() = dev
.has_unified_memory();
340 case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR
:
341 buf
.as_scalar
<cl_uint
>() = 16;
344 case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT
:
345 buf
.as_scalar
<cl_uint
>() = 8;
348 case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT
:
349 buf
.as_scalar
<cl_uint
>() = 4;
352 case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG
:
353 buf
.as_scalar
<cl_uint
>() = 2;
356 case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT
:
357 buf
.as_scalar
<cl_uint
>() = 4;
360 case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE
:
361 buf
.as_scalar
<cl_uint
>() = dev
.has_doubles() ? 2 : 0;
364 case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF
:
365 buf
.as_scalar
<cl_uint
>() = dev
.has_halves() ? 8 : 0;
368 case CL_DEVICE_OPENCL_C_VERSION
:
369 buf
.as_string() = "OpenCL C " + dev
.device_clc_version() + " ";
372 case CL_DEVICE_PRINTF_BUFFER_SIZE
:
373 // Per the spec, the minimum value for the FULL profile is 1 MB.
374 // However, clover is not ready yet to support it
375 buf
.as_scalar
<size_t>() = 0 /* 1024 */;
378 case CL_DEVICE_PREFERRED_INTEROP_USER_SYNC
:
379 buf
.as_scalar
<cl_bool
>() = CL_TRUE
;
382 case CL_DEVICE_PARENT_DEVICE
:
383 buf
.as_scalar
<cl_device_id
>() = NULL
;
386 case CL_DEVICE_PARTITION_MAX_SUB_DEVICES
:
387 buf
.as_scalar
<cl_uint
>() = 0;
390 case CL_DEVICE_PARTITION_PROPERTIES
:
391 buf
.as_vector
<cl_device_partition_property
>() =
392 desc(property_list
<cl_device_partition_property
>());
395 case CL_DEVICE_PARTITION_AFFINITY_DOMAIN
:
396 buf
.as_scalar
<cl_device_affinity_domain
>() = 0;
399 case CL_DEVICE_PARTITION_TYPE
:
400 buf
.as_vector
<cl_device_partition_property
>() =
401 desc(property_list
<cl_device_partition_property
>());
404 case CL_DEVICE_REFERENCE_COUNT
:
405 buf
.as_scalar
<cl_uint
>() = 1;
408 case CL_DEVICE_SVM_CAPABILITIES
:
409 case CL_DEVICE_SVM_CAPABILITIES_ARM
:
410 buf
.as_scalar
<cl_device_svm_capabilities
>() = dev
.svm_support();
414 throw error(CL_INVALID_VALUE
);