From 991febcdf4c0796f25341e44bbc5d23bf6a40317 Mon Sep 17 00:00:00 2001 From: Kacper Kasper Date: Mon, 21 Aug 2023 12:00:06 +0000 Subject: [PATCH] fix: extend cache hash with compiler commit sha, lib size and mtime Related-To: NEO-4262 Signed-off-by: Kacper Kasper --- .../firmware_util/mock_fw_util_fixture.h | 3 ++ .../firmware_util/test_fw_util_helper.cpp | 12 ++++++++ .../sources/linux/nl_api/mock_nl_dll.h | 3 ++ .../metrics/test_metric_oa_initialization.cpp | 6 +++- .../firmware_util/mock_fw_util_fixture.h | 3 ++ .../firmware_util/test_fw_util_helper.cpp | 12 ++++++++ .../sources/sysman/linux/nl_api/mock_nl_dll.h | 5 +++- opencl/test/unit_test/mocks/mock_program.cpp | 5 +++- .../mock_performance_counters.cpp | 7 +++++ .../os_interface/mock_performance_counters.h | 1 + shared/offline_compiler/source/CMakeLists.txt | 2 ++ .../source/ocloc_igc_facade.cpp | 28 +++++++++++++++++++ .../source/ocloc_igc_facade.h | 6 ++++ .../source/offline_compiler.cpp | 19 +++++++++---- .../compiler_interface/compiler_cache.cpp | 12 +++++++- .../compiler_interface/compiler_cache.h | 3 +- .../compiler_interface/compiler_interface.cpp | 19 +++++++++++-- .../compiler_interface/compiler_interface.h | 3 ++ .../linux/os_compiler_cache_helper.cpp | 25 +++++++++++++++++ .../os_compiler_cache_helper.h | 2 ++ .../windows/os_compiler_cache_helper.cpp | 6 ++++ .../os_interface/linux/os_library_linux.cpp | 12 +++++++- .../os_interface/linux/os_library_linux.h | 3 +- shared/source/os_interface/linux/sys_calls.h | 1 + .../os_interface/linux/sys_calls_linux.cpp | 4 +++ shared/source/os_interface/os_library.h | 3 +- .../os_interface/windows/os_library_win.cpp | 6 ++++ .../os_interface/windows/os_library_win.h | 3 +- .../test/common/mock_gdi/mock_os_library.cpp | 4 +++ shared/test/common/mock_gdi/mock_os_library.h | 3 +- shared/test/common/mocks/mock_compilers.h | 2 +- shared/test/common/mocks/mock_os_library.h | 6 +++- .../linux/sys_calls_linux_ult.cpp | 8 ++++++ .../compiler_cache_tests.cpp | 19 +++++++++---- .../os_interface/os_library_tests.cpp | 10 ++++++- 35 files changed, 240 insertions(+), 26 deletions(-) diff --git a/level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h b/level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h index e93fbd4f27..df22c15b9a 100644 --- a/level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h +++ b/level_zero/sysman/test/unit_tests/sources/firmware_util/mock_fw_util_fixture.h @@ -60,6 +60,9 @@ struct MockFwUtilOsLibrary : public OsLibrary { bool isLoaded() override { return false; } + std::string getFullPath() override { + return std::string(); + } static OsLibrary *load(const std::string &name) { if (mockLoad == true) { auto ptr = new (std::nothrow) MockFwUtilOsLibrary(); diff --git a/level_zero/sysman/test/unit_tests/sources/firmware_util/test_fw_util_helper.cpp b/level_zero/sysman/test/unit_tests/sources/firmware_util/test_fw_util_helper.cpp index 2f1bc0897b..51d62d28e8 100644 --- a/level_zero/sysman/test/unit_tests/sources/firmware_util/test_fw_util_helper.cpp +++ b/level_zero/sysman/test/unit_tests/sources/firmware_util/test_fw_util_helper.cpp @@ -145,6 +145,9 @@ TEST(FwGetProcAddressTest, GivenValidFwUtilMethodNameWhenFirmwareUtilIsInitalize return nullptr; } bool isLoaded() override { return true; } + std::string getFullPath() override { + return std::string(); + } std::map ifrFuncMap; }; uint16_t domain = 0; @@ -179,6 +182,9 @@ TEST(FwEccTest, GivenFwEccConfigCallFailsWhenCallingFirmwareUtilSetAndGetEccThen bool isLoaded() override { return false; } + std::string getFullPath() override { + return std::string(); + } std::map eccFuncMap; }; uint16_t domain = 0; @@ -218,6 +224,9 @@ TEST(LinuxFwEccTest, GivenValidFwUtilMethodWhenCallingFirmwareUtilSetAndGetEccTh bool isLoaded() override { return false; } + std::string getFullPath() override { + return std::string(); + } std::map eccFuncMap; }; uint16_t domain = 0; @@ -293,6 +302,9 @@ TEST(FwGetMemErrorCountTest, GivenValidFwUtilMethodWhenMemoryErrorCountIsRequest bool isLoaded() override { return false; } + std::string getFullPath() override { + return std::string(); + } std::map memErrFuncMap; }; L0::Sysman::FirmwareUtilImp *pFwUtilImp = new L0::Sysman::FirmwareUtilImp(0, 0, 0, 0); diff --git a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h index 28f5fcc84e..bc8b905deb 100644 --- a/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h +++ b/level_zero/sysman/test/unit_tests/sources/linux/nl_api/mock_nl_dll.h @@ -26,6 +26,9 @@ class MockNlDll : public NEO::OsLibrary { public: bool isLoaded() override { return false; } void *getProcAddress(const std::string &procName) override; + std::string getFullPath() override { + return std::string(); + } void deleteEntryPoint(const std::string &procName); diff --git a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_initialization.cpp b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_initialization.cpp index 2e0d606039..53b6cba706 100644 --- a/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_initialization.cpp +++ b/level_zero/tools/test/unit_tests/sources/metrics/test_metric_oa_initialization.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Intel Corporation + * Copyright (C) 2022-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -34,6 +34,10 @@ class MockOsLibrary : public NEO::OsLibrary { return false; } + std::string getFullPath() override { + return std::string(); + } + static OsLibrary *load(const std::string &name) { auto ptr = new (std::nothrow) MockOsLibrary(name, nullptr); if (ptr == nullptr) { diff --git a/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/mock_fw_util_fixture.h b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/mock_fw_util_fixture.h index 23c005d729..779a559014 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/mock_fw_util_fixture.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/mock_fw_util_fixture.h @@ -60,6 +60,9 @@ struct MockFwUtilOsLibrary : public OsLibrary { bool isLoaded() override { return false; } + std::string getFullPath() override { + return std::string(); + } static OsLibrary *load(const std::string &name) { if (mockLoad == true) { auto ptr = new (std::nothrow) MockFwUtilOsLibrary(); diff --git a/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/test_fw_util_helper.cpp b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/test_fw_util_helper.cpp index 1bf7c0bec8..b9a16282a6 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/test_fw_util_helper.cpp +++ b/level_zero/tools/test/unit_tests/sources/sysman/firmware_util/test_fw_util_helper.cpp @@ -157,6 +157,9 @@ TEST(FwGetProcAddressTest, GivenValidFwUtilMethodNameWhenFirmwareUtilIsInitalize return nullptr; } bool isLoaded() override { return true; } + std::string getFullPath() override { + return std::string(); + } std::map ifrFuncMap; }; uint16_t domain = 0; @@ -194,6 +197,9 @@ TEST(FwEccTest, GivenFwEccConfigCallFailsWhenCallingFirmwareUtilSetAndGetEccThen bool isLoaded() override { return false; } + std::string getFullPath() override { + return std::string(); + } std::map eccFuncMap; }; uint16_t domain = 0; @@ -236,6 +242,9 @@ TEST(LinuxFwEccTest, GivenValidFwUtilMethodWhenCallingFirmwareUtilSetAndGetEccTh bool isLoaded() override { return false; } + std::string getFullPath() override { + return std::string(); + } std::map eccFuncMap; }; uint16_t domain = 0; @@ -323,6 +332,9 @@ TEST(FwGetMemErrorCountTest, GivenValidFwUtilMethodWhenMemoryErrorCountIsRequest bool isLoaded() override { return false; } + std::string getFullPath() override { + return std::string(); + } std::map memErrFuncMap; }; FirmwareUtilImp *pFwUtilImp = new FirmwareUtilImp(0, 0, 0, 0); diff --git a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.h b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.h index 1b3b7e596e..39ca8591da 100644 --- a/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.h +++ b/level_zero/tools/test/unit_tests/sources/sysman/linux/nl_api/mock_nl_dll.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -25,6 +25,9 @@ class MockNlDll : public NEO::OsLibrary { public: bool isLoaded() override { return false; } void *getProcAddress(const std::string &procName) override; + std::string getFullPath() override { + return std::string(); + } void deleteEntryPoint(const std::string &procName); diff --git a/opencl/test/unit_test/mocks/mock_program.cpp b/opencl/test/unit_test/mocks/mock_program.cpp index 541f8493cb..845022bb02 100644 --- a/opencl/test/unit_test/mocks/mock_program.cpp +++ b/opencl/test/unit_test/mocks/mock_program.cpp @@ -34,12 +34,15 @@ int MockProgram::getInternalOptionsCalled = 0; std::string MockProgram::getCachedFileName() const { CompilerCache cache(CompilerCacheConfig{}); + std::string igcRevision = "0001"; + size_t igcLibSize = 1000; + time_t igcLibMTime = 0; auto hwInfo = this->context->getDevice(0)->getHardwareInfo(); auto input = ArrayRef(this->sourceCode.c_str(), this->sourceCode.size()); auto opts = ArrayRef(this->options.c_str(), this->options.size()); auto internalOptions = getInternalOptions(); auto internalOpts = ArrayRef(internalOptions.c_str(), internalOptions.size()); - return cache.getCachedFileName(hwInfo, input, opts, internalOpts); + return cache.getCachedFileName(hwInfo, input, opts, internalOpts, igcRevision, igcLibSize, igcLibMTime); } } // namespace NEO diff --git a/opencl/test/unit_test/os_interface/mock_performance_counters.cpp b/opencl/test/unit_test/os_interface/mock_performance_counters.cpp index 4c2cf6ba4e..93fd014ff4 100644 --- a/opencl/test/unit_test/os_interface/mock_performance_counters.cpp +++ b/opencl/test/unit_test/os_interface/mock_performance_counters.cpp @@ -134,6 +134,13 @@ bool MockMetricsLibraryDll::isLoaded() { return validIsLoaded; } +////////////////////////////////////////////////////// +// MockMetricsLibrary::getFullPath +////////////////////////////////////////////////////// +std::string MockMetricsLibraryDll::getFullPath() { + return std::string(); +} + ////////////////////////////////////////////////////// // MockMetricsLibraryValidInterface::ContextCreate ////////////////////////////////////////////////////// diff --git a/opencl/test/unit_test/os_interface/mock_performance_counters.h b/opencl/test/unit_test/os_interface/mock_performance_counters.h index a90b76d5bd..ec5cfb8f08 100644 --- a/opencl/test/unit_test/os_interface/mock_performance_counters.h +++ b/opencl/test/unit_test/os_interface/mock_performance_counters.h @@ -191,6 +191,7 @@ class MockMetricsLibraryDll : public OsLibrary { void *getProcAddress(const std::string &procName) override; bool isLoaded() override; + std::string getFullPath() override; }; ////////////////////////////////////////////////////// diff --git a/shared/offline_compiler/source/CMakeLists.txt b/shared/offline_compiler/source/CMakeLists.txt index ebb5f189e8..1f9f4c0a1e 100644 --- a/shared/offline_compiler/source/CMakeLists.txt +++ b/shared/offline_compiler/source/CMakeLists.txt @@ -136,6 +136,7 @@ endif() if(WIN32) list(APPEND CLOC_LIB_SRCS_LIB ${NEO_SHARED_DIRECTORY}/compiler_interface/windows/compiler_cache_windows.cpp + ${NEO_SHARED_DIRECTORY}/compiler_interface/windows/os_compiler_cache_helper.cpp ${NEO_SHARED_DIRECTORY}/dll/windows/options_windows.cpp ${NEO_SHARED_DIRECTORY}/os_interface/windows/os_inc.h ${NEO_SHARED_DIRECTORY}/os_interface/windows/os_library_win.cpp @@ -145,6 +146,7 @@ if(WIN32) else() list(APPEND CLOC_LIB_SRCS_LIB ${NEO_SHARED_DIRECTORY}/compiler_interface/linux/compiler_cache_linux.cpp + ${NEO_SHARED_DIRECTORY}/compiler_interface/linux/os_compiler_cache_helper.cpp ${NEO_SHARED_DIRECTORY}/dll/linux/options_linux.cpp ${NEO_SHARED_DIRECTORY}/os_interface/linux/os_inc.h ${NEO_SHARED_DIRECTORY}/os_interface/linux/os_library_linux.cpp diff --git a/shared/offline_compiler/source/ocloc_igc_facade.cpp b/shared/offline_compiler/source/ocloc_igc_facade.cpp index cb87dfda4c..50395879b4 100644 --- a/shared/offline_compiler/source/ocloc_igc_facade.cpp +++ b/shared/offline_compiler/source/ocloc_igc_facade.cpp @@ -10,9 +10,11 @@ #include "shared/offline_compiler/source/ocloc_arg_helper.h" #include "shared/offline_compiler/source/ocloc_error_code.h" #include "shared/source/compiler_interface/igc_platform_helper.h" +#include "shared/source/compiler_interface/os_compiler_cache_helper.h" #include "shared/source/helpers/compiler_product_helper.h" #include "shared/source/helpers/debug_helpers.h" #include "shared/source/helpers/hw_info.h" +#include "shared/source/helpers/string.h" #include "shared/source/os_interface/os_inc_base.h" #include "shared/source/os_interface/os_library.h" @@ -37,6 +39,10 @@ int OclocIgcFacade::initialize(const HardwareInfo &hwInfo) { return OclocErrorCode::OUT_OF_HOST_MEMORY; } + std::string igcPath = igcLib->getFullPath(); + igcLibSize = NEO::getFileSize(igcPath); + igcLibMTime = NEO::getFileModificationTime(igcPath); + const auto igcCreateMainFunction = loadCreateIgcMainFunction(); if (!igcCreateMainFunction) { argHelper->printf("Error! Cannot load required functions from IGC library.\n"); @@ -63,6 +69,16 @@ int OclocIgcFacade::initialize(const HardwareInfo &hwInfo) { return OclocErrorCode::OUT_OF_HOST_MEMORY; } + { + auto igcDeviceCtx3 = igcMain->CreateInterface>(); + if (igcDeviceCtx3) { + const char *revision = igcDeviceCtx3->GetIGCRevision(); + // revision is sha-1 hash + igcRevision.resize(41); + strncpy_s(igcRevision.data(), 41, revision, 40); + } + } + igcDeviceCtx = createIgcDeviceContext(); if (!igcDeviceCtx) { argHelper->printf("Error! Cannot create IGC device context!\n"); @@ -140,6 +156,18 @@ void OclocIgcFacade::populateWithFeatures(IGC::IgcFeaturesAndWorkaroundsTagOCL * handle->SetFtrPooledEuEnabled(hwInfo.featureTable.flags.ftrPooledEuEnabled); } +const char *OclocIgcFacade::getIgcRevision() { + return igcRevision.data(); +} + +size_t OclocIgcFacade::getIgcLibSize() { + return igcLibSize; +} + +time_t OclocIgcFacade::getIgcLibMTime() { + return igcLibMTime; +} + CIF::RAII::UPtr_t OclocIgcFacade::createConstBuffer(const void *data, size_t size) { return CIF::Builtins::CreateConstBuffer(igcMain.get(), data, size); } diff --git a/shared/offline_compiler/source/ocloc_igc_facade.h b/shared/offline_compiler/source/ocloc_igc_facade.h index e037557092..b73a8594c3 100644 --- a/shared/offline_compiler/source/ocloc_igc_facade.h +++ b/shared/offline_compiler/source/ocloc_igc_facade.h @@ -36,6 +36,9 @@ class OclocIgcFacade { int initialize(const HardwareInfo &hwInfo); bool isInitialized() const; + const char *getIgcRevision(); + size_t getIgcLibSize(); + time_t getIgcLibMTime(); CIF::RAII::UPtr_t createConstBuffer(const void *data, size_t size); CIF::RAII::UPtr_t createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType); @@ -54,6 +57,9 @@ class OclocIgcFacade { OclocArgHelper *argHelper{}; std::unique_ptr igcLib; + std::vector igcRevision; + size_t igcLibSize{0}; + time_t igcLibMTime{0}; CIF::RAII::UPtr_t igcMain; CIF::RAII::UPtr_t igcDeviceCtx; bool initialized{false}; diff --git a/shared/offline_compiler/source/offline_compiler.cpp b/shared/offline_compiler/source/offline_compiler.cpp index 22601b7258..590605df04 100644 --- a/shared/offline_compiler/source/offline_compiler.cpp +++ b/shared/offline_compiler/source/offline_compiler.cpp @@ -209,10 +209,13 @@ int OfflineCompiler::buildIrBinary() { int retVal = SUCCESS; if (allowCaching) { + const std::string igcRevision = igcFacade->getIgcRevision(); + const auto igcLibSize = igcFacade->getIgcLibSize(); + const auto igcLibMTime = igcFacade->getIgcLibMTime(); irHash = cache->getCachedFileName(getHardwareInfo(), sourceCode, options, - internalOptions); + internalOptions, igcRevision, igcLibSize, igcLibMTime); irBinary = cache->loadCachedBinary(irHash, irBinarySize).release(); if (irBinary) { return retVal; @@ -329,17 +332,20 @@ int OfflineCompiler::buildSourceCode() { } if (allowCaching) { - irHash = cache->getCachedFileName(getHardwareInfo(), sourceCode, options, internalOptions); + const std::string igcRevision = igcFacade->getIgcRevision(); + const auto igcLibSize = igcFacade->getIgcLibSize(); + const auto igcLibMTime = igcFacade->getIgcLibMTime(); + irHash = cache->getCachedFileName(getHardwareInfo(), sourceCode, options, internalOptions, igcRevision, igcLibSize, igcLibMTime); irBinary = cache->loadCachedBinary(irHash, irBinarySize).release(); - genHash = cache->getCachedFileName(getHardwareInfo(), ArrayRef(irBinary, irBinarySize), options, internalOptions); + genHash = cache->getCachedFileName(getHardwareInfo(), ArrayRef(irBinary, irBinarySize), options, internalOptions, igcRevision, igcLibSize, igcLibMTime); genBinary = cache->loadCachedBinary(genHash, genBinarySize).release(); if (irBinary && genBinary) { if (!CompilerOptions::contains(options, CompilerOptions::generateDebugInfo)) return retVal; else { - dbgHash = cache->getCachedFileName(getHardwareInfo(), irHash, options, internalOptions); + dbgHash = cache->getCachedFileName(getHardwareInfo(), irHash, options, internalOptions, igcRevision, igcLibSize, igcLibMTime); debugDataBinary = cache->loadCachedBinary(dbgHash, debugDataBinarySize).release(); if (debugDataBinary) return retVal; @@ -1121,10 +1127,13 @@ bool OfflineCompiler::generateElfBinary() { } if (allowCaching) { + const std::string igcRevision = igcFacade->getIgcRevision(); + const auto igcLibSize = igcFacade->getIgcLibSize(); + const auto igcLibMTime = igcFacade->getIgcLibMTime(); elfHash = cache->getCachedFileName(getHardwareInfo(), genHash, options, - internalOptions); + internalOptions, igcRevision, igcLibSize, igcLibMTime); auto loadedData = cache->loadCachedBinary(elfHash, elfBinarySize); elfBinary.assign(loadedData.get(), loadedData.get() + elfBinarySize); if (!elfBinary.empty()) { diff --git a/shared/source/compiler_interface/compiler_cache.cpp b/shared/source/compiler_interface/compiler_cache.cpp index a697097388..382e685ddf 100644 --- a/shared/source/compiler_interface/compiler_cache.cpp +++ b/shared/source/compiler_interface/compiler_cache.cpp @@ -29,9 +29,15 @@ namespace NEO { std::mutex CompilerCache::cacheAccessMtx; const std::string CompilerCache::getCachedFileName(const HardwareInfo &hwInfo, const ArrayRef input, - const ArrayRef options, const ArrayRef internalOptions) { + const ArrayRef options, const ArrayRef internalOptions, + const ArrayRef igcRevision, size_t igcLibSize, time_t igcLibMTime) { Hash hash; + hash.update("----", 4); + hash.update(&*igcRevision.begin(), igcRevision.size()); + hash.update(safePodCast(&igcLibSize), sizeof(igcLibSize)); + hash.update(safePodCast(&igcLibMTime), sizeof(igcLibMTime)); + hash.update("----", 4); hash.update(&*input.begin(), input.size()); hash.update("----", 4); @@ -62,6 +68,10 @@ const std::string CompilerCache::getCachedFileName(const HardwareInfo &hwInfo, c std::lock_guard lock(cacheAccessMtx); auto fp = NEO::IoFunctions::fopenPtr(traceFilePath.c_str(), "w"); if (fp) { + NEO::IoFunctions::fprintf(fp, "---- igcRevision ----\n"); + NEO::IoFunctions::fprintf(fp, "%s\n", &*igcRevision.begin()); + NEO::IoFunctions::fprintf(fp, " libSize=%d\n", igcLibSize); + NEO::IoFunctions::fprintf(fp, " libMTime=%d\n", igcLibMTime); NEO::IoFunctions::fprintf(fp, "---- input ----\n"); NEO::IoFunctions::fprintf(fp, "<%s>\n", inputFilePath.c_str()); NEO::IoFunctions::fprintf(fp, "---- options ----\n"); diff --git a/shared/source/compiler_interface/compiler_cache.h b/shared/source/compiler_interface/compiler_cache.h index beffe6620e..3cc416af44 100644 --- a/shared/source/compiler_interface/compiler_cache.h +++ b/shared/source/compiler_interface/compiler_cache.h @@ -39,7 +39,8 @@ class CompilerCache { } const std::string getCachedFileName(const HardwareInfo &hwInfo, ArrayRef input, - ArrayRef options, ArrayRef internalOptions); + ArrayRef options, ArrayRef internalOptions, + ArrayRef igcRevision, size_t igcLibSize, time_t igcLibMTime); MOCKABLE_VIRTUAL bool cacheBinary(const std::string &kernelFileHash, const char *pBinary, size_t binarySize); MOCKABLE_VIRTUAL std::unique_ptr loadCachedBinary(const std::string &kernelFileHash, size_t &cachedBinarySize); diff --git a/shared/source/compiler_interface/compiler_interface.cpp b/shared/source/compiler_interface/compiler_interface.cpp index 69fafb2d7f..b87d5bdbd7 100644 --- a/shared/source/compiler_interface/compiler_interface.cpp +++ b/shared/source/compiler_interface/compiler_interface.cpp @@ -12,6 +12,7 @@ #include "shared/source/compiler_interface/compiler_interface.inl" #include "shared/source/compiler_interface/compiler_options.h" #include "shared/source/compiler_interface/igc_platform_helper.h" +#include "shared/source/compiler_interface/os_compiler_cache_helper.h" #include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/device/device.h" #include "shared/source/helpers/compiler_product_helper.h" @@ -83,7 +84,7 @@ TranslationOutput::ErrorCode CompilerInterface::build( kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(), input.src, input.apiOptions, - input.internalOptions); + input.internalOptions, igcRevision, igcLibSize, igcLibMTime); output.deviceBinary.mem = cache->loadCachedBinary(kernelFileHash, output.deviceBinary.size); if (output.deviceBinary.mem) { return TranslationOutput::ErrorCode::Success; @@ -136,7 +137,7 @@ TranslationOutput::ErrorCode CompilerInterface::build( if (cachingMode == CachingMode::PreProcess) { kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(), ArrayRef(intermediateRepresentation->GetMemory(), intermediateRepresentation->GetSize()), input.apiOptions, - input.internalOptions); + input.internalOptions, igcRevision, igcLibSize, igcLibMTime); output.deviceBinary.mem = cache->loadCachedBinary(kernelFileHash, output.deviceBinary.size); if (output.deviceBinary.mem) { return TranslationOutput::ErrorCode::Success; @@ -374,7 +375,19 @@ bool CompilerInterface::loadFcl() { } bool CompilerInterface::loadIgc() { - return NEO::loadCompiler(Os::igcDllName, igcLib, igcMain); + bool result = NEO::loadCompiler(Os::igcDllName, igcLib, igcMain); + + if (result) { + std::string igcPath = igcLib->getFullPath(); + igcLibSize = NEO::getFileSize(igcPath); + igcLibMTime = NEO::getFileModificationTime(igcPath); + + auto igcDeviceCtx3 = igcMain->CreateInterface>(); + if (igcDeviceCtx3) { + igcRevision = igcDeviceCtx3->GetIGCRevision(); + } + } + return result; } bool CompilerInterface::initialize(std::unique_ptr &&cache, bool requireFcl) { diff --git a/shared/source/compiler_interface/compiler_interface.h b/shared/source/compiler_interface/compiler_interface.h index c9e7d03760..c357caca43 100644 --- a/shared/source/compiler_interface/compiler_interface.h +++ b/shared/source/compiler_interface/compiler_interface.h @@ -156,6 +156,9 @@ class CompilerInterface { std::unique_ptr igcLib; CIF::RAII::UPtr_t igcMain = nullptr; std::map igcDeviceContexts; + std::string igcRevision; + size_t igcLibSize; + time_t igcLibMTime; std::unique_ptr fclLib; CIF::RAII::UPtr_t fclMain = nullptr; diff --git a/shared/source/compiler_interface/linux/os_compiler_cache_helper.cpp b/shared/source/compiler_interface/linux/os_compiler_cache_helper.cpp index fa45ec3f91..353a67cc42 100644 --- a/shared/source/compiler_interface/linux/os_compiler_cache_helper.cpp +++ b/shared/source/compiler_interface/linux/os_compiler_cache_helper.cpp @@ -9,6 +9,10 @@ #include "shared/source/os_interface/linux/sys_calls.h" #include "shared/source/utilities/debug_settings_reader.h" +#include "shared/source/utilities/io_functions.h" + +#include +#include namespace NEO { bool createCompilerCachePath(std::string &cacheDir) { @@ -54,4 +58,25 @@ bool checkDefaultCacheDirSettings(std::string &cacheDir, SettingsReader *reader) return false; } + +time_t getFileModificationTime(std::string &path) { + struct stat st; + if (NEO::SysCalls::stat(path, &st) == 0) { + return st.st_mtim.tv_sec; + } + return 0; +} + +size_t getFileSize(std::string &path) { + size_t size = 0u; + FILE *fileDescriptor = NEO::IoFunctions::fopenPtr(path.c_str(), "rb"); + if (fileDescriptor == nullptr) { + return 0u; + } + + NEO::IoFunctions::fseekPtr(fileDescriptor, 0, SEEK_END); + size = NEO::IoFunctions::ftellPtr(fileDescriptor); + NEO::IoFunctions::fclosePtr(fileDescriptor); + return size; +} } // namespace NEO \ No newline at end of file diff --git a/shared/source/compiler_interface/os_compiler_cache_helper.h b/shared/source/compiler_interface/os_compiler_cache_helper.h index d29a2952af..d775dc5fcf 100644 --- a/shared/source/compiler_interface/os_compiler_cache_helper.h +++ b/shared/source/compiler_interface/os_compiler_cache_helper.h @@ -11,4 +11,6 @@ namespace NEO { class SettingsReader; bool checkDefaultCacheDirSettings(std::string &cacheDir, SettingsReader *reader); +time_t getFileModificationTime(std::string &path); +size_t getFileSize(std::string &path); } // namespace NEO \ No newline at end of file diff --git a/shared/source/compiler_interface/windows/os_compiler_cache_helper.cpp b/shared/source/compiler_interface/windows/os_compiler_cache_helper.cpp index a8c1fc3675..926838a479 100644 --- a/shared/source/compiler_interface/windows/os_compiler_cache_helper.cpp +++ b/shared/source/compiler_interface/windows/os_compiler_cache_helper.cpp @@ -11,4 +11,10 @@ namespace NEO { bool checkDefaultCacheDirSettings(std::string &cacheDir, SettingsReader *reader) { return false; } +time_t getFileModificationTime(std::string &path) { + return 0; +} +size_t getFileSize(std::string &path) { + return 0; +} } // namespace NEO \ No newline at end of file diff --git a/shared/source/os_interface/linux/os_library_linux.cpp b/shared/source/os_interface/linux/os_library_linux.cpp index 7c8f2aa9c9..d7d88050cd 100644 --- a/shared/source/os_interface/linux/os_library_linux.cpp +++ b/shared/source/os_interface/linux/os_library_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2021 Intel Corporation + * Copyright (C) 2019-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -11,6 +11,7 @@ #include "shared/source/os_interface/linux/sys_calls.h" #include +#include namespace NEO { OsLibrary *OsLibrary::load(const std::string &name) { @@ -69,5 +70,14 @@ void *OsLibrary::getProcAddress(const std::string &procName) { return dlsym(this->handle, procName.c_str()); } + +std::string OsLibrary::getFullPath() { + struct link_map *map = nullptr; + int retVal = NEO::SysCalls::dlinfo(this->handle, RTLD_DI_LINKMAP, &map); + if (retVal == 0 && map != nullptr) { + return std::string(map->l_name); + } + return std::string(); +} } // namespace Linux } // namespace NEO diff --git a/shared/source/os_interface/linux/os_library_linux.h b/shared/source/os_interface/linux/os_library_linux.h index 3cdadef270..3bf015fa3e 100644 --- a/shared/source/os_interface/linux/os_library_linux.h +++ b/shared/source/os_interface/linux/os_library_linux.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2021 Intel Corporation + * Copyright (C) 2019-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -23,6 +23,7 @@ class OsLibrary : public NEO::OsLibrary { bool isLoaded() override; void *getProcAddress(const std::string &procName) override; + std::string getFullPath() override; }; } // namespace Linux } // namespace NEO diff --git a/shared/source/os_interface/linux/sys_calls.h b/shared/source/os_interface/linux/sys_calls.h index a5c238418f..6f1f1cbc37 100644 --- a/shared/source/os_interface/linux/sys_calls.h +++ b/shared/source/os_interface/linux/sys_calls.h @@ -21,6 +21,7 @@ int mkdir(const std::string &path); int open(const char *file, int flags); int openWithMode(const char *file, int flags, int mode); void *dlopen(const char *filename, int flag); +int dlinfo(void *handle, int request, void *info); int ioctl(int fileDescriptor, unsigned long int request, void *arg); int getDevicePath(int deviceFd, char *buf, size_t &bufSize); int access(const char *pathname, int mode); diff --git a/shared/source/os_interface/linux/sys_calls_linux.cpp b/shared/source/os_interface/linux/sys_calls_linux.cpp index 4ab967409a..31a9374a53 100644 --- a/shared/source/os_interface/linux/sys_calls_linux.cpp +++ b/shared/source/os_interface/linux/sys_calls_linux.cpp @@ -72,6 +72,10 @@ void *dlopen(const char *filename, int flag) { return ::dlopen(filename, flag); } +int dlinfo(void *handle, int request, void *info) { + return ::dlinfo(handle, request, info); +} + int access(const char *pathName, int mode) { return ::access(pathName, mode); } diff --git a/shared/source/os_interface/os_library.h b/shared/source/os_interface/os_library.h index d88145646c..e688995693 100644 --- a/shared/source/os_interface/os_library.h +++ b/shared/source/os_interface/os_library.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2022 Intel Corporation + * Copyright (C) 2018-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -39,5 +39,6 @@ class OsLibrary { } virtual void *getProcAddress(const std::string &procName) = 0; virtual bool isLoaded() = 0; + virtual std::string getFullPath() = 0; }; } // namespace NEO diff --git a/shared/source/os_interface/windows/os_library_win.cpp b/shared/source/os_interface/windows/os_library_win.cpp index b073f20126..900f0985eb 100644 --- a/shared/source/os_interface/windows/os_library_win.cpp +++ b/shared/source/os_interface/windows/os_library_win.cpp @@ -98,5 +98,11 @@ bool OsLibrary::isLoaded() { void *OsLibrary::getProcAddress(const std::string &procName) { return ::GetProcAddress(this->handle, procName.c_str()); } + +std::string OsLibrary::getFullPath() { + char dllPath[MAX_PATH]; + getModuleFileNameA(GetModuleHINSTANCE(), dllPath, MAX_PATH); + return std::string(dllPath); +} } // namespace Windows } // namespace NEO diff --git a/shared/source/os_interface/windows/os_library_win.h b/shared/source/os_interface/windows/os_library_win.h index 094aa7212e..7fe198ecfb 100644 --- a/shared/source/os_interface/windows/os_library_win.h +++ b/shared/source/os_interface/windows/os_library_win.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 Intel Corporation + * Copyright (C) 2019-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -26,6 +26,7 @@ class OsLibrary : public NEO::OsLibrary { void *getProcAddress(const std::string &procName); static decltype(&GetSystemDirectoryA) getSystemDirectoryA; void getLastErrorString(std::string *errorValue); + std::string getFullPath(); protected: HMODULE loadDependency(const std::string &dependencyFileName) const; diff --git a/shared/test/common/mock_gdi/mock_os_library.cpp b/shared/test/common/mock_gdi/mock_os_library.cpp index 1396b517c8..a899df1958 100644 --- a/shared/test/common/mock_gdi/mock_os_library.cpp +++ b/shared/test/common/mock_gdi/mock_os_library.cpp @@ -14,6 +14,10 @@ bool MockOsLibrary::isLoaded() { return true; } +std::string MockOsLibrary::getFullPath() { + return std::string(); +} + void *MockOsLibrary::getProcAddress(const std::string &procName) { if (procName == "D3DKMTCreateAllocation") { return reinterpret_cast(mockD3DKMTCreateAllocation); diff --git a/shared/test/common/mock_gdi/mock_os_library.h b/shared/test/common/mock_gdi/mock_os_library.h index ae75d54d1e..17a4f0ef06 100644 --- a/shared/test/common/mock_gdi/mock_os_library.h +++ b/shared/test/common/mock_gdi/mock_os_library.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Intel Corporation + * Copyright (C) 2022-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -16,6 +16,7 @@ class MockOsLibrary : public NEO::OsLibrary { MockOsLibrary(){}; void *getProcAddress(const std::string &procName) override; bool isLoaded() override; + std::string getFullPath() override; static OsLibrary *load(const std::string &name) { return new MockOsLibrary(); diff --git a/shared/test/common/mocks/mock_compilers.h b/shared/test/common/mocks/mock_compilers.h index 828e4f8abc..04ce78604c 100644 --- a/shared/test/common/mocks/mock_compilers.h +++ b/shared/test/common/mocks/mock_compilers.h @@ -195,7 +195,7 @@ struct MockOclTranslationOutput : MockCIF { MockCIFBuffer *debugData = nullptr; }; -struct MockIgcOclDeviceCtx : MockCIF { +struct MockIgcOclDeviceCtx : MockCIF> { static CIF::ICIF *Create(CIF::InterfaceId_t intId, CIF::Version_t version); // NOLINT(readability-identifier-naming) MockIgcOclDeviceCtx(); diff --git a/shared/test/common/mocks/mock_os_library.h b/shared/test/common/mocks/mock_os_library.h index e3bf5860e3..f07ce8a295 100644 --- a/shared/test/common/mocks/mock_os_library.h +++ b/shared/test/common/mocks/mock_os_library.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Intel Corporation + * Copyright (C) 2021-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -28,6 +28,10 @@ class MockOsLibrary : public NEO::OsLibrary { return isLoadedReturn; } + std::string getFullPath() override { + return std::string(); + } + static OsLibrary *loadLibraryNewObject; static OsLibrary *load(const std::string &name) { diff --git a/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp b/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp index bf3fe41a79..6b1bb4db2f 100644 --- a/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp +++ b/shared/test/common/os_interface/linux/sys_calls_linux_ult.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -157,6 +158,13 @@ void *dlopen(const char *filename, int flag) { return ::dlopen(filename, flag); } +int dlinfo(void *handle, int request, void *info) { + if (request == RTLD_DI_LINKMAP) { + return ::dlinfo(handle, request, info); + } + return -1; +} + int ioctl(int fileDescriptor, unsigned long int request, void *arg) { if (sysCallsIoctl != nullptr) { diff --git a/shared/test/unit_test/compiler_interface/compiler_cache_tests.cpp b/shared/test/unit_test/compiler_interface/compiler_cache_tests.cpp index 800e48f8f3..d5f59101b8 100644 --- a/shared/test/unit_test/compiler_interface/compiler_cache_tests.cpp +++ b/shared/test/unit_test/compiler_interface/compiler_cache_tests.cpp @@ -129,6 +129,9 @@ TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCac HardwareInfo hwInfo = *defaultHwInfo; std::set hashes; + std::string igcRevision = "0001"; + size_t igcLibSize = 1000; + time_t igcLibMTime = 0; PLATFORM p1 = {(PRODUCT_FAMILY)1}; PLATFORM p2 = {(PRODUCT_FAMILY)2}; @@ -187,7 +190,7 @@ TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCac strcpy_s(buf3.get(), bufSize, internalOptionsArray[i3].c_str()); internalOptions = ArrayRef(buf3.get(), strlen(buf3.get())); - std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions); + std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions, igcRevision, igcLibSize, igcLibMTime); if (hashes.find(hash) != hashes.end()) { FAIL() << "failed: " << i1 << ":" << i2 << ":" << i3; @@ -200,8 +203,8 @@ TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCac } } - std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions); - std::string hash2 = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions); + std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions, igcRevision, igcLibSize, igcLibMTime); + std::string hash2 = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions, igcRevision, igcLibSize, igcLibMTime); EXPECT_STREQ(hash.c_str(), hash2.c_str()); } @@ -249,8 +252,11 @@ TEST(CompilerCacheTests, GivenBinaryCacheWhenDebugFlagIsSetThenTraceFilesAreCrea ArrayRef src; ArrayRef apiOptions; ArrayRef internalOptions; + ArrayRef revision; + size_t libSize = 0; + time_t libMTime = 0; CompilerCache cache(CompilerCacheConfig{}); - std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions); + std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions, revision, libSize, libMTime); for (size_t idx = 0; idx < sizeof(verifyData) / sizeof(verifyData[0]); idx++) { EXPECT_TRUE(verifyData[idx].matched); @@ -280,8 +286,11 @@ TEST(CompilerCacheTests, GivenBinaryCacheWhenDebugFlagIsSetAndOpenFailesThenNoCl ArrayRef src; ArrayRef apiOptions; ArrayRef internalOptions; + ArrayRef revision; + size_t libSize = 0; + time_t libMTime = 0; CompilerCache cache(CompilerCacheConfig{}); - std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions); + std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions, revision, libSize, libMTime); EXPECT_EQ(IoFunctions::mockFopenCalled, 2u); EXPECT_EQ(IoFunctions::mockFcloseCalled, 0u); diff --git a/shared/test/unit_test/os_interface/os_library_tests.cpp b/shared/test/unit_test/os_interface/os_library_tests.cpp index 31760f8f23..5ae1f1c635 100644 --- a/shared/test/unit_test/os_interface/os_library_tests.cpp +++ b/shared/test/unit_test/os_interface/os_library_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2022 Intel Corporation + * Copyright (C) 2018-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -71,6 +71,13 @@ TEST(OSLibraryTest, whenSymbolNameIsInvalidThenGetProcAddressReturnsNullPointer) EXPECT_EQ(nullptr, ptr); } +TEST(OSLibraryTest, GivenValidLibNameWhenGettingFullPathThenPathIsNotEmpty) { + std::unique_ptr library(OsLibrary::load(Os::testDllName)); + EXPECT_NE(nullptr, library); + std::string path = library->getFullPath(); + EXPECT_NE(0u, path.size()); +} + using OsLibraryTestWithFailureInjection = Test; TEST_F(OsLibraryTestWithFailureInjection, GivenFailureInjectionWhenLibraryIsLoadedThenOnlyFailedAllocationIsNull) { @@ -99,6 +106,7 @@ TEST(OsLibrary, whenCallingIndexOperatorThenObjectConvertibleToFunctionOrVoidPoi return ptrToReturn; } bool isLoaded() override { return true; } + std::string getFullPath() override { return std::string(); } void *ptrToReturn = nullptr; std::string lastRequestedProcName;