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"
27 using namespace clover
;
30 clGetDeviceIDs(cl_platform_id d_platform
, cl_device_type device_type
,
31 cl_uint num_entries
, cl_device_id
*rd_devices
,
32 cl_uint
*rnum_devices
) try {
33 auto &platform
= obj(d_platform
);
34 std::vector
<cl_device_id
> d_devs
;
36 if ((!num_entries
&& rd_devices
) ||
37 (!rnum_devices
&& !rd_devices
))
38 throw error(CL_INVALID_VALUE
);
40 // Collect matching devices
41 for (device
&dev
: platform
) {
42 if (((device_type
& CL_DEVICE_TYPE_DEFAULT
) &&
43 dev
== platform
.front()) ||
44 (device_type
& dev
.type()))
45 d_devs
.push_back(desc(dev
));
49 throw error(CL_DEVICE_NOT_FOUND
);
51 // ...and return the requested data.
53 *rnum_devices
= d_devs
.size();
55 copy(range(d_devs
.begin(),
56 std::min((unsigned)d_devs
.size(), num_entries
)),
66 clCreateSubDevices(cl_device_id d_dev
,
67 const cl_device_partition_property
*props
,
68 cl_uint num_devs
, cl_device_id
*rd_devs
,
70 // There are no currently supported partitioning schemes.
71 return CL_INVALID_VALUE
;
75 clRetainDevice(cl_device_id d_dev
) try {
78 // The reference count doesn't change for root devices.
86 clReleaseDevice(cl_device_id d_dev
) try {
89 // The reference count doesn't change for root devices.
97 clGetDeviceInfo(cl_device_id d_dev
, cl_device_info param
,
98 size_t size
, void *r_buf
, size_t *r_size
) try {
99 property_buffer buf
{ r_buf
, size
, r_size
};
100 auto &dev
= obj(d_dev
);
104 buf
.as_scalar
<cl_device_type
>() = dev
.type();
107 case CL_DEVICE_VENDOR_ID
:
108 buf
.as_scalar
<cl_uint
>() = dev
.vendor_id();
111 case CL_DEVICE_MAX_COMPUTE_UNITS
:
112 buf
.as_scalar
<cl_uint
>() = dev
.max_compute_units();
115 case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
:
116 buf
.as_scalar
<cl_uint
>() = dev
.max_block_size().size();
119 case CL_DEVICE_MAX_WORK_ITEM_SIZES
:
120 buf
.as_vector
<size_t>() = dev
.max_block_size();
123 case CL_DEVICE_MAX_WORK_GROUP_SIZE
:
124 buf
.as_scalar
<size_t>() = dev
.max_threads_per_block();
127 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR
:
128 buf
.as_scalar
<cl_uint
>() = 16;
131 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT
:
132 buf
.as_scalar
<cl_uint
>() = 8;
135 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT
:
136 buf
.as_scalar
<cl_uint
>() = 4;
139 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG
:
140 buf
.as_scalar
<cl_uint
>() = 2;
143 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT
:
144 buf
.as_scalar
<cl_uint
>() = 4;
147 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE
:
148 buf
.as_scalar
<cl_uint
>() = dev
.has_doubles() ? 2 : 0;
151 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF
:
152 buf
.as_scalar
<cl_uint
>() = 0;
155 case CL_DEVICE_MAX_CLOCK_FREQUENCY
:
156 buf
.as_scalar
<cl_uint
>() = dev
.max_clock_frequency();
159 case CL_DEVICE_ADDRESS_BITS
:
160 buf
.as_scalar
<cl_uint
>() = 32;
163 case CL_DEVICE_MAX_READ_IMAGE_ARGS
:
164 buf
.as_scalar
<cl_uint
>() = dev
.max_images_read();
167 case CL_DEVICE_MAX_WRITE_IMAGE_ARGS
:
168 buf
.as_scalar
<cl_uint
>() = dev
.max_images_write();
171 case CL_DEVICE_MAX_MEM_ALLOC_SIZE
:
172 buf
.as_scalar
<cl_ulong
>() = dev
.max_mem_alloc_size();
175 case CL_DEVICE_IMAGE2D_MAX_WIDTH
:
176 case CL_DEVICE_IMAGE2D_MAX_HEIGHT
:
177 buf
.as_scalar
<size_t>() = 1 << dev
.max_image_levels_2d();
180 case CL_DEVICE_IMAGE3D_MAX_WIDTH
:
181 case CL_DEVICE_IMAGE3D_MAX_HEIGHT
:
182 case CL_DEVICE_IMAGE3D_MAX_DEPTH
:
183 buf
.as_scalar
<size_t>() = 1 << dev
.max_image_levels_3d();
186 case CL_DEVICE_IMAGE_SUPPORT
:
187 buf
.as_scalar
<cl_bool
>() = dev
.image_support();
190 case CL_DEVICE_MAX_PARAMETER_SIZE
:
191 buf
.as_scalar
<size_t>() = dev
.max_mem_input();
194 case CL_DEVICE_MAX_SAMPLERS
:
195 buf
.as_scalar
<cl_uint
>() = dev
.max_samplers();
198 case CL_DEVICE_MEM_BASE_ADDR_ALIGN
:
199 case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE
:
200 buf
.as_scalar
<cl_uint
>() = 128;
203 case CL_DEVICE_SINGLE_FP_CONFIG
:
204 // This is the "mandated minimum single precision floating-point
205 // capability" for OpenCL 1.1. In OpenCL 1.2, nothing is required for
207 buf
.as_scalar
<cl_device_fp_config
>() =
208 CL_FP_INF_NAN
| CL_FP_ROUND_TO_NEAREST
;
211 case CL_DEVICE_DOUBLE_FP_CONFIG
:
212 if (dev
.has_doubles())
213 // This is the "mandated minimum double precision floating-point
215 buf
.as_scalar
<cl_device_fp_config
>() =
217 | CL_FP_ROUND_TO_NEAREST
218 | CL_FP_ROUND_TO_ZERO
223 buf
.as_scalar
<cl_device_fp_config
>() = 0;
226 case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE
:
227 buf
.as_scalar
<cl_device_mem_cache_type
>() = CL_NONE
;
230 case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE
:
231 buf
.as_scalar
<cl_uint
>() = 0;
234 case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE
:
235 buf
.as_scalar
<cl_ulong
>() = 0;
238 case CL_DEVICE_GLOBAL_MEM_SIZE
:
239 buf
.as_scalar
<cl_ulong
>() = dev
.max_mem_global();
242 case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE
:
243 buf
.as_scalar
<cl_ulong
>() = dev
.max_const_buffer_size();
246 case CL_DEVICE_MAX_CONSTANT_ARGS
:
247 buf
.as_scalar
<cl_uint
>() = dev
.max_const_buffers();
250 case CL_DEVICE_LOCAL_MEM_TYPE
:
251 buf
.as_scalar
<cl_device_local_mem_type
>() = CL_LOCAL
;
254 case CL_DEVICE_LOCAL_MEM_SIZE
:
255 buf
.as_scalar
<cl_ulong
>() = dev
.max_mem_local();
258 case CL_DEVICE_ERROR_CORRECTION_SUPPORT
:
259 buf
.as_scalar
<cl_bool
>() = CL_FALSE
;
262 case CL_DEVICE_PROFILING_TIMER_RESOLUTION
:
263 buf
.as_scalar
<size_t>() = 0;
266 case CL_DEVICE_ENDIAN_LITTLE
:
267 buf
.as_scalar
<cl_bool
>() = (dev
.endianness() == PIPE_ENDIAN_LITTLE
);
270 case CL_DEVICE_AVAILABLE
:
271 case CL_DEVICE_COMPILER_AVAILABLE
:
272 buf
.as_scalar
<cl_bool
>() = CL_TRUE
;
275 case CL_DEVICE_EXECUTION_CAPABILITIES
:
276 buf
.as_scalar
<cl_device_exec_capabilities
>() = CL_EXEC_KERNEL
;
279 case CL_DEVICE_QUEUE_PROPERTIES
:
280 buf
.as_scalar
<cl_command_queue_properties
>() = CL_QUEUE_PROFILING_ENABLE
;
284 buf
.as_string() = dev
.device_name();
287 case CL_DEVICE_VENDOR
:
288 buf
.as_string() = dev
.vendor_name();
291 case CL_DRIVER_VERSION
:
292 buf
.as_string() = PACKAGE_VERSION
;
295 case CL_DEVICE_PROFILE
:
296 buf
.as_string() = "FULL_PROFILE";
299 case CL_DEVICE_VERSION
:
300 buf
.as_string() = "OpenCL 1.1 MESA " PACKAGE_VERSION
;
303 case CL_DEVICE_EXTENSIONS
:
305 "cl_khr_global_int32_base_atomics"
306 " cl_khr_global_int32_extended_atomics"
307 " cl_khr_local_int32_base_atomics"
308 " cl_khr_local_int32_extended_atomics"
309 " cl_khr_byte_addressable_store"
310 + std::string(dev
.has_doubles() ? " cl_khr_fp64" : "");
313 case CL_DEVICE_PLATFORM
:
314 buf
.as_scalar
<cl_platform_id
>() = desc(dev
.platform
);
317 case CL_DEVICE_HOST_UNIFIED_MEMORY
:
318 buf
.as_scalar
<cl_bool
>() = CL_TRUE
;
321 case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR
:
322 buf
.as_scalar
<cl_uint
>() = 16;
325 case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT
:
326 buf
.as_scalar
<cl_uint
>() = 8;
329 case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT
:
330 buf
.as_scalar
<cl_uint
>() = 4;
333 case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG
:
334 buf
.as_scalar
<cl_uint
>() = 2;
337 case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT
:
338 buf
.as_scalar
<cl_uint
>() = 4;
341 case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE
:
342 buf
.as_scalar
<cl_uint
>() = dev
.has_doubles() ? 2 : 0;
345 case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF
:
346 buf
.as_scalar
<cl_uint
>() = 0;
349 case CL_DEVICE_OPENCL_C_VERSION
:
350 buf
.as_string() = "OpenCL C 1.1 ";
353 case CL_DEVICE_PARENT_DEVICE
:
354 buf
.as_scalar
<cl_device_id
>() = NULL
;
357 case CL_DEVICE_PARTITION_MAX_SUB_DEVICES
:
358 buf
.as_scalar
<cl_uint
>() = 0;
361 case CL_DEVICE_PARTITION_PROPERTIES
:
362 buf
.as_vector
<cl_device_partition_property
>() =
363 desc(property_list
<cl_device_partition_property
>());
366 case CL_DEVICE_PARTITION_AFFINITY_DOMAIN
:
367 buf
.as_scalar
<cl_device_affinity_domain
>() = 0;
370 case CL_DEVICE_PARTITION_TYPE
:
371 buf
.as_vector
<cl_device_partition_property
>() =
372 desc(property_list
<cl_device_partition_property
>());
375 case CL_DEVICE_REFERENCE_COUNT
:
376 buf
.as_scalar
<cl_uint
>() = 1;
380 throw error(CL_INVALID_VALUE
);