performance: Implement InvertedCompatibilityMap to optimize compatibility lookup

Added getInvertedCompatibilityMapping() utility in AOT namespace
to enable efficient reverse lookup of product compatibility. This change
reduces redundant searches and improves performance for compatibility
fallback queries.

Related-To: NEO-14300,GSD-10568
Signed-off-by: Aleksandra Nizio <aleksandra.nizio@intel.com>
This commit is contained in:
Aleksandra Nizio
2025-12-01 09:44:50 +00:00
committed by Compute-Runtime-Automation
parent 7661a8ee5f
commit 748e947c10
8 changed files with 66 additions and 31 deletions

View File

@@ -34,6 +34,7 @@ set(CLOC_LIB_SRCS_LIB
${NEO_SHARED_DIRECTORY}/compiler_interface/oclc_extensions_extra.h ${NEO_SHARED_DIRECTORY}/compiler_interface/oclc_extensions_extra.h
${NEO_SHARED_DIRECTORY}/compiler_interface/igc_platform_helper.h ${NEO_SHARED_DIRECTORY}/compiler_interface/igc_platform_helper.h
${NEO_SHARED_DIRECTORY}/compiler_interface/igc_platform_helper.cpp ${NEO_SHARED_DIRECTORY}/compiler_interface/igc_platform_helper.cpp
${NEO_SHARED_DIRECTORY}/device_binary_format/aot_platforms/neo_aot_platforms.cpp
${NEO_SHARED_DIRECTORY}/device_binary_format/ar/ar.h ${NEO_SHARED_DIRECTORY}/device_binary_format/ar/ar.h
${NEO_SHARED_DIRECTORY}/device_binary_format/ar/ar_decoder.cpp ${NEO_SHARED_DIRECTORY}/device_binary_format/ar/ar_decoder.cpp
${NEO_SHARED_DIRECTORY}/device_binary_format/ar/ar_decoder.h ${NEO_SHARED_DIRECTORY}/device_binary_format/ar/ar_decoder.h

View File

@@ -1,11 +1,12 @@
# #
# Copyright (C) 2020-2024 Intel Corporation # Copyright (C) 2020-2025 Intel Corporation
# #
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
# #
set(NEO_DEVICE_BINARY_FORMAT set(NEO_DEVICE_BINARY_FORMAT
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/aot_platforms/neo_aot_platforms.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ar/ar.h ${CMAKE_CURRENT_SOURCE_DIR}/ar/ar.h
${CMAKE_CURRENT_SOURCE_DIR}/ar/ar_decoder.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ar/ar_decoder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ar/ar_decoder.h ${CMAKE_CURRENT_SOURCE_DIR}/ar/ar_decoder.h

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "neo_aot_platforms.h"
namespace AOT {
const std::map<PRODUCT_CONFIG, std::vector<PRODUCT_CONFIG>> &getInvertedCompatibilityMapping() {
static const std::map<PRODUCT_CONFIG, std::vector<PRODUCT_CONFIG>> invertedMapping = []() {
std::map<PRODUCT_CONFIG, std::vector<PRODUCT_CONFIG>> inverted;
for (const auto &[targetConfig, compatibleConfigs] : compatibilityMapping) {
for (const auto &compatConfig : compatibleConfigs) {
inverted[compatConfig].push_back(targetConfig);
}
}
return inverted;
}();
return invertedMapping;
}
} // namespace AOT

View File

@@ -22,4 +22,5 @@ inline const auto &getRtlIdAcronyms() {
return rtlIdAcronyms; return rtlIdAcronyms;
} }
const std::map<PRODUCT_CONFIG, std::vector<PRODUCT_CONFIG>> &getInvertedCompatibilityMapping();
} // namespace AOT } // namespace AOT

View File

@@ -45,15 +45,13 @@ bool isZebin(ArrayRef<const uint8_t> binary) {
bool isTargetProductConfigCompatibleWithProductConfig(const AOT::PRODUCT_CONFIG &targetDeviceProductConfig, bool isTargetProductConfigCompatibleWithProductConfig(const AOT::PRODUCT_CONFIG &targetDeviceProductConfig,
const AOT::PRODUCT_CONFIG &productConfig) { const AOT::PRODUCT_CONFIG &productConfig) {
auto compatProdConfPairItr = AOT::getCompatibilityMapping().find(productConfig); const auto &invertedMapping = AOT::getInvertedCompatibilityMapping();
if (compatProdConfPairItr != AOT::getCompatibilityMapping().end()) { auto invertedProdConfPairItr = invertedMapping.find(targetDeviceProductConfig);
for (auto &compatibleConfig : compatProdConfPairItr->second) { if (invertedProdConfPairItr == invertedMapping.end()) {
if (targetDeviceProductConfig == compatibleConfig) { return false;
return true;
}
}
} }
return false; const auto &compatibleProducts = invertedProdConfPairItr->second;
return std::find(compatibleProducts.begin(), compatibleProducts.end(), productConfig) != compatibleProducts.end();
} }
bool validateTargetDevice(const TargetDevice &targetDevice, Elf::ElfIdentifierClass numBits, PRODUCT_FAMILY productFamily, GFXCORE_FAMILY gfxCore, AOT::PRODUCT_CONFIG productConfig, Elf::ZebinTargetFlags targetMetadata) { bool validateTargetDevice(const TargetDevice &targetDevice, Elf::ElfIdentifierClass numBits, PRODUCT_FAMILY productFamily, GFXCORE_FAMILY gfxCore, AOT::PRODUCT_CONFIG productConfig, Elf::ZebinTargetFlags targetMetadata) {

View File

@@ -380,25 +380,25 @@ std::vector<std::string> ProductConfigHelper::getCompatibilityFallbackProductAbb
return result; return result;
} }
for (const auto &compatibilityEntry : AOT::compatibilityMapping) { const auto &invertedMapping = AOT::getInvertedCompatibilityMapping();
bool contains = std::find(compatibilityEntry.second.begin(),
compatibilityEntry.second.end(), auto it = invertedMapping.find(requestedConfig);
requestedConfig) != compatibilityEntry.second.end(); if (it != invertedMapping.end()) {
if (!contains) { for (const auto &compatConfig : it->second) {
continue; for (const auto &acronymEntry : AOT::deviceAcronyms) {
} if (acronymEntry.second == compatConfig) {
for (const auto &acronymEntry : AOT::deviceAcronyms) { std::string name = acronymEntry.first;
if (acronymEntry.second == compatibilityEntry.first) { if (auto pos = name.find('-'); pos != std::string::npos) {
std::string name = acronymEntry.first; name = name.substr(0, pos);
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;
} }
if (std::find(result.begin(), result.end(), name) == result.end()) {
result.push_back(name);
}
break;
} }
} }
} }
return result; return result;
} }

