feat(zebin): Use AOT config for validating target device

Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
This commit is contained in:
Kacper Nowak 2022-12-15 13:23:05 +00:00 committed by Compute-Runtime-Automation
parent 5ae75f0234
commit 7b8d1925a9
4 changed files with 140 additions and 8 deletions

View File

@ -70,7 +70,8 @@ enum IntelGTSectionType : uint32_t {
GfxCore = 2,
TargetMetadata = 3,
ZebinVersion = 4,
LastSupported = ZebinVersion
ProductConfig = 5,
LastSupported = ProductConfig
};
struct IntelGTNote {
IntelGTSectionType type;

View File

@ -21,6 +21,8 @@
#include "shared/source/program/kernel_info.h"
#include "shared/source/program/program_info.h"
#include "platforms.h"
namespace NEO {
void setKernelMiscInfoPosition(ConstStringRef metadata, NEO::ProgramInfo &dst) {
@ -39,12 +41,46 @@ bool isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(const ArrayRef<const u
: isValidZebinHeader(Elf::decodeElfFileHeader<Elf::EI_CLASS_64>(binary));
}
bool validateTargetDevice(const TargetDevice &targetDevice, Elf::ELF_IDENTIFIER_CLASS numBits, PRODUCT_FAMILY productFamily, GFXCORE_FAMILY gfxCore, AOT::PRODUCT_CONFIG productConfig, Elf::ZebinTargetFlags targetMetadata) {
if (targetDevice.maxPointerSizeInBytes == 4 && static_cast<uint32_t>(numBits == Elf::EI_CLASS_64)) {
return false;
}
if (gfxCore == IGFX_UNKNOWN_CORE && productFamily == IGFX_UNKNOWN && productConfig == AOT::UNKNOWN_ISA) {
return false;
}
if (productConfig != AOT::UNKNOWN_ISA) {
if (targetDevice.aotConfig.value != productConfig) {
return false;
}
} else {
if (gfxCore != IGFX_UNKNOWN_CORE) {
if (targetDevice.coreFamily != gfxCore) {
return false;
}
}
if (productFamily != IGFX_UNKNOWN) {
if (false == haveSameCore(targetDevice.productFamily, productFamily)) {
return false;
}
}
}
if (targetMetadata.validateRevisionId) {
bool isValidStepping = (targetDevice.stepping >= targetMetadata.minHwRevisionId) && (targetDevice.stepping <= targetMetadata.maxHwRevisionId);
if (false == isValidStepping) {
return false;
}
}
return true;
}
template bool validateTargetDevice<Elf::EI_CLASS_32>(const Elf::Elf<Elf::EI_CLASS_32> &elf, const TargetDevice &targetDevice, std::string &outErrReason, std::string &outWarning);
template bool validateTargetDevice<Elf::EI_CLASS_64>(const Elf::Elf<Elf::EI_CLASS_64> &elf, const TargetDevice &targetDevice, std::string &outErrReason, std::string &outWarning);
template <Elf::ELF_IDENTIFIER_CLASS numBits>
bool validateTargetDevice(const Elf::Elf<numBits> &elf, const TargetDevice &targetDevice, std::string &outErrReason, std::string &outWarning) {
GFXCORE_FAMILY gfxCore = IGFX_UNKNOWN_CORE;
PRODUCT_FAMILY productFamily = IGFX_UNKNOWN;
AOT::PRODUCT_CONFIG productConfig = AOT::UNKNOWN_ISA;
Elf::ZebinTargetFlags targetMetadata = {};
std::vector<Elf::IntelGTNote> intelGTNotes = {};
auto decodeError = getIntelGTNotes(elf, intelGTNotes, outErrReason, outWarning);
@ -85,17 +121,18 @@ bool validateTargetDevice(const Elf::Elf<numBits> &elf, const TargetDevice &targ
}
break;
}
case Elf::IntelGTSectionType::ProductConfig: {
DEBUG_BREAK_IF(sizeof(uint32_t) != intelGTNote.data.size());
auto productConfigData = reinterpret_cast<const uint32_t *>(intelGTNote.data.begin());
productConfig = static_cast<AOT::PRODUCT_CONFIG>(*productConfigData);
break;
}
default:
outWarning.append("DeviceBinaryFormat::Zebin : Unrecognized IntelGTNote type: " + std::to_string(intelGTNote.type) + "\n");
break;
}
}
bool validForTarget = (gfxCore != IGFX_UNKNOWN_CORE) | (productFamily != IGFX_UNKNOWN);
validForTarget &= (gfxCore != IGFX_UNKNOWN_CORE) ? targetDevice.coreFamily == gfxCore : true;
validForTarget &= (productFamily != IGFX_UNKNOWN) ? haveSameCore(targetDevice.productFamily, productFamily) : true;
validForTarget &= (0 == targetMetadata.validateRevisionId) | ((targetDevice.stepping >= targetMetadata.minHwRevisionId) & (targetDevice.stepping <= targetMetadata.maxHwRevisionId));
validForTarget &= (targetDevice.maxPointerSizeInBytes >= static_cast<uint32_t>(numBits == Elf::EI_CLASS_32 ? 4 : 8));
return validForTarget;
return validateTargetDevice(targetDevice, numBits, productFamily, gfxCore, productConfig, targetMetadata);
}
DecodeError validateZeInfoVersion(const Elf::ZebinKernelMetadata::Types::Version &receivedZeInfoVersion, std::string &outErrReason, std::string &outWarning) {

View File

@ -50,6 +50,8 @@ struct ZeInfoKernelSections {
DecodeError validateZeInfoVersion(const Elf::ZebinKernelMetadata::Types::Version &receivedZeInfoVersion, std::string &outErrReason, std::string &outWarning);
bool validateTargetDevice(const TargetDevice &targetDevice, Elf::ELF_IDENTIFIER_CLASS numBits, PRODUCT_FAMILY productFamily, GFXCORE_FAMILY gfxCore, AOT::PRODUCT_CONFIG productConfig, Elf::ZebinTargetFlags targetMetadata);
template <Elf::ELF_IDENTIFIER_CLASS numBits>
bool validateTargetDevice(const Elf::Elf<numBits> &elf, const TargetDevice &targetDevice, std::string &outErrReason, std::string &outWarning);

View File

@ -20,6 +20,8 @@
#include "shared/test/common/mocks/mock_modules_zebin.h"
#include "shared/test/common/test_macros/test.h"
#include "platforms.h"
#include <numeric>
#include <vector>
@ -6314,6 +6316,37 @@ TEST_F(IntelGTNotesFixture, WhenValidatingTargetDeviceGivenValidTargetDeviceAndV
EXPECT_TRUE(validateTargetDevice(elf, targetDevice, outErrReason, outWarning));
}
TEST_F(IntelGTNotesFixture, givenAotConfigInIntelGTNotesSectionWhenValidatingTargetDeviceThenUseOnlyItForValidation) {
NEO::HardwareIpVersion aotConfig = {0};
aotConfig.value = 0x00001234;
TargetDevice targetDevice;
targetDevice.maxPointerSizeInBytes = 8u;
ASSERT_EQ(IGFX_UNKNOWN, targetDevice.productFamily);
ASSERT_EQ(IGFX_UNKNOWN_CORE, targetDevice.coreFamily);
targetDevice.aotConfig.value = aotConfig.value;
Elf::ElfNoteSection elfNoteSection;
elfNoteSection.descSize = 4u;
elfNoteSection.nameSize = 8u;
elfNoteSection.type = Elf::IntelGTSectionType::ProductConfig;
uint8_t productConfigData[4];
memcpy_s(productConfigData, 4, &aotConfig.value, 4);
auto sectionDataSize = sizeof(Elf::ElfNoteSection) + elfNoteSection.nameSize + elfNoteSection.descSize;
auto noteIntelGTSectionData = std::make_unique<uint8_t[]>(sectionDataSize);
appendSingleIntelGTSectionData(elfNoteSection, noteIntelGTSectionData.get(), productConfigData, NEO::Elf::IntelGtNoteOwnerName.data(), sectionDataSize);
zebin.appendSection(Elf::SHT_NOTE, Elf::SectionsNamesZebin::noteIntelGT, ArrayRef<uint8_t>::fromAny(noteIntelGTSectionData.get(), sectionDataSize));
std::string outErrReason, outWarning;
auto elf = Elf::decodeElf<Elf::EI_CLASS_64>(zebin.storage, outErrReason, outWarning);
EXPECT_TRUE(outWarning.empty());
EXPECT_TRUE(outErrReason.empty());
EXPECT_TRUE(validateTargetDevice(elf, targetDevice, outErrReason, outWarning));
}
TEST(ValidateTargetDevice32BitZebin, Given32BitZebinAndValidIntelGTNotesWhenValidatingTargetDeviceThenReturnTrue) {
TargetDevice targetDevice;
targetDevice.productFamily = productFamily;
@ -6415,7 +6448,7 @@ TEST_F(IntelGTNotesFixture, WhenValidatingTargetDeviceGivenValidTargetDeviceAndI
targetDevice.stepping = hardwareInfoTable[productFamily]->platform.usRevId;
Elf::ElfNoteSection elfNoteSection = {};
elfNoteSection.type = 5;
elfNoteSection.type = Elf::IntelGTSectionType::LastSupported + 1;
elfNoteSection.descSize = 0u;
elfNoteSection.nameSize = 8u;
auto sectionDataSize = sizeof(Elf::ElfNoteSection) + elfNoteSection.nameSize + elfNoteSection.descSize;
@ -6557,6 +6590,65 @@ TEST_F(IntelGTNotesFixture, GivenIncompatibleVersioningWhenValidatingTargetDevic
EXPECT_STREQ("DeviceBinaryFormat::Zebin::.ze_info : Unhandled major version : 2, decoder is at : 1\n", outErrReason.c_str());
}
TEST(ValidateTargetDeviceTests, givenMismatechAotConfigWhenValidatingTargetDeviceThenUseOnlyItForValidationAndReturnFalse) {
TargetDevice targetDevice;
targetDevice.aotConfig.value = 0x00001234;
targetDevice.maxPointerSizeInBytes = 8u;
auto mismatchedAotConfig = static_cast<AOT::PRODUCT_CONFIG>(0x00004321);
Elf::ZebinTargetFlags targetMetadata;
auto res = validateTargetDevice(targetDevice, Elf::EI_CLASS_64, productFamily, renderCoreFamily, mismatchedAotConfig, targetMetadata);
EXPECT_FALSE(res);
}
TEST(ValidateTargetDeviceTests, givenMismatchedProductFamilyWhenValidatingTargetDeviceThenReturnFalse) {
TargetDevice targetDevice;
targetDevice.maxPointerSizeInBytes = 8u;
ASSERT_EQ(AOT::UNKNOWN_ISA, targetDevice.aotConfig.value);
targetDevice.coreFamily = IGFX_UNKNOWN_CORE;
targetDevice.productFamily = productFamily;
Elf::ZebinTargetFlags targetMetadata;
auto mismatchedPlatformFamily = IGFX_UNKNOWN;
for (int i = 0; i < IGFX_MAX_PRODUCT; i++) {
const auto hwInfo = NEO::hardwareInfoTable[i];
if (nullptr != hwInfo && hwInfo->platform.eRenderCoreFamily != renderCoreFamily) {
mismatchedPlatformFamily = hwInfo->platform.eProductFamily;
}
}
auto res = validateTargetDevice(targetDevice, Elf::EI_CLASS_64, mismatchedPlatformFamily, IGFX_UNKNOWN_CORE, AOT::UNKNOWN_ISA, targetMetadata);
EXPECT_FALSE(res);
}
TEST(ValidateTargetDeviceTests, givenMismatchedGfxCoreWhenValidatingTargetDeviceThenReturnFalse) {
TargetDevice targetDevice;
targetDevice.maxPointerSizeInBytes = 8u;
ASSERT_EQ(AOT::UNKNOWN_ISA, targetDevice.aotConfig.value);
targetDevice.coreFamily = renderCoreFamily;
Elf::ZebinTargetFlags targetMetadata;
auto mismatchedGfxCore = static_cast<GFXCORE_FAMILY>(renderCoreFamily + 1);
auto res = validateTargetDevice(targetDevice, Elf::EI_CLASS_64, IGFX_UNKNOWN, mismatchedGfxCore, AOT::UNKNOWN_ISA, targetMetadata);
EXPECT_FALSE(res);
}
TEST(ValidateTargetDeviceTests, givenSteppingBiggerThanMaxHwRevisionWhenValidatingTargetDeviceThenReturnFalse) {
TargetDevice targetDevice;
targetDevice.maxPointerSizeInBytes = 8u;
auto aotConfigValue = 0x00001234u;
targetDevice.aotConfig.value = aotConfigValue;
targetDevice.stepping = 2u;
Elf::ZebinTargetFlags targetMetadata;
targetMetadata.validateRevisionId = true;
targetMetadata.maxHwRevisionId = 1u;
auto res = validateTargetDevice(targetDevice, Elf::EI_CLASS_64, IGFX_UNKNOWN, IGFX_UNKNOWN_CORE, static_cast<AOT::PRODUCT_CONFIG>(aotConfigValue), targetMetadata);
EXPECT_FALSE(res);
}
TEST(PopulateGlobalDeviceHostNameMapping, givenValidZebinWithGlobalHostAccessTableSectionThenPopulateHostDeviceNameMapCorrectly) {
NEO::ConstStringRef zeinfo = R"===(
kernels: