summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Moreau <dev@pmoreau.org>2021-01-16 14:55:36 +0100
committerMarge Bot <eric+marge@anholt.net>2021-08-03 16:43:48 +0000
commit8061dfef6bf6f524712d13bba9adfd4dcbc73eb5 (patch)
treed021b216c7abdddfbaaac295fed2c0e7397203e0
parentcd79351f02af898b0b01997f0b8b77007ed88135 (diff)
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@redhat.com> Signed-off-by: Pierre Moreau <dev@pmoreau.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10256>
-rw-r--r--src/gallium/frontends/clover/core/device.cpp120
1 files 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