Mesa (main): clover: Do not advertise OpenCL x.y when unsupported

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Aug 3 17:25:25 UTC 2021


Module: Mesa
Branch: main
Commit: 8061dfef6bf6f524712d13bba9adfd4dcbc73eb5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8061dfef6bf6f524712d13bba9adfd4dcbc73eb5

Author: Pierre Moreau <dev at pmoreau.org>
Date:   Sat Jan 16 14:55:36 2021 +0100

clover: Do not advertise OpenCL x.y when unsupported

Instead of hardcoding a fixed version for all devices, compute the
highest version supported by a device based on the different constraints
mandated by each new version.

For example, besides new functionalities, OpenCL 1.1 also increases the
minimum limits regarding the amount of local memory and the amount of
bytes taken by all arguments to a kernel. Some hardware (such as all
GPUs from NVIDIA’s Tesla micro-architecture) can support the additional
features but do not pass those new minimums.

v3:
* Change `get_highest_supported_version()` to return the version instead
  of modifying the version components passed as arguments. (Francisco
  Jerez)
* Tweak the line wrapping for `has_extension()`. (Francisco Jerez)

v2:
* Invert the ordering of OpenCL and OpenCL C version, to restrict OpenCL
  version based on supported OpenCL C version.
* Rename `get_supported_version()` to `get_highest_supported_version()`;
* Use device methods to query parameters instead of manually executing
  them;
* Clarify that the limit checking is only for non-custom devices
  supporting the full profile.
* Check for mandatory extensions as well;
* Validate CL_DEVICE_MEM_BASE_ADDR_ALIGN;
* Fix the OpenCL>=1.1 minimum limit for CL_DEVICE_LOCAL_MEM_SIZE, from
  32 * 1000 to 32 * 1024;
* Restrict to OpenCL 1.0 if OpenCL C 1.1 is not supported.
* Compute the highest supported version based on constraints (ignoring
  2.x versions).

Reviewed-by: Karol Herbst <kherbst at redhat.com>
Signed-off-by: Pierre Moreau <dev at pmoreau.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10256>

---

 src/gallium/frontends/clover/core/device.cpp | 120 +++++++++++++++++++++++++--
 1 file changed, 112 insertions(+), 8 deletions(-)

diff --git a/src/gallium/frontends/clover/core/device.cpp b/src/gallium/frontends/clover/core/device.cpp
index 2ba673e71b9..d9bd2d00f04 100644
--- a/src/gallium/frontends/clover/core/device.cpp
+++ b/src/gallium/frontends/clover/core/device.cpp
@@ -45,20 +45,124 @@ namespace {
       pipe->get_compute_param(pipe, ir_format, cap, &v.front());
       return v;
    }
