diff --git a/include/ur_api.h b/include/ur_api.h index ae736e4675..3b3e05348c 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -2198,6 +2198,9 @@ typedef enum ur_device_info_t { /// to the `USMPool` entry points and usage of the `pool` parameter of the /// USM alloc entry points. UR_DEVICE_INFO_USM_POOL_SUPPORT = 119, + /// [::ur_bool_t] support the ::urProgramSetSpecializationConstants entry + /// point + UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS = 120, /// [::ur_bool_t] Returns true if the device supports the use of /// command-buffers. UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP = 0x1000, @@ -5739,6 +5742,10 @@ typedef struct ur_specialization_constant_info_t { /// @brief Set an array of specialization constants on a Program. /// /// @details +/// - This entry point is optional, the application should query for support +/// with device query +/// ::UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS passed to +/// ::urDeviceGetInfo. /// - The application may call this function from simultaneous threads for /// the same device. /// - The implementation of this function should be thread-safe. @@ -5758,6 +5765,9 @@ typedef struct ur_specialization_constant_info_t { /// + `NULL == pSpecConstants` /// - ::UR_RESULT_ERROR_INVALID_SIZE /// + `count == 0` +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If ::UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS query is +/// false /// - ::UR_RESULT_ERROR_INVALID_VALUE /// + A pSpecConstant entry contains a size that does not match that of /// the specialization constant in the module. diff --git a/include/ur_print.hpp b/include/ur_print.hpp index ae03936835..2e6f7d715d 100644 --- a/include/ur_print.hpp +++ b/include/ur_print.hpp @@ -2917,6 +2917,9 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_device_info_t value) { case UR_DEVICE_INFO_USM_POOL_SUPPORT: os << "UR_DEVICE_INFO_USM_POOL_SUPPORT"; break; + case UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS: + os << "UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS"; + break; case UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP: os << "UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP"; break; @@ -4548,6 +4551,19 @@ inline ur_result_t printTagged(std::ostream &os, const void *ptr, os << ")"; } break; + case UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS: { + const ur_bool_t *tptr = (const ur_bool_t *)ptr; + if (sizeof(ur_bool_t) > size) { + os << "invalid size (is: " << size + << ", expected: >=" << sizeof(ur_bool_t) << ")"; + return UR_RESULT_ERROR_INVALID_SIZE; + } + os << (const void *)(tptr) << " ("; + + os << *tptr; + + os << ")"; + } break; case UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP: { const ur_bool_t *tptr = (const ur_bool_t *)ptr; if (sizeof(ur_bool_t) > size) { diff --git a/scripts/core/device.yml b/scripts/core/device.yml index ce671c24d6..c260303c87 100644 --- a/scripts/core/device.yml +++ b/scripts/core/device.yml @@ -443,6 +443,8 @@ etors: desc: "[$x_bool_t] return true if the device supports the `EnqueueDeviceGlobalVariableWrite` and `EnqueueDeviceGlobalVariableRead` entry points." - name: USM_POOL_SUPPORT desc: "[$x_bool_t] return true if the device supports USM pooling. Pertains to the `USMPool` entry points and usage of the `pool` parameter of the USM alloc entry points." + - name: PROGRAM_SET_SPECIALIZATION_CONSTANTS + desc: "[$x_bool_t] support the $xProgramSetSpecializationConstants entry point" --- #-------------------------------------------------------------------------- type: function desc: "Retrieves various information about device" diff --git a/scripts/core/program.yml b/scripts/core/program.yml index 0449a58d6d..037b65ccc5 100644 --- a/scripts/core/program.yml +++ b/scripts/core/program.yml @@ -528,6 +528,7 @@ desc: "Set an array of specialization constants on a Program." class: $xProgram name: SetSpecializationConstants details: + - "This entry point is optional, the application should query for support with device query $X_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS passed to $xDeviceGetInfo." - "The application may call this function from simultaneous threads for the same device." - "The implementation of this function should be thread-safe." - "`hProgram` must have been created with the $xProgramCreateWithIL entry point." @@ -546,6 +547,8 @@ params: returns: - $X_RESULT_ERROR_INVALID_SIZE: - "`count == 0`" + - $X_RESULT_ERROR_UNSUPPORTED_FEATURE: + - "If $X_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS query is false" - $X_RESULT_ERROR_INVALID_VALUE: - "A pSpecConstant entry contains a size that does not match that of the specialization constant in the module." - "A pSpecConstant entry contains a nullptr pValue." diff --git a/source/adapters/cuda/device.cpp b/source/adapters/cuda/device.cpp index 10c4e1d1af..bcdfe8f6dd 100644 --- a/source/adapters/cuda/device.cpp +++ b/source/adapters/cuda/device.cpp @@ -1065,6 +1065,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, return ReturnValue(AddressBuffer, strnlen(AddressBuffer, AddressBufferSize - 1) + 1); } + case UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS: case UR_DEVICE_INFO_KERNEL_SET_SPECIALIZATION_CONSTANTS: return ReturnValue(static_cast(false)); // TODO: Investigate if this information is available on CUDA. diff --git a/source/adapters/hip/device.cpp b/source/adapters/hip/device.cpp index 85c4dba8f6..76bfefaa33 100644 --- a/source/adapters/hip/device.cpp +++ b/source/adapters/hip/device.cpp @@ -789,6 +789,10 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, return ReturnValue(ur_bool_t{false}); } + case UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS: { + return ReturnValue(ur_bool_t{false}); + } + case UR_DEVICE_INFO_ATOMIC_MEMORY_ORDER_CAPABILITIES: { ur_memory_order_capability_flags_t Capabilities = UR_MEMORY_ORDER_CAPABILITY_FLAG_RELAXED | diff --git a/source/adapters/level_zero/device.cpp b/source/adapters/level_zero/device.cpp index 8b8a69f1b2..6b21507d8e 100644 --- a/source/adapters/level_zero/device.cpp +++ b/source/adapters/level_zero/device.cpp @@ -1156,6 +1156,8 @@ ur_result_t urDeviceGetInfo( // L0 does not support sampling 1D USM sampled image data. return ReturnValue(false); } + case UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS: + return ReturnValue(true); case UR_DEVICE_INFO_KERNEL_SET_SPECIALIZATION_CONSTANTS: return ReturnValue(false); case UR_DEVICE_INFO_GLOBAL_VARIABLE_SUPPORT: diff --git a/source/adapters/native_cpu/device.cpp b/source/adapters/native_cpu/device.cpp index b00892d040..6f3234ab0b 100644 --- a/source/adapters/native_cpu/device.cpp +++ b/source/adapters/native_cpu/device.cpp @@ -428,6 +428,11 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, case UR_DEVICE_INFO_LOW_POWER_EVENTS_EXP: return ReturnValue(false); + + case UR_DEVICE_INFO_KERNEL_SET_SPECIALIZATION_CONSTANTS: + case UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS: + return ReturnValue(false); + default: DIE_NO_IMPLEMENTATION; } diff --git a/source/adapters/opencl/device.cpp b/source/adapters/opencl/device.cpp index dc5343b51c..4ed3eeb3b0 100644 --- a/source/adapters/opencl/device.cpp +++ b/source/adapters/opencl/device.cpp @@ -7,6 +7,7 @@ //===-----------------------------------------------------------------===// #include "device.hpp" +#include "adapter.hpp" #include "common.hpp" #include "platform.hpp" @@ -1125,6 +1126,11 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, return ReturnValue(UUID); } + case UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS: { + return ReturnValue( + ur::cl::getAdapter()->clSetProgramSpecializationConstant != nullptr); + } + // We can't query to check if these are supported, they will need to be // manually updated if support is ever implemented. case UR_DEVICE_INFO_KERNEL_SET_SPECIALIZATION_CONSTANTS: diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index 83cee5fa63..5b55b71d4d 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -3543,6 +3543,10 @@ ur_result_t UR_APICALL urProgramGetBuildInfo( /// @brief Set an array of specialization constants on a Program. /// /// @details +/// - This entry point is optional, the application should query for support +/// with device query +/// ::UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS passed to +/// ::urDeviceGetInfo. /// - The application may call this function from simultaneous threads for /// the same device. /// - The implementation of this function should be thread-safe. @@ -3562,6 +3566,9 @@ ur_result_t UR_APICALL urProgramGetBuildInfo( /// + `NULL == pSpecConstants` /// - ::UR_RESULT_ERROR_INVALID_SIZE /// + `count == 0` +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If ::UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS query is +/// false /// - ::UR_RESULT_ERROR_INVALID_VALUE /// + A pSpecConstant entry contains a size that does not match that of /// the specialization constant in the module. diff --git a/source/ur_api.cpp b/source/ur_api.cpp index e77d562b62..15cb0442b1 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -3109,6 +3109,10 @@ ur_result_t UR_APICALL urProgramGetBuildInfo( /// @brief Set an array of specialization constants on a Program. /// /// @details +/// - This entry point is optional, the application should query for support +/// with device query +/// ::UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS passed to +/// ::urDeviceGetInfo. /// - The application may call this function from simultaneous threads for /// the same device. /// - The implementation of this function should be thread-safe. @@ -3128,6 +3132,9 @@ ur_result_t UR_APICALL urProgramGetBuildInfo( /// + `NULL == pSpecConstants` /// - ::UR_RESULT_ERROR_INVALID_SIZE /// + `count == 0` +/// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE +/// + If ::UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS query is +/// false /// - ::UR_RESULT_ERROR_INVALID_VALUE /// + A pSpecConstant entry contains a size that does not match that of /// the specialization constant in the module. diff --git a/test/conformance/device/urDeviceGetInfo.cpp b/test/conformance/device/urDeviceGetInfo.cpp index ef2f10dca3..1ed7db02b3 100644 --- a/test/conformance/device/urDeviceGetInfo.cpp +++ b/test/conformance/device/urDeviceGetInfo.cpp @@ -110,6 +110,7 @@ static std::unordered_map device_info_size_map = { {UR_DEVICE_INFO_BFLOAT16, sizeof(ur_bool_t)}, {UR_DEVICE_INFO_MAX_COMPUTE_QUEUE_INDICES, sizeof(uint32_t)}, {UR_DEVICE_INFO_KERNEL_SET_SPECIALIZATION_CONSTANTS, sizeof(ur_bool_t)}, + {UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS, sizeof(ur_bool_t)}, {UR_DEVICE_INFO_MEMORY_BUS_WIDTH, sizeof(uint32_t)}, {UR_DEVICE_INFO_MAX_WORK_GROUPS_3D, sizeof(size_t[3])}, {UR_DEVICE_INFO_ASYNC_BARRIER, sizeof(ur_bool_t)}, @@ -251,7 +252,8 @@ UUR_DEVICE_TEST_SUITE_P( UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP, // UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_DOUBLE, // UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_HALF, // - UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_INT // + UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_INT, // + UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS // ), uur::deviceTestWithParamPrinter); diff --git a/test/conformance/program/urProgramSetSpecializationConstants.cpp b/test/conformance/program/urProgramSetSpecializationConstants.cpp index 6631eae699..de646d8576 100644 --- a/test/conformance/program/urProgramSetSpecializationConstants.cpp +++ b/test/conformance/program/urProgramSetSpecializationConstants.cpp @@ -11,6 +11,15 @@ struct urProgramSetSpecializationConstantsTest : uur::urKernelExecutionTest { void SetUp() override { program_name = "spec_constant"; UUR_RETURN_ON_FATAL_FAILURE(urProgramTest::SetUp()); + + bool supports_kernel_spec_constant = false; + ASSERT_SUCCESS(urDeviceGetInfo( + device, UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS, + sizeof(supports_kernel_spec_constant), &supports_kernel_spec_constant, + nullptr)); + if (!supports_kernel_spec_constant) { + GTEST_SKIP() << "Device does not support setting program spec constants."; + } } uint32_t spec_value = 42; @@ -19,20 +28,50 @@ struct urProgramSetSpecializationConstantsTest : uur::urKernelExecutionTest { }; UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urProgramSetSpecializationConstantsTest); +struct urProgramSetSpecializationConstantsNegativeTest + : uur::urKernelExecutionTest { + void SetUp() override { + program_name = "spec_constant"; + UUR_RETURN_ON_FATAL_FAILURE(urProgramTest::SetUp()); + + bool supports_kernel_spec_constant = false; + ASSERT_SUCCESS(urDeviceGetInfo( + device, UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS, + sizeof(supports_kernel_spec_constant), &supports_kernel_spec_constant, + nullptr)); + if (supports_kernel_spec_constant) { + GTEST_SKIP() << "Device does supports setting program spec constants."; + } + } + + uint32_t spec_value = 42; + uint32_t default_spec_value = 1000; // Must match the one in the SYCL source + ur_specialization_constant_info_t info = {0, sizeof(spec_value), &spec_value}; +}; +UUR_INSTANTIATE_DEVICE_TEST_SUITE_P( + urProgramSetSpecializationConstantsNegativeTest); + struct urProgramSetMultipleSpecializationConstantsTest : uur::urKernelExecutionTest { // The types of spec constants in this program are {uint32_t, uint64_t, bool} void SetUp() override { program_name = "spec_constant_multiple"; UUR_RETURN_ON_FATAL_FAILURE(urProgramTest::SetUp()); + + bool supports_kernel_spec_constant = false; + ASSERT_SUCCESS(urDeviceGetInfo( + device, UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS, + sizeof(supports_kernel_spec_constant), &supports_kernel_spec_constant, + nullptr)); + if (!supports_kernel_spec_constant) { + GTEST_SKIP() << "Device does not support setting program spec constants."; + } } }; UUR_INSTANTIATE_DEVICE_TEST_SUITE_P( urProgramSetMultipleSpecializationConstantsTest); TEST_P(urProgramSetSpecializationConstantsTest, Success) { - UUR_KNOWN_FAILURE_ON(uur::CUDA{}, uur::HIP{}); - ASSERT_SUCCESS(urProgramSetSpecializationConstants(program, 1, &info)); ASSERT_SUCCESS(urProgramBuild(context, program, nullptr)); auto entry_points = @@ -46,9 +85,12 @@ TEST_P(urProgramSetSpecializationConstantsTest, Success) { ValidateBuffer(buffer, sizeof(spec_value), spec_value); } -TEST_P(urProgramSetSpecializationConstantsTest, UseDefaultValue) { - UUR_KNOWN_FAILURE_ON(uur::CUDA{}, uur::HIP{}); +TEST_P(urProgramSetSpecializationConstantsNegativeTest, Unsupported) { + ASSERT_EQ_RESULT(UR_RESULT_ERROR_UNSUPPORTED_FEATURE, + urProgramSetSpecializationConstants(program, 1, &info)); +} +TEST_P(urProgramSetSpecializationConstantsTest, UseDefaultValue) { ur_platform_backend_t backend; ASSERT_SUCCESS(urPlatformGetInfo(platform, UR_PLATFORM_INFO_BACKEND, sizeof(ur_platform_backend_t), &backend, @@ -72,8 +114,6 @@ TEST_P(urProgramSetSpecializationConstantsTest, UseDefaultValue) { } TEST_P(urProgramSetMultipleSpecializationConstantsTest, MultipleCalls) { - UUR_KNOWN_FAILURE_ON(uur::CUDA{}, uur::HIP{}); - uint32_t a = 100; uint64_t b = 200; bool c = false; @@ -104,8 +144,6 @@ TEST_P(urProgramSetMultipleSpecializationConstantsTest, MultipleCalls) { } TEST_P(urProgramSetMultipleSpecializationConstantsTest, SingleCall) { - UUR_KNOWN_FAILURE_ON(uur::CUDA{}, uur::HIP{}); - uint32_t a = 200; uint64_t b = 300; bool c = true; @@ -159,8 +197,7 @@ TEST_P(urProgramSetSpecializationConstantsTest, InvalidValueSize) { } TEST_P(urProgramSetSpecializationConstantsTest, InvalidValueId) { - UUR_KNOWN_FAILURE_ON(uur::CUDA{}, uur::HIP{}, uur::LevelZero{}, - uur::LevelZeroV2{}); + UUR_KNOWN_FAILURE_ON(uur::LevelZero{}, uur::LevelZeroV2{}); ur_specialization_constant_info_t bad_info = {999, sizeof(spec_value), &spec_value}; @@ -169,8 +206,7 @@ TEST_P(urProgramSetSpecializationConstantsTest, InvalidValueId) { } TEST_P(urProgramSetSpecializationConstantsTest, InvalidValuePtr) { - UUR_KNOWN_FAILURE_ON(uur::CUDA{}, uur::HIP{}, uur::LevelZero{}, - uur::LevelZeroV2{}); + UUR_KNOWN_FAILURE_ON(uur::LevelZero{}, uur::LevelZeroV2{}); ur_specialization_constant_info_t bad_info = {0, sizeof(spec_value), nullptr}; ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_VALUE, diff --git a/tools/urinfo/urinfo.hpp b/tools/urinfo/urinfo.hpp index e06a8b7f3e..c6409764a3 100644 --- a/tools/urinfo/urinfo.hpp +++ b/tools/urinfo/urinfo.hpp @@ -327,6 +327,9 @@ inline void printDeviceInfos(ur_device_handle_t hDevice, std::cout << prefix; printDeviceInfo(hDevice, UR_DEVICE_INFO_USM_POOL_SUPPORT); std::cout << prefix; + printDeviceInfo( + hDevice, UR_DEVICE_INFO_PROGRAM_SET_SPECIALIZATION_CONSTANTS); + std::cout << prefix; printDeviceInfo(hDevice, UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP); std::cout << prefix;