Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 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
291 changes: 264 additions & 27 deletions .github/workflows/amdsmi-build.yml

Large diffs are not rendered by default.

128 changes: 128 additions & 0 deletions .github/workflows/manylinux-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: AMDSMI ManyLinux Wheels

on:
pull_request:
branches: [develop]
paths:
- 'projects/amdsmi/**'
- '.github/workflows/manylinux-build.yml'
push:
branches: [develop]
paths:
- 'projects/amdsmi/**'
- '.github/workflows/manylinux-build.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
manylinux-wheels:
name: Build Manylinux Wheels
runs-on: ubuntu-latest
container:
image: quay.io/pypa/manylinux_2_28_x86_64

steps:
- uses: actions/checkout@v4

- name: Mark workspace safe for git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

- name: Build manylinux wheels
run: |
set -euo pipefail
set -x
PROJECT_DIR=$GITHUB_WORKSPACE/projects/amdsmi
BUILD_DIR=/tmp/amdsmi-build
RAW_WHEELS=/tmp/raw-wheels
WHEEL_OUT=$GITHUB_WORKSPACE/wheels
PY_BUILD=/opt/python/cp38-cp38/bin/python3

echo "Using manylinux image: quay.io/pypa/manylinux_2_28_x86_64"

echo "Installing build prerequisites..."
dnf -y install git make gcc gcc-c++ cmake ninja-build openssl-devel

echo "Configuring and building core..."
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
cmake "$PROJECT_DIR" \
-DBUILD_TESTS=OFF \
-DENABLE_ESMI_LIB=ON \
-DBUILD_PYTHON_LIB=ON \
-DCMAKE_BUILD_TYPE=Release \
-DPython3_EXECUTABLE="$PY_BUILD"
make -j"$(nproc)"

echo "Building wheels for all supported Python versions..."
mkdir -p "$RAW_WHEELS" "$WHEEL_OUT"
chmod 777 "$WHEEL_OUT"
$PY_BUILD -m pip install --upgrade pip setuptools wheel auditwheel

for PY in \
/opt/python/cp38-cp38/bin/python3 \
/opt/python/cp39-cp39/bin/python3 \
/opt/python/cp310-cp310/bin/python3 \
/opt/python/cp311-cp311/bin/python3 \
/opt/python/cp312-cp312/bin/python3 \
/opt/python/cp313-cp313/bin/python3; do
if [ ! -x "$PY" ]; then
echo "Skipping missing interpreter $PY"
continue
fi
echo "Building wheel with $PY"
$PY -m pip install --upgrade pip setuptools wheel
pushd "$BUILD_DIR/py-interface/python_package"
rm -rf build dist *.whl *.egg-info
$PY -m pip wheel --no-deps --no-build-isolation -w "$RAW_WHEELS" .
popd
done

echo "Raw wheels built:"
ls -al "$RAW_WHEELS" || true

