From 7ebcb8c743b2eea63c46c3e962135b4c58c6c934 Mon Sep 17 00:00:00 2001 From: Ewan Crawford Date: Fri, 13 Dec 2024 10:00:54 +0000 Subject: [PATCH 1/4] Improve command-buffer update error code wording The `UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_SUPPORT_EXP` query no longer exists, so error defined for trying to make an updatable command-buffer when a device doesn't support it needs reworded to say if no capabilities are supported. Additionally, for each individual update capability, specify that an error is thrown if update is attempted using that characteristic. UR CTS added to verify this. --- include/ur_api.h | 19 +- scripts/core/exp-command-buffer.yml | 19 +- source/adapters/opencl/command_buffer.cpp | 2 +- source/loader/ur_libapi.cpp | 19 +- source/ur_api.cpp | 19 +- .../exp_command_buffer/CMakeLists.txt | 1 + ...xp_command_buffer_adapter_native_cpu.match | 1 + .../exp_command_buffer/invalid.cpp | 45 ++++ .../update/invalid_update.cpp | 249 ++++++++++++++++++ 9 files changed, 345 insertions(+), 29 deletions(-) create mode 100644 test/conformance/exp_command_buffer/invalid.cpp diff --git a/include/ur_api.h b/include/ur_api.h index 15cfb09e82..c672ef04a7 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -8508,8 +8508,8 @@ typedef struct ur_exp_command_buffer_command_handle_t_ *ur_exp_command_buffer_co /// + `NULL == phCommandBuffer` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_DEVICE -/// - ::UR_RESULT_ERROR_INVALID_OPERATION -/// + If `pCommandBufferDesc->isUpdatable` is true and `hDevice` does not support UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_SUPPORT_EXP. +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If `pCommandBufferDesc->isUpdatable` is true and `hDevice` returns 0 for the ::UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_CAPABILITIES_EXP query. /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES UR_APIEXPORT ur_result_t UR_APICALL @@ -9315,11 +9315,16 @@ urCommandBufferReleaseCommandExp( /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == pUpdateKernelLaunch` /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE -/// + If update functionality is not supported by the device. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS is not supported by the device, but any of `pUpdateKernelLaunch->numNewMemObjArgs`, `pUpdateKernelLaunch->numNewPointerArgs`, or `pUpdateKernelLaunch->numNewValueArgs` are not zero. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is not nullptr. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkOffset` is not nullptr. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE is not supported by the device but `pUpdateKernelLaunch->hNewKernel` is not nullptr. /// - ::UR_RESULT_ERROR_INVALID_OPERATION /// + If ::ur_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to. /// + If the command-buffer `hCommand` belongs to has not been finalized. -/// - ::UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_COMMAND_HANDLE_EXP - "If `hCommand` is not a kernel execution command." +/// - ::UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_COMMAND_HANDLE_EXP +/// + If `hCommand` is not a kernel execution command. /// - ::UR_RESULT_ERROR_INVALID_MEM_OBJECT /// - ::UR_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_INDEX /// - ::UR_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE @@ -9329,7 +9334,7 @@ urCommandBufferReleaseCommandExp( /// - ::UR_RESULT_ERROR_INVALID_WORK_GROUP_SIZE /// - ::UR_RESULT_ERROR_INVALID_VALUE /// + If `pUpdateKernelLaunch->hNewKernel` was not passed to the `hKernel` or `phKernelAlternatives` parameters of ::urCommandBufferAppendKernelLaunchExp when this command was created. -/// + If `pUpdateKernelLaunch->newWorkDim` is different from the current workDim in `hCommand` and, pUpdateKernelLaunch->pNewGlobalWorkSize, or pUpdateKernelLaunch->pNewGlobalWorkOffset are nullptr. +/// + If `pUpdateKernelLaunch->newWorkDim` is different from the current workDim in `hCommand` and, `pUpdateKernelLaunch->pNewGlobalWorkSize`, or `pUpdateKernelLaunch->pNewGlobalWorkOffset` are nullptr. /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES UR_APIEXPORT ur_result_t UR_APICALL @@ -9355,7 +9360,7 @@ urCommandBufferUpdateKernelLaunchExp( /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == phSignalEvent` /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE -/// + If UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. /// - ::UR_RESULT_ERROR_INVALID_OPERATION /// + If ::ur_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to. /// + If the command-buffer `hCommand` belongs to has not been finalized. @@ -9382,7 +9387,7 @@ urCommandBufferUpdateSignalEventExp( /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hCommand` /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE -/// + If UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. /// - ::UR_RESULT_ERROR_INVALID_OPERATION /// + If ::ur_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to. /// + If the command-buffer `hCommand` belongs to has not been finalized. diff --git a/scripts/core/exp-command-buffer.yml b/scripts/core/exp-command-buffer.yml index 7ca4c957d5..c181eb0df2 100644 --- a/scripts/core/exp-command-buffer.yml +++ b/scripts/core/exp-command-buffer.yml @@ -289,8 +289,9 @@ params: returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_DEVICE - - $X_RESULT_ERROR_INVALID_OPERATION: - - "If `pCommandBufferDesc->isUpdatable` is true and `hDevice` does not support UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_SUPPORT_EXP." + - $X_RESULT_ERROR_UNSUPPORTED_FEATURE: + - "If `pCommandBufferDesc->isUpdatable` is true and `hDevice` returns 0 + for the $X_DEVICE_INFO_COMMAND_BUFFER_UPDATE_CAPABILITIES_EXP query." - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- @@ -1203,11 +1204,15 @@ params: desc: "[in] Struct defining how the kernel command is to be updated." returns: - $X_RESULT_ERROR_UNSUPPORTED_FEATURE: - - "If update functionality is not supported by the device." + - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS is not supported by the device, but any of `pUpdateKernelLaunch->numNewMemObjArgs`, `pUpdateKernelLaunch->numNewPointerArgs`, or `pUpdateKernelLaunch->numNewValueArgs` are not zero." + - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is not nullptr." + - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr" + - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkOffset` is not nullptr." + - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE is not supported by the device but `pUpdateKernelLaunch->hNewKernel` is not nullptr." - $X_RESULT_ERROR_INVALID_OPERATION: - "If $x_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to." - "If the command-buffer `hCommand` belongs to has not been finalized." - - $X_RESULT_ERROR_INVALID_COMMAND_BUFFER_COMMAND_HANDLE_EXP + - $X_RESULT_ERROR_INVALID_COMMAND_BUFFER_COMMAND_HANDLE_EXP: - "If `hCommand` is not a kernel execution command." - $X_RESULT_ERROR_INVALID_MEM_OBJECT - $X_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_INDEX @@ -1218,7 +1223,7 @@ returns: - $X_RESULT_ERROR_INVALID_WORK_GROUP_SIZE - $X_RESULT_ERROR_INVALID_VALUE: - "If `pUpdateKernelLaunch->hNewKernel` was not passed to the `hKernel` or `phKernelAlternatives` parameters of $xCommandBufferAppendKernelLaunchExp when this command was created." - - "If `pUpdateKernelLaunch->newWorkDim` is different from the current workDim in `hCommand` and, pUpdateKernelLaunch->pNewGlobalWorkSize, or pUpdateKernelLaunch->pNewGlobalWorkOffset are nullptr." + - "If `pUpdateKernelLaunch->newWorkDim` is different from the current workDim in `hCommand` and, `pUpdateKernelLaunch->pNewGlobalWorkSize`, or `pUpdateKernelLaunch->pNewGlobalWorkOffset` are nullptr." - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- @@ -1236,7 +1241,7 @@ params: desc: "[out] Event to be signaled." returns: - $X_RESULT_ERROR_UNSUPPORTED_FEATURE: - - "If UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`." + - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`." - $X_RESULT_ERROR_INVALID_OPERATION: - "If $x_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to." - "If the command-buffer `hCommand` belongs to has not been finalized." @@ -1262,7 +1267,7 @@ params: desc: "[in][optional][range(0, numEventsInWaitList)] pointer to a list of events that must be complete before the command execution. If nullptr, the numEventsInWaitList must be 0, indicating no wait events." returns: - $X_RESULT_ERROR_UNSUPPORTED_FEATURE: - - "If UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`." + - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`." - $X_RESULT_ERROR_INVALID_OPERATION: - "If $x_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to." - "If the command-buffer `hCommand` belongs to has not been finalized." diff --git a/source/adapters/opencl/command_buffer.cpp b/source/adapters/opencl/command_buffer.cpp index ac23765f0f..6d67f07ab8 100644 --- a/source/adapters/opencl/command_buffer.cpp +++ b/source/adapters/opencl/command_buffer.cpp @@ -78,7 +78,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferCreateExp( bool DeviceSupportsUpdate = UpdateCapabilities > 0; if (IsUpdatable && !DeviceSupportsUpdate) { - return UR_RESULT_ERROR_INVALID_OPERATION; + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } cl_command_buffer_properties_khr Properties[3] = { diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index b8425367cf..b5a6d92861 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -7492,8 +7492,8 @@ ur_result_t UR_APICALL urBindlessImagesSignalExternalSemaphoreExp( /// + `NULL == phCommandBuffer` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_DEVICE -/// - ::UR_RESULT_ERROR_INVALID_OPERATION -/// + If `pCommandBufferDesc->isUpdatable` is true and `hDevice` does not support UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_SUPPORT_EXP. +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If `pCommandBufferDesc->isUpdatable` is true and `hDevice` returns 0 for the ::UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_CAPABILITIES_EXP query. /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urCommandBufferCreateExp( @@ -8637,11 +8637,16 @@ ur_result_t UR_APICALL urCommandBufferReleaseCommandExp( /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == pUpdateKernelLaunch` /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE -/// + If update functionality is not supported by the device. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS is not supported by the device, but any of `pUpdateKernelLaunch->numNewMemObjArgs`, `pUpdateKernelLaunch->numNewPointerArgs`, or `pUpdateKernelLaunch->numNewValueArgs` are not zero. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is not nullptr. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkOffset` is not nullptr. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE is not supported by the device but `pUpdateKernelLaunch->hNewKernel` is not nullptr. /// - ::UR_RESULT_ERROR_INVALID_OPERATION /// + If ::ur_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to. /// + If the command-buffer `hCommand` belongs to has not been finalized. -/// - ::UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_COMMAND_HANDLE_EXP - "If `hCommand` is not a kernel execution command." +/// - ::UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_COMMAND_HANDLE_EXP +/// + If `hCommand` is not a kernel execution command. /// - ::UR_RESULT_ERROR_INVALID_MEM_OBJECT /// - ::UR_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_INDEX /// - ::UR_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE @@ -8651,7 +8656,7 @@ ur_result_t UR_APICALL urCommandBufferReleaseCommandExp( /// - ::UR_RESULT_ERROR_INVALID_WORK_GROUP_SIZE /// - ::UR_RESULT_ERROR_INVALID_VALUE /// + If `pUpdateKernelLaunch->hNewKernel` was not passed to the `hKernel` or `phKernelAlternatives` parameters of ::urCommandBufferAppendKernelLaunchExp when this command was created. -/// + If `pUpdateKernelLaunch->newWorkDim` is different from the current workDim in `hCommand` and, pUpdateKernelLaunch->pNewGlobalWorkSize, or pUpdateKernelLaunch->pNewGlobalWorkOffset are nullptr. +/// + If `pUpdateKernelLaunch->newWorkDim` is different from the current workDim in `hCommand` and, `pUpdateKernelLaunch->pNewGlobalWorkSize`, or `pUpdateKernelLaunch->pNewGlobalWorkOffset` are nullptr. /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urCommandBufferUpdateKernelLaunchExp( @@ -8689,7 +8694,7 @@ ur_result_t UR_APICALL urCommandBufferUpdateKernelLaunchExp( /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == phSignalEvent` /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE -/// + If UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. /// - ::UR_RESULT_ERROR_INVALID_OPERATION /// + If ::ur_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to. /// + If the command-buffer `hCommand` belongs to has not been finalized. @@ -8727,7 +8732,7 @@ ur_result_t UR_APICALL urCommandBufferUpdateSignalEventExp( /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hCommand` /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE -/// + If UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. /// - ::UR_RESULT_ERROR_INVALID_OPERATION /// + If ::ur_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to. /// + If the command-buffer `hCommand` belongs to has not been finalized. diff --git a/source/ur_api.cpp b/source/ur_api.cpp index 745f018aef..731094ad1e 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -6369,8 +6369,8 @@ ur_result_t UR_APICALL urBindlessImagesSignalExternalSemaphoreExp( /// + `NULL == phCommandBuffer` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_DEVICE -/// - ::UR_RESULT_ERROR_INVALID_OPERATION -/// + If `pCommandBufferDesc->isUpdatable` is true and `hDevice` does not support UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_SUPPORT_EXP. +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If `pCommandBufferDesc->isUpdatable` is true and `hDevice` returns 0 for the ::UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_CAPABILITIES_EXP query. /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urCommandBufferCreateExp( @@ -7331,11 +7331,16 @@ ur_result_t UR_APICALL urCommandBufferReleaseCommandExp( /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == pUpdateKernelLaunch` /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE -/// + If update functionality is not supported by the device. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS is not supported by the device, but any of `pUpdateKernelLaunch->numNewMemObjArgs`, `pUpdateKernelLaunch->numNewPointerArgs`, or `pUpdateKernelLaunch->numNewValueArgs` are not zero. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is not nullptr. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkOffset` is not nullptr. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE is not supported by the device but `pUpdateKernelLaunch->hNewKernel` is not nullptr. /// - ::UR_RESULT_ERROR_INVALID_OPERATION /// + If ::ur_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to. /// + If the command-buffer `hCommand` belongs to has not been finalized. -/// - ::UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_COMMAND_HANDLE_EXP - "If `hCommand` is not a kernel execution command." +/// - ::UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_COMMAND_HANDLE_EXP +/// + If `hCommand` is not a kernel execution command. /// - ::UR_RESULT_ERROR_INVALID_MEM_OBJECT /// - ::UR_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_INDEX /// - ::UR_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE @@ -7345,7 +7350,7 @@ ur_result_t UR_APICALL urCommandBufferReleaseCommandExp( /// - ::UR_RESULT_ERROR_INVALID_WORK_GROUP_SIZE /// - ::UR_RESULT_ERROR_INVALID_VALUE /// + If `pUpdateKernelLaunch->hNewKernel` was not passed to the `hKernel` or `phKernelAlternatives` parameters of ::urCommandBufferAppendKernelLaunchExp when this command was created. -/// + If `pUpdateKernelLaunch->newWorkDim` is different from the current workDim in `hCommand` and, pUpdateKernelLaunch->pNewGlobalWorkSize, or pUpdateKernelLaunch->pNewGlobalWorkOffset are nullptr. +/// + If `pUpdateKernelLaunch->newWorkDim` is different from the current workDim in `hCommand` and, `pUpdateKernelLaunch->pNewGlobalWorkSize`, or `pUpdateKernelLaunch->pNewGlobalWorkOffset` are nullptr. /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urCommandBufferUpdateKernelLaunchExp( @@ -7375,7 +7380,7 @@ ur_result_t UR_APICALL urCommandBufferUpdateKernelLaunchExp( /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == phSignalEvent` /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE -/// + If UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. /// - ::UR_RESULT_ERROR_INVALID_OPERATION /// + If ::ur_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to. /// + If the command-buffer `hCommand` belongs to has not been finalized. @@ -7405,7 +7410,7 @@ ur_result_t UR_APICALL urCommandBufferUpdateSignalEventExp( /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hCommand` /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE -/// + If UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_EVENTS is not supported by the device associated with `hCommand`. /// - ::UR_RESULT_ERROR_INVALID_OPERATION /// + If ::ur_exp_command_buffer_desc_t::isUpdatable was not set to true on creation of the command buffer `hCommand` belongs to. /// + If the command-buffer `hCommand` belongs to has not been finalized. diff --git a/test/conformance/exp_command_buffer/CMakeLists.txt b/test/conformance/exp_command_buffer/CMakeLists.txt index 8b7aaa5a63..4e26368032 100644 --- a/test/conformance/exp_command_buffer/CMakeLists.txt +++ b/test/conformance/exp_command_buffer/CMakeLists.txt @@ -10,6 +10,7 @@ add_conformance_test_with_kernels_environment(exp_command_buffer fill.cpp event_sync.cpp kernel_event_sync.cpp + invalid.cpp update/buffer_fill_kernel_update.cpp update/invalid_update.cpp update/kernel_handle_update.cpp diff --git a/test/conformance/exp_command_buffer/exp_command_buffer_adapter_native_cpu.match b/test/conformance/exp_command_buffer/exp_command_buffer_adapter_native_cpu.match index d6dc9a975c..e8d1df4fe2 100644 --- a/test/conformance/exp_command_buffer/exp_command_buffer_adapter_native_cpu.match +++ b/test/conformance/exp_command_buffer/exp_command_buffer_adapter_native_cpu.match @@ -46,3 +46,4 @@ {{OPT}}LocalMemoryUpdateTest.UpdateParametersPartialLocalSize/* {{OPT}}LocalMemoryMultiUpdateTest.UpdateParameters/* {{OPT}}LocalMemoryMultiUpdateTest.UpdateWithoutBlocking/* +{{OPT}}urInvalidUpdateCommandBufferExpExecutionTest.* diff --git a/test/conformance/exp_command_buffer/invalid.cpp b/test/conformance/exp_command_buffer/invalid.cpp new file mode 100644 index 0000000000..be77d8f9fc --- /dev/null +++ b/test/conformance/exp_command_buffer/invalid.cpp @@ -0,0 +1,45 @@ +// Copyright (C) 2024 Intel Corporation +// 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 "fixtures.h" + +struct InvalidCreationTest : uur::urContextTest { + void SetUp() override { + UUR_RETURN_ON_FATAL_FAILURE(uur::urContextTest::SetUp()); + UUR_RETURN_ON_FATAL_FAILURE( + uur::command_buffer::checkCommandBufferSupport(device)); + } +}; + +UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(InvalidCreationTest); + +// Check correct error is reported when trying to create a +// command-buffer with update enabled on a device that doesn't +// support it. +TEST_P(InvalidCreationTest, Update) { + ur_device_command_buffer_update_capability_flags_t update_capability_flags; + ASSERT_SUCCESS(urDeviceGetInfo( + device, UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_CAPABILITIES_EXP, + sizeof(update_capability_flags), &update_capability_flags, nullptr)); + + if (0 != update_capability_flags) { + GTEST_SKIP() << "Test requires a device without update support"; + } + + ur_exp_command_buffer_handle_t cmd_buf_handle = nullptr; + ur_exp_command_buffer_desc_t desc{ + UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_DESC, // stype + nullptr, // pNext + true, // isUpdatable + false, // isInOrder + false // enableProfiling + }; + + ASSERT_EQ( + UR_RESULT_ERROR_UNSUPPORTED_FEATURE, + urCommandBufferCreateExp(context, device, &desc, &cmd_buf_handle)); + + ASSERT_EQ(cmd_buf_handle, nullptr); +}; diff --git a/test/conformance/exp_command_buffer/update/invalid_update.cpp b/test/conformance/exp_command_buffer/update/invalid_update.cpp index 036e9a464c..52bd929016 100644 --- a/test/conformance/exp_command_buffer/update/invalid_update.cpp +++ b/test/conformance/exp_command_buffer/update/invalid_update.cpp @@ -224,3 +224,252 @@ TEST_P(InvalidUpdateTest, InvalidDimensions) { UR_RESULT_ERROR_INVALID_VALUE, urCommandBufferUpdateKernelLaunchExp(command_handle, &update_desc)); } + +// Tests that an error is thrown when trying to update a kernel capability +// that isn't supported. +struct InvalidUpdateCommandBufferExpExecutionTest : uur::urKernelExecutionTest { + void SetUp() override { + program_name = "fill_usm"; + UUR_RETURN_ON_FATAL_FAILURE(uur::urKernelExecutionTest::SetUp()); + + UUR_RETURN_ON_FATAL_FAILURE( + uur::command_buffer::checkCommandBufferSupport(device)); + + ASSERT_SUCCESS(urDeviceGetInfo( + device, UR_DEVICE_INFO_COMMAND_BUFFER_UPDATE_CAPABILITIES_EXP, + sizeof(update_capability_flags), &update_capability_flags, + nullptr)); + + if (0 == update_capability_flags) { + GTEST_SKIP() << "Test requires update support from device"; + } + + ur_device_usm_access_capability_flags_t shared_usm_flags; + ASSERT_SUCCESS( + uur::GetDeviceUSMSingleSharedSupport(device, shared_usm_flags)); + if (!(shared_usm_flags & UR_DEVICE_USM_ACCESS_CAPABILITY_FLAG_ACCESS)) { + GTEST_SKIP() << "Shared USM is not supported."; + } + + // Allocate USM pointer to fill + ASSERT_SUCCESS(urUSMSharedAlloc(context, device, nullptr, nullptr, + allocation_size, &shared_ptr)); + ASSERT_NE(shared_ptr, nullptr); + std::memset(shared_ptr, 0, allocation_size); + + // Index 0 is output + ASSERT_SUCCESS(urKernelSetArgPointer(kernel, 0, nullptr, shared_ptr)); + // Index 1 is input scalar + ASSERT_SUCCESS( + urKernelSetArgValue(kernel, 1, sizeof(val), nullptr, &val)); + + // Create a command-buffer with update enabled. + ur_exp_command_buffer_desc_t desc{ + UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_DESC, nullptr, true, false, + false}; + + ASSERT_SUCCESS(urCommandBufferCreateExp(context, device, &desc, + &updatable_cmd_buf_handle)); + ASSERT_NE(updatable_cmd_buf_handle, nullptr); + + // Append kernel command to command-buffer + ASSERT_SUCCESS(urCommandBufferAppendKernelLaunchExp( + updatable_cmd_buf_handle, kernel, n_dimensions, &global_offset, + &global_size, &local_size, 0, nullptr, 0, nullptr, 0, nullptr, + nullptr, nullptr, &command_handle)); + ASSERT_NE(command_handle, nullptr); + + ASSERT_SUCCESS(urCommandBufferFinalizeExp(updatable_cmd_buf_handle)); + + ASSERT_SUCCESS(urKernelCreate(program, kernel_name.data(), &kernel_2)); + } + + void TearDown() override { + if (updatable_cmd_buf_handle) { + EXPECT_SUCCESS(urCommandBufferReleaseExp(updatable_cmd_buf_handle)); + } + + if (shared_ptr) { + EXPECT_SUCCESS(urUSMFree(context, shared_ptr)); + } + + if (command_handle) { + EXPECT_SUCCESS(urCommandBufferReleaseCommandExp(command_handle)); + } + + if (kernel_2) { + ASSERT_SUCCESS(urKernelRelease(kernel_2)); + } + + UUR_RETURN_ON_FATAL_FAILURE(urKernelExecutionTest::TearDown()); + } + + ur_exp_command_buffer_handle_t updatable_cmd_buf_handle = nullptr; + ur_exp_command_buffer_command_handle_t command_handle = nullptr; + ur_kernel_handle_t kernel_2 = nullptr; + static constexpr uint32_t val = 42; + static constexpr size_t local_size = 4; + static constexpr size_t global_size = 32; + static constexpr size_t global_offset = 0; + static constexpr uint32_t n_dimensions = 1; + static constexpr size_t allocation_size = sizeof(val) * global_size; + void *shared_ptr = nullptr; + ur_device_command_buffer_update_capability_flags_t update_capability_flags = + 0; +}; + +UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(InvalidUpdateCommandBufferExpExecutionTest); + +// Test error reported if device doesn't support updating kernel args +TEST_P(InvalidUpdateCommandBufferExpExecutionTest, KernelArg) { + if (update_capability_flags & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS) { + GTEST_SKIP() << "Test requires device to not support kernel arg update " + "capability"; + } + + uint32_t new_val = 33; + ur_exp_command_buffer_update_value_arg_desc_t new_input_desc = { + UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_UPDATE_VALUE_ARG_DESC, // stype + nullptr, // pNext + 1, // argIndex + sizeof(new_val), // argSize + nullptr, // pProperties + &new_val, // hArgValue + }; + + ur_exp_command_buffer_update_kernel_launch_desc_t update_desc = { + UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_UPDATE_KERNEL_LAUNCH_DESC, // stype + nullptr, // pNext + nullptr, // hNewKernel + 0, // numNewMemObjArgs + 0, // numNewPointerArgs + 1, // numNewValueArgs + n_dimensions, // newWorkDim + nullptr, // pNewMemObjArgList + nullptr, // pNewPointerArgList + &new_input_desc, // pNewValueArgList + nullptr, // pNewGlobalWorkOffset + nullptr, // pNewGlobalWorkSize + nullptr, // pNewLocalWorkSize + }; + + ur_result_t result = + urCommandBufferUpdateKernelLaunchExp(command_handle, &update_desc); + ASSERT_EQ(UR_RESULT_ERROR_UNSUPPORTED_FEATURE, result); +} + +TEST_P(InvalidUpdateCommandBufferExpExecutionTest, GlobalSize) { + if (update_capability_flags & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE) { + GTEST_SKIP() << "Test requires device to not support global work size " + "update capability."; + } + + auto new_global_size = global_size * 2; + ur_exp_command_buffer_update_kernel_launch_desc_t update_desc = { + UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_UPDATE_KERNEL_LAUNCH_DESC, // stype + nullptr, // pNext + nullptr, // hNewKernel + 0, // numNewMemObjArgs + 0, // numNewPointerArgs + 0, // numNewValueArgs + n_dimensions, // newWorkDim + nullptr, // pNewMemObjArgList + nullptr, // pNewPointerArgList + nullptr, // pNewValueArgList + nullptr, // pNewGlobalWorkOffset + &new_global_size, // pNewGlobalWorkSize + nullptr, // pNewLocalWorkSize + }; + + ur_result_t result = + urCommandBufferUpdateKernelLaunchExp(command_handle, &update_desc); + ASSERT_EQ(UR_RESULT_ERROR_UNSUPPORTED_FEATURE, result); +} + +TEST_P(InvalidUpdateCommandBufferExpExecutionTest, GlobalOffset) { + if (update_capability_flags & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET) { + GTEST_SKIP() << "Test requires device to not support global work " + "offset update capability."; + } + + size_t new_global_offset = 1; + ur_exp_command_buffer_update_kernel_launch_desc_t update_desc = { + UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_UPDATE_KERNEL_LAUNCH_DESC, // stype + nullptr, // pNext + nullptr, // hNewKernel + 0, // numNewMemObjArgs + 0, // numNewPointerArgs + 0, // numNewValueArgs + n_dimensions, // newWorkDim + nullptr, // pNewMemObjArgList + nullptr, // pNewPointerArgList + nullptr, // pNewValueArgList + &new_global_offset, // pNewGlobalWorkOffset + nullptr, // pNewGlobalWorkSize + nullptr, // pNewLocalWorkSize + }; + + ur_result_t result = + urCommandBufferUpdateKernelLaunchExp(command_handle, &update_desc); + ASSERT_EQ(UR_RESULT_ERROR_UNSUPPORTED_FEATURE, result); +} + +TEST_P(InvalidUpdateCommandBufferExpExecutionTest, LocalSize) { + if (update_capability_flags & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE) { + GTEST_SKIP() << "Test requires device to not support local work size " + "update capability."; + } + + size_t new_local_size = 2; + ur_exp_command_buffer_update_kernel_launch_desc_t update_desc = { + UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_UPDATE_KERNEL_LAUNCH_DESC, // stype + nullptr, // pNext + nullptr, // hNewKernel + 0, // numNewMemObjArgs + 0, // numNewPointerArgs + 0, // numNewValueArgs + n_dimensions, // newWorkDim + nullptr, // pNewMemObjArgList + nullptr, // pNewPointerArgList + nullptr, // pNewValueArgList + nullptr, // pNewGlobalWorkOffset + nullptr, // pNewGlobalWorkSize + &new_local_size, // pNewLocalWorkSize + }; + + ur_result_t result = + urCommandBufferUpdateKernelLaunchExp(command_handle, &update_desc); + ASSERT_EQ(UR_RESULT_ERROR_UNSUPPORTED_FEATURE, result); +} + +TEST_P(InvalidUpdateCommandBufferExpExecutionTest, Kernel) { + if (update_capability_flags & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE) { + GTEST_SKIP() << "Test requires device to not support kernel handle " + "update capability."; + } + + ur_exp_command_buffer_update_kernel_launch_desc_t update_desc = { + UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_UPDATE_KERNEL_LAUNCH_DESC, // stype + nullptr, // pNext + kernel_2, // hNewKernel + 0, // numNewMemObjArgs + 0, // numNewPointerArgs + 0, // numNewValueArgs + n_dimensions, // newWorkDim + nullptr, // pNewMemObjArgList + nullptr, // pNewPointerArgList + nullptr, // pNewValueArgList + nullptr, // pNewGlobalWorkOffset + nullptr, // pNewGlobalWorkSize + nullptr, // pNewLocalWorkSize + }; + + ur_result_t result = + urCommandBufferUpdateKernelLaunchExp(command_handle, &update_desc); + ASSERT_EQ(UR_RESULT_ERROR_UNSUPPORTED_FEATURE, result); +} From 2b77f4a0d0a1976479c767a5fe0aa51e1be6b74f Mon Sep 17 00:00:00 2001 From: Ewan Crawford Date: Fri, 20 Dec 2024 15:55:11 +0000 Subject: [PATCH 2/4] Extra error case Return unsupported when a device doesn't support local memory update but attempts the following usage > If pNewGlobalWorkSize is set and pNewLocalWorkSize is nullptr, then the runtime implementation will choose the local work size. --- include/ur_api.h | 1 + scripts/core/exp-command-buffer.yml | 1 + source/loader/ur_libapi.cpp | 1 + source/ur_api.cpp | 1 + .../update/invalid_update.cpp | 36 +++++++++++++++++++ 5 files changed, 40 insertions(+) diff --git a/include/ur_api.h b/include/ur_api.h index c672ef04a7..c8c03633af 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -9317,6 +9317,7 @@ urCommandBufferReleaseCommandExp( /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS is not supported by the device, but any of `pUpdateKernelLaunch->numNewMemObjArgs`, `pUpdateKernelLaunch->numNewPointerArgs`, or `pUpdateKernelLaunch->numNewValueArgs` are not zero. /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is not nullptr. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is nullptr and `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr. /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkOffset` is not nullptr. /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE is not supported by the device but `pUpdateKernelLaunch->hNewKernel` is not nullptr. diff --git a/scripts/core/exp-command-buffer.yml b/scripts/core/exp-command-buffer.yml index c181eb0df2..6abcb48695 100644 --- a/scripts/core/exp-command-buffer.yml +++ b/scripts/core/exp-command-buffer.yml @@ -1206,6 +1206,7 @@ returns: - $X_RESULT_ERROR_UNSUPPORTED_FEATURE: - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS is not supported by the device, but any of `pUpdateKernelLaunch->numNewMemObjArgs`, `pUpdateKernelLaunch->numNewPointerArgs`, or `pUpdateKernelLaunch->numNewValueArgs` are not zero." - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is not nullptr." + - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is nullptr and `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr." - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr" - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkOffset` is not nullptr." - "If $X_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE is not supported by the device but `pUpdateKernelLaunch->hNewKernel` is not nullptr." diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index b5a6d92861..1eb3428b5f 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -8639,6 +8639,7 @@ ur_result_t UR_APICALL urCommandBufferReleaseCommandExp( /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS is not supported by the device, but any of `pUpdateKernelLaunch->numNewMemObjArgs`, `pUpdateKernelLaunch->numNewPointerArgs`, or `pUpdateKernelLaunch->numNewValueArgs` are not zero. /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is not nullptr. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is nullptr and `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr. /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkOffset` is not nullptr. /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE is not supported by the device but `pUpdateKernelLaunch->hNewKernel` is not nullptr. diff --git a/source/ur_api.cpp b/source/ur_api.cpp index 731094ad1e..20b5359e56 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -7333,6 +7333,7 @@ ur_result_t UR_APICALL urCommandBufferReleaseCommandExp( /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS is not supported by the device, but any of `pUpdateKernelLaunch->numNewMemObjArgs`, `pUpdateKernelLaunch->numNewPointerArgs`, or `pUpdateKernelLaunch->numNewValueArgs` are not zero. /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is not nullptr. +/// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewLocalWorkSize` is nullptr and `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr. /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkSize` is not nullptr /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET is not supported by the device but `pUpdateKernelLaunch->pNewGlobalWorkOffset` is not nullptr. /// + If ::UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE is not supported by the device but `pUpdateKernelLaunch->hNewKernel` is not nullptr. diff --git a/test/conformance/exp_command_buffer/update/invalid_update.cpp b/test/conformance/exp_command_buffer/update/invalid_update.cpp index 52bd929016..dd8c7e8674 100644 --- a/test/conformance/exp_command_buffer/update/invalid_update.cpp +++ b/test/conformance/exp_command_buffer/update/invalid_update.cpp @@ -446,6 +446,42 @@ TEST_P(InvalidUpdateCommandBufferExpExecutionTest, LocalSize) { ASSERT_EQ(UR_RESULT_ERROR_UNSUPPORTED_FEATURE, result); } +TEST_P(InvalidUpdateCommandBufferExpExecutionTest, ImplChosenLocalSize) { + bool local_update_support = + update_capability_flags & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE; + bool global_update_support = + update_capability_flags & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE; + + if (local_update_support || !global_update_support) { + GTEST_SKIP() + << "Test requires device to not support local work size " + "update capability, but support global work size update."; + } + + auto new_global_size = global_size * 2; + ur_exp_command_buffer_update_kernel_launch_desc_t update_desc = { + UR_STRUCTURE_TYPE_EXP_COMMAND_BUFFER_UPDATE_KERNEL_LAUNCH_DESC, // stype + nullptr, // pNext + nullptr, // hNewKernel + 0, // numNewMemObjArgs + 0, // numNewPointerArgs + 0, // numNewValueArgs + n_dimensions, // newWorkDim + nullptr, // pNewMemObjArgList + nullptr, // pNewPointerArgList + nullptr, // pNewValueArgList + nullptr, // pNewGlobalWorkOffset + &new_global_size, // pNewGlobalWorkSize + nullptr, // pNewLocalWorkSize + }; + + ur_result_t result = + urCommandBufferUpdateKernelLaunchExp(command_handle, &update_desc); + ASSERT_EQ(UR_RESULT_ERROR_UNSUPPORTED_FEATURE, result); +} + TEST_P(InvalidUpdateCommandBufferExpExecutionTest, Kernel) { if (update_capability_flags & UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_HANDLE) { From b341dd01a4ecfc49a593ae002bc30d10e709629e Mon Sep 17 00:00:00 2001 From: Ewan Crawford Date: Tue, 7 Jan 2025 09:30:46 +0000 Subject: [PATCH 3/4] OpenCL adapter granular update error checks --- source/adapters/opencl/command_buffer.cpp | 72 +++++++++++++++---- source/adapters/opencl/command_buffer.hpp | 5 +- ...xp_command_buffer_adapter_native_cpu.match | 2 +- 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/source/adapters/opencl/command_buffer.cpp b/source/adapters/opencl/command_buffer.cpp index 6d67f07ab8..2bbb0694f4 100644 --- a/source/adapters/opencl/command_buffer.cpp +++ b/source/adapters/opencl/command_buffer.cpp @@ -92,7 +92,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferCreateExp( try { auto URCommandBuffer = std::make_unique( - Queue, hContext, CLCommandBuffer, IsUpdatable); + Queue, hContext, hDevice, CLCommandBuffer, IsUpdatable); *phCommandBuffer = URCommandBuffer.release(); } catch (...) { return UR_RESULT_ERROR_OUT_OF_RESOURCES; @@ -540,6 +540,64 @@ void updateKernelArgs(std::vector &CLArgs, } } +ur_result_t validateCommandDesc( + ur_exp_command_buffer_command_handle_t Command, + const ur_exp_command_buffer_update_kernel_launch_desc_t *UpdateDesc) { + // Kernel handle updates are not yet supported. + if (UpdateDesc->hNewKernel && UpdateDesc->hNewKernel != Command->Kernel) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + + // Error if work-dim has change but a new global size/offset hasn't been set + if (UpdateDesc->newWorkDim != Command->WorkDim && + (!UpdateDesc->pNewGlobalWorkOffset || !UpdateDesc->pNewGlobalWorkSize)) { + return UR_RESULT_ERROR_INVALID_OPERATION; + } + + // Verify that the device supports updating the aspects of the kernel that + // the user is requesting. + ur_device_handle_t URDevice = Command->hCommandBuffer->hDevice; + cl_device_id CLDevice = cl_adapter::cast(URDevice); + + ur_device_command_buffer_update_capability_flags_t UpdateCapabilities = 0; + CL_RETURN_ON_FAILURE( + getDeviceCommandBufferUpdateCapabilities(CLDevice, UpdateCapabilities)); + + size_t *NewGlobalWorkOffset = UpdateDesc->pNewGlobalWorkOffset; + UR_ASSERT( + !NewGlobalWorkOffset || + (UpdateCapabilities & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_OFFSET), + UR_RESULT_ERROR_UNSUPPORTED_FEATURE); + + size_t *NewLocalWorkSize = UpdateDesc->pNewLocalWorkSize; + UR_ASSERT( + !NewLocalWorkSize || + (UpdateCapabilities & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE), + UR_RESULT_ERROR_UNSUPPORTED_FEATURE); + + size_t *NewGlobalWorkSize = UpdateDesc->pNewGlobalWorkSize; + UR_ASSERT( + !NewGlobalWorkSize || + (UpdateCapabilities & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_GLOBAL_WORK_SIZE), + UR_RESULT_ERROR_UNSUPPORTED_FEATURE); + UR_ASSERT( + !(NewGlobalWorkSize && !NewLocalWorkSize) || + (UpdateCapabilities & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_LOCAL_WORK_SIZE), + UR_RESULT_ERROR_UNSUPPORTED_FEATURE); + + UR_ASSERT( + (!UpdateDesc->numNewMemObjArgs && !UpdateDesc->numNewPointerArgs && + !UpdateDesc->numNewValueArgs) || + (UpdateCapabilities & + UR_DEVICE_COMMAND_BUFFER_UPDATE_CAPABILITY_FLAG_KERNEL_ARGUMENTS), + UR_RESULT_ERROR_UNSUPPORTED_FEATURE); + + return UR_RESULT_SUCCESS; +} } // end anonymous namespace UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferUpdateKernelLaunchExp( @@ -547,11 +605,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferUpdateKernelLaunchExp( const ur_exp_command_buffer_update_kernel_launch_desc_t *pUpdateKernelLaunch) { - // Kernel handle updates are not yet supported. - if (pUpdateKernelLaunch->hNewKernel && - pUpdateKernelLaunch->hNewKernel != hCommand->Kernel) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; - } + UR_RETURN_ON_FAILURE(validateCommandDesc(hCommand, pUpdateKernelLaunch)); ur_exp_command_buffer_handle_t hCommandBuffer = hCommand->hCommandBuffer; cl_context CLContext = cl_adapter::cast(hCommandBuffer->hContext); @@ -565,12 +619,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferUpdateKernelLaunchExp( if (!hCommandBuffer->IsFinalized || !hCommandBuffer->IsUpdatable) return UR_RESULT_ERROR_INVALID_OPERATION; - if (pUpdateKernelLaunch->newWorkDim != hCommand->WorkDim && - (!pUpdateKernelLaunch->pNewGlobalWorkOffset || - !pUpdateKernelLaunch->pNewGlobalWorkSize)) { - return UR_RESULT_ERROR_INVALID_OPERATION; - } - // Find the CL USM pointer arguments to the kernel to update std::vector CLUSMArgs; updateKernelPointerArgs(CLUSMArgs, pUpdateKernelLaunch); diff --git a/source/adapters/opencl/command_buffer.hpp b/source/adapters/opencl/command_buffer.hpp index d8e975a3df..6873edec51 100644 --- a/source/adapters/opencl/command_buffer.hpp +++ b/source/adapters/opencl/command_buffer.hpp @@ -64,6 +64,8 @@ struct ur_exp_command_buffer_handle_t_ { ur_queue_handle_t hInternalQueue; /// Context the command-buffer is created for. ur_context_handle_t hContext; + /// Device the command-buffer is created for. + ur_device_handle_t hDevice; /// OpenCL command-buffer object. cl_command_buffer_khr CLCommandBuffer; /// Set to true if the kernel commands in the command-buffer can be updated, @@ -83,9 +85,10 @@ struct ur_exp_command_buffer_handle_t_ { ur_exp_command_buffer_handle_t_(ur_queue_handle_t hQueue, ur_context_handle_t hContext, + ur_device_handle_t hDevice, cl_command_buffer_khr CLCommandBuffer, bool IsUpdatable) - : hInternalQueue(hQueue), hContext(hContext), + : hInternalQueue(hQueue), hContext(hContext), hDevice(hDevice), CLCommandBuffer(CLCommandBuffer), IsUpdatable(IsUpdatable), IsFinalized(false), RefCountInternal(0), RefCountExternal(0) {} diff --git a/test/conformance/exp_command_buffer/exp_command_buffer_adapter_native_cpu.match b/test/conformance/exp_command_buffer/exp_command_buffer_adapter_native_cpu.match index e8d1df4fe2..5d4ca6fb80 100644 --- a/test/conformance/exp_command_buffer/exp_command_buffer_adapter_native_cpu.match +++ b/test/conformance/exp_command_buffer/exp_command_buffer_adapter_native_cpu.match @@ -46,4 +46,4 @@ {{OPT}}LocalMemoryUpdateTest.UpdateParametersPartialLocalSize/* {{OPT}}LocalMemoryMultiUpdateTest.UpdateParameters/* {{OPT}}LocalMemoryMultiUpdateTest.UpdateWithoutBlocking/* -{{OPT}}urInvalidUpdateCommandBufferExpExecutionTest.* +{{OPT}}InvalidUpdateCommandBufferExpExecutionTest.* From ead3d07d4228a34fc71c884bbea6cef4669cef0c Mon Sep 17 00:00:00 2001 From: Ewan Crawford Date: Tue, 7 Jan 2025 11:35:57 +0000 Subject: [PATCH 4/4] Update source/adapters/opencl/command_buffer.cpp Co-authored-by: Ben Tracy --- source/adapters/opencl/command_buffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/adapters/opencl/command_buffer.cpp b/source/adapters/opencl/command_buffer.cpp index 2bbb0694f4..5087e65f0b 100644 --- a/source/adapters/opencl/command_buffer.cpp +++ b/source/adapters/opencl/command_buffer.cpp @@ -548,7 +548,7 @@ ur_result_t validateCommandDesc( return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } - // Error if work-dim has change but a new global size/offset hasn't been set + // Error if work-dim has changed but a new global size/offset hasn't been set if (UpdateDesc->newWorkDim != Command->WorkDim && (!UpdateDesc->pNewGlobalWorkOffset || !UpdateDesc->pNewGlobalWorkSize)) { return UR_RESULT_ERROR_INVALID_OPERATION;