Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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 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.
  21. //
  22.  
  23. #include "api/util.hpp"
  24. #include "core/platform.hpp"
  25. #include "core/device.hpp"
  26.  
  27. using namespace clover;
  28.  
  29. CLOVER_API cl_int
  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;
  35.  
  36.    if ((!num_entries && rd_devices) ||
  37.        (!rnum_devices && !rd_devices))
  38.       throw error(CL_INVALID_VALUE);
  39.  
  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));
  46.    }
  47.  
  48.    if (d_devs.empty())
  49.       throw error(CL_DEVICE_NOT_FOUND);
  50.  
  51.    // ...and return the requested data.
  52.    if (rnum_devices)
  53.       *rnum_devices = d_devs.size();
  54.    if (rd_devices)
  55.       copy(range(d_devs.begin(),
  56.                  std::min((unsigned)d_devs.size(), num_entries)),
  57.            rd_devices);
  58.  
  59.    return CL_SUCCESS;
  60.  
  61. } catch (error &e) {
  62.    return e.get();
  63. }
  64.  
  65. CLOVER_API cl_int
  66. clCreateSubDevices(cl_device_id d_dev,
  67.                    const cl_device_partition_property *props,
  68.                    cl_uint num_devs, cl_device_id *rd_devs,
  69.                    cl_uint *rnum_devs) {
  70.    // There are no currently supported partitioning schemes.
  71.    return CL_INVALID_VALUE;
  72. }
  73.  
  74. CLOVER_API cl_int
  75. clRetainDevice(cl_device_id d_dev) try {
  76.    obj(d_dev);
  77.  
  78.    // The reference count doesn't change for root devices.
  79.    return CL_SUCCESS;
  80.  
  81. } catch (error &e) {
  82.    return e.get();
  83. }
  84.  
  85. CLOVER_API cl_int
  86. clReleaseDevice(cl_device_id d_dev) try {
  87.    obj(d_dev);
  88.  
  89.    // The reference count doesn't change for root devices.
  90.    return CL_SUCCESS;
  91.  
  92. } catch (error &e) {
  93.    return e.get();
  94. }
  95.  
  96. CLOVER_API cl_int
  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);
  101.  
  102.    switch (param) {
  103.    case CL_DEVICE_TYPE:
  104.       buf.as_scalar<cl_device_type>() = dev.type();
  105.       break;
  106.  
  107.    case CL_DEVICE_VENDOR_ID:
  108.       buf.as_scalar<cl_uint>() = dev.vendor_id();
  109.       break;
  110.  
  111.    case CL_DEVICE_MAX_COMPUTE_UNITS:
  112.       buf.as_scalar<cl_uint>() = dev.max_compute_units();
  113.       break;
  114.  
  115.    case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
  116.       buf.as_scalar<cl_uint>() = dev.max_block_size().size();
  117.       break;
  118.  
  119.    case CL_DEVICE_MAX_WORK_ITEM_SIZES:
  120.       buf.as_vector<size_t>() = dev.max_block_size();
  121.       break;
  122.  
  123.    case CL_DEVICE_MAX_WORK_GROUP_SIZE:
  124.       buf.as_scalar<size_t>() = dev.max_threads_per_block();
  125.       break;
  126.  
  127.    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
  128.       buf.as_scalar<cl_uint>() = 16;
  129.       break;
  130.  
  131.    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
  132.       buf.as_scalar<cl_uint>() = 8;
  133.       break;
  134.  
  135.    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
  136.       buf.as_scalar<cl_uint>() = 4;
  137.       break;
  138.  
  139.    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
  140.       buf.as_scalar<cl_uint>() = 2;
  141.       break;
  142.  
  143.    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
  144.       buf.as_scalar<cl_uint>() = 4;
  145.       break;
  146.  
  147.    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
  148.       buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0;
  149.       break;
  150.  
  151.    case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:
  152.       buf.as_scalar<cl_uint>() = 0;
  153.       break;
  154.  
  155.    case CL_DEVICE_MAX_CLOCK_FREQUENCY:
  156.       buf.as_scalar<cl_uint>() = dev.max_clock_frequency();
  157.       break;
  158.  
  159.    case CL_DEVICE_ADDRESS_BITS:
  160.       buf.as_scalar<cl_uint>() = 32;
  161.       break;
  162.  
  163.    case CL_DEVICE_MAX_READ_IMAGE_ARGS:
  164.       buf.as_scalar<cl_uint>() = dev.max_images_read();
  165.       break;
  166.  
  167.    case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
  168.       buf.as_scalar<cl_uint>() = dev.max_images_write();
  169.       break;
  170.  
  171.    case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
  172.       buf.as_scalar<cl_ulong>() = dev.max_mem_alloc_size();
  173.       break;
  174.  
  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();
  178.       break;
  179.  
  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();
  184.       break;
  185.  
  186.    case CL_DEVICE_IMAGE_SUPPORT:
  187.       buf.as_scalar<cl_bool>() = dev.image_support();
  188.       break;
  189.  
  190.    case CL_DEVICE_MAX_PARAMETER_SIZE:
  191.       buf.as_scalar<size_t>() = dev.max_mem_input();
  192.       break;
  193.  
  194.    case CL_DEVICE_MAX_SAMPLERS:
  195.       buf.as_scalar<cl_uint>() = dev.max_samplers();
  196.       break;
  197.  
  198.    case CL_DEVICE_MEM_BASE_ADDR_ALIGN:
  199.       buf.as_scalar<cl_uint>() = 128 * 8;
  200.       break;
  201.  
  202.    case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:
  203.       buf.as_scalar<cl_uint>() = 128;
  204.       break;
  205.  
  206.    case CL_DEVICE_SINGLE_FP_CONFIG:
  207.       // This is the "mandated minimum single precision floating-point
  208.       // capability" for OpenCL 1.1.  In OpenCL 1.2, nothing is required for
  209.       // custom devices.
  210.       buf.as_scalar<cl_device_fp_config>() =
  211.          CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST;
  212.       break;
  213.  
  214.    case CL_DEVICE_DOUBLE_FP_CONFIG:
  215.       if (dev.has_doubles())
  216.          // This is the "mandated minimum double precision floating-point
  217.          // capability"
  218.          buf.as_scalar<cl_device_fp_config>() =
  219.                CL_FP_FMA
  220.              | CL_FP_ROUND_TO_NEAREST
  221.              | CL_FP_ROUND_TO_ZERO
  222.              | CL_FP_ROUND_TO_INF
  223.              | CL_FP_INF_NAN
  224.              | CL_FP_DENORM;
  225.       else
  226.          buf.as_scalar<cl_device_fp_config>() = 0;
  227.       break;
  228.  
  229.    case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:
  230.       buf.as_scalar<cl_device_mem_cache_type>() = CL_NONE;
  231.       break;
  232.  
  233.    case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:
  234.       buf.as_scalar<cl_uint>() = 0;
  235.       break;
  236.  
  237.    case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:
  238.       buf.as_scalar<cl_ulong>() = 0;
  239.       break;
  240.  
  241.    case CL_DEVICE_GLOBAL_MEM_SIZE:
  242.       buf.as_scalar<cl_ulong>() = dev.max_mem_global();
  243.       break;
  244.  
  245.    case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
  246.       buf.as_scalar<cl_ulong>() = dev.max_const_buffer_size();
  247.       break;
  248.  
  249.    case CL_DEVICE_MAX_CONSTANT_ARGS:
  250.       buf.as_scalar<cl_uint>() = dev.max_const_buffers();
  251.       break;
  252.  
  253.    case CL_DEVICE_LOCAL_MEM_TYPE:
  254.       buf.as_scalar<cl_device_local_mem_type>() = CL_LOCAL;
  255.       break;
  256.  
  257.    case CL_DEVICE_LOCAL_MEM_SIZE:
  258.       buf.as_scalar<cl_ulong>() = dev.max_mem_local();
  259.       break;
  260.  
  261.    case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
  262.       buf.as_scalar<cl_bool>() = CL_FALSE;
  263.       break;
  264.  
  265.    case CL_DEVICE_PROFILING_TIMER_RESOLUTION:
  266.       buf.as_scalar<size_t>() = 0;
  267.       break;
  268.  
  269.    case CL_DEVICE_ENDIAN_LITTLE:
  270.       buf.as_scalar<cl_bool>() = (dev.endianness() == PIPE_ENDIAN_LITTLE);
  271.       break;
  272.  
  273.    case CL_DEVICE_AVAILABLE:
  274.    case CL_DEVICE_COMPILER_AVAILABLE:
  275.       buf.as_scalar<cl_bool>() = CL_TRUE;
  276.       break;
  277.  
  278.    case CL_DEVICE_EXECUTION_CAPABILITIES:
  279.       buf.as_scalar<cl_device_exec_capabilities>() = CL_EXEC_KERNEL;
  280.       break;
  281.  
  282.    case CL_DEVICE_QUEUE_PROPERTIES:
  283.       buf.as_scalar<cl_command_queue_properties>() = CL_QUEUE_PROFILING_ENABLE;
  284.       break;
  285.  
  286.    case CL_DEVICE_NAME:
  287.       buf.as_string() = dev.device_name();
  288.       break;
  289.  
  290.    case CL_DEVICE_VENDOR:
  291.       buf.as_string() = dev.vendor_name();
  292.       break;
  293.  
  294.    case CL_DRIVER_VERSION:
  295.       buf.as_string() = PACKAGE_VERSION;
  296.       break;
  297.  
  298.    case CL_DEVICE_PROFILE:
  299.       buf.as_string() = "FULL_PROFILE";
  300.       break;
  301.  
  302.    case CL_DEVICE_VERSION:
  303.       buf.as_string() = "OpenCL 1.1 MESA " PACKAGE_VERSION;
  304.       break;
  305.  
  306.    case CL_DEVICE_EXTENSIONS:
  307.       buf.as_string() =
  308.          "cl_khr_global_int32_base_atomics"
  309.          " cl_khr_global_int32_extended_atomics"
  310.          " cl_khr_local_int32_base_atomics"
  311.          " cl_khr_local_int32_extended_atomics"
  312.          " cl_khr_byte_addressable_store"
  313.          + std::string(dev.has_doubles() ? " cl_khr_fp64" : "");
  314.       break;
  315.  
  316.    case CL_DEVICE_PLATFORM:
  317.       buf.as_scalar<cl_platform_id>() = desc(dev.platform);
  318.       break;
  319.  
  320.    case CL_DEVICE_HOST_UNIFIED_MEMORY:
  321.       buf.as_scalar<cl_bool>() = CL_TRUE;
  322.       break;
  323.  
  324.    case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:
  325.       buf.as_scalar<cl_uint>() = 16;
  326.       break;
  327.  
  328.    case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:
  329.       buf.as_scalar<cl_uint>() = 8;
  330.       break;
  331.  
  332.    case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:
  333.       buf.as_scalar<cl_uint>() = 4;
  334.       break;
  335.  
  336.    case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:
  337.       buf.as_scalar<cl_uint>() = 2;
  338.       break;
  339.  
  340.    case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:
  341.       buf.as_scalar<cl_uint>() = 4;
  342.       break;
  343.  
  344.    case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:
  345.       buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0;
  346.       break;
  347.  
  348.    case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:
  349.       buf.as_scalar<cl_uint>() = 0;
  350.       break;
  351.  
  352.    case CL_DEVICE_OPENCL_C_VERSION:
  353.       buf.as_string() = "OpenCL C 1.1 ";
  354.       break;
  355.  
  356.    case CL_DEVICE_PARENT_DEVICE:
  357.       buf.as_scalar<cl_device_id>() = NULL;
  358.       break;
  359.  
  360.    case CL_DEVICE_PARTITION_MAX_SUB_DEVICES:
  361.       buf.as_scalar<cl_uint>() = 0;
  362.       break;
  363.  
  364.    case CL_DEVICE_PARTITION_PROPERTIES:
  365.       buf.as_vector<cl_device_partition_property>() =
  366.          desc(property_list<cl_device_partition_property>());
  367.       break;
  368.  
  369.    case CL_DEVICE_PARTITION_AFFINITY_DOMAIN:
  370.       buf.as_scalar<cl_device_affinity_domain>() = 0;
  371.       break;
  372.  
  373.    case CL_DEVICE_PARTITION_TYPE:
  374.       buf.as_vector<cl_device_partition_property>() =
  375.          desc(property_list<cl_device_partition_property>());
  376.       break;
  377.  
  378.    case CL_DEVICE_REFERENCE_COUNT:
  379.       buf.as_scalar<cl_uint>() = 1;
  380.       break;
  381.  
  382.    default:
  383.       throw error(CL_INVALID_VALUE);
  384.    }
  385.  
  386.    return CL_SUCCESS;
  387.  
  388. } catch (error &e) {
  389.    return e.get();
  390. }
  391.