AMD SMI packaging and install paths#

AMD SMI ships through several delivery channels. This page describes each one, how the Python module locates the native library in each, which combinations are supported, and how upgrades and downgrades behave. It is the reference for the loader contract that py-interface/amdsmi_wrapper.py implements.

Delivery paths#

Path

Native library (.so)

Python module

How the module finds the .so

System package (deb/rpm)

/opt/rocm/lib/libamd_smi.so.<MAJOR> (+ ld.so.conf.d entry)

Installed into the system interpreter’s site-packages/dist-packages and share/amd_smi

SONAME via the dynamic linker

Tarball

Present in the extracted tree

Not installed

n/a — CLI and .so work; import amdsmi is not provided

ROCm via pip (TheRock rocm_sdk_core)

<root>/lib/libamd_smi.so.<MAJOR>

<root>/share/amd_smi/amdsmi

Resolved relative to the wrapper (../../../lib)

ROCm via pip in a venv

Same as above, inside the venv

Same as above, inside the venv

Same as above

PyPI wheel

Bundled libamd_smi_python.so next to the wrapper

Interpreter site-packages

The bundled .so; system fallback is disabled

The loader#

py-interface/amdsmi_wrapper.py selects the library in this order:

  1. AMDSMI_LIB_OVERRIDE — explicit path, for ABI tests.

  2. A bundled libamd_smi_python.so next to the wrapper — the PyPI wheel.

  3. The SONAME resolved relative to the wrapper (parents[3]/lib) — the TheRock share/amd_smi layout, where a venv has no ld.so.conf.d entry.

  4. The bare SONAME via the dynamic linker — the system deb/rpm.

Steps 3 and 4 are skipped when _AMDSMI_ALLOW_SYSTEM_FALLBACK is False. The committed wrapper and the system package keep it True; the wheel build flips it to False, so a wheel never loads a system libamd_smi.so (which could be a different version and would risk symbol conflicts inside processes such as PyTorch or JAX that ship their own copy).

The wheel’s libamd_smi_python.so has a distinct SONAME and is linked with -Bsymbolic-functions, so the system and wheel libraries can be loaded in the same process without the dynamic linker interposing one on the other.

Two installed copies (system package)#

The deb/rpm installs the module into both the interpreter’s site-packages and share/amd_smi. Both are required:

  • site-packages makes a plain import amdsmi work.

  • share/amd_smi is captured by the TheRock artifact flow (which packages only /opt/rocm, so it cannot reach the /usr site-packages tree) and is used by downstream tools that sys.path.insert(ROCM_PATH + "/share/amd_smi").

A redirector or symlink is not viable because TheRock ships only /opt/rocm. The build harness runs a guard (tests/run_amdsmi_dual_copy_test.py) asserting the two copies stay byte-identical, so drift fails a build instead of shipping.

Coexistence and precedence#

A user installs one delivery path. When a PyPI wheel is installed alongside a system package, the wheel wins and the package uninstall does not remove it, because they live in separate, file-manager-owned trees and sys.path favors the wheel:

Installed together

import amdsmi resolves to

Package uninstall removes the wheel?

deb + pip wheel (Debian)

wheel in /usr/local/.../dist-packages (precedes /usr/lib)

No — dpkg removes only its own files

rpm + pip --user wheel (RHEL)

wheel in ~/.local/.../site-packages (precedes system)

No — rpm removes only its own files

deb/rpm + venv wheel

wheel in the venv (isolated)

No — separate tree

The precedence above is the default sys.path ordering between install locations. A global PYTHONPATH overrides it: Python searches PYTHONPATH entries before any install location, so import amdsmi resolves there regardless of where the wheel or package installed. Some ROCm container images set PYTHONPATH=/opt/rocm/share/amd_smi, which makes the share/amd_smi copy win over a pip wheel in that environment. Unset PYTHONPATH (or point it at the copy you want) to restore the install-location precedence.

Support matrix#

Legend: ✅ supported and tested · 🟡 supported, pick one recommended · ⛔ unsupported.

Single path#

Path

amd-smi CLI

import amdsmi

deb/rpm

tarball

⛔ (module not installed)

ROCm pip

ROCm pip in venv

PyPI wheel

⛔ (Python bindings only)

Two paths together#

Combination

Coexist?

deb/rpm + PyPI wheel

✅ (wheel wins; package uninstall keeps the wheel)

deb/rpm + ROCm pip, same interpreter

🟡 (discouraged; two library families)

PyPI wheel + ROCm pip

🟡 (discouraged)

tarball + any pip/wheel

✅ (module comes from pip; tarball .so unused by the module)

ROCm pip + ROCm pip venv

✅ (venv wins while active)

Unsupported#

  • Two system packages of different major SOVERSION on one prefix.

  • Relying on the tarball to provide import amdsmi.

  • A wheel loading a system /opt/rocm library (blocked by design).

Upgrade and downgrade (deb/rpm)#

Transition

Behavior

pre-7.14 (pip-era) → 7.14+ package

The old package’s prerm still pip uninstalls the legacy module and removes its .pth; the new package owns the site-packages files.

7.14+ → 7.14+

Plain file replacement by the package manager.

7.14+ → pre-7.14 (downgrade)

The old package re-adds the pip install; a user-installed PyPI wheel in /usr/local or ~/.local still wins and survives.

package removed, then newest PyPI wheel

Package removal deletes only its own files; the wheel is self-contained (bundled .so, fallback disabled).

RPM interpreter dependency#

On RPM distros the module installs into a version-specific site-packages (e.g. /usr/lib64/python3.9/site-packages). The package therefore declares a dependency on the matching interpreter so it installs only where that interpreter (and thus the baked path) exists:

  • RHEL/CentOS/Fedora/AlmaLinux/AzureLinux: python(abi) = X.Y.

  • SLES/openSUSE: pythonXY (e.g. python311).

Debian’s dist-packages is version-agnostic, so the deb keeps the loose python3 (>= 3.6.8) dependency and the #!/usr/bin/python3 CLI shebang serves every python3 minor.