View File

@@ -30,6 +30,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "hw_cmds_default.h" #include "hw_cmds_default.h"
#include "neo_aot_platforms.h"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
@@ -144,6 +145,10 @@ void applyCommonWorkarounds() {
NEO::fileLoggerInstance(); NEO::fileLoggerInstance();
NEO::usmReusePerfLoggerInstance(); NEO::usmReusePerfLoggerInstance();
} }
// Force initialization of inverted compatibility mapping here so its allocations happen before memory-leak listener is enabled.
// This prevents false-positive leak reports.
AOT::getInvertedCompatibilityMapping();
} }
bool enableAlarm = ENABLE_ALARM_DEFAULT; bool enableAlarm = ENABLE_ALARM_DEFAULT;

View File

@@ -620,11 +620,13 @@ TEST(UnpackSingleDeviceBinaryAr, WhenRequestedDeviceHasCompatibleFallbackThenUse
std::string requestedProduct = "lnl"; std::string requestedProduct = "lnl";
std::string fallbackProduct = "bmg"; std::string fallbackProduct = "bmg";
auto compatibleDevices = ProductConfigHelper::getCompatibilityFallbackProductAbbreviations(requestedProduct); {
auto compatibleDevices = ProductConfigHelper::getCompatibilityFallbackProductAbbreviations(requestedProduct);
if (compatibleDevices.empty() || if (compatibleDevices.empty() ||
std::find(compatibleDevices.begin(), compatibleDevices.end(), fallbackProduct) == compatibleDevices.end()) { std::find(compatibleDevices.begin(), compatibleDevices.end(), fallbackProduct) == compatibleDevices.end()) {
GTEST_SKIP(); GTEST_SKIP();
}
} }
NEO::Ar::ArEncoder encoder{true}; NEO::Ar::ArEncoder encoder{true};
@@ -632,7 +634,7 @@ TEST(UnpackSingleDeviceBinaryAr, WhenRequestedDeviceHasCompatibleFallbackThenUse
ASSERT_TRUE(encoder.appendFileEntry(pointerSize + "." + fallbackProduct, programTokens.storage)); ASSERT_TRUE(encoder.appendFileEntry(pointerSize + "." + fallbackProduct, programTokens.storage));
NEO::TargetDevice target; NEO::TargetDevice target{};
target.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device); target.coreFamily = static_cast<GFXCORE_FAMILY>(programTokens.header->Device);
target.stepping = programTokens.header->SteppingId; target.stepping = programTokens.header->SteppingId;
target.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes; target.maxPointerSizeInBytes = programTokens.header->GPUPointerSizeInBytes;
@@ -646,7 +648,6 @@ TEST(UnpackSingleDeviceBinaryAr, WhenRequestedDeviceHasCompatibleFallbackThenUse
EXPECT_TRUE(unpackErrors.empty()); EXPECT_TRUE(unpackErrors.empty());
EXPECT_FALSE(unpacked.deviceBinary.empty()); EXPECT_FALSE(unpacked.deviceBinary.empty());
EXPECT_EQ(NEO::DeviceBinaryFormat::patchtokens, unpacked.format); EXPECT_EQ(NEO::DeviceBinaryFormat::patchtokens, unpacked.format);
EXPECT_STREQ("Couldn't find perfectly matched binary in AR, using best usable", unpackWarnings.c_str()); EXPECT_STREQ("Couldn't find perfectly matched binary in AR, using best usable", unpackWarnings.c_str());
} }