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