Return True only if an actual AMD GPU is visible (not just ROCm tools installed). Always returns False when an NVIDIA GPU is present -- NVIDIA takes priority on mixed hosts and prevents every detection path below (rocminfo, amd-smi, KFD sysfs) from producing a false positive even if
()
| 726 | |
| 727 | |
| 728 | def _has_rocm_gpu() -> bool: |
| 729 | """Return True only if an actual AMD GPU is visible (not just ROCm tools installed). |
| 730 | |
| 731 | Always returns False when an NVIDIA GPU is present -- NVIDIA takes |
| 732 | priority on mixed hosts and prevents every detection path below |
| 733 | (rocminfo, amd-smi, KFD sysfs) from producing a false positive even |
| 734 | if ROCm tools are installed alongside the NVIDIA driver. |
| 735 | """ |
| 736 | if _has_usable_nvidia_gpu(): |
| 737 | return False |
| 738 | for cmd, check_fn in ( |
| 739 | # rocminfo: look for a real gfx GPU id (3-4 chars, nonzero first digit). |
| 740 | # gfx000 is the CPU agent; ROCm 6.1+ also emits generic ISA lines like |
| 741 | # "gfx11-generic"/"gfx9-4-generic" with only 1-2 digits before the dash, |
| 742 | # which must not be treated as a real GPU. |
| 743 | ( |
| 744 | ["rocminfo"], |
| 745 | lambda out: bool(re.search(r"gfx[1-9][0-9a-z]{2,3}", out.lower())), |
| 746 | ), |
| 747 | # amd-smi list: require "GPU: <number>" data rows, not just a header |
| 748 | ( |
| 749 | ["amd-smi", "list"], |
| 750 | lambda out: bool(re.search(r"(?im)^gpu\s*[:\[]\s*\d", out)), |
| 751 | ), |
| 752 | ): |
| 753 | exe = shutil.which(cmd[0]) |
| 754 | if not exe: |
| 755 | continue |
| 756 | # Skip amd-smi on Windows w/o a HIP SDK (avoids the UAC/DiskPart prompt); |
| 757 | # rely on rocminfo / the sysfs fallback there. |
| 758 | if cmd[0] == "amd-smi" and not _amd_smi_allowed(): |
| 759 | continue |
| 760 | try: |
| 761 | result = subprocess.run( |
| 762 | [exe, *cmd[1:]], |
| 763 | stdout = subprocess.PIPE, |
| 764 | stderr = subprocess.DEVNULL, |
| 765 | text = True, |
| 766 | timeout = 10, |
| 767 | env = _amd_smi_env() if cmd[0] == "amd-smi" else None, |
| 768 | ) |
| 769 | except Exception: |
| 770 | continue |
| 771 | if result.returncode == 0 and result.stdout.strip(): |
| 772 | if check_fn(result.stdout): |
| 773 | return True |
| 774 | # sysfs KFD topology fallback (Linux only) -- matches install.sh's |
| 775 | # runtime-only detection. On minimal package-managed installs (no |
| 776 | # rocminfo / no amd-smi tools), the kernel exposes AMD GPUs via |
| 777 | # /sys/class/kfd so `studio update` can still detect and repair. |
| 778 | # |
| 779 | # Guard: reject any KFD node whose properties file reports a non-AMD |
| 780 | # vendor. With the NVIDIA open kernel module (driver 560+), NVIDIA GPUs |
| 781 | # can register KFD topology nodes with a non-zero gpu_id; those nodes |
| 782 | # have vendor_id 4318 (0x10DE) rather than the AMD value 4098 (0x1002). |
| 783 | # Without this check the fallback returns True on NVIDIA-only systems, |
| 784 | # causing _ensure_rocm_torch to install ROCm wheels on NVIDIA hardware. |
| 785 | if sys.platform != "win32": |
no test coverage detected
searching dependent graphs…