mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 14:55:24 +08:00
Allow to create partially linked module
Don't allow to create kernel from partially linked module Change-Id: Id70b484686e6d1ca79f242bf96ff92582172e378 Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
committed by
sys_ocldev
parent
2b30166415
commit
794296334b
@@ -370,6 +370,9 @@ void ModuleImp::updateBuildLog(NEO::Device *neoDevice) {
|
||||
ze_result_t ModuleImp::createKernel(const ze_kernel_desc_t *desc,
|
||||
ze_kernel_handle_t *phFunction) {
|
||||
ze_result_t res;
|
||||
if (!isFullyLinked) {
|
||||
return ZE_RESULT_ERROR_MODULE_BUILD_FAILURE;
|
||||
}
|
||||
auto kernel = Kernel::create(productFamily, this, desc, &res);
|
||||
|
||||
if (res == ZE_RESULT_SUCCESS) {
|
||||
@@ -404,6 +407,7 @@ ze_result_t ModuleImp::getDebugInfo(size_t *pDebugDataSize, uint8_t *pDebugData)
|
||||
bool ModuleImp::linkBinary() {
|
||||
using namespace NEO;
|
||||
if (this->translationUnit->programInfo.linkerInput == nullptr) {
|
||||
isFullyLinked = true;
|
||||
return true;
|
||||
}
|
||||
Linker linker(*this->translationUnit->programInfo.linkerInput);
|
||||
@@ -439,20 +443,22 @@ bool ModuleImp::linkBinary() {
|
||||
}
|
||||
|
||||
Linker::UnresolvedExternals unresolvedExternalsInfo;
|
||||
bool linkSuccess = linker.link(globals, constants, exportedFunctions,
|
||||
globalsForPatching, constantsForPatching,
|
||||
isaSegmentsForPatching, unresolvedExternalsInfo, this->device->getNEODevice(),
|
||||
translationUnit->programInfo.globalConstants.initData,
|
||||
translationUnit->programInfo.globalVariables.initData);
|
||||
auto linkStatus = linker.link(globals, constants, exportedFunctions,
|
||||
globalsForPatching, constantsForPatching,
|
||||
isaSegmentsForPatching, unresolvedExternalsInfo, this->device->getNEODevice(),
|
||||
translationUnit->programInfo.globalConstants.initData,
|
||||
translationUnit->programInfo.globalVariables.initData);
|
||||
this->symbols = linker.extractRelocatedSymbols();
|
||||
if (false == linkSuccess) {
|
||||
std::vector<std::string> kernelNames;
|
||||
for (const auto &kernelInfo : this->translationUnit->programInfo.kernelInfos) {
|
||||
kernelNames.push_back("kernel : " + kernelInfo->name);
|
||||
if (LinkingStatus::LinkedFully != linkStatus) {
|
||||
if (moduleBuildLog) {
|
||||
std::vector<std::string> kernelNames;
|
||||
for (const auto &kernelInfo : this->translationUnit->programInfo.kernelInfos) {
|
||||
kernelNames.push_back("kernel : " + kernelInfo->name);
|
||||
}
|
||||
auto error = constructLinkerErrorMessage(unresolvedExternalsInfo, kernelNames);
|
||||
moduleBuildLog->appendString(error.c_str(), error.size());
|
||||
}
|
||||
auto error = constructLinkerErrorMessage(unresolvedExternalsInfo, kernelNames);
|
||||
moduleBuildLog->appendString(error.c_str(), error.size());
|
||||
return false;
|
||||
return LinkingStatus::LinkedPartially == linkStatus;
|
||||
} else if (this->translationUnit->programInfo.linkerInput->getTraits().requiresPatchingOfInstructionSegments) {
|
||||
for (const auto &kernelImmData : this->kernelImmDatas) {
|
||||
if (nullptr == kernelImmData->getIsaGraphicsAllocation()) {
|
||||
@@ -465,6 +471,7 @@ bool ModuleImp::linkBinary() {
|
||||
}
|
||||
}
|
||||
DBG_LOG(PrintRelocations, NEO::constructRelocationsDebugMessage(this->symbols));
|
||||
isFullyLinked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ struct ModuleImp : public Module {
|
||||
std::vector<std::unique_ptr<KernelImmutableData>> kernelImmDatas;
|
||||
NEO::Linker::RelocatedSymbolsMap symbols;
|
||||
bool debugEnabled = false;
|
||||
bool isFullyLinked = false;
|
||||
};
|
||||
|
||||
bool moveBuildOption(std::string &dstOptionsSet, std::string &srcOptionSet, ConstStringRef dstOptionName, ConstStringRef srcOptionName);
|
||||
|
||||
@@ -22,6 +22,7 @@ struct WhiteBox<::L0::Module> : public ::L0::ModuleImp {
|
||||
using BaseClass = ::L0::ModuleImp;
|
||||
using BaseClass::BaseClass;
|
||||
using BaseClass::device;
|
||||
using BaseClass::isFullyLinked;
|
||||
using BaseClass::translationUnit;
|
||||
};
|
||||
|
||||
@@ -56,7 +57,16 @@ struct MockModuleTranslationUnit : public L0::ModuleTranslationUnit {
|
||||
};
|
||||
|
||||
struct MockCompilerInterface : public NEO::CompilerInterface {
|
||||
MockCompilerInterface(uint32_t moduleNumSpecConstants) : moduleNumSpecConstants(moduleNumSpecConstants) {
|
||||
NEO::TranslationOutput::ErrorCode build(const NEO::Device &device,
|
||||
const NEO::TranslationInput &input,
|
||||
NEO::TranslationOutput &output) override {
|
||||
|
||||
return NEO::TranslationOutput::ErrorCode::Success;
|
||||
}
|
||||
};
|
||||
|
||||
struct MockCompilerInterfaceWithSpecConstants : public NEO::CompilerInterface {
|
||||
MockCompilerInterfaceWithSpecConstants(uint32_t moduleNumSpecConstants) : moduleNumSpecConstants(moduleNumSpecConstants) {
|
||||
}
|
||||
NEO::TranslationOutput::ErrorCode build(const NEO::Device &device,
|
||||
const NEO::TranslationInput &input,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/test/unit_test/compiler_interface/linker_mock.h"
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "level_zero/core/source/kernel/kernel_imp.h"
|
||||
@@ -103,7 +105,7 @@ struct ModuleSpecConstantsTests : public DeviceFixture,
|
||||
void SetUp() override {
|
||||
DeviceFixture::SetUp();
|
||||
|
||||
mockCompiler = new MockCompilerInterface(moduleNumSpecConstants);
|
||||
mockCompiler = new MockCompilerInterfaceWithSpecConstants(moduleNumSpecConstants);
|
||||
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
|
||||
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
|
||||
|
||||
@@ -120,7 +122,7 @@ struct ModuleSpecConstantsTests : public DeviceFixture,
|
||||
|
||||
const std::string binaryFilename = "test_kernel";
|
||||
const std::string kernelName = "test";
|
||||
MockCompilerInterface *mockCompiler;
|
||||
MockCompilerInterfaceWithSpecConstants *mockCompiler;
|
||||
MockModuleTranslationUnit *mockTranslationUnit;
|
||||
};
|
||||
|
||||
@@ -156,6 +158,70 @@ HWTEST_F(ModuleSpecConstantsTests, givenSpecializationConstantsSetInDescriptorTh
|
||||
module->destroy();
|
||||
}
|
||||
|
||||
using ModuleLinkingTest = Test<DeviceFixture>;
|
||||
|
||||
HWTEST_F(ModuleLinkingTest, givenFailureDuringLinkingWhenCreatingModuleThenModuleInitialiationFails) {
|
||||
auto mockCompiler = new MockCompilerInterface();
|
||||
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
|
||||
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
|
||||
|
||||
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
|
||||
|
||||
auto linkerInput = std::make_unique<::WhiteBox<NEO::LinkerInput>>();
|
||||
linkerInput->valid = false;
|
||||
|
||||
mockTranslationUnit->programInfo.linkerInput = std::move(linkerInput);
|
||||
uint8_t spirvData{};
|
||||
|
||||
ze_module_desc_t moduleDesc = {ZE_MODULE_DESC_VERSION_CURRENT};
|
||||
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
|
||||
moduleDesc.pInputModule = &spirvData;
|
||||
moduleDesc.inputSize = sizeof(spirvData);
|
||||
|
||||
Module module(device, nullptr);
|
||||
module.translationUnit.reset(mockTranslationUnit);
|
||||
|
||||
bool success = module.initialize(&moduleDesc, neoDevice);
|
||||
EXPECT_FALSE(success);
|
||||
}
|
||||
|
||||
HWTEST_F(ModuleLinkingTest, givenRemainingUnresolvedSymbolsDuringLinkingWhenCreatingModuleThenModuleIsNotLinkedFully) {
|
||||
auto mockCompiler = new MockCompilerInterface();
|
||||
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
|
||||
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
|
||||
|
||||
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
|
||||
|
||||
auto linkerInput = std::make_unique<::WhiteBox<NEO::LinkerInput>>();
|
||||
|
||||
NEO::LinkerInput::RelocationInfo relocation;
|
||||
relocation.symbolName = "unresolved";
|
||||
linkerInput->dataRelocations.push_back(relocation);
|
||||
linkerInput->traits.requiresPatchingOfGlobalVariablesBuffer = true;
|
||||
|
||||
mockTranslationUnit->programInfo.linkerInput = std::move(linkerInput);
|
||||
uint8_t spirvData{};
|
||||
|
||||
ze_module_desc_t moduleDesc = {ZE_MODULE_DESC_VERSION_CURRENT};
|
||||
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
|
||||
moduleDesc.pInputModule = &spirvData;
|
||||
moduleDesc.inputSize = sizeof(spirvData);
|
||||
|
||||
Module module(device, nullptr);
|
||||
module.translationUnit.reset(mockTranslationUnit);
|
||||
|
||||
bool success = module.initialize(&moduleDesc, neoDevice);
|
||||
EXPECT_TRUE(success);
|
||||
EXPECT_FALSE(module.isFullyLinked);
|
||||
}
|
||||
HWTEST_F(ModuleLinkingTest, givenNotFullyLinkedModuleWhenCreatingKernelThenErrorIsReturned) {
|
||||
Module module(device, nullptr);
|
||||
module.isFullyLinked = false;
|
||||
|
||||
auto retVal = module.createKernel(nullptr, nullptr);
|
||||
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_MODULE_BUILD_FAILURE, retVal);
|
||||
}
|
||||
using ModuleDynamicLinkTests = Test<ModuleFixture>;
|
||||
|
||||
HWTEST_F(ModuleDynamicLinkTests, givenCallToDynamicLinkThenUnsupportedFeatureIsReturned) {
|
||||
|
||||
Reference in New Issue
Block a user