fix(oci): offer what the AMD GPU can run without warning about ROCm support

This commit is contained in:
MacRimi
2026-11-04 17:25:08 +01:00
parent 64e9e0e8dd
commit e916c3b8bb
3 changed files with 16 additions and 15 deletions
+3 -9
View File
@@ -962,15 +962,14 @@ def _ask_immich_acceleration(ui, rootfs_storage: str | None = None) -> tuple[str
return software return software
# Recognition on an AMD GPU depends on ROCm: it is offered when the host # Recognition on an AMD GPU depends on ROCm: it is offered when the host
# can run it, marked as experimental on a GPU ROCm does not support # can run it, marked as experimental on a GPU ROCm does not support
# officially, and left out, with the reason, when it cannot. # officially, and left out when it cannot. A GPU of a generation ROCm does
# not run is simply not offered; what the host can fix is explained.
amd_blocker = host.rocm_blocker(rootfs_storage) if found["amd"] else None amd_blocker = host.rocm_blocker(rootfs_storage) if found["amd"] else None
amd_experimental = (found["amd"] and not amd_blocker amd_experimental = (found["amd"] and not amd_blocker
and host.rocm_support(found.get("amd_gfx_target")) == "experimental") and host.rocm_support(found.get("amd_gfx_target")) == "experimental")
if amd_blocker: if amd_blocker in ("kfd", "space"):
reason = (translate("The AMD driver does not offer its compute interface (/dev/kfd) on this host.") reason = (translate("The AMD driver does not offer its compute interface (/dev/kfd) on this host.")
if amd_blocker == "kfd" else if amd_blocker == "kfd" else
f"{translate('The ROCm image has no support for the AMD GPU of this host:')} {host.amd_gpu_name()}."
if amd_blocker == "generation" else
translate("The storage has less than 40 GB free for the ROCm image.")) translate("The storage has less than 40 GB free for the ROCm image."))
real.message(f"{reason}\n\n{translate('Recognition is not offered on the AMD GPU; video transcoding is.')}") real.message(f"{reason}\n\n{translate('Recognition is not offered on the AMD GPU; video transcoding is.')}")
mark = f" — {translate('experimental on this GPU')}" if amd_experimental else "" mark = f" — {translate('experimental on this GPU')}" if amd_experimental else ""
@@ -1916,11 +1915,6 @@ def configure_acceleration(installer_profile, environment, unprivileged, ui, mod
found.get("amd_gfx_target"), tuple(item["amd_gfx_targets"])) == "experimental"} found.get("amd_gfx_target"), tuple(item["amd_gfx_targets"])) == "experimental"}
options = [(item["id"], item["label"]) for item in usable] options = [(item["id"], item["label"]) for item in usable]
asked = advanced or not installer_profile.get("selkies") asked = advanced or not installer_profile.get("selkies")
if asked and found["amd"] and any(item.get("amd_gfx_targets") and item not in usable and host.rocm_support(
found.get("amd_gfx_target"), tuple(item["amd_gfx_targets"])) is None for item in profiles):
# Its owner may expect the GPU to be offered: say why it is not.
ui.message(f"{translate('The ROCm image of this application has no support for the AMD GPU of this host:')} "
f"{host.amd_gpu_name()}. {translate('Its ROCm profile is not offered.')}")
if asked and len(usable) < len(profiles) and len(usable) == 1: if asked and len(usable) < len(profiles) and len(usable) == 1:
# Nothing but the CPU is left: say why there is nothing to choose. # Nothing but the CPU is left: say why there is nothing to choose.
ui.message(translate("No usable GPU was found on this host. The application will be installed " ui.message(translate("No usable GPU was found on this host. The application will be installed "
+4 -2
View File
@@ -191,8 +191,10 @@ class FrigateExperimentalRocmTests(unittest.TestCase):
self.assertEqual(plan["hardware_profile"], "vaapi") self.assertEqual(plan["hardware_profile"], "vaapi")
self.assertEqual(self.override(plan), []) self.assertEqual(self.override(plan), [])
def test_a_gpu_the_image_cannot_use_is_not_offered_and_the_reason_is_said(self, *_): def test_a_gpu_the_image_cannot_use_is_simply_not_offered(self, *_):
# The menu offers what works on the GPU; it does not explain ROCm.
with patch("proxmenux_oci.installer.host.amd_gpu_name", return_value="Lucienne (gfx90c)"): with patch("proxmenux_oci.installer.host.amd_gpu_name", return_value="Lucienne (gfx90c)"):
ui, plan = self.build(90012, {}) ui, plan = self.build(90012, {})
self.assertNotIn("rocm", ui.labels[PROMPT]) self.assertNotIn("rocm", ui.labels[PROMPT])
self.assertTrue(any("Lucienne (gfx90c)" in message and "not offered" in message for message in ui.messages)) self.assertIn("vaapi", ui.labels[PROMPT])
self.assertFalse(any("ROCm" in message for message in ui.messages))
+7 -2
View File
@@ -92,16 +92,21 @@ class ImmichAccelerationTests(unittest.TestCase):
self.assertIn("No usable GPU", ui.messages[0]) self.assertIn("No usable GPU", ui.messages[0])
self.assertEqual(result, ("cpu", "cpu"), mode) self.assertEqual(result, ("cpu", "cpu"), mode)
def test_an_amd_host_that_cannot_run_rocm_offers_video_only_and_says_why(self, *_): def test_an_amd_host_that_cannot_run_rocm_offers_video_only(self, *_):
for blocker, text in (("kfd", "/dev/kfd"), ("space", "40 GB"), ("generation", "no support for the AMD GPU")): # What the host can fix is said; a GPU generation ROCm does not run is not.
for blocker, text in (("kfd", "/dev/kfd"), ("space", "40 GB"), ("generation", None)):
with patch("proxmenux_oci.installer.host.rocm_blocker", return_value=blocker), \ with patch("proxmenux_oci.installer.host.rocm_blocker", return_value=blocker), \
patch("proxmenux_oci.installer.host.amd_gpu_name", return_value="Lucienne (gfx90c)"): patch("proxmenux_oci.installer.host.amd_gpu_name", return_value="Lucienne (gfx90c)"):
ui, result, _ = self.plan(AMD, DEFAULT_MODE) ui, result, _ = self.plan(AMD, DEFAULT_MODE)
self.assertEqual(ui.options[PROMPT], ["cpu", "amd-video"], blocker) self.assertEqual(ui.options[PROMPT], ["cpu", "amd-video"], blocker)
self.assertEqual(ui.defaults[PROMPT], "amd-video", blocker) self.assertEqual(ui.defaults[PROMPT], "amd-video", blocker)
self.assertEqual(result, ("vaapi", "cpu"), blocker) self.assertEqual(result, ("vaapi", "cpu"), blocker)
if text:
self.assertTrue(any(text in message and "Recognition is not offered" in message self.assertTrue(any(text in message and "Recognition is not offered" in message
for message in ui.messages), blocker) for message in ui.messages), blocker)
else:
self.assertFalse(any("ROCm" in message or "Recognition" in message
for message in ui.messages), blocker)
def test_a_gpu_rocm_supports_is_proposed_whole(self, *_): def test_a_gpu_rocm_supports_is_proposed_whole(self, *_):
for target in (100300, 110501, None): for target in (100300, 110501, None):