fix: extend cache hash with compiler commit sha, lib size and mtime

Related-To: NEO-4262

Signed-off-by: Kacper Kasper <kacper.k.kasper@intel.com>
This commit is contained in:
Kacper Kasper
2023-08-21 12:00:06 +00:00
committed by Compute-Runtime-Automation
parent d49190f4ae
commit 991febcdf4
35 changed files with 240 additions and 26 deletions

View File

@@ -60,6 +60,9 @@ struct MockFwUtilOsLibrary : public OsLibrary {
bool isLoaded() override { bool isLoaded() override {
return false; return false;
} }
std::string getFullPath() override {
return std::string();
}
static OsLibrary *load(const std::string &name) { static OsLibrary *load(const std::string &name) {
if (mockLoad == true) { if (mockLoad == true) {
auto ptr = new (std::nothrow) MockFwUtilOsLibrary(); auto ptr = new (std::nothrow) MockFwUtilOsLibrary();

View File

@@ -145,6 +145,9 @@ TEST(FwGetProcAddressTest, GivenValidFwUtilMethodNameWhenFirmwareUtilIsInitalize
return nullptr; return nullptr;
} }
bool isLoaded() override { return true; } bool isLoaded() override { return true; }
std::string getFullPath() override {
return std::string();
}
std::map<std::string, void *> ifrFuncMap; std::map<std::string, void *> ifrFuncMap;
}; };
uint16_t domain = 0; uint16_t domain = 0;
@@ -179,6 +182,9 @@ TEST(FwEccTest, GivenFwEccConfigCallFailsWhenCallingFirmwareUtilSetAndGetEccThen
bool isLoaded() override { bool isLoaded() override {
return false; return false;
} }
std::string getFullPath() override {
return std::string();
}
std::map<std::string, void *> eccFuncMap; std::map<std::string, void *> eccFuncMap;
}; };
uint16_t domain = 0; uint16_t domain = 0;
@@ -218,6 +224,9 @@ TEST(LinuxFwEccTest, GivenValidFwUtilMethodWhenCallingFirmwareUtilSetAndGetEccTh
bool isLoaded() override { bool isLoaded() override {
return false; return false;
} }
std::string getFullPath() override {
return std::string();
}
std::map<std::string, void *> eccFuncMap; std::map<std::string, void *> eccFuncMap;
}; };
uint16_t domain = 0; uint16_t domain = 0;
@@ -293,6 +302,9 @@ TEST(FwGetMemErrorCountTest, GivenValidFwUtilMethodWhenMemoryErrorCountIsRequest
bool isLoaded() override { bool isLoaded() override {
return false; return false;
} }
std::string getFullPath() override {
return std::string();
}
std::map<std::string, void *> memErrFuncMap; std::map<std::string, void *> memErrFuncMap;
}; };
L0::Sysman::FirmwareUtilImp *pFwUtilImp = new L0::Sysman::FirmwareUtilImp(0, 0, 0, 0); L0::Sysman::FirmwareUtilImp *pFwUtilImp = new L0::Sysman::FirmwareUtilImp(0, 0, 0, 0);

View File

