Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/cpp/server/system_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,12 +652,24 @@ static std::string read_version_file(const fs::path& version_file);
static std::string get_expected_backend_version(const std::string& recipe, const std::string& backend);

// Check if device matches constraints (empty constraint set = all families allowed)
// A trailing 'X' in an allowed family acts as a wildcard (e.g. "gfx110X" matches "gfx1103").
static bool device_matches_constraint(const std::string& device_family,
const std::set<std::string>& allowed_families) {
if (allowed_families.empty()) {
return true; // Empty = all families allowed
}
return allowed_families.count(device_family) > 0;
if (allowed_families.count(device_family) > 0) {
return true;
}
for (const auto& af : allowed_families) {
if (af.size() > 1 && af.back() == 'X') {
std::string prefix = af.substr(0, af.size() - 1);
if (device_family.compare(0, prefix.size(), prefix) == 0) {
return true;
}
}
}
return false;
}

// Generic installation check
Expand Down
62 changes: 62 additions & 0 deletions test/test_device_family_matching.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env python3
"""
CPU-runnable unit tests for device family matching logic (device_matches_constraint).

These tests replicate the C++ logic for matching a device family against a set of
allowed families, including support for wildcard 'X' at the end of a family name.
"""

import unittest

# ---------------------------------------------------------------------------
# Python replica of system_info.cpp::device_matches_constraint()
# ---------------------------------------------------------------------------

def device_matches_constraint(device_family: str, allowed_families: set) -> bool:
if not allowed_families:
return True # Empty = all families allowed

if device_family in allowed_families:
return True

for af in allowed_families:
if len(af) > 1 and af.endswith('X'):
prefix = af[:-1]
if device_family.startswith(prefix):
return True

return False

# ---------------------------------------------------------------------------
# Tests
# ---------------------------------------------------------------------------

class TestDeviceFamilyMatching(unittest.TestCase):
def test_wildcard_matching(self):
# gfx1103 should match gfx110X
self.assertTrue(device_matches_constraint("gfx1103", {"gfx110X"}))
# gfx1201 should match gfx120X
self.assertTrue(device_matches_constraint("gfx1201", {"gfx120X"}))

def test_exact_matching(self):
# gfx1151 should match gfx1151
self.assertTrue(device_matches_constraint("gfx1151", {"gfx1151"}))
# gfx1152 should match gfx1152
self.assertTrue(device_matches_constraint("gfx1152", {"gfx1152"}))

def test_non_matching(self):
# gfx1151 should NOT match gfx110X
self.assertFalse(device_matches_constraint("gfx1151", {"gfx110X"}))

def test_empty_allowed_families(self):
# Empty allowed_families should match everything
self.assertTrue(device_matches_constraint("gfx1151", set()))

def test_multiple_allowed_families(self):
# Should match if any in the set match
self.assertTrue(device_matches_constraint("gfx1103", {"gfx103X", "gfx110X"}))
self.assertTrue(device_matches_constraint("gfx1201", {"gfx110X", "gfx120X"}))
self.assertFalse(device_matches_constraint("gfx1151", {"gfx103X", "gfx110X"}))

if __name__ == "__main__":
unittest.main()
Loading