diff --git a/level_zero/core/source/driver/driver_handle_imp.cpp b/level_zero/core/source/driver/driver_handle_imp.cpp index 7842a729a2..d3944c4c0e 100644 --- a/level_zero/core/source/driver/driver_handle_imp.cpp +++ b/level_zero/core/source/driver/driver_handle_imp.cpp @@ -10,6 +10,7 @@ #include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/device/device.h" #include "shared/source/memory_manager/memory_manager.h" +#include "shared/source/os_interface/debug_env_reader.h" #include "shared/source/os_interface/os_library.h" #include "level_zero/core/source/device/device_imp.h" @@ -161,7 +162,9 @@ DriverHandle *DriverHandle::create(std::vector> dev DriverHandleImp *driverHandle = new DriverHandleImp; UNRECOVERABLE_IF(nullptr == driverHandle); - driverHandle->getEnv("ZE_AFFINITY_MASK", driverHandle->affinityMask); + NEO::EnvironmentVariableReader envReader; + driverHandle->affinityMask = envReader.getSetting("ZE_AFFINITY_MASK", static_cast(driverHandle->affinityMask)); + driverHandle->enableProgramDebugging = envReader.getSetting("ZET_ENABLE_PROGRAM_DEBUGGING", driverHandle->enableProgramDebugging); ze_result_t res = driverHandle->initialize(std::move(devices)); if (res != ZE_RESULT_SUCCESS) { diff --git a/level_zero/core/source/driver/driver_handle_imp.h b/level_zero/core/source/driver/driver_handle_imp.h index 8781fed589..629e7c0e62 100644 --- a/level_zero/core/source/driver/driver_handle_imp.h +++ b/level_zero/core/source/driver/driver_handle_imp.h @@ -58,16 +58,6 @@ struct DriverHandleImp : public DriverHandle { size_t size, bool *allocationRangeCovered) override; - template - bool getEnv(const char *varName, T &varValue) { - char *varChar = getenv(varName); - if (varChar) { - varValue = static_cast(atoi(varChar)); - return true; - } - return false; - } - uint32_t numDevices = 0; std::unordered_map extensionFunctionsLookupMap; std::vector devices; @@ -75,6 +65,7 @@ struct DriverHandleImp : public DriverHandle { NEO::SVMAllocsManager *svmAllocsManager = nullptr; uint32_t affinityMask = std::numeric_limits::max(); + bool enableProgramDebugging = false; }; } // namespace L0 diff --git a/level_zero/core/test/unit_tests/mocks/mock_driver_handle.h b/level_zero/core/test/unit_tests/mocks/mock_driver_handle.h index 08051975c9..b4a1953053 100644 --- a/level_zero/core/test/unit_tests/mocks/mock_driver_handle.h +++ b/level_zero/core/test/unit_tests/mocks/mock_driver_handle.h @@ -21,10 +21,11 @@ namespace L0 { namespace ult { template <> -struct WhiteBox<::L0::DriverHandleImp> : public ::L0::DriverHandleImp { +struct WhiteBox<::L0::DriverHandle> : public ::L0::DriverHandleImp { + using ::L0::DriverHandleImp::enableProgramDebugging; }; -using DriverHandle = WhiteBox<::L0::DriverHandleImp>; +using DriverHandle = WhiteBox<::L0::DriverHandle>; template <> struct Mock : public DriverHandleImp { 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 2d0a282874..f33a67f700 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 @@ -9,6 +9,7 @@ #include "shared/source/os_interface/hw_info_config.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h" +#include "opencl/test/unit_test/mocks/mock_io_functions.h" #include "test.h" #include "level_zero/core/source/driver/driver_handle_imp.h" @@ -60,6 +61,40 @@ TEST(DriverTestFamilySupport, whenInitializingDriverOnNotSupportedFamilyThenDriv EXPECT_EQ(nullptr, driverHandle); } +TEST(DriverTest, givenNullEnvVariableWhenCreatingDriverThenEnableProgramDebuggingIsFalse) { + NEO::HardwareInfo hwInfo = *NEO::defaultHwInfo.get(); + hwInfo.capabilityTable.levelZeroSupported = true; + + NEO::MockDevice *neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment(&hwInfo); + NEO::DeviceVector devices; + devices.push_back(std::unique_ptr(neoDevice)); + + auto driverHandle = whitebox_cast(DriverHandle::create(std::move(devices))); + EXPECT_NE(nullptr, driverHandle); + + EXPECT_FALSE(driverHandle->enableProgramDebugging); + + delete driverHandle; +} + +TEST(DriverTest, givenEnvVariableNonZeroWhenCreatingDriverThenEnableProgramDebuggingIsSetTrue) { + NEO::HardwareInfo hwInfo = *NEO::defaultHwInfo.get(); + hwInfo.capabilityTable.levelZeroSupported = true; + + VariableBackup mockDeviceFlagBackup(&IoFunctions::returnMockEnvValue, true); + + NEO::MockDevice *neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment(&hwInfo); + NEO::DeviceVector devices; + devices.push_back(std::unique_ptr(neoDevice)); + + auto driverHandle = whitebox_cast(DriverHandle::create(std::move(devices))); + EXPECT_NE(nullptr, driverHandle); + + EXPECT_TRUE(driverHandle->enableProgramDebugging); + + delete driverHandle; +} + struct DriverTestMultipleFamilySupport : public ::testing::Test { void SetUp() override { VariableBackup mockDeviceFlagBackup(&MockDevice::createSingleDevice, false); diff --git a/opencl/test/unit_test/command_stream/command_stream_receiver_flush_task_gmock_tests.cpp b/opencl/test/unit_test/command_stream/command_stream_receiver_flush_task_gmock_tests.cpp index 06448ccf87..ae6d514a13 100644 --- a/opencl/test/unit_test/command_stream/command_stream_receiver_flush_task_gmock_tests.cpp +++ b/opencl/test/unit_test/command_stream/command_stream_receiver_flush_task_gmock_tests.cpp @@ -17,7 +17,7 @@ #include "shared/source/helpers/ptr_math.h" #include "shared/source/memory_manager/graphics_allocation.h" #include "shared/source/memory_manager/memory_manager.h" -#include "shared/source/os_interface/linux/debug_env_reader.h" +#include "shared/source/os_interface/debug_env_reader.h" #include "shared/test/unit_test/cmd_parse/hw_parse.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h" #include "shared/test/unit_test/helpers/dispatch_flags_helper.h" diff --git a/opencl/test/unit_test/command_stream/command_stream_receiver_hw_tests.cpp b/opencl/test/unit_test/command_stream/command_stream_receiver_hw_tests.cpp index d17bbeece6..e378ba8624 100644 --- a/opencl/test/unit_test/command_stream/command_stream_receiver_hw_tests.cpp +++ b/opencl/test/unit_test/command_stream/command_stream_receiver_hw_tests.cpp @@ -19,7 +19,7 @@ #include "shared/source/memory_manager/graphics_allocation.h" #include "shared/source/memory_manager/memory_manager.h" #include "shared/source/memory_manager/unified_memory_manager.h" -#include "shared/source/os_interface/linux/debug_env_reader.h" +#include "shared/source/os_interface/debug_env_reader.h" #include "shared/source/os_interface/os_context.h" #include "shared/test/unit_test/cmd_parse/hw_parse.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h" diff --git a/opencl/test/unit_test/libult/io_functions.cpp b/opencl/test/unit_test/libult/io_functions.cpp index 24af9f4fe0..d70960623d 100644 --- a/opencl/test/unit_test/libult/io_functions.cpp +++ b/opencl/test/unit_test/libult/io_functions.cpp @@ -12,9 +12,13 @@ namespace IoFunctions { fopenFuncPtr fopenPtr = &mockFopen; vfprintfFuncPtr vfprintfPtr = &mockVfptrinf; fcloseFuncPtr fclosePtr = &mockFclose; +getenvFuncPtr getenvPtr = &mockGetenv; uint32_t mockFopenCalled = 0; uint32_t mockVfptrinfCalled = 0; uint32_t mockFcloseCalled = 0; +bool returnMockEnvValue = false; +std::string mockEnvValue = "1"; + } // namespace IoFunctions } // namespace NEO diff --git a/opencl/test/unit_test/mocks/mock_io_functions.h b/opencl/test/unit_test/mocks/mock_io_functions.h index 1351d592b7..49ddc8980c 100644 --- a/opencl/test/unit_test/mocks/mock_io_functions.h +++ b/opencl/test/unit_test/mocks/mock_io_functions.h @@ -9,6 +9,7 @@ #include "shared/source/utilities/io_functions.h" #include +#include namespace NEO { namespace IoFunctions { @@ -16,6 +17,9 @@ extern uint32_t mockFopenCalled; extern uint32_t mockVfptrinfCalled; extern uint32_t mockFcloseCalled; +extern bool returnMockEnvValue; +extern std::string mockEnvValue; + inline FILE *mockFopen(const char *filename, const char *mode) { mockFopenCalled++; return reinterpret_cast(0x40); @@ -30,5 +34,13 @@ inline int mockFclose(FILE *stream) { mockFcloseCalled++; return 0; } + +inline char *mockGetenv(const char *name) noexcept { + if (returnMockEnvValue) { + return const_cast(mockEnvValue.c_str()); + } + return getenv(name); +} + } // namespace IoFunctions } // namespace NEO diff --git a/opencl/test/unit_test/os_interface/linux/debug_env_reader.cpp b/opencl/test/unit_test/os_interface/linux/debug_env_reader.cpp index 8ce4d54367..7acaf4e0c4 100644 --- a/opencl/test/unit_test/os_interface/linux/debug_env_reader.cpp +++ b/opencl/test/unit_test/os_interface/linux/debug_env_reader.cpp @@ -5,7 +5,7 @@ * */ -#include "shared/source/os_interface/linux/debug_env_reader.h" +#include "shared/source/os_interface/debug_env_reader.h" #include "test.h" diff --git a/opencl/test/unit_test/utilities/debug_settings_reader_tests.cpp b/opencl/test/unit_test/utilities/debug_settings_reader_tests.cpp index 0fa1727de4..68ca82880a 100644 --- a/opencl/test/unit_test/utilities/debug_settings_reader_tests.cpp +++ b/opencl/test/unit_test/utilities/debug_settings_reader_tests.cpp @@ -19,6 +19,17 @@ using namespace NEO; +class MockSettingsReader : public SettingsReader { + public: + std::string getSetting(const char *settingName, const std::string &value) override { + return value; + } + bool getSetting(const char *settingName, bool defaultValue) override { return defaultValue; }; + int64_t getSetting(const char *settingName, int64_t defaultValue) override { return defaultValue; }; + int32_t getSetting(const char *settingName, int32_t defaultValue) override { return defaultValue; }; + const char *appSpecificLocation(const std::string &name) override { return name.c_str(); }; +}; + TEST(SettingsReader, Create) { SettingsReader *reader = SettingsReader::create(oclRegPath); EXPECT_NE(nullptr, reader); @@ -82,6 +93,7 @@ TEST(SettingsReader, givenPrintDebugStringWhenCalledWithTrueItPrintsToOutput) { std::string output = testing::internal::GetCapturedStdout(); EXPECT_STRNE(output.c_str(), ""); } + TEST(SettingsReader, givenPrintDebugStringWhenCalledWithFalseThenNothingIsPrinted) { int i = 4; testing::internal::CaptureStdout(); @@ -89,3 +101,9 @@ TEST(SettingsReader, givenPrintDebugStringWhenCalledWithFalseThenNothingIsPrinte std::string output = testing::internal::GetCapturedStdout(); EXPECT_STREQ(output.c_str(), ""); } + +TEST(SettingsReader, givenNonExistingEnvVarWhenGettingEnvThenNullptrIsReturned) { + MockSettingsReader reader; + auto value = reader.getenv("ThisEnvVarDoesNotExist"); + EXPECT_EQ(nullptr, value); +} diff --git a/shared/source/os_interface/CMakeLists.txt b/shared/source/os_interface/CMakeLists.txt index 4e6e41d43f..ee8d1e0d34 100644 --- a/shared/source/os_interface/CMakeLists.txt +++ b/shared/source/os_interface/CMakeLists.txt @@ -8,6 +8,8 @@ set(NEO_CORE_OS_INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/aub_memory_operations_handler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/aub_memory_operations_handler.h + ${CMAKE_CURRENT_SOURCE_DIR}/debug_env_reader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/debug_env_reader.h ${CMAKE_CURRENT_SOURCE_DIR}/device_factory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/device_factory.h ${CMAKE_CURRENT_SOURCE_DIR}/driver_info.h diff --git a/shared/source/os_interface/linux/debug_env_reader.cpp b/shared/source/os_interface/debug_env_reader.cpp similarity index 80% rename from shared/source/os_interface/linux/debug_env_reader.cpp rename to shared/source/os_interface/debug_env_reader.cpp index 24bffaf4b2..385fa5231c 100644 --- a/shared/source/os_interface/linux/debug_env_reader.cpp +++ b/shared/source/os_interface/debug_env_reader.cpp @@ -5,14 +5,12 @@ * */ -#include "shared/source/os_interface/linux/debug_env_reader.h" +#include "shared/source/os_interface/debug_env_reader.h" + +#include "shared/source/utilities/io_functions.h" namespace NEO { -SettingsReader *SettingsReader::createOsReader(bool userScope, const std::string ®Key) { - return new EnvironmentVariableReader; -} - const char *EnvironmentVariableReader::appSpecificLocation(const std::string &name) { return name.c_str(); } @@ -29,7 +27,7 @@ int64_t EnvironmentVariableReader::getSetting(const char *settingName, int64_t d int64_t value = defaultValue; char *envValue; - envValue = getenv(settingName); + envValue = IoFunctions::getenvPtr(settingName); if (envValue) { value = atoi(envValue); } @@ -41,7 +39,7 @@ std::string EnvironmentVariableReader::getSetting(const char *settingName, const std::string keyValue; keyValue.assign(value); - envValue = getenv(settingName); + envValue = IoFunctions::getenvPtr(settingName); if (envValue) { keyValue.assign(envValue); } diff --git a/shared/source/os_interface/linux/debug_env_reader.h b/shared/source/os_interface/debug_env_reader.h similarity index 100% rename from shared/source/os_interface/linux/debug_env_reader.h rename to shared/source/os_interface/debug_env_reader.h diff --git a/shared/source/os_interface/linux/CMakeLists.txt b/shared/source/os_interface/linux/CMakeLists.txt index 5a13644a60..bc99c37b03 100644 --- a/shared/source/os_interface/linux/CMakeLists.txt +++ b/shared/source/os_interface/linux/CMakeLists.txt @@ -7,8 +7,6 @@ set(NEO_CORE_OS_INTERFACE_LINUX ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/allocator_helper.h - ${CMAKE_CURRENT_SOURCE_DIR}/debug_env_reader.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/debug_env_reader.h ${CMAKE_CURRENT_SOURCE_DIR}/driver_info_linux.cpp ${CMAKE_CURRENT_SOURCE_DIR}/driver_info_linux.h ${CMAKE_CURRENT_SOURCE_DIR}/drm_allocation.cpp @@ -50,6 +48,7 @@ set(NEO_CORE_OS_INTERFACE_LINUX ${CMAKE_CURRENT_SOURCE_DIR}/os_time_linux.h ${CMAKE_CURRENT_SOURCE_DIR}/page_table_manager_functions.cpp ${CMAKE_CURRENT_SOURCE_DIR}/print.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/settings_reader_create.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sys_calls.h ) diff --git a/shared/source/os_interface/linux/settings_reader_create.cpp b/shared/source/os_interface/linux/settings_reader_create.cpp new file mode 100644 index 0000000000..70073f6b25 --- /dev/null +++ b/shared/source/os_interface/linux/settings_reader_create.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/os_interface/debug_env_reader.h" + +namespace NEO { + +SettingsReader *SettingsReader::createOsReader(bool userScope, const std::string ®Key) { + return new EnvironmentVariableReader; +} +} // namespace NEO diff --git a/shared/source/utilities/io_functions.cpp b/shared/source/utilities/io_functions.cpp index 5b1dcd7e4c..989610d8aa 100644 --- a/shared/source/utilities/io_functions.cpp +++ b/shared/source/utilities/io_functions.cpp @@ -12,5 +12,6 @@ namespace IoFunctions { fopenFuncPtr fopenPtr = &fopen; vfprintfFuncPtr vfprintfPtr = &vfprintf; fcloseFuncPtr fclosePtr = &fclose; +getenvFuncPtr getenvPtr = &getenv; } // namespace IoFunctions } // namespace NEO diff --git a/shared/source/utilities/io_functions.h b/shared/source/utilities/io_functions.h index 7f6407f6fe..d6582fbb5d 100644 --- a/shared/source/utilities/io_functions.h +++ b/shared/source/utilities/io_functions.h @@ -8,16 +8,19 @@ #pragma once #include #include +#include namespace NEO { namespace IoFunctions { using fopenFuncPtr = FILE *(*)(const char *, const char *); using vfprintfFuncPtr = int (*)(FILE *, char const *const formatStr, va_list arg); using fcloseFuncPtr = int (*)(FILE *); +using getenvFuncPtr = decltype(&getenv); extern fopenFuncPtr fopenPtr; extern vfprintfFuncPtr vfprintfPtr; extern fcloseFuncPtr fclosePtr; +extern getenvFuncPtr getenvPtr; inline int fprintf(FILE *fileDesc, char const *const formatStr, ...) { va_list args;