mirror of
https://github.com/gentoo-mirror/gentoo.git
synced 2026-08-24 18:58:08 -07:00
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>
205 lines
6.3 KiB
Diff
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;
|