Allow for zebin rebuild when IR is present

This commits adds rebuilding zebin binary.
If zebin is built for different device and has SPIRV, then new ze binary
will be built using SPIRV.

Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
Krystian Chmielewski
2022-04-07 12:29:43 +00:00
committed by Compute-Runtime-Automation
parent e9ebd10ab8
commit 01a719cf33
8 changed files with 55 additions and 19 deletions

View File

@ -64,10 +64,12 @@ cl_int Program::build(
deviceBuildInfos[device].buildStatus = CL_BUILD_IN_PROGRESS;
}
if (nullptr != buildOptions) {
options = buildOptions;
} else if (this->createdFrom != CreatedFrom::BINARY) {
options = "";
if (false == requiresRebuild) {
if (nullptr != buildOptions) {
options = buildOptions;
} else if (this->createdFrom != CreatedFrom::BINARY) {
options = "";
}
}
const bool shouldSuppressRebuildWarning{CompilerOptions::extract(CompilerOptions::noRecompiledFromIr, options)};
@ -130,7 +132,7 @@ cl_int Program::build(
NEO::TranslationOutput compilerOuput = {};
for (const auto &clDevice : deviceVector) {
if (shouldWarnAboutRebuild && !shouldSuppressRebuildWarning) {
if (requiresRebuild && !shouldSuppressRebuildWarning) {
this->updateBuildLog(clDevice->getRootDeviceIndex(), CompilerWarnings::recompiledFromIr.data(), CompilerWarnings::recompiledFromIr.length());
}
auto compilerErr = pCompilerInterface->build(clDevice->getDevice(), inputArgs, compilerOuput);

View File

@ -149,7 +149,7 @@ cl_int Program::compile(
TranslationOutput compilerOuput;
auto compilerErr = pCompilerInterface->compile(defaultDevice, inputArgs, compilerOuput);
for (const auto &device : deviceVector) {
if (shouldWarnAboutRebuild && !shouldSuppressRebuildWarning) {
if (requiresRebuild && !shouldSuppressRebuildWarning) {
this->updateBuildLog(device->getRootDeviceIndex(), CompilerWarnings::recompiledFromIr.data(), CompilerWarnings::recompiledFromIr.length());
}

View File

@ -198,7 +198,7 @@ cl_int Program::createProgramFromBinary(
this->buildInfos[rootDeviceIndex].packedDeviceBinarySize = archive.size();
} else {
this->isCreatedFromBinary = false;
this->shouldWarnAboutRebuild = true;
this->requiresRebuild = true;
}
switch (singleDeviceBinary.format) {

View File

@ -318,7 +318,7 @@ class Program : public BaseObject<_cl_program> {
std::unordered_map<ClDevice *, DeviceBuildInfo> deviceBuildInfos;
bool isCreatedFromBinary = false;
bool shouldWarnAboutRebuild = false;
bool requiresRebuild = false;
std::string sourceCode;
std::string options;

View File

@ -48,8 +48,8 @@ class MockProgram : public Program {
using Program::options;
using Program::packDeviceBinary;
using Program::Program;
using Program::requiresRebuild;
using Program::setBuildStatus;
using Program::shouldWarnAboutRebuild;
using Program::sourceCode;
using Program::specConstantsIds;
using Program::specConstantsSizes;
@ -130,7 +130,7 @@ class MockProgram : public Program {
cl_int rebuildProgramFromIr() {
this->isCreatedFromBinary = false;
this->shouldWarnAboutRebuild = true;
this->requiresRebuild = true;
setBuildStatus(CL_BUILD_NONE);
std::unordered_map<std::string, BuiltinDispatchInfoBuilder *> builtins;
return this->build(getDevices(), this->options.c_str(), false, builtins);
@ -138,7 +138,7 @@ class MockProgram : public Program {
cl_int recompile() {
this->isCreatedFromBinary = false;
this->shouldWarnAboutRebuild = true;
this->requiresRebuild = true;
setBuildStatus(CL_BUILD_NONE);
return this->compile(getDevices(), this->options.c_str(), 0, nullptr, nullptr);
}

View File

@ -2659,7 +2659,7 @@ TEST(CreateProgramFromBinaryTests, givenBinaryProgramBuiltInWhenKernelRebulildIs
retVal = pProgram->createProgramFromBinary(programTokens.storage.data(), programTokens.storage.size(), *clDevice);
ASSERT_EQ(CL_SUCCESS, retVal);
ASSERT_TRUE(pProgram->shouldWarnAboutRebuild);
ASSERT_TRUE(pProgram->requiresRebuild);
}
TEST(CreateProgramFromBinaryTests, givenBinaryProgramNotBuiltInWhenBuiltInKernelRebulildIsForcedThenDeviceBinaryIsUsed) {

View File

@ -46,6 +46,17 @@ SingleDeviceBinary unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(cons
break;
}
SingleDeviceBinary ret;
ret.deviceBinary = archive;
ret.format = NEO::DeviceBinaryFormat::Zebin;
ret.targetDevice = requestedTargetDevice;
for (auto &elfSH : elf.sectionHeaders) {
if (elfSH.header->type == Elf::SHT_ZEBIN_SPIRV) {
ret.intermediateRepresentation = elfSH.data;
}
}
bool validForTarget = true;
if (elf.elfFileHeader->machine == Elf::ELF_MACHINE::EM_INTELGT) {
validForTarget &= validateTargetDevice(elf, requestedTargetDevice);
@ -59,15 +70,15 @@ SingleDeviceBinary unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(cons
}
if (false == validForTarget) {
outErrReason = "Unhandled target device";
return {};
if (false == ret.intermediateRepresentation.empty()) {
ret.buildOptions = NEO::CompilerOptions::allowZebin;
ret.deviceBinary = {};
} else {
outErrReason = "Unhandled target device";
return {};
}
}
SingleDeviceBinary ret;
ret.deviceBinary = archive;
ret.format = NEO::DeviceBinaryFormat::Zebin;
ret.targetDevice = requestedTargetDevice;
return ret;
}

View File

@ -358,3 +358,26 @@ TEST(UnpackSingleDeviceBinaryZebin, WhenMachineIsIntelGTAndIntelGTNoteSectionIsV
EXPECT_TRUE(unpackWarnings.empty());
EXPECT_TRUE(unpackErrors.empty());
}
TEST(UnpackSingleDeviceBinaryZebin, WhenZebinIsNotValidForTargetAndHasSPIRVThenSetIRAndBuildOptions) {
ZebinTestData::ValidEmptyProgram zebin;
const uint8_t spirvData[30] = {0xd};
zebin.appendSection(NEO::Elf::SHT_ZEBIN_SPIRV, NEO::Elf::SectionsNamesZebin::spv, spirvData);
zebin.elfHeader->type = NEO::Elf::ET_ZEBIN_EXE;
zebin.elfHeader->machine = IGFX_UNKNOWN;
NEO::TargetDevice targetDevice;
targetDevice.productFamily = IGFX_SKYLAKE;
targetDevice.maxPointerSizeInBytes = 8;
std::string unpackErrors;
std::string unpackWarnings;
auto unpackResult = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(zebin.storage, "", targetDevice, unpackErrors, unpackWarnings);
EXPECT_EQ(NEO::DeviceBinaryFormat::Zebin, unpackResult.format);
EXPECT_TRUE(unpackResult.deviceBinary.empty());
EXPECT_FALSE(unpackResult.intermediateRepresentation.empty());
EXPECT_EQ(0, memcmp(spirvData, unpackResult.intermediateRepresentation.begin(), sizeof(spirvData)));
EXPECT_STREQ(NEO::CompilerOptions::allowZebin.begin(), unpackResult.buildOptions.begin());
}