Files
gentoo/dev-libs/rocm-comgr/files/rocm-comgr-6.4.1-extend-isa-compatibility-check.patch
Sv. Lockal 8acc0557b2 dev-libs/rocm-comgr: add 6.4.1
Signed-off-by: Sv. Lockal <lockalsash@gmail.com>
Part-of: https://github.com/gentoo/gentoo/pull/42554
Signed-off-by: Sam James <sam@gentoo.org>
2025-06-14 23:36:57 +01:00

205 lines
6.3 KiB
Diff

Load kernels when compatible by ISA, e. g. if AMDGPU_TARGETS is set
to gfx1030 and some application was started on gfx1036, it loads gfx1030 kernel.
Based on Debian patch by Cordell Bloor <cgmb@slerp.xyz>
https://salsa.debian.org/rocm-team/rocm-hipamd/-/blob/master/debian/patches/0026-extend-hip-isa-compatibility-check.patch
--- a/src/comgr-metadata.cpp
+++ b/src/comgr-metadata.cpp
@@ -927,23 +927,86 @@ constexpr size_t OffloadBundleMagicLen =
strLiteralLength(ClangOffloadBundlerMagic);
} // namespace
-bool isCompatibleIsaName(StringRef IsaName, StringRef CodeObjectIsaName) {
+struct GfxPattern {
+ std::string root;
+ std::string suffixes;
+};
+
+static bool matches(const GfxPattern& p, StringRef s) {
+ if (p.root.size() + 1 != s.size()) {
+ return false;
+ }
+ if (0 != std::memcmp(p.root.data(), s.data(), p.root.size())) {
+ return false;
+ }
+ return p.suffixes.find(s[p.root.size()]) != std::string::npos;
+}
+
+static bool isGfx900EquivalentProcessor(StringRef processor) {
+ return matches(GfxPattern{"gfx90", "029c"}, processor);
+}
+
+static bool isGfx900SupersetProcessor(StringRef processor) {
+ return matches(GfxPattern{"gfx90", "0269c"}, processor);
+}
+
+static bool isGfx1030EquivalentProcessor(StringRef processor) {
+ return matches(GfxPattern{"gfx103", "0123456"}, processor);
+}
+
+static bool isGfx1010EquivalentProcessor(StringRef processor) {
+ return matches(GfxPattern{"gfx101", "0"}, processor);
+}
+
+static bool isGfx1010SupersetProcessor(StringRef processor) {
+ return matches(GfxPattern{"gfx101", "0123"}, processor);
+}
+
+enum CompatibilityScore {
+ CS_EXACT_MATCH = 1 << 4,
+ CS_PROCESSOR_MATCH = 1 << 3,
+ CS_PROCESSOR_COMPATIBLE = 1 << 2,
+ CS_XNACK_SPECIALIZED = 1 << 1,
+ CS_SRAM_ECC_SPECIALIZED = 1 << 0,
+ CS_INCOMPATIBLE = 0,
+};
+
+static int getProcessorCompatibilityScore(StringRef CodeObjectProcessor,
+ StringRef AgentProcessor) {
+ if (CodeObjectProcessor == AgentProcessor) {
+ return CS_PROCESSOR_MATCH;
+ }
+
+ bool compatible = false;
+ if (isGfx900SupersetProcessor(AgentProcessor)) {
+ compatible = isGfx900EquivalentProcessor(CodeObjectProcessor);
+ } else if (isGfx1010SupersetProcessor(AgentProcessor)) {
+ compatible = isGfx1010EquivalentProcessor(CodeObjectProcessor);
+ } else if (isGfx1030EquivalentProcessor(AgentProcessor)) {
+ compatible = isGfx1030EquivalentProcessor(CodeObjectProcessor);
+ }
+
+ return compatible ? CS_PROCESSOR_COMPATIBLE : CS_INCOMPATIBLE;
+}
+
+static int getCompatiblityScore(StringRef IsaName, StringRef CodeObjectIsaName) {
if (IsaName == CodeObjectIsaName) {
- return true;
+ return CS_EXACT_MATCH;
}
TargetIdentifier CodeObjectIdent;
if (parseTargetIdentifier(CodeObjectIsaName, CodeObjectIdent)) {
- return false;
+ return CS_INCOMPATIBLE;
}
TargetIdentifier IsaIdent;
if (parseTargetIdentifier(IsaName, IsaIdent)) {
- return false;
+ return CS_INCOMPATIBLE;
}
- if (CodeObjectIdent.Processor != IsaIdent.Processor) {
- return false;
+ int ProcessorScore = getProcessorCompatibilityScore(CodeObjectIdent.Processor, IsaIdent.Processor);
+ if (ProcessorScore == CS_INCOMPATIBLE) {
+ return CS_INCOMPATIBLE;
}
char CodeObjectXnack = ' ', CodeObjectSramecc = ' ';
@@ -967,18 +1030,23 @@ bool isCompatibleIsaName(StringRef IsaName, StringRef CodeObjectIsaName) {
}
}
+ int XnackBonus = 0;
if (CodeObjectXnack != ' ') {
if (CodeObjectXnack != IsaXnack) {
- return false;
+ return CS_INCOMPATIBLE;
}
+ XnackBonus = CS_XNACK_SPECIALIZED;
}
+ int SrameccBonus = 0;
if (CodeObjectSramecc != ' ') {
if (CodeObjectSramecc != IsaSramecc) {
- return false;
+ return CS_INCOMPATIBLE;
}
+ SrameccBonus = CS_SRAM_ECC_SPECIALIZED;
}
- return true;
+
+ return ProcessorScore + XnackBonus + SrameccBonus;
}
amd_comgr_status_t
@@ -996,14 +1064,21 @@ lookUpCodeObjectInSharedObject(DataObject *DataP,
return Status;
}
+ int MaxScore = 0;
+ unsigned MaxScoreItem;
for (unsigned J = 0; J < QueryListSize; J++) {
- if (isCompatibleIsaName(QueryList[J].isa, IsaName)) {
- QueryList[J].offset = 0;
- QueryList[J].size = DataP->Size;
- break;
+ int Score = getCompatiblityScore(QueryList[J].isa, IsaName);
+ if (Score > MaxScore) {
+ MaxScore = Score;
+ MaxScoreItem = J;
}
}
+ if (MaxScore) {
+ QueryList[MaxScoreItem].offset = 0;
+ QueryList[MaxScoreItem].size = DataP->Size;
+ }
+
return AMD_COMGR_STATUS_SUCCESS;
}
@@ -1015,7 +1090,6 @@ amd_comgr_status_t lookUpCodeObject(DataObject *DataP,
return lookUpCodeObjectInSharedObject(DataP, QueryList, QueryListSize);
}
- int Seen = 0;
BinaryStreamReader Reader(StringRef(DataP->Data, DataP->Size),
llvm::endianness::little);
@@ -1041,6 +1115,8 @@ amd_comgr_status_t lookUpCodeObject(DataObject *DataP,
QueryList[I].size = 0;
}
+ std::vector<int> QueryListScores(QueryListSize);
+
// For each code object, extract BundleEntryID information, and check that
// against each ISA in the QueryList
for (uint64_t I = 0; I < NumOfCodeObjects; I++) {
@@ -1073,28 +1149,22 @@ amd_comgr_status_t lookUpCodeObject(DataObject *DataP,
}
for (unsigned J = 0; J < QueryListSize; J++) {
- // If this QueryList item has already been found to be compatible with
+ // If this QueryList item has exact match with
// another BundleEntryID, no need to check against the current
// BundleEntryID
- if (QueryList[J].size != 0) {
+ if (QueryListScores[J] == CS_EXACT_MATCH) {
continue;
}
// If the QueryList Isa is compatible with the BundleEntryID, set the
// QueryList offset/size to this BundleEntryID
- if (isCompatibleIsaName(QueryList[J].isa, OffloadAndTargetId.second)) {
+ int Score = getCompatiblityScore(QueryList[J].isa, OffloadAndTargetId.second);
+ if (Score > QueryListScores[J]) {
+ QueryListScores[J] = Score;
QueryList[J].offset = BundleEntryCodeObjectOffset;
QueryList[J].size = BundleEntryCodeObjectSize;
- Seen++;
- break;
}
}
-
- // Stop iterating over BundleEntryIDs once we have populated the entire
- // QueryList
- if (Seen == (int)QueryListSize) {
- break;
- }
}
return AMD_COMGR_STATUS_SUCCESS;