diff --git a/core/compiler_interface/CMakeLists.txt b/core/compiler_interface/CMakeLists.txt index 91909c1d72..83f82aafb5 100644 --- a/core/compiler_interface/CMakeLists.txt +++ b/core/compiler_interface/CMakeLists.txt @@ -6,6 +6,8 @@ set(NEO_COMPILER_INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/compiler_cache.h + ${CMAKE_CURRENT_SOURCE_DIR}/compiler_cache.cpp ${CMAKE_CURRENT_SOURCE_DIR}/linker.h ${CMAKE_CURRENT_SOURCE_DIR}/linker.cpp ) diff --git a/runtime/compiler_interface/binary_cache.cpp b/core/compiler_interface/compiler_cache.cpp similarity index 57% rename from runtime/compiler_interface/binary_cache.cpp rename to core/compiler_interface/compiler_cache.cpp index c1a8357411..59382d9581 100644 --- a/runtime/compiler_interface/binary_cache.cpp +++ b/core/compiler_interface/compiler_cache.cpp @@ -5,15 +5,13 @@ * */ -#include "runtime/compiler_interface/binary_cache.h" +#include "core/compiler_interface/compiler_cache.h" #include "core/helpers/aligned_memory.h" #include "core/helpers/file_io.h" #include "core/helpers/hash.h" #include "core/utilities/debug_settings_reader.h" #include "runtime/helpers/hw_info.h" -#include "runtime/os_interface/ocl_reg_path.h" -#include "runtime/os_interface/os_inc_base.h" #include "config.h" #include "os_inc.h" @@ -25,9 +23,9 @@ #include namespace NEO { -std::mutex BinaryCache::cacheAccessMtx; -const std::string BinaryCache::getCachedFileName(const HardwareInfo &hwInfo, const ArrayRef input, - const ArrayRef options, const ArrayRef internalOptions) { +std::mutex CompilerCache::cacheAccessMtx; +const std::string CompilerCache::getCachedFileName(const HardwareInfo &hwInfo, const ArrayRef input, + const ArrayRef options, const ArrayRef internalOptions) { Hash hash; hash.update("----", 4); @@ -53,26 +51,20 @@ const std::string BinaryCache::getCachedFileName(const HardwareInfo &hwInfo, con return stream.str(); } -BinaryCache::BinaryCache() { - std::string keyName = oclRegPath; - keyName += "cl_cache_dir"; - std::unique_ptr settingsReader(SettingsReader::createOsReader(false, keyName)); - clCacheLocation = settingsReader->getSetting(settingsReader->appSpecificLocation(keyName), static_cast(CL_CACHE_LOCATION)); -}; +CompilerCache::CompilerCache(const CompilerCacheConfig &cacheConfig) + : config(cacheConfig){}; -BinaryCache::~BinaryCache(){}; - -bool BinaryCache::cacheBinary(const std::string kernelFileHash, const char *pBinary, uint32_t binarySize) { +bool CompilerCache::cacheBinary(const std::string kernelFileHash, const char *pBinary, uint32_t binarySize) { if (pBinary == nullptr || binarySize == 0) { return false; } - std::string filePath = clCacheLocation + PATH_SEPARATOR + kernelFileHash + ".cl_cache"; + std::string filePath = config.cacheDir + PATH_SEPARATOR + kernelFileHash + config.cacheFileExtension; std::lock_guard lock(cacheAccessMtx); return 0 != writeDataToFile(filePath.c_str(), pBinary, binarySize); } -std::unique_ptr BinaryCache::loadCachedBinary(const std::string kernelFileHash, size_t &cachedBinarySize) { - std::string filePath = clCacheLocation + PATH_SEPARATOR + kernelFileHash + ".cl_cache"; +std::unique_ptr CompilerCache::loadCachedBinary(const std::string kernelFileHash, size_t &cachedBinarySize) { + std::string filePath = config.cacheDir + PATH_SEPARATOR + kernelFileHash + config.cacheFileExtension; std::lock_guard lock(cacheAccessMtx); return loadDataFromFile(filePath.c_str(), cachedBinarySize); diff --git a/core/compiler_interface/compiler_cache.h b/core/compiler_interface/compiler_cache.h new file mode 100644 index 0000000000..4b6ab49c69 --- /dev/null +++ b/core/compiler_interface/compiler_cache.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017-2019 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "core/utilities/arrayref.h" + +#include +#include +#include +#include +#include + +namespace NEO { +struct HardwareInfo; + +struct CompilerCacheConfig { + bool enabled = true; + std::string cacheFileExtension; + std::string cacheDir; +}; + +class CompilerCache { + public: + static const std::string getCachedFileName(const HardwareInfo &hwInfo, ArrayRef input, + ArrayRef options, ArrayRef internalOptions); + + CompilerCache(const CompilerCacheConfig &config); + virtual ~CompilerCache() = default; + + CompilerCache(const CompilerCache &) = delete; + CompilerCache(CompilerCache &&) = delete; + CompilerCache &operator=(const CompilerCache &) = delete; + CompilerCache &operator=(CompilerCache &&) = delete; + + MOCKABLE_VIRTUAL bool cacheBinary(const std::string kernelFileHash, const char *pBinary, uint32_t binarySize); + MOCKABLE_VIRTUAL std::unique_ptr loadCachedBinary(const std::string kernelFileHash, size_t &cachedBinarySize); + + protected: + static std::mutex cacheAccessMtx; + CompilerCacheConfig config; +}; +} // namespace NEO diff --git a/core/unit_tests/compiler_interface/CMakeLists.txt b/core/unit_tests/compiler_interface/CMakeLists.txt index 176f9d095f..7c0d7ba193 100644 --- a/core/unit_tests/compiler_interface/CMakeLists.txt +++ b/core/unit_tests/compiler_interface/CMakeLists.txt @@ -6,8 +6,9 @@ set(NEO_CORE_COMPILER_INTERFACE_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/compiler_cache_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/linker_mock.h ${CMAKE_CURRENT_SOURCE_DIR}/linker_tests.cpp ) -set_property(GLOBAL PROPERTY NEO_CORE_COMPILER_INTERFACE_TESTS ${NEO_CORE_COMPILER_INTERFACE_TESTS}) \ No newline at end of file +set_property(GLOBAL PROPERTY NEO_CORE_COMPILER_INTERFACE_TESTS ${NEO_CORE_COMPILER_INTERFACE_TESTS}) diff --git a/unit_tests/compiler_interface/binary_cache_tests.cpp b/core/unit_tests/compiler_interface/compiler_cache_tests.cpp similarity index 54% rename from unit_tests/compiler_interface/binary_cache_tests.cpp rename to core/unit_tests/compiler_interface/compiler_cache_tests.cpp index df1aa590ae..6d7e1f67b6 100644 --- a/unit_tests/compiler_interface/binary_cache_tests.cpp +++ b/core/unit_tests/compiler_interface/compiler_cache_tests.cpp @@ -5,11 +5,12 @@ * */ +#include "core/compiler_interface/compiler_cache.h" #include "core/helpers/aligned_memory.h" #include "core/helpers/hash.h" #include "core/helpers/string.h" -#include "runtime/compiler_interface/binary_cache.h" #include "runtime/compiler_interface/compiler_interface.h" +#include "runtime/compiler_interface/default_cl_cache_config.h" #include "runtime/helpers/hw_info.h" #include "test.h" #include "unit_tests/fixtures/device_fixture.h" @@ -24,23 +25,9 @@ using namespace NEO; using namespace std; -class BinaryCacheFixture - -{ +class CompilerCacheMock : public CompilerCache { public: - void SetUp() { - cache = new BinaryCache; - } - - void TearDown() { - delete cache; - } - BinaryCache *cache; -}; - -class BinaryCacheMock : public BinaryCache { - public: - BinaryCacheMock() { + CompilerCacheMock() : CompilerCache(CompilerCacheConfig{}) { } bool cacheBinary(const std::string kernelFileHash, const char *pBinary, uint32_t binarySize) override { @@ -57,25 +44,6 @@ class BinaryCacheMock : public BinaryCache { bool loadResult = false; }; -class CompilerInterfaceCachedFixture : public DeviceFixture { - public: - void SetUp() { - DeviceFixture::SetUp(); - pCompilerInterface = pDevice->getExecutionEnvironment()->getCompilerInterface(); - ASSERT_NE(pCompilerInterface, nullptr); - } - - void TearDown() { - DeviceFixture::TearDown(); - } - - CompilerInterface *pCompilerInterface; -}; - -typedef Test BinaryCacheHashTests; -typedef Test BinaryCacheTests; -typedef Test CompilerInterfaceCachedTests; - TEST(HashGeneration, givenMisalignedBufferWhenPassedToUpdateFunctionThenProperPtrDataIsUsed) { Hash hash; auto originalPtr = alignedMalloc(1024, MemoryConstants::pageSize); @@ -148,7 +116,7 @@ TEST(HashGeneration, givenMisalignedBufferWithSizeOneWhenPassedToUpdateFunctionT alignedFree(originalPtr); } -TEST_F(BinaryCacheHashTests, hashShortBuffers) { +TEST(CompilerCacheHashTests, hashShortBuffers) { Hash hash; std::list hashes; @@ -172,9 +140,8 @@ TEST_F(BinaryCacheHashTests, hashShortBuffers) { } } -TEST_F(BinaryCacheHashTests, testUnique) { +TEST(CompilerCacheHashTests, testUnique) { static const size_t bufSize = 64; - TranslationInput args{IGC::CodeType::undefined, IGC::CodeType::undefined}; HardwareInfo hwInfo; std::set hashes; @@ -193,30 +160,28 @@ TEST_F(BinaryCacheHashTests, testUnique) { w2.waDoNotUseMIReportPerfCount = false; const WorkaroundTable *was[] = {&w1, &w2}; - std::array input = {{std::string(""), - std::string("12345678901234567890123456789012"), - std::string("12345678910234567890123456789012"), - std::string("12345678901234567891023456789012")}}; + std::array inputArray = {{std::string(""), + std::string("12345678901234567890123456789012"), + std::string("12345678910234567890123456789012"), + std::string("12345678901234567891023456789012")}}; - std::array options = {{std::string(""), - std::string("--some --options"), - std::string("--some --different --options")}}; + std::array optionsArray = {{std::string(""), + std::string("--some --options"), + std::string("--some --different --options")}}; - std::array internalOptions = {{std::string(""), - std::string("--some --options"), - std::string("--some --different --options")}}; - - std::array tracingOptions = {{ - std::string(""), - // std::string("--some --options"), - // std::string("--some --different --options") - }}; + std::array internalOptionsArray = {{std::string(""), + std::string("--some --options"), + std::string("--some --different --options")}}; std::unique_ptr buf1(new char[bufSize]); std::unique_ptr buf2(new char[bufSize]); std::unique_ptr buf3(new char[bufSize]); std::unique_ptr buf4(new char[bufSize]); + ArrayRef src; + ArrayRef apiOptions; + ArrayRef internalOptions; + for (auto platform : platforms) { hwInfo.platform = *platform; @@ -226,27 +191,22 @@ TEST_F(BinaryCacheHashTests, testUnique) { for (auto wa : was) { hwInfo.workaroundTable = *wa; - for (size_t i1 = 0; i1 < input.size(); i1++) { - strcpy_s(buf1.get(), bufSize, input[i1].c_str()); - args.src = ArrayRef(buf1.get(), strlen(buf1.get())); - for (size_t i2 = 0; i2 < options.size(); i2++) { - strcpy_s(buf2.get(), bufSize, options[i2].c_str()); - args.apiOptions = ArrayRef(buf2.get(), strlen(buf2.get())); - for (size_t i3 = 0; i3 < internalOptions.size(); i3++) { - strcpy_s(buf3.get(), bufSize, internalOptions[i3].c_str()); - args.internalOptions = ArrayRef(buf3.get(), strlen(buf3.get())); - for (size_t i4 = 0; i4 < tracingOptions.size(); i4++) { - strcpy_s(buf4.get(), bufSize, tracingOptions[i4].c_str()); - args.tracingOptions = buf4.get(); - args.tracingOptionsCount = static_cast(strlen(buf4.get())); + for (size_t i1 = 0; i1 < inputArray.size(); i1++) { + strcpy_s(buf1.get(), bufSize, inputArray[i1].c_str()); + src = ArrayRef(buf1.get(), strlen(buf1.get())); + for (size_t i2 = 0; i2 < optionsArray.size(); i2++) { + strcpy_s(buf2.get(), bufSize, optionsArray[i2].c_str()); + apiOptions = ArrayRef(buf2.get(), strlen(buf2.get())); + for (size_t i3 = 0; i3 < internalOptionsArray.size(); i3++) { + strcpy_s(buf3.get(), bufSize, internalOptionsArray[i3].c_str()); + internalOptions = ArrayRef(buf3.get(), strlen(buf3.get())); - string hash = cache->getCachedFileName(hwInfo, args.src, args.apiOptions, args.internalOptions); + string hash = CompilerCache::getCachedFileName(hwInfo, src, apiOptions, internalOptions); - if (hashes.find(hash) != hashes.end()) { - FAIL() << "failed: " << i1 << ":" << i2 << ":" << i3 << ":" << i4; - } - hashes.emplace(hash); + if (hashes.find(hash) != hashes.end()) { + FAIL() << "failed: " << i1 << ":" << i2 << ":" << i3; } + hashes.emplace(hash); } } } @@ -254,52 +214,46 @@ TEST_F(BinaryCacheHashTests, testUnique) { } } - string hash = cache->getCachedFileName(hwInfo, args.src, args.apiOptions, args.internalOptions); - string hash2 = cache->getCachedFileName(hwInfo, args.src, args.apiOptions, args.internalOptions); + string hash = CompilerCache::getCachedFileName(hwInfo, src, apiOptions, internalOptions); + string hash2 = CompilerCache::getCachedFileName(hwInfo, src, apiOptions, internalOptions); EXPECT_STREQ(hash.c_str(), hash2.c_str()); } -TEST_F(BinaryCacheTests, doNotCacheEmpty) { - bool ret = cache->cacheBinary("some_hash", nullptr, 12u); +TEST(CompilerCacheTests, doNotCacheEmpty) { + CompilerCache cache(CompilerCacheConfig{}); + bool ret = cache.cacheBinary("some_hash", nullptr, 12u); EXPECT_FALSE(ret); const char *tmp1 = "Data"; - ret = cache->cacheBinary("some_hash", tmp1, 0u); + ret = cache.cacheBinary("some_hash", tmp1, 0u); EXPECT_FALSE(ret); } -TEST_F(BinaryCacheTests, loadNotFound) { +TEST(CompilerCacheTests, loadNotFound) { + CompilerCache cache(CompilerCacheConfig{}); size_t size; - auto ret = cache->loadCachedBinary("----do-not-exists----", size); + auto ret = cache.loadCachedBinary("----do-not-exists----", size); EXPECT_EQ(nullptr, ret); EXPECT_EQ(0U, size); } -TEST_F(BinaryCacheTests, cacheThenLoad) { +TEST(CompilerCacheTests, cacheThenLoad) { + CompilerCache cache(getDefaultClCompilerCacheConfig()); static const char *hash = "SOME_HASH"; std::unique_ptr data(new char[32]); for (size_t i = 0; i < 32; i++) data.get()[i] = static_cast(i); - bool ret = cache->cacheBinary(hash, static_cast(data.get()), 32); + bool ret = cache.cacheBinary(hash, static_cast(data.get()), 32); EXPECT_TRUE(ret); size_t size; - auto loadedBin = cache->loadCachedBinary(hash, size); + auto loadedBin = cache.loadCachedBinary(hash, size); EXPECT_NE(nullptr, loadedBin); EXPECT_NE(0U, size); } -TEST_F(CompilerInterfaceCachedTests, canInjectCache) { - std::unique_ptr cache(new BinaryCache()); - auto res1 = pCompilerInterface->replaceBinaryCache(cache.get()); - auto res2 = pCompilerInterface->replaceBinaryCache(res1); - - EXPECT_NE(res1, res2); - EXPECT_EQ(res2, cache.get()); -} -TEST_F(CompilerInterfaceCachedTests, notCachedAndIgcFailed) { - BinaryCacheMock cache; +TEST(CompilerInterfaceCachedTests, notCachedAndIgcFailed) { TranslationInput inputArgs{IGC::CodeType::oclC, IGC::CodeType::oclGenBin}; auto src = "#include \"header.h\"\n__kernel k() {}"; @@ -315,21 +269,20 @@ TEST_F(CompilerInterfaceCachedTests, notCachedAndIgcFailed) { igcDebugVars.forceBuildFailure = true; gEnvironment->igcPushDebugVars(igcDebugVars); - auto res1 = pCompilerInterface->replaceBinaryCache(&cache); + std::unique_ptr cache(new CompilerCacheMock()); + auto compilerInterface = std::unique_ptr(CompilerInterface::createInstance(std::move(cache), true)); TranslationOutput translationOutput; inputArgs.allowCaching = true; - auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput); + MockDevice device; + auto err = compilerInterface->build(device, inputArgs, translationOutput); EXPECT_EQ(TranslationOutput::ErrorCode::BuildFailure, err); - pCompilerInterface->replaceBinaryCache(res1); - gEnvironment->fclPopDebugVars(); gEnvironment->igcPopDebugVars(); } -TEST_F(CompilerInterfaceCachedTests, wasCached) { - BinaryCacheMock cache; +TEST(CompilerInterfaceCachedTests, wasCached) { TranslationInput inputArgs{IGC::CodeType::oclC, IGC::CodeType::oclGenBin}; auto src = "#include \"header.h\"\n__kernel k() {}"; @@ -344,51 +297,24 @@ TEST_F(CompilerInterfaceCachedTests, wasCached) { igcDebugVars.forceBuildFailure = true; gEnvironment->igcPushDebugVars(igcDebugVars); - auto res1 = pCompilerInterface->replaceBinaryCache(&cache); - cache.loadResult = true; + std::unique_ptr cache(new CompilerCacheMock()); + cache->loadResult = true; + auto compilerInterface = std::unique_ptr(CompilerInterface::createInstance(std::move(cache), true)); + TranslationOutput translationOutput; inputArgs.allowCaching = true; - auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput); + MockDevice device; + auto err = compilerInterface->build(device, inputArgs, translationOutput); EXPECT_EQ(TranslationOutput::ErrorCode::Success, err); - pCompilerInterface->replaceBinaryCache(res1); - gEnvironment->fclPopDebugVars(); gEnvironment->igcPopDebugVars(); } -TEST_F(CompilerInterfaceCachedTests, builtThenCached) { - BinaryCacheMock cache; - TranslationInput inputArgs{IGC::CodeType::oclC, IGC::CodeType::oclGenBin}; - - auto src = "#include \"header.h\"\n__kernel k() {}"; - inputArgs.src = ArrayRef(src, strlen(src)); - - MockCompilerDebugVars fclDebugVars; - fclDebugVars.fileName = gEnvironment->fclGetMockFile(); - gEnvironment->fclPushDebugVars(fclDebugVars); - - MockCompilerDebugVars igcDebugVars; - igcDebugVars.fileName = gEnvironment->igcGetMockFile(); - gEnvironment->igcPushDebugVars(igcDebugVars); - - auto res1 = pCompilerInterface->replaceBinaryCache(&cache); - TranslationOutput translationOutput = {}; - inputArgs.allowCaching = true; - auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput); - EXPECT_EQ(TranslationOutput::ErrorCode::Success, err); - EXPECT_EQ(1u, cache.cacheInvoked); - - pCompilerInterface->replaceBinaryCache(res1); - - gEnvironment->fclPopDebugVars(); - gEnvironment->igcPopDebugVars(); -} - -TEST_F(CompilerInterfaceCachedTests, givenKernelWithoutIncludesAndBinaryInCacheWhenCompilationRequestedThenFCLIsNotCalled) { - MockContext context(pDevice, true); - MockProgram program(*pDevice->getExecutionEnvironment(), &context, false); - BinaryCacheMock cache; +TEST(CompilerInterfaceCachedTests, givenKernelWithoutIncludesAndBinaryInCacheWhenCompilationRequestedThenFCLIsNotCalled) { + MockDevice device; + MockContext context(&device, true); + MockProgram program(*device.getExecutionEnvironment(), &context, false); TranslationInput inputArgs{IGC::CodeType::oclC, IGC::CodeType::oclGenBin}; auto src = "__kernel k() {}"; @@ -406,23 +332,22 @@ TEST_F(CompilerInterfaceCachedTests, givenKernelWithoutIncludesAndBinaryInCacheW igcDebugVars.forceBuildFailure = true; gEnvironment->igcPushDebugVars(igcDebugVars); - auto res = pCompilerInterface->replaceBinaryCache(&cache); - cache.loadResult = true; + std::unique_ptr cache(new CompilerCacheMock()); + cache->loadResult = true; + auto compilerInterface = std::unique_ptr(CompilerInterface::createInstance(std::move(cache), true)); TranslationOutput translationOutput; inputArgs.allowCaching = true; - auto retVal = pCompilerInterface->build(*pDevice, inputArgs, translationOutput); + auto retVal = compilerInterface->build(device, inputArgs, translationOutput); EXPECT_EQ(TranslationOutput::ErrorCode::Success, retVal); - pCompilerInterface->replaceBinaryCache(res); - gEnvironment->fclPopDebugVars(); gEnvironment->igcPopDebugVars(); } -TEST_F(CompilerInterfaceCachedTests, givenKernelWithIncludesAndBinaryInCacheWhenCompilationRequestedThenFCLIsCalled) { - MockContext context(pDevice, true); - MockProgram program(*pDevice->getExecutionEnvironment(), &context, false); - BinaryCacheMock cache; +TEST(CompilerInterfaceCachedTests, givenKernelWithIncludesAndBinaryInCacheWhenCompilationRequestedThenFCLIsCalled) { + MockDevice device; + MockContext context(&device, true); + MockProgram program(*device.getExecutionEnvironment(), &context, false); TranslationInput inputArgs{IGC::CodeType::oclC, IGC::CodeType::oclGenBin}; auto src = "#include \"file.h\"\n__kernel k() {}"; @@ -433,14 +358,13 @@ TEST_F(CompilerInterfaceCachedTests, givenKernelWithIncludesAndBinaryInCacheWhen fclDebugVars.forceBuildFailure = true; gEnvironment->fclPushDebugVars(fclDebugVars); - auto res = pCompilerInterface->replaceBinaryCache(&cache); - cache.loadResult = true; + std::unique_ptr cache(new CompilerCacheMock()); + cache->loadResult = true; + auto compilerInterface = std::unique_ptr(CompilerInterface::createInstance(std::move(cache), true)); TranslationOutput translationOutput; inputArgs.allowCaching = true; - auto retVal = pCompilerInterface->build(*pDevice, inputArgs, translationOutput); + auto retVal = compilerInterface->build(device, inputArgs, translationOutput); EXPECT_EQ(TranslationOutput::ErrorCode::BuildFailure, retVal); - pCompilerInterface->replaceBinaryCache(res); - gEnvironment->fclPopDebugVars(); } diff --git a/runtime/compiler_interface/CMakeLists.txt b/runtime/compiler_interface/CMakeLists.txt index f5763b3121..cf7b3c645f 100644 --- a/runtime/compiler_interface/CMakeLists.txt +++ b/runtime/compiler_interface/CMakeLists.txt @@ -6,14 +6,13 @@ set(RUNTIME_SRCS_COMPILER_INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt - ${CMAKE_CURRENT_SOURCE_DIR}/binary_cache.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/binary_cache.h ${CMAKE_CURRENT_SOURCE_DIR}/compiler_interface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/compiler_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/compiler_options.cpp ${CMAKE_CURRENT_SOURCE_DIR}/compiler_options.h ${CMAKE_CURRENT_SOURCE_DIR}/compiler_interface.inl ${CMAKE_CURRENT_SOURCE_DIR}/create_main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/default_cl_cache_config.cpp ) get_property(NEO_COMPILER_INTERFACE GLOBAL PROPERTY NEO_COMPILER_INTERFACE) diff --git a/runtime/compiler_interface/binary_cache.h b/runtime/compiler_interface/binary_cache.h deleted file mode 100644 index 610ec6365d..0000000000 --- a/runtime/compiler_interface/binary_cache.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2017-2019 Intel Corporation - * - * SPDX-License-Identifier: MIT - * - */ - -#pragma once - -#include "core/utilities/arrayref.h" - -#include -#include -#include -#include -#include - -namespace NEO { -struct HardwareInfo; - -class BinaryCache { - public: - static const std::string getCachedFileName(const HardwareInfo &hwInfo, ArrayRef input, - ArrayRef options, ArrayRef internalOptions); - BinaryCache(); - virtual ~BinaryCache(); - virtual bool cacheBinary(const std::string kernelFileHash, const char *pBinary, uint32_t binarySize); - virtual std::unique_ptr loadCachedBinary(const std::string kernelFileHash, size_t &cachedBinarySize); - - protected: - static std::mutex cacheAccessMtx; - std::string clCacheLocation; -}; -} // namespace NEO diff --git a/runtime/compiler_interface/compiler_interface.cpp b/runtime/compiler_interface/compiler_interface.cpp index d556f80410..473b03212b 100644 --- a/runtime/compiler_interface/compiler_interface.cpp +++ b/runtime/compiler_interface/compiler_interface.cpp @@ -7,7 +7,7 @@ #include "runtime/compiler_interface/compiler_interface.h" -#include "runtime/compiler_interface/binary_cache.h" +#include "core/compiler_interface/compiler_cache.h" #include "runtime/compiler_interface/compiler_interface.inl" #include "runtime/device/device.h" #include "runtime/helpers/hw_info.h" @@ -33,9 +33,11 @@ enum CachingMode { PreProcess }; -CompilerInterface::CompilerInterface() = default; +CompilerInterface::CompilerInterface() + : cache() { +} CompilerInterface::~CompilerInterface() = default; -NO_SANITIZE + TranslationOutput::ErrorCode CompilerInterface::build( const NEO::Device &device, const TranslationInput &input, @@ -61,29 +63,29 @@ TranslationOutput::ErrorCode CompilerInterface::build( } } - if (intermediateCodeType == IGC::CodeType::undefined) { - intermediateCodeType = getPreferredIntermediateRepresentation(device); - } - std::string kernelFileHash; if (cachingMode == CachingMode::Direct) { - kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(), - input.src, - input.apiOptions, - input.internalOptions); + kernelFileHash = CompilerCache::getCachedFileName(device.getHardwareInfo(), + input.src, + input.apiOptions, + input.internalOptions); output.deviceBinary.mem = cache->loadCachedBinary(kernelFileHash, output.deviceBinary.size); if (output.deviceBinary.mem) { return TranslationOutput::ErrorCode::Success; } } - auto inSrc = CIF::Builtins::CreateConstBuffer(fclMain.get(), input.src.begin(), input.src.size()); - auto fclOptions = CIF::Builtins::CreateConstBuffer(fclMain.get(), input.apiOptions.begin(), input.apiOptions.size()); - auto fclInternalOptions = CIF::Builtins::CreateConstBuffer(fclMain.get(), input.internalOptions.begin(), input.internalOptions.size()); + auto inSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), input.src.begin(), input.src.size()); + auto fclOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), input.apiOptions.begin(), input.apiOptions.size()); + auto fclInternalOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), input.internalOptions.begin(), input.internalOptions.size()); CIF::RAII::UPtr_t intermediateRepresentation; if (srcCodeType == IGC::CodeType::oclC) { + if (intermediateCodeType == IGC::CodeType::undefined) { + intermediateCodeType = getPreferredIntermediateRepresentation(device); + } + auto fclTranslationCtx = createFclTranslationCtx(device, srcCodeType, intermediateCodeType); auto fclOutput = translate(fclTranslationCtx.get(), inSrc.get(), fclOptions.get(), fclInternalOptions.get()); @@ -110,9 +112,9 @@ TranslationOutput::ErrorCode CompilerInterface::build( } if (cachingMode == CachingMode::PreProcess) { - kernelFileHash = cache->getCachedFileName(device.getHardwareInfo(), ArrayRef(intermediateRepresentation->GetMemory(), intermediateRepresentation->GetSize()), - input.apiOptions, - input.internalOptions); + kernelFileHash = CompilerCache::getCachedFileName(device.getHardwareInfo(), ArrayRef(intermediateRepresentation->GetMemory(), intermediateRepresentation->GetSize()), + input.apiOptions, + input.internalOptions); output.deviceBinary.mem = cache->loadCachedBinary(kernelFileHash, output.deviceBinary.size); if (output.deviceBinary.mem) { return TranslationOutput::ErrorCode::Success; @@ -326,20 +328,13 @@ bool CompilerInterface::loadIgc() { return NEO::loadCompiler(Os::igcDllName, igcLib, igcMain); } -bool CompilerInterface::initialize(bool requireFcl) { - bool fclAvailable = this->loadFcl(); +bool CompilerInterface::initialize(std::unique_ptr cache, bool requireFcl) { + bool fclAvailable = requireFcl ? this->loadFcl() : false; bool igcAvailable = this->loadIgc(); - cache.reset(new BinaryCache()); + this->cache.swap(cache); - return igcAvailable && (fclAvailable || (false == requireFcl)); -} - -BinaryCache *CompilerInterface::replaceBinaryCache(BinaryCache *newCache) { - auto res = cache.release(); - this->cache.reset(newCache); - - return res; + return this->cache && igcAvailable && (fclAvailable || (false == requireFcl)); } IGC::FclOclDeviceCtxTagOCL *CompilerInterface::getFclDeviceCtx(const Device &device) { diff --git a/runtime/compiler_interface/compiler_interface.h b/runtime/compiler_interface/compiler_interface.h index 9759c7f21a..008b5b9ee6 100644 --- a/runtime/compiler_interface/compiler_interface.h +++ b/runtime/compiler_interface/compiler_interface.h @@ -6,10 +6,10 @@ */ #pragma once +#include "core/compiler_interface/compiler_cache.h" #include "core/helpers/string.h" #include "core/utilities/arrayref.h" #include "runtime/built_ins/sip.h" -#include "runtime/compiler_interface/binary_cache.h" #include "runtime/os_interface/os_library.h" #include "cif/common/cif_main.h" @@ -22,7 +22,6 @@ namespace NEO { class Device; -class Program; struct TranslationInput { TranslationInput(IGC::CodeType::CodeType_t srcType, IGC::CodeType::CodeType_t outType, IGC::CodeType::CodeType_t preferredIntermediateType = IGC::CodeType::undefined) @@ -107,9 +106,9 @@ class CompilerInterface { CompilerInterface &operator=(CompilerInterface &&) = delete; virtual ~CompilerInterface(); - static CompilerInterface *createInstance(bool requireFcl) { + static CompilerInterface *createInstance(std::unique_ptr cache, bool requireFcl) { auto instance = new CompilerInterface(); - if (!instance->initialize(requireFcl)) { + if (!instance->initialize(std::move(cache), requireFcl)) { delete instance; instance = nullptr; } @@ -137,10 +136,8 @@ class CompilerInterface { MOCKABLE_VIRTUAL TranslationOutput::ErrorCode getSipKernelBinary(NEO::Device &device, SipKernelType type, std::vector &retBinary); - BinaryCache *replaceBinaryCache(BinaryCache *newCache); - protected: - bool initialize(bool requireFcl); + bool initialize(std::unique_ptr cache, bool requireFcl); MOCKABLE_VIRTUAL bool loadFcl(); MOCKABLE_VIRTUAL bool loadIgc(); @@ -148,7 +145,7 @@ class CompilerInterface { MOCKABLE_VIRTUAL std::unique_lock lock() { return std::unique_lock{mtx}; } - std::unique_ptr cache = nullptr; + std::unique_ptr cache = nullptr; using igcDevCtxUptr = CIF::RAII::UPtr_t; using fclDevCtxUptr = CIF::RAII::UPtr_t; diff --git a/runtime/compiler_interface/default_cl_cache_config.cpp b/runtime/compiler_interface/default_cl_cache_config.cpp new file mode 100644 index 0000000000..2ae788e9a5 --- /dev/null +++ b/runtime/compiler_interface/default_cl_cache_config.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "default_cl_cache_config.h" + +#include "core/utilities/debug_settings_reader.h" +#include "runtime/os_interface/ocl_reg_path.h" + +#include "config.h" +#include "os_inc.h" + +#include + +namespace NEO { + +CompilerCacheConfig getDefaultClCompilerCacheConfig() { + CompilerCacheConfig ret; + + std::string keyName = oclRegPath; + keyName += "cl_cache_dir"; + std::unique_ptr settingsReader(SettingsReader::createOsReader(false, keyName)); + ret.cacheDir = settingsReader->getSetting(settingsReader->appSpecificLocation(keyName), static_cast(CL_CACHE_LOCATION)); + + ret.cacheFileExtension = ".cl_cache"; + + return ret; +} + +} // namespace NEO diff --git a/runtime/compiler_interface/default_cl_cache_config.h b/runtime/compiler_interface/default_cl_cache_config.h new file mode 100644 index 0000000000..a5bf44d6bf --- /dev/null +++ b/runtime/compiler_interface/default_cl_cache_config.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2019 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "core/compiler_interface/compiler_cache.h" + +namespace NEO { + +CompilerCacheConfig getDefaultClCompilerCacheConfig(); +} diff --git a/runtime/execution_environment/execution_environment.cpp b/runtime/execution_environment/execution_environment.cpp index 8792ab92ca..e7248fccae 100644 --- a/runtime/execution_environment/execution_environment.cpp +++ b/runtime/execution_environment/execution_environment.cpp @@ -14,6 +14,7 @@ #include "runtime/command_stream/command_stream_receiver.h" #include "runtime/command_stream/tbx_command_stream_receiver_hw.h" #include "runtime/compiler_interface/compiler_interface.h" +#include "runtime/compiler_interface/default_cl_cache_config.h" #include "runtime/gmm_helper/gmm_helper.h" #include "runtime/helpers/hw_helper.h" #include "runtime/memory_manager/memory_manager.h" @@ -105,7 +106,8 @@ CompilerInterface *ExecutionEnvironment::getCompilerInterface() { if (this->compilerInterface.get() == nullptr) { std::lock_guard autolock(this->mtx); if (this->compilerInterface.get() == nullptr) { - this->compilerInterface.reset(CompilerInterface::createInstance(true)); + auto cache = std::make_unique(getDefaultClCompilerCacheConfig()); + this->compilerInterface.reset(CompilerInterface::createInstance(std::move(cache), true)); } } return this->compilerInterface.get(); diff --git a/unit_tests/compiler_interface/CMakeLists.txt b/unit_tests/compiler_interface/CMakeLists.txt index f9ed1996b4..512a57a148 100644 --- a/unit_tests/compiler_interface/CMakeLists.txt +++ b/unit_tests/compiler_interface/CMakeLists.txt @@ -6,8 +6,8 @@ set(IGDRCL_SRCS_tests_compiler_interface ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt - ${CMAKE_CURRENT_SOURCE_DIR}/binary_cache_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/compiler_interface_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/default_cl_cache_config_tests.cpp ) get_property(NEO_CORE_COMPILER_INTERFACE_TESTS GLOBAL PROPERTY NEO_CORE_COMPILER_INTERFACE_TESTS) diff --git a/unit_tests/compiler_interface/compiler_interface_tests.cpp b/unit_tests/compiler_interface/compiler_interface_tests.cpp index e17003133d..89f2f2ef99 100644 --- a/unit_tests/compiler_interface/compiler_interface_tests.cpp +++ b/unit_tests/compiler_interface/compiler_interface_tests.cpp @@ -44,7 +44,7 @@ class CompilerInterfaceTest : public DeviceFixture, // create the compiler interface this->pCompilerInterface = new MockCompilerInterface(); - bool initRet = pCompilerInterface->initialize(true); + bool initRet = pCompilerInterface->initialize(std::make_unique(CompilerCacheConfig{}), true); ASSERT_TRUE(initRet); pDevice->getExecutionEnvironment()->compilerInterface.reset(pCompilerInterface); @@ -75,7 +75,16 @@ class CompilerInterfaceTest : public DeviceFixture, size_t sourceSize = 0; }; -TEST(CompilerInterface, WhenInitializeIsCalledThenFailOnlyIfOneOfRequiredCompilersIsUnavailable) { +TEST(CompilerInterface, WhenInitializeIsCalledThenFailIfCompilerCacheHandlerIsEmpty) { + MockCompilerInterface ci; + + ci.failLoadFcl = false; + ci.failLoadIgc = false; + bool initSuccess = ci.initialize(nullptr, true); + EXPECT_FALSE(initSuccess); +} + +TEST(CompilerInterface, WhenInitializeIsCalledThenFailIfOneOfRequiredCompilersIsUnavailable) { bool initSuccess = false; bool requireFcl = true; MockCompilerInterface ci; @@ -83,49 +92,49 @@ TEST(CompilerInterface, WhenInitializeIsCalledThenFailOnlyIfOneOfRequiredCompile ci.failLoadFcl = false; ci.failLoadIgc = false; requireFcl = true; - initSuccess = ci.initialize(requireFcl); + initSuccess = ci.initialize(std::make_unique(CompilerCacheConfig{}), requireFcl); EXPECT_TRUE(initSuccess); ci.failLoadFcl = false; ci.failLoadIgc = false; requireFcl = false; - initSuccess = ci.initialize(requireFcl); + initSuccess = ci.initialize(std::make_unique(CompilerCacheConfig{}), requireFcl); EXPECT_TRUE(initSuccess); ci.failLoadFcl = true; ci.failLoadIgc = false; requireFcl = false; - initSuccess = ci.initialize(requireFcl); + initSuccess = ci.initialize(std::make_unique(CompilerCacheConfig{}), requireFcl); EXPECT_TRUE(initSuccess); ci.failLoadFcl = true; ci.failLoadIgc = false; requireFcl = true; - initSuccess = ci.initialize(requireFcl); + initSuccess = ci.initialize(std::make_unique(CompilerCacheConfig{}), requireFcl); EXPECT_FALSE(initSuccess); ci.failLoadFcl = false; ci.failLoadIgc = true; requireFcl = true; - initSuccess = ci.initialize(requireFcl); + initSuccess = ci.initialize(std::make_unique(CompilerCacheConfig{}), requireFcl); EXPECT_FALSE(initSuccess); ci.failLoadFcl = false; ci.failLoadIgc = true; requireFcl = false; - initSuccess = ci.initialize(requireFcl); + initSuccess = ci.initialize(std::make_unique(CompilerCacheConfig{}), requireFcl); EXPECT_FALSE(initSuccess); ci.failLoadFcl = true; ci.failLoadIgc = true; requireFcl = false; - initSuccess = ci.initialize(requireFcl); + initSuccess = ci.initialize(std::make_unique(CompilerCacheConfig{}), requireFcl); EXPECT_FALSE(initSuccess); ci.failLoadFcl = true; ci.failLoadIgc = true; requireFcl = true; - initSuccess = ci.initialize(requireFcl); + initSuccess = ci.initialize(std::make_unique(CompilerCacheConfig{}), requireFcl); EXPECT_FALSE(initSuccess); } diff --git a/unit_tests/compiler_interface/default_cl_cache_config_tests.cpp b/unit_tests/compiler_interface/default_cl_cache_config_tests.cpp new file mode 100644 index 0000000000..8ebb16be6b --- /dev/null +++ b/unit_tests/compiler_interface/default_cl_cache_config_tests.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2019 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "runtime/compiler_interface/default_cl_cache_config.h" +#include "test.h" + +TEST(CompilerCache, GivenDefaultClCacheConfigThenValuesAreProperlyPopulated) { + auto cacheConfig = NEO::getDefaultClCompilerCacheConfig(); + EXPECT_STREQ("cl_cache", cacheConfig.cacheDir.c_str()); + EXPECT_STREQ(".cl_cache", cacheConfig.cacheFileExtension.c_str()); + EXPECT_TRUE(cacheConfig.enabled); +} diff --git a/unit_tests/helpers/built_ins_helper.cpp b/unit_tests/helpers/built_ins_helper.cpp index 2ab99ded75..41173ea206 100644 --- a/unit_tests/helpers/built_ins_helper.cpp +++ b/unit_tests/helpers/built_ins_helper.cpp @@ -7,6 +7,7 @@ #include "runtime/helpers/built_ins_helper.h" +#include "runtime/compiler_interface/default_cl_cache_config.h" #include "runtime/device/device.h" #include "unit_tests/mocks/mock_compilers.h" #include "unit_tests/mocks/mock_program.h" @@ -15,7 +16,7 @@ namespace NEO { const SipKernel &initSipKernel(SipKernelType type, Device &device) { auto mockCompilerInterface = new MockCompilerInterface(); - mockCompilerInterface->initialize(false); + mockCompilerInterface->initialize(std::make_unique(getDefaultClCompilerCacheConfig()), true); device.getExecutionEnvironment()->compilerInterface.reset(mockCompilerInterface); mockCompilerInterface->sipKernelBinaryOverride = mockCompilerInterface->getDummyGenBinary(); diff --git a/unit_tests/mocks/mock_program.cpp b/unit_tests/mocks/mock_program.cpp index bd382139c6..70ccc53dbe 100644 --- a/unit_tests/mocks/mock_program.cpp +++ b/unit_tests/mocks/mock_program.cpp @@ -7,8 +7,8 @@ #include "unit_tests/mocks/mock_program.h" +#include "core/compiler_interface/compiler_cache.h" #include "core/helpers/hash.h" -#include "runtime/compiler_interface/binary_cache.h" #include "runtime/context/context.h" #include "runtime/program/create.inl" #include "unit_tests/mocks/mock_compilers.h" @@ -22,7 +22,7 @@ std::string MockProgram::getCachedFileName() const { auto input = ArrayRef(this->sourceCode.c_str(), this->sourceCode.size()); auto opts = ArrayRef(this->options.c_str(), this->options.size()); auto internalOpts = ArrayRef(this->internalOptions.c_str(), this->internalOptions.size()); - return BinaryCache::getCachedFileName(hwInfo, input, opts, internalOpts); + return CompilerCache::getCachedFileName(hwInfo, input, opts, internalOpts); } cl_int GlobalMockSipProgram::processGenBinary() { return CL_SUCCESS;