mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-20 17:00:59 +08:00
feat(zebin): Add support for SHT_ZEBIN_GTPIN_INFO type section
This commit adds support for decoding SHT_ZEBIN_GTPIN_INFO type sections. For each section, passed data will be stored in kernel info (for corresponding kernel). Related-To: NEO-7689 Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
7790e208fd
commit
1a4755694e
@@ -56,7 +56,7 @@ inline constexpr ConstStringRef debugPrefix = ".debug_";
|
||||
inline constexpr ConstStringRef debugInfo = ".debug_info";
|
||||
inline constexpr ConstStringRef debugAbbrev = ".debug_abbrev";
|
||||
inline constexpr ConstStringRef zeInfo = ".ze_info";
|
||||
inline constexpr ConstStringRef gtpinInfo = ".gtpin_info";
|
||||
inline constexpr ConstStringRef gtpinInfo = ".gtpin_info.";
|
||||
inline constexpr ConstStringRef noteIntelGT = ".note.intelgt.compat";
|
||||
inline constexpr ConstStringRef buildOptions = ".misc.buildOptions";
|
||||
inline constexpr ConstStringRef vIsaAsmPrefix = ".visaasm.";
|
||||
|
||||
@@ -270,8 +270,12 @@ DecodeError extractZebinSections(NEO::Elf::Elf<numBits> &elf, ZebinSections<numB
|
||||
// ignoring intentionally - rel/rela sections handled by Elf decoder
|
||||
continue;
|
||||
case NEO::Elf::SHT_ZEBIN_GTPIN_INFO:
|
||||
// ignoring intentionally - gtpin internal data
|
||||
continue;
|
||||
if (sectionName.startsWith(NEO::Elf::SectionsNamesZebin::gtpinInfo.data())) {
|
||||
out.gtpinInfoSections.push_back(&elfSectionHeader);
|
||||
} else {
|
||||
outWarning.append("DeviceBinaryFormat::Zebin : Unhandled SHT_ZEBIN_GTPIN_INFO section : " + sectionName.str() + ", currently supports only : " + NEO::Elf::SectionsNamesZebin::gtpinInfo.str() + "KERNEL_NAME\n");
|
||||
}
|
||||
break;
|
||||
case NEO::Elf::SHT_ZEBIN_VISA_ASM:
|
||||
// ignoring intentionally - visa asm
|
||||
continue;
|
||||
@@ -765,6 +769,11 @@ DecodeError decodeZebin(ProgramInfo &dst, NEO::Elf::Elf<numBits> &elf, std::stri
|
||||
return DecodeError::InvalidBinary;
|
||||
}
|
||||
|
||||
auto gtpinInfoForKernel = getKernelGtpinInfo(kernelName, elf, zebinSections);
|
||||
if (false == gtpinInfoForKernel.empty()) {
|
||||
kernelInfo->igcInfoForGtpin = reinterpret_cast<const gtpin::igc_info_t *>(gtpinInfoForKernel.begin());
|
||||
}
|
||||
|
||||
kernelInfo->heapInfo.pKernelHeap = kernelInstructions.begin();
|
||||
kernelInfo->heapInfo.KernelHeapSize = static_cast<uint32_t>(kernelInstructions.size());
|
||||
kernelInfo->heapInfo.KernelUnpaddedSize = static_cast<uint32_t>(kernelInstructions.size());
|
||||
@@ -797,6 +806,22 @@ ArrayRef<const uint8_t> getKernelHeap(ConstStringRef &kernelName, Elf::Elf<numBi
|
||||
return {};
|
||||
}
|
||||
|
||||
template ArrayRef<const uint8_t> getKernelGtpinInfo<Elf::EI_CLASS_32>(ConstStringRef &kernelName, Elf::Elf<Elf::EI_CLASS_32> &elf, const ZebinSections<Elf::EI_CLASS_32> &zebinSections);
|
||||
template ArrayRef<const uint8_t> getKernelGtpinInfo<Elf::EI_CLASS_64>(ConstStringRef &kernelName, Elf::Elf<Elf::EI_CLASS_64> &elf, const ZebinSections<Elf::EI_CLASS_64> &zebinSections);
|
||||
template <Elf::ELF_IDENTIFIER_CLASS numBits>
|
||||
ArrayRef<const uint8_t> getKernelGtpinInfo(ConstStringRef &kernelName, Elf::Elf<numBits> &elf, const ZebinSections<numBits> &zebinSections) {
|
||||
auto sectionHeaderNamesData = elf.sectionHeaders[elf.elfFileHeader->shStrNdx].data;
|
||||
ConstStringRef sectionHeaderNamesString(reinterpret_cast<const char *>(sectionHeaderNamesData.begin()), sectionHeaderNamesData.size());
|
||||
for (auto *gtpinInfoSection : zebinSections.gtpinInfoSections) {
|
||||
ConstStringRef sectionName = ConstStringRef(sectionHeaderNamesString.begin() + gtpinInfoSection->header->name);
|
||||
auto sufix = sectionName.substr(static_cast<int>(NEO::Elf::SectionsNamesZebin::gtpinInfo.length()));
|
||||
if (sufix == kernelName) {
|
||||
return gtpinInfoSection->data;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
DecodeError decodeZeInfo(ProgramInfo &dst, ConstStringRef zeInfo, std::string &outErrReason, std::string &outWarning) {
|
||||
Yaml::YamlParser yamlParser;
|
||||
bool parseSuccess = yamlParser.parse(zeInfo, outErrReason, outWarning);
|
||||
|
||||
@@ -28,6 +28,7 @@ template <Elf::ELF_IDENTIFIER_CLASS numBits = Elf::EI_CLASS_64>
|
||||
struct ZebinSections {
|
||||
using SectionHeaderData = typename NEO::Elf::Elf<numBits>::SectionHeaderAndData;
|
||||
StackVec<SectionHeaderData *, 32> textKernelSections;
|
||||
StackVec<SectionHeaderData *, 32> gtpinInfoSections;
|
||||
StackVec<SectionHeaderData *, 1> zeInfoSections;
|
||||
StackVec<SectionHeaderData *, 1> globalDataSections;
|
||||
StackVec<SectionHeaderData *, 1> globalZeroInitDataSections;
|
||||
@@ -104,6 +105,9 @@ NEO::DecodeError decodeZebin(ProgramInfo &dst, NEO::Elf::Elf<numBits> &elf, std:
|
||||
template <Elf::ELF_IDENTIFIER_CLASS numBits>
|
||||
ArrayRef<const uint8_t> getKernelHeap(ConstStringRef &kernelName, Elf::Elf<numBits> &elf, const ZebinSections<numBits> &zebinSections);
|
||||
|
||||
template <Elf::ELF_IDENTIFIER_CLASS numBits>
|
||||
ArrayRef<const uint8_t> getKernelGtpinInfo(ConstStringRef &kernelName, Elf::Elf<numBits> &elf, const ZebinSections<numBits> &zebinSections);
|
||||
|
||||
NEO::DecodeError decodeZeInfo(ProgramInfo &dst, ConstStringRef zeInfo, std::string &outErrReason, std::string &outWarning);
|
||||
|
||||
void setKernelMiscInfoPosition(ConstStringRef metadata, NEO::ProgramInfo &dst);
|
||||
|
||||
@@ -149,7 +149,8 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_SYMTAB, NEO::Elf::SectionsNamesZebin::symtab, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_ZEINFO, NEO::Elf::SectionsNamesZebin::zeInfo, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_SPIRV, NEO::Elf::SectionsNamesZebin::spv, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_GTPIN_INFO, NEO::Elf::SectionsNamesZebin::gtpinInfo, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_GTPIN_INFO, NEO::Elf::SectionsNamesZebin::gtpinInfo.str() + "someKernel", std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_GTPIN_INFO, NEO::Elf::SectionsNamesZebin::gtpinInfo.str() + "someOtherKernel", std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_VISA_ASM, NEO::Elf::SectionsNamesZebin::vIsaAsmPrefix.str() + "someKernel", std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_MISC, NEO::Elf::SectionsNamesZebin::buildOptions, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_NOBITS, NEO::Elf::SectionsNamesZebin::dataConstZeroInit.str(), std::string{});
|
||||
@@ -172,6 +173,8 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
|
||||
EXPECT_TRUE(errors.empty()) << errors;
|
||||
|
||||
ASSERT_EQ(2U, sections.textKernelSections.size());
|
||||
ASSERT_EQ(2U, sections.gtpinInfoSections.size());
|
||||
|
||||
ASSERT_EQ(1U, sections.globalDataSections.size());
|
||||
ASSERT_EQ(1U, sections.constDataSections.size());
|
||||
ASSERT_EQ(1U, sections.constDataStringSections.size());
|
||||
@@ -186,6 +189,8 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
|
||||
const char *strings = stringSection.data.toArrayRef<const char>().begin();
|
||||
EXPECT_STREQ((NEO::Elf::SectionsNamesZebin::textPrefix.str() + "someKernel").c_str(), strings + sections.textKernelSections[0]->header->name);
|
||||
EXPECT_STREQ((NEO::Elf::SectionsNamesZebin::textPrefix.str() + "someOtherKernel").c_str(), strings + sections.textKernelSections[1]->header->name);
|
||||
EXPECT_STREQ((NEO::Elf::SectionsNamesZebin::gtpinInfo.str() + "someKernel").c_str(), strings + sections.gtpinInfoSections[0]->header->name);
|
||||
EXPECT_STREQ((NEO::Elf::SectionsNamesZebin::gtpinInfo.str() + "someOtherKernel").c_str(), strings + sections.gtpinInfoSections[1]->header->name);
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::dataGlobal.data(), strings + sections.globalDataSections[0]->header->name);
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::dataConst.data(), strings + sections.constDataSections[0]->header->name);
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::dataConstString.data(), strings + sections.constDataStringSections[0]->header->name);
|
||||
@@ -196,7 +201,7 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::dataGlobalZeroInit.data(), strings + sections.globalZeroInitDataSections[0]->header->name);
|
||||
}
|
||||
|
||||
TEST(ExtractZebinSections, GivenMispelledConstDataSectionThenAllowItButEmitError) {
|
||||
TEST(ExtractZebinSections, GivenMispelledConstDataSectionThenAllowItButEmitWarning) {
|
||||
NEO::Elf::ElfEncoder<> elfEncoder;
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, ".data.global_const", std::string{});
|
||||
auto encodedElf = elfEncoder.encode();
|
||||
@@ -219,6 +224,24 @@ TEST(ExtractZebinSections, GivenMispelledConstDataSectionThenAllowItButEmitError
|
||||
EXPECT_STREQ(".data.global_const", strings + sections.constDataSections[0]->header->name);
|
||||
}
|
||||
|
||||
TEST(ExtractZebinSections, GivenUnknownZebinGtpinInfoSectionThenEmitWarning) {
|
||||
NEO::Elf::ElfEncoder<> elfEncoder;
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_ZEBIN_GTPIN_INFO, ".unknown", std::string{});
|
||||
auto encodedElf = elfEncoder.encode();
|
||||
std::string elferrors;
|
||||
std::string elfwarnings;
|
||||
auto decodedElf = NEO::Elf::decodeElf(encodedElf, elferrors, elfwarnings);
|
||||
|
||||
NEO::ZebinSections sections;
|
||||
std::string errors;
|
||||
std::string warnings;
|
||||
auto decodeError = NEO::extractZebinSections(decodedElf, sections, errors, warnings);
|
||||
EXPECT_EQ(NEO::DecodeError::Success, decodeError);
|
||||
std::string expectedWarning{"DeviceBinaryFormat::Zebin : Unhandled SHT_ZEBIN_GTPIN_INFO section : .unknown, currently supports only : " + NEO::Elf::SectionsNamesZebin::gtpinInfo.str() + "KERNEL_NAME\n"};
|
||||
EXPECT_STREQ(expectedWarning.c_str(), warnings.c_str());
|
||||
EXPECT_TRUE(errors.empty()) << errors;
|
||||
}
|
||||
|
||||
TEST(ExtractZebinSections, GivenUnknownMiscSectionThenEmitWarning) {
|
||||
NEO::Elf::ElfEncoder<> elfEncoder;
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix.str() + "someKernel", std::string{});
|
||||
@@ -3817,6 +3840,37 @@ kernels:
|
||||
EXPECT_STREQ("DeviceBinaryFormat::Zebin : Could not find text section for kernel some_kernel\n", errors.c_str());
|
||||
}
|
||||
|
||||
TEST(DecodeZebinTest, givenGtpinInfoSectionsWhenDecodingZebinThenProperlySetIgcInfoForGtpinForEachCorrespondingKernel) {
|
||||
std::string errors, warnings;
|
||||
ZebinTestData::ValidEmptyProgram zebin;
|
||||
const uint8_t data[0x10]{0u};
|
||||
zebin.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix.str() + "someOtherKernel", ArrayRef<const uint8_t>::fromAny(data, 0x10));
|
||||
|
||||
std::array<uint8_t, 16> mockGtpinData1{};
|
||||
mockGtpinData1.fill(7u);
|
||||
std::array<uint8_t, 16> mockGtpinData2{};
|
||||
mockGtpinData2.fill(16u);
|
||||
zebin.appendSection(NEO::Elf::SHT_ZEBIN_GTPIN_INFO, NEO::Elf::SectionsNamesZebin::gtpinInfo.str() + zebin.kernelName, ArrayRef<const uint8_t>::fromAny(mockGtpinData1.data(), mockGtpinData1.size()));
|
||||
zebin.appendSection(NEO::Elf::SHT_ZEBIN_GTPIN_INFO, NEO::Elf::SectionsNamesZebin::gtpinInfo.str() + "someOtherKernel", ArrayRef<const uint8_t>::fromAny(mockGtpinData2.data(), mockGtpinData2.size()));
|
||||
|
||||
auto elf = NEO::Elf::decodeElf(zebin.storage, errors, warnings);
|
||||
ASSERT_NE(nullptr, elf.elfFileHeader) << errors << " " << warnings;
|
||||
|
||||
NEO::ProgramInfo programInfo;
|
||||
programInfo.kernelInfos.reserve(2);
|
||||
auto kernelInfo1 = new KernelInfo();
|
||||
kernelInfo1->kernelDescriptor.kernelMetadata.kernelName = zebin.kernelName;
|
||||
programInfo.kernelInfos.push_back(kernelInfo1);
|
||||
auto kernelInfo2 = new KernelInfo();
|
||||
kernelInfo2->kernelDescriptor.kernelMetadata.kernelName = "someOtherKernel";
|
||||
programInfo.kernelInfos.push_back(kernelInfo2);
|
||||
|
||||
auto err = decodeZebin(programInfo, elf, errors, warnings);
|
||||
EXPECT_EQ(NEO::DecodeError::Success, err);
|
||||
EXPECT_EQ(0, memcmp(reinterpret_cast<const uint8_t *>(kernelInfo1->igcInfoForGtpin), mockGtpinData1.data(), mockGtpinData1.size()));
|
||||
EXPECT_EQ(0, memcmp(reinterpret_cast<const uint8_t *>(kernelInfo2->igcInfoForGtpin), mockGtpinData2.data(), mockGtpinData2.size()));
|
||||
}
|
||||
|
||||
TEST_F(decodeZeInfoKernelEntryTest, GivenValidExecutionEnvironmentThenPopulateKernelDescriptorProperly) {
|
||||
ConstStringRef zeinfo = R"===(
|
||||
kernels:
|
||||
|
||||
Reference in New Issue
Block a user