Add cl_cache mechanism to ocloc

Related-To: NEO-6476

Signed-off-by: Baj, Tomasz <tomasz.baj@intel.com>
This commit is contained in:
Baj, Tomasz
2022-08-29 09:13:10 +00:00
committed by Compute-Runtime-Automation
parent 4292a47c53
commit 0eab93501c
11 changed files with 357 additions and 66 deletions

View File

@@ -12,6 +12,8 @@ set(OCLOC_FOLDER_NAME "offline_compiler")
set(CLOC_LIB_SRCS_LIB
${NEO_SHARED_DIRECTORY}/compiler_interface/compiler_options.cpp
${NEO_SHARED_DIRECTORY}/compiler_interface/compiler_options.h
${NEO_SHARED_DIRECTORY}/compiler_interface/compiler_cache.cpp
${NEO_SHARED_DIRECTORY}/compiler_interface/compiler_cache.h
${NEO_SHARED_DIRECTORY}/compiler_interface/create_main.cpp
${NEO_SHARED_DIRECTORY}/compiler_interface/oclc_extensions.cpp
${NEO_SHARED_DIRECTORY}/compiler_interface/oclc_extensions.h
@@ -56,6 +58,9 @@ set(CLOC_LIB_SRCS_LIB
${NEO_SHARED_DIRECTORY}/helpers/product_config_helper.cpp
${NEO_SHARED_DIRECTORY}/helpers/product_config_helper.h
${NEO_SHARED_DIRECTORY}/os_interface/os_library.h
${NEO_SHARED_DIRECTORY}/utilities/io_functions.cpp
${NEO_SHARED_DIRECTORY}/utilities/io_functions.h
${OCLOC_DIRECTORY}/source/default_cache_config.cpp
${OCLOC_DIRECTORY}/source/decoder/binary_decoder.cpp
${OCLOC_DIRECTORY}/source/decoder/binary_decoder.h
${OCLOC_DIRECTORY}/source/decoder/binary_encoder.cpp
@@ -111,12 +116,14 @@ endif()
if(WIN32)
list(APPEND CLOC_LIB_SRCS_LIB
${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
${NEO_SHARED_DIRECTORY}/os_interface/windows/os_library_win.h
)
else()
list(APPEND CLOC_LIB_SRCS_LIB
${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
${NEO_SHARED_DIRECTORY}/os_interface/linux/os_library_linux.h
${NEO_SHARED_DIRECTORY}/os_interface/linux/sys_calls_linux.cpp
@@ -200,6 +207,16 @@ set(CLOC_LIB_INCLUDES
${NEO__IGC_INCLUDE_DIR}
)
if(WIN32)
list(APPEND CLOC_LIB_INCLUDES
${NEO_SHARED_DIRECTORY}/os_interface/windows
)
else()
list(APPEND CLOC_LIB_INCLUDES
${NEO_SHARED_DIRECTORY}/os_interface/linux
)
endif()
target_include_directories(${OCLOC_NAME}_lib BEFORE PRIVATE ${CLOC_LIB_INCLUDES})
target_include_directories(${OCLOC_NAME}_lib BEFORE PRIVATE ${IGA_INCLUDE_DIR})

View File

@@ -0,0 +1,17 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/compiler_interface/default_cache_config.h"
namespace NEO {
CompilerCacheConfig getDefaultCompilerCacheConfig() {
CompilerCacheConfig ret;
ret.cacheDir = "ocloc_cache";
ret.cacheFileExtension = ".ocloc_cache";
return ret;
}
} // namespace NEO

View File

@@ -11,6 +11,7 @@
#include "shared/offline_compiler/source/queries.h"
#include "shared/offline_compiler/source/utilities/get_git_version_info.h"
#include "shared/source/compiler_interface/compiler_options.h"
#include "shared/source/compiler_interface/default_cache_config.h"
#include "shared/source/compiler_interface/intermediate_representations.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/device_binary_format/device_binary_formats.h"
@@ -213,6 +214,18 @@ struct OfflineCompiler::buildInfo {
int OfflineCompiler::buildIrBinary() {
int retVal = SUCCESS;
if (allowCaching) {
irHash = cache->getCachedFileName(getHardwareInfo(),
sourceCode,
options,
internalOptions);
irBinary = cache->loadCachedBinary(irHash, irBinarySize).release();
if (irBinary) {
return retVal;
}
}
UNRECOVERABLE_IF(!fclFacade->isInitialized());
pBuildInfo->intermediateRepresentation = useLlvmText ? IGC::CodeType::llvmLl
: (useLlvmBc ? IGC::CodeType::llvmBc : preferredIntermediateRepresentation);
@@ -281,6 +294,10 @@ int OfflineCompiler::buildIrBinary() {
updateBuildLog(pBuildInfo->fclOutput->GetBuildLog()->GetMemory<char>(), pBuildInfo->fclOutput->GetBuildLog()->GetSizeRaw());
if (allowCaching) {
cache->cacheBinary(irHash, irBinary, static_cast<uint32_t>(irBinarySize));
}
return retVal;
}
@@ -314,54 +331,75 @@ std::string OfflineCompiler::validateInputType(const std::string &input, bool is
int OfflineCompiler::buildSourceCode() {
int retVal = SUCCESS;
do {
if (sourceCode.empty()) {
retVal = INVALID_PROGRAM;
break;
if (sourceCode.empty()) {
return INVALID_PROGRAM;
}
if (allowCaching) {
irHash = cache->getCachedFileName(getHardwareInfo(), sourceCode, options, internalOptions);
irBinary = cache->loadCachedBinary(irHash, irBinarySize).release();
genHash = cache->getCachedFileName(getHardwareInfo(), ArrayRef<const char>(irBinary, irBinarySize), options, internalOptions);
genBinary = cache->loadCachedBinary(genHash, genBinarySize).release();
if (irBinary && genBinary) {
if (!CompilerOptions::contains(internalOptions, CompilerOptions::debugKernelEnable))
return retVal;
else {
dbgHash = cache->getCachedFileName(getHardwareInfo(), irHash, options, internalOptions);
debugDataBinary = cache->loadCachedBinary(dbgHash, debugDataBinarySize).release();
if (debugDataBinary)
return retVal;
}
}
}
UNRECOVERABLE_IF(!igcFacade->isInitialized());
UNRECOVERABLE_IF(!igcFacade->isInitialized());
auto inputTypeWarnings = validateInputType(sourceCode, inputFileLlvm, inputFileSpirV);
this->argHelper->printf(inputTypeWarnings.c_str());
auto inputTypeWarnings = validateInputType(sourceCode, inputFileLlvm, inputFileSpirV);
this->argHelper->printf(inputTypeWarnings.c_str());
CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> igcOutput;
bool inputIsIntermediateRepresentation = inputFileLlvm || inputFileSpirV;
if (false == inputIsIntermediateRepresentation) {
retVal = buildIrBinary();
if (retVal != SUCCESS)
break;
CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> igcOutput;
bool inputIsIntermediateRepresentation = inputFileLlvm || inputFileSpirV;
if (false == inputIsIntermediateRepresentation) {
retVal = buildIrBinary();
if (retVal != SUCCESS)
return retVal;
auto igcTranslationCtx = igcFacade->createTranslationContext(pBuildInfo->intermediateRepresentation, IGC::CodeType::oclGenBin);
igcOutput = igcTranslationCtx->Translate(pBuildInfo->fclOutput->GetOutput(), pBuildInfo->fclOptions.get(),
pBuildInfo->fclInternalOptions.get(),
nullptr, 0);
auto igcTranslationCtx = igcFacade->createTranslationContext(pBuildInfo->intermediateRepresentation, IGC::CodeType::oclGenBin);
igcOutput = igcTranslationCtx->Translate(pBuildInfo->fclOutput->GetOutput(), pBuildInfo->fclOptions.get(),
pBuildInfo->fclInternalOptions.get(),
nullptr, 0);
} else {
storeBinary(irBinary, irBinarySize, sourceCode.c_str(), sourceCode.size());
isSpirV = inputFileSpirV;
auto igcSrc = igcFacade->createConstBuffer(sourceCode.c_str(), sourceCode.size());
auto igcOptions = igcFacade->createConstBuffer(options.c_str(), options.size());
auto igcInternalOptions = igcFacade->createConstBuffer(internalOptions.c_str(), internalOptions.size());
auto igcTranslationCtx = igcFacade->createTranslationContext(inputFileSpirV ? IGC::CodeType::spirV : IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin);
igcOutput = igcTranslationCtx->Translate(igcSrc.get(), igcOptions.get(), igcInternalOptions.get(), nullptr, 0);
}
if (igcOutput == nullptr) {
retVal = OUT_OF_HOST_MEMORY;
break;
}
UNRECOVERABLE_IF(igcOutput->GetBuildLog() == nullptr);
UNRECOVERABLE_IF(igcOutput->GetOutput() == nullptr);
updateBuildLog(igcOutput->GetBuildLog()->GetMemory<char>(), igcOutput->GetBuildLog()->GetSizeRaw());
} else {
storeBinary(irBinary, irBinarySize, sourceCode.c_str(), sourceCode.size());
isSpirV = inputFileSpirV;
auto igcSrc = igcFacade->createConstBuffer(sourceCode.c_str(), sourceCode.size());
auto igcOptions = igcFacade->createConstBuffer(options.c_str(), options.size());
auto igcInternalOptions = igcFacade->createConstBuffer(internalOptions.c_str(), internalOptions.size());
auto igcTranslationCtx = igcFacade->createTranslationContext(inputFileSpirV ? IGC::CodeType::spirV : IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin);
igcOutput = igcTranslationCtx->Translate(igcSrc.get(), igcOptions.get(), igcInternalOptions.get(), nullptr, 0);
}
if (igcOutput == nullptr) {
return OUT_OF_HOST_MEMORY;
}
UNRECOVERABLE_IF(igcOutput->GetBuildLog() == nullptr);
UNRECOVERABLE_IF(igcOutput->GetOutput() == nullptr);
updateBuildLog(igcOutput->GetBuildLog()->GetMemory<char>(), igcOutput->GetBuildLog()->GetSizeRaw());
if (igcOutput->GetOutput()->GetSizeRaw() != 0) {
storeBinary(genBinary, genBinarySize, igcOutput->GetOutput()->GetMemory<char>(), igcOutput->GetOutput()->GetSizeRaw());
}
if (igcOutput->GetDebugData()->GetSizeRaw() != 0) {
storeBinary(debugDataBinary, debugDataBinarySize, igcOutput->GetDebugData()->GetMemory<char>(), igcOutput->GetDebugData()->GetSizeRaw());
}
retVal = igcOutput->Successful() ? SUCCESS : BUILD_PROGRAM_FAILURE;
} while (0);
if (igcOutput->GetOutput()->GetSizeRaw() != 0) {
storeBinary(genBinary, genBinarySize, igcOutput->GetOutput()->GetMemory<char>(), igcOutput->GetOutput()->GetSizeRaw());
}
if (igcOutput->GetDebugData()->GetSizeRaw() != 0) {
storeBinary(debugDataBinary, debugDataBinarySize, igcOutput->GetDebugData()->GetMemory<char>(), igcOutput->GetDebugData()->GetSizeRaw());
}
if (allowCaching) {
cache->cacheBinary(irHash, irBinary, static_cast<uint32_t>(irBinarySize));
cache->cacheBinary(genHash, genBinary, static_cast<uint32_t>(genBinarySize));
cache->cacheBinary(dbgHash, debugDataBinary, static_cast<uint32_t>(debugDataBinarySize));
}
retVal = igcOutput->Successful() ? SUCCESS : BUILD_PROGRAM_FAILURE;
return retVal;
}
@@ -504,6 +542,8 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector<std::string> &
std::unique_ptr<char[]> sourceFromFile;
size_t sourceFromFileSize = 0;
this->pBuildInfo = std::make_unique<buildInfo>();
auto cacheConfig = getDefaultCompilerCacheConfig();
cacheDir = cacheConfig.cacheDir;
retVal = parseCommandLine(numArgs, allArgs);
if (showHelp) {
printUsage();
@@ -630,6 +670,11 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector<std::string> &
argHelper->printf("Error! IGC initialization failure. Error code = %d\n", igcInitializationResult);
return igcInitializationResult;
}
if (allowCaching) {
cacheConfig.cacheDir = cacheDir;
cache = std::make_unique<CompilerCache>(cacheConfig);
createDir(cacheConfig.cacheDir);
}
return retVal;
}
@@ -686,6 +731,9 @@ int OfflineCompiler::parseCommandLine(size_t numArgs, const std::vector<std::str
} else if (("-out_dir" == currArg) && hasMoreArgs) {
outputDirectory = argv[argIndex + 1];
argIndex++;
} else if (("-cache_dir" == currArg) && hasMoreArgs) {
cacheDir = argv[argIndex + 1];
argIndex++;
} else if ("-q" == currArg) {
argHelper->getPrinterRef() = MessagePrinter(true);
quiet = true;
@@ -712,6 +760,8 @@ int OfflineCompiler::parseCommandLine(size_t numArgs, const std::vector<std::str
break;
}
argIndex++;
} else if ("-allow_caching" == currArg) {
allowCaching = true;
} else {
argHelper->printf("Invalid option (arg %d): %s\n", argIndex, argv[argIndex].c_str());
retVal = INVALID_COMMAND_LINE;
@@ -908,6 +958,13 @@ Usage: ocloc [compile] -file <filename> -device <device_type> [-output <filename
-out_dir <output_dir> Optional output directory.
Default is current working directory.
-allow_caching Allows caching binaries from compilation (like spirv,
gen or debug data) and loading them by ocloc
when the same program is compiled again.
-cache_dir <output_dir> Optional caching directory.
Default directory is "ocloc_cache".
-options <options> Optional OpenCL C compilation options
as defined by OpenCL specification.
Special options for Vector Compute:
@@ -1023,6 +1080,18 @@ bool OfflineCompiler::generateElfBinary() {
return true;
}
if (allowCaching) {
elfHash = cache->getCachedFileName(getHardwareInfo(),
genHash,
options,
internalOptions);
auto loadedData = cache->loadCachedBinary(elfHash, elfBinarySize);
elfBinary.assign(loadedData.get(), loadedData.get() + elfBinarySize);
if (!elfBinary.empty()) {
return true;
}
}
SingleDeviceBinary binary = {};
binary.buildOptions = this->options;
binary.intermediateRepresentation = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(this->irBinary), this->irBinarySize);
@@ -1056,7 +1125,9 @@ bool OfflineCompiler::generateElfBinary() {
}
this->elfBinary = elfEncoder.encode();
if (allowCaching) {
cache->cacheBinary(elfHash, reinterpret_cast<char *>(elfBinary.data()), static_cast<uint32_t>(this->elfBinary.size()));
}
return true;
}

View File

@@ -25,6 +25,7 @@ namespace NEO {
struct HardwareInfo;
class OsLibrary;
class CompilerCache;
std::string convertToPascalCase(const std::string &inString);
@@ -111,7 +112,7 @@ All supported acronyms: %s.
void storeBinary(char *&pDst, size_t &dstSize, const void *pSrc, const size_t srcSize);
MOCKABLE_VIRTUAL int buildSourceCode();
MOCKABLE_VIRTUAL std::string validateInputType(const std::string &input, bool isLlvm, bool isSpirv);
int buildIrBinary();
MOCKABLE_VIRTUAL int buildIrBinary();
void updateBuildLog(const char *pErrorString, const size_t errorStringSize);
MOCKABLE_VIRTUAL bool generateElfBinary();
std::string generateFilePathForIr(const std::string &fileNameBase) {
@@ -144,7 +145,10 @@ All supported acronyms: %s.
std::string optionsReadFromFile = "";
std::string internalOptionsReadFromFile = "";
std::string formatToEnforce = "";
std::string irHash, genHash, dbgHash, elfHash;
std::string cacheDir;
bool allowCaching = false;
bool dumpFiles = true;
bool useLlvmText = false;
bool useLlvmBc = false;
@@ -162,6 +166,7 @@ All supported acronyms: %s.
bool excludeIr = false;
std::vector<uint8_t> elfBinary;
size_t elfBinarySize = 0;
char *genBinary = nullptr;
size_t genBinarySize = 0;
char *irBinary = nullptr;
@@ -175,6 +180,7 @@ All supported acronyms: %s.
std::unique_ptr<OclocIgcFacade> igcFacade{nullptr};
std::unique_ptr<OclocFclFacade> fclFacade{nullptr};
std::unique_ptr<CompilerCache> cache;
IGC::CodeType::CodeType_t preferredIntermediateRepresentation;
OclocArgHelper *argHelper = nullptr;