mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-04 15:53:45 +08:00
[N/N] compiler interface refactor - move to core
Change-Id: I029e3cd7a6adde9df97a0a7760ecbf5d25d8f501
This commit is contained in:
@@ -8,6 +8,10 @@ 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}/compiler_interface.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compiler_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/compiler_interface.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/create_main.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linker.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/linker.cpp
|
||||
)
|
||||
|
||||
465
core/compiler_interface/compiler_interface.cpp
Normal file
465
core/compiler_interface/compiler_interface.cpp
Normal file
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/compiler_interface/compiler_interface.h"
|
||||
|
||||
#include "core/compiler_interface/compiler_cache.h"
|
||||
#include "core/compiler_interface/compiler_interface.inl"
|
||||
#include "runtime/device/device.h"
|
||||
#include "runtime/helpers/hw_info.h"
|
||||
#include "runtime/os_interface/debug_settings_manager.h"
|
||||
#include "runtime/os_interface/os_inc_base.h"
|
||||
|
||||
#include "cif/common/cif_main.h"
|
||||
#include "cif/helpers/error.h"
|
||||
#include "cif/import/library_api.h"
|
||||
#include "ocl_igc_interface/code_type.h"
|
||||
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
||||
#include "ocl_igc_interface/igc_ocl_device_ctx.h"
|
||||
#include "ocl_igc_interface/platform_helper.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace NEO {
|
||||
std::mutex CompilerInterface::mtx;
|
||||
|
||||
enum CachingMode {
|
||||
None,
|
||||
Direct,
|
||||
PreProcess
|
||||
};
|
||||
|
||||
CompilerInterface::CompilerInterface()
|
||||
: cache() {
|
||||
}
|
||||
CompilerInterface::~CompilerInterface() = default;
|
||||
|
||||
TranslationOutput::ErrorCode CompilerInterface::build(
|
||||
const NEO::Device &device,
|
||||
const TranslationInput &input,
|
||||
TranslationOutput &output) {
|
||||
if (false == isCompilerAvailable(input.srcType, input.outType)) {
|
||||
return TranslationOutput::ErrorCode::CompilerNotAvailable;
|
||||
}
|
||||
|
||||
IGC::CodeType::CodeType_t srcCodeType = input.srcType;
|
||||
IGC::CodeType::CodeType_t intermediateCodeType = IGC::CodeType::undefined;
|
||||
|
||||
if (input.preferredIntermediateType != IGC::CodeType::undefined) {
|
||||
intermediateCodeType = input.preferredIntermediateType;
|
||||
}
|
||||
|
||||
CachingMode cachingMode = None;
|
||||
|
||||
if (input.allowCaching) {
|
||||
if ((srcCodeType == IGC::CodeType::oclC) && (std::strstr(input.src.begin(), "#include") == nullptr)) {
|
||||
cachingMode = CachingMode::Direct;
|
||||
} else {
|
||||
cachingMode = CachingMode::PreProcess;
|
||||
}
|
||||
}
|
||||
|
||||
std::string kernelFileHash;
|
||||
if (cachingMode == CachingMode::Direct) {
|
||||
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(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<CIF::Builtins::BufferSimple> 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());
|
||||
|
||||
if (fclOutput == nullptr) {
|
||||
return TranslationOutput::ErrorCode::UnknownError;
|
||||
}
|
||||
|
||||
TranslationOutput::makeCopy(output.frontendCompilerLog, fclOutput->GetBuildLog());
|
||||
|
||||
if (fclOutput->Successful() == false) {
|
||||
return TranslationOutput::ErrorCode::BuildFailure;
|
||||
}
|
||||
|
||||
output.intermediateCodeType = intermediateCodeType;
|
||||
TranslationOutput::makeCopy(output.intermediateRepresentation, fclOutput->GetOutput());
|
||||
|
||||
fclOutput->GetOutput()->Retain(); // will be used as input to compiler
|
||||
intermediateRepresentation.reset(fclOutput->GetOutput());
|
||||
} else {
|
||||
inSrc->Retain(); // will be used as input to compiler directly
|
||||
intermediateRepresentation.reset(inSrc.get());
|
||||
intermediateCodeType = srcCodeType;
|
||||
}
|
||||
|
||||
if (cachingMode == CachingMode::PreProcess) {
|
||||
kernelFileHash = CompilerCache::getCachedFileName(device.getHardwareInfo(), ArrayRef<const char>(intermediateRepresentation->GetMemory<char>(), intermediateRepresentation->GetSize<char>()),
|
||||
input.apiOptions,
|
||||
input.internalOptions);
|
||||
output.deviceBinary.mem = cache->loadCachedBinary(kernelFileHash, output.deviceBinary.size);
|
||||
if (output.deviceBinary.mem) {
|
||||
return TranslationOutput::ErrorCode::Success;
|
||||
}
|
||||
}
|
||||
|
||||
auto igcTranslationCtx = createIgcTranslationCtx(device, intermediateCodeType, IGC::CodeType::oclGenBin);
|
||||
|
||||
auto igcOutput = translate(igcTranslationCtx.get(), intermediateRepresentation.get(), input.specConstants.idsBuffer, input.specConstants.valuesBuffer,
|
||||
fclOptions.get(), fclInternalOptions.get(), input.GTPinInput);
|
||||
|
||||
if (igcOutput == nullptr) {
|
||||
return TranslationOutput::ErrorCode::UnknownError;
|
||||
}
|
||||
|
||||
TranslationOutput::makeCopy(output.backendCompilerLog, igcOutput->GetBuildLog());
|
||||
|
||||
if (igcOutput->Successful() == false) {
|
||||
return TranslationOutput::ErrorCode::BuildFailure;
|
||||
}
|
||||
|
||||
if (input.allowCaching) {
|
||||
cache->cacheBinary(kernelFileHash, igcOutput->GetOutput()->GetMemory<char>(), static_cast<uint32_t>(igcOutput->GetOutput()->GetSize<char>()));
|
||||
}
|
||||
|
||||
TranslationOutput::makeCopy(output.deviceBinary, igcOutput->GetOutput());
|
||||
TranslationOutput::makeCopy(output.debugData, igcOutput->GetDebugData());
|
||||
|
||||
return TranslationOutput::ErrorCode::Success;
|
||||
}
|
||||
|
||||
TranslationOutput::ErrorCode CompilerInterface::compile(
|
||||
const NEO::Device &device,
|
||||
const TranslationInput &input,
|
||||
TranslationOutput &output) {
|
||||
|
||||
if ((IGC::CodeType::oclC != input.srcType) && (IGC::CodeType::elf != input.srcType)) {
|
||||
return TranslationOutput::ErrorCode::AlreadyCompiled;
|
||||
}
|
||||
|
||||
if (false == isCompilerAvailable(input.srcType, input.outType)) {
|
||||
return TranslationOutput::ErrorCode::CompilerNotAvailable;
|
||||
}
|
||||
|
||||
auto outType = input.outType;
|
||||
|
||||
if (outType == IGC::CodeType::undefined) {
|
||||
outType = getPreferredIntermediateRepresentation(device);
|
||||
}
|
||||
|
||||
auto fclSrc = 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 fclTranslationCtx = createFclTranslationCtx(device, input.srcType, outType);
|
||||
|
||||
auto fclOutput = translate(fclTranslationCtx.get(), fclSrc.get(),
|
||||
fclOptions.get(), fclInternalOptions.get());
|
||||
|
||||
if (fclOutput == nullptr) {
|
||||
return TranslationOutput::ErrorCode::UnknownError;
|
||||
}
|
||||
|
||||
TranslationOutput::makeCopy(output.frontendCompilerLog, fclOutput->GetBuildLog());
|
||||
|
||||
if (fclOutput->Successful() == false) {
|
||||
return TranslationOutput::ErrorCode::CompilationFailure;
|
||||
}
|
||||
|
||||
output.intermediateCodeType = outType;
|
||||
TranslationOutput::makeCopy(output.intermediateRepresentation, fclOutput->GetOutput());
|
||||
|
||||
return TranslationOutput::ErrorCode::Success;
|
||||
}
|
||||
|
||||
TranslationOutput::ErrorCode CompilerInterface::link(
|
||||
const NEO::Device &device,
|
||||
const TranslationInput &input,
|
||||
TranslationOutput &output) {
|
||||
if (false == isCompilerAvailable(input.srcType, input.outType)) {
|
||||
return TranslationOutput::ErrorCode::CompilerNotAvailable;
|
||||
}
|
||||
|
||||
auto inSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), input.src.begin(), input.src.size());
|
||||
auto igcOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), input.apiOptions.begin(), input.apiOptions.size());
|
||||
auto igcInternalOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), input.internalOptions.begin(), input.internalOptions.size());
|
||||
|
||||
if (inSrc == nullptr) {
|
||||
return TranslationOutput::ErrorCode::UnknownError;
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> currOut;
|
||||
inSrc->Retain(); // shared with currSrc
|
||||
CIF::RAII::UPtr_t<CIF::Builtins::BufferSimple> currSrc(inSrc.get());
|
||||
IGC::CodeType::CodeType_t translationChain[] = {IGC::CodeType::elf, IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin};
|
||||
constexpr size_t numTranslations = sizeof(translationChain) / sizeof(translationChain[0]);
|
||||
for (size_t ti = 1; ti < numTranslations; ti++) {
|
||||
IGC::CodeType::CodeType_t inType = translationChain[ti - 1];
|
||||
IGC::CodeType::CodeType_t outType = translationChain[ti];
|
||||
|
||||
auto igcTranslationCtx = createIgcTranslationCtx(device, inType, outType);
|
||||
currOut = translate(igcTranslationCtx.get(), currSrc.get(),
|
||||
igcOptions.get(), igcInternalOptions.get());
|
||||
|
||||
if (currOut == nullptr) {
|
||||
return TranslationOutput::ErrorCode::UnknownError;
|
||||
}
|
||||
|
||||
if (currOut->Successful() == false) {
|
||||
TranslationOutput::makeCopy(output.backendCompilerLog, currOut->GetBuildLog());
|
||||
return TranslationOutput::ErrorCode::LinkFailure;
|
||||
}
|
||||
|
||||
currOut->GetOutput()->Retain(); // shared with currSrc
|
||||
currSrc.reset(currOut->GetOutput());
|
||||
}
|
||||
|
||||
TranslationOutput::makeCopy(output.backendCompilerLog, currOut->GetBuildLog());
|
||||
TranslationOutput::makeCopy(output.deviceBinary, currOut->GetOutput());
|
||||
TranslationOutput::makeCopy(output.debugData, currOut->GetDebugData());
|
||||
|
||||
return TranslationOutput::ErrorCode::Success;
|
||||
}
|
||||
|
||||
TranslationOutput::ErrorCode CompilerInterface::getSpecConstantsInfo(const NEO::Device &device, ArrayRef<const char> srcSpirV, SpecConstantInfo &output) {
|
||||
if (false == isIgcAvailable()) {
|
||||
return TranslationOutput::ErrorCode::CompilerNotAvailable;
|
||||
}
|
||||
|
||||
auto igcTranslationCtx = createIgcTranslationCtx(device, IGC::CodeType::spirV, IGC::CodeType::oclGenBin);
|
||||
|
||||
auto inSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), srcSpirV.begin(), srcSpirV.size());
|
||||
output.idsBuffer = CIF::Builtins::CreateConstBuffer(igcMain.get(), nullptr, 0);
|
||||
output.sizesBuffer = CIF::Builtins::CreateConstBuffer(igcMain.get(), nullptr, 0);
|
||||
output.valuesBuffer = CIF::Builtins::CreateConstBuffer(igcMain.get(), nullptr, 0);
|
||||
|
||||
auto retVal = getSpecConstantsInfoImpl(igcTranslationCtx.get(), inSrc.get(), output.idsBuffer.get(), output.sizesBuffer.get(), output.valuesBuffer.get());
|
||||
|
||||
if (!retVal) {
|
||||
return TranslationOutput::ErrorCode::UnknownError;
|
||||
}
|
||||
|
||||
return TranslationOutput::ErrorCode::Success;
|
||||
}
|
||||
|
||||
TranslationOutput::ErrorCode CompilerInterface::createLibrary(
|
||||
NEO::Device &device,
|
||||
const TranslationInput &input,
|
||||
TranslationOutput &output) {
|
||||
if (false == isIgcAvailable()) {
|
||||
return TranslationOutput::ErrorCode::CompilerNotAvailable;
|
||||
}
|
||||
|
||||
auto igcSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), input.src.begin(), input.src.size());
|
||||
auto igcOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), input.apiOptions.begin(), input.apiOptions.size());
|
||||
auto igcInternalOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), input.internalOptions.begin(), input.internalOptions.size());
|
||||
|
||||
auto intermediateRepresentation = IGC::CodeType::llvmBc;
|
||||
auto igcTranslationCtx = createIgcTranslationCtx(device, IGC::CodeType::elf, intermediateRepresentation);
|
||||
|
||||
auto igcOutput = translate(igcTranslationCtx.get(), igcSrc.get(),
|
||||
igcOptions.get(), igcInternalOptions.get());
|
||||
|
||||
if (igcOutput == nullptr) {
|
||||
return TranslationOutput::ErrorCode::UnknownError;
|
||||
}
|
||||
|
||||
TranslationOutput::makeCopy(output.backendCompilerLog, igcOutput->GetBuildLog());
|
||||
|
||||
if (igcOutput->Successful() == false) {
|
||||
return TranslationOutput::ErrorCode::LinkFailure;
|
||||
}
|
||||
|
||||
output.intermediateCodeType = intermediateRepresentation;
|
||||
TranslationOutput::makeCopy(output.intermediateRepresentation, igcOutput->GetOutput());
|
||||
|
||||
return TranslationOutput::ErrorCode::Success;
|
||||
}
|
||||
|
||||
TranslationOutput::ErrorCode CompilerInterface::getSipKernelBinary(NEO::Device &device, SipKernelType type, std::vector<char> &retBinary) {
|
||||
if (false == isIgcAvailable()) {
|
||||
return TranslationOutput::ErrorCode::CompilerNotAvailable;
|
||||
}
|
||||
|
||||
const char *sipSrc = getSipLlSrc(device);
|
||||
std::string sipInternalOptions = getSipKernelCompilerInternalOptions(type);
|
||||
|
||||
auto igcSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), sipSrc, strlen(sipSrc) + 1);
|
||||
auto igcOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), nullptr, 0);
|
||||
auto igcInternalOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), sipInternalOptions.c_str(), sipInternalOptions.size() + 1);
|
||||
|
||||
auto igcTranslationCtx = createIgcTranslationCtx(device, IGC::CodeType::llvmLl, IGC::CodeType::oclGenBin);
|
||||
|
||||
auto igcOutput = translate(igcTranslationCtx.get(), igcSrc.get(),
|
||||
igcOptions.get(), igcInternalOptions.get());
|
||||
|
||||
if ((igcOutput == nullptr) || (igcOutput->Successful() == false)) {
|
||||
return TranslationOutput::ErrorCode::UnknownError;
|
||||
}
|
||||
|
||||
retBinary.assign(igcOutput->GetOutput()->GetMemory<char>(), igcOutput->GetOutput()->GetMemory<char>() + igcOutput->GetOutput()->GetSizeRaw());
|
||||
return TranslationOutput::ErrorCode::Success;
|
||||
}
|
||||
|
||||
bool CompilerInterface::loadFcl() {
|
||||
return NEO::loadCompiler<IGC::FclOclDeviceCtx>(Os::frontEndDllName, fclLib, fclMain);
|
||||
;
|
||||
}
|
||||
|
||||
bool CompilerInterface::loadIgc() {
|
||||
return NEO::loadCompiler<IGC::IgcOclDeviceCtx>(Os::igcDllName, igcLib, igcMain);
|
||||
}
|
||||
|
||||
bool CompilerInterface::initialize(std::unique_ptr<CompilerCache> cache, bool requireFcl) {
|
||||
bool fclAvailable = requireFcl ? this->loadFcl() : false;
|
||||
bool igcAvailable = this->loadIgc();
|
||||
|
||||
this->cache.swap(cache);
|
||||
|
||||
return this->cache && igcAvailable && (fclAvailable || (false == requireFcl));
|
||||
}
|
||||
|
||||
IGC::FclOclDeviceCtxTagOCL *CompilerInterface::getFclDeviceCtx(const Device &device) {
|
||||
auto it = fclDeviceContexts.find(&device);
|
||||
if (it != fclDeviceContexts.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
{
|
||||
auto ulock = this->lock();
|
||||
it = fclDeviceContexts.find(&device);
|
||||
if (it != fclDeviceContexts.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
if (fclMain == nullptr) {
|
||||
DEBUG_BREAK_IF(true); // compiler not available
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto newDeviceCtx = fclMain->CreateInterface<IGC::FclOclDeviceCtxTagOCL>();
|
||||
if (newDeviceCtx == nullptr) {
|
||||
DEBUG_BREAK_IF(true); // could not create device context
|
||||
return nullptr;
|
||||
}
|
||||
newDeviceCtx->SetOclApiVersion(device.getHardwareInfo().capabilityTable.clVersionSupport * 10);
|
||||
fclDeviceContexts[&device] = std::move(newDeviceCtx);
|
||||
|
||||
return fclDeviceContexts[&device].get();
|
||||
}
|
||||
}
|
||||
|
||||
IGC::CodeType::CodeType_t CompilerInterface::getPreferredIntermediateRepresentation(const Device &device) {
|
||||
return getFclDeviceCtx(device)->GetPreferredIntermediateRepresentation();
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::FclOclTranslationCtxTagOCL> CompilerInterface::createFclTranslationCtx(const Device &device, IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType) {
|
||||
|
||||
auto deviceCtx = getFclDeviceCtx(device);
|
||||
if (deviceCtx == nullptr) {
|
||||
DEBUG_BREAK_IF(true); // could not create device context
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (fclBaseTranslationCtx == nullptr) {
|
||||
fclBaseTranslationCtx = fclDeviceContexts[&device]->CreateTranslationCtx(inType, outType);
|
||||
}
|
||||
|
||||
return deviceCtx->CreateTranslationCtx(inType, outType);
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::IgcOclTranslationCtxTagOCL> CompilerInterface::createIgcTranslationCtx(const Device &device, IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType) {
|
||||
auto it = igcDeviceContexts.find(&device);
|
||||
if (it != igcDeviceContexts.end()) {
|
||||
return it->second->CreateTranslationCtx(inType, outType);
|
||||
}
|
||||
|
||||
{
|
||||
auto ulock = this->lock();
|
||||
it = igcDeviceContexts.find(&device);
|
||||
if (it != igcDeviceContexts.end()) {
|
||||
return it->second->CreateTranslationCtx(inType, outType);
|
||||
}
|
||||
|
||||
if (igcMain == nullptr) {
|
||||
DEBUG_BREAK_IF(true); // compiler not available
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto newDeviceCtx = igcMain->CreateInterface<IGC::IgcOclDeviceCtxTagOCL>();
|
||||
if (newDeviceCtx == nullptr) {
|
||||
DEBUG_BREAK_IF(true); // could not create device context
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
newDeviceCtx->SetProfilingTimerResolution(static_cast<float>(device.getDeviceInfo().outProfilingTimerResolution));
|
||||
auto igcPlatform = newDeviceCtx->GetPlatformHandle();
|
||||
auto igcGtSystemInfo = newDeviceCtx->GetGTSystemInfoHandle();
|
||||
auto igcFeWa = newDeviceCtx->GetIgcFeaturesAndWorkaroundsHandle();
|
||||
if (false == NEO::areNotNullptr(igcPlatform.get(), igcGtSystemInfo.get(), igcFeWa.get())) {
|
||||
DEBUG_BREAK_IF(true); // could not acquire handles to device descriptors
|
||||
return nullptr;
|
||||
}
|
||||
const HardwareInfo *hwInfo = &device.getHardwareInfo();
|
||||
auto productFamily = DebugManager.flags.ForceCompilerUsePlatform.get();
|
||||
if (productFamily != "unk") {
|
||||
getHwInfoForPlatformString(productFamily, hwInfo);
|
||||
}
|
||||
IGC::PlatformHelper::PopulateInterfaceWith(*igcPlatform, hwInfo->platform);
|
||||
IGC::GtSysInfoHelper::PopulateInterfaceWith(*igcGtSystemInfo, hwInfo->gtSystemInfo);
|
||||
|
||||
igcFeWa.get()->SetFtrDesktop(device.getHardwareInfo().featureTable.ftrDesktop);
|
||||
igcFeWa.get()->SetFtrChannelSwizzlingXOREnabled(device.getHardwareInfo().featureTable.ftrChannelSwizzlingXOREnabled);
|
||||
|
||||
igcFeWa.get()->SetFtrGtBigDie(device.getHardwareInfo().featureTable.ftrGtBigDie);
|
||||
igcFeWa.get()->SetFtrGtMediumDie(device.getHardwareInfo().featureTable.ftrGtMediumDie);
|
||||
igcFeWa.get()->SetFtrGtSmallDie(device.getHardwareInfo().featureTable.ftrGtSmallDie);
|
||||
|
||||
igcFeWa.get()->SetFtrGT1(device.getHardwareInfo().featureTable.ftrGT1);
|
||||
igcFeWa.get()->SetFtrGT1_5(device.getHardwareInfo().featureTable.ftrGT1_5);
|
||||
igcFeWa.get()->SetFtrGT2(device.getHardwareInfo().featureTable.ftrGT2);
|
||||
igcFeWa.get()->SetFtrGT3(device.getHardwareInfo().featureTable.ftrGT3);
|
||||
igcFeWa.get()->SetFtrGT4(device.getHardwareInfo().featureTable.ftrGT4);
|
||||
|
||||
igcFeWa.get()->SetFtrIVBM0M1Platform(device.getHardwareInfo().featureTable.ftrIVBM0M1Platform);
|
||||
igcFeWa.get()->SetFtrGTL(device.getHardwareInfo().featureTable.ftrGT1);
|
||||
igcFeWa.get()->SetFtrGTM(device.getHardwareInfo().featureTable.ftrGT2);
|
||||
igcFeWa.get()->SetFtrGTH(device.getHardwareInfo().featureTable.ftrGT3);
|
||||
|
||||
igcFeWa.get()->SetFtrSGTPVSKUStrapPresent(device.getHardwareInfo().featureTable.ftrSGTPVSKUStrapPresent);
|
||||
igcFeWa.get()->SetFtrGTA(device.getHardwareInfo().featureTable.ftrGTA);
|
||||
igcFeWa.get()->SetFtrGTC(device.getHardwareInfo().featureTable.ftrGTC);
|
||||
igcFeWa.get()->SetFtrGTX(device.getHardwareInfo().featureTable.ftrGTX);
|
||||
igcFeWa.get()->SetFtr5Slice(device.getHardwareInfo().featureTable.ftr5Slice);
|
||||
|
||||
igcFeWa.get()->SetFtrGpGpuMidThreadLevelPreempt(device.getHardwareInfo().featureTable.ftrGpGpuMidThreadLevelPreempt);
|
||||
igcFeWa.get()->SetFtrIoMmuPageFaulting(device.getHardwareInfo().featureTable.ftrIoMmuPageFaulting);
|
||||
igcFeWa.get()->SetFtrWddm2Svm(device.getHardwareInfo().featureTable.ftrWddm2Svm);
|
||||
igcFeWa.get()->SetFtrPooledEuEnabled(device.getHardwareInfo().featureTable.ftrPooledEuEnabled);
|
||||
|
||||
igcFeWa.get()->SetFtrResourceStreamer(device.getHardwareInfo().featureTable.ftrResourceStreamer);
|
||||
|
||||
igcDeviceContexts[&device] = std::move(newDeviceCtx);
|
||||
return igcDeviceContexts[&device]->CreateTranslationCtx(inType, outType);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
186
core/compiler_interface/compiler_interface.h
Normal file
186
core/compiler_interface/compiler_interface.h
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#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/os_interface/os_library.h"
|
||||
|
||||
#include "cif/common/cif_main.h"
|
||||
#include "ocl_igc_interface/code_type.h"
|
||||
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
||||
#include "ocl_igc_interface/igc_ocl_device_ctx.h"
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
namespace NEO {
|
||||
class Device;
|
||||
|
||||
struct TranslationInput {
|
||||
TranslationInput(IGC::CodeType::CodeType_t srcType, IGC::CodeType::CodeType_t outType, IGC::CodeType::CodeType_t preferredIntermediateType = IGC::CodeType::undefined)
|
||||
: srcType(srcType), preferredIntermediateType(preferredIntermediateType), outType(outType) {
|
||||
}
|
||||
|
||||
bool allowCaching = false;
|
||||
|
||||
ArrayRef<const char> src;
|
||||
ArrayRef<const char> apiOptions;
|
||||
ArrayRef<const char> internalOptions;
|
||||
const char *tracingOptions = nullptr;
|
||||
uint32_t tracingOptionsCount = 0;
|
||||
IGC::CodeType::CodeType_t srcType = IGC::CodeType::invalid;
|
||||
IGC::CodeType::CodeType_t preferredIntermediateType = IGC::CodeType::invalid;
|
||||
IGC::CodeType::CodeType_t outType = IGC::CodeType::invalid;
|
||||
void *GTPinInput = nullptr;
|
||||
|
||||
struct SpecConstants {
|
||||
CIF::Builtins::BufferLatest *idsBuffer = nullptr;
|
||||
CIF::Builtins::BufferLatest *sizesBuffer = nullptr;
|
||||
CIF::Builtins::BufferLatest *valuesBuffer = nullptr;
|
||||
} specConstants;
|
||||
};
|
||||
|
||||
struct TranslationOutput {
|
||||
enum class ErrorCode {
|
||||
Success = 0,
|
||||
CompilerNotAvailable,
|
||||
CompilationFailure,
|
||||
BuildFailure,
|
||||
LinkFailure,
|
||||
AlreadyCompiled,
|
||||
UnknownError,
|
||||
};
|
||||
|
||||
struct MemAndSize {
|
||||
std::unique_ptr<char[]> mem;
|
||||
size_t size = 0;
|
||||
};
|
||||
|
||||
IGC::CodeType::CodeType_t intermediateCodeType = IGC::CodeType::invalid;
|
||||
MemAndSize intermediateRepresentation;
|
||||
MemAndSize deviceBinary;
|
||||
MemAndSize debugData;
|
||||
std::string frontendCompilerLog;
|
||||
std::string backendCompilerLog;
|
||||
|
||||
template <typename ContainerT>
|
||||
static void makeCopy(ContainerT &dst, CIF::Builtins::BufferSimple *src) {
|
||||
if ((nullptr == src) || (src->GetSizeRaw() == 0)) {
|
||||
dst.clear();
|
||||
return;
|
||||
}
|
||||
dst.assign(src->GetMemory<char>(), src->GetSize<char>());
|
||||
}
|
||||
|
||||
static void makeCopy(MemAndSize &dst, CIF::Builtins::BufferSimple *src) {
|
||||
if ((nullptr == src) || (src->GetSizeRaw() == 0)) {
|
||||
dst.mem.reset();
|
||||
dst.size = 0U;
|
||||
return;
|
||||
}
|
||||
|
||||
dst.size = src->GetSize<char>();
|
||||
dst.mem = ::makeCopy(src->GetMemory<void>(), src->GetSize<char>());
|
||||
}
|
||||
};
|
||||
|
||||
struct SpecConstantInfo {
|
||||
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> idsBuffer;
|
||||
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> sizesBuffer;
|
||||
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> valuesBuffer;
|
||||
};
|
||||
|
||||
class CompilerInterface {
|
||||
public:
|
||||
CompilerInterface();
|
||||
CompilerInterface(const CompilerInterface &) = delete;
|
||||
CompilerInterface &operator=(const CompilerInterface &) = delete;
|
||||
CompilerInterface(CompilerInterface &&) = delete;
|
||||
CompilerInterface &operator=(CompilerInterface &&) = delete;
|
||||
virtual ~CompilerInterface();
|
||||
|
||||
static CompilerInterface *createInstance(std::unique_ptr<CompilerCache> cache, bool requireFcl) {
|
||||
auto instance = new CompilerInterface();
|
||||
if (!instance->initialize(std::move(cache), requireFcl)) {
|
||||
delete instance;
|
||||
instance = nullptr;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
MOCKABLE_VIRTUAL TranslationOutput::ErrorCode build(const NEO::Device &device,
|
||||
const TranslationInput &input,
|
||||
TranslationOutput &output);
|
||||
|
||||
MOCKABLE_VIRTUAL TranslationOutput::ErrorCode compile(const NEO::Device &device,
|
||||
const TranslationInput &input,
|
||||
TranslationOutput &output);
|
||||
|
||||
MOCKABLE_VIRTUAL TranslationOutput::ErrorCode link(const NEO::Device &device,
|
||||
const TranslationInput &input,
|
||||
TranslationOutput &output);
|
||||
|
||||
MOCKABLE_VIRTUAL TranslationOutput::ErrorCode getSpecConstantsInfo(const NEO::Device &device,
|
||||
ArrayRef<const char> srcSpirV, SpecConstantInfo &output);
|
||||
|
||||
TranslationOutput::ErrorCode createLibrary(NEO::Device &device,
|
||||
const TranslationInput &input,
|
||||
TranslationOutput &output);
|
||||
|
||||
MOCKABLE_VIRTUAL TranslationOutput::ErrorCode getSipKernelBinary(NEO::Device &device, SipKernelType type, std::vector<char> &retBinary);
|
||||
|
||||
protected:
|
||||
bool initialize(std::unique_ptr<CompilerCache> cache, bool requireFcl);
|
||||
MOCKABLE_VIRTUAL bool loadFcl();
|
||||
MOCKABLE_VIRTUAL bool loadIgc();
|
||||
|
||||
static std::mutex mtx;
|
||||
MOCKABLE_VIRTUAL std::unique_lock<std::mutex> lock() {
|
||||
return std::unique_lock<std::mutex>{mtx};
|
||||
}
|
||||
std::unique_ptr<CompilerCache> cache = nullptr;
|
||||
|
||||
using igcDevCtxUptr = CIF::RAII::UPtr_t<IGC::IgcOclDeviceCtxTagOCL>;
|
||||
using fclDevCtxUptr = CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL>;
|
||||
|
||||
std::unique_ptr<OsLibrary> igcLib;
|
||||
CIF::RAII::UPtr_t<CIF::CIFMain> igcMain = nullptr;
|
||||
std::map<const Device *, igcDevCtxUptr> igcDeviceContexts;
|
||||
|
||||
std::unique_ptr<OsLibrary> fclLib;
|
||||
CIF::RAII::UPtr_t<CIF::CIFMain> fclMain = nullptr;
|
||||
std::map<const Device *, fclDevCtxUptr> fclDeviceContexts;
|
||||
CIF::RAII::UPtr_t<IGC::FclOclTranslationCtxTagOCL> fclBaseTranslationCtx = nullptr;
|
||||
|
||||
MOCKABLE_VIRTUAL IGC::FclOclDeviceCtxTagOCL *getFclDeviceCtx(const Device &device);
|
||||
MOCKABLE_VIRTUAL IGC::CodeType::CodeType_t getPreferredIntermediateRepresentation(const Device &device);
|
||||
|
||||
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<IGC::FclOclTranslationCtxTagOCL> createFclTranslationCtx(const Device &device,
|
||||
IGC::CodeType::CodeType_t inType,
|
||||
IGC::CodeType::CodeType_t outType);
|
||||
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<IGC::IgcOclTranslationCtxTagOCL> createIgcTranslationCtx(const Device &device,
|
||||
IGC::CodeType::CodeType_t inType,
|
||||
IGC::CodeType::CodeType_t outType);
|
||||
|
||||
bool isFclAvailable() const {
|
||||
return (fclMain != nullptr);
|
||||
}
|
||||
|
||||
bool isIgcAvailable() const {
|
||||
return (igcMain != nullptr);
|
||||
}
|
||||
|
||||
bool isCompilerAvailable(IGC::CodeType::CodeType_t translationSrc, IGC::CodeType::CodeType_t translationDst) const {
|
||||
bool requiresFcl = (IGC::CodeType::oclC == translationSrc);
|
||||
bool requiresIgc = (IGC::CodeType::oclC != translationSrc) || ((IGC::CodeType::spirV != translationDst) && (IGC::CodeType::llvmBc != translationDst) && (IGC::CodeType::llvmLl != translationDst));
|
||||
return (isFclAvailable() || (false == requiresFcl)) && (isIgcAvailable() || (false == requiresIgc));
|
||||
}
|
||||
};
|
||||
} // namespace NEO
|
||||
119
core/compiler_interface/compiler_interface.inl
Normal file
119
core/compiler_interface/compiler_interface.inl
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "runtime/helpers/validators.h"
|
||||
#include "runtime/os_interface/os_library.h"
|
||||
|
||||
#include "cif/builtins/memory/buffer/buffer.h"
|
||||
#include "cif/common/cif.h"
|
||||
#include "cif/import/library_api.h"
|
||||
#include "ocl_igc_interface/ocl_translation_output.h"
|
||||
|
||||
namespace NEO {
|
||||
using CIFBuffer = CIF::Builtins::BufferSimple;
|
||||
|
||||
template <typename TranslationCtx>
|
||||
inline CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> translate(TranslationCtx *tCtx, CIFBuffer *src, CIFBuffer *options,
|
||||
CIFBuffer *internalOptions) {
|
||||
if (false == NEO::areNotNullptr(tCtx, src, options, internalOptions)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto ret = tCtx->Translate(src, options, internalOptions, nullptr, 0);
|
||||
if (ret == nullptr) {
|
||||
return nullptr; // assume OOM or internal error
|
||||
}
|
||||
|
||||
if ((ret->GetOutput() == nullptr) || (ret->GetBuildLog() == nullptr) || (ret->GetDebugData() == nullptr)) {
|
||||
return nullptr; // assume OOM or internal error
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
template <typename TranslationCtx>
|
||||
inline CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> translate(TranslationCtx *tCtx, CIFBuffer *src, CIFBuffer *options,
|
||||
CIFBuffer *internalOptions, void *gtpinInit) {
|
||||
if (false == NEO::areNotNullptr(tCtx, src, options, internalOptions)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto ret = tCtx->Translate(src, options, internalOptions, nullptr, 0, gtpinInit);
|
||||
if (ret == nullptr) {
|
||||
return nullptr; // assume OOM or internal error
|
||||
}
|
||||
|
||||
if ((ret->GetOutput() == nullptr) || (ret->GetBuildLog() == nullptr) || (ret->GetDebugData() == nullptr)) {
|
||||
return nullptr; // assume OOM or internal error
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename TranslationCtx>
|
||||
inline bool getSpecConstantsInfoImpl(TranslationCtx *tCtx,
|
||||
CIFBuffer *src,
|
||||
CIFBuffer *outSpecConstantsIds,
|
||||
CIFBuffer *outSpecConstantsSizes,
|
||||
CIFBuffer *outSpecConstantsValues) {
|
||||
if (!NEO::areNotNullptr(tCtx, src, outSpecConstantsIds, outSpecConstantsSizes, outSpecConstantsValues)) {
|
||||
return false;
|
||||
}
|
||||
return tCtx->GetSpecConstantsInfoImpl(src, outSpecConstantsIds, outSpecConstantsSizes);
|
||||
}
|
||||
|
||||
template <typename TranslationCtx>
|
||||
inline CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> translate(TranslationCtx *tCtx, CIFBuffer *src, CIFBuffer *specConstantsIds, CIFBuffer *specConstantsValues, CIFBuffer *options,
|
||||
CIFBuffer *internalOptions, void *gtpinInit) {
|
||||
if (false == NEO::areNotNullptr(tCtx, src, options, internalOptions)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto ret = tCtx->Translate(src, specConstantsIds, specConstantsValues, options, internalOptions, nullptr, 0, gtpinInit);
|
||||
if (ret == nullptr) {
|
||||
return nullptr; // assume OOM or internal error
|
||||
}
|
||||
|
||||
if (!NEO::areNotNullptr(ret->GetOutput(), ret->GetBuildLog(), ret->GetDebugData())) {
|
||||
return nullptr; // assume OOM or internal error
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CIF::CIFMain *createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc);
|
||||
|
||||
template <template <CIF::Version_t> class EntryPointT>
|
||||
inline bool loadCompiler(const char *libName, std::unique_ptr<OsLibrary> &outLib,
|
||||
CIF::RAII::UPtr_t<CIF::CIFMain> &outLibMain) {
|
||||
auto lib = std::unique_ptr<OsLibrary>(OsLibrary::load(libName));
|
||||
if (lib == nullptr) {
|
||||
DEBUG_BREAK_IF(true); // could not load library
|
||||
return false;
|
||||
}
|
||||
|
||||
auto createMain = reinterpret_cast<CIF::CreateCIFMainFunc_t>(lib->getProcAddress(CIF::CreateCIFMainFuncName));
|
||||
UNRECOVERABLE_IF(createMain == nullptr); // invalid compiler library
|
||||
|
||||
auto main = CIF::RAII::UPtr(createMainNoSanitize(createMain));
|
||||
if (main == nullptr) {
|
||||
DEBUG_BREAK_IF(true); // could not create main entry point
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false == main->IsCompatible<EntryPointT>()) {
|
||||
DEBUG_BREAK_IF(true); // given compiler library is not compatible
|
||||
return false;
|
||||
}
|
||||
|
||||
outLib = std::move(lib);
|
||||
outLibMain = std::move(main);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
19
core/compiler_interface/create_main.cpp
Normal file
19
core/compiler_interface/create_main.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cif/common/cif_main.h"
|
||||
#include "cif/common/library_api.h"
|
||||
|
||||
namespace NEO {
|
||||
#if defined(__clang__)
|
||||
__attribute__((no_sanitize("undefined")))
|
||||
#endif
|
||||
CIF::CIFMain *
|
||||
createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc) {
|
||||
return createFunc();
|
||||
}
|
||||
} // namespace NEO
|
||||
Reference in New Issue
Block a user