mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-21 09:14:47 +08:00
fix: select target device compatible binary from fatbinary
removes recompilation from IR step when fatbinary contains compatible devices binaries Resolves: NEO-14300,GSD-10568 Signed-off-by: Aleksandra Nizio <aleksandra.nizio@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
7a97b98cfe
commit
4a9b918a85
@@ -10,6 +10,9 @@
|
||||
#include "shared/source/helpers/product_config_helper.h"
|
||||
#include "shared/source/helpers/string.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
|
||||
namespace NEO {
|
||||
void searchForBinary(Ar::Ar &archiveData, const ConstStringRef filter, Ar::ArFileEntryHeaderAndData *&matched) {
|
||||
for (auto &file : archiveData.files) {
|
||||
@@ -19,70 +22,112 @@ void searchForBinary(Ar::Ar &archiveData, const ConstStringRef filter, Ar::ArFil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
bool isDeviceBinaryFormat<NEO::DeviceBinaryFormat::archive>(const ArrayRef<const uint8_t> binary) {
|
||||
return NEO::Ar::isAr(binary);
|
||||
}
|
||||
|
||||
template <>
|
||||
SingleDeviceBinary unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::archive>(const ArrayRef<const uint8_t> archive, const ConstStringRef requestedProductAbbreviation, const TargetDevice &requestedTargetDevice,
|
||||
std::string &outErrReason, std::string &outWarning) {
|
||||
SingleDeviceBinary unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::archive>(const ArrayRef<const uint8_t> archive,
|
||||
const ConstStringRef requestedProductAbbreviation,
|
||||
const TargetDevice &requestedTargetDevice,
|
||||
std::string &outErrReason,
|
||||
std::string &outWarning) {
|
||||
auto archiveData = NEO::Ar::decodeAr(archive, outErrReason, outWarning);
|
||||
if (nullptr == archiveData.magic) {
|
||||
return {};
|
||||
}
|
||||
|
||||
ConstStringRef filterGenericIrFileName{"generic_ir"};
|
||||
Ar::ArFileEntryHeaderAndData *matchedGenericIr = nullptr;
|
||||
searchForBinary(archiveData, filterGenericIrFileName, matchedGenericIr);
|
||||
|
||||
SingleDeviceBinary binaryForRecompilation{};
|
||||
|
||||
auto tryPlatform = [&](ConstStringRef platformAbbreviation) -> std::optional<SingleDeviceBinary> {
|
||||
std::string pointerSize = ((requestedTargetDevice.maxPointerSizeInBytes == 8) ? "64" : "32");
|
||||
std::string filterPointerSizeAndMajorMinorRevision = pointerSize + "." + ProductConfigHelper::parseMajorMinorRevisionValue(requestedTargetDevice.aotConfig);
|
||||
std::string filterPointerSizeAndMajorMinor = pointerSize + "." + ProductConfigHelper::parseMajorMinorValue(requestedTargetDevice.aotConfig);
|
||||
std::string filterPointerSizeAndPlatform = pointerSize + "." + requestedProductAbbreviation.str();
|
||||
std::string filterPointerSizeAndPlatform = pointerSize + "." + platformAbbreviation.str();
|
||||
std::string filterPointerSizeAndPlatformAndStepping = filterPointerSizeAndPlatform + "." + std::to_string(requestedTargetDevice.stepping);
|
||||
ConstStringRef filterGenericIrFileName{"generic_ir"};
|
||||
|
||||
Ar::ArFileEntryHeaderAndData *matchedFiles[5] = {};
|
||||
Ar::ArFileEntryHeaderAndData *matchedFiles[4] = {};
|
||||
Ar::ArFileEntryHeaderAndData *&matchedPointerSizeAndMajorMinorRevision = matchedFiles[0];
|
||||
Ar::ArFileEntryHeaderAndData *&matchedPointerSizeAndPlatformAndStepping = matchedFiles[1];
|
||||
Ar::ArFileEntryHeaderAndData *&matchedPointerSizeAndMajorMinor = matchedFiles[2];
|
||||
Ar::ArFileEntryHeaderAndData *&matchedPointerSizeAndPlatform = matchedFiles[3];
|
||||
Ar::ArFileEntryHeaderAndData *&matchedGenericIr = matchedFiles[4];
|
||||
|
||||
searchForBinary(archiveData, ConstStringRef(filterPointerSizeAndMajorMinorRevision), matchedPointerSizeAndMajorMinorRevision);
|
||||
searchForBinary(archiveData, ConstStringRef(filterPointerSizeAndPlatformAndStepping), matchedPointerSizeAndPlatformAndStepping);
|
||||
searchForBinary(archiveData, ConstStringRef(filterPointerSizeAndMajorMinor), matchedPointerSizeAndMajorMinor);
|
||||
searchForBinary(archiveData, ConstStringRef(filterPointerSizeAndPlatform), matchedPointerSizeAndPlatform);
|
||||
searchForBinary(archiveData, filterGenericIrFileName, matchedGenericIr);
|
||||
|
||||
std::string unpackErrors;
|
||||
std::string unpackWarnings;
|
||||
SingleDeviceBinary binaryForRecompilation = {};
|
||||
|
||||
for (auto matchedFile : matchedFiles) {
|
||||
if (nullptr == matchedFile) {
|
||||
continue;
|
||||
}
|
||||
auto unpacked = unpackSingleDeviceBinary(matchedFile->fileData, requestedProductAbbreviation, requestedTargetDevice, unpackErrors, unpackWarnings);
|
||||
if (false == unpacked.deviceBinary.empty()) {
|
||||
if ((matchedFile != matchedPointerSizeAndPlatformAndStepping) && (matchedFile != matchedPointerSizeAndMajorMinorRevision)) {
|
||||
auto unpacked = unpackSingleDeviceBinary(matchedFile->fileData, platformAbbreviation,
|
||||
requestedTargetDevice, unpackErrors, unpackWarnings);
|
||||
|
||||
if (!unpacked.deviceBinary.empty()) {
|
||||
if ((matchedFile != matchedPointerSizeAndPlatformAndStepping) &&
|
||||
(matchedFile != matchedPointerSizeAndMajorMinorRevision)) {
|
||||
outWarning = "Couldn't find perfectly matched binary in AR, using best usable";
|
||||
}
|
||||
if (unpacked.intermediateRepresentation.empty() && matchedGenericIr) {
|
||||
auto unpackedGenericIr = unpackSingleDeviceBinary(matchedGenericIr->fileData, requestedProductAbbreviation, requestedTargetDevice, unpackErrors, unpackWarnings);
|
||||
if (!unpackedGenericIr.intermediateRepresentation.empty()) {
|
||||
unpacked.intermediateRepresentation = unpackedGenericIr.intermediateRepresentation;
|
||||
std::string irErrors, irWarnings;
|
||||
auto genericIrResult = unpackSingleDeviceBinary(matchedGenericIr->fileData, platformAbbreviation,
|
||||
requestedTargetDevice, irErrors, irWarnings);
|
||||
if (!genericIrResult.intermediateRepresentation.empty()) {
|
||||
unpacked.intermediateRepresentation = genericIrResult.intermediateRepresentation;
|
||||
}
|
||||
}
|
||||
unpacked.packedTargetDeviceBinary = ArrayRef<const uint8_t>(matchedFile->fileData.begin(), matchedFile->fileData.size());
|
||||
unpacked.packedTargetDeviceBinary =
|
||||
ArrayRef<const uint8_t>(matchedFile->fileData.begin(), matchedFile->fileData.size());
|
||||
return unpacked;
|
||||
}
|
||||
if (binaryForRecompilation.intermediateRepresentation.empty() && (false == unpacked.intermediateRepresentation.empty())) {
|
||||
|
||||
if (binaryForRecompilation.intermediateRepresentation.empty() &&
|
||||
!unpacked.intermediateRepresentation.empty()) {
|
||||
binaryForRecompilation = unpacked;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
if (false == binaryForRecompilation.intermediateRepresentation.empty()) {
|
||||
if (auto primary = tryPlatform(requestedProductAbbreviation); primary.has_value()) {
|
||||
return *primary;
|
||||
}
|
||||
|
||||
auto compatibilityFallbackAbbreviations =
|
||||
ProductConfigHelper::getCompatibilityFallbackProductAbbreviations(requestedProductAbbreviation.str());
|
||||
|
||||
for (const auto &compatAbbrev : compatibilityFallbackAbbreviations) {
|
||||
if (compatAbbrev == requestedProductAbbreviation.str()) {
|
||||
continue;
|
||||
}
|
||||
ConstStringRef compatRef{compatAbbrev};
|
||||
if (auto compatResult = tryPlatform(compatRef); compatResult.has_value()) {
|
||||
return *compatResult;
|
||||
}
|
||||
}
|
||||
|
||||
if (!binaryForRecompilation.intermediateRepresentation.empty()) {
|
||||
return binaryForRecompilation;
|
||||
}
|
||||
|
||||
if (matchedGenericIr) {
|
||||
std::string irErrors, irWarnings;
|
||||
auto genericIrResult = unpackSingleDeviceBinary(matchedGenericIr->fileData, requestedProductAbbreviation,
|
||||
requestedTargetDevice, irErrors, irWarnings);
|
||||
if (!genericIrResult.intermediateRepresentation.empty()) {
|
||||
return genericIrResult;
|
||||
}
|
||||
}
|
||||
|
||||
outErrReason = "Couldn't find matching binary in AR archive";
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -344,3 +344,41 @@ AOT::PRODUCT_CONFIG ProductConfigHelper::getProductConfigFromAcronym(const std::
|
||||
}
|
||||
return AOT::UNKNOWN_ISA;
|
||||
}
|
||||
|
||||
std::vector<std::string> ProductConfigHelper::getCompatibilityFallbackProductAbbreviations(const std::string &requestedProductAbbreviation) {
|
||||
std::vector<std::string> result;
|
||||
|
||||
AOT::PRODUCT_CONFIG requestedConfig = AOT::PRODUCT_CONFIG::UNKNOWN_ISA;
|
||||
for (const auto &acronymEntry : AOT::deviceAcronyms) {
|
||||
if (acronymEntry.first == requestedProductAbbreviation ||
|
||||
acronymEntry.first.rfind(requestedProductAbbreviation + "-", 0) == 0) {
|
||||
requestedConfig = acronymEntry.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (requestedConfig == AOT::PRODUCT_CONFIG::UNKNOWN_ISA) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (const auto &compatibilityEntry : AOT::compatibilityMapping) {
|
||||
bool contains = std::find(compatibilityEntry.second.begin(),
|
||||
compatibilityEntry.second.end(),
|
||||
requestedConfig) != compatibilityEntry.second.end();
|
||||
if (!contains) {
|
||||
continue;
|
||||
}
|
||||
for (const auto &acronymEntry : AOT::deviceAcronyms) {
|
||||
if (acronymEntry.second == compatibilityEntry.first) {
|
||||
std::string name = acronymEntry.first;
|
||||
if (auto pos = name.find('-'); pos != std::string::npos) {
|
||||
name = name.substr(0, pos);
|
||||
}
|
||||
if (std::find(result.begin(), result.end(), name) == result.end()) {
|
||||
result.push_back(name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ struct ProductConfigHelper {
|
||||
static NEO::ConstStringRef getAcronymFromARelease(AOT::RELEASE release);
|
||||
static uint32_t getProductConfigFromVersionValue(const std::string &device);
|
||||
static AOT::PRODUCT_CONFIG getProductConfigFromAcronym(const std::string &device);
|
||||
static std::vector<std::string> getCompatibilityFallbackProductAbbreviations(const std::string &requestedProductAbbreviation);
|
||||
|
||||
static bool compareConfigs(DeviceAotInfo deviceAotInfo0, DeviceAotInfo deviceAotInfo1);
|
||||
|
||||
|
||||
@@ -613,3 +613,47 @@ TEST(UnpackSingleDeviceBinaryAr, WhenCouldNotFindBinaryWithRightPointerSizeThenU
|
||||
EXPECT_TRUE(unpackWarnings.empty()) << unpackWarnings;
|
||||
EXPECT_STREQ("Couldn't find matching binary in AR archive", unpackErrors.c_str());
|
||||
}
|
||||
|
||||
TEST(UnpackSingleDeviceBinaryAr, WhenRequestedDeviceHasCompatibleFallbackThenUseFallbackDevice) {
|
||||
PatchTokensTestData::ValidEmptyProgram programTokens;
|
||||
|
||||
std::string requestedProduct = "lnl";
|
||||
std::string fallbackProduct = "bmg";
|
||||
|
||||
auto compatibleDevices = ProductConfigHelper::getCompatibilityFallbackProductAbbreviations(requestedProduct);
|
||||
|
||||
if (compatibleDevices.empty() ||
|
||||
std::find(compatibleDevices.begin(), compatibleDevices.end(), fallbackProduct) == compatibleDevices.end()) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
NEO::Ar::ArEncoder encoder{true};
|
||||
std::string pointerSize = (programTokens.header->GPUPointerSizeInBytes == 4) ? "32" : "64";
|
||||
|
||||
ASSERT_TRUE(encoder.appendFileEntry(pointerSize + "." + fallbackProduct, programTokens.storage));
|
||||
|
||||
NEO::TargetDevice target;
|
||||
target.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device);
|
||||
target.stepping = programTokens.header->SteppingId;
|
||||
target.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes;
|
||||
|
||||
auto arData = encoder.encode();
|
||||
std::string unpackErrors;
|
||||
std::string unpackWarnings;
|
||||
|
||||
auto unpacked = NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::archive>(arData, requestedProduct, target, unpackErrors, unpackWarnings);
|
||||
|
||||
EXPECT_TRUE(unpackErrors.empty());
|
||||
EXPECT_FALSE(unpacked.deviceBinary.empty());
|
||||
EXPECT_EQ(NEO::DeviceBinaryFormat::patchtokens, unpacked.format);
|
||||
|
||||
EXPECT_STREQ("Couldn't find perfectly matched binary in AR, using best usable", unpackWarnings.c_str());
|
||||
}
|
||||
|
||||
TEST(ProductConfigHelper, GivenUnknownDeviceWhenGettingCompatibilityFallbacksThenReturnEmpty) {
|
||||
const std::string requestedProduct = "nonexistent_device_acronym_xyz";
|
||||
|
||||
auto result = ProductConfigHelper::getCompatibilityFallbackProductAbbreviations(requestedProduct);
|
||||
|
||||
EXPECT_TRUE(result.empty());
|
||||
}
|
||||
Reference in New Issue
Block a user