From 0590b34cfa92c79947c39d4099f8d6cdf23ef10a Mon Sep 17 00:00:00 2001 From: Winston Zhang Date: Tue, 20 Aug 2024 00:14:56 +0000 Subject: [PATCH] feature: refactor and rewrite setErrorDescription Related-To: NEO-8379 Signed-off-by: Winston Zhang --- level_zero/core/source/cmdlist/cmdlist_hw.inl | 32 +++++----- .../cmdlist/cmdlist_hw_skl_to_tgllp.inl | 3 +- .../cmdlist/cmdlist_hw_xehp_and_later.inl | 3 +- level_zero/core/source/driver/driver_handle.h | 6 +- .../core/source/driver/driver_handle_imp.cpp | 43 ++----------- .../core/source/driver/driver_handle_imp.h | 2 +- level_zero/core/source/kernel/kernel_imp.cpp | 4 +- level_zero/core/source/module/module_imp.cpp | 27 +++++--- .../unit_tests/sources/driver/test_driver.cpp | 25 ++++---- .../execution_environment.cpp | 36 +++++++++++ .../execution_environment.h | 7 +++ shared/source/utilities/logger.h | 5 ++ .../execution_environment_tests.cpp | 61 ++++++++++++++++++- 13 files changed, 172 insertions(+), 82 deletions(-) diff --git a/level_zero/core/source/cmdlist/cmdlist_hw.inl b/level_zero/core/source/cmdlist/cmdlist_hw.inl index b00d0a062b..538799617d 100644 --- a/level_zero/core/source/cmdlist/cmdlist_hw.inl +++ b/level_zero/core/source/cmdlist/cmdlist_hw.inl @@ -803,8 +803,8 @@ ze_result_t CommandListCoreFamily::appendImageCopyFromMemoryExt(z } if (pDstRegion->width % groupSizeX || pDstRegion->height % groupSizeY || pDstRegion->depth % groupSizeZ) { - driverHandle->setErrorDescription("Invalid group size {%d, %d, %d} specified\n", - groupSizeX, groupSizeY, groupSizeZ); + CREATE_DEBUG_STRING(str, "Invalid group size {%d, %d, %d} specified\n", groupSizeX, groupSizeY, groupSizeZ); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Invalid group size {%d, %d, %d} specified\n", groupSizeX, groupSizeY, groupSizeZ); DEBUG_BREAK_IF(true); @@ -917,11 +917,13 @@ ze_result_t CommandListCoreFamily::appendImageCopyToMemoryExt(voi Kernel *builtinKernel = nullptr; switch (bytesPerPixel) { - default: - driverHandle->setErrorDescription("invalid bytesPerPixel of size: %u\n", bytesPerPixel); + default: { + CREATE_DEBUG_STRING(str, "Invalid bytesPerPixel of size: %u\n", bytesPerPixel); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "invalid bytesPerPixel of size: %u\n", bytesPerPixel); UNRECOVERABLE_IF(true); break; + } case 1u: builtinKernel = device->getBuiltinFunctionsLib()->getImageFunction(ImageBuiltin::copyImage3dToBufferBytes); break; @@ -976,8 +978,8 @@ ze_result_t CommandListCoreFamily::appendImageCopyToMemoryExt(voi } if (pSrcRegion->width % groupSizeX || pSrcRegion->height % groupSizeY || pSrcRegion->depth % groupSizeZ) { - driverHandle->setErrorDescription("Invalid group size {%d, %d, %d} specified\n", - groupSizeX, groupSizeY, groupSizeZ); + CREATE_DEBUG_STRING(str, "Invalid group size {%d, %d, %d} specified\n", groupSizeX, groupSizeY, groupSizeZ); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Invalid group size {%d, %d, %d} specified\n", groupSizeX, groupSizeY, groupSizeZ); DEBUG_BREAK_IF(true); @@ -1118,8 +1120,8 @@ ze_result_t CommandListCoreFamily::appendImageCopyRegion(ze_image } if (srcRegion.width % groupSizeX || srcRegion.height % groupSizeY || srcRegion.depth % groupSizeZ) { - driverHandle->setErrorDescription("Invalid group size {%d, %d, %d} specified\n", - groupSizeX, groupSizeY, groupSizeZ); + CREATE_DEBUG_STRING(str, "Invalid group size {%d, %d, %d} specified\n", groupSizeX, groupSizeY, groupSizeZ); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Invalid group size {%d, %d, %d} specified\n", groupSizeX, groupSizeY, groupSizeZ); DEBUG_BREAK_IF(true); @@ -1786,8 +1788,8 @@ ze_result_t CommandListCoreFamily::appendMemoryCopyKernel3d(Align } if (srcRegion->width % groupSizeX || srcRegion->height % groupSizeY || srcRegion->depth % groupSizeZ) { - driverHandle->setErrorDescription("Invalid group size {%d, %d, %d} specified\n", - groupSizeX, groupSizeY, groupSizeZ); + CREATE_DEBUG_STRING(str, "Invalid group size {%d, %d, %d} specified\n", groupSizeX, groupSizeY, groupSizeZ); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Invalid group size {%d, %d, %d} specified\n", groupSizeX, groupSizeY, groupSizeZ); DEBUG_BREAK_IF(true); @@ -1856,8 +1858,8 @@ ze_result_t CommandListCoreFamily::appendMemoryCopyKernel2d(Align } if (srcRegion->width % groupSizeX || srcRegion->height % groupSizeY) { - driverHandle->setErrorDescription("Invalid group size {%d, %d}\n", - groupSizeX, groupSizeY); + CREATE_DEBUG_STRING(str, "Invalid group size {%d, %d} specified\n", groupSizeX, groupSizeY); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Invalid group size {%d, %d}\n", groupSizeX, groupSizeY); DEBUG_BREAK_IF(true); @@ -2289,11 +2291,13 @@ inline uint64_t CommandListCoreFamily::getInputBufferSize(NEO::Im const ze_image_region_t *region) { const auto driverHandle = static_cast(device->getDriverHandle()); switch (imageType) { - default: - driverHandle->setErrorDescription("invalid imageType: %d\n", imageType); + default: { + CREATE_DEBUG_STRING(str, "invalid imageType: %d\n", static_cast(imageType)); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "invalid imageType: %d\n", imageType); UNRECOVERABLE_IF(true); break; + } case NEO::ImageType::image1D: return bufferRowPitch; case NEO::ImageType::image1DArray: diff --git a/level_zero/core/source/cmdlist/cmdlist_hw_skl_to_tgllp.inl b/level_zero/core/source/cmdlist/cmdlist_hw_skl_to_tgllp.inl index fba2d7856a..98502ff476 100644 --- a/level_zero/core/source/cmdlist/cmdlist_hw_skl_to_tgllp.inl +++ b/level_zero/core/source/cmdlist/cmdlist_hw_skl_to_tgllp.inl @@ -175,7 +175,8 @@ ze_result_t CommandListCoreFamily::appendLaunchKernelWithParams(K auto localMemSize = static_cast(neoDevice->getDeviceInfo().localMemSize); auto slmTotalSize = kernelImp->getSlmTotalSize(); if (slmTotalSize > 0 && localMemSize < slmTotalSize) { - driverHandle->setErrorDescription("Size of SLM (%u) larger than available (%u)\n", slmTotalSize, localMemSize); + CREATE_DEBUG_STRING(str, "Size of SLM (%u) larger than available (%u)\n", slmTotalSize, localMemSize); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Size of SLM (%u) larger than available (%u)\n", slmTotalSize, localMemSize); return ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY; } diff --git a/level_zero/core/source/cmdlist/cmdlist_hw_xehp_and_later.inl b/level_zero/core/source/cmdlist/cmdlist_hw_xehp_and_later.inl index 959f0b959f..bf729df474 100644 --- a/level_zero/core/source/cmdlist/cmdlist_hw_xehp_and_later.inl +++ b/level_zero/core/source/cmdlist/cmdlist_hw_xehp_and_later.inl @@ -305,7 +305,8 @@ ze_result_t CommandListCoreFamily::appendLaunchKernelWithParams(K auto localMemSize = static_cast(neoDevice->getDeviceInfo().localMemSize); auto slmTotalSize = kernelImp->getSlmTotalSize(); if (slmTotalSize > 0 && localMemSize < slmTotalSize) { - deviceHandle->setErrorDescription("Size of SLM (%u) larger than available (%u)\n", slmTotalSize, localMemSize); + CREATE_DEBUG_STRING(str, "Size of SLM (%u) larger than available (%u)\n", slmTotalSize, localMemSize); + deviceHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Size of SLM (%u) larger than available (%u)\n", slmTotalSize, localMemSize); return ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY; } diff --git a/level_zero/core/source/driver/driver_handle.h b/level_zero/core/source/driver/driver_handle.h index 47c23acde8..8bd22602e6 100644 --- a/level_zero/core/source/driver/driver_handle.h +++ b/level_zero/core/source/driver/driver_handle.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -11,7 +11,9 @@ #include #include +#include #include + struct _ze_driver_handle_t { virtual ~_ze_driver_handle_t() = default; }; @@ -78,7 +80,7 @@ struct DriverHandle : BaseDriver { virtual ze_result_t createRTASParallelOperation(ze_rtas_parallel_operation_exp_handle_t *phParallelOperation) = 0; virtual ze_result_t formatRTASCompatibilityCheck(ze_rtas_format_exp_t rtasFormatA, ze_rtas_format_exp_t rtasFormatB) = 0; - virtual int setErrorDescription(const char *fmt, ...) = 0; + virtual int setErrorDescription(const std::string &str) = 0; virtual ze_result_t getErrorDescription(const char **ppString) = 0; virtual ze_result_t clearErrorDescription() = 0; diff --git a/level_zero/core/source/driver/driver_handle_imp.cpp b/level_zero/core/source/driver/driver_handle_imp.cpp index 99759816be..cb59125080 100644 --- a/level_zero/core/source/driver/driver_handle_imp.cpp +++ b/level_zero/core/source/driver/driver_handle_imp.cpp @@ -23,6 +23,7 @@ #include "shared/source/memory_manager/unified_memory_manager.h" #include "shared/source/os_interface/os_interface.h" #include "shared/source/os_interface/os_library.h" +#include "shared/source/utilities/logger.h" #include "level_zero/api/driver_experimental/public/zex_common.h" #include "level_zero/core/source/builtin/builtin_functions_lib.h" @@ -1059,51 +1060,17 @@ uint32_t DriverHandleImp::getEventMaxKernelCount(uint32_t numDevices, ze_device_ return maxCount; } -int DriverHandleImp::setErrorDescription(const char *fmt, ...) { - int result = 0; - int size = -1; - va_list args; - - auto threadId = std::this_thread::get_id(); - { - std::lock_guard errorDescsLock(errorDescsMutex); - if (errorDescs.find(threadId) == errorDescs.end()) { - errorDescs[threadId] = std::string(); - } - } - errorDescs[threadId].clear(); - va_start(args, fmt); - size = vsnprintf(nullptr, 0, fmt, args); // NOLINT(clang-analyzer-valist.Uninitialized) - va_end(args); - if (size > 0) { - va_start(args, fmt); - errorDescs[threadId].resize(size + 1); // to temporarilly copy \0 - result = vsnprintf(errorDescs[threadId].data(), size + 1, fmt, args); - errorDescs[threadId].resize(size); // to remove \0 - va_end(args); - } - - return result; +int DriverHandleImp::setErrorDescription(const std::string &str) { + return this->devices[0]->getNEODevice()->getExecutionEnvironment()->setErrorDescription(str); } ze_result_t DriverHandleImp::getErrorDescription(const char **ppString) { - auto threadId = std::this_thread::get_id(); - { - std::lock_guard errorDescsLock(errorDescsMutex); - if (errorDescs.find(threadId) == errorDescs.end()) { - errorDescs[threadId] = std::string(); - } - } - *ppString = errorDescs[threadId].c_str(); + this->devices[0]->getNEODevice()->getExecutionEnvironment()->getErrorDescription(ppString); return ZE_RESULT_SUCCESS; } ze_result_t DriverHandleImp::clearErrorDescription() { - auto threadId = std::this_thread::get_id(); - if (errorDescs.find(threadId) != errorDescs.end()) { - errorDescs[threadId].clear(); - } - return ZE_RESULT_SUCCESS; + return static_cast(this->devices[0]->getNEODevice()->getExecutionEnvironment()->clearErrorDescription()); } } // namespace L0 diff --git a/level_zero/core/source/driver/driver_handle_imp.h b/level_zero/core/source/driver/driver_handle_imp.h index ea8bc16bc5..d7a602b5bb 100644 --- a/level_zero/core/source/driver/driver_handle_imp.h +++ b/level_zero/core/source/driver/driver_handle_imp.h @@ -173,7 +173,7 @@ struct DriverHandleImp : public DriverHandle { // not based on the lifetime of the object of a class. std::unordered_map errorDescs; std::mutex errorDescsMutex; - int setErrorDescription(const char *fmt, ...) override; + int setErrorDescription(const std::string &str) override; ze_result_t getErrorDescription(const char **ppString) override; ze_result_t clearErrorDescription() override; }; diff --git a/level_zero/core/source/kernel/kernel_imp.cpp b/level_zero/core/source/kernel/kernel_imp.cpp index f8e1417618..6f01915c71 100644 --- a/level_zero/core/source/kernel/kernel_imp.cpp +++ b/level_zero/core/source/kernel/kernel_imp.cpp @@ -449,7 +449,9 @@ ze_result_t KernelImp::suggestGroupSize(uint32_t globalSizeX, uint32_t globalSiz if (this->getSlmTotalSize() > 0 && localMemSize < this->getSlmTotalSize()) { const auto device = static_cast(module->getDevice()); const auto driverHandle = static_cast(device->getDriverHandle()); - driverHandle->setErrorDescription("Size of SLM (%u) larger than available (%u)\n", this->getSlmTotalSize(), localMemSize); + + CREATE_DEBUG_STRING(str, "Size of SLM (%u) larger than available (%u)\n", this->getSlmTotalSize(), localMemSize); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Size of SLM (%u) larger than available (%u)\n", this->getSlmTotalSize(), localMemSize); return ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY; } diff --git a/level_zero/core/source/module/module_imp.cpp b/level_zero/core/source/module/module_imp.cpp index 20b56f0690..ca4c7d5cda 100644 --- a/level_zero/core/source/module/module_imp.cpp +++ b/level_zero/core/source/module/module_imp.cpp @@ -276,8 +276,9 @@ ze_result_t ModuleTranslationUnit::buildFromSpirV(const char *input, uint32_t in if (isZebinAllowed == false) { const auto &rootDevice = neoDevice->getRootDevice(); if (!rootDevice->getCompilerInterface()->addOptionDisableZebin(this->options, internalOptions)) { - driverHandle->setErrorDescription("Cannot build zebinary for this device with debugger enabled. Add \"-ze-intel-disable-zebin\" build flag\n"); - updateBuildLog("Cannot build zebinary for this device with debugger enabled. Add \"-ze-intel-disable-zebin\" build flag"); + CREATE_DEBUG_STRING(str, "%s", "Cannot build zebinary for this device with debugger enabled. Remove \"-ze-intel-enable-zebin\" build flag\n"); + driverHandle->setErrorDescription(std::string(str.get())); + updateBuildLog(std::string(str.get())); return ZE_RESULT_ERROR_MODULE_BUILD_FAILURE; } } @@ -305,7 +306,8 @@ ze_result_t ModuleTranslationUnit::createFromNativeBinary(const char *input, siz PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodeWarnings.c_str()); } if (singleDeviceBinary.intermediateRepresentation.empty() && singleDeviceBinary.deviceBinary.empty()) { - driverHandle->setErrorDescription("%s\n", decodeErrors.c_str()); + CREATE_DEBUG_STRING(str, "%s\n", decodeErrors.c_str()); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodeErrors.c_str()); return ZE_RESULT_ERROR_MODULE_BUILD_FAILURE; } else { @@ -378,7 +380,8 @@ ze_result_t ModuleTranslationUnit::processUnpackedBinary() { } if (NEO::DecodeError::success != decodeError) { - driverHandle->setErrorDescription("%s\n", decodeErrors.c_str()); + CREATE_DEBUG_STRING(str, "%s\n", decodeErrors.c_str()); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "%s\n", decodeErrors.c_str()); return ZE_RESULT_ERROR_MODULE_BUILD_FAILURE; } @@ -400,8 +403,8 @@ ze_result_t ModuleTranslationUnit::processUnpackedBinary() { } if (slmNeeded > slmAvailable) { - driverHandle->setErrorDescription("Size of SLM (%u) larger than available (%u)\n", - static_cast(slmNeeded), static_cast(slmAvailable)); + CREATE_DEBUG_STRING(str, "Size of SLM (%u) larger than available (%u)\n", static_cast(slmNeeded), static_cast(slmAvailable)); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Size of SLM (%u) larger than available (%u)\n", static_cast(slmNeeded), static_cast(slmAvailable)); return ZE_RESULT_ERROR_MODULE_BUILD_FAILURE; @@ -977,7 +980,8 @@ ze_result_t ModuleImp::createKernel(const ze_kernel_desc_t *desc, for (const auto &kernelImmutableData : this->getKernelImmutableDataVector()) { auto slmInlineSize = kernelImmutableData->getDescriptor().kernelAttributes.slmInlineSize; if (slmInlineSize > 0 && localMemSize < slmInlineSize) { - driverHandle->setErrorDescription("Size of SLM (%u) larger than available (%u)\n", slmInlineSize, localMemSize); + CREATE_DEBUG_STRING(str, "Size of SLM (%u) larger than available (%u)\n", slmInlineSize, localMemSize); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Size of SLM (%u) larger than available (%u)\n", slmInlineSize, localMemSize); res = ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY; break; @@ -1196,7 +1200,8 @@ ze_result_t ModuleImp::getFunctionPointer(const char *pFunctionName, void **pfnF if (*pfnFunction == nullptr) { if (!this->isFunctionSymbolExportEnabled) { - driverHandle->setErrorDescription("Function Pointers Not Supported Without Compiler flag %s\n", BuildOptions::enableLibraryCompile.str().c_str()); + CREATE_DEBUG_STRING(str, "Function Pointers Not Supported Without Compiler flag %s\n", BuildOptions::enableLibraryCompile.str().c_str()); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Function Pointers Not Supported Without Compiler flag %s\n", BuildOptions::enableLibraryCompile.str().c_str()); return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -1223,7 +1228,8 @@ ze_result_t ModuleImp::getGlobalPointer(const char *pGlobalName, size_t *pSize, } } else { if (!this->isGlobalSymbolExportEnabled) { - driverHandle->setErrorDescription("Global Pointers Not Supported Without Compiler flag %s\n", BuildOptions::enableGlobalVariableSymbols.str().c_str()); + CREATE_DEBUG_STRING(str, "Global Pointers Not Supported Without Compiler flag %s\n", BuildOptions::enableGlobalVariableSymbols.str().c_str()); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Global Pointers Not Supported Without Compiler flag %s\n", BuildOptions::enableGlobalVariableSymbols.str().c_str()); return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -1491,7 +1497,8 @@ ze_result_t ModuleImp::performDynamicLink(uint32_t numModules, if (numPatchedSymbols != moduleId->unresolvedExternalsInfo.size()) { driverHandle->clearErrorDescription(); if (functionSymbolExportEnabledCounter == 0) { - driverHandle->setErrorDescription("Dynamic Link Not Supported Without Compiler flag %s\n", BuildOptions::enableLibraryCompile.str().c_str()); + CREATE_DEBUG_STRING(str, "Dynamic Link Not Supported Without Compiler flag %s\n", BuildOptions::enableLibraryCompile.str().c_str()); + driverHandle->setErrorDescription(std::string(str.get())); PRINT_DEBUG_STRING(NEO::debugManager.flags.PrintDebugMessages.get(), stderr, "Dynamic Link Not Supported Without Compiler flag %s\n", BuildOptions::enableLibraryCompile.str().c_str()); } return ZE_RESULT_ERROR_MODULE_LINK_FAILURE; 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 941603e07f..be3a1a7e05 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 @@ -1216,47 +1216,46 @@ TEST_F(DriverHandleTest, givenValidDriverHandleWhenGetSvmAllocManagerIsCalledThe } TEST_F(DriverHandleTest, givenValidDriverHandleWhenSetErrorDescriptionIsCalledThenGetErrorDecriptionGetsStringCorrectly) { - std::string errorString = "we manually created error"; + const char *errorString = "we manually created error"; std::string errorString2 = "here's the next string to pass with arguments: "; - std::string errorString2Fmt = errorString2 + std::string("%d"); ze_result_t result = ZE_RESULT_SUCCESS; - driverHandle->setErrorDescription(errorString.c_str()); + driverHandle->setErrorDescription(std::string(errorString)); const char *pStr = nullptr; result = zeDriverGetLastErrorDescription(driverHandle->toHandle(), &pStr); - EXPECT_EQ(0, strcmp(errorString.c_str(), pStr)); + EXPECT_EQ(0, strcmp(errorString, pStr)); EXPECT_EQ(ZE_RESULT_SUCCESS, result); - driverHandle->setErrorDescription(errorString2Fmt.c_str(), 4); + std::string expectedString = errorString2; + driverHandle->setErrorDescription(errorString2); result = zeDriverGetLastErrorDescription(driverHandle->toHandle(), &pStr); - std::string expectedString = errorString2 + "4"; EXPECT_EQ(0, strcmp(expectedString.c_str(), pStr)); EXPECT_EQ(ZE_RESULT_SUCCESS, result); } TEST_F(DriverHandleTest, givenValidDriverHandleWhenGetErrorDescriptionIsCalledThenEmptyStringIsReturned) { - std::string errorString = ""; + const char *errorString = ""; ze_result_t result = ZE_RESULT_SUCCESS; const char *pStr = nullptr; result = zeDriverGetLastErrorDescription(driverHandle->toHandle(), &pStr); - EXPECT_EQ(0, strcmp(errorString.c_str(), pStr)); + EXPECT_EQ(0, strcmp(errorString, pStr)); EXPECT_EQ(ZE_RESULT_SUCCESS, result); - driverHandle->setErrorDescription(errorString.c_str()); + driverHandle->setErrorDescription(std::string(errorString)); result = zeDriverGetLastErrorDescription(driverHandle->toHandle(), &pStr); - EXPECT_EQ(0, strcmp(errorString.c_str(), pStr)); + EXPECT_EQ(0, strcmp(errorString, pStr)); EXPECT_EQ(ZE_RESULT_SUCCESS, result); } TEST_F(DriverHandleTest, givenValidDriverHandleWhenClearErrorDescriptionIsCalledThenEmptyStringIsReturned) { - std::string errorString = "error string"; + const char *errorString = "error string"; std::string emptyString = ""; const char *pStr = nullptr; ze_result_t result = ZE_RESULT_SUCCESS; - driverHandle->setErrorDescription(errorString.c_str()); + driverHandle->setErrorDescription(std::string(errorString)); result = zeDriverGetLastErrorDescription(driverHandle->toHandle(), &pStr); - EXPECT_EQ(0, strcmp(errorString.c_str(), pStr)); + EXPECT_EQ(0, strcmp(errorString, pStr)); EXPECT_EQ(ZE_RESULT_SUCCESS, result); result = driverHandle->clearErrorDescription(); diff --git a/shared/source/execution_environment/execution_environment.cpp b/shared/source/execution_environment/execution_environment.cpp index 4004e76c7a..83eae45c9e 100644 --- a/shared/source/execution_environment/execution_environment.cpp +++ b/shared/source/execution_environment/execution_environment.cpp @@ -168,6 +168,42 @@ void ExecutionEnvironment::prepareRootDeviceEnvironment(const uint32_t rootDevic rootDeviceEnvironments[rootDeviceIndexForReInit] = std::make_unique(*this); } +int ExecutionEnvironment::setErrorDescription(const std::string &str) { + auto threadId = std::this_thread::get_id(); + { + std::lock_guard errorDescsLock(errorDescsMutex); + if (errorDescs.find(threadId) == errorDescs.end()) { + errorDescs[threadId] = str; + } else { + errorDescs[threadId].clear(); + errorDescs[threadId] = str; + } + } + return static_cast(str.size()); +} + +void ExecutionEnvironment::getErrorDescription(const char **ppString) { + auto threadId = std::this_thread::get_id(); + { + std::lock_guard errorDescsLock(errorDescsMutex); + if (errorDescs.find(threadId) == errorDescs.end()) { + errorDescs[threadId] = std::string(); + } + } + *ppString = errorDescs[threadId].c_str(); +} + +int ExecutionEnvironment::clearErrorDescription() { + auto threadId = std::this_thread::get_id(); + { + std::lock_guard errorDescsLock(errorDescsMutex); + if (errorDescs.find(threadId) != errorDescs.end()) { + errorDescs[threadId].clear(); + } + } + return 0; +} + bool ExecutionEnvironment::getSubDeviceHierarchy(uint32_t index, std::tuple *subDeviceMap) { if (mapOfSubDeviceIndices.find(index) != mapOfSubDeviceIndices.end()) { *subDeviceMap = mapOfSubDeviceIndices.at(index); diff --git a/shared/source/execution_environment/execution_environment.h b/shared/source/execution_environment/execution_environment.h index 689601f5ad..4223515caf 100644 --- a/shared/source/execution_environment/execution_environment.h +++ b/shared/source/execution_environment/execution_environment.h @@ -10,7 +10,9 @@ #include "shared/source/utilities/reference_tracked_object.h" #include +#include #include +#include #include #include @@ -29,6 +31,7 @@ class ExecutionEnvironment : public ReferenceTrackedObject MOCKABLE_VIRTUAL bool initializeMemoryManager(); void calculateMaxOsContextCount(); + int clearErrorDescription(); virtual void prepareRootDeviceEnvironments(uint32_t numRootDevices); void prepareRootDeviceEnvironment(const uint32_t rootDeviceIndexForReInit); void parseAffinityMask(); @@ -55,8 +58,10 @@ class ExecutionEnvironment : public ReferenceTrackedObject } bool isExposingSubDevicesAsDevices() const { return this->subDevicesAsDevices; } bool isCombinedDeviceHierarchy() const { return this->combinedDeviceHierarchy; } + void getErrorDescription(const char **ppString); bool getSubDeviceHierarchy(uint32_t index, std::tuple *subDeviceMap); bool areMetricsEnabled() { return this->metricsEnabled; } + int setErrorDescription(const std::string &str); void setFP64EmulationEnabled() { fp64EmulationEnabled = true; } @@ -73,6 +78,8 @@ class ExecutionEnvironment : public ReferenceTrackedObject // // Primarily used by the Metrics Library to communicate the actual Sub Device Index being used in queries. std::unordered_map> mapOfSubDeviceIndices; + std::unordered_map errorDescs; + std::mutex errorDescsMutex; protected: static bool comparePciIdBusNumber(std::unique_ptr &rootDeviceEnvironment1, std::unique_ptr &rootDeviceEnvironment2); diff --git a/shared/source/utilities/logger.h b/shared/source/utilities/logger.h index da244799bc..96b689cf64 100644 --- a/shared/source/utilities/logger.h +++ b/shared/source/utilities/logger.h @@ -12,11 +12,16 @@ #include #include +#define CREATE_DEBUG_STRING(buffer, format, ...) \ + std::unique_ptr buffer(new char[NEO::maxErrorDescriptionSize]); \ + snprintf(buffer.get(), NEO::maxErrorDescriptionSize, format, __VA_ARGS__) + namespace NEO { class Kernel; struct MultiDispatchInfo; class GraphicsAllocation; +static const int32_t maxErrorDescriptionSize = 1024; const char *getAllocationTypeString(GraphicsAllocation const *graphicsAllocation); const char *getMemoryPoolString(GraphicsAllocation const *graphicsAllocation); diff --git a/shared/test/unit_test/execution_environment/execution_environment_tests.cpp b/shared/test/unit_test/execution_environment/execution_environment_tests.cpp index 284aea0af5..4e25133ee4 100644 --- a/shared/test/unit_test/execution_environment/execution_environment_tests.cpp +++ b/shared/test/unit_test/execution_environment/execution_environment_tests.cpp @@ -324,7 +324,9 @@ static_assert(sizeof(ExecutionEnvironment) == sizeof(std::unique_ptr>) + - sizeof(std::vector>), + sizeof(std::vector>) + + sizeof(std::unordered_map) + + sizeof(std::mutex), "New members detected in ExecutionEnvironment, please ensure that destruction sequence of objects is correct"); TEST(ExecutionEnvironment, givenExecutionEnvironmentWithVariousMembersWhenItIsDestroyedThenDeleteSequenceIsSpecified) { @@ -618,6 +620,63 @@ TEST(ExecutionEnvironmentDeviceHierarchy, givenExecutionEnvironmentWithCombinedD EXPECT_FALSE(executionEnvironment.isExposingSubDevicesAsDevices()); } +TEST(ExecutionEnvironment, givenExecutionEnvironmentWhenSetErrorDescriptionIsCalledThenGetErrorDescriptionGetsStringCorrectly) { + std::string errorString = "we manually created error"; + std::string errorString2 = "here's the next string to pass with arguments: "; + MockExecutionEnvironment executionEnvironment; + executionEnvironment.setErrorDescription(std::string(errorString)); + + const char *pStr = nullptr; + executionEnvironment.getErrorDescription(&pStr); + EXPECT_EQ(0, strcmp(errorString.c_str(), pStr)); + + int result = [](MockExecutionEnvironment *exeEnv, const std::string &str) { + int res = exeEnv->setErrorDescription(std::string(str)); + return res; + }(&executionEnvironment, errorString2); + EXPECT_NE(0, result); + executionEnvironment.getErrorDescription(&pStr); + std::string expectedString = errorString2; + printf("the received string is: \"%s\"\n", pStr); + printf("the expected string is: \"%s\"\n", expectedString.c_str()); + EXPECT_EQ(0, strcmp(expectedString.c_str(), pStr)); +} + +TEST(ExecutionEnvironment, givenValidExecutionEnvironmentWhenClearErrorDescriptionIsCalledThenEmptyStringIsReturned) { + std::string errorString = "error string"; + std::string emptyString = ""; + const char *pStr = nullptr; + MockExecutionEnvironment executionEnvironment; + + int result = executionEnvironment.clearErrorDescription(); + EXPECT_EQ(0, result); + executionEnvironment.getErrorDescription(&pStr); + EXPECT_EQ(0, strcmp(emptyString.c_str(), pStr)); + executionEnvironment.setErrorDescription(errorString); + executionEnvironment.getErrorDescription(&pStr); + + EXPECT_EQ(0, strcmp(errorString.c_str(), pStr)); + EXPECT_EQ(0, result); + + result = executionEnvironment.clearErrorDescription(); + EXPECT_EQ(0, result); + executionEnvironment.getErrorDescription(&pStr); + EXPECT_EQ(0, strcmp(emptyString.c_str(), pStr)); +} + +TEST(ExecutionEnvironment, givenExecutionEnvironmentWhenGetErrorDescriptionIsCalledThenEmptyStringIsReturned) { + std::string errorString = ""; + MockExecutionEnvironment executionEnvironment; + + const char *pStr = nullptr; + executionEnvironment.getErrorDescription(&pStr); + EXPECT_EQ(0, strcmp(errorString.c_str(), pStr)); + + executionEnvironment.setErrorDescription(errorString); + executionEnvironment.getErrorDescription(&pStr); + EXPECT_EQ(0, strcmp(errorString.c_str(), pStr)); +} + void ExecutionEnvironmentSortTests::SetUp() { executionEnvironment.prepareRootDeviceEnvironments(numRootDevices); for (uint32_t rootDeviceIndex = 0; rootDeviceIndex < numRootDevices; rootDeviceIndex++) {