if ! ls "$RAW_WHEELS"/*.whl >/dev/null 2>&1; then
echo "No wheels were built; aborting."
exit 1
fi

echo "Repairing wheels with auditwheel..."
if ! $PY_BUILD -m auditwheel repair "$RAW_WHEELS"/*.whl --wheel-dir "$WHEEL_OUT"; then
echo "auditwheel repair failed; keeping raw wheels only."
cp -v "$RAW_WHEELS"/*.whl "$WHEEL_OUT"/
fi
sync

echo "Final wheels:"
ls -al "$WHEEL_OUT"

- name: Verify wheels exist
run: |
mkdir -p "$GITHUB_WORKSPACE/wheels"
ls -al "$GITHUB_WORKSPACE/wheels"
if ! ls "$GITHUB_WORKSPACE"/wheels/*.whl >/dev/null 2>&1; then
echo "No wheels found; failing."
exit 1
fi
echo "Wheel summary:"
for whl in "$GITHUB_WORKSPACE"/wheels/*.whl; do
echo " $(basename $whl)"
done

- name: Upload manylinux wheels (by SHA)
uses: actions/upload-artifact@v4
with:
name: amdsmi-manylinux-wheels-${{ github.sha }}
path: ${{ github.workspace }}/wheels/*.whl
if-no-files-found: error
retention-days: 30

- name: Upload manylinux wheels (downloadable)
uses: actions/upload-artifact@v4
with:
name: amdsmi-python-wheels
path: ${{ github.workspace }}/wheels/*.whl
if-no-files-found: warn
retention-days: 90
102 changes: 31 additions & 71 deletions projects/amdsmi/DEBIAN/postinst.in
Original file line number Diff line number Diff line change
Expand Up @@ -105,92 +105,52 @@ do_ldconfig() {
}

do_install_amdsmi_python_lib() {
# get python version
local python3_minor_version
python3_minor_version=$(python3 -c 'import sys;print(sys.version_info.minor)')
if [ $? -ne 0 ]; then
echo "[WARNING] Could not determine python version. "\
"AMD-SMI python library will not be installed."
return
fi
# Drop a .pth file into the system site-packages so that
# "import amdsmi" finds the package installed under
# @CPACK_PACKAGING_INSTALL_PREFIX@/@SHARE_INSTALL_PREFIX@
# without requiring pip. The .pth approach is version-agnostic:
# it works with any Python 3.x without needing pip or setuptools.

# check if python version is supported
if [ "$python3_minor_version" -lt 6 ]; then
echo "[WARNING] AMD-SMI python library is not "\
"supported on python version 3.$python3_minor_version. "\
"AMD-SMI python library will not be installed."
return
fi
local python_lib_path=@CPACK_PACKAGING_INSTALL_PREFIX@/@SHARE_INSTALL_PREFIX@

local PREVIOUS_PIP_ROOT_USER_ACTION="$PIP_ROOT_USER_ACTION"
export PIP_ROOT_USER_ACTION=ignore
# python3.11 requires --break-system-packages
local PREVIOUS_PIP_BREAK_SYSTEM_PACKAGES="$PIP_BREAK_SYSTEM_PACKAGES"
export PIP_BREAK_SYSTEM_PACKAGES=1

# Remove old python library
local amdsmi_pip_list_output
amdsmi_pip_list_output=$(python3 -m pip list --format=columns --disable-pip-version-check)
# check pip list output for amdsmi
if [[ $amdsmi_pip_list_output == *"amdsmi"* ]]; then
echo "Detected old AMD-SMI python library (amdsmi)..."
python3 -m pip uninstall amdsmi --yes --quiet --disable-pip-version-check
echo "Removed old AMD-SMI python library (amdsmi)..."
fi
# Remove stale SWIG-based Python extension (now uses ctypes)
rm -f "${python_lib_path}/amdsmi/libamd_smi_python.so" 2>/dev/null || true

# static builds don't include python lib
if [ "@BUILD_SHARED_LIBS@" != "ON" ]; then
return
# Remove any previously pip-installed amdsmi to avoid conflicts
if python3 -m pip list --format=columns --disable-pip-version-check 2>/dev/null | grep -q amdsmi; then
echo "Removing previously pip-installed amdsmi..."
PIP_BREAK_SYSTEM_PACKAGES=1 python3 -m pip uninstall amdsmi --yes --quiet --disable-pip-version-check 2>/dev/null || true
fi

check_and_install_amdsmi() {
local setuptools_version
setuptools_version=$(python3 -c 'import setuptools; print(setuptools.__version__)')
if [ $? -ne 0 ]; then
echo "[WARNING] Could not determine setuptools version. "\
"AMD-SMI python library will not be installed."
return
# Determine site-packages directory
local site_packages
site_packages=$(python3 -c 'import site; print(site.getsitepackages()[0])' 2>/dev/null)
if [ -z "$site_packages" ]; then
echo "[WARNING] Could not determine site-packages directory. Trying dist-packages fallback..."
site_packages=$(python3 -c 'import sysconfig; print(sysconfig.get_path("purelib"))' 2>/dev/null)
fi

# install python library at @CPACK_PACKAGING_INSTALL_PREFIX@/@SHARE_INSTALL_PREFIX@/amdsmi
local python_lib_path=@CPACK_PACKAGING_INSTALL_PREFIX@/@SHARE_INSTALL_PREFIX@
local amdsmi_python_lib_path="$python_lib_path"
local amdsmi_setup_py_path="$python_lib_path/setup.py"

# Decide installation method based on setuptools version
if [[ "$(printf '%s\n' "$setuptools_version" "28.5" | sort -V | head -n1)" == "$setuptools_version" ]]; then
echo "[WARNING] Setuptools version is less than 28.5. AMD-SMI will not be installed."
elif [[ "$(printf '%s\n' "$setuptools_version" "41.0.1" | sort -V | head -n1)" != "41.0.1" ]]; then
echo "Using setup.py for installation due to setuptools version $setuptools_version"
python3 "$amdsmi_setup_py_path" install
else
echo "Using pyproject.toml for installation due to setuptools version $setuptools_version"
python3 -m pip install "$amdsmi_python_lib_path" --quiet --disable-pip-version-check --no-build-isolation --no-index
if [ -z "$site_packages" ] || [ ! -d "$site_packages" ]; then
echo "[WARNING] Could not locate Python site-packages. AMD-SMI .pth file will not be installed."
return
fi
}

# Call the function
check_and_install_amdsmi
# Write the .pth file — Python adds this path to sys.path on startup
echo "$python_lib_path" > "$site_packages/amdsmi.pth"
echo "Installed amdsmi.pth -> $site_packages/amdsmi.pth (points to $python_lib_path)"

export PIP_ROOT_USER_ACTION="$PREVIOUS_PIP_ROOT_USER_ACTION"
export PIP_BREAK_SYSTEM_PACKAGES="$PREVIOUS_PIP_BREAK_SYSTEM_PACKAGES"

# only try to activate argcomplete if such command exists
# python3-argcomplete is recommended but optional, we handle its absence gracefully
# Activate argcomplete if available
if command -v activate-global-python-argcomplete &>/dev/null; then
activate-global-python-argcomplete 2>/dev/null || {
echo "[INFO] Bash completion activation skipped. You can manually enable it with: activate-global-python-argcomplete"
}
elif command -v activate-global-python-argcomplete3 &>/dev/null; then
activate-global-python-argcomplete3 2>/dev/null || {
echo "[INFO] Bash completion activation skipped. You can manually enable it with: activate-global-python-argcomplete3"
}
else
# try older argcomplete3 version
if command -v activate-global-python-argcomplete3 &>/dev/null; then
activate-global-python-argcomplete3 2>/dev/null || {
echo "[INFO] Bash completion activation skipped. You can manually enable it with: activate-global-python-argcomplete3"
}
else
echo "[WARNING] Could not find argcomplete activation command. "\
"Argument completion will not work. Install python3-argcomplete package to enable it."
fi
echo "[WARNING] Could not find argcomplete activation command. "\
"Argument completion will not work. Install python3-argcomplete package to enable it."
fi
}

Expand Down
105 changes: 31 additions & 74 deletions projects/amdsmi/RPM/post.in
Original file line number Diff line number Diff line change
Expand Up @@ -104,95 +104,52 @@ do_ldconfig() {
}

do_install_amdsmi_python_lib() {
# get python version
local python3_minor_version
python3_minor_version=$(python3 -c 'import sys;print(sys.version_info.minor)')
if [ $? -ne 0 ]; then
echo "[WARNING] Could not determine python version. "\
"AMD-SMI python library will not be installed."
return
fi
# Drop a .pth file into the system site-packages so that
# "import amdsmi" finds the package installed under
# $RPM_INSTALL_PREFIX0/@SHARE_INSTALL_PREFIX@
# without requiring pip. The .pth approach is version-agnostic:
# it works with any Python 3.x without needing pip or setuptools.

# check if python version is supported
if [ "$python3_minor_version" -lt 6 ]; then
echo "[WARNING] AMD-SMI python library is not "\
"supported on python version 3.$python3_minor_version. "\
"AMD-SMI python library will not be installed."
return
fi
local python_lib_path=$RPM_INSTALL_PREFIX0/@SHARE_INSTALL_PREFIX@

local PREVIOUS_PIP_ROOT_USER_ACTION="$PIP_ROOT_USER_ACTION"
export PIP_ROOT_USER_ACTION=ignore
# python3.11 requires --break-system-packages
local PREVIOUS_PIP_BREAK_SYSTEM_PACKAGES="$PIP_BREAK_SYSTEM_PACKAGES"
export PIP_BREAK_SYSTEM_PACKAGES=1


# Remove old python library
local amdsmi_pip_list_output
amdsmi_pip_list_output=$(python3 -m pip list --format=columns --disable-pip-version-check)
# check pip list output for amdsmi
if [[ $amdsmi_pip_list_output == *"amdsmi"* ]]; then
echo "Detected old AMD-SMI python library (amdsmi)..."
python3 -m pip uninstall amdsmi --yes --quiet --disable-pip-version-check
echo "Removed old AMD-SMI python library (amdsmi)..."
fi
# Remove stale SWIG-based Python extension (now uses ctypes)
rm -f "${python_lib_path}/amdsmi/libamd_smi_python.so" 2>/dev/null || true

# static builds don't include python lib
if [ "@BUILD_SHARED_LIBS@" != "ON" ]; then
return
# Remove any previously pip-installed amdsmi to avoid conflicts
if python3 -m pip list --format=columns --disable-pip-version-check 2>/dev/null | grep -q amdsmi; then
echo "Removing previously pip-installed amdsmi..."
PIP_BREAK_SYSTEM_PACKAGES=1 python3 -m pip uninstall amdsmi --yes --quiet --disable-pip-version-check 2>/dev/null || true
fi

check_and_install_amdsmi() {
local setuptools_version
setuptools_version=$(python3 -c 'import setuptools; print(setuptools.__version__)')
if [ $? -ne 0 ]; then
echo "[WARNING] Could not determine setuptools version. "\
"AMD-SMI python library will not be installed."
return
# Determine site-packages directory
local site_packages
site_packages=$(python3 -c 'import site; print(site.getsitepackages()[0])' 2>/dev/null)
if [ -z "$site_packages" ]; then
echo "[WARNING] Could not determine site-packages directory. Trying sysconfig fallback..."
site_packages=$(python3 -c 'import sysconfig; print(sysconfig.get_path("purelib"))' 2>/dev/null)
fi

# install python library at $RPM_INSTALL_PREFIX0/@SHARE_INSTALL_PREFIX@/amdsmi
local python_lib_path=$RPM_INSTALL_PREFIX0/@SHARE_INSTALL_PREFIX@
local amdsmi_python_lib_path="$python_lib_path"
local amdsmi_setup_py_path="$python_lib_path/setup.py"

# Decide installation method based on setuptools version
if [[ "$(printf '%s\n' "$setuptools_version" "28.5" | sort -V | head -n1)" == "$setuptools_version" ]]; then
echo "[WARNING] Setuptools version is less than 28.5. AMD-SMI will not be installed."
elif [[ "$(printf '%s\n' "$setuptools_version" "41.0.1" | sort -V | head -n1)" != "41.0.1" ]]; then
echo "Using setup.py for installation due to setuptools version $setuptools_version"
cd $amdsmi_python_lib_path
python3 setup.py install
cd -
else
echo "Using pyproject.toml for installation due to setuptools version $setuptools_version"
python3 -m pip install "$amdsmi_python_lib_path" --quiet --disable-pip-version-check --no-build-isolation --no-index
if [ -z "$site_packages" ] || [ ! -d "$site_packages" ]; then
echo "[WARNING] Could not locate Python site-packages. AMD-SMI .pth file will not be installed."
return
fi
}

# Call the function
check_and_install_amdsmi
# Write the .pth file — Python adds this path to sys.path on startup
echo "$python_lib_path" > "$site_packages/amdsmi.pth"
echo "Installed amdsmi.pth -> $site_packages/amdsmi.pth (points to $python_lib_path)"

export PIP_ROOT_USER_ACTION="$PREVIOUS_PIP_ROOT_USER_ACTION"
export PIP_BREAK_SYSTEM_PACKAGES="$PREVIOUS_PIP_BREAK_SYSTEM_PACKAGES"

# only try to activate argcomplete if such command exists
# python3-argcomplete is recommended but optional, we handle its absence gracefully
# Activate argcomplete if available
if command -v activate-global-python-argcomplete &>/dev/null; then
activate-global-python-argcomplete 2>/dev/null || {
echo "[INFO] Bash completion activation skipped. You can manually enable it with: activate-global-python-argcomplete"
}
elif command -v activate-global-python-argcomplete3 &>/dev/null; then
activate-global-python-argcomplete3 2>/dev/null || {
echo "[INFO] Bash completion activation skipped. You can manually enable it with: activate-global-python-argcomplete3"
}
else
# try older argcomplete3 version
if command -v activate-global-python-argcomplete3 &>/dev/null; then
activate-global-python-argcomplete3 2>/dev/null || {
echo "[INFO] Bash completion activation skipped. You can manually enable it with: activate-global-python-argcomplete3"
}
else
echo "[WARNING] Could not find argcomplete activation command. "\
"Argument completion will not work. Install python3-argcomplete package to enable it."
fi
echo "[WARNING] Could not find argcomplete activation command. "\
"Argument completion will not work. Install python3-argcomplete package to enable it."
fi
}

Expand Down
1 change: 1 addition & 0 deletions projects/amdsmi/amdsmi_cli/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
# Set CLI Build Directory
set(PY_PACKAGE_DIR "amdsmi_cli")
set(PY_CLI_INSTALL_DIR "${CMAKE_INSTALL_LIBEXECDIR}" CACHE STRING "CLI tool installation directory")
set(PY_LIB_FROM_PKG "${PROJECT_BINARY_DIR}/py-interface/python_package/amdsmi/libamd_smi_python.so")

# populate version string
configure_file(_version.py.in ${PY_PACKAGE_DIR}/_version.py @ONLY)
Expand Down
Loading
Loading