mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-21 09:14:47 +08:00
Add cl_cache mechanism to ocloc
Related-To: NEO-6476 Signed-off-by: Baj, Tomasz <tomasz.baj@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
4292a47c53
commit
0eab93501c
@@ -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})
|
||||
|
||||
|
||||
17
shared/offline_compiler/source/default_cache_config.cpp
Normal file
17
shared/offline_compiler/source/default_cache_config.cpp
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user