// // 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; } }