feature: Adding support for scoped debug variables

This allows for limitting debug variables to specific
components.

Related-To: NEO-14473
Signed-off-by: Chodor, Jaroslaw <jaroslaw.chodor@intel.com>
This commit is contained in:
Chodor, Jaroslaw
2025-04-08 14:43:25 +00:00
committed by Compute-Runtime-Automation
parent 3204411aca
commit 9e14eaaed1
14 changed files with 156 additions and 27 deletions

View File

@@ -26,6 +26,9 @@
namespace NEO {
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
template <typename T>
static std::string toString(const T &arg) {
if constexpr (std::is_convertible_v<std::string, T>) {
@@ -39,6 +42,9 @@ template <DebugFunctionalityLevel debugLevel>
DebugSettingsManager<debugLevel>::DebugSettingsManager(const char *registryPath) {
readerImpl = SettingsReaderCreator::create(std::string(registryPath));
ApiSpecificConfig::initPrefixes();
for (auto prefixType : ApiSpecificConfig::getPrefixTypes()) {
this->scope |= getDebugVarScopeMaskFor(prefixType);
}
injectSettingsFromReader();
dumpFlags();
translateDebugSettings(flags);
@@ -145,8 +151,10 @@ void DebugSettingsManager<debugLevel>::injectSettingsFromReader() {
DebugVarPrefix type; \
constexpr auto keyName = getNonReleaseKeyName(#variableName); \
dataType tempData = readerImpl->getSetting(keyName, flags.variableName.get(), type); \
flags.variableName.setPrefixType(type); \
flags.variableName.set(tempData); \
if (0 != (this->scope & flags.variableName.getScopeMask())) { \
flags.variableName.setPrefixType(type); \
flags.variableName.set(tempData); \
} \
}
if (registryReadAvailable() || isDebugKeysReadEnabled()) {
@@ -158,12 +166,14 @@ void DebugSettingsManager<debugLevel>::injectSettingsFromReader() {
{ \
DebugVarPrefix type; \
dataType tempData = readerImpl->getSetting(#variableName, flags.variableName.get(), type); \
flags.variableName.setPrefixType(type); \
flags.variableName.set(tempData); \
if (0 != (this->scope & flags.variableName.getScopeMask())) { \
flags.variableName.setPrefixType(type); \
flags.variableName.set(tempData); \
} \
}
#include "release_variables.inl"
#undef DECLARE_DEBUG_VARIABLE
}
} // namespace NEO
void logDebugString(std::string_view debugString) {
NEO::fileLoggerInstance().logDebugString(true, debugString);

View File

@@ -17,6 +17,7 @@
#include <memory>
#include <sstream>
#include <string_view>
#include <type_traits>
enum class DebugFunctionalityLevel {
none, // Debug functionality disabled
@@ -68,12 +69,27 @@ enum class DebugVarPrefix : uint8_t {
none = 1,
neo = 2,
neoL0 = 3,
neoOcl = 4
neoOcl = 4,
neoOcloc = 5
};
using DVarsScopeMask = std::underlying_type_t<DebugVarPrefix>;
constexpr auto getDebugVarScopeMaskFor(DebugVarPrefix v) {
return static_cast<DVarsScopeMask>(1U) << static_cast<DVarsScopeMask>(v);
}
template <DebugVarPrefix... vs>
constexpr auto getDebugVarScopeMaskFor() {
return (0 | ... | getDebugVarScopeMaskFor(vs));
}
// compatibility with "old" behavior (prior to introducing scope masks)
constexpr inline DVarsScopeMask compatibilityMask = getDebugVarScopeMaskFor<DebugVarPrefix::neoL0, DebugVarPrefix::neoOcl>();
template <typename T>
struct DebugVarBase {
DebugVarBase(const T &defaultValue) : value(defaultValue), defaultValue(defaultValue) {}
DebugVarBase(const T &defaultValue, DVarsScopeMask scopeMask) : value(defaultValue), defaultValue(defaultValue), scopeMask(scopeMask) {}
T get() const {
return value;
}
@@ -94,11 +110,15 @@ struct DebugVarBase {
DebugVarPrefix getPrefixType() const {
return prefixType;
}
DVarsScopeMask getScopeMask() const {
return scopeMask;
}
private:
T value;
T defaultValue;
DebugVarPrefix prefixType = DebugVarPrefix::none;
DVarsScopeMask scopeMask = compatibilityMask;
};
struct DebugVariables { // NOLINT(clang-analyzer-optin.performance.Padding)
@@ -114,8 +134,22 @@ struct DebugVariables { // NOLINT(clang-analyzer
#define DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description) \
DebugVarBase<dataType> variableName{defaultValue};
#define S_NONE getDebugVarScopeMaskFor(DebugVarPrefix::none)
#define S_NEO getDebugVarScopeMaskFor(DebugVarPrefix::neo)
#define S_OCL getDebugVarScopeMaskFor(DebugVarPrefix::neoOcl)
#define S_L0 getDebugVarScopeMaskFor(DebugVarPrefix::neoL0)
#define S_RT (S_NEO | S_OCL | S_L0 | S_NONE)
#define S_OCLOC getDebugVarScopeMaskFor(DebugVarPrefix::neoOcloc)
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, scope, description) \
DebugVarBase<dataType> variableName{defaultValue, scope};
#include "debug_variables.inl"
#include "release_variables.inl"
#undef S_OCLOC
#undef S_RT
#undef S_L0
#undef S_OCL
#undef S_NEO
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
};
@@ -169,6 +203,7 @@ class DebugSettingsManager : NEO::NonCopyableAndNonMovableClass {
}
protected:
DVarsScopeMask scope = 0;
std::unique_ptr<SettingsReader> readerImpl;
bool isLoopAtDriverInitEnabled() const {
auto loopingEnabled = flags.LoopAtDriverInit.get();

View File

@@ -633,7 +633,7 @@ DECLARE_DEBUG_VARIABLE(int32_t, NumberOfBOChunks, 2, "Number of chunks to use")
DECLARE_DEBUG_VARIABLE(int32_t, SetBOChunkingSize, -1, "Size of chunk in bytes: -1 = default, otherwise power of two chunk size in bytes")
DECLARE_DEBUG_VARIABLE(int32_t, MinimalAllocationSizeForChunking, -1, "2097152: default, >0: size in B. Minimal size an allocation should have to use chunking.")
DECLARE_DEBUG_VARIABLE(int32_t, ForceAutoGrfCompilationMode, -1, "Adds build option -*-intel-enable-auto-large-GRF-mode to force kernel compilation")
DECLARE_DEBUG_VARIABLE(int32_t, ForceOCLVersion, 0, "Force specific OpenCL API version")
DECLARE_DEBUG_SCOPED_V(int32_t, ForceOCLVersion, 0, S_OCL, "Force specific OpenCL API version")
DECLARE_DEBUG_VARIABLE(int32_t, ForceOCL21FeaturesSupport, -1, "-1: default, 0: disable, 1:enable. Force support of OpenCL 2.0 and OpenCL 2.1 API features")
DECLARE_DEBUG_VARIABLE(int32_t, ForcePreemptionMode, -1, "Keep this variable in sync with PreemptionMode enum. -1 - devices default mode, 1 - disable, 2 - midBatch, 3 - threadGroup, 4 - midThread")
DECLARE_DEBUG_VARIABLE(int32_t, ForceKernelPreemptionMode, -1, "Keep this variable in sync with PreemptionMode enum. -1 - kernel default mode, 1 - disable, 2 - midBatch, 3 - threadGroup, 4 - midThread")

View File

@@ -46,11 +46,12 @@ void BaseUltConfigListener::OnTestEnd(const ::testing::TestInfo &) {
#undef DECLARE_DEBUG_VARIABLE
#define DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description) \
EXPECT_EQ(debugVarSnapshot.variableName.getRef(), debugManager.flags.variableName.getRef());
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "shared/source/debug_settings/release_variables.inl"
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
EXPECT_EQ(injectFcnSnapshot, debugManager.injectFcn);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Intel Corporation
* Copyright (C) 2019-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -10,6 +10,7 @@
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/helpers/file_io.h"
#include "shared/source/utilities/directory.h"
#include "shared/source/utilities/stackvec.h"
#include <map>
@@ -17,6 +18,11 @@ using namespace NEO;
#undef DECLARE_DEBUG_VARIABLE
namespace NEO {
extern std::unique_ptr<SettingsReader> mockSettingsReader;
extern const StackVec<DebugVarPrefix, 4> *validUltPrefixTypesOverride;
} // namespace NEO
class TestDebugFlagsChecker {
public:
static bool isEqual(int32_t returnedValue, bool defaultValue) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -21,9 +21,12 @@ class DebugManagerStateRestore {
debugManager.injectFcn = injectFcnSnapshot;
#undef DECLARE_DEBUG_VARIABLE
#define DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description) shrink(debugManager.flags.variableName.getRef());
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "shared/source/debug_settings/release_variables.inl"
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
}
DebugVariables debugVarSnapshot;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -15,15 +15,15 @@ class VariableBackup {
oldValue = *ptr;
}
VariableBackup(T *ptr, T &&newValue) : pValue(ptr) {
oldValue = *ptr;
*pValue = newValue;
oldValue = std::move(*ptr);
*pValue = std::move(newValue);
}
VariableBackup(T *ptr, T &newValue) : pValue(ptr) {
oldValue = *ptr;
*pValue = newValue;
}
~VariableBackup() {
*pValue = oldValue;
*pValue = std::move(oldValue);
}
void operator=(const T &val) {
*pValue = val;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -8,7 +8,13 @@
#include "shared/source/utilities/debug_settings_reader_creator.h"
namespace NEO {
std::unique_ptr<SettingsReader> mockSettingsReader;
std::unique_ptr<SettingsReader> SettingsReaderCreator::create(const std::string &regKey) {
if (mockSettingsReader) {
return std::move(mockSettingsReader);
}
return std::unique_ptr<SettingsReader>(SettingsReader::createOsReader(false, regKey));
}
} // namespace NEO

View File

@@ -21,6 +21,7 @@ bool globalStatelessOcl = false;
bool isStatelessCompressionSupportedForUlts = true;
bool isDeviceUsmPoolingEnabledForUlts = true;
const StackVec<DebugVarPrefix, 4> *validUltPrefixTypesOverride = nullptr;
StackVec<const char *, 4> validUltL0Prefixes = {"NEO_L0_", "NEO_", ""};
StackVec<NEO::DebugVarPrefix, 4> validUltL0PrefixTypes = {DebugVarPrefix::neoL0, DebugVarPrefix::neo, DebugVarPrefix::none};
StackVec<const char *, 4> validUltOclPrefixes = {"NEO_OCL_", "NEO_", ""};
@@ -94,6 +95,9 @@ const StackVec<const char *, 4> &ApiSpecificConfig::getPrefixStrings() {
}
const StackVec<DebugVarPrefix, 4> &ApiSpecificConfig::getPrefixTypes() {
if (validUltPrefixTypesOverride) {
return *validUltPrefixTypesOverride;
}
if (apiTypeForUlts == ApiSpecificConfig::L0) {
return validUltL0PrefixTypes;
} else {

View File

@@ -58,9 +58,12 @@ TEST(DebugSettingsManager, WhenDebugManagerIsDisabledThenDebugFunctionalityIsNot
bool isEqual = TestDebugFlagsChecker::isEqual(debugManager.flags.variableName.get(), static_cast<dataType>(defaultValue)); \
EXPECT_TRUE(isEqual); \
}
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "shared/source/debug_settings/release_variables.inl"
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
}
@@ -150,8 +153,10 @@ TEST(DebugSettingsManager, givenPrintDebugSettingsEnabledWithNoPrefixWhenCalling
DebugVarPrefix type; \
EXPECT_EQ(debugManager.flags.varName.get(), allSettingsReader.getSetting(#varName, defaultValue, type)); \
}
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
std::remove(FullyEnabledTestDebugManager::settingsDumpFileName);
@@ -189,8 +194,10 @@ TEST(DebugSettingsManager, DISABLED_givenPrintDebugSettingsEnabledWithNeoPrefixW
DebugVarPrefix type; \
EXPECT_EQ(debugManager.flags.varName.get(), allSettingsReader.getSetting(#varName, defaultValue, type)); \
}
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
std::remove(FullyEnabledTestDebugManager::settingsDumpFileName);
@@ -228,8 +235,10 @@ TEST(DebugSettingsManager, givenPrintDebugSettingsEnabledWithLevelZeroPrefixWhen
DebugVarPrefix type; \
EXPECT_EQ(debugManager.flags.varName.get(), allSettingsReader.getSetting(#varName, defaultValue, type)); \
}
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
std::remove(FullyEnabledTestDebugManager::settingsDumpFileName);
@@ -267,8 +276,10 @@ TEST(DebugSettingsManager, givenPrintDebugSettingsEnabledWithOclPrefixWhenCallin
DebugVarPrefix type; \
EXPECT_EQ(debugManager.flags.varName.get(), allSettingsReader.getSetting(#varName, defaultValue, type)); \
}
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
std::remove(FullyEnabledTestDebugManager::settingsDumpFileName);
@@ -306,8 +317,10 @@ TEST(DebugSettingsManager, givenPrintDebugSettingsEnabledWithMixedPrefixWhenCall
DebugVarPrefix type; \
EXPECT_EQ(debugManager.flags.varName.get(), allSettingsReader.getSetting(#varName, defaultValue, type)); \
}
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
std::remove(FullyEnabledTestDebugManager::settingsDumpFileName);
@@ -516,4 +529,44 @@ TEST(DebugSettingsManager, GivenHardwareOrHardwareWithAubCsrTypeAndTbxFaultsEnab
NEO::debugManager.flags.SetCommandStreamReceiver.set(3);
EXPECT_FALSE(NEO::debugManager.isTbxPageFaultManagerEnabled());
}
TEST(DebugSettingsManager, whenDebugVariableDoesntMatchScopeThenIgnoreIt) {
struct MockSettingFileReader : SettingsFileReader {
MockSettingFileReader() : SettingsFileReader("") {
settingStringMap["ForceOCLVersion"] = "1";
settingStringMap["NEO_ForceOCLVersion"] = "1";
settingStringMap["NEO_OCL_ForceOCLVersion"] = "1";
settingStringMap["NEO_L0_ForceOCLVersion"] = "1";
settingStringMap["ZE_AFFINITY_MASK"] = "1";
}
};
VariableBackup<decltype(mockSettingsReader)> backupReader(&mockSettingsReader, {});
VariableBackup backupPrefixes(&validUltPrefixTypesOverride);
{
mockSettingsReader = std::make_unique<MockSettingFileReader>();
FullyEnabledTestDebugManager debugManager;
VariableBackup<ApiSpecificConfig::ApiType> backup(&apiTypeForUlts, ApiSpecificConfig::OCL);
EXPECT_EQ(1, debugManager.flags.ForceOCLVersion.get());
EXPECT_STREQ("1", debugManager.flags.ZE_AFFINITY_MASK.get().c_str());
}
{
mockSettingsReader = std::make_unique<MockSettingFileReader>();
VariableBackup<ApiSpecificConfig::ApiType> backup(&apiTypeForUlts, ApiSpecificConfig::L0);
FullyEnabledTestDebugManager debugManager;
EXPECT_EQ(0, debugManager.flags.ForceOCLVersion.get());
EXPECT_STREQ("1", debugManager.flags.ZE_AFFINITY_MASK.get().c_str());
}
{
mockSettingsReader = std::make_unique<MockSettingFileReader>();
StackVec<DebugVarPrefix, 4> prefixes = {};
validUltPrefixTypesOverride = &prefixes;
FullyEnabledTestDebugManager debugManager;
EXPECT_EQ(0, debugManager.flags.ForceOCLVersion.get());
EXPECT_STREQ("default", debugManager.flags.ZE_AFFINITY_MASK.get().c_str());
}
}

View File

@@ -60,8 +60,10 @@ TEST(DebugSettingsManager, givenPrintDebugSettingsAndDebugKeysReadEnabledOnDisab
SettingsFileReader allSettingsReader{FullyDisabledTestDebugManager::settingsDumpFileName};
#define DECLARE_DEBUG_VARIABLE(dataType, varName, defaultValue, description) \
EXPECT_EQ(debugManager.flags.varName.get(), allSettingsReader.getSetting(#varName, defaultValue));
#define DECLARE_DEBUG_SCOPED_V(dataType, varName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, varName, defaultValue, description)
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
std::remove(FullyDisabledTestDebugManager::settingsDumpFileName);
std::string output = testing::internal::GetCapturedStdout();

View File

@@ -342,11 +342,12 @@ TEST(ExecutionEnvironment, givenNeoCalEnabledWhenCreateExecutionEnvironmentThenS
#undef DECLARE_DEBUG_VARIABLE
#define DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description) \
EXPECT_EQ(defaultValue, debugManager.flags.variableName.getRef());
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "shared/source/debug_settings/release_variables.inl"
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
DebugManagerStateRestore restorer;
@@ -375,11 +376,13 @@ TEST(ExecutionEnvironment, givenNeoCalEnabledWhenCreateExecutionEnvironmentThenS
} \
} \
}
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "shared/source/debug_settings/release_variables.inl"
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2022 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -26,9 +26,12 @@ TEST(SettingsFileReader, givenTestFileWithDefaultValuesWhenTheyAreQueriedThenDef
compareSuccessful = (defaultValue == reader->getSetting(#variableName, defaultValue)); \
EXPECT_TRUE(compareSuccessful) << #variableName; \
debugVariableCount++;
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "shared/source/debug_settings/release_variables.inl"
#include "debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
size_t mapCount = reader->getStringSettingsCount();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -92,7 +92,10 @@ TEST(SettingsFileReader, WhenGettingSettingThenCorrectStringValueIsReturned) {
EXPECT_TRUE(true); \
} \
}
#define DECLARE_DEBUG_SCOPED_V(dataType, variableName, defaultValue, description, ...) \
DECLARE_DEBUG_VARIABLE(dataType, variableName, defaultValue, description)
#include "shared/test/unit_test/helpers/test_debug_variables.inl"
#undef DECLARE_DEBUG_SCOPED_V
#undef DECLARE_DEBUG_VARIABLE
}