From f72443448e4cef5725f3dad3c654d52f45223eeb Mon Sep 17 00:00:00 2001 From: Aaron Greig Date: Mon, 27 Nov 2023 16:11:47 +0000 Subject: [PATCH] Clarify spec for QUEUE_INFO_SIZE and change testing for it accordingly. Also correctly report lack of queue on device support in cuda and hip adapters. --- include/ur_api.h | 11 +++- scripts/core/queue.yml | 18 ++++-- source/adapters/cuda/device.cpp | 6 +- source/adapters/hip/device.cpp | 6 +- source/adapters/native_cpu/device.cpp | 4 ++ source/adapters/opencl/common.cpp | 2 + source/loader/ur_libapi.cpp | 1 + source/ur_api.cpp | 1 + .../device/device_adapter_native_cpu.match | 1 - .../conformance/queue/queue_adapter_hip.match | 2 - .../queue/queue_adapter_native_cpu.match | 2 - .../queue/queue_adapter_opencl.match | 2 - test/conformance/queue/urQueueGetInfo.cpp | 62 ++++++++++++++++++- 13 files changed, 93 insertions(+), 25 deletions(-) diff --git a/include/ur_api.h b/include/ur_api.h index 8579ff0326..c7dad2dae4 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -5130,14 +5130,17 @@ typedef enum ur_queue_info_t { UR_QUEUE_INFO_CONTEXT = 0, ///< [::ur_context_handle_t] context associated with this queue. UR_QUEUE_INFO_DEVICE = 1, ///< [::ur_device_handle_t] device associated with this queue. UR_QUEUE_INFO_DEVICE_DEFAULT = 2, ///< [::ur_queue_handle_t] the current default queue of the underlying - ///< device. + ///< device. Only returns a value if a queue associated with the + ///< underlying device has been created with `::UR_QUEUE_FLAG_ON_DEVICE_DEFAULT`. UR_QUEUE_INFO_FLAGS = 3, ///< [::ur_queue_flags_t] the properties associated with ///< ::ur_queue_properties_t::flags. UR_QUEUE_INFO_REFERENCE_COUNT = 4, ///< [uint32_t] Reference count of the queue object. ///< The reference count returned should be considered immediately stale. ///< It is unsuitable for general use in applications. This feature is ///< provided for identifying memory leaks. - UR_QUEUE_INFO_SIZE = 5, ///< [uint32_t] The size of the queue + UR_QUEUE_INFO_SIZE = 5, ///< [uint32_t] The size of the queue on the device. Only a valid query + ///< if the queue was created with the `ON_DEVICE` queue flag, otherwise + ///< `::urQueueGetInfo` will return `::UR_RESULT_ERROR_INVALID_QUEUE`. UR_QUEUE_INFO_EMPTY = 6, ///< [::ur_bool_t] return true if the queue was empty at the time of the ///< query /// @cond @@ -5152,7 +5155,8 @@ typedef uint32_t ur_queue_flags_t; typedef enum ur_queue_flag_t { UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE = UR_BIT(0), ///< Enable/disable out of order execution UR_QUEUE_FLAG_PROFILING_ENABLE = UR_BIT(1), ///< Enable/disable profiling - UR_QUEUE_FLAG_ON_DEVICE = UR_BIT(2), ///< Is a device queue + UR_QUEUE_FLAG_ON_DEVICE = UR_BIT(2), ///< Is a device queue. If this is enabled + ///< `::UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE` must also be enabled. UR_QUEUE_FLAG_ON_DEVICE_DEFAULT = UR_BIT(3), ///< Is the default queue for a device UR_QUEUE_FLAG_DISCARD_EVENTS = UR_BIT(4), ///< Events will be discarded UR_QUEUE_FLAG_PRIORITY_LOW = UR_BIT(5), ///< Low priority queue @@ -5198,6 +5202,7 @@ typedef enum ur_queue_flag_t { /// + `propSize != 0 && pPropValue == NULL` /// + `pPropValue == NULL && pPropSizeRet == NULL` /// - ::UR_RESULT_ERROR_INVALID_QUEUE +/// + If `hQueue` isn't a valid queue handle or if `propName` isn't supported by `hQueue`. /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES UR_APIEXPORT ur_result_t UR_APICALL diff --git a/scripts/core/queue.yml b/scripts/core/queue.yml index 816da179ba..c2e3468e63 100644 --- a/scripts/core/queue.yml +++ b/scripts/core/queue.yml @@ -23,16 +23,23 @@ etors: - name: DEVICE desc: "[$x_device_handle_t] device associated with this queue." - name: DEVICE_DEFAULT - desc: "[$x_queue_handle_t] the current default queue of the underlying device." + desc: | + [$x_queue_handle_t] the current default queue of the underlying + device. Only returns a value if a queue associated with the + underlying device has been created with `$X_QUEUE_FLAG_ON_DEVICE_DEFAULT`. - name: FLAGS desc: "[$x_queue_flags_t] the properties associated with $x_queue_properties_t::flags." - name: REFERENCE_COUNT desc: | [uint32_t] Reference count of the queue object. The reference count returned should be considered immediately stale. - It is unsuitable for general use in applications. This feature is provided for identifying memory leaks. + It is unsuitable for general use in applications. This feature is + provided for identifying memory leaks. - name: SIZE - desc: "[uint32_t] The size of the queue" + desc: | + [uint32_t] The size of the queue on the device. Only a valid query + if the queue was created with the `ON_DEVICE` queue flag, otherwise + `$xQueueGetInfo` will return `$X_RESULT_ERROR_INVALID_QUEUE`. - name: EMPTY desc: "[$x_bool_t] return true if the queue was empty at the time of the query" --- #-------------------------------------------------------------------------- @@ -49,7 +56,7 @@ etors: desc: "Enable/disable profiling" - name: ON_DEVICE value: "$X_BIT(2)" - desc: "Is a device queue" + desc: "Is a device queue. If this is enabled `$X_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE` must also be enabled." - name: ON_DEVICE_DEFAULT value: "$X_BIT(3)" desc: "Is the default queue for a device" @@ -107,7 +114,8 @@ returns: - $X_RESULT_ERROR_INVALID_NULL_POINTER: - "`propSize != 0 && pPropValue == NULL`" - "`pPropValue == NULL && pPropSizeRet == NULL`" - - $X_RESULT_ERROR_INVALID_QUEUE + - $X_RESULT_ERROR_INVALID_QUEUE: + - "If `hQueue` isn't a valid queue handle or if `propName` isn't supported by `hQueue`." - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- diff --git a/source/adapters/cuda/device.cpp b/source/adapters/cuda/device.cpp index b33ad6c792..d90bb768e7 100644 --- a/source/adapters/cuda/device.cpp +++ b/source/adapters/cuda/device.cpp @@ -554,10 +554,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, ur_queue_flag_t(UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE | UR_QUEUE_FLAG_PROFILING_ENABLE)); case UR_DEVICE_INFO_QUEUE_ON_DEVICE_PROPERTIES: { - // The mandated minimum capability: - ur_queue_flags_t Capability = UR_QUEUE_FLAG_PROFILING_ENABLE | - UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE; - return ReturnValue(Capability); + ur_queue_flags_t QueueOnDevice = 0; + return ReturnValue(QueueOnDevice); } case UR_DEVICE_INFO_QUEUE_ON_HOST_PROPERTIES: { // The mandated minimum capability: diff --git a/source/adapters/hip/device.cpp b/source/adapters/hip/device.cpp index bc67fcee71..1311641788 100644 --- a/source/adapters/hip/device.cpp +++ b/source/adapters/hip/device.cpp @@ -465,10 +465,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, return ReturnValue(Capability); } case UR_DEVICE_INFO_QUEUE_ON_DEVICE_PROPERTIES: { - // The mandated minimum capability: - ur_queue_flags_t Capability = UR_QUEUE_FLAG_PROFILING_ENABLE | - UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE; - return ReturnValue(Capability); + ur_queue_flags_t QueueOnDevice = 0; + return ReturnValue(QueueOnDevice); } case UR_DEVICE_INFO_QUEUE_ON_HOST_PROPERTIES: case UR_DEVICE_INFO_QUEUE_PROPERTIES: { diff --git a/source/adapters/native_cpu/device.cpp b/source/adapters/native_cpu/device.cpp index dfabfb81e5..c6a8d98af0 100644 --- a/source/adapters/native_cpu/device.cpp +++ b/source/adapters/native_cpu/device.cpp @@ -313,6 +313,10 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, case UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_SUPPORT_EXP: return ReturnValue(false); + case UR_DEVICE_INFO_QUEUE_ON_DEVICE_PROPERTIES: { + ur_queue_flags_t QueueOnDevice = 0; + return ReturnValue(QueueOnDevice); + } default: DIE_NO_IMPLEMENTATION; } diff --git a/source/adapters/opencl/common.cpp b/source/adapters/opencl/common.cpp index 4fe8bed408..e7fb09eeda 100644 --- a/source/adapters/opencl/common.cpp +++ b/source/adapters/opencl/common.cpp @@ -81,6 +81,8 @@ ur_result_t mapCLErrorToUR(cl_int Result) { return UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_EXP; case CL_INVALID_SYNC_POINT_WAIT_LIST_KHR: return UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_SYNC_POINT_WAIT_LIST_EXP; + case CL_INVALID_COMMAND_QUEUE: + return UR_RESULT_ERROR_INVALID_QUEUE; default: return UR_RESULT_ERROR_UNKNOWN; } diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index 1e9400aaa4..dbf233c31d 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -4014,6 +4014,7 @@ ur_result_t UR_APICALL urKernelCreateWithNativeHandle( /// + `propSize != 0 && pPropValue == NULL` /// + `pPropValue == NULL && pPropSizeRet == NULL` /// - ::UR_RESULT_ERROR_INVALID_QUEUE +/// + If `hQueue` isn't a valid queue handle or if `propName` isn't supported by `hQueue`. /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urQueueGetInfo( diff --git a/source/ur_api.cpp b/source/ur_api.cpp index 5ee68ce529..911df7b195 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -3401,6 +3401,7 @@ ur_result_t UR_APICALL urKernelCreateWithNativeHandle( /// + `propSize != 0 && pPropValue == NULL` /// + `pPropValue == NULL && pPropSizeRet == NULL` /// - ::UR_RESULT_ERROR_INVALID_QUEUE +/// + If `hQueue` isn't a valid queue handle or if `propName` isn't supported by `hQueue`. /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urQueueGetInfo( diff --git a/test/conformance/device/device_adapter_native_cpu.match b/test/conformance/device/device_adapter_native_cpu.match index 4c1a0f7f7f..18e8b327a7 100644 --- a/test/conformance/device/device_adapter_native_cpu.match +++ b/test/conformance/device/device_adapter_native_cpu.match @@ -4,7 +4,6 @@ urDeviceGetInfoTest.Success/UR_DEVICE_INFO_DEVICE_ID urDeviceGetInfoTest.Success/UR_DEVICE_INFO_MEMORY_CLOCK_RATE urDeviceGetInfoTest.Success/UR_DEVICE_INFO_MAX_READ_WRITE_IMAGE_ARGS urDeviceGetInfoTest.Success/UR_DEVICE_INFO_GLOBAL_MEM_FREE -urDeviceGetInfoTest.Success/UR_DEVICE_INFO_QUEUE_ON_DEVICE_PROPERTIES urDeviceGetInfoTest.Success/UR_DEVICE_INFO_QUEUE_ON_HOST_PROPERTIES urDeviceGetInfoTest.Success/UR_DEVICE_INFO_IL_VERSION urDeviceGetInfoTest.Success/UR_DEVICE_INFO_MAX_NUM_SUB_GROUPS diff --git a/test/conformance/queue/queue_adapter_hip.match b/test/conformance/queue/queue_adapter_hip.match index d39b30aa73..e69de29bb2 100644 --- a/test/conformance/queue/queue_adapter_hip.match +++ b/test/conformance/queue/queue_adapter_hip.match @@ -1,2 +0,0 @@ -urQueueGetInfoTestWithInfoParam.Success/AMD_HIP_BACKEND___{{.*}}___UR_QUEUE_INFO_DEVICE_DEFAULT -urQueueGetInfoTestWithInfoParam.Success/AMD_HIP_BACKEND___{{.*}}___UR_QUEUE_INFO_SIZE diff --git a/test/conformance/queue/queue_adapter_native_cpu.match b/test/conformance/queue/queue_adapter_native_cpu.match index 98c622a472..39e3049c66 100644 --- a/test/conformance/queue/queue_adapter_native_cpu.match +++ b/test/conformance/queue/queue_adapter_native_cpu.match @@ -4,10 +4,8 @@ urQueueFinishTest.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU_ urQueueFlushTest.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU_ urQueueGetInfoTestWithInfoParam.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU___UR_QUEUE_INFO_CONTEXT urQueueGetInfoTestWithInfoParam.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU___UR_QUEUE_INFO_DEVICE -urQueueGetInfoTestWithInfoParam.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU___UR_QUEUE_INFO_DEVICE_DEFAULT urQueueGetInfoTestWithInfoParam.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU___UR_QUEUE_INFO_FLAGS urQueueGetInfoTestWithInfoParam.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU___UR_QUEUE_INFO_REFERENCE_COUNT -urQueueGetInfoTestWithInfoParam.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU___UR_QUEUE_INFO_SIZE urQueueGetInfoTestWithInfoParam.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU___UR_QUEUE_INFO_EMPTY urQueueGetInfoTest.InvalidSizeSmall/SYCL_NATIVE_CPU___SYCL_Native_CPU_ urQueueRetainTest.Success/SYCL_NATIVE_CPU___SYCL_Native_CPU_ diff --git a/test/conformance/queue/queue_adapter_opencl.match b/test/conformance/queue/queue_adapter_opencl.match index a374e0b4b1..e69de29bb2 100644 --- a/test/conformance/queue/queue_adapter_opencl.match +++ b/test/conformance/queue/queue_adapter_opencl.match @@ -1,2 +0,0 @@ -urQueueGetInfoTestWithInfoParam.Success/Intel_R__OpenCL___{{.*}}___UR_QUEUE_INFO_DEVICE_DEFAULT -urQueueGetInfoTestWithInfoParam.Success/Intel_R__OpenCL___{{.*}}___UR_QUEUE_INFO_SIZE diff --git a/test/conformance/queue/urQueueGetInfo.cpp b/test/conformance/queue/urQueueGetInfo.cpp index 9269e4de30..a29a1e5f5a 100644 --- a/test/conformance/queue/urQueueGetInfo.cpp +++ b/test/conformance/queue/urQueueGetInfo.cpp @@ -2,7 +2,7 @@ // Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions. // See LICENSE.TXT // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include +#include #include std::unordered_map queue_info_size_map = { @@ -19,6 +19,64 @@ using urQueueGetInfoTestWithInfoParam = uur::urQueueTestWithParam; UUR_TEST_SUITE_P(urQueueGetInfoTestWithInfoParam, + ::testing::Values(UR_QUEUE_INFO_CONTEXT, UR_QUEUE_INFO_DEVICE, + UR_QUEUE_INFO_FLAGS, + UR_QUEUE_INFO_REFERENCE_COUNT, + UR_QUEUE_INFO_EMPTY), + uur::deviceTestWithParamPrinter); + +TEST_P(urQueueGetInfoTestWithInfoParam, Success) { + ur_queue_info_t info_type = getParam(); + size_t size = 0; + auto result = urQueueGetInfo(queue, info_type, 0, nullptr, &size); + + if (result == UR_RESULT_SUCCESS) { + ASSERT_NE(size, 0); + + if (const auto expected_size = queue_info_size_map.find(info_type); + expected_size != queue_info_size_map.end()) { + ASSERT_EQ(expected_size->second, size); + } + + std::vector data(size); + ASSERT_SUCCESS( + urQueueGetInfo(queue, info_type, size, data.data(), nullptr)); + } else { + ASSERT_EQ_RESULT(result, UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION); + } +} + +struct urQueueGetInfoDeviceQueueTestWithInfoParam + : public uur::urContextTestWithParam { + void SetUp() { + urContextTestWithParam::SetUp(); + ur_queue_flags_t deviceQueueCapabilities; + ASSERT_SUCCESS( + urDeviceGetInfo(device, UR_DEVICE_INFO_QUEUE_ON_DEVICE_PROPERTIES, + sizeof(deviceQueueCapabilities), + &deviceQueueCapabilities, nullptr)); + if (!deviceQueueCapabilities) { + GTEST_SKIP() << "Queue on device is not supported."; + } + ASSERT_SUCCESS( + urQueueCreate(context, device, &queueProperties, &queue)); + } + + void TearDown() { + if (queue) { + ASSERT_SUCCESS(urQueueRelease(queue)); + } + urContextTestWithParam::TearDown(); + } + + ur_queue_handle_t queue = nullptr; + ur_queue_properties_t queueProperties = { + UR_STRUCTURE_TYPE_QUEUE_PROPERTIES, nullptr, + UR_QUEUE_FLAG_ON_DEVICE | UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE | + UR_QUEUE_FLAG_ON_DEVICE_DEFAULT}; +}; + +UUR_TEST_SUITE_P(urQueueGetInfoDeviceQueueTestWithInfoParam, ::testing::Values(UR_QUEUE_INFO_CONTEXT, UR_QUEUE_INFO_DEVICE, UR_QUEUE_INFO_DEVICE_DEFAULT, UR_QUEUE_INFO_FLAGS, @@ -26,7 +84,7 @@ UUR_TEST_SUITE_P(urQueueGetInfoTestWithInfoParam, UR_QUEUE_INFO_SIZE, UR_QUEUE_INFO_EMPTY), uur::deviceTestWithParamPrinter); -TEST_P(urQueueGetInfoTestWithInfoParam, Success) { +TEST_P(urQueueGetInfoDeviceQueueTestWithInfoParam, Success) { ur_queue_info_t info_type = getParam(); size_t size = 0; auto result = urQueueGetInfo(queue, info_type, 0, nullptr, &size);