@@ -26,6 +26,9 @@ class MockNlDll : public NEO::OsLibrary {
public: public:
bool isLoaded() override { return false; } bool isLoaded() override { return false; }
void *getProcAddress(const std::string &procName) override; void *getProcAddress(const std::string &procName) override;
std::string getFullPath() override {
return std::string();
}
void deleteEntryPoint(const std::string &procName); void deleteEntryPoint(const std::string &procName);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2022 Intel Corporation * Copyright (C) 2022-2023 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -34,6 +34,10 @@ class MockOsLibrary : public NEO::OsLibrary {
return false; return false;
} }
std::string getFullPath() override {
return std::string();
}
static OsLibrary *load(const std::string &name) { static OsLibrary *load(const std::string &name) {
auto ptr = new (std::nothrow) MockOsLibrary(name, nullptr); auto ptr = new (std::nothrow) MockOsLibrary(name, nullptr);
if (ptr == nullptr) { if (ptr == nullptr) {

View File

@@ -60,6 +60,9 @@ struct MockFwUtilOsLibrary : public OsLibrary {
bool isLoaded() override { bool isLoaded() override {
return false; return false;
} }
std::string getFullPath() override {
return std::string();
}
static OsLibrary *load(const std::string &name) { static OsLibrary *load(const std::string &name) {
if (mockLoad == true) { if (mockLoad == true) {
auto ptr = new (std::nothrow) MockFwUtilOsLibrary(); auto ptr = new (std::nothrow) MockFwUtilOsLibrary();

View File

@@ -157,6 +157,9 @@ TEST(FwGetProcAddressTest, GivenValidFwUtilMethodNameWhenFirmwareUtilIsInitalize
return nullptr; return nullptr;
} }
bool isLoaded() override { return true; } bool isLoaded() override { return true; }
std::string getFullPath() override {
return std::string();
}
std::map<std::string, void *> ifrFuncMap; std::map<std::string, void *> ifrFuncMap;
}; };
uint16_t domain = 0; uint16_t domain = 0;
@@ -194,6 +197,9 @@ TEST(FwEccTest, GivenFwEccConfigCallFailsWhenCallingFirmwareUtilSetAndGetEccThen
bool isLoaded() override { bool isLoaded() override {
return false; return false;
} }
std::string getFullPath() override {
return std::string();
}
std::map<std::string, void *> eccFuncMap; std::map<std::string, void *> eccFuncMap;
}; };
uint16_t domain = 0; uint16_t domain = 0;
@@ -236,6 +242,9 @@ TEST(LinuxFwEccTest, GivenValidFwUtilMethodWhenCallingFirmwareUtilSetAndGetEccTh
bool isLoaded() override { bool isLoaded() override {
return false; return false;
} }
std::string getFullPath() override {
return std::string();
}
std::map<std::string, void *> eccFuncMap; std::map<std::string, void *> eccFuncMap;
}; };
uint16_t domain = 0; uint16_t domain = 0;
@@ -323,6 +332,9 @@ TEST(FwGetMemErrorCountTest, GivenValidFwUtilMethodWhenMemoryErrorCountIsRequest
bool isLoaded() override { bool isLoaded() override {
return false; return false;
} }
std::string getFullPath() override {
return std::string();
}
std::map<std::string, void *> memErrFuncMap; std::map<std::string, void *> memErrFuncMap;
}; };
FirmwareUtilImp *pFwUtilImp = new FirmwareUtilImp(0, 0, 0, 0); FirmwareUtilImp *pFwUtilImp = new FirmwareUtilImp(0, 0, 0, 0);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2020-2022 Intel Corporation * Copyright (C) 2020-2023 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -25,6 +25,9 @@ class MockNlDll : public NEO::OsLibrary {
public: public:
bool isLoaded() override { return false; } bool isLoaded() override { return false; }
void *getProcAddress(const std::string &procName) override; void *getProcAddress(const std::string &procName) override;
std::string getFullPath() override {
return std::string();
}
void deleteEntryPoint(const std::string &procName); void deleteEntryPoint(const std::string &procName);

View File

@@ -34,12 +34,15 @@ int MockProgram::getInternalOptionsCalled = 0;
std::string MockProgram::getCachedFileName() const { std::string MockProgram::getCachedFileName() const {
CompilerCache cache(CompilerCacheConfig{}); CompilerCache cache(CompilerCacheConfig{});
std::string igcRevision = "0001";
size_t igcLibSize = 1000;
time_t igcLibMTime = 0;
auto hwInfo = this->context->getDevice(0)->getHardwareInfo(); auto hwInfo = this->context->getDevice(0)->getHardwareInfo();
auto input = ArrayRef<const char>(this->sourceCode.c_str(), this->sourceCode.size()); auto input = ArrayRef<const char>(this->sourceCode.c_str(), this->sourceCode.size());
auto opts = ArrayRef<const char>(this->options.c_str(), this->options.size()); auto opts = ArrayRef<const char>(this->options.c_str(), this->options.size());
auto internalOptions = getInternalOptions(); auto internalOptions = getInternalOptions();
auto internalOpts = ArrayRef<const char>(internalOptions.c_str(), internalOptions.size()); auto internalOpts = ArrayRef<const char>(internalOptions.c_str(), internalOptions.size());
return cache.getCachedFileName(hwInfo, input, opts, internalOpts); return cache.getCachedFileName(hwInfo, input, opts, internalOpts, igcRevision, igcLibSize, igcLibMTime);
} }
} // namespace NEO } // namespace NEO

View File

@@ -134,6 +134,13 @@ bool MockMetricsLibraryDll::isLoaded() {
return validIsLoaded; return validIsLoaded;
} }
//////////////////////////////////////////////////////
// MockMetricsLibrary::getFullPath
//////////////////////////////////////////////////////
std::string MockMetricsLibraryDll::getFullPath() {
return std::string();
}
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
// MockMetricsLibraryValidInterface::ContextCreate // MockMetricsLibraryValidInterface::ContextCreate
////////////////////////////////////////////////////// //////////////////////////////////////////////////////

View File

@@ -191,6 +191,7 @@ class MockMetricsLibraryDll : public OsLibrary {
void *getProcAddress(const std::string &procName) override; void *getProcAddress(const std::string &procName) override;
bool isLoaded() override; bool isLoaded() override;
std::string getFullPath() override;
}; };
////////////////////////////////////////////////////// //////////////////////////////////////////////////////

View File

@@ -136,6 +136,7 @@ endif()
if(WIN32) if(WIN32)
list(APPEND CLOC_LIB_SRCS_LIB list(APPEND CLOC_LIB_SRCS_LIB
${NEO_SHARED_DIRECTORY}/compiler_interface/windows/compiler_cache_windows.cpp ${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}/dll/windows/options_windows.cpp
${NEO_SHARED_DIRECTORY}/os_interface/windows/os_inc.h ${NEO_SHARED_DIRECTORY}/os_interface/windows/os_inc.h
${NEO_SHARED_DIRECTORY}/os_interface/windows/os_library_win.cpp ${NEO_SHARED_DIRECTORY}/os_interface/windows/os_library_win.cpp
@@ -145,6 +146,7 @@ if(WIN32)
else() else()
list(APPEND CLOC_LIB_SRCS_LIB list(APPEND CLOC_LIB_SRCS_LIB
${NEO_SHARED_DIRECTORY}/compiler_interface/linux/compiler_cache_linux.cpp ${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}/dll/linux/options_linux.cpp
${NEO_SHARED_DIRECTORY}/os_interface/linux/os_inc.h ${NEO_SHARED_DIRECTORY}/os_interface/linux/os_inc.h
${NEO_SHARED_DIRECTORY}/os_interface/linux/os_library_linux.cpp ${NEO_SHARED_DIRECTORY}/os_interface/linux/os_library_linux.cpp

View File

@@ -10,9 +10,11 @@
#include "shared/offline_compiler/source/ocloc_arg_helper.h" #include "shared/offline_compiler/source/ocloc_arg_helper.h"
#include "shared/offline_compiler/source/ocloc_error_code.h" #include "shared/offline_compiler/source/ocloc_error_code.h"
#include "shared/source/compiler_interface/igc_platform_helper.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/compiler_product_helper.h"
#include "shared/source/helpers/debug_helpers.h" #include "shared/source/helpers/debug_helpers.h"
#include "shared/source/helpers/hw_info.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_inc_base.h"
#include "shared/source/os_interface/os_library.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; return OclocErrorCode::OUT_OF_HOST_MEMORY;
} }
std::string igcPath = igcLib->getFullPath();
igcLibSize = NEO::getFileSize(igcPath);
igcLibMTime = NEO::getFileModificationTime(igcPath);
const auto igcCreateMainFunction = loadCreateIgcMainFunction(); const auto igcCreateMainFunction = loadCreateIgcMainFunction();
if (!igcCreateMainFunction) { if (!igcCreateMainFunction) {
argHelper->printf("Error! Cannot load required functions from IGC library.\n"); 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; return OclocErrorCode::OUT_OF_HOST_MEMORY;
} }
{
auto igcDeviceCtx3 = igcMain->CreateInterface<IGC::IgcOclDeviceCtx<3>>();
if (igcDeviceCtx3) {
const char *revision = igcDeviceCtx3->GetIGCRevision();
// revision is sha-1 hash
igcRevision.resize(41);
strncpy_s(igcRevision.data(), 41, revision, 40);
}
}
igcDeviceCtx = createIgcDeviceContext(); igcDeviceCtx = createIgcDeviceContext();
if (!igcDeviceCtx) { if (!igcDeviceCtx) {
argHelper->printf("Error! Cannot create IGC device context!\n"); argHelper->printf("Error! Cannot create IGC device context!\n");
@@ -140,6 +156,18 @@ void OclocIgcFacade::populateWithFeatures(IGC::IgcFeaturesAndWorkaroundsTagOCL *
handle->SetFtrPooledEuEnabled(hwInfo.featureTable.flags.ftrPooledEuEnabled); 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<CIF::Builtins::BufferLatest> OclocIgcFacade::createConstBuffer(const void *data, size_t size) { CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> OclocIgcFacade::createConstBuffer(const void *data, size_t size) {
return CIF::Builtins::CreateConstBuffer(igcMain.get(), data, size); return CIF::Builtins::CreateConstBuffer(igcMain.get(), data, size);
} }

View File

@@ -36,6 +36,9 @@ class OclocIgcFacade {
int initialize(const HardwareInfo &hwInfo); int initialize(const HardwareInfo &hwInfo);
bool isInitialized() const; bool isInitialized() const;
const char *getIgcRevision();
size_t getIgcLibSize();
time_t getIgcLibMTime();
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> createConstBuffer(const void *data, size_t size); CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> createConstBuffer(const void *data, size_t size);
CIF::RAII::UPtr_t<IGC::IgcOclTranslationCtxTagOCL> createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType); CIF::RAII::UPtr_t<IGC::IgcOclTranslationCtxTagOCL> createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType);
@@ -54,6 +57,9 @@ class OclocIgcFacade {
OclocArgHelper *argHelper{}; OclocArgHelper *argHelper{};
std::unique_ptr<OsLibrary> igcLib; std::unique_ptr<OsLibrary> igcLib;
std::vector<char> igcRevision;
size_t igcLibSize{0};
time_t igcLibMTime{0};
CIF::RAII::UPtr_t<CIF::CIFMain> igcMain; CIF::RAII::UPtr_t<CIF::CIFMain> igcMain;
CIF::RAII::UPtr_t<IGC::IgcOclDeviceCtxTagOCL> igcDeviceCtx; CIF::RAII::UPtr_t<IGC::IgcOclDeviceCtxTagOCL> igcDeviceCtx;
bool initialized{false}; bool initialized{false};

View File

@@ -209,10 +209,13 @@ int OfflineCompiler::buildIrBinary() {
int retVal = SUCCESS; int retVal = SUCCESS;
if (allowCaching) { if (allowCaching) {
const std::string igcRevision = igcFacade->getIgcRevision();
const auto igcLibSize = igcFacade->getIgcLibSize();
const auto igcLibMTime = igcFacade->getIgcLibMTime();
irHash = cache->getCachedFileName(getHardwareInfo(), irHash = cache->getCachedFileName(getHardwareInfo(),
sourceCode, sourceCode,
options, options,
internalOptions); internalOptions, igcRevision, igcLibSize, igcLibMTime);
irBinary = cache->loadCachedBinary(irHash, irBinarySize).release(); irBinary = cache->loadCachedBinary(irHash, irBinarySize).release();
if (irBinary) { if (irBinary) {
return retVal; return retVal;
@@ -329,17 +332,20 @@ int OfflineCompiler::buildSourceCode() {
} }
if (allowCaching) { 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(); irBinary = cache->loadCachedBinary(irHash, irBinarySize).release();
genHash = cache->getCachedFileName(getHardwareInfo(), ArrayRef<const char>(irBinary, irBinarySize), options, internalOptions); genHash = cache->getCachedFileName(getHardwareInfo(), ArrayRef<const char>(irBinary, irBinarySize), options, internalOptions, igcRevision, igcLibSize, igcLibMTime);
genBinary = cache->loadCachedBinary(genHash, genBinarySize).release(); genBinary = cache->loadCachedBinary(genHash, genBinarySize).release();
if (irBinary && genBinary) { if (irBinary && genBinary) {
if (!CompilerOptions::contains(options, CompilerOptions::generateDebugInfo)) if (!CompilerOptions::contains(options, CompilerOptions::generateDebugInfo))
return retVal; return retVal;
else { else {
dbgHash = cache->getCachedFileName(getHardwareInfo(), irHash, options, internalOptions); dbgHash = cache->getCachedFileName(getHardwareInfo(), irHash, options, internalOptions, igcRevision, igcLibSize, igcLibMTime);
debugDataBinary = cache->loadCachedBinary(dbgHash, debugDataBinarySize).release(); debugDataBinary = cache->loadCachedBinary(dbgHash, debugDataBinarySize).release();
if (debugDataBinary) if (debugDataBinary)
return retVal; return retVal;
@@ -1121,10 +1127,13 @@ bool OfflineCompiler::generateElfBinary() {
} }
if (allowCaching) { if (allowCaching) {
const std::string igcRevision = igcFacade->getIgcRevision();
const auto igcLibSize = igcFacade->getIgcLibSize();
const auto igcLibMTime = igcFacade->getIgcLibMTime();
elfHash = cache->getCachedFileName(getHardwareInfo(), elfHash = cache->getCachedFileName(getHardwareInfo(),
genHash, genHash,
options, options,
internalOptions); internalOptions, igcRevision, igcLibSize, igcLibMTime);
auto loadedData = cache->loadCachedBinary(elfHash, elfBinarySize); auto loadedData = cache->loadCachedBinary(elfHash, elfBinarySize);
elfBinary.assign(loadedData.get(), loadedData.get() + elfBinarySize); elfBinary.assign(loadedData.get(), loadedData.get() + elfBinarySize);
if (!elfBinary.empty()) { if (!elfBinary.empty()) {

View File

@@ -29,9 +29,15 @@ namespace NEO {
std::mutex CompilerCache::cacheAccessMtx; std::mutex CompilerCache::cacheAccessMtx;
const std::string CompilerCache::getCachedFileName(const HardwareInfo &hwInfo, const ArrayRef<const char> input, const std::string CompilerCache::getCachedFileName(const HardwareInfo &hwInfo, const ArrayRef<const char> input,
const ArrayRef<const char> options, const ArrayRef<const char> internalOptions) { const ArrayRef<const char> options, const ArrayRef<const char> internalOptions,
const ArrayRef<const char> igcRevision, size_t igcLibSize, time_t igcLibMTime) {
Hash hash; Hash hash;
hash.update("----", 4);
hash.update(&*igcRevision.begin(), igcRevision.size());
hash.update(safePodCast<const char *>(&igcLibSize), sizeof(igcLibSize));
hash.update(safePodCast<const char *>(&igcLibMTime), sizeof(igcLibMTime));
hash.update("----", 4); hash.update("----", 4);
hash.update(&*input.begin(), input.size()); hash.update(&*input.begin(), input.size());
hash.update("----", 4); hash.update("----", 4);
@@ -62,6 +68,10 @@ const std::string CompilerCache::getCachedFileName(const HardwareInfo &hwInfo, c
std::lock_guard<std::mutex> lock(cacheAccessMtx); std::lock_guard<std::mutex> lock(cacheAccessMtx);
auto fp = NEO::IoFunctions::fopenPtr(traceFilePath.c_str(), "w"); auto fp = NEO::IoFunctions::fopenPtr(traceFilePath.c_str(), "w");
if (fp) { 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, "---- input ----\n");
NEO::IoFunctions::fprintf(fp, "<%s>\n", inputFilePath.c_str()); NEO::IoFunctions::fprintf(fp, "<%s>\n", inputFilePath.c_str());
NEO::IoFunctions::fprintf(fp, "---- options ----\n"); NEO::IoFunctions::fprintf(fp, "---- options ----\n");

View File

@@ -39,7 +39,8 @@ class CompilerCache {
} }
const std::string getCachedFileName(const HardwareInfo &hwInfo, ArrayRef<const char> input, const std::string getCachedFileName(const HardwareInfo &hwInfo, ArrayRef<const char> input,
ArrayRef<const char> options, ArrayRef<const char> internalOptions); ArrayRef<const char> options, ArrayRef<const char> internalOptions,
ArrayRef<const char> igcRevision, size_t igcLibSize, time_t igcLibMTime);
MOCKABLE_VIRTUAL bool cacheBinary(const std::string &kernelFileHash, const char *pBinary, size_t binarySize); MOCKABLE_VIRTUAL bool cacheBinary(const std::string &kernelFileHash, const char *pBinary, size_t binarySize);
MOCKABLE_VIRTUAL std::unique_ptr<char[]> loadCachedBinary(const std::string &kernelFileHash, size_t &cachedBinarySize); MOCKABLE_VIRTUAL std::unique_ptr<char[]> loadCachedBinary(const std::string &kernelFileHash, size_t &cachedBinarySize);

View File

@@ -12,6 +12,7 @@
#include "shared/source/compiler_interface/compiler_interface.inl" #include "shared/source/compiler_interface/compiler_interface.inl"
#include "shared/source/compiler_interface/compiler_options.h" #include "shared/source/compiler_interface/compiler_options.h"
#include "shared/source/compiler_interface/igc_platform_helper.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/debug_settings/debug_settings_manager.h"
#include "shared/source/device/device.h" #include "shared/source/device/device.h"
#include "shared/source/helpers/compiler_product_helper.h" #include "shared/source/helpers/compiler_product_helper.h"
@@ -83,7 +84,7 @@ TranslationOutput::ErrorCode CompilerInterface::build(
kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(), kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(),
input.src, input.src,
input.apiOptions, input.apiOptions,
input.internalOptions); input.internalOptions, igcRevision, igcLibSize, igcLibMTime);
output.deviceBinary.mem = cache->loadCachedBinary(kernelFileHash, output.deviceBinary.size); output.deviceBinary.mem = cache->loadCachedBinary(kernelFileHash, output.deviceBinary.size);
if (output.deviceBinary.mem) { if (output.deviceBinary.mem) {
return TranslationOutput::ErrorCode::Success; return TranslationOutput::ErrorCode::Success;
@@ -136,7 +137,7 @@ TranslationOutput::ErrorCode CompilerInterface::build(
if (cachingMode == CachingMode::PreProcess) { if (cachingMode == CachingMode::PreProcess) {
kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(), ArrayRef<const char>(intermediateRepresentation->GetMemory<char>(), intermediateRepresentation->GetSize<char>()), kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(), ArrayRef<const char>(intermediateRepresentation->GetMemory<char>(), intermediateRepresentation->GetSize<char>()),
input.apiOptions, input.apiOptions,
input.internalOptions); input.internalOptions, igcRevision, igcLibSize, igcLibMTime);
output.deviceBinary.mem = cache->loadCachedBinary(kernelFileHash, output.deviceBinary.size); output.deviceBinary.mem = cache->loadCachedBinary(kernelFileHash, output.deviceBinary.size);
if (output.deviceBinary.mem) { if (output.deviceBinary.mem) {
return TranslationOutput::ErrorCode::Success; return TranslationOutput::ErrorCode::Success;
@@ -374,7 +375,19 @@ bool CompilerInterface::loadFcl() {
} }
bool CompilerInterface::loadIgc() { bool CompilerInterface::loadIgc() {
return NEO::loadCompiler<IGC::IgcOclDeviceCtx>(Os::igcDllName, igcLib, igcMain); bool result = NEO::loadCompiler<IGC::IgcOclDeviceCtx>(Os::igcDllName, igcLib, igcMain);
if (result) {
std::string igcPath = igcLib->getFullPath();
igcLibSize = NEO::getFileSize(igcPath);
igcLibMTime = NEO::getFileModificationTime(igcPath);
auto igcDeviceCtx3 = igcMain->CreateInterface<IGC::IgcOclDeviceCtx<3>>();
if (igcDeviceCtx3) {
igcRevision = igcDeviceCtx3->GetIGCRevision();
}
}
return result;
} }
bool CompilerInterface::initialize(std::unique_ptr<CompilerCache> &&cache, bool requireFcl) { bool CompilerInterface::initialize(std::unique_ptr<CompilerCache> &&cache, bool requireFcl) {

View File

@@ -156,6 +156,9 @@ class CompilerInterface {
std::unique_ptr<OsLibrary> igcLib; std::unique_ptr<OsLibrary> igcLib;
CIF::RAII::UPtr_t<CIF::CIFMain> igcMain = nullptr; CIF::RAII::UPtr_t<CIF::CIFMain> igcMain = nullptr;
std::map<const Device *, igcDevCtxUptr> igcDeviceContexts; std::map<const Device *, igcDevCtxUptr> igcDeviceContexts;
std::string igcRevision;
size_t igcLibSize;
time_t igcLibMTime;
std::unique_ptr<OsLibrary> fclLib; std::unique_ptr<OsLibrary> fclLib;
CIF::RAII::UPtr_t<CIF::CIFMain> fclMain = nullptr; CIF::RAII::UPtr_t<CIF::CIFMain> fclMain = nullptr;

View File

@@ -9,6 +9,10 @@
#include "shared/source/os_interface/linux/sys_calls.h" #include "shared/source/os_interface/linux/sys_calls.h"
#include "shared/source/utilities/debug_settings_reader.h" #include "shared/source/utilities/debug_settings_reader.h"
#include "shared/source/utilities/io_functions.h"
#include <dlfcn.h>
#include <link.h>
namespace NEO { namespace NEO {
bool createCompilerCachePath(std::string &cacheDir) { bool createCompilerCachePath(std::string &cacheDir) {
@@ -54,4 +58,25 @@ bool checkDefaultCacheDirSettings(std::string &cacheDir, SettingsReader *reader)
return false; 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 } // namespace NEO

View File

@@ -11,4 +11,6 @@
namespace NEO { namespace NEO {
class SettingsReader; class SettingsReader;
bool checkDefaultCacheDirSettings(std::string &cacheDir, SettingsReader *reader); bool checkDefaultCacheDirSettings(std::string &cacheDir, SettingsReader *reader);
time_t getFileModificationTime(std::string &path);
size_t getFileSize(std::string &path);
} // namespace NEO } // namespace NEO

View File

@@ -11,4 +11,10 @@ namespace NEO {
bool checkDefaultCacheDirSettings(std::string &cacheDir, SettingsReader *reader) { bool checkDefaultCacheDirSettings(std::string &cacheDir, SettingsReader *reader) {
return false; return false;
} }
time_t getFileModificationTime(std::string &path) {
return 0;
}
size_t getFileSize(std::string &path) {
return 0;
}
} // namespace NEO } // namespace NEO

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019-2021 Intel Corporation * Copyright (C) 2019-2023 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -11,6 +11,7 @@
#include "shared/source/os_interface/linux/sys_calls.h" #include "shared/source/os_interface/linux/sys_calls.h"
#include <dlfcn.h> #include <dlfcn.h>
#include <link.h>
namespace NEO { namespace NEO {
OsLibrary *OsLibrary::load(const std::string &name) { 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()); 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 Linux
} // namespace NEO } // namespace NEO

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019-2021 Intel Corporation * Copyright (C) 2019-2023 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -23,6 +23,7 @@ class OsLibrary : public NEO::OsLibrary {
bool isLoaded() override; bool isLoaded() override;
void *getProcAddress(const std::string &procName) override; void *getProcAddress(const std::string &procName) override;
std::string getFullPath() override;
}; };
} // namespace Linux } // namespace Linux
} // namespace NEO } // namespace NEO

View File

@@ -21,6 +21,7 @@ int mkdir(const std::string &path);
int open(const char *file, int flags); int open(const char *file, int flags);
int openWithMode(const char *file, int flags, int mode); int openWithMode(const char *file, int flags, int mode);
void *dlopen(const char *filename, int flag); 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 ioctl(int fileDescriptor, unsigned long int request, void *arg);
int getDevicePath(int deviceFd, char *buf, size_t &bufSize); int getDevicePath(int deviceFd, char *buf, size_t &bufSize);
int access(const char *pathname, int mode); int access(const char *pathname, int mode);

View File

@@ -72,6 +72,10 @@ void *dlopen(const char *filename, int flag) {
return ::dlopen(filename, 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) { int access(const char *pathName, int mode) {
return ::access(pathName, mode); return ::access(pathName, mode);
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2022 Intel Corporation * Copyright (C) 2018-2023 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -39,5 +39,6 @@ class OsLibrary {
} }
virtual void *getProcAddress(const std::string &procName) = 0; virtual void *getProcAddress(const std::string &procName) = 0;
virtual bool isLoaded() = 0; virtual bool isLoaded() = 0;
virtual std::string getFullPath() = 0;
}; };
} // namespace NEO } // namespace NEO

View File

@@ -98,5 +98,11 @@ bool OsLibrary::isLoaded() {
void *OsLibrary::getProcAddress(const std::string &procName) { void *OsLibrary::getProcAddress(const std::string &procName) {
return ::GetProcAddress(this->handle, procName.c_str()); 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 Windows
} // namespace NEO } // namespace NEO

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019-2022 Intel Corporation * Copyright (C) 2019-2023 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -26,6 +26,7 @@ class OsLibrary : public NEO::OsLibrary {
void *getProcAddress(const std::string &procName); void *getProcAddress(const std::string &procName);
static decltype(&GetSystemDirectoryA) getSystemDirectoryA; static decltype(&GetSystemDirectoryA) getSystemDirectoryA;
void getLastErrorString(std::string *errorValue); void getLastErrorString(std::string *errorValue);
std::string getFullPath();
protected: protected:
HMODULE loadDependency(const std::string &dependencyFileName) const; HMODULE loadDependency(const std::string &dependencyFileName) const;

View File

@@ -14,6 +14,10 @@ bool MockOsLibrary::isLoaded() {
return true; return true;
} }
std::string MockOsLibrary::getFullPath() {
return std::string();
}
void *MockOsLibrary::getProcAddress(const std::string &procName) { void *MockOsLibrary::getProcAddress(const std::string &procName) {
if (procName == "D3DKMTCreateAllocation") { if (procName == "D3DKMTCreateAllocation") {
return reinterpret_cast<void *>(mockD3DKMTCreateAllocation); return reinterpret_cast<void *>(mockD3DKMTCreateAllocation);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2022 Intel Corporation * Copyright (C) 2022-2023 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -16,6 +16,7 @@ class MockOsLibrary : public NEO::OsLibrary {
MockOsLibrary(){}; MockOsLibrary(){};
void *getProcAddress(const std::string &procName) override; void *getProcAddress(const std::string &procName) override;
bool isLoaded() override; bool isLoaded() override;
std::string getFullPath() override;
static OsLibrary *load(const std::string &name) { static OsLibrary *load(const std::string &name) {
return new MockOsLibrary(); return new MockOsLibrary();

View File

@@ -195,7 +195,7 @@ struct MockOclTranslationOutput : MockCIF<IGC::OclTranslationOutputTagOCL> {
MockCIFBuffer *debugData = nullptr; MockCIFBuffer *debugData = nullptr;
}; };
struct MockIgcOclDeviceCtx : MockCIF<IGC::IgcOclDeviceCtxTagOCL> { struct MockIgcOclDeviceCtx : MockCIF<IGC::IgcOclDeviceCtx<3>> {
static CIF::ICIF *Create(CIF::InterfaceId_t intId, CIF::Version_t version); // NOLINT(readability-identifier-naming) static CIF::ICIF *Create(CIF::InterfaceId_t intId, CIF::Version_t version); // NOLINT(readability-identifier-naming)
MockIgcOclDeviceCtx(); MockIgcOclDeviceCtx();

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2021-2022 Intel Corporation * Copyright (C) 2021-2023 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -28,6 +28,10 @@ class MockOsLibrary : public NEO::OsLibrary {
return isLoadedReturn; return isLoadedReturn;
} }
std::string getFullPath() override {
return std::string();
}
static OsLibrary *loadLibraryNewObject; static OsLibrary *loadLibraryNewObject;
static OsLibrary *load(const std::string &name) { static OsLibrary *load(const std::string &name) {

View File

@@ -21,6 +21,7 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <fcntl.h> #include <fcntl.h>
#include <iostream> #include <iostream>
#include <link.h>
#include <poll.h> #include <poll.h>
#include <string.h> #include <string.h>
#include <string_view> #include <string_view>
@@ -157,6 +158,13 @@ void *dlopen(const char *filename, int flag) {
return ::dlopen(filename, 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) { int ioctl(int fileDescriptor, unsigned long int request, void *arg) {
if (sysCallsIoctl != nullptr) { if (sysCallsIoctl != nullptr) {

View File

@@ -129,6 +129,9 @@ TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCac
HardwareInfo hwInfo = *defaultHwInfo; HardwareInfo hwInfo = *defaultHwInfo;
std::set<std::string> hashes; std::set<std::string> hashes;
std::string igcRevision = "0001";
size_t igcLibSize = 1000;
time_t igcLibMTime = 0;
PLATFORM p1 = {(PRODUCT_FAMILY)1}; PLATFORM p1 = {(PRODUCT_FAMILY)1};
PLATFORM p2 = {(PRODUCT_FAMILY)2}; PLATFORM p2 = {(PRODUCT_FAMILY)2};
@@ -187,7 +190,7 @@ TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCac
strcpy_s(buf3.get(), bufSize, internalOptionsArray[i3].c_str()); strcpy_s(buf3.get(), bufSize, internalOptionsArray[i3].c_str());
internalOptions = ArrayRef<char>(buf3.get(), strlen(buf3.get())); internalOptions = ArrayRef<char>(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()) { if (hashes.find(hash) != hashes.end()) {
FAIL() << "failed: " << i1 << ":" << i2 << ":" << i3; FAIL() << "failed: " << i1 << ":" << i2 << ":" << i3;
@@ -200,8 +203,8 @@ TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCac
} }
} }
std::string hash = 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); std::string hash2 = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions, igcRevision, igcLibSize, igcLibMTime);
EXPECT_STREQ(hash.c_str(), hash2.c_str()); EXPECT_STREQ(hash.c_str(), hash2.c_str());
} }
@@ -249,8 +252,11 @@ TEST(CompilerCacheTests, GivenBinaryCacheWhenDebugFlagIsSetThenTraceFilesAreCrea
ArrayRef<char> src; ArrayRef<char> src;
ArrayRef<char> apiOptions; ArrayRef<char> apiOptions;
ArrayRef<char> internalOptions; ArrayRef<char> internalOptions;
ArrayRef<char> revision;
size_t libSize = 0;
time_t libMTime = 0;
CompilerCache cache(CompilerCacheConfig{}); 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++) { for (size_t idx = 0; idx < sizeof(verifyData) / sizeof(verifyData[0]); idx++) {
EXPECT_TRUE(verifyData[idx].matched); EXPECT_TRUE(verifyData[idx].matched);
@@ -280,8 +286,11 @@ TEST(CompilerCacheTests, GivenBinaryCacheWhenDebugFlagIsSetAndOpenFailesThenNoCl
ArrayRef<char> src; ArrayRef<char> src;
ArrayRef<char> apiOptions; ArrayRef<char> apiOptions;
ArrayRef<char> internalOptions; ArrayRef<char> internalOptions;
ArrayRef<char> revision;
size_t libSize = 0;
time_t libMTime = 0;
CompilerCache cache(CompilerCacheConfig{}); 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::mockFopenCalled, 2u);
EXPECT_EQ(IoFunctions::mockFcloseCalled, 0u); EXPECT_EQ(IoFunctions::mockFcloseCalled, 0u);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018-2022 Intel Corporation * Copyright (C) 2018-2023 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -71,6 +71,13 @@ TEST(OSLibraryTest, whenSymbolNameIsInvalidThenGetProcAddressReturnsNullPointer)
EXPECT_EQ(nullptr, ptr); EXPECT_EQ(nullptr, ptr);
} }
TEST(OSLibraryTest, GivenValidLibNameWhenGettingFullPathThenPathIsNotEmpty) {
std::unique_ptr<OsLibrary> library(OsLibrary::load(Os::testDllName));
EXPECT_NE(nullptr, library);
std::string path = library->getFullPath();
EXPECT_NE(0u, path.size());
}
using OsLibraryTestWithFailureInjection = Test<MemoryManagementFixture>; using OsLibraryTestWithFailureInjection = Test<MemoryManagementFixture>;
TEST_F(OsLibraryTestWithFailureInjection, GivenFailureInjectionWhenLibraryIsLoadedThenOnlyFailedAllocationIsNull) { TEST_F(OsLibraryTestWithFailureInjection, GivenFailureInjectionWhenLibraryIsLoadedThenOnlyFailedAllocationIsNull) {
@@ -99,6 +106,7 @@ TEST(OsLibrary, whenCallingIndexOperatorThenObjectConvertibleToFunctionOrVoidPoi
return ptrToReturn; return ptrToReturn;
} }
bool isLoaded() override { return true; } bool isLoaded() override { return true; }
std::string getFullPath() override { return std::string(); }
void *ptrToReturn = nullptr; void *ptrToReturn = nullptr;
std::string lastRequestedProcName; std::string lastRequestedProcName;