mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 06:49:52 +08:00
Allow ocloc to link files
Added 'link' option to ocloc CLI, which allows linking of several IR files to single output file. Supported formats of output file are ELF and LLVM BC. Related-To: NEO-6163 Signed-off-by: Patryk Wrobel <patryk.wrobel@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
504b49effa
commit
53482e6821
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2020-2021 Intel Corporation
|
||||
# Copyright (C) 2020-2022 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
@@ -60,6 +60,7 @@ set(CLOC_LIB_SRCS_LIB
|
||||
${OCLOC_DIRECTORY}/source/ocloc_api.h
|
||||
${OCLOC_DIRECTORY}/source/ocloc_arg_helper.cpp
|
||||
${OCLOC_DIRECTORY}/source/ocloc_arg_helper.h
|
||||
${OCLOC_DIRECTORY}/source/ocloc_error_code.h
|
||||
${OCLOC_DIRECTORY}/source/ocloc_fatbinary.cpp
|
||||
${OCLOC_DIRECTORY}/source/ocloc_fatbinary.h
|
||||
${OCLOC_DIRECTORY}/source/ocloc_validator.cpp
|
||||
@@ -68,6 +69,8 @@ set(CLOC_LIB_SRCS_LIB
|
||||
${OCLOC_DIRECTORY}/source/offline_compiler.h
|
||||
${OCLOC_DIRECTORY}/source/offline_compiler_helper.cpp
|
||||
${OCLOC_DIRECTORY}/source/offline_compiler_options.cpp
|
||||
${OCLOC_DIRECTORY}/source/offline_linker.cpp
|
||||
${OCLOC_DIRECTORY}/source/offline_linker.h
|
||||
${OCLOC_DIRECTORY}/source/queries.h
|
||||
${OCLOC_DIRECTORY}/source/utilities/get_git_version_info.h
|
||||
${OCLOC_DIRECTORY}/source/utilities/get_git_version_info.cpp
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019-2021 Intel Corporation
|
||||
* Copyright (C) 2019-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "shared/offline_compiler/source/multi_command.h"
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_error_code.h"
|
||||
#include "shared/offline_compiler/source/ocloc_fatbinary.h"
|
||||
#include "shared/source/utilities/const_stringref.h"
|
||||
|
||||
@@ -14,13 +15,13 @@
|
||||
|
||||
namespace NEO {
|
||||
int MultiCommand::singleBuild(const std::vector<std::string> &args) {
|
||||
int retVal = OfflineCompiler::ErrorCode::SUCCESS;
|
||||
int retVal = OclocErrorCode::SUCCESS;
|
||||
|
||||
if (requestedFatBinary(args, argHelper)) {
|
||||
retVal = buildFatBinary(args, argHelper);
|
||||
} else {
|
||||
std::unique_ptr<OfflineCompiler> pCompiler{OfflineCompiler::create(args.size(), args, true, retVal, argHelper)};
|
||||
if (retVal == OfflineCompiler::ErrorCode::SUCCESS) {
|
||||
if (retVal == OclocErrorCode::SUCCESS) {
|
||||
retVal = buildWithSafetyGuard(pCompiler.get());
|
||||
|
||||
std::string &buildLog = pCompiler->getBuildLog();
|
||||
@@ -30,14 +31,14 @@ int MultiCommand::singleBuild(const std::vector<std::string> &args) {
|
||||
}
|
||||
outFileName += ".bin";
|
||||
}
|
||||
if (retVal == OfflineCompiler::ErrorCode::SUCCESS) {
|
||||
if (retVal == OclocErrorCode::SUCCESS) {
|
||||
if (!quiet)
|
||||
argHelper->printf("Build succeeded.\n");
|
||||
} else {
|
||||
argHelper->printf("Build failed with error code: %d\n", retVal);
|
||||
}
|
||||
|
||||
if (retVal == OfflineCompiler::ErrorCode::SUCCESS) {
|
||||
if (retVal == OclocErrorCode::SUCCESS) {
|
||||
outputFile << getCurrentDirectoryOwn(outDirForBuilds) + outFileName;
|
||||
} else {
|
||||
outputFile << "Unsuccesful build";
|
||||
@@ -48,7 +49,7 @@ int MultiCommand::singleBuild(const std::vector<std::string> &args) {
|
||||
}
|
||||
|
||||
MultiCommand *MultiCommand::create(const std::vector<std::string> &args, int &retVal, OclocArgHelper *helper) {
|
||||
retVal = OfflineCompiler::ErrorCode::SUCCESS;
|
||||
retVal = OclocErrorCode::SUCCESS;
|
||||
auto pMultiCommand = new MultiCommand();
|
||||
|
||||
if (pMultiCommand) {
|
||||
@@ -56,7 +57,7 @@ MultiCommand *MultiCommand::create(const std::vector<std::string> &args, int &re
|
||||
retVal = pMultiCommand->initialize(args);
|
||||
}
|
||||
|
||||
if (retVal != OfflineCompiler::ErrorCode::SUCCESS) {
|
||||
if (retVal != OclocErrorCode::SUCCESS) {
|
||||
delete pMultiCommand;
|
||||
pMultiCommand = nullptr;
|
||||
}
|
||||
@@ -107,7 +108,7 @@ int MultiCommand::initialize(const std::vector<std::string> &args) {
|
||||
} else {
|
||||
argHelper->printf("Invalid option (arg %zu): %s\n", argIndex, currArg.c_str());
|
||||
printHelp();
|
||||
return OfflineCompiler::ErrorCode::INVALID_COMMAND_LINE;
|
||||
return OclocErrorCode::INVALID_COMMAND_LINE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,11 +117,11 @@ int MultiCommand::initialize(const std::vector<std::string> &args) {
|
||||
argHelper->readFileToVectorOfStrings(pathToCommandFile, lines);
|
||||
if (lines.empty()) {
|
||||
argHelper->printf("Command file was empty.\n");
|
||||
return OfflineCompiler::ErrorCode::INVALID_FILE;
|
||||
return OclocErrorCode::INVALID_FILE;
|
||||
}
|
||||
} else {
|
||||
argHelper->printf("Could not find/open file with builds argument.s\n");
|
||||
return OfflineCompiler::ErrorCode::INVALID_FILE;
|
||||
return OclocErrorCode::INVALID_FILE;
|
||||
}
|
||||
|
||||
runBuilds(args[0]);
|
||||
@@ -136,7 +137,7 @@ void MultiCommand::runBuilds(const std::string &argZero) {
|
||||
std::vector<std::string> args = {argZero};
|
||||
|
||||
int retVal = splitLineInSeparateArgs(args, lines[i], i);
|
||||
if (retVal != OfflineCompiler::ErrorCode::SUCCESS) {
|
||||
if (retVal != OclocErrorCode::SUCCESS) {
|
||||
retValues.push_back(retVal);
|
||||
continue;
|
||||
}
|
||||
@@ -188,22 +189,22 @@ int MultiCommand::splitLineInSeparateArgs(std::vector<std::string> &qargs, const
|
||||
}
|
||||
if (end == std::string::npos) {
|
||||
argHelper->printf("One of the quotes is open in build number %zu\n", numberOfBuild + 1);
|
||||
return OfflineCompiler::ErrorCode::INVALID_FILE;
|
||||
return OclocErrorCode::INVALID_FILE;
|
||||
}
|
||||
argLen = end - start;
|
||||
i = end;
|
||||
qargs.push_back(commandsLine.substr(start, argLen));
|
||||
}
|
||||
return OfflineCompiler::ErrorCode::SUCCESS;
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
int MultiCommand::showResults() {
|
||||
int retValue = OfflineCompiler::ErrorCode::SUCCESS;
|
||||
int retValue = OclocErrorCode::SUCCESS;
|
||||
int indexRetVal = 0;
|
||||
for (int retVal : retValues) {
|
||||
retValue |= retVal;
|
||||
if (!quiet) {
|
||||
if (retVal != OfflineCompiler::ErrorCode::SUCCESS) {
|
||||
if (retVal != OclocErrorCode::SUCCESS) {
|
||||
argHelper->printf("Build command %d: failed. Error code: %d\n", indexRetVal, retVal);
|
||||
} else {
|
||||
argHelper->printf("Build command %d: successful\n", indexRetVal);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2021 Intel Corporation
|
||||
* Copyright (C) 2020-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -10,9 +10,11 @@
|
||||
#include "shared/offline_compiler/source/decoder/binary_decoder.h"
|
||||
#include "shared/offline_compiler/source/decoder/binary_encoder.h"
|
||||
#include "shared/offline_compiler/source/multi_command.h"
|
||||
#include "shared/offline_compiler/source/ocloc_error_code.h"
|
||||
#include "shared/offline_compiler/source/ocloc_fatbinary.h"
|
||||
#include "shared/offline_compiler/source/ocloc_validator.h"
|
||||
#include "shared/offline_compiler/source/offline_compiler.h"
|
||||
#include "shared/offline_compiler/source/offline_linker.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -36,6 +38,7 @@ Use 'ocloc <command> --help' to get help about specific command.
|
||||
|
||||
Commands:
|
||||
compile Compiles input to Intel Compute GPU device binary.
|
||||
link Links several IR files.
|
||||
disasm Disassembles Intel Compute GPU device binary.
|
||||
asm Assembles Intel Compute GPU device binary.
|
||||
multi Compiles multiple files using a config file.
|
||||
@@ -48,6 +51,9 @@ Examples:
|
||||
Compile file to Intel Compute GPU device binary (out = source_file_Gen9core.bin)
|
||||
ocloc -file source_file.cl -device skl
|
||||
|
||||
Link two SPIR-V files.
|
||||
ocloc link -file sample1.spv -file sample2.spv -out_format LLVM_BC -out samples_merged.llvm_bc
|
||||
|
||||
Disassemble Intel Compute GPU device binary
|
||||
ocloc disasm -file source_file_Gen9core.bin
|
||||
|
||||
@@ -108,7 +114,7 @@ int oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
try {
|
||||
if (numArgs == 1 || (numArgs > 1 && (ConstStringRef("-h") == allArgs[1] || ConstStringRef("--help") == allArgs[1]))) {
|
||||
helper->printf("%s", help);
|
||||
return OfflineCompiler::ErrorCode::SUCCESS;
|
||||
return OclocErrorCode::SUCCESS;
|
||||
} else if (numArgs > 1 && ConstStringRef("disasm") == allArgs[1]) {
|
||||
BinaryDecoder disasm(helper.get());
|
||||
int retVal = disasm.validateInput(allArgs);
|
||||
@@ -138,7 +144,7 @@ int oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
return retVal;
|
||||
}
|
||||
} else if (numArgs > 1 && ConstStringRef("multi") == allArgs[1]) {
|
||||
int retValue = OfflineCompiler::ErrorCode::SUCCESS;
|
||||
int retValue = OclocErrorCode::SUCCESS;
|
||||
std::unique_ptr<MultiCommand> pMulti{(MultiCommand::create(allArgs, retValue, helper.get()))};
|
||||
return retValue;
|
||||
} else if (requestedFatBinary(allArgs, helper.get())) {
|
||||
@@ -147,11 +153,26 @@ int oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
return NEO::Ocloc::validate(allArgs, helper.get());
|
||||
} else if (numArgs > 1 && ConstStringRef("query") == allArgs[1]) {
|
||||
return OfflineCompiler::query(numArgs, allArgs, helper.get());
|
||||
} else if (numArgs > 1 && ConstStringRef("link") == allArgs[1]) {
|
||||
int createResult{OclocErrorCode::SUCCESS};
|
||||
const auto linker{OfflineLinker::create(numArgs, allArgs, createResult, helper.get())};
|
||||
const auto linkingResult{linkWithSafetyGuard(linker.get())};
|
||||
|
||||
const auto buildLog = linker->getBuildLog();
|
||||
if (!buildLog.empty()) {
|
||||
helper->printf("%s\n", buildLog.c_str());
|
||||
}
|
||||
|
||||
if (createResult == OclocErrorCode::SUCCESS && linkingResult == OclocErrorCode::SUCCESS) {
|
||||
helper->printf("Linker execution has succeeded!\n");
|
||||
}
|
||||
|
||||
return createResult | linkingResult;
|
||||
} else {
|
||||
int retVal = OfflineCompiler::ErrorCode::SUCCESS;
|
||||
int retVal = OclocErrorCode::SUCCESS;
|
||||
|
||||
std::unique_ptr<OfflineCompiler> pCompiler{OfflineCompiler::create(numArgs, allArgs, true, retVal, helper.get())};
|
||||
if (retVal == OfflineCompiler::ErrorCode::SUCCESS) {
|
||||
if (retVal == OclocErrorCode::SUCCESS) {
|
||||
retVal = buildWithSafetyGuard(pCompiler.get());
|
||||
|
||||
std::string buildLog = pCompiler->getBuildLog();
|
||||
@@ -159,7 +180,7 @@ int oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
helper->printf("%s\n", buildLog.c_str());
|
||||
}
|
||||
|
||||
if (retVal == OfflineCompiler::ErrorCode::SUCCESS) {
|
||||
if (retVal == OclocErrorCode::SUCCESS) {
|
||||
if (!pCompiler->isQuiet())
|
||||
helper->printf("Build succeeded.\n");
|
||||
} else {
|
||||
@@ -167,7 +188,7 @@ int oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
}
|
||||
}
|
||||
|
||||
if (retVal != OfflineCompiler::ErrorCode::SUCCESS) {
|
||||
if (retVal != OclocErrorCode::SUCCESS) {
|
||||
printOclocOptionsReadFromFile(pCompiler.get());
|
||||
printOclocCmdLine(numArgs, argv, helper);
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ class OclocArgHelper {
|
||||
bool isFatbinary() {
|
||||
return fatBinary;
|
||||
}
|
||||
void saveOutput(const std::string &filename, const void *pData, const size_t &dataSize);
|
||||
MOCKABLE_VIRTUAL void saveOutput(const std::string &filename, const void *pData, const size_t &dataSize);
|
||||
void saveOutput(const std::string &filename, const std::ostream &stream);
|
||||
|
||||
MessagePrinter &getPrinterRef() { return messagePrinter; }
|
||||
|
||||
22
shared/offline_compiler/source/ocloc_error_code.h
Normal file
22
shared/offline_compiler/source/ocloc_error_code.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace NEO::OclocErrorCode {
|
||||
|
||||
enum {
|
||||
SUCCESS = 0,
|
||||
OUT_OF_HOST_MEMORY = -6,
|
||||
BUILD_PROGRAM_FAILURE = -11,
|
||||
INVALID_DEVICE = -33,
|
||||
INVALID_PROGRAM = -44,
|
||||
INVALID_COMMAND_LINE = -5150,
|
||||
INVALID_FILE = -5151,
|
||||
};
|
||||
|
||||
} // namespace NEO::OclocErrorCode
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2021 Intel Corporation
|
||||
* Copyright (C) 2020-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_fatbinary.h"
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_error_code.h"
|
||||
#include "shared/offline_compiler/source/utilities/safety_caller.h"
|
||||
#include "shared/source/helpers/file_io.h"
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
@@ -378,7 +379,7 @@ int buildFatBinary(const std::vector<std::string> &args, OclocArgHelper *argHelp
|
||||
argsCopy[deviceArgIndex] = targetPlatform.str();
|
||||
|
||||
std::unique_ptr<OfflineCompiler> pCompiler{OfflineCompiler::create(argsCopy.size(), argsCopy, false, retVal, argHelper)};
|
||||
if (OfflineCompiler::ErrorCode::SUCCESS != retVal) {
|
||||
if (OclocErrorCode::SUCCESS != retVal) {
|
||||
argHelper->printf("Error! Couldn't create OfflineCompiler. Exiting.\n");
|
||||
return retVal;
|
||||
}
|
||||
@@ -402,7 +403,7 @@ int buildFatBinary(const std::vector<std::string> &args, OclocArgHelper *argHelp
|
||||
argHelper->setFatbinary(true);
|
||||
argHelper->setDeviceInfoForFatbinaryTarget(targetConfig);
|
||||
std::unique_ptr<OfflineCompiler> pCompiler{OfflineCompiler::create(argsCopy.size(), argsCopy, false, retVal, argHelper)};
|
||||
if (OfflineCompiler::ErrorCode::SUCCESS != retVal) {
|
||||
if (OclocErrorCode::SUCCESS != retVal) {
|
||||
argHelper->printf("Error! Couldn't create OfflineCompiler. Exiting.\n");
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "offline_compiler.h"
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_error_code.h"
|
||||
#include "shared/offline_compiler/source/queries.h"
|
||||
#include "shared/offline_compiler/source/utilities/get_git_version_info.h"
|
||||
#include "shared/source/compiler_interface/intermediate_representations.h"
|
||||
@@ -50,6 +51,8 @@
|
||||
#define GetCurrentWorkingDirectory getcwd
|
||||
#endif
|
||||
|
||||
using namespace NEO::OclocErrorCode;
|
||||
|
||||
namespace NEO {
|
||||
|
||||
CIF::CIFMain *createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc);
|
||||
|
||||
@@ -33,16 +33,6 @@ std::string getDevicesTypes();
|
||||
|
||||
class OfflineCompiler {
|
||||
public:
|
||||
enum ErrorCode {
|
||||
SUCCESS = 0,
|
||||
OUT_OF_HOST_MEMORY = -6,
|
||||
BUILD_PROGRAM_FAILURE = -11,
|
||||
INVALID_DEVICE = -33,
|
||||
INVALID_PROGRAM = -44,
|
||||
INVALID_COMMAND_LINE = -5150,
|
||||
INVALID_FILE = -5151,
|
||||
};
|
||||
|
||||
static int query(size_t numArgs, const std::vector<std::string> &allArgs, OclocArgHelper *helper);
|
||||
|
||||
static OfflineCompiler *create(size_t numArgs, const std::vector<std::string> &allArgs, bool dumpFiles, int &retVal, OclocArgHelper *helper);
|
||||
|
||||
409
shared/offline_compiler/source/offline_linker.cpp
Normal file
409
shared/offline_compiler/source/offline_linker.cpp
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "offline_linker.h"
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_arg_helper.h"
|
||||
#include "shared/offline_compiler/source/ocloc_error_code.h"
|
||||
#include "shared/source/compiler_interface/intermediate_representations.h"
|
||||
#include "shared/source/device_binary_format/elf/elf_encoder.h"
|
||||
#include "shared/source/device_binary_format/elf/ocl_elf.h"
|
||||
#include "shared/source/helpers/compiler_hw_info_config.h"
|
||||
#include "shared/source/helpers/string.h"
|
||||
#include "shared/source/os_interface/os_inc_base.h"
|
||||
#include "shared/source/os_interface/os_library.h"
|
||||
|
||||
#include "cif/common/cif_main.h"
|
||||
#include "ocl_igc_interface/platform_helper.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
CIF::CIFMain *createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc);
|
||||
|
||||
std::unique_ptr<OfflineLinker> OfflineLinker::create(size_t argsCount, const std::vector<std::string> &args, int &errorCode, OclocArgHelper *argHelper) {
|
||||
std::unique_ptr<OfflineLinker> linker{new OfflineLinker{argHelper}};
|
||||
errorCode = linker->initialize(argsCount, args);
|
||||
|
||||
return linker;
|
||||
}
|
||||
|
||||
OfflineLinker::OfflineLinker(OclocArgHelper *argHelper)
|
||||
: argHelper{argHelper}, operationMode{OperationMode::SKIP_EXECUTION}, outputFilename{"linker_output"}, outputFormat{IGC::CodeType::llvmBc} {}
|
||||
|
||||
OfflineLinker::~OfflineLinker() = default;
|
||||
|
||||
int OfflineLinker::initialize(size_t argsCount, const std::vector<std::string> &args) {
|
||||
const auto parsingResult{parseCommand(argsCount, args)};
|
||||
if (parsingResult != OclocErrorCode::SUCCESS) {
|
||||
return parsingResult;
|
||||
}
|
||||
|
||||
// If a user requested help, then stop here.
|
||||
if (operationMode == OperationMode::SHOW_HELP) {
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
const auto verificationResult{verifyLinkerCommand()};
|
||||
if (verificationResult != OclocErrorCode::SUCCESS) {
|
||||
return verificationResult;
|
||||
}
|
||||
|
||||
const auto loadingResult{loadInputFilesContent()};
|
||||
if (loadingResult != OclocErrorCode::SUCCESS) {
|
||||
return loadingResult;
|
||||
}
|
||||
|
||||
const auto hwInfoInitializationResult{initHardwareInfo()};
|
||||
if (hwInfoInitializationResult != OclocErrorCode::SUCCESS) {
|
||||
return hwInfoInitializationResult;
|
||||
}
|
||||
|
||||
const auto igcPreparationResult{prepareIgc()};
|
||||
if (igcPreparationResult != OclocErrorCode::SUCCESS) {
|
||||
return igcPreparationResult;
|
||||
}
|
||||
|
||||
operationMode = OperationMode::LINK_FILES;
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
int OfflineLinker::parseCommand(size_t argsCount, const std::vector<std::string> &args) {
|
||||
if (argsCount < 2u) {
|
||||
operationMode = OperationMode::SHOW_HELP;
|
||||
return OclocErrorCode::INVALID_COMMAND_LINE;
|
||||
}
|
||||
|
||||
for (size_t argIndex = 1u; argIndex < argsCount; ++argIndex) {
|
||||
const auto ¤tArg{args[argIndex]};
|
||||
const auto hasMoreArgs{argIndex + 1 < argsCount};
|
||||
|
||||
if (currentArg == "link") {
|
||||
continue;
|
||||
} else if ((currentArg == "-file") && hasMoreArgs) {
|
||||
inputFilenames.push_back(args[argIndex + 1]);
|
||||
++argIndex;
|
||||
} else if (currentArg == "-out" && hasMoreArgs) {
|
||||
outputFilename = args[argIndex + 1];
|
||||
++argIndex;
|
||||
} else if ((currentArg == "-out_format") && hasMoreArgs) {
|
||||
outputFormat = parseOutputFormat(args[argIndex + 1]);
|
||||
++argIndex;
|
||||
} else if ((currentArg == "-options") && hasMoreArgs) {
|
||||
options = args[argIndex + 1];
|
||||
++argIndex;
|
||||
} else if ((currentArg == "-internal_options") && hasMoreArgs) {
|
||||
internalOptions = args[argIndex + 1];
|
||||
++argIndex;
|
||||
} else if (currentArg == "--help") {
|
||||
operationMode = OperationMode::SHOW_HELP;
|
||||
return OclocErrorCode::SUCCESS;
|
||||
} else {
|
||||
argHelper->printf("Invalid option (arg %zd): %s\n", argIndex, currentArg.c_str());
|
||||
return OclocErrorCode::INVALID_COMMAND_LINE;
|
||||
}
|
||||
}
|
||||
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
IGC::CodeType::CodeType_t OfflineLinker::parseOutputFormat(const std::string &outputFormatName) {
|
||||
constexpr static std::array supportedFormatNames = {
|
||||
std::pair{"ELF", IGC::CodeType::elf},
|
||||
std::pair{"LLVM_BC", IGC::CodeType::llvmBc}};
|
||||
|
||||
for (const auto &[name, format] : supportedFormatNames) {
|
||||
if (name == outputFormatName) {
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
return IGC::CodeType::invalid;
|
||||
}
|
||||
|
||||
int OfflineLinker::verifyLinkerCommand() {
|
||||
if (inputFilenames.empty()) {
|
||||
argHelper->printf("Error: Input name is missing! At least one input file is required!\n");
|
||||
return OclocErrorCode::INVALID_COMMAND_LINE;
|
||||
}
|
||||
|
||||
for (const auto &filename : inputFilenames) {
|
||||
if (filename.empty()) {
|
||||
argHelper->printf("Error: Empty filename cannot be used!\n");
|
||||
return OclocErrorCode::INVALID_COMMAND_LINE;
|
||||
}
|
||||
|
||||
if (!argHelper->fileExists(filename)) {
|
||||
argHelper->printf("Error: Input file %s missing.\n", filename.c_str());
|
||||
return OclocErrorCode::INVALID_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
if (outputFormat == IGC::CodeType::invalid) {
|
||||
argHelper->printf("Error: Invalid output type!\n");
|
||||
return OclocErrorCode::INVALID_COMMAND_LINE;
|
||||
}
|
||||
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
int OfflineLinker::loadInputFilesContent() {
|
||||
std::unique_ptr<char[]> bytes{};
|
||||
size_t size{};
|
||||
IGC::CodeType::CodeType_t codeType{};
|
||||
|
||||
inputFilesContent.reserve(inputFilenames.size());
|
||||
|
||||
for (const auto &filename : inputFilenames) {
|
||||
size = 0;
|
||||
bytes = argHelper->loadDataFromFile(filename, size);
|
||||
if (bytes == nullptr || size == 0) {
|
||||
argHelper->printf("Error: Cannot read input file: %s\n", filename.c_str());
|
||||
return OclocErrorCode::INVALID_FILE;
|
||||
}
|
||||
|
||||
codeType = detectCodeType(bytes.get(), size);
|
||||
if (codeType == IGC::CodeType::invalid) {
|
||||
argHelper->printf("Error: Unsupported format of input file: %s\n", filename.c_str());
|
||||
return OclocErrorCode::INVALID_PROGRAM;
|
||||
}
|
||||
|
||||
inputFilesContent.emplace_back(std::move(bytes), size, codeType);
|
||||
}
|
||||
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
IGC::CodeType::CodeType_t OfflineLinker::detectCodeType(char *bytes, size_t size) const {
|
||||
const auto bytesArray = ArrayRef<const uint8_t>::fromAny(bytes, size);
|
||||
if (isSpirVBitcode(bytesArray)) {
|
||||
return IGC::CodeType::spirV;
|
||||
}
|
||||
|
||||
if (isLlvmBitcode(bytesArray)) {
|
||||
return IGC::CodeType::llvmBc;
|
||||
}
|
||||
|
||||
return IGC::CodeType::invalid;
|
||||
}
|
||||
|
||||
int OfflineLinker::initHardwareInfo() {
|
||||
// In spite of linking input files to intermediate representation instead of native binaries,
|
||||
// we have to initialize hardware info. Without that, initialization of IGC fails.
|
||||
// Therefore, we select the first valid hardware info entry and use it.
|
||||
const auto hwInfoTable{getHardwareInfoTable()};
|
||||
for (auto productId = 0u; productId < hwInfoTable.size(); ++productId) {
|
||||
if (hwInfoTable[productId]) {
|
||||
hwInfo = *hwInfoTable[productId];
|
||||
|
||||
const auto hwInfoConfig = defaultHardwareInfoConfigTable[hwInfo.platform.eProductFamily];
|
||||
setHwInfoValuesFromConfig(hwInfoConfig, hwInfo);
|
||||
hardwareInfoSetup[hwInfo.platform.eProductFamily](&hwInfo, true, hwInfoConfig);
|
||||
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
argHelper->printf("Error! Cannot retrieve any valid hardware information!\n");
|
||||
return OclocErrorCode::INVALID_DEVICE;
|
||||
}
|
||||
|
||||
ArrayRef<const HardwareInfo *> OfflineLinker::getHardwareInfoTable() const {
|
||||
return {hardwareInfoTable};
|
||||
}
|
||||
|
||||
int OfflineLinker::prepareIgc() {
|
||||
igcLib = loadIgcLibrary();
|
||||
if (!igcLib) {
|
||||
argHelper->printf("Error! Loading of IGC library has failed! Filename: %s\n", Os::igcDllName);
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
const auto igcCreateMainFunction = loadCreateIgcMainFunction();
|
||||
if (!igcCreateMainFunction) {
|
||||
argHelper->printf("Error! Cannot load required functions from IGC library.\n");
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
igcMain = createIgcMain(igcCreateMainFunction);
|
||||
if (!igcMain) {
|
||||
argHelper->printf("Error! Cannot create IGC main component!\n");
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
igcDeviceCtx = createIgcDeviceContext();
|
||||
if (!igcDeviceCtx) {
|
||||
argHelper->printf("Error! Cannot create IGC device context!\n");
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
const auto igcPlatform = getIgcPlatformHandle();
|
||||
const auto igcGtSystemInfo = getGTSystemInfoHandle();
|
||||
if (!igcPlatform || !igcGtSystemInfo) {
|
||||
argHelper->printf("Error! IGC device context has not been properly created!\n");
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
IGC::PlatformHelper::PopulateInterfaceWith(*igcPlatform.get(), hwInfo.platform);
|
||||
IGC::GtSysInfoHelper::PopulateInterfaceWith(*igcGtSystemInfo.get(), hwInfo.gtSystemInfo);
|
||||
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
std::unique_ptr<OsLibrary> OfflineLinker::loadIgcLibrary() const {
|
||||
return std::unique_ptr<OsLibrary>{OsLibrary::load(Os::igcDllName)};
|
||||
}
|
||||
|
||||
CIF::CreateCIFMainFunc_t OfflineLinker::loadCreateIgcMainFunction() const {
|
||||
return reinterpret_cast<CIF::CreateCIFMainFunc_t>(igcLib->getProcAddress(CIF::CreateCIFMainFuncName));
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<CIF::CIFMain> OfflineLinker::createIgcMain(CIF::CreateCIFMainFunc_t createMainFunction) const {
|
||||
return CIF::RAII::UPtr(createMainNoSanitize(createMainFunction));
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::IgcOclDeviceCtxTagOCL> OfflineLinker::createIgcDeviceContext() const {
|
||||
return igcMain->CreateInterface<IGC::IgcOclDeviceCtxTagOCL>();
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::PlatformTagOCL> OfflineLinker::getIgcPlatformHandle() const {
|
||||
return igcDeviceCtx->GetPlatformHandle();
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::GTSystemInfoTagOCL> OfflineLinker::getGTSystemInfoHandle() const {
|
||||
return igcDeviceCtx->GetGTSystemInfoHandle();
|
||||
}
|
||||
|
||||
int OfflineLinker::execute() {
|
||||
switch (operationMode) {
|
||||
case OperationMode::SHOW_HELP:
|
||||
return showHelp();
|
||||
case OperationMode::LINK_FILES:
|
||||
return link();
|
||||
case OperationMode::SKIP_EXECUTION:
|
||||
[[fallthrough]];
|
||||
default:
|
||||
argHelper->printf("Error: Linker cannot be executed due to unsuccessful initialization!\n");
|
||||
return OclocErrorCode::INVALID_COMMAND_LINE;
|
||||
}
|
||||
}
|
||||
|
||||
int OfflineLinker::showHelp() {
|
||||
constexpr auto help{R"===(Links several IR files to selected output format (LLVM BC, ELF).
|
||||
Input files can be given in SPIR-V or LLVM BC.
|
||||
|
||||
Usage: ocloc link [-file <filename>]... -out <filename> [-out_format <format>] [-options <options>] [-internal_options <options>] [--help]
|
||||
|
||||
-file <filename> The input file to be linked.
|
||||
Multiple files can be passed using repetition of this arguments.
|
||||
Please see examples below.
|
||||
|
||||
-out <filename> Output filename.
|
||||
|
||||
-out_format <format> Output file format. Supported ones are ELF and LLVM_BC.
|
||||
When not specified, LLVM_BC is used.
|
||||
|
||||
-options <options> Optional OpenCL C compilation options
|
||||
as defined by OpenCL specification.
|
||||
|
||||
-internal_options <options> Optional compiler internal options
|
||||
as defined by compilers used underneath.
|
||||
Check intel-graphics-compiler (IGC) project
|
||||
for details on available internal options.
|
||||
You also may provide explicit --help to inquire
|
||||
information about option, mentioned in -options.
|
||||
|
||||
--help Print this usage message.
|
||||
|
||||
Examples:
|
||||
Link two SPIR-V files to LLVM BC output
|
||||
ocloc link -file first_file.spv -file second_file.spv -out linker_output.llvmbc
|
||||
|
||||
Link two LLVM BC files to ELF output
|
||||
ocloc link -file first_file.llvmbc -file second_file.llvmbc -out_format ELF -out translated.elf
|
||||
)==="};
|
||||
|
||||
argHelper->printf(help);
|
||||
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
int OfflineLinker::link() {
|
||||
const auto encodedElfFile{createSingleInputFile()};
|
||||
if (outputFormat == IGC::CodeType::elf) {
|
||||
argHelper->saveOutput(outputFilename, encodedElfFile.data(), encodedElfFile.size());
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
const auto [translationResult, translatedBitcode] = translateToOutputFormat(encodedElfFile);
|
||||
if (translationResult == OclocErrorCode::SUCCESS) {
|
||||
argHelper->saveOutput(outputFilename, translatedBitcode.data(), translatedBitcode.size());
|
||||
}
|
||||
|
||||
return translationResult;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> OfflineLinker::createSingleInputFile() const {
|
||||
NEO::Elf::ElfEncoder<> elfEncoder{true, false, 1U};
|
||||
elfEncoder.getElfFileHeader().type = Elf::ET_OPENCL_OBJECTS;
|
||||
|
||||
for (const auto &[bytes, size, codeType] : inputFilesContent) {
|
||||
const auto isSpirv = codeType == IGC::CodeType::spirV;
|
||||
const auto sectionType = isSpirv ? Elf::SHT_OPENCL_SPIRV : Elf::SHT_OPENCL_LLVM_BINARY;
|
||||
const auto sectionName = isSpirv ? Elf::SectionNamesOpenCl::spirvObject : Elf::SectionNamesOpenCl::llvmObject;
|
||||
const auto bytesArray = ArrayRef<const uint8_t>::fromAny(bytes.get(), size);
|
||||
|
||||
elfEncoder.appendSection(sectionType, sectionName, bytesArray);
|
||||
}
|
||||
|
||||
return elfEncoder.encode();
|
||||
}
|
||||
|
||||
std::pair<int, std::vector<uint8_t>> OfflineLinker::translateToOutputFormat(const std::vector<uint8_t> &elfInput) {
|
||||
auto igcSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), elfInput.data(), elfInput.size());
|
||||
auto igcOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), options.c_str(), options.size());
|
||||
auto igcInternalOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), internalOptions.c_str(), internalOptions.size());
|
||||
auto igcTranslationCtx = igcDeviceCtx->CreateTranslationCtx(IGC::CodeType::elf, outputFormat);
|
||||
|
||||
const auto tracingOptions{nullptr};
|
||||
const auto tracingOptionsSize{0};
|
||||
const auto igcOutput = igcTranslationCtx->Translate(igcSrc.get(), igcOptions.get(), igcInternalOptions.get(), tracingOptions, tracingOptionsSize);
|
||||
|
||||
std::vector<uint8_t> outputFileContent{};
|
||||
if (!igcOutput) {
|
||||
argHelper->printf("Error: Translation has failed! IGC output is nullptr!\n");
|
||||
return {OclocErrorCode::OUT_OF_HOST_MEMORY, std::move(outputFileContent)};
|
||||
}
|
||||
|
||||
if (igcOutput->GetOutput()->GetSizeRaw() != 0) {
|
||||
outputFileContent.resize(igcOutput->GetOutput()->GetSizeRaw());
|
||||
memcpy_s(outputFileContent.data(), outputFileContent.size(), igcOutput->GetOutput()->GetMemory<char>(), igcOutput->GetOutput()->GetSizeRaw());
|
||||
}
|
||||
|
||||
tryToStoreBuildLog(igcOutput->GetBuildLog()->GetMemory<char>(), igcOutput->GetBuildLog()->GetSizeRaw());
|
||||
|
||||
const auto errorCode{igcOutput->Successful() ? OclocErrorCode::SUCCESS : OclocErrorCode::BUILD_PROGRAM_FAILURE};
|
||||
if (errorCode != OclocErrorCode::SUCCESS) {
|
||||
argHelper->printf("Error: Translation has failed! IGC returned empty output.\n");
|
||||
}
|
||||
|
||||
return {errorCode, std::move(outputFileContent)};
|
||||
}
|
||||
|
||||
std::string OfflineLinker::getBuildLog() const {
|
||||
return buildLog;
|
||||
}
|
||||
|
||||
void OfflineLinker::tryToStoreBuildLog(const char *buildLogRaw, size_t size) {
|
||||
if (buildLogRaw && size != 0) {
|
||||
buildLog = std::string{buildLogRaw, buildLogRaw + size};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
95
shared/offline_compiler/source/offline_linker.h
Normal file
95
shared/offline_compiler/source/offline_linker.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
#include "shared/source/utilities/arrayref.h"
|
||||
|
||||
#include "cif/common/cif_main.h"
|
||||
#include "cif/import/library_api.h"
|
||||
#include "ocl_igc_interface/code_type.h"
|
||||
#include "ocl_igc_interface/igc_ocl_device_ctx.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class OclocArgHelper;
|
||||
|
||||
namespace NEO {
|
||||
|
||||
class OsLibrary;
|
||||
|
||||
class OfflineLinker {
|
||||
protected:
|
||||
enum class OperationMode {
|
||||
SKIP_EXECUTION = 0,
|
||||
SHOW_HELP = 1,
|
||||
LINK_FILES = 2,
|
||||
};
|
||||
|
||||
struct InputFileContent {
|
||||
InputFileContent(std::unique_ptr<char[]> bytes, size_t size, IGC::CodeType::CodeType_t codeType)
|
||||
: bytes{std::move(bytes)}, size{size}, codeType{codeType} {}
|
||||
|
||||
std::unique_ptr<char[]> bytes{};
|
||||
size_t size{};
|
||||
IGC::CodeType::CodeType_t codeType{};
|
||||
};
|
||||
|
||||
public:
|
||||
static std::unique_ptr<OfflineLinker> create(size_t argsCount, const std::vector<std::string> &args, int &errorCode, OclocArgHelper *argHelper);
|
||||
MOCKABLE_VIRTUAL ~OfflineLinker();
|
||||
|
||||
int execute();
|
||||
std::string getBuildLog() const;
|
||||
|
||||
protected:
|
||||
explicit OfflineLinker(OclocArgHelper *argHelper);
|
||||
int initialize(size_t argsCount, const std::vector<std::string> &args);
|
||||
int parseCommand(size_t argsCount, const std::vector<std::string> &args);
|
||||
IGC::CodeType::CodeType_t parseOutputFormat(const std::string &outputFormatName);
|
||||
int verifyLinkerCommand();
|
||||
int loadInputFilesContent();
|
||||
IGC::CodeType::CodeType_t detectCodeType(char *bytes, size_t size) const;
|
||||
int initHardwareInfo();
|
||||
int prepareIgc();
|
||||
int link();
|
||||
int showHelp();
|
||||
std::vector<uint8_t> createSingleInputFile() const;
|
||||
std::pair<int, std::vector<uint8_t>> translateToOutputFormat(const std::vector<uint8_t> &elfInput);
|
||||
void tryToStoreBuildLog(const char *buildLogRaw, size_t size);
|
||||
|
||||
MOCKABLE_VIRTUAL ArrayRef<const HardwareInfo *> getHardwareInfoTable() const;
|
||||
MOCKABLE_VIRTUAL std::unique_ptr<OsLibrary> loadIgcLibrary() const;
|
||||
MOCKABLE_VIRTUAL CIF::CreateCIFMainFunc_t loadCreateIgcMainFunction() const;
|
||||
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<CIF::CIFMain> createIgcMain(CIF::CreateCIFMainFunc_t createMainFunction) const;
|
||||
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<IGC::IgcOclDeviceCtxTagOCL> createIgcDeviceContext() const;
|
||||
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<IGC::PlatformTagOCL> getIgcPlatformHandle() const;
|
||||
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<IGC::GTSystemInfoTagOCL> getGTSystemInfoHandle() const;
|
||||
|
||||
OclocArgHelper *argHelper{};
|
||||
OperationMode operationMode{};
|
||||
|
||||
std::vector<std::string> inputFilenames{};
|
||||
std::vector<InputFileContent> inputFilesContent{};
|
||||
std::string outputFilename{};
|
||||
IGC::CodeType::CodeType_t outputFormat{};
|
||||
std::string options{};
|
||||
std::string internalOptions{};
|
||||
|
||||
std::unique_ptr<OsLibrary> igcLib{};
|
||||
CIF::RAII::UPtr_t<CIF::CIFMain> igcMain{};
|
||||
CIF::RAII::UPtr_t<IGC::IgcOclDeviceCtxTagOCL> igcDeviceCtx{};
|
||||
HardwareInfo hwInfo{};
|
||||
std::string buildLog{};
|
||||
};
|
||||
|
||||
} // namespace NEO
|
||||
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2021 Intel Corporation
|
||||
* Copyright (C) 2020-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/offline_compiler/source/offline_compiler.h"
|
||||
#include "shared/offline_compiler/source/offline_linker.h"
|
||||
#include "shared/offline_compiler/source/utilities/linux/safety_guard_linux.h"
|
||||
#include "shared/source/os_interface/os_library.h"
|
||||
|
||||
@@ -17,3 +18,10 @@ int buildWithSafetyGuard(OfflineCompiler *compiler) {
|
||||
|
||||
return safetyGuard.call<int, OfflineCompiler, decltype(&OfflineCompiler::build)>(compiler, &OfflineCompiler::build, retVal);
|
||||
}
|
||||
|
||||
int linkWithSafetyGuard(OfflineLinker *linker) {
|
||||
SafetyGuardLinux safetyGuard{};
|
||||
int returnValueOnCrash{-1};
|
||||
|
||||
return safetyGuard.call(linker, &OfflineLinker::execute, returnValueOnCrash);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 Intel Corporation
|
||||
* Copyright (C) 2018-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -8,6 +8,8 @@
|
||||
#pragma once
|
||||
namespace NEO {
|
||||
class OfflineCompiler;
|
||||
}
|
||||
class OfflineLinker;
|
||||
} // namespace NEO
|
||||
|
||||
extern int buildWithSafetyGuard(NEO::OfflineCompiler *compiler);
|
||||
extern int buildWithSafetyGuard(NEO::OfflineCompiler *compiler);
|
||||
extern int linkWithSafetyGuard(NEO::OfflineLinker *linker);
|
||||
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2021 Intel Corporation
|
||||
* Copyright (C) 2020-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/offline_compiler/source/offline_compiler.h"
|
||||
#include "shared/offline_compiler/source/offline_linker.h"
|
||||
#include "shared/offline_compiler/source/utilities/windows/safety_guard_windows.h"
|
||||
|
||||
using namespace NEO;
|
||||
@@ -15,3 +16,10 @@ int buildWithSafetyGuard(OfflineCompiler *compiler) {
|
||||
int retVal = 0;
|
||||
return safetyGuard.call<int, OfflineCompiler, decltype(&OfflineCompiler::build)>(compiler, &OfflineCompiler::build, retVal);
|
||||
}
|
||||
|
||||
int linkWithSafetyGuard(OfflineLinker *linker) {
|
||||
SafetyGuardWindows safetyGuard{};
|
||||
int returnValueOnCrash{-1};
|
||||
|
||||
return safetyGuard.call(linker, &OfflineLinker::execute, returnValueOnCrash);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Intel Corporation
|
||||
* Copyright (C) 2018-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -521,6 +521,10 @@ IGC::OclTranslationOutputBase *MockIgcOclTranslationCtx::TranslateImpl(
|
||||
CIF::Builtins::BufferSimple *internalOptions,
|
||||
CIF::Builtins::BufferSimple *tracingOptions,
|
||||
uint32_t tracingOptionsCount) {
|
||||
if (igcDebugVars->shouldReturnInvalidTranslationOutput) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto out = new MockOclTranslationOutput();
|
||||
translate(true, src, options, internalOptions, out);
|
||||
return out;
|
||||
@@ -534,6 +538,10 @@ IGC::OclTranslationOutputBase *MockIgcOclTranslationCtx::TranslateImpl(
|
||||
CIF::Builtins::BufferSimple *tracingOptions,
|
||||
uint32_t tracingOptionsCount,
|
||||
void *gtpinInput) {
|
||||
if (igcDebugVars->shouldReturnInvalidTranslationOutput) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto out = new MockOclTranslationOutput();
|
||||
translate(true, src, options, internalOptions, out);
|
||||
return out;
|
||||
@@ -556,6 +564,10 @@ IGC::OclTranslationOutputBase *MockIgcOclTranslationCtx::TranslateImpl(
|
||||
CIF::Builtins::BufferSimple *tracingOptions,
|
||||
uint32_t tracingOptionsCount,
|
||||
void *gtPinInput) {
|
||||
if (igcDebugVars->shouldReturnInvalidTranslationOutput) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto out = new MockOclTranslationOutput();
|
||||
translate(true, src, options, internalOptions, out);
|
||||
return out;
|
||||
@@ -618,6 +630,10 @@ IGC::OclTranslationOutputBase *MockFclOclTranslationCtx::TranslateImpl(
|
||||
CIF::Builtins::BufferSimple *internalOptions,
|
||||
CIF::Builtins::BufferSimple *tracingOptions,
|
||||
uint32_t tracingOptionsCount) {
|
||||
if (fclDebugVars->shouldReturnInvalidTranslationOutput) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto out = new MockOclTranslationOutput();
|
||||
translate(false, src, options, internalOptions, out);
|
||||
return out;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2021 Intel Corporation
|
||||
* Copyright (C) 2018-2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -25,6 +25,7 @@ struct MockCompilerDebugVars {
|
||||
bindful,
|
||||
bindless
|
||||
};
|
||||
bool shouldReturnInvalidTranslationOutput = false;
|
||||
bool forceBuildFailure = false;
|
||||
bool forceCreateFailure = false;
|
||||
bool forceRegisterFail = false;
|
||||
|
||||
Reference in New Issue
Block a user