17ec681f3Smrg//
27ec681f3Smrg// Copyright 2012 Francisco Jerez
37ec681f3Smrg//
47ec681f3Smrg// Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg// copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg// to deal in the Software without restriction, including without limitation
77ec681f3Smrg// the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg// and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg// Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg//
117ec681f3Smrg// The above copyright notice and this permission notice shall be included in
127ec681f3Smrg// all copies or substantial portions of the Software.
137ec681f3Smrg//
147ec681f3Smrg// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
157ec681f3Smrg// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
167ec681f3Smrg// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
177ec681f3Smrg// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
187ec681f3Smrg// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
197ec681f3Smrg// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
207ec681f3Smrg// OTHER DEALINGS IN THE SOFTWARE.
217ec681f3Smrg//
227ec681f3Smrg
237ec681f3Smrg#include "api/util.hpp"
247ec681f3Smrg#include "core/platform.hpp"
257ec681f3Smrg#include "core/device.hpp"
267ec681f3Smrg#include "git_sha1.h"
277ec681f3Smrg
287ec681f3Smrgusing namespace clover;
297ec681f3Smrg
307ec681f3Smrgnamespace {
317ec681f3Smrg   std::string
327ec681f3Smrg   supported_il_versions_as_string(const device &dev) {
337ec681f3Smrg      std::string il_versions_string;
347ec681f3Smrg
357ec681f3Smrg      for (const auto &il_version : dev.supported_il_versions()) {
367ec681f3Smrg         if (!il_versions_string.empty())
377ec681f3Smrg            il_versions_string += " ";
387ec681f3Smrg
397ec681f3Smrg         il_versions_string += std::string(il_version.name) + "_" +
407ec681f3Smrg            std::to_string(CL_VERSION_MAJOR(il_version.version)) + "." +
417ec681f3Smrg            std::to_string(CL_VERSION_MINOR(il_version.version));
427ec681f3Smrg      }
437ec681f3Smrg      return il_versions_string;
447ec681f3Smrg   }
457ec681f3Smrg}
467ec681f3Smrg
477ec681f3SmrgCLOVER_API cl_int
487ec681f3SmrgclGetDeviceIDs(cl_platform_id d_platform, cl_device_type device_type,
497ec681f3Smrg               cl_uint num_entries, cl_device_id *rd_devices,
507ec681f3Smrg               cl_uint *rnum_devices) try {
517ec681f3Smrg   auto &platform = obj(d_platform);
527ec681f3Smrg   std::vector<cl_device_id> d_devs;
537ec681f3Smrg
547ec681f3Smrg   if ((!num_entries && rd_devices) ||
557ec681f3Smrg       (!rnum_devices && !rd_devices))
567ec681f3Smrg      throw error(CL_INVALID_VALUE);
577ec681f3Smrg
587ec681f3Smrg   // Collect matching devices
597ec681f3Smrg   for (device &dev : platform) {
607ec681f3Smrg      if (((device_type & CL_DEVICE_TYPE_DEFAULT) &&
617ec681f3Smrg           dev == platform.front()) ||
627ec681f3Smrg          (device_type & dev.type()))
637ec681f3Smrg         d_devs.push_back(desc(dev));
647ec681f3Smrg   }
657ec681f3Smrg
667ec681f3Smrg   if (d_devs.empty())
677ec681f3Smrg      throw error(CL_DEVICE_NOT_FOUND);
687ec681f3Smrg
697ec681f3Smrg   // ...and return the requested data.
707ec681f3Smrg   if (rnum_devices)
717ec681f3Smrg      *rnum_devices = d_devs.size();
727ec681f3Smrg   if (rd_devices)
737ec681f3Smrg      copy(range(d_devs.begin(),
747ec681f3Smrg                 std::min((unsigned)d_devs.size(), num_entries)),
757ec681f3Smrg           rd_devices);
767ec681f3Smrg
777ec681f3Smrg   return CL_SUCCESS;
787ec681f3Smrg
797ec681f3Smrg} catch (error &e) {
807ec681f3Smrg   return e.get();
817ec681f3Smrg}
827ec681f3Smrg
837ec681f3SmrgCLOVER_API cl_int
847ec681f3SmrgclCreateSubDevices(cl_device_id d_dev,
857ec681f3Smrg                   const cl_device_partition_property *props,
867ec681f3Smrg                   cl_uint num_devs, cl_device_id *rd_devs,
877ec681f3Smrg                   cl_uint *rnum_devs) {
887ec681f3Smrg   // There are no currently supported partitioning schemes.
897ec681f3Smrg   return CL_INVALID_VALUE;
907ec681f3Smrg}
917ec681f3Smrg
927ec681f3SmrgCLOVER_API cl_int
937ec681f3SmrgclRetainDevice(cl_device_id d_dev) try {
947ec681f3Smrg   obj(d_dev);
957ec681f3Smrg
967ec681f3Smrg   // The reference count doesn't change for root devices.
977ec681f3Smrg   return CL_SUCCESS;
987ec681f3Smrg
997ec681f3Smrg} catch (error &e) {
1007ec681f3Smrg   return e.get();
1017ec681f3Smrg}
1027ec681f3Smrg
1037ec681f3SmrgCLOVER_API cl_int
1047ec681f3SmrgclReleaseDevice(cl_device_id d_dev) try {
1057ec681f3Smrg   obj(d_dev);
1067ec681f3Smrg
1077ec681f3Smrg   // The reference count doesn't change for root devices.
1087ec681f3Smrg   return CL_SUCCESS;
1097ec681f3Smrg
1107ec681f3Smrg} catch (error &e) {
1117ec681f3Smrg   return e.get();
1127ec681f3Smrg}
1137ec681f3Smrg
1147ec681f3SmrgCLOVER_API cl_int
1157ec681f3SmrgclGetDeviceInfo(cl_device_id d_dev, cl_device_info param,
1167ec681f3Smrg                size_t size, void *r_buf, size_t *r_size) try {
1177ec681f3Smrg   property_buffer buf { r_buf, size, r_size };
1187ec681f3Smrg   auto &dev = obj(d_dev);
1197ec681f3Smrg
1207ec681f3Smrg   switch (param) {
1217ec681f3Smrg   case CL_DEVICE_TYPE:
1227ec681f3Smrg      buf.as_scalar<cl_device_type>() = dev.type();
1237ec681f3Smrg      break;
1247ec681f3Smrg
1257ec681f3Smrg   case CL_DEVICE_VENDOR_ID:
1267ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.vendor_id();
1277ec681f3Smrg      break;
1287ec681f3Smrg
1297ec681f3Smrg   case CL_DEVICE_MAX_COMPUTE_UNITS:
1307ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.max_compute_units();
1317ec681f3Smrg      break;
1327ec681f3Smrg
1337ec681f3Smrg   case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
1347ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.max_block_size().size();
1357ec681f3Smrg      break;
1367ec681f3Smrg
1377ec681f3Smrg   case CL_DEVICE_MAX_WORK_ITEM_SIZES:
1387ec681f3Smrg      buf.as_vector<size_t>() = dev.max_block_size();
1397ec681f3Smrg      break;
1407ec681f3Smrg
1417ec681f3Smrg   case CL_DEVICE_MAX_WORK_GROUP_SIZE:
1427ec681f3Smrg      buf.as_scalar<size_t>() = dev.max_threads_per_block();
1437ec681f3Smrg      break;
1447ec681f3Smrg
1457ec681f3Smrg   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
1467ec681f3Smrg      buf.as_scalar<cl_uint>() = 16;
1477ec681f3Smrg      break;
1487ec681f3Smrg
1497ec681f3Smrg   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
1507ec681f3Smrg      buf.as_scalar<cl_uint>() = 8;
1517ec681f3Smrg      break;
1527ec681f3Smrg
1537ec681f3Smrg   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
1547ec681f3Smrg      buf.as_scalar<cl_uint>() = 4;
1557ec681f3Smrg      break;
1567ec681f3Smrg
1577ec681f3Smrg   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
1587ec681f3Smrg      buf.as_scalar<cl_uint>() = 2;
1597ec681f3Smrg      break;
1607ec681f3Smrg
1617ec681f3Smrg   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
1627ec681f3Smrg      buf.as_scalar<cl_uint>() = 4;
1637ec681f3Smrg      break;
1647ec681f3Smrg
1657ec681f3Smrg   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
1667ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0;
1677ec681f3Smrg      break;
1687ec681f3Smrg
1697ec681f3Smrg   case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:
1707ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.has_halves() ? 8 : 0;
1717ec681f3Smrg      break;
1727ec681f3Smrg
1737ec681f3Smrg   case CL_DEVICE_MAX_CLOCK_FREQUENCY:
1747ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.max_clock_frequency();
1757ec681f3Smrg      break;
1767ec681f3Smrg
1777ec681f3Smrg   case CL_DEVICE_ADDRESS_BITS:
1787ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.address_bits();
1797ec681f3Smrg      break;
1807ec681f3Smrg
1817ec681f3Smrg   case CL_DEVICE_MAX_READ_IMAGE_ARGS:
1827ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.max_images_read();
1837ec681f3Smrg      break;
1847ec681f3Smrg
1857ec681f3Smrg   case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
1867ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.max_images_write();
1877ec681f3Smrg      break;
1887ec681f3Smrg
1897ec681f3Smrg   case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
1907ec681f3Smrg      buf.as_scalar<cl_ulong>() = dev.max_mem_alloc_size();
1917ec681f3Smrg      break;
1927ec681f3Smrg
1937ec681f3Smrg   case CL_DEVICE_IMAGE2D_MAX_WIDTH:
1947ec681f3Smrg   case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
1957ec681f3Smrg      buf.as_scalar<size_t>() = dev.max_image_size();
1967ec681f3Smrg      break;
1977ec681f3Smrg
1987ec681f3Smrg   case CL_DEVICE_IMAGE3D_MAX_WIDTH:
1997ec681f3Smrg   case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
2007ec681f3Smrg   case CL_DEVICE_IMAGE3D_MAX_DEPTH:
2017ec681f3Smrg      buf.as_scalar<size_t>() = dev.max_image_size_3d();
2027ec681f3Smrg      break;
2037ec681f3Smrg
2047ec681f3Smrg   case CL_DEVICE_IMAGE_MAX_BUFFER_SIZE:
2057ec681f3Smrg      buf.as_scalar<size_t>() = dev.max_image_buffer_size();
2067ec681f3Smrg      break;
2077ec681f3Smrg
2087ec681f3Smrg   case CL_DEVICE_IMAGE_MAX_ARRAY_SIZE:
2097ec681f3Smrg      buf.as_scalar<size_t>() = dev.max_image_array_number();
2107ec681f3Smrg      break;
2117ec681f3Smrg
2127ec681f3Smrg   case CL_DEVICE_IMAGE_SUPPORT:
2137ec681f3Smrg      buf.as_scalar<cl_bool>() = dev.image_support();
2147ec681f3Smrg      break;
2157ec681f3Smrg
2167ec681f3Smrg   case CL_DEVICE_MAX_PARAMETER_SIZE:
2177ec681f3Smrg      buf.as_scalar<size_t>() = dev.max_mem_input();
2187ec681f3Smrg      break;
2197ec681f3Smrg
2207ec681f3Smrg   case CL_DEVICE_MAX_SAMPLERS:
2217ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.max_samplers();
2227ec681f3Smrg      break;
2237ec681f3Smrg
2247ec681f3Smrg   case CL_DEVICE_MEM_BASE_ADDR_ALIGN:
2257ec681f3Smrg      buf.as_scalar<cl_uint>() = 8 * dev.mem_base_addr_align();
2267ec681f3Smrg      break;
2277ec681f3Smrg
2287ec681f3Smrg   case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:
2297ec681f3Smrg      buf.as_scalar<cl_uint>() = 128;
2307ec681f3Smrg      break;
2317ec681f3Smrg
2327ec681f3Smrg   case CL_DEVICE_HALF_FP_CONFIG:
2337ec681f3Smrg      // This is the "mandated minimum half precision floating-point
2347ec681f3Smrg      // capability" for OpenCL 1.x.
2357ec681f3Smrg      buf.as_scalar<cl_device_fp_config>() =
2367ec681f3Smrg         CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST;
2377ec681f3Smrg      break;
2387ec681f3Smrg
2397ec681f3Smrg   case CL_DEVICE_SINGLE_FP_CONFIG:
2407ec681f3Smrg      // This is the "mandated minimum single precision floating-point
2417ec681f3Smrg      // capability" for OpenCL 1.1.  In OpenCL 1.2, nothing is required for
2427ec681f3Smrg      // custom devices.
2437ec681f3Smrg      buf.as_scalar<cl_device_fp_config>() =
2447ec681f3Smrg         CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST;
2457ec681f3Smrg      break;
2467ec681f3Smrg
2477ec681f3Smrg   case CL_DEVICE_DOUBLE_FP_CONFIG:
2487ec681f3Smrg      if (dev.has_doubles())
2497ec681f3Smrg         // This is the "mandated minimum double precision floating-point
2507ec681f3Smrg         // capability"
2517ec681f3Smrg         buf.as_scalar<cl_device_fp_config>() =
2527ec681f3Smrg               CL_FP_FMA
2537ec681f3Smrg             | CL_FP_ROUND_TO_NEAREST
2547ec681f3Smrg             | CL_FP_ROUND_TO_ZERO
2557ec681f3Smrg             | CL_FP_ROUND_TO_INF
2567ec681f3Smrg             | CL_FP_INF_NAN
2577ec681f3Smrg             | CL_FP_DENORM;
2587ec681f3Smrg      else
2597ec681f3Smrg         buf.as_scalar<cl_device_fp_config>() = 0;
2607ec681f3Smrg      break;
2617ec681f3Smrg
2627ec681f3Smrg   case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:
2637ec681f3Smrg      buf.as_scalar<cl_device_mem_cache_type>() = CL_NONE;
2647ec681f3Smrg      break;
2657ec681f3Smrg
2667ec681f3Smrg   case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:
2677ec681f3Smrg      buf.as_scalar<cl_uint>() = 0;
2687ec681f3Smrg      break;
2697ec681f3Smrg
2707ec681f3Smrg   case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:
2717ec681f3Smrg      buf.as_scalar<cl_ulong>() = 0;
2727ec681f3Smrg      break;
2737ec681f3Smrg
2747ec681f3Smrg   case CL_DEVICE_GLOBAL_MEM_SIZE:
2757ec681f3Smrg      buf.as_scalar<cl_ulong>() = dev.max_mem_global();
2767ec681f3Smrg      break;
2777ec681f3Smrg
2787ec681f3Smrg   case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
2797ec681f3Smrg      buf.as_scalar<cl_ulong>() = dev.max_const_buffer_size();
2807ec681f3Smrg      break;
2817ec681f3Smrg
2827ec681f3Smrg   case CL_DEVICE_MAX_CONSTANT_ARGS:
2837ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.max_const_buffers();
2847ec681f3Smrg      break;
2857ec681f3Smrg
2867ec681f3Smrg   case CL_DEVICE_LOCAL_MEM_TYPE:
2877ec681f3Smrg      buf.as_scalar<cl_device_local_mem_type>() = CL_LOCAL;
2887ec681f3Smrg      break;
2897ec681f3Smrg
2907ec681f3Smrg   case CL_DEVICE_LOCAL_MEM_SIZE:
2917ec681f3Smrg      buf.as_scalar<cl_ulong>() = dev.max_mem_local();
2927ec681f3Smrg      break;
2937ec681f3Smrg
2947ec681f3Smrg   case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
2957ec681f3Smrg      buf.as_scalar<cl_bool>() = CL_FALSE;
2967ec681f3Smrg      break;
2977ec681f3Smrg
2987ec681f3Smrg   case CL_DEVICE_PROFILING_TIMER_RESOLUTION:
2997ec681f3Smrg      buf.as_scalar<size_t>() = 0;
3007ec681f3Smrg      break;
3017ec681f3Smrg
3027ec681f3Smrg   case CL_DEVICE_ENDIAN_LITTLE:
3037ec681f3Smrg      buf.as_scalar<cl_bool>() = (dev.endianness() == PIPE_ENDIAN_LITTLE);
3047ec681f3Smrg      break;
3057ec681f3Smrg
3067ec681f3Smrg   case CL_DEVICE_AVAILABLE:
3077ec681f3Smrg   case CL_DEVICE_COMPILER_AVAILABLE:
3087ec681f3Smrg   case CL_DEVICE_LINKER_AVAILABLE:
3097ec681f3Smrg      buf.as_scalar<cl_bool>() = CL_TRUE;
3107ec681f3Smrg      break;
3117ec681f3Smrg
3127ec681f3Smrg   case CL_DEVICE_EXECUTION_CAPABILITIES:
3137ec681f3Smrg      buf.as_scalar<cl_device_exec_capabilities>() = CL_EXEC_KERNEL;
3147ec681f3Smrg      break;
3157ec681f3Smrg
3167ec681f3Smrg   case CL_DEVICE_QUEUE_PROPERTIES:
3177ec681f3Smrg      buf.as_scalar<cl_command_queue_properties>() = CL_QUEUE_PROFILING_ENABLE;
3187ec681f3Smrg      break;
3197ec681f3Smrg
3207ec681f3Smrg   case CL_DEVICE_BUILT_IN_KERNELS:
3217ec681f3Smrg      buf.as_string() = "";
3227ec681f3Smrg      break;
3237ec681f3Smrg
3247ec681f3Smrg   case CL_DEVICE_NAME:
3257ec681f3Smrg      buf.as_string() = dev.device_name();
3267ec681f3Smrg      break;
3277ec681f3Smrg
3287ec681f3Smrg   case CL_DEVICE_VENDOR:
3297ec681f3Smrg      buf.as_string() = dev.vendor_name();
3307ec681f3Smrg      break;
3317ec681f3Smrg
3327ec681f3Smrg   case CL_DRIVER_VERSION:
3337ec681f3Smrg      buf.as_string() = PACKAGE_VERSION;
3347ec681f3Smrg      break;
3357ec681f3Smrg
3367ec681f3Smrg   case CL_DEVICE_PROFILE:
3377ec681f3Smrg      buf.as_string() = "FULL_PROFILE";
3387ec681f3Smrg      break;
3397ec681f3Smrg
3407ec681f3Smrg   case CL_DEVICE_VERSION:
3417ec681f3Smrg      buf.as_string() = "OpenCL " + dev.device_version_as_string() + " Mesa " PACKAGE_VERSION MESA_GIT_SHA1;
3427ec681f3Smrg      break;
3437ec681f3Smrg
3447ec681f3Smrg   case CL_DEVICE_EXTENSIONS:
3457ec681f3Smrg      buf.as_string() = dev.supported_extensions_as_string();
3467ec681f3Smrg      break;
3477ec681f3Smrg
3487ec681f3Smrg   case CL_DEVICE_PLATFORM:
3497ec681f3Smrg      buf.as_scalar<cl_platform_id>() = desc(dev.platform);
3507ec681f3Smrg      break;
3517ec681f3Smrg
3527ec681f3Smrg   case CL_DEVICE_HOST_UNIFIED_MEMORY:
3537ec681f3Smrg      buf.as_scalar<cl_bool>() = dev.has_unified_memory();
3547ec681f3Smrg      break;
3557ec681f3Smrg
3567ec681f3Smrg   case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:
3577ec681f3Smrg      buf.as_scalar<cl_uint>() = 16;
3587ec681f3Smrg      break;
3597ec681f3Smrg
3607ec681f3Smrg   case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:
3617ec681f3Smrg      buf.as_scalar<cl_uint>() = 8;
3627ec681f3Smrg      break;
3637ec681f3Smrg
3647ec681f3Smrg   case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:
3657ec681f3Smrg      buf.as_scalar<cl_uint>() = 4;
3667ec681f3Smrg      break;
3677ec681f3Smrg
3687ec681f3Smrg   case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:
3697ec681f3Smrg      buf.as_scalar<cl_uint>() = 2;
3707ec681f3Smrg      break;
3717ec681f3Smrg
3727ec681f3Smrg   case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:
3737ec681f3Smrg      buf.as_scalar<cl_uint>() = 4;
3747ec681f3Smrg      break;
3757ec681f3Smrg
3767ec681f3Smrg   case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:
3777ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0;
3787ec681f3Smrg      break;
3797ec681f3Smrg
3807ec681f3Smrg   case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:
3817ec681f3Smrg      buf.as_scalar<cl_uint>() = dev.has_halves() ? 8 : 0;
3827ec681f3Smrg      break;
3837ec681f3Smrg
3847ec681f3Smrg   case CL_DEVICE_OPENCL_C_VERSION:
3857ec681f3Smrg      buf.as_string() = "OpenCL C " + dev.device_clc_version_as_string() + " ";
3867ec681f3Smrg      break;
3877ec681f3Smrg
3887ec681f3Smrg   case CL_DEVICE_PRINTF_BUFFER_SIZE:
3897ec681f3Smrg      buf.as_scalar<size_t>() = dev.max_printf_buffer_size();
3907ec681f3Smrg      break;
3917ec681f3Smrg
3927ec681f3Smrg   case CL_DEVICE_PREFERRED_INTEROP_USER_SYNC:
3937ec681f3Smrg      buf.as_scalar<cl_bool>() = CL_TRUE;
3947ec681f3Smrg      break;
3957ec681f3Smrg
3967ec681f3Smrg   case CL_DEVICE_PARENT_DEVICE:
3977ec681f3Smrg      buf.as_scalar<cl_device_id>() = NULL;
3987ec681f3Smrg      break;
3997ec681f3Smrg
4007ec681f3Smrg   case CL_DEVICE_PARTITION_MAX_SUB_DEVICES:
4017ec681f3Smrg      buf.as_scalar<cl_uint>() = 0;
4027ec681f3Smrg      break;
4037ec681f3Smrg
4047ec681f3Smrg   case CL_DEVICE_PARTITION_PROPERTIES:
4057ec681f3Smrg      buf.as_vector<cl_device_partition_property>() =
4067ec681f3Smrg         desc(property_list<cl_device_partition_property>());
4077ec681f3Smrg      break;
4087ec681f3Smrg
4097ec681f3Smrg   case CL_DEVICE_PARTITION_AFFINITY_DOMAIN:
4107ec681f3Smrg      buf.as_scalar<cl_device_affinity_domain>() = 0;
4117ec681f3Smrg      break;
4127ec681f3Smrg
4137ec681f3Smrg   case CL_DEVICE_PARTITION_TYPE:
4147ec681f3Smrg      buf.as_vector<cl_device_partition_property>() =
4157ec681f3Smrg         desc(property_list<cl_device_partition_property>());
4167ec681f3Smrg      break;
4177ec681f3Smrg
4187ec681f3Smrg   case CL_DEVICE_REFERENCE_COUNT:
4197ec681f3Smrg      buf.as_scalar<cl_uint>() = 1;
4207ec681f3Smrg      break;
4217ec681f3Smrg
4227ec681f3Smrg   case CL_DEVICE_SVM_CAPABILITIES:
4237ec681f3Smrg   case CL_DEVICE_SVM_CAPABILITIES_ARM:
4247ec681f3Smrg      buf.as_scalar<cl_device_svm_capabilities>() = dev.svm_support();
4257ec681f3Smrg      break;
4267ec681f3Smrg
4277ec681f3Smrg   case CL_DEVICE_NUMERIC_VERSION:
4287ec681f3Smrg      buf.as_scalar<cl_version>() = dev.device_version();
4297ec681f3Smrg      break;
4307ec681f3Smrg
4317ec681f3Smrg   case CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR:
4327ec681f3Smrg      buf.as_scalar<cl_version>() = dev.device_clc_version(true);
4337ec681f3Smrg      break;
4347ec681f3Smrg
4357ec681f3Smrg   case CL_DEVICE_OPENCL_C_ALL_VERSIONS:
4367ec681f3Smrg      buf.as_vector<cl_name_version>() = dev.opencl_c_all_versions();
4377ec681f3Smrg      break;
4387ec681f3Smrg
4397ec681f3Smrg   case CL_DEVICE_EXTENSIONS_WITH_VERSION:
4407ec681f3Smrg      buf.as_vector<cl_name_version>() = dev.supported_extensions();
4417ec681f3Smrg      break;
4427ec681f3Smrg
4437ec681f3Smrg   case CL_DEVICE_OPENCL_C_FEATURES:
4447ec681f3Smrg      buf.as_vector<cl_name_version>() = dev.opencl_c_features();
4457ec681f3Smrg      break;
4467ec681f3Smrg
4477ec681f3Smrg   case CL_DEVICE_IL_VERSION:
4487ec681f3Smrg      if (dev.supported_extensions_as_string().find("cl_khr_il_program") == std::string::npos)
4497ec681f3Smrg         throw error(CL_INVALID_VALUE);
4507ec681f3Smrg      buf.as_string() = supported_il_versions_as_string(dev);
4517ec681f3Smrg      break;
4527ec681f3Smrg
4537ec681f3Smrg   case CL_DEVICE_ILS_WITH_VERSION:
4547ec681f3Smrg      buf.as_vector<cl_name_version>() = dev.supported_il_versions();
4557ec681f3Smrg      break;
4567ec681f3Smrg
4577ec681f3Smrg   case CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION:
4587ec681f3Smrg      buf.as_vector<cl_name_version>() = std::vector<cl_name_version>{};
4597ec681f3Smrg      break;
4607ec681f3Smrg
4617ec681f3Smrg   case CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS:
4627ec681f3Smrg   case CL_DEVICE_IMAGE_PITCH_ALIGNMENT:
4637ec681f3Smrg   case CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT:
4647ec681f3Smrg   case CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT:
4657ec681f3Smrg   case CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT:
4667ec681f3Smrg   case CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT:
4677ec681f3Smrg   case CL_DEVICE_MAX_NUM_SUB_GROUPS:
4687ec681f3Smrg   case CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE:
4697ec681f3Smrg   case CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE:
4707ec681f3Smrg   case CL_DEVICE_MAX_ON_DEVICE_QUEUES:
4717ec681f3Smrg   case CL_DEVICE_MAX_ON_DEVICE_EVENTS:
4727ec681f3Smrg   case CL_DEVICE_MAX_PIPE_ARGS:
4737ec681f3Smrg   case CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS:
4747ec681f3Smrg   case CL_DEVICE_PIPE_MAX_PACKET_SIZE:
4757ec681f3Smrg      buf.as_scalar<cl_uint>() = 0;
4767ec681f3Smrg      break;
4777ec681f3Smrg
4787ec681f3Smrg   case CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE:
4797ec681f3Smrg   case CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE:
4807ec681f3Smrg      buf.as_scalar<size_t>() = 0;
4817ec681f3Smrg      break;
4827ec681f3Smrg
4837ec681f3Smrg   case CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS:
4847ec681f3Smrg   case CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT:
4857ec681f3Smrg   case CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT:
4867ec681f3Smrg   case CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT:
4877ec681f3Smrg   case CL_DEVICE_PIPE_SUPPORT:
4887ec681f3Smrg      buf.as_scalar<cl_bool>() = CL_FALSE;
4897ec681f3Smrg      break;
4907ec681f3Smrg
4917ec681f3Smrg   case CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES:
4927ec681f3Smrg      buf.as_scalar<cl_command_queue_properties>() = 0;
4937ec681f3Smrg      break;
4947ec681f3Smrg
4957ec681f3Smrg   case CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES:
4967ec681f3Smrg      buf.as_scalar<cl_device_atomic_capabilities>() = (CL_DEVICE_ATOMIC_ORDER_RELAXED |
4977ec681f3Smrg                                                        CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP);
4987ec681f3Smrg      break;
4997ec681f3Smrg   case CL_DEVICE_ATOMIC_FENCE_CAPABILITIES:
5007ec681f3Smrg      buf.as_scalar<cl_device_atomic_capabilities>() = (CL_DEVICE_ATOMIC_ORDER_RELAXED |
5017ec681f3Smrg                                                        CL_DEVICE_ATOMIC_ORDER_ACQ_REL |
5027ec681f3Smrg                                                        CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP);
5037ec681f3Smrg      break;
5047ec681f3Smrg
5057ec681f3Smrg   case CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES:
5067ec681f3Smrg      buf.as_scalar<cl_device_device_enqueue_capabilities>() = 0;
5077ec681f3Smrg      break;
5087ec681f3Smrg
5097ec681f3Smrg   case CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE:
5107ec681f3Smrg      buf.as_scalar<size_t>() = 1;
5117ec681f3Smrg      break;
5127ec681f3Smrg
5137ec681f3Smrg   case CL_DEVICE_LATEST_CONFORMANCE_VERSION_PASSED:
5147ec681f3Smrg      buf.as_string() = "";
5157ec681f3Smrg      break;
5167ec681f3Smrg
5177ec681f3Smrg   default:
5187ec681f3Smrg      throw error(CL_INVALID_VALUE);
5197ec681f3Smrg   }
5207ec681f3Smrg
5217ec681f3Smrg   return CL_SUCCESS;
5227ec681f3Smrg
5237ec681f3Smrg} catch (error &e) {
5247ec681f3Smrg   return e.get();
5257ec681f3Smrg}
526