mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-24 21:18:24 +08:00
fix: encode options in elf file
Resolves: NEO-8035 Signed-off-by: Maciej Plewka <maciej.plewka@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
40c7b2842f
commit
3a9a835692
@@ -1442,6 +1442,69 @@ TEST_F(OclocFatBinaryProductAcronymsTests, givenOpenRangeToFamilyWhenFatBinaryBu
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(OclocFatBinaryTest, givenSpirvInputWhenFatBinaryIsRequestedThenArchiveContainsOptions) {
|
||||
const auto devices = prepareTwoDevices(&mockArgHelper);
|
||||
if (devices.empty()) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
char data[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
MockCompilerDebugVars igcDebugVars(gEnvironment->igcDebugVars);
|
||||
igcDebugVars.binaryToReturn = data;
|
||||
igcDebugVars.binaryToReturnSize = sizeof(data);
|
||||
NEO::setIgcDebugVars(igcDebugVars);
|
||||
|
||||
std::string dummyOptions = "-dummy-option ";
|
||||
const std::vector<std::string> args = {
|
||||
"ocloc",
|
||||
"-output",
|
||||
outputArchiveName,
|
||||
"-file",
|
||||
spirvFilename,
|
||||
"-output_no_suffix",
|
||||
"-spirv_input",
|
||||
"-options",
|
||||
dummyOptions,
|
||||
"-device",
|
||||
devices};
|
||||
|
||||
mockArgHelper.getPrinterRef().setSuppressMessages(true);
|
||||
const auto buildResult = buildFatBinary(args, &mockArgHelper);
|
||||
ASSERT_EQ(OclocErrorCode::SUCCESS, buildResult);
|
||||
ASSERT_EQ(1u, mockArgHelper.interceptedFiles.count(outputArchiveName));
|
||||
|
||||
const auto &rawArchive = mockArgHelper.interceptedFiles[outputArchiveName];
|
||||
const auto archiveBytes = ArrayRef<const std::uint8_t>::fromAny(rawArchive.data(), rawArchive.size());
|
||||
|
||||
std::string outErrReason{};
|
||||
std::string outWarning{};
|
||||
const auto decodedArchive = NEO::Ar::decodeAr(archiveBytes, outErrReason, outWarning);
|
||||
|
||||
ASSERT_NE(nullptr, decodedArchive.magic);
|
||||
ASSERT_TRUE(outErrReason.empty());
|
||||
ASSERT_TRUE(outWarning.empty());
|
||||
|
||||
const auto spirvFileIt = searchInArchiveByFilename(decodedArchive, archiveGenericIrName);
|
||||
ASSERT_NE(decodedArchive.files.end(), spirvFileIt);
|
||||
|
||||
const auto elf = Elf::decodeElf<Elf::EI_CLASS_64>(spirvFileIt->fileData, outErrReason, outWarning);
|
||||
ASSERT_NE(nullptr, elf.elfFileHeader);
|
||||
ASSERT_TRUE(outErrReason.empty());
|
||||
ASSERT_TRUE(outWarning.empty());
|
||||
|
||||
const auto isOptionSection = [](const auto §ion) {
|
||||
return section.header && section.header->type == Elf::SHT_OPENCL_OPTIONS;
|
||||
};
|
||||
|
||||
const auto optionSectionIt = std::find_if(elf.sectionHeaders.begin(), elf.sectionHeaders.end(), isOptionSection);
|
||||
ASSERT_NE(elf.sectionHeaders.end(), optionSectionIt);
|
||||
|
||||
ASSERT_EQ(dummyOptions.size(), optionSectionIt->header->size);
|
||||
const auto isSpirvDataEqualsInputFileData = std::memcmp(dummyOptions.data(), optionSectionIt->data.begin(), dummyOptions.size()) == 0;
|
||||
EXPECT_TRUE(isSpirvDataEqualsInputFileData);
|
||||
NEO::setIgcDebugVars(gEnvironment->igcDebugVars);
|
||||
}
|
||||
|
||||
TEST_F(OclocFatBinaryTest, givenSpirvInputWhenFatBinaryIsRequestedThenArchiveContainsGenericIrFileWithSpirvContent) {
|
||||
const auto devices = prepareTwoDevices(&mockArgHelper);
|
||||
if (devices.empty()) {
|
||||
@@ -1688,11 +1751,12 @@ TEST_F(OclocFatBinaryTest, givenClInputFileWhenFatBinaryIsRequestedThenArchiveDo
|
||||
TEST_F(OclocFatBinaryTest, givenEmptyFileWhenAppendingGenericIrThenInvalidFileIsReturned) {
|
||||
Ar::ArEncoder ar;
|
||||
std::string emptyFile{"empty_file.spv"};
|
||||
std::string dummyOptions{"-cl-opt-disable "};
|
||||
mockArgHelperFilesMap[emptyFile] = "";
|
||||
mockArgHelper.shouldLoadDataFromFileReturnZeroSize = true;
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto errorCode{appendGenericIr(ar, emptyFile, &mockArgHelper)};
|
||||
const auto errorCode{appendGenericIr(ar, emptyFile, &mockArgHelper, dummyOptions)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::INVALID_FILE, errorCode);
|
||||
@@ -1702,10 +1766,11 @@ TEST_F(OclocFatBinaryTest, givenEmptyFileWhenAppendingGenericIrThenInvalidFileIs
|
||||
TEST_F(OclocFatBinaryTest, givenInvalidIrFileWhenAppendingGenericIrThenInvalidFileIsReturned) {
|
||||
Ar::ArEncoder ar;
|
||||
std::string dummyFile{"dummy_file.spv"};
|
||||
std::string dummyOptions{"-cl-opt-disable "};
|
||||
mockArgHelperFilesMap[dummyFile] = "This is not IR!";
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto errorCode{appendGenericIr(ar, dummyFile, &mockArgHelper)};
|
||||
const auto errorCode{appendGenericIr(ar, dummyFile, &mockArgHelper, dummyOptions)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::INVALID_FILE, errorCode);
|
||||
|
||||
@@ -357,7 +357,7 @@ int buildFatBinary(const std::vector<std::string> &args, OclocArgHelper *argHelp
|
||||
argHelper->printf("Warning! -device_options set for non-compiled device: %s\n", deviceAcronym.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::string optionsForIr;
|
||||
for (const auto &product : targetProducts) {
|
||||
int retVal = 0;
|
||||
argsCopy[deviceArgIndex] = product.str();
|
||||
@@ -372,10 +372,13 @@ int buildFatBinary(const std::vector<std::string> &args, OclocArgHelper *argHelp
|
||||
if (retVal) {
|
||||
return retVal;
|
||||
}
|
||||
if (optionsForIr.empty()) {
|
||||
optionsForIr = pCompiler->getOptions();
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldPreserveGenericIr) {
|
||||
const auto errorCode = appendGenericIr(fatbinary, inputFileName, argHelper);
|
||||
const auto errorCode = appendGenericIr(fatbinary, inputFileName, argHelper, optionsForIr);
|
||||
if (errorCode != OclocErrorCode::SUCCESS) {
|
||||
argHelper->printf("Error! Couldn't append generic IR file!\n");
|
||||
return errorCode;
|
||||
@@ -395,7 +398,7 @@ int buildFatBinary(const std::vector<std::string> &args, OclocArgHelper *argHelp
|
||||
return 0;
|
||||
}
|
||||
|
||||
int appendGenericIr(Ar::ArEncoder &fatbinary, const std::string &inputFile, OclocArgHelper *argHelper) {
|
||||
int appendGenericIr(Ar::ArEncoder &fatbinary, const std::string &inputFile, OclocArgHelper *argHelper, std::string options) {
|
||||
std::size_t fileSize = 0;
|
||||
std::unique_ptr<char[]> fileContents = argHelper->loadDataFromFile(inputFile, fileSize);
|
||||
if (fileSize == 0) {
|
||||
@@ -404,24 +407,26 @@ int appendGenericIr(Ar::ArEncoder &fatbinary, const std::string &inputFile, Oclo
|
||||
}
|
||||
|
||||
const auto ir = ArrayRef<const uint8_t>::fromAny(fileContents.get(), fileSize);
|
||||
const auto opt = ArrayRef<const uint8_t>::fromAny(options.data(), options.size());
|
||||
if (!isSpirVBitcode(ir)) {
|
||||
argHelper->printf("Error! Input file is not in supported generic IR format! "
|
||||
"Currently supported format is SPIR-V.\n");
|
||||
return OclocErrorCode::INVALID_FILE;
|
||||
}
|
||||
|
||||
const auto encodedElf = createEncodedElfWithSpirv(ir);
|
||||
const auto encodedElf = createEncodedElfWithSpirv(ir, opt);
|
||||
ArrayRef<const uint8_t> genericIrFile{encodedElf.data(), encodedElf.size()};
|
||||
|
||||
fatbinary.appendFileEntry("generic_ir", genericIrFile);
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> createEncodedElfWithSpirv(const ArrayRef<const uint8_t> &spirv) {
|
||||
std::vector<uint8_t> createEncodedElfWithSpirv(const ArrayRef<const uint8_t> &spirv, const ArrayRef<const uint8_t> &options) {
|
||||
using namespace NEO::Elf;
|
||||
ElfEncoder<EI_CLASS_64> elfEncoder;
|
||||
elfEncoder.getElfFileHeader().type = ET_OPENCL_OBJECTS;
|
||||
elfEncoder.appendSection(SHT_OPENCL_SPIRV, SectionNamesOpenCl::spirvObject, spirv);
|
||||
elfEncoder.appendSection(SHT_OPENCL_OPTIONS, SectionNamesOpenCl::buildOptions, options);
|
||||
|
||||
return elfEncoder.encode();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ std::vector<NEO::ConstStringRef> getProductsForRange(unsigned int productFrom, u
|
||||
std::vector<ConstStringRef> getTargetProductsForFatbinary(ConstStringRef deviceArg, OclocArgHelper *argHelper);
|
||||
int buildFatBinaryForTarget(int retVal, const std::vector<std::string> &argsCopy, std::string pointerSize, Ar::ArEncoder &fatbinary,
|
||||
OfflineCompiler *pCompiler, OclocArgHelper *argHelper, const std::string &deviceConfig);
|
||||
int appendGenericIr(Ar::ArEncoder &fatbinary, const std::string &inputFile, OclocArgHelper *argHelper);
|
||||
std::vector<uint8_t> createEncodedElfWithSpirv(const ArrayRef<const uint8_t> &spirv);
|
||||
int appendGenericIr(Ar::ArEncoder &fatbinary, const std::string &inputFile, OclocArgHelper *argHelper, std::string options);
|
||||
std::vector<uint8_t> createEncodedElfWithSpirv(const ArrayRef<const uint8_t> &spirv, const ArrayRef<const uint8_t> &options);
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -97,6 +97,10 @@ All supported acronyms: %s.
|
||||
}
|
||||
bool showHelpOnly() const { return showHelp; }
|
||||
|
||||
std::string getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
protected:
|
||||
OfflineCompiler();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user