fix(zebin): corrections related to IntelGT notes + bump ZEInfo version
- Value correction: IntelGTSectionType::ProductConfig to 6, add new type IntelGTSectionType::vISAAbiVersion = 5 - currently ignored by the runtime - For zebin manipulator: allow to extract PRODUCT_FAMILY from AOT productConfig - required by IGA wrapper for binary encoding/decoding + add tests - Bump ZEInfo version to the latest: 1.32 Related-To: IGC-6300 Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
This commit is contained in:
parent
b004a27e4e
commit
12f597bc72
|
@ -22,6 +22,7 @@
|
||||||
#include "igfxfmid.h"
|
#include "igfxfmid.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <platforms.h>
|
||||||
|
|
||||||
template <NEO::Elf::ELF_IDENTIFIER_CLASS numBits>
|
template <NEO::Elf::ELF_IDENTIFIER_CLASS numBits>
|
||||||
struct MockZebin {
|
struct MockZebin {
|
||||||
|
@ -268,7 +269,7 @@ TEST(ZebinManipulatorTests, GivenIntelGTNotesWithProductFamilyWhenParsingIntelGT
|
||||||
intelGTnotes[0].data = ArrayRef<const uint8_t>::fromAny(&productFamily, 1);
|
intelGTnotes[0].data = ArrayRef<const uint8_t>::fromAny(&productFamily, 1);
|
||||||
|
|
||||||
auto iga = std::make_unique<MockIgaWrapper>();
|
auto iga = std::make_unique<MockIgaWrapper>();
|
||||||
auto retVal = NEO::Zebin::Manipulator::parseIntelGTNotesSectionForDevice(intelGTnotes, iga.get());
|
auto retVal = NEO::Zebin::Manipulator::parseIntelGTNotesSectionForDevice(intelGTnotes, iga.get(), nullptr);
|
||||||
EXPECT_EQ(NEO::OclocErrorCode::SUCCESS, retVal);
|
EXPECT_EQ(NEO::OclocErrorCode::SUCCESS, retVal);
|
||||||
EXPECT_TRUE(iga->setProductFamilyWasCalled);
|
EXPECT_TRUE(iga->setProductFamilyWasCalled);
|
||||||
}
|
}
|
||||||
|
@ -281,16 +282,50 @@ TEST(ZebinManipulatorTests, GivenIntelGTNotesWithGfxCoreFamilyWhenParsingIntelGT
|
||||||
intelGTnotes[0].data = ArrayRef<const uint8_t>::fromAny(&gfxCore, 1);
|
intelGTnotes[0].data = ArrayRef<const uint8_t>::fromAny(&gfxCore, 1);
|
||||||
|
|
||||||
auto iga = std::make_unique<MockIgaWrapper>();
|
auto iga = std::make_unique<MockIgaWrapper>();
|
||||||
auto retVal = NEO::Zebin::Manipulator::parseIntelGTNotesSectionForDevice(intelGTnotes, iga.get());
|
auto retVal = NEO::Zebin::Manipulator::parseIntelGTNotesSectionForDevice(intelGTnotes, iga.get(), nullptr);
|
||||||
EXPECT_EQ(NEO::OclocErrorCode::SUCCESS, retVal);
|
EXPECT_EQ(NEO::OclocErrorCode::SUCCESS, retVal);
|
||||||
EXPECT_TRUE(iga->setGfxCoreWasCalled);
|
EXPECT_TRUE(iga->setGfxCoreWasCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ZebinManipulatorTests, GivenIntelGTNotesWithValidProductConfigWhenParsingIntelGTNoteSectionsForDeviceThenIgaProductFamilyIsSetAndSuccessIsReturned) {
|
||||||
|
MockOclocArgHelper::FilesMap files;
|
||||||
|
files.insert({"binary.bin", "000000000000000"});
|
||||||
|
MockOclocArgHelper argHelper(files);
|
||||||
|
|
||||||
|
const auto &aotInfo = argHelper.productConfigHelper->getDeviceAotInfo().back();
|
||||||
|
auto productConfig = aotInfo.aotConfig;
|
||||||
|
std::vector<NEO::Zebin::Elf::IntelGTNote> intelGTnotes;
|
||||||
|
intelGTnotes.resize(1);
|
||||||
|
intelGTnotes[0].type = NEO::Zebin::Elf::IntelGTSectionType::ProductConfig;
|
||||||
|
intelGTnotes[0].data = ArrayRef<const uint8_t>::fromAny(&productConfig, 1u);
|
||||||
|
|
||||||
|
auto iga = std::make_unique<MockIgaWrapper>();
|
||||||
|
auto retVal = NEO::Zebin::Manipulator::parseIntelGTNotesSectionForDevice(intelGTnotes, iga.get(), &argHelper);
|
||||||
|
EXPECT_EQ(NEO::OclocErrorCode::SUCCESS, retVal);
|
||||||
|
EXPECT_TRUE(iga->setProductFamilyWasCalled);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ZebinManipulatorTests, GivenIntelGTNotesWithInvalidProductConfigWhenParsingIntelGTNoteSectionsForDeviceThenReturnError) {
|
||||||
|
MockOclocArgHelper::FilesMap files;
|
||||||
|
files.insert({"binary.bin", "000000000000000"});
|
||||||
|
MockOclocArgHelper argHelper(files);
|
||||||
|
|
||||||
|
AOT::PRODUCT_CONFIG productConfig = AOT::PRODUCT_CONFIG::UNKNOWN_ISA;
|
||||||
|
std::vector<NEO::Zebin::Elf::IntelGTNote> intelGTnotes;
|
||||||
|
intelGTnotes.resize(1);
|
||||||
|
intelGTnotes[0].type = NEO::Zebin::Elf::IntelGTSectionType::ProductConfig;
|
||||||
|
intelGTnotes[0].data = ArrayRef<const uint8_t>::fromAny(&productConfig, 1u);
|
||||||
|
|
||||||
|
auto iga = std::make_unique<MockIgaWrapper>();
|
||||||
|
auto retVal = NEO::Zebin::Manipulator::parseIntelGTNotesSectionForDevice(intelGTnotes, iga.get(), &argHelper);
|
||||||
|
EXPECT_EQ(NEO::OclocErrorCode::INVALID_DEVICE, retVal);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ZebinManipulatorTests, GivenIntelGTNotesWithoutProductFamilyOrGfxCoreFamilyEntryWhenParsingIntelGTNoteSectionsForDeviceThenReturnError) {
|
TEST(ZebinManipulatorTests, GivenIntelGTNotesWithoutProductFamilyOrGfxCoreFamilyEntryWhenParsingIntelGTNoteSectionsForDeviceThenReturnError) {
|
||||||
std::vector<NEO::Zebin::Elf::IntelGTNote> intelGTnotes;
|
std::vector<NEO::Zebin::Elf::IntelGTNote> intelGTnotes;
|
||||||
|
|
||||||
auto iga = std::make_unique<MockIgaWrapper>();
|
auto iga = std::make_unique<MockIgaWrapper>();
|
||||||
auto retVal = NEO::Zebin::Manipulator::parseIntelGTNotesSectionForDevice(intelGTnotes, iga.get());
|
auto retVal = NEO::Zebin::Manipulator::parseIntelGTNotesSectionForDevice(intelGTnotes, iga.get(), nullptr);
|
||||||
EXPECT_EQ(NEO::OclocErrorCode::INVALID_DEVICE, retVal);
|
EXPECT_EQ(NEO::OclocErrorCode::INVALID_DEVICE, retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,24 +14,45 @@
|
||||||
#include "shared/source/device_binary_format/elf/elf_decoder.h"
|
#include "shared/source/device_binary_format/elf/elf_decoder.h"
|
||||||
#include "shared/source/device_binary_format/elf/elf_encoder.h"
|
#include "shared/source/device_binary_format/elf/elf_encoder.h"
|
||||||
#include "shared/source/device_binary_format/zebin/zebin_decoder.h"
|
#include "shared/source/device_binary_format/zebin/zebin_decoder.h"
|
||||||
|
#include "shared/source/helpers/hw_info.h"
|
||||||
#include "shared/source/utilities/directory.h"
|
#include "shared/source/utilities/directory.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace NEO::Zebin::Manipulator {
|
namespace NEO::Zebin::Manipulator {
|
||||||
|
|
||||||
ErrorCode parseIntelGTNotesSectionForDevice(const std::vector<Zebin::Elf::IntelGTNote> &intelGTNotes, IgaWrapper *iga) {
|
ErrorCode parseIntelGTNotesSectionForDevice(const std::vector<Zebin::Elf::IntelGTNote> &intelGTNotes, IgaWrapper *iga, OclocArgHelper *argHelper) {
|
||||||
size_t productFamilyNoteId = std::numeric_limits<size_t>::max();
|
size_t productFamilyNoteId = std::numeric_limits<size_t>::max();
|
||||||
size_t gfxCoreNoteId = std::numeric_limits<size_t>::max();
|
size_t gfxCoreNoteId = std::numeric_limits<size_t>::max();
|
||||||
|
size_t productConfigNoteId = std::numeric_limits<size_t>::max();
|
||||||
|
|
||||||
for (size_t i = 0; i < intelGTNotes.size(); i++) {
|
for (size_t i = 0; i < intelGTNotes.size(); i++) {
|
||||||
if (intelGTNotes[i].type == Zebin::Elf::IntelGTSectionType::ProductFamily) {
|
if (intelGTNotes[i].type == Zebin::Elf::IntelGTSectionType::ProductFamily) {
|
||||||
productFamilyNoteId = i;
|
productFamilyNoteId = i;
|
||||||
} else if (intelGTNotes[i].type == Zebin::Elf::IntelGTSectionType::GfxCore) {
|
} else if (intelGTNotes[i].type == Zebin::Elf::IntelGTSectionType::GfxCore) {
|
||||||
gfxCoreNoteId = i;
|
gfxCoreNoteId = i;
|
||||||
|
} else if (intelGTNotes[i].type == Zebin::Elf::IntelGTSectionType::ProductConfig) {
|
||||||
|
productConfigNoteId = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (productFamilyNoteId != std::numeric_limits<size_t>::max()) {
|
if (productConfigNoteId != std::numeric_limits<size_t>::max()) {
|
||||||
|
UNRECOVERABLE_IF(sizeof(uint32_t) != intelGTNotes[productConfigNoteId].data.size());
|
||||||
|
auto productConfig = *reinterpret_cast<const uint32_t *>(intelGTNotes[productConfigNoteId].data.begin());
|
||||||
|
|
||||||
|
NEO::HardwareInfo hwInfo;
|
||||||
|
const auto &deviceAotMap = argHelper->productConfigHelper->getDeviceAotInfo();
|
||||||
|
for (auto &deviceConfig : deviceAotMap) {
|
||||||
|
if (deviceConfig.aotConfig.value == productConfig) {
|
||||||
|
hwInfo = *deviceConfig.hwInfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (IGFX_UNKNOWN != hwInfo.platform.eProductFamily) {
|
||||||
|
iga->setProductFamily(hwInfo.platform.eProductFamily);
|
||||||
|
return OclocErrorCode::SUCCESS;
|
||||||
|
}
|
||||||
|
} else if (productFamilyNoteId != std::numeric_limits<size_t>::max()) {
|
||||||
UNRECOVERABLE_IF(sizeof(PRODUCT_FAMILY) != intelGTNotes[productFamilyNoteId].data.size());
|
UNRECOVERABLE_IF(sizeof(PRODUCT_FAMILY) != intelGTNotes[productFamilyNoteId].data.size());
|
||||||
auto productFamily = *reinterpret_cast<const PRODUCT_FAMILY *>(intelGTNotes[productFamilyNoteId].data.begin());
|
auto productFamily = *reinterpret_cast<const PRODUCT_FAMILY *>(intelGTNotes[productFamilyNoteId].data.begin());
|
||||||
iga->setProductFamily(productFamily);
|
iga->setProductFamily(productFamily);
|
||||||
|
@ -160,7 +181,7 @@ ErrorCode ZebinDecoder<numBits>::decode() {
|
||||||
return OclocErrorCode::INVALID_FILE;
|
return OclocErrorCode::INVALID_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal = parseIntelGTNotesSectionForDevice(intelGTNotes, iga.get());
|
retVal = parseIntelGTNotesSectionForDevice(intelGTNotes, iga.get(), argHelper);
|
||||||
if (retVal != OclocErrorCode::SUCCESS) {
|
if (retVal != OclocErrorCode::SUCCESS) {
|
||||||
argHelper->printf("Error while parsing Intel GT Notes section for device.\n");
|
argHelper->printf("Error while parsing Intel GT Notes section for device.\n");
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -380,7 +401,7 @@ ErrorCode ZebinEncoder<numBits>::encode() {
|
||||||
|
|
||||||
auto intelGTNotesSectionData = getIntelGTNotesSection(sectionInfos);
|
auto intelGTNotesSectionData = getIntelGTNotesSection(sectionInfos);
|
||||||
auto intelGTNotes = getIntelGTNotes(intelGTNotesSectionData);
|
auto intelGTNotes = getIntelGTNotes(intelGTNotesSectionData);
|
||||||
retVal = parseIntelGTNotesSectionForDevice(intelGTNotes, iga.get());
|
retVal = parseIntelGTNotesSectionForDevice(intelGTNotes, iga.get(), argHelper);
|
||||||
if (retVal != OclocErrorCode::SUCCESS) {
|
if (retVal != OclocErrorCode::SUCCESS) {
|
||||||
argHelper->printf("Error while parsing Intel GT Notes section for device.\n");
|
argHelper->printf("Error while parsing Intel GT Notes section for device.\n");
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
|
@ -52,7 +52,7 @@ enum BinaryFormats {
|
||||||
|
|
||||||
using ErrorCode = int;
|
using ErrorCode = int;
|
||||||
|
|
||||||
ErrorCode parseIntelGTNotesSectionForDevice(const std::vector<Zebin::Elf::IntelGTNote> &intelGTNotes, IgaWrapper *iga);
|
ErrorCode parseIntelGTNotesSectionForDevice(const std::vector<Zebin::Elf::IntelGTNote> &intelGTNotes, IgaWrapper *iga, OclocArgHelper *argHelper);
|
||||||
ErrorCode validateInput(const std::vector<std::string> &args, IgaWrapper *iga, OclocArgHelper *argHelper, Arguments &outArguments);
|
ErrorCode validateInput(const std::vector<std::string> &args, IgaWrapper *iga, OclocArgHelper *argHelper, Arguments &outArguments);
|
||||||
|
|
||||||
BinaryFormats getBinaryFormatForAssemble(OclocArgHelper *argHelper, const std::vector<std::string> &args);
|
BinaryFormats getBinaryFormatForAssemble(OclocArgHelper *argHelper, const std::vector<std::string> &args);
|
||||||
|
|
|
@ -129,6 +129,9 @@ bool validateTargetDevice(const Elf::Elf<numBits> &elf, const TargetDevice &targ
|
||||||
productConfig = static_cast<AOT::PRODUCT_CONFIG>(*productConfigData);
|
productConfig = static_cast<AOT::PRODUCT_CONFIG>(*productConfigData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Elf::IntelGTSectionType::vISAAbiVersion: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
outWarning.append("DeviceBinaryFormat::Zebin : Unrecognized IntelGTNote type: " + std::to_string(intelGTNote.type) + "\n");
|
outWarning.append("DeviceBinaryFormat::Zebin : Unrecognized IntelGTNote type: " + std::to_string(intelGTNote.type) + "\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -64,7 +64,8 @@ enum IntelGTSectionType : uint32_t {
|
||||||
GfxCore = 2,
|
GfxCore = 2,
|
||||||
TargetMetadata = 3,
|
TargetMetadata = 3,
|
||||||
ZebinVersion = 4,
|
ZebinVersion = 4,
|
||||||
ProductConfig = 5,
|
vISAAbiVersion = 5, // for debugger only
|
||||||
|
ProductConfig = 6,
|
||||||
LastSupported = ProductConfig
|
LastSupported = ProductConfig
|
||||||
};
|
};
|
||||||
struct IntelGTNote {
|
struct IntelGTNote {
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct KernelInfo;
|
||||||
struct ProgramInfo;
|
struct ProgramInfo;
|
||||||
|
|
||||||
namespace Zebin::ZeInfo {
|
namespace Zebin::ZeInfo {
|
||||||
inline constexpr NEO::Zebin::ZeInfo::Types::Version zeInfoDecoderVersion{1, 26};
|
inline constexpr NEO::Zebin::ZeInfo::Types::Version zeInfoDecoderVersion{1, 32};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool readEnumChecked(ConstStringRef enumString, T &outValue, ConstStringRef kernelName, std::string &outErrReason);
|
bool readEnumChecked(ConstStringRef enumString, T &outValue, ConstStringRef kernelName, std::string &outErrReason);
|
||||||
|
|
|
@ -5342,8 +5342,9 @@ class IntelGTNotesFixture : public ::testing::Test {
|
||||||
|
|
||||||
TEST_F(IntelGTNotesFixture, WhenGettingIntelGTNotesGivenValidIntelGTNotesSectionThenReturnsIntelGTNotes) {
|
TEST_F(IntelGTNotesFixture, WhenGettingIntelGTNotesGivenValidIntelGTNotesSectionThenReturnsIntelGTNotes) {
|
||||||
std::vector<NEO::Elf::ElfNoteSection> elfNoteSections;
|
std::vector<NEO::Elf::ElfNoteSection> elfNoteSections;
|
||||||
|
size_t numNotes = 5;
|
||||||
|
|
||||||
for (auto i = 0; i < 4; i++) {
|
for (size_t i = 0; i < numNotes; i++) {
|
||||||
auto &inserted = elfNoteSections.emplace_back();
|
auto &inserted = elfNoteSections.emplace_back();
|
||||||
inserted.nameSize = 8u;
|
inserted.nameSize = 8u;
|
||||||
inserted.descSize = 4u;
|
inserted.descSize = 4u;
|
||||||
|
@ -5352,6 +5353,7 @@ TEST_F(IntelGTNotesFixture, WhenGettingIntelGTNotesGivenValidIntelGTNotesSection
|
||||||
elfNoteSections.at(1).type = Zebin::Elf::IntelGTSectionType::GfxCore;
|
elfNoteSections.at(1).type = Zebin::Elf::IntelGTSectionType::GfxCore;
|
||||||
elfNoteSections.at(2).type = Zebin::Elf::IntelGTSectionType::TargetMetadata;
|
elfNoteSections.at(2).type = Zebin::Elf::IntelGTSectionType::TargetMetadata;
|
||||||
elfNoteSections.at(3).type = Zebin::Elf::IntelGTSectionType::ZebinVersion;
|
elfNoteSections.at(3).type = Zebin::Elf::IntelGTSectionType::ZebinVersion;
|
||||||
|
elfNoteSections.at(4).type = Zebin::Elf::IntelGTSectionType::vISAAbiVersion; // not handled by the runtime, but should be recognized
|
||||||
|
|
||||||
Zebin::Elf::ZebinTargetFlags targetMetadata;
|
Zebin::Elf::ZebinTargetFlags targetMetadata;
|
||||||
targetMetadata.validateRevisionId = true;
|
targetMetadata.validateRevisionId = true;
|
||||||
|
@ -5371,8 +5373,9 @@ TEST_F(IntelGTNotesFixture, WhenGettingIntelGTNotesGivenValidIntelGTNotesSection
|
||||||
memcpy_s(metadataPackedData, 4, &targetMetadata.packed, 4);
|
memcpy_s(metadataPackedData, 4, &targetMetadata.packed, 4);
|
||||||
descData.push_back(metadataPackedData);
|
descData.push_back(metadataPackedData);
|
||||||
|
|
||||||
uint8_t zebinaryVersionData[4] = {0x0, 0x0, 0x0, 0x0};
|
uint8_t mockData[4] = {0x0, 0x0, 0x0, 0x0}; // mock data for ZebinVersion and vISAAbiVersion notes
|
||||||
descData.push_back(zebinaryVersionData);
|
descData.push_back(mockData);
|
||||||
|
descData.push_back(mockData);
|
||||||
const auto sectionDataSize = std::accumulate(elfNoteSections.begin(), elfNoteSections.end(), size_t{0u},
|
const auto sectionDataSize = std::accumulate(elfNoteSections.begin(), elfNoteSections.end(), size_t{0u},
|
||||||
[](auto totalSize, const auto &elfNoteSection) {
|
[](auto totalSize, const auto &elfNoteSection) {
|
||||||
return totalSize + sizeof(NEO::Elf::ElfNoteSection) + elfNoteSection.nameSize + elfNoteSection.descSize;
|
return totalSize + sizeof(NEO::Elf::ElfNoteSection) + elfNoteSection.nameSize + elfNoteSection.descSize;
|
||||||
|
@ -5392,7 +5395,7 @@ TEST_F(IntelGTNotesFixture, WhenGettingIntelGTNotesGivenValidIntelGTNotesSection
|
||||||
EXPECT_EQ(DecodeError::Success, decodeError);
|
EXPECT_EQ(DecodeError::Success, decodeError);
|
||||||
EXPECT_TRUE(outWarning.empty());
|
EXPECT_TRUE(outWarning.empty());
|
||||||
EXPECT_TRUE(outErrReason.empty());
|
EXPECT_TRUE(outErrReason.empty());
|
||||||
EXPECT_EQ(4U, intelGTNotesRead.size());
|
EXPECT_EQ(numNotes, intelGTNotesRead.size());
|
||||||
|
|
||||||
auto validNotes = true;
|
auto validNotes = true;
|
||||||
for (size_t i = 0; i < intelGTNotesRead.size(); ++i) {
|
for (size_t i = 0; i < intelGTNotesRead.size(); ++i) {
|
||||||
|
|
Loading…
Reference in New Issue