From 53223dc2b5f2ff6868b19b8130b50766b270a8a9 Mon Sep 17 00:00:00 2001 From: Artur Harasimiuk Date: Thu, 28 Oct 2021 13:06:49 +0000 Subject: [PATCH] create trace files about cl_cache usage Signed-off-by: Artur Harasimiuk --- opencl/test/unit_test/mocks/mock_program.cpp | 3 +- .../test/unit_test/test_files/igdrcl.config | 1 + .../compiler_interface/compiler_cache.cpp | 44 ++++++++++++++++ .../compiler_interface/compiler_cache.h | 6 +-- .../compiler_interface/compiler_interface.cpp | 14 ++--- .../debug_settings/debug_variables_base.inl | 3 ++ .../compiler_cache_tests.cpp | 51 +++++++++++++++++-- 7 files changed, 108 insertions(+), 14 deletions(-) diff --git a/opencl/test/unit_test/mocks/mock_program.cpp b/opencl/test/unit_test/mocks/mock_program.cpp index a64fbff6952e7..5910d4b08440b 100644 --- a/opencl/test/unit_test/mocks/mock_program.cpp +++ b/opencl/test/unit_test/mocks/mock_program.cpp @@ -31,12 +31,13 @@ ClDeviceVector toClDeviceVector(ClDevice &clDevice) { int MockProgram::initInternalOptionsCalled = 0; std::string MockProgram::getCachedFileName() const { + CompilerCache cache(CompilerCacheConfig{}); 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 = getInitInternalOptions(); auto internalOpts = ArrayRef(internalOptions.c_str(), internalOptions.size()); - return CompilerCache::getCachedFileName(hwInfo, input, opts, internalOpts); + return cache.getCachedFileName(hwInfo, input, opts, internalOpts); } } // namespace NEO diff --git a/opencl/test/unit_test/test_files/igdrcl.config b/opencl/test/unit_test/test_files/igdrcl.config index acfc9a0366311..b3049dd1877cf 100644 --- a/opencl/test/unit_test/test_files/igdrcl.config +++ b/opencl/test/unit_test/test_files/igdrcl.config @@ -334,3 +334,4 @@ AllowPatchingVfeStateInCommandLists = 0 PrintMemoryRegionSizes = 0 OverrideDrmRegion = -1 AllowSingleTileEngineInstancedSubDevices = 0 +BinaryCacheTrace = false diff --git a/shared/source/compiler_interface/compiler_cache.cpp b/shared/source/compiler_interface/compiler_cache.cpp index 27d12f4cc3f21..ebc313f406fda 100644 --- a/shared/source/compiler_interface/compiler_cache.cpp +++ b/shared/source/compiler_interface/compiler_cache.cpp @@ -7,12 +7,14 @@ #include "shared/source/compiler_interface/compiler_cache.h" +#include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/helpers/aligned_memory.h" #include "shared/source/helpers/casts.h" #include "shared/source/helpers/file_io.h" #include "shared/source/helpers/hash.h" #include "shared/source/helpers/hw_info.h" #include "shared/source/utilities/debug_settings_reader.h" +#include "shared/source/utilities/io_functions.h" #include "config.h" #include "os_inc.h" @@ -50,6 +52,48 @@ const std::string CompilerCache::getCachedFileName(const HardwareInfo &hwInfo, c << std::hex << res; + if (DebugManager.flags.BinaryCacheTrace.get()) { + std::string filePath = config.cacheDir + PATH_SEPARATOR + stream.str() + ".trace"; + std::lock_guard lock(cacheAccessMtx); + auto fp = NEO::IoFunctions::fopenPtr(filePath.c_str(), "w"); + if (fp) { + NEO::IoFunctions::fprintf(fp, "---- input ----\n"); + NEO::IoFunctions::fprintf(fp, "%s\n", &*input.begin()); + NEO::IoFunctions::fprintf(fp, "---- options ----\n"); + NEO::IoFunctions::fprintf(fp, "%s\n", &*options.begin()); + NEO::IoFunctions::fprintf(fp, "---- internal options ----\n"); + NEO::IoFunctions::fprintf(fp, "%s\n", &*internalOptions.begin()); + + NEO::IoFunctions::fprintf(fp, "---- platform ----\n"); + NEO::IoFunctions::fprintf(fp, " eProductFamily=%d\n", hwInfo.platform.eProductFamily); + NEO::IoFunctions::fprintf(fp, " ePCHProductFamily=%d\n", hwInfo.platform.ePCHProductFamily); + NEO::IoFunctions::fprintf(fp, " eDisplayCoreFamily=%d\n", hwInfo.platform.eDisplayCoreFamily); + NEO::IoFunctions::fprintf(fp, " eRenderCoreFamily=%d\n", hwInfo.platform.eRenderCoreFamily); + NEO::IoFunctions::fprintf(fp, " ePlatformType=%d\n", hwInfo.platform.ePlatformType); + NEO::IoFunctions::fprintf(fp, " usDeviceID=%d\n", hwInfo.platform.usDeviceID); + NEO::IoFunctions::fprintf(fp, " usRevId=%d\n", hwInfo.platform.usRevId); + NEO::IoFunctions::fprintf(fp, " usDeviceID_PCH=%d\n", hwInfo.platform.usDeviceID_PCH); + NEO::IoFunctions::fprintf(fp, " usRevId_PCH=%d\n", hwInfo.platform.usRevId_PCH); + NEO::IoFunctions::fprintf(fp, " eGTType=%d\n", hwInfo.platform.eGTType); + + NEO::IoFunctions::fprintf(fp, "---- feature table ----\n"); + auto featureTable = r_pod_cast(&hwInfo.featureTable.packed); + for (size_t idx = 0; idx < sizeof(hwInfo.featureTable.packed); idx++) { + NEO::IoFunctions::fprintf(fp, "%02x.", (uint8_t)(featureTable[idx])); + } + NEO::IoFunctions::fprintf(fp, "\n"); + + NEO::IoFunctions::fprintf(fp, "---- workaround table ----\n"); + auto workaroundTable = reinterpret_cast(&hwInfo.workaroundTable); + for (size_t idx = 0; idx < sizeof(hwInfo.workaroundTable); idx++) { + NEO::IoFunctions::fprintf(fp, "%02x.", (uint8_t)(workaroundTable[idx])); + } + NEO::IoFunctions::fprintf(fp, "\n"); + + NEO::IoFunctions::fclosePtr(fp); + } + } + return stream.str(); } diff --git a/shared/source/compiler_interface/compiler_cache.h b/shared/source/compiler_interface/compiler_cache.h index dd5c4e0a26e1d..4ad0bd2a09ca2 100644 --- a/shared/source/compiler_interface/compiler_cache.h +++ b/shared/source/compiler_interface/compiler_cache.h @@ -26,9 +26,6 @@ struct CompilerCacheConfig { class CompilerCache { public: - static const std::string getCachedFileName(const HardwareInfo &hwInfo, ArrayRef input, - ArrayRef options, ArrayRef internalOptions); - CompilerCache(const CompilerCacheConfig &config); virtual ~CompilerCache() = default; @@ -37,6 +34,9 @@ class CompilerCache { CompilerCache &operator=(const CompilerCache &) = delete; CompilerCache &operator=(CompilerCache &&) = delete; + const std::string getCachedFileName(const HardwareInfo &hwInfo, ArrayRef input, + ArrayRef options, ArrayRef internalOptions); + 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); diff --git a/shared/source/compiler_interface/compiler_interface.cpp b/shared/source/compiler_interface/compiler_interface.cpp index 8d9799d379462..53ed03e43ebca 100644 --- a/shared/source/compiler_interface/compiler_interface.cpp +++ b/shared/source/compiler_interface/compiler_interface.cpp @@ -66,10 +66,10 @@ TranslationOutput::ErrorCode CompilerInterface::build( std::string kernelFileHash; if (cachingMode == CachingMode::Direct) { - kernelFileHash = CompilerCache::getCachedFileName(device.getHardwareInfo(), - input.src, - input.apiOptions, - input.internalOptions); + kernelFileHash = cache->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; @@ -120,9 +120,9 @@ TranslationOutput::ErrorCode CompilerInterface::build( } if (cachingMode == CachingMode::PreProcess) { - kernelFileHash = CompilerCache::getCachedFileName(device.getHardwareInfo(), ArrayRef(intermediateRepresentation->GetMemory(), intermediateRepresentation->GetSize()), - input.apiOptions, - input.internalOptions); + kernelFileHash = cache->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; diff --git a/shared/source/debug_settings/debug_variables_base.inl b/shared/source/debug_settings/debug_variables_base.inl index b1dad08184237..4fd0a7560dedb 100644 --- a/shared/source/debug_settings/debug_variables_base.inl +++ b/shared/source/debug_settings/debug_variables_base.inl @@ -352,3 +352,6 @@ DECLARE_DEBUG_VARIABLE(bool, SkipFlushingEventsOnGetStatusCalls, false, "When se DECLARE_DEBUG_VARIABLE(bool, AllowUnrestrictedSize, false, "Allow allocating memory with greater size than MAX_MEM_ALLOC_SIZE") DECLARE_DEBUG_VARIABLE(int32_t, ProgramPipeControlPriorToNonPipelinedStateCommand, -1, "-1: default, 0: disable, 1: enable, Program additional PIPE CONTROL command before non pipelined state command") DECLARE_DEBUG_VARIABLE(int32_t, OverrideDrmRegion, -1, "-1: disable, 0+: override to given memory region for all allocations") + +/* Binary Cache */ +DECLARE_DEBUG_VARIABLE(bool, BinaryCacheTrace, false, "enable cl_cache to produce .trace files with information about hash computation") 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 dc1ecf2f8bd50..e7cd3f0bdfb7f 100644 --- a/shared/test/unit_test/compiler_interface/compiler_cache_tests.cpp +++ b/shared/test/unit_test/compiler_interface/compiler_cache_tests.cpp @@ -11,6 +11,8 @@ #include "shared/source/helpers/hash.h" #include "shared/source/helpers/hw_info.h" #include "shared/source/helpers/string.h" +#include "shared/source/utilities/io_functions.h" +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/default_hw_info.h" #include "shared/test/common/libult/global_environment.h" #include "shared/test/common/mocks/mock_device.h" @@ -180,6 +182,8 @@ TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCac ArrayRef apiOptions; ArrayRef internalOptions; + CompilerCache cache(CompilerCacheConfig{}); + for (auto platform : platforms) { hwInfo.platform = *platform; @@ -199,7 +203,7 @@ TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCac strcpy_s(buf3.get(), bufSize, internalOptionsArray[i3].c_str()); internalOptions = ArrayRef(buf3.get(), strlen(buf3.get())); - std::string hash = CompilerCache::getCachedFileName(hwInfo, src, apiOptions, internalOptions); + std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions); if (hashes.find(hash) != hashes.end()) { FAIL() << "failed: " << i1 << ":" << i2 << ":" << i3; @@ -212,11 +216,52 @@ TEST(CompilerCacheHashTests, GivenCompilingOptionsWhenGettingCacheThenCorrectCac } } - std::string hash = CompilerCache::getCachedFileName(hwInfo, src, apiOptions, internalOptions); - std::string hash2 = CompilerCache::getCachedFileName(hwInfo, src, apiOptions, internalOptions); + std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions); + std::string hash2 = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions); EXPECT_STREQ(hash.c_str(), hash2.c_str()); } +TEST(CompilerCacheTests, GivenBinaryCacheWhenDebugFlagIsSetThenTraceFileIsCreated) { + DebugManagerStateRestore restorer; + DebugManager.flags.BinaryCacheTrace.set(true); + + static struct VerifyData { + bool matched; + const char *pattern; + } verifyData[] = { + {false, "---- input ----"}, + {false, "---- options ----"}, + {false, "---- internal options ----"}, + {false, "---- platform ----"}, + {false, "---- feature table ----"}, + {false, "---- workaround table ----"}}; + + // reset global array state + for (size_t idx = 0; idx < sizeof(verifyData) / sizeof(verifyData[0]); idx++) { + verifyData[idx].matched = false; + } + + VariableBackup mockVFprintf(&NEO::IoFunctions::vfprintfPtr, [](FILE *fp, const char *formatStr, va_list) -> int { + for (size_t idx = 0; idx < sizeof(verifyData) / sizeof(verifyData[0]); idx++) { + if (strncmp(formatStr, verifyData[idx].pattern, strlen(verifyData[idx].pattern))) { + verifyData[idx].matched = true; + } + } + return 0; + }); + + HardwareInfo hwInfo = *defaultHwInfo; + ArrayRef src; + ArrayRef apiOptions; + ArrayRef internalOptions; + CompilerCache cache(CompilerCacheConfig{}); + std::string hash = cache.getCachedFileName(hwInfo, src, apiOptions, internalOptions); + + for (size_t idx = 0; idx < sizeof(verifyData) / sizeof(verifyData[0]); idx++) { + EXPECT_TRUE(verifyData[idx].matched); + } +} + TEST(CompilerCacheTests, GivenEmptyBinaryWhenCachingThenBinaryIsNotCached) { CompilerCache cache(CompilerCacheConfig{}); bool ret = cache.cacheBinary("some_hash", nullptr, 12u);