+
+   cl_version
+   get_highest_supported_version(const device &dev) {
+      // All the checks below assume that the device supports FULL_PROFILE
+      // (which is the only profile support by clover) and that a device is
+      // not CUSTOM.
+      assert(dev.type() != CL_DEVICE_TYPE_CUSTOM);
+
+      cl_version version = CL_MAKE_VERSION(0, 0, 0);
+
+      const auto has_extension =
+         [extensions = dev.supported_extensions()](const char *extension_name){
+            return std::find_if(extensions.begin(), extensions.end(),
+                  [extension_name](const cl_name_version &extension){
+                     return strcmp(extension.name, extension_name) == 0;
+               }) != extensions.end();
+      };
+      const bool supports_images = dev.image_support();
+
+      // Check requirements for OpenCL 1.0
+      if (dev.max_compute_units() < 1 ||
+          dev.max_block_size().size() < 3 ||
+          // TODO: Check CL_DEVICE_MAX_WORK_ITEM_SIZES
+          dev.max_threads_per_block() < 1 ||
+          (dev.address_bits() != 32 && dev.address_bits() != 64) ||
+          dev.max_mem_alloc_size() < std::max(dev.max_mem_global() / 4,
+                                              (cl_ulong)128 * 1024 * 1024) ||
+          dev.max_mem_input() < 256 ||
+          dev.max_const_buffer_size() < 64 * 1024 ||
+          dev.max_const_buffers() < 8 ||
+          dev.max_mem_local() < 16 * 1024 ||
+          dev.clc_version < CL_MAKE_VERSION(1, 0, 0) ||
+          (supports_images &&
+           (dev.max_images_read() < 128 ||
+            dev.max_images_write() < 8 ||
+            dev.max_image_size() < 8192 ||
+            dev.max_image_size_3d() < 2048 ||
+            dev.max_samplers() < 16))) {
+         return version;
+      }
+      version = CL_MAKE_VERSION(1, 0, 0);
+
+      // Check requirements for OpenCL 1.1
+      if (!has_extension("cl_khr_byte_addressable_store") ||
+          !has_extension("cl_khr_global_int32_base_atomics") ||
+          !has_extension("cl_khr_global_int32_extended_atomics") ||
+          !has_extension("cl_khr_local_int32_base_atomics") ||
+          !has_extension("cl_khr_local_int32_extended_atomics") ||
+          // OpenCL 1.1 increased the minimum value for
+          // CL_DEVICE_MAX_PARAMETER_SIZE to 1024 bytes.
+          dev.max_mem_input() < 1024 ||
+          dev.mem_base_addr_align() < sizeof(cl_long16) ||
+          // OpenCL 1.1 increased the minimum value for
+          // CL_DEVICE_LOCAL_MEM_SIZE to 32 KB.
+          dev.max_mem_local() < 32 * 1024 ||
+          dev.clc_version < CL_MAKE_VERSION(1, 1, 0)) {
+         return version;
+      }
+      version = CL_MAKE_VERSION(1, 1, 0);
+
+      // Check requirements for OpenCL 1.2
+      if ((dev.has_doubles() && !has_extension("cl_khr_fp64")) ||
+          dev.clc_version < CL_MAKE_VERSION(1, 2, 0) ||
+          dev.max_printf_buffer_size() < 1 * 1024 * 1024 ||
+          (supports_images &&
+           (dev.max_image_buffer_size()  < 65536 ||
+            dev.max_image_array_number() < 2048))) {
+         return version;
+      }
+      version = CL_MAKE_VERSION(1, 2, 0);
+
+      // Check requirements for OpenCL 3.0
+      if (dev.max_mem_alloc_size() < std::max(std::min((cl_ulong)1024 * 1024 * 1024,
+                                                       dev.max_mem_global() / 4),
+                                              (cl_ulong)128 * 1024 * 1024) ||
+          // TODO: If pipes are supported, check:
+          //       * CL_DEVICE_MAX_PIPE_ARGS
+          //       * CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS
+          //       * CL_DEVICE_PIPE_MAX_PACKET_SIZE
+          // TODO: If on-device queues are supported, check:
+          //       * CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES
+          //       * CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE
+          //       * CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE
+          //       * CL_DEVICE_MAX_ON_DEVICE_QUEUES
+          //       * CL_DEVICE_MAX_ON_DEVICE_EVENTS
+          dev.clc_version < CL_MAKE_VERSION(3, 0, 0) ||
+          (supports_images &&
+           (dev.max_images_write() < 64 ||
+            dev.max_image_size() < 16384))) {
+         return version;
+      }
+      version = CL_MAKE_VERSION(3, 0, 0);
+
+      return version;
+   }
 }
 
 device::device(clover::platform &platform, pipe_loader_device *ldev) :
    platform(platform), clc_cache(NULL), ldev(ldev) {
-   unsigned major = 1, minor = 1;
-   debug_get_version_option("CLOVER_DEVICE_VERSION_OVERRIDE", &major, &minor);
-   version = CL_MAKE_VERSION(major, minor, 0);
-
-   major = 1, minor = 1;
-   debug_get_version_option("CLOVER_DEVICE_CLC_VERSION_OVERRIDE", &major, &minor);
-   clc_version = CL_MAKE_VERSION(major, minor, 0);
-
    pipe = pipe_loader_create_screen(ldev);
    if (pipe && pipe->get_param(pipe, PIPE_CAP_COMPUTE)) {
+      const bool has_supported_ir = supports_ir(PIPE_SHADER_IR_NATIVE) ||
+                                    supports_ir(PIPE_SHADER_IR_NIR_SERIALIZED);
+      if (has_supported_ir) {
+         unsigned major = 1, minor = 1;
+         debug_get_version_option("CLOVER_DEVICE_CLC_VERSION_OVERRIDE",
+                                  &major, &minor);
+         clc_version = CL_MAKE_VERSION(major, minor, 0);
+
+         version = get_highest_supported_version(*this);
+         major = CL_VERSION_MAJOR(version);
+         minor = CL_VERSION_MINOR(version);
+         debug_get_version_option("CLOVER_DEVICE_VERSION_OVERRIDE", &major,
+                                  &minor);
+         version = CL_MAKE_VERSION(major, minor, 0);
+
+      }
+
       if (supports_ir(PIPE_SHADER_IR_NATIVE))
          return;
 #ifdef HAVE_CLOVER_SPIRV



More information about the mesa-commit mailing list