| // |
| // Copyright 2012 Francisco Jerez |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining a |
| // copy of this software and associated documentation files (the "Software"), |
| // to deal in the Software without restriction, including without limitation |
| // the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| // and/or sell copies of the Software, and to permit persons to whom the |
| // Software is furnished to do so, subject to the following conditions: |
| // |
| // The above copyright notice and this permission notice shall be included in |
| // all copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| // THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF |
| // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| // SOFTWARE. |
| // |
| |
| #include "api/util.hpp" |
| #include "core/device.hpp" |
| |
| using namespace clover; |
| |
| static device_registry registry; |
| |
| 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) { |
| std::vector<cl_device_id> devs; |
| |
| if (platform != NULL) |
| return CL_INVALID_PLATFORM; |
| |
| if ((!num_entries && devices) || |
| (!num_devices && !devices)) |
| return CL_INVALID_VALUE; |
| |
| // Collect matching devices |
| for (device &dev : registry) { |
| if (((device_type & CL_DEVICE_TYPE_DEFAULT) && |
| &dev == ®istry.front()) || |
| (device_type & dev.type())) |
| devs.push_back(&dev); |
| } |
| |
| if (devs.empty()) |
| return CL_DEVICE_NOT_FOUND; |
| |
| // ...and return the requested data. |
| if (num_devices) |
| *num_devices = devs.size(); |
| if (devices) |
| std::copy_n(devs.begin(), |
| std::min((cl_uint)devs.size(), num_entries), |
| devices); |
| |
| return CL_SUCCESS; |
| } |
| |
| PUBLIC cl_int |
| clGetDeviceInfo(cl_device_id dev, cl_device_info param, |
| size_t size, void *buf, size_t *size_ret) { |
| if (!dev) |
| return CL_INVALID_DEVICE; |
| |
| switch (param) { |
| case CL_DEVICE_TYPE: |
| return scalar_property<cl_device_type>(buf, size, size_ret, dev->type()); |
| |
| case CL_DEVICE_VENDOR_ID: |
| return scalar_property<cl_uint>(buf, size, size_ret, dev->vendor_id()); |
| |
| case CL_DEVICE_MAX_COMPUTE_UNITS: |
| return scalar_property<cl_uint>(buf, size, size_ret, 1); |
| |
| case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: |
| return scalar_property<cl_uint>(buf, size, size_ret, |
| dev->max_block_size().size()); |
| |
| case CL_DEVICE_MAX_WORK_ITEM_SIZES: |
| return vector_property<size_t>(buf, size, size_ret, |
| dev->max_block_size()); |
| |
| case CL_DEVICE_MAX_WORK_GROUP_SIZE: |
| return scalar_property<size_t>(buf, size, size_ret, |
| dev->max_threads_per_block()); |
| |
| case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: |
| return scalar_property<cl_uint>(buf, size, size_ret, 16); |
| |
| case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: |
| return scalar_property<cl_uint>(buf, size, size_ret, 8); |
| |
| case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT: |
| return scalar_property<cl_uint>(buf, size, size_ret, 4); |
| |
| case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: |
| return scalar_property<cl_uint>(buf, size, size_ret, 2); |
| |
| case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: |
| return scalar_property<cl_uint>(buf, size, size_ret, 4); |
| |
| case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: |
| return scalar_property<cl_uint>(buf, size, size_ret, 2); |
| |
| case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF: |
| return scalar_property<cl_uint>(buf, size, size_ret, 0); |
| |
| case CL_DEVICE_MAX_CLOCK_FREQUENCY: |
| return scalar_property<cl_uint>(buf, size, size_ret, 0); |
| |
| case CL_DEVICE_ADDRESS_BITS: |
| return scalar_property<cl_uint>(buf, size, size_ret, 32); |
| |
| case CL_DEVICE_MAX_READ_IMAGE_ARGS: |
| return scalar_property<cl_uint>(buf, size, size_ret, |
| dev->max_images_read()); |
| |
| case CL_DEVICE_MAX_WRITE_IMAGE_ARGS: |
| return scalar_property<cl_uint>(buf, size, size_ret, |
| dev->max_images_write()); |
| |
| case CL_DEVICE_MAX_MEM_ALLOC_SIZE: |
| return scalar_property<cl_ulong>(buf, size, size_ret, 0); |
| |
| case CL_DEVICE_IMAGE2D_MAX_WIDTH: |
| case CL_DEVICE_IMAGE2D_MAX_HEIGHT: |
| return scalar_property<size_t>(buf, size, size_ret, |
| 1 << dev->max_image_levels_2d()); |
| |
| case CL_DEVICE_IMAGE3D_MAX_WIDTH: |
| case CL_DEVICE_IMAGE3D_MAX_HEIGHT: |
| case CL_DEVICE_IMAGE3D_MAX_DEPTH: |
| return scalar_property<size_t>(buf, size, size_ret, |
| 1 << dev->max_image_levels_3d()); |
| |
| case CL_DEVICE_IMAGE_SUPPORT: |
| return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE); |
| |
| case CL_DEVICE_MAX_PARAMETER_SIZE: |
| return scalar_property<size_t>(buf, size, size_ret, |
| dev->max_mem_input()); |
| |
| case CL_DEVICE_MAX_SAMPLERS: |
| return scalar_property<cl_uint>(buf, size, size_ret, |
| dev->max_samplers()); |
| |
| case CL_DEVICE_MEM_BASE_ADDR_ALIGN: |
| case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE: |
| return scalar_property<cl_uint>(buf, size, size_ret, 128); |
| |
| case CL_DEVICE_SINGLE_FP_CONFIG: |
| return scalar_property<cl_device_fp_config>(buf, size, size_ret, |
| CL_FP_DENORM | CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST); |
| |
| case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: |
| return scalar_property<cl_device_mem_cache_type>(buf, size, size_ret, |
| CL_NONE); |
| |
| case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: |
| return scalar_property<cl_uint>(buf, size, size_ret, 0); |
| |
| case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE: |
| return scalar_property<cl_ulong>(buf, size, size_ret, 0); |
| |
| case CL_DEVICE_GLOBAL_MEM_SIZE: |
| return scalar_property<cl_ulong>(buf, size, size_ret, |
| dev->max_mem_global()); |
| |
| case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: |
| return scalar_property<cl_ulong>(buf, size, size_ret, |
| dev->max_const_buffer_size()); |
| |
| case CL_DEVICE_MAX_CONSTANT_ARGS: |
| return scalar_property<cl_uint>(buf, size, size_ret, |
| dev->max_const_buffers()); |
| |
| case CL_DEVICE_LOCAL_MEM_TYPE: |
| return scalar_property<cl_device_local_mem_type>(buf, size, size_ret, |
| CL_LOCAL); |
| |
| case CL_DEVICE_LOCAL_MEM_SIZE: |
| return scalar_property<cl_ulong>(buf, size, size_ret, |
| dev->max_mem_local()); |
| |
| case CL_DEVICE_ERROR_CORRECTION_SUPPORT: |
| return scalar_property<cl_bool>(buf, size, size_ret, CL_FALSE); |
| |
| case CL_DEVICE_PROFILING_TIMER_RESOLUTION: |
| return scalar_property<size_t>(buf, size, size_ret, 0); |
| |
| case CL_DEVICE_ENDIAN_LITTLE: |
| return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE); |
| |
| case CL_DEVICE_AVAILABLE: |
| case CL_DEVICE_COMPILER_AVAILABLE: |
| return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE); |
| |
| case CL_DEVICE_EXECUTION_CAPABILITIES: |
| return scalar_property<cl_device_exec_capabilities>(buf, size, size_ret, |
| CL_EXEC_KERNEL); |
| |
| case CL_DEVICE_QUEUE_PROPERTIES: |
| return scalar_property<cl_command_queue_properties>(buf, size, size_ret, |
| CL_QUEUE_PROFILING_ENABLE); |
| |
| case CL_DEVICE_NAME: |
| return string_property(buf, size, size_ret, dev->device_name()); |
| |
| case CL_DEVICE_VENDOR: |
| return string_property(buf, size, size_ret, dev->vendor_name()); |
| |
| case CL_DRIVER_VERSION: |
| return string_property(buf, size, size_ret, MESA_VERSION); |
| |
| case CL_DEVICE_PROFILE: |
| return string_property(buf, size, size_ret, "FULL_PROFILE"); |
| |
| case CL_DEVICE_VERSION: |
| return string_property(buf, size, size_ret, "OpenCL 1.1 MESA " MESA_VERSION); |
| |
| case CL_DEVICE_EXTENSIONS: |
| return string_property(buf, size, size_ret, ""); |
| |
| case CL_DEVICE_PLATFORM: |
| return scalar_property<cl_platform_id>(buf, size, size_ret, NULL); |
| |
| case CL_DEVICE_HOST_UNIFIED_MEMORY: |
| return scalar_property<cl_bool>(buf, size, size_ret, CL_TRUE); |
| |
| case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR: |
| return scalar_property<cl_uint>(buf, size, size_ret, 16); |
| |
| case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT: |
| return scalar_property<cl_uint>(buf, size, size_ret, 8); |
| |
| case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT: |
| return scalar_property<cl_uint>(buf, size, size_ret, 4); |
| |
| case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG: |
| return scalar_property<cl_uint>(buf, size, size_ret, 2); |
| |
| case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT: |
| return scalar_property<cl_uint>(buf, size, size_ret, 4); |
| |
| case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE: |
| return scalar_property<cl_uint>(buf, size, size_ret, 2); |
| |
| case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF: |
| return scalar_property<cl_uint>(buf, size, size_ret, 0); |
| |
| case CL_DEVICE_OPENCL_C_VERSION: |
| return string_property(buf, size, size_ret, "OpenCL C 1.1"); |
| |
| default: |
| return CL_INVALID_VALUE; |
| } |
| } |