diff --git a/driver_version.h.in b/driver_version.h.in index d52b248232..86d4dab8fa 100644 --- a/driver_version.h.in +++ b/driver_version.h.in @@ -12,5 +12,6 @@ #cmakedefine NEO_REVISION "${NEO_REVISION}" #define NEO_VERSION_BUILD ${NEO_VERSION_BUILD} +#define NEO_VERSION_HOTFIX ${NEO_VERSION_HOTFIX} #endif /* DRIVER_VERSION_H */ diff --git a/level_zero/api/driver_experimental/public/zex_driver.cpp b/level_zero/api/driver_experimental/public/zex_driver.cpp index b6c159534c..f094ccaa26 100644 --- a/level_zero/api/driver_experimental/public/zex_driver.cpp +++ b/level_zero/api/driver_experimental/public/zex_driver.cpp @@ -5,9 +5,16 @@ * */ +#include "shared/source/helpers/string.h" + #include "level_zero/api/driver_experimental/public/zex_api.h" #include "level_zero/core/source/driver/driver.h" #include "level_zero/core/source/driver/driver_handle.h" +#include "level_zero/include/ze_intel_gpu.h" + +#include "driver_version.h" + +#include namespace L0 { @@ -36,6 +43,25 @@ zexDriverGetHostPointerBaseAddress( } // namespace L0 +ze_result_t ZE_APICALL +zeIntelGetDriverVersionString( + ze_driver_handle_t hDriver, + char *pDriverVersion, + size_t *pVersionSize) { + ze_api_version_t apiVersion; + L0::DriverHandle::fromHandle(hDriver)->getApiVersion(&apiVersion); + std::string driverVersionString = std::to_string(ZE_MAJOR_VERSION(apiVersion)) + "." + std::to_string(ZE_MINOR_VERSION(apiVersion)) + "." + std::to_string(NEO_VERSION_BUILD); + if (NEO_VERSION_HOTFIX > 0) { + driverVersionString += "+" + std::to_string(NEO_VERSION_HOTFIX); + } + if (*pVersionSize == 0) { + *pVersionSize = strlen(driverVersionString.c_str()); + return ZE_RESULT_SUCCESS; + } + driverVersionString.copy(pDriverVersion, *pVersionSize, 0); + return ZE_RESULT_SUCCESS; +} + extern "C" { ZE_APIEXPORT ze_result_t ZE_APICALL diff --git a/level_zero/core/source/driver/driver_handle_imp_helper.cpp b/level_zero/core/source/driver/driver_handle_imp_helper.cpp index 92bd257102..2daabc4f0a 100644 --- a/level_zero/core/source/driver/driver_handle_imp_helper.cpp +++ b/level_zero/core/source/driver/driver_handle_imp_helper.cpp @@ -37,5 +37,6 @@ const std::vector> DriverHandleImp::extensionsS {ZE_EVENT_POOL_COUNTER_BASED_EXP_NAME, ZE_EVENT_POOL_COUNTER_BASED_EXP_VERSION_CURRENT}, {ZE_INTEL_COMMAND_LIST_MEMORY_SYNC, ZE_INTEL_COMMAND_LIST_MEMORY_SYNC_EXP_VERSION_CURRENT}, {ZEX_INTEL_EVENT_SYNC_MODE_EXP_NAME, ZEX_INTEL_EVENT_SYNC_MODE_EXP_VERSION_CURRENT}, + {ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_NAME, ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_VERSION_CURRENT}, }; } // namespace L0 diff --git a/level_zero/core/source/driver/extension_function_address.cpp b/level_zero/core/source/driver/extension_function_address.cpp index aae0e2f1bf..37ca567ee2 100644 --- a/level_zero/core/source/driver/extension_function_address.cpp +++ b/level_zero/core/source/driver/extension_function_address.cpp @@ -9,6 +9,7 @@ #include "level_zero/api/driver_experimental/public/zex_api.h" #include "level_zero/api/extensions/public/ze_exp_ext.h" +#include "level_zero/include/ze_intel_gpu.h" #include @@ -41,6 +42,7 @@ void *ExtensionFunctionAddressHelper::getExtensionFunctionAddress(const std::str RETURN_FUNC_PTR_IF_EXIST(zeMemGetPitchFor2dImage); RETURN_FUNC_PTR_IF_EXIST(zeImageGetDeviceOffsetExp); RETURN_FUNC_PTR_IF_EXIST(zexDeviceGetConcurrentMetricGroups); + RETURN_FUNC_PTR_IF_EXIST(zeIntelGetDriverVersionString); #undef RETURN_FUNC_PTR_IF_EXIST return ExtensionFunctionAddressHelper::getAdditionalExtensionFunctionAddress(functionName); diff --git a/level_zero/core/test/unit_tests/sources/device/test_l0_device.cpp b/level_zero/core/test/unit_tests/sources/device/test_l0_device.cpp index 01b27bc0cd..8e208d5719 100644 --- a/level_zero/core/test/unit_tests/sources/device/test_l0_device.cpp +++ b/level_zero/core/test/unit_tests/sources/device/test_l0_device.cpp @@ -6105,5 +6105,9 @@ TEST(ExtensionLookupTest, givenLookupMapWhenAskingForBindlessImageExtensionFunct EXPECT_NE(nullptr, ExtensionFunctionAddressHelper::getExtensionFunctionAddress("zeImageGetDeviceOffsetExp")); } +TEST(ExtensionLookupTest, givenLookupMapWhenAskingForZeIntelGetDriverVersionStringThenReturnCorrectValue) { + EXPECT_NE(nullptr, ExtensionFunctionAddressHelper::getExtensionFunctionAddress("zeIntelGetDriverVersionString")); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp index ca53092997..34bc805ee0 100644 --- a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp +++ b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp @@ -39,6 +39,7 @@ #include "level_zero/core/test/unit_tests/mocks/mock_builtin_functions_lib_impl.h" #include "level_zero/core/test/unit_tests/mocks/mock_driver.h" #include "level_zero/core/test/unit_tests/mocks/mock_driver_handle.h" +#include "level_zero/include/ze_intel_gpu.h" #include "driver_version.h" @@ -1264,6 +1265,7 @@ TEST_F(DriverExperimentalApiTest, whenRetrievingApiFunctionThenExpectProperPoint decltype(&zexDriverReleaseImportedPointer) expectedRelease = L0::zexDriverReleaseImportedPointer; decltype(&zexDriverGetHostPointerBaseAddress) expectedGet = L0::zexDriverGetHostPointerBaseAddress; decltype(&zexKernelGetBaseAddress) expectedKernelGetBaseAddress = L0::zexKernelGetBaseAddress; + decltype(&zeIntelGetDriverVersionString) expectedIntelGetDriverVersionString = zeIntelGetDriverVersionString; void *funPtr = nullptr; @@ -1282,6 +1284,10 @@ TEST_F(DriverExperimentalApiTest, whenRetrievingApiFunctionThenExpectProperPoint result = zeDriverGetExtensionFunctionAddress(driverHandle, "zexKernelGetBaseAddress", &funPtr); EXPECT_EQ(ZE_RESULT_SUCCESS, result); EXPECT_EQ(expectedKernelGetBaseAddress, reinterpret_cast(funPtr)); + + result = zeDriverGetExtensionFunctionAddress(driverHandle, "zeIntelGetDriverVersionString", &funPtr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(expectedIntelGetDriverVersionString, reinterpret_cast(funPtr)); } TEST_F(DriverExperimentalApiTest, givenHostPointerApiExistWhenImportingPtrThenExpectProperBehavior) { @@ -1303,5 +1309,17 @@ TEST_F(DriverExperimentalApiTest, givenHostPointerApiExistWhenImportingPtrThenEx EXPECT_EQ(ZE_RESULT_SUCCESS, result); } +TEST_F(DriverExperimentalApiTest, givenGetVersionStringAPIExistsThenGetCurrentVersionString) { + size_t sizeOfDriverString = 0; + auto result = zeIntelGetDriverVersionString(driverHandle, nullptr, &sizeOfDriverString); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(sizeOfDriverString, 0u); + char *driverVersionString = reinterpret_cast(malloc(sizeOfDriverString * sizeof(char))); + result = zeIntelGetDriverVersionString(driverHandle, driverVersionString, &sizeOfDriverString); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE("", driverVersionString); + free(driverVersionString); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/doc/experimental_extensions/GET_DRIVER_VERSION_STRING.md b/level_zero/doc/experimental_extensions/GET_DRIVER_VERSION_STRING.md new file mode 100644 index 0000000000..2f1e66b3cb --- /dev/null +++ b/level_zero/doc/experimental_extensions/GET_DRIVER_VERSION_STRING.md @@ -0,0 +1,82 @@ + + +# Get Driver Versiopn String + +* [Overview](#Overview) +* [Definitions](#Definitions) + +# Overview + +To support reporting the Level Zero gpu driver version as a set string value, a new extension API `zeIntelGetDriverVersionString` to retrieve a specific version string from the driver has been created. + +## Outline + +`zeIntelGetDriverVersionString` reports the driver version in the form: `Major.Minor.Patch+Optional`. + +Example Versions: + +| Level Zero Package Version | Level Zero Driver Version String +|---|---| +| 1.3.27642.40 | 1.3.27642+40 | +| 1.3.27191 | 1.3.27191 + + +# Definitions + +```cpp +#define ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_NAME "ZE_intel_get_driver_version_string" +``` + +## Interfaces + +```cpp +/// @brief Query to read the Intel Level Zero Driver Version String +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// - The Driver Version String will be in the format: +/// - Major.Minor.Patch+Optional per semver guidelines https://semver.org/#spec-item-10 +/// @returns +/// - ::ZE_RESULT_SUCCESS +ze_result_t ZE_APICALL +zeIntelGetDriverVersionString( + ze_driver_handle_t hDriver, ///< [in] Driver handle whose version is being read. + char *pDriverVersion, ///< [in,out] pointer to driver version string. + size_t *pVersionSize); ///< [in,out] pointer to the size of the driver version string. + ///< if size is zero, then the size of the version string is returned. +``` + +## Programming example + +```cpp +//Check for extension existence +uint32_t count = 0; +bool supported = false; +zeDriverGetExtensionProperties(driverHandle, &count, nullptr); + +std::vector properties(count); +memset(properties.data(), 0, + sizeof(ze_driver_extension_properties_t) * count); +zeDriverGetExtensionProperties(driverHandle, &count, properties.data()); +for (auto &extension : properties) { + if (strcmp(extension.name, ZE_intel_get_driver_version_string) == 0) { + supported = true; + } +} +//Call the driver extension if it exists. +if (supported) { + zeDriverGetExtensionFunctionAddress(driverHandle, "zeIntelGetDriverVersionString", pfnGetDriverVersionFn); + size_t sizeOfDriverString = 0; + pfnGetDriverVersionFn(driverHandle, nullptr, &sizeOfDriverString); + char *driverVersionString = reinterpret_cast(malloc(sizeOfDriverString * sizeof(char))); + pfnGetDriverVersionFn(driverHandle, driverVersionString, &sizeOfDriverString); + free(driverVersionString); +} +``` diff --git a/level_zero/include/ze_intel_gpu.h b/level_zero/include/ze_intel_gpu.h index d1fc8dd10a..71b5a8f9c0 100644 --- a/level_zero/include/ze_intel_gpu.h +++ b/level_zero/include/ze_intel_gpu.h @@ -185,6 +185,35 @@ typedef enum _zex_intel_queue_copy_operations_offload_hint_exp_version_t { ZEX_INTEL_QUEUE_COPY_OPERATIONS_OFFLOAD_HINT_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } zex_intel_queue_copy_operations_offload_hint_exp_version_t; +#ifndef ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_NAME +/// @brief Extension name for query to read the Intel Level Zero Driver Version String +#define ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_NAME "ZE_intel_get_driver_version_string" +#endif // ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_NAME + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Query to read the Intel Level Zero Driver Version String extension version(s) +typedef enum _ze_intel_get_driver_version_string_exp_version_t { + ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_VERSION_1_0 = ZE_MAKE_VERSION(1, 0), ///< version 1.0 + ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_VERSION_CURRENT = ZE_MAKE_VERSION(1, 0), ///< latest known version + ZE_INTEL_GET_DRIVER_VERSION_STRING_EXP_VERSION_FORCE_UINT32 = 0x7fffffff +} ze_intel_get_driver_version_string_exp_version_t; + +/// @brief Query to read the Intel Level Zero Driver Version String +/// +/// @details +/// - The application may call this function from simultaneous threads. +/// - The implementation of this function should be lock-free. +/// - The Driver Version String will be in the format: +/// - Major.Minor.Patch+Optional per semver guidelines https://semver.org/#spec-item-10 +/// @returns +/// - ::ZE_RESULT_SUCCESS +ze_result_t ZE_APICALL +zeIntelGetDriverVersionString( + ze_driver_handle_t hDriver, ///< [in] Driver handle whose version is being read. + char *pDriverVersion, ///< [in,out] pointer to driver version string. + size_t *pVersionSize); ///< [in,out] pointer to the size of the driver version string. + ///< if size is zero, then the size of the version string is returned. + #if defined(__cplusplus) } // extern "C" #endif diff --git a/version.cmake b/version.cmake index 70e2a5d780..83b0e90fcc 100644 --- a/version.cmake +++ b/version.cmake @@ -74,6 +74,10 @@ if(NOT DEFINED NEO_VERSION_BUILD) set(NEO_VERSION_BUILD 0) endif() +if(NOT DEFINED NEO_VERSION_HOTFIX) + set(NEO_VERSION_HOTFIX 0) +endif() + # OpenCL pacakge version set(NEO_OCL_DRIVER_VERSION "${NEO_OCL_VERSION_MAJOR}.${NEO_OCL_VERSION_MINOR}.${NEO_VERSION_BUILD}") @@ -83,3 +87,4 @@ set(NEO_L0_VERSION_MINOR 3) # Remove leading zeros string(REGEX REPLACE "^0+([0-9]+)" "\\1" NEO_VERSION_BUILD "${NEO_VERSION_BUILD}") +string(REGEX REPLACE "^0+([0-9]+)" "\\1" NEO_VERSION_HOTFIX "${NEO_VERSION_HOTFIX}")