Add 'projects/amdsmi/' from commit 'b4b3539631460b986dddc86a2303cef11cd38816'

git-subtree-dir: projects/amdsmi
git-subtree-mainline: 0633d8d8ce
git-subtree-split: b4b3539631
This commit is contained in:
Ameya Keshava Mallya
2025-11-17 22:28:37 +00:00
302 changed files with 140753 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
* @maisarif_amdeng @shuzhliu_amdeng @dgalants_amdeng @charpoag_amdeng @daolivei_amdeng @marifamd @bill-shuzhou-liu @dmitrii-galantsev @charis-poag-amd @oliveiradan @gabrpham_amdeng
docs/* @ROCm/rocm-documentation
*.md @ROCm/rocm-documentation
*.rst @ROCm/rocm-documentation
+84
View File
@@ -0,0 +1,84 @@
# Contributing to AMD SMI #
We welcome contributions to AMD SMI.
Please follow these details to help ensure your contributions will be successfully accepted.
## Issue Discussion ##
Please use the GitHub Issues tab to notify us of issues.
* Use your best judgement for issue creation. If your issue is already listed, upvote the issue and
comment or post to provide additional details, such as how you reproduced this issue.
* If you're not sure if your issue is the same, err on the side of caution and file your issue.
You can add a comment to include the issue number (and link) for the similar issue. If we evaluate
your issue as being the same as the existing issue, we'll close the duplicate.
* If your issue doesn't exist, use the issue template to file a new issue.
* When filing an issue, be sure to provide as much information as possible, including script output so
we can collect information about your configuration. This helps reduce the time required to
reproduce your issue.
* Check your issue regularly, as we may require additional information to successfully reproduce the
issue.
* You may also open an issue to ask questions to the maintainers about whether a proposed change
meets the acceptance criteria, or to discuss an idea pertaining to the library.
## Acceptance Criteria ##
The goal of AMD SMI project is to provide a simple CLI interface and a library
for interacting with AMD GPUs.
## Coding Style ##
Please refer to `.clang-format`. It is suggested you use `pre-commit` tool.
It mostly follows Google C++ formatting with 100 character line limit.
## Pull Request Guidelines ##
When you create a pull request, you should target the default branch. Our
current default branch is the **amd-staging** branch, which serves as our
integration branch.
### Deliverables ###
For each new file in repository,
Please include the licensing header
/*
* =============================================================================
* Copyright (c) 2019-2025 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
### Process ###
* Reviewers are listed in the CODEOWNERS file
* Code format guidelines
AMD SMI uses the clang-format tool for formatting code in source files.
The formatting style is captured in .clang-format which is located at
the root of AMD SMI. These are different options to follow:
1. Using pre-commit and docker - `pre-commit run`
1. Using only clang-format - `clang-format -i \<path-to-the-source-file\>`
## References ##
1. [pre-commit](https://github.com/pre-commit/pre-commit)
1. [clang-format](https://clang.llvm.org/docs/ClangFormat.html)
+18
View File
@@ -0,0 +1,18 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "pip" # See documentation for possible values
directory: "/docs/sphinx" # Location of package manifests
open-pull-requests-limit: 10
schedule:
interval: "weekly"
target-branch: "amd-staging"
labels:
- "documentation"
- "dependencies"
reviewers:
- "petepark_amdeng"
+5
View File
@@ -0,0 +1,5 @@
disabled: false
scmId: gh-emu-rocm
branchesToScan:
- amd-staging
- amd-mainline
@@ -0,0 +1,314 @@
name: ABI Compliance Check
on:
pull_request:
branches:
- amd-staging
- release/rocm-rel-*
paths:
- 'include/amd_smi/amdsmi.h'
push:
branches:
- amd-staging
- release/rocm-rel-*
paths:
- 'include/amd_smi/amdsmi.h'
workflow_dispatch:
permissions:
contents: read
pull-requests: write
jobs:
major_abi_check:
name: Major ABI Compliance Check
runs-on: AMD-ROCm-Internal-dev1
steps:
- name: Setup Environment
run: |
sudo rm -rf $GITHUB_WORKSPACE/* || true
sudo rm -rf $GITHUB_WORKSPACE/.[!.]* || true
sudo apt-get update -qq
sudo apt-get install -y -qq perl build-essential git universal-ctags
git clone https://github.com/lvc/abi-compliance-checker.git
cd abi-compliance-checker
sudo make install
abi-compliance-checker --version
- name: Checkout current code (new version)
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Fetch base branch for PR
if: github.event_name == 'pull_request'
run: |
echo "Fetching base branch: ${{ github.base_ref }}"
git fetch origin ${{ github.base_ref }}:${{ github.base_ref }}
git branch -a
- name: Prepare amdsmi.h files for comparison
id: prepare_files
run: |
echo "Preparing amdsmi.h files..."
echo "abi_exit_code=1" > $GITHUB_WORKSPACE/major_abi_status.txt
if [ -f include/amd_smi/amdsmi.h ]; then
cp include/amd_smi/amdsmi.h amdsmi_new.h
echo "Copied current amdsmi.h to amdsmi_new.h"
else
echo "::error::New amdsmi.h (include/amd_smi/amdsmi.h) not found in current checkout."
touch amdsmi_new.h
exit 0
fi
OLD_VERSION_REF=""
V1_NAME_SUFFIX=""
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
OLD_VERSION_REF="${{ github.base_ref }}"
V1_NAME_SUFFIX="base_${{ github.base_ref }}"
echo "Event is Pull Request. Old version source is base branch: ${OLD_VERSION_REF}"
elif [[ "${{ github.event_name }}" == "push" ]]; then
if [[ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]]; then
OLD_VERSION_REF="${{ github.event.before }}"
V1_NAME_SUFFIX="before_$(echo ${{ github.event.before }} | cut -c1-7)"
echo "Event is Push. Old version source is commit before push: ${OLD_VERSION_REF}"
else
echo "Push event is for a new branch or forced push. Cannot determine 'old' version."
touch amdsmi_old.h
echo "Created dummy amdsmi_old.h. Assuming no ABI breakage as no baseline."
echo "abi_exit_code=0" > $GITHUB_WORKSPACE/major_abi_status.txt
echo "skip_check=true" >> $GITHUB_OUTPUT
exit 0
fi
else
echo "::warning::Unsupported event type: ${{ github.event_name }}. Cannot determine old version."
touch amdsmi_old.h
echo "abi_exit_code=0" > $GITHUB_WORKSPACE/major_abi_status.txt
echo "skip_check=true" >> $GITHUB_OUTPUT
exit 0
fi
echo "Fetching amdsmi.h from ref: $OLD_VERSION_REF (as amdsmi_old.h)"
git show $OLD_VERSION_REF:include/amd_smi/amdsmi.h > amdsmi_old.h 2>/dev/null
if [ $? -ne 0 ] || [ ! -s amdsmi_old.h ]; then
echo "::warning::Failed to fetch 'include/amd_smi/amdsmi.h' from ref '$OLD_VERSION_REF' or file is empty/missing."
echo "Proceeding with an empty amdsmi_old.h. This may result in all symbols reported as 'added'."
echo -n "" > amdsmi_old.h
if [ ! -s amdsmi_new.h ]; then
echo "abi_exit_code=0" > $GITHUB_WORKSPACE/major_abi_status.txt
fi
else
echo "Successfully fetched amdsmi.h from $OLD_VERSION_REF to amdsmi_old.h"
fi
echo "v1_name_suffix=${V1_NAME_SUFFIX}" >> $GITHUB_OUTPUT
echo "skip_check=false" >> $GITHUB_OUTPUT
- name: Run Major ABI Compliance Check
if: steps.prepare_files.outputs.skip_check == 'false'
run: |
V1_NAME_SUFFIX_CLEAN=$(echo "${{ steps.prepare_files.outputs.v1_name_suffix }}" | tr '/' '-')
V2_NAME_CLEAN=$(echo "${{ github.ref_name || github.head_ref }}" | tr '/' '-')
echo "Comparing $V1_NAME_SUFFIX_CLEAN (old) with $V2_NAME_CLEAN (new) for Major ABI Check"
abi-compliance-checker -lib amdsmi -old amdsmi_old.h -new amdsmi_new.h -v1 "$V1_NAME_SUFFIX_CLEAN" -v2 "$V2_NAME_CLEAN" -report-path major-abi-report.html && echo "abi_exit_code=0" > $GITHUB_WORKSPACE/major_abi_status.txt
continue-on-error: true
- name: Display ABI Check Logs (Major)
if: always() && steps.prepare_files.outputs.skip_check == 'false'
run: |
echo "Displaying Major ABI compliance check logs (if any)"
find logs -type f -name "*.txt" -exec echo "--- {} ---" \; -exec cat {} \; || echo "No .txt logs found in logs/ directory."
- name: Label PR on Major ABI Breakage
if: always() && github.event_name == 'pull_request'
run: |
source $GITHUB_WORKSPACE/major_abi_status.txt
if [ "$abi_exit_code" -ne 0 ]; then
echo "Major ABI check failed, adding 'MAJOR ABI BREAKAGE' label to PR #${{ github.event.pull_request.number }}"
gh pr edit ${{ github.event.pull_request.number }} --add-label "MAJOR ABI BREAKAGE"
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Major ABI Report
if: always()
uses: actions/upload-artifact@v4
with:
name: major-abi-report
path: major-abi-report.html
if-no-files-found: ignore
- name: Report Major ABI Check Results
if: always()
run: |
echo "Checking Major ABI check exit code..."
source $GITHUB_WORKSPACE/major_abi_status.txt
echo "Major ABI check exit code: $abi_exit_code"
if [ "$abi_exit_code" -ne 0 ]; then
echo "::warning::⚠️ MAJOR ABI BREAKAGE FOUND ⚠️ CHECK \"Run Major ABI Compliance Check\" LOGS OR THE major-abi-report ARTIFACT FOR DETAILS."
else
echo "✅ Major ABI check succeeded."
fi
minor_abi_check:
name: Minor ABI Compliance Check
runs-on: AMD-ROCm-Internal-dev1
steps:
- name: Setup Environment
run: |
sudo rm -rf $GITHUB_WORKSPACE/* || true
sudo rm -rf $GITHUB_WORKSPACE/.[!.]* || true
sudo apt-get update -qq
sudo apt-get install -y -qq perl build-essential git universal-ctags
git clone https://github.com/lvc/abi-compliance-checker.git
cd abi-compliance-checker
sudo make install
abi-compliance-checker --version
- name: Checkout current code (new version)
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Fetch base branch for PR
if: github.event_name == 'pull_request'
run: |
echo "Fetching base branch: ${{ github.base_ref }}"
git fetch origin ${{ github.base_ref }}:${{ github.base_ref }}
git branch -a
- name: Prepare amdsmi.h files for comparison
id: prepare_files_minor
run: |
echo "Preparing amdsmi.h files for Minor check..."
echo "abi_exit_code=1" > $GITHUB_WORKSPACE/minor_abi_status.txt
if [ -f include/amd_smi/amdsmi.h ]; then
cp include/amd_smi/amdsmi.h amdsmi_new.h
echo "Copied current amdsmi.h to amdsmi_new.h for Minor check"
else
echo "::error::New amdsmi.h (include/amd_smi/amdsmi.h) not found in current checkout for Minor check."
touch amdsmi_new.h
exit 0
fi
OLD_VERSION_REF_MINOR=""
V1_NAME_SUFFIX_MINOR=""
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
OLD_VERSION_REF_MINOR="${{ github.base_ref }}"
V1_NAME_SUFFIX_MINOR="base_${{ github.base_ref }}"
elif [[ "${{ github.event_name }}" == "push" ]]; then
if [[ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]]; then
OLD_VERSION_REF_MINOR="${{ github.event.before }}"
V1_NAME_SUFFIX_MINOR="before_$(echo ${{ github.event.before }} | cut -c1-7)"
else
echo "Push event is for a new branch (Minor check). Assuming no ABI changes as no baseline."
touch amdsmi_old.h
echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
echo "skip_check_minor=true" >> $GITHUB_OUTPUT
exit 0
fi
else
echo "::warning::Unsupported event type for Minor ABI check: ${{ github.event_name }}."
touch amdsmi_old.h
echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
echo "skip_check_minor=true" >> $GITHUB_OUTPUT
exit 0
fi
echo "Fetching amdsmi.h from ref: $OLD_VERSION_REF_MINOR (as amdsmi_old.h) for Minor check"
git show $OLD_VERSION_REF_MINOR:include/amd_smi/amdsmi.h > amdsmi_old.h 2>/dev/null
if [ $? -ne 0 ] || [ ! -s amdsmi_old.h ]; then
echo "::warning::Failed to fetch 'include/amd_smi/amdsmi.h' from ref '$OLD_VERSION_REF_MINOR' or file is empty/missing for Minor check."
echo "Proceeding with an empty amdsmi_old.h for Minor check."
echo -n "" > amdsmi_old.h
if [ ! -s amdsmi_new.h ]; then
echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
fi
else
echo "Successfully fetched amdsmi.h from $OLD_VERSION_REF_MINOR to amdsmi_old.h for Minor check"
fi
echo "v1_name_suffix_minor=${V1_NAME_SUFFIX_MINOR}" >> $GITHUB_OUTPUT
echo "skip_check_minor=false" >> $GITHUB_OUTPUT
- name: Run Minor ABI Compliance Check (Strict)
if: steps.prepare_files_minor.outputs.skip_check_minor == 'false'
run: |
V1_NAME_SUFFIX_CLEAN=$(echo "${{ steps.prepare_files_minor.outputs.v1_name_suffix_minor }}" | tr '/' '-')
V2_NAME_CLEAN=$(echo "${{ github.ref_name || github.head_ref }}" | tr '/' '-')
COMPARE_MSG="$V1_NAME_SUFFIX_CLEAN vs $V2_NAME_CLEAN"
echo "Comparing $COMPARE_MSG for Minor ABI Check (Strict)"
abi-compliance-checker -lib amdsmi -old amdsmi_old.h -new amdsmi_new.h -v1 "$V1_NAME_SUFFIX_CLEAN" -v2 "$V2_NAME_CLEAN" -report-path minor-abi-report.html -strict || {
ACC_EXIT_CODE=$?
echo "abi-compliance-checker -strict failed with exit code $ACC_EXIT_CODE."
echo "abi_exit_code=$ACC_EXIT_CODE" > $GITHUB_WORKSPACE/minor_abi_status.txt
}
current_abi_status=$(cat $GITHUB_WORKSPACE/minor_abi_status.txt)
current_exit_code=${current_abi_status#*=}
if [ "$current_exit_code" -eq 0 ] && [ -f minor-abi-report.html ]; then
echo "ACC strict check passed. Parsing HTML report for any changes..."
CHANGED=0
if grep -q "Added Symbols.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found added symbols"; fi
if grep -q "Removed Symbols.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found removed symbols"; fi
if grep -q "Problems with.*Data Types.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found problems with data types"; fi
if grep -q "Problems with.*Symbols.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found problems with symbols"; fi
if grep -q "Problems with.*Constants.*[1-9]" minor-abi-report.html; then CHANGED=1; echo "::warning::STRICT ABI: Found problems with constants"; fi
if [ "$CHANGED" -eq 1 ]; then
echo "::error::STRICT ABI CHECK FAILED: Found changes in ABI report comparing $COMPARE_MSG"
echo "abi_exit_code=1" > $GITHUB_WORKSPACE/minor_abi_status.txt
else
echo "No strict ABI changes found in HTML report."
echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
fi
elif [ ! -f minor-abi-report.html ] && [ "$current_exit_code" -eq 0 ]; then
echo "::warning::Minor ABI report (minor-abi-report.html) not found, but ACC reported success. Assuming no changes."
echo "abi_exit_code=0" > $GITHUB_WORKSPACE/minor_abi_status.txt
elif [ "$current_exit_code" -ne 0 ]; then
echo "ACC strict check already indicated failure (exit code $current_exit_code). HTML parsing for further changes skipped or confirmed failure."
fi
continue-on-error: true
- name: Display ABI Check Logs (Minor)
if: always() && steps.prepare_files_minor.outputs.skip_check_minor == 'false'
run: |
echo "Displaying Minor ABI compliance check logs (if any)"
find logs -type f -name "*.txt" -exec echo "--- {} ---" \; -exec cat {} \; || echo "No .txt logs found in logs/ directory."
- name: Label PR on Minor ABI Breakage
if: always() && github.event_name == 'pull_request'
run: |
source $GITHUB_WORKSPACE/minor_abi_status.txt
if [ "$abi_exit_code" -ne 0 ]; then
echo "Minor ABI check failed, adding 'MINOR ABI BREAKAGE' label to PR #${{ github.event.pull_request.number }}"
gh pr edit ${{ github.event.pull_request.number }} --add-label "MINOR ABI BREAKAGE"
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Minor ABI Report
if: always()
uses: actions/upload-artifact@v4
with:
name: minor-abi-report
path: minor-abi-report.html
if-no-files-found: ignore
- name: Report Minor ABI Check Results
if: always()
run: |
echo "Checking Minor ABI check exit code..."
source $GITHUB_WORKSPACE/minor_abi_status.txt
echo "Minor ABI check exit code: $abi_exit_code"
if [ "$abi_exit_code" -ne 0 ]; then
echo "::warning::⚠️ MINOR ABI CHANGES FOUND (STRICT CHECK) ⚠️ CHECK \"Run Minor ABI Compliance Check (Strict)\" LOGS OR THE minor-abi-report ARTIFACT FOR DETAILS."
else
echo "✅ Minor ABI check (Strict) succeeded or found no changes."
fi
+836
View File
@@ -0,0 +1,836 @@
name: AMDSMI CI
on:
pull_request:
branches: [amd-staging, amd-mainline, release/rocm-rel-*]
push:
branches: [amd-staging, amd-mainline, release/rocm-rel-*]
workflow_dispatch:
permissions:
contents: read
env:
DEBIAN_FRONTEND: noninteractive
DEBCONF_NONINTERACTIVE_SEEN: true
BUILD_TYPE: Release
ROCM_DIR: /opt/rocm
jobs:
debian-buildinstall:
name: Build
runs-on:
- self-hosted
- ${{ vars.RUNNER_TYPE }}
continue-on-error: true
strategy:
max-parallel: 10
matrix:
os: [Ubuntu20, Ubuntu22, Debian10]
container:
image: ${{ vars[format('{0}_DOCKER_IMAGE', matrix.os)] }}
options: --rm --privileged --device=/dev/kfd --device=/dev/dri --group-add video --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --shm-size=64G --cap-add=SYS_MODULE -v /lib/modules:/lib/modules
steps:
- uses: actions/checkout@v4
- name: Update repositories for Debian10
if: matrix.os == 'Debian10'
run: |
set -e
echo 'Updating repositories for Debian10 (archived)'
cat > /etc/apt/sources.list << EOF
deb http://archive.debian.org/debian buster main
deb http://archive.debian.org/debian-security buster/updates main
EOF
echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/99-disable-check-valid-until
apt update
- name: Build AMDSMI
run: |
set -e
echo 'Building on ${{ matrix.os }}'
BUILD_FOLDER=$GITHUB_WORKSPACE/build
RETRIES=3
for i in $(seq 1 $RETRIES); do
echo "Build attempt $i for ${{ matrix.os }}..."
rm -rf $BUILD_FOLDER
mkdir -p $BUILD_FOLDER
cd $BUILD_FOLDER
# Capture build output to parse warnings
if cmake $GITHUB_WORKSPACE -DBUILD_TESTS=ON -DENABLE_ESMI_LIB=ON 2>&1 | tee cmake.log && \
make -j $(nproc) 2>&1 | tee make.log && \
make package 2>&1 | tee package.log; then
# Parse and report warnings as GitHub annotations
echo "::group::Build Warnings"
grep -i "warning" cmake.log make.log package.log | while read -r line; do
echo "::warning::$line"
done
echo "::endgroup::"
echo "Build successful on attempt $i"
break
else
echo "Build failed on attempt $i"
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES build attempts failed. Exiting."
exit 1
fi
sleep $((2 * i))
fi
done
echo "Build completed on ${{ matrix.os }}"
- name: Install AMDSMI
run: |
cd $GITHUB_WORKSPACE/build
if [ "${{ matrix.os }}" != "Debian10" ]; then
apt update
fi
RETRIES=3
for i in $(seq 1 $RETRIES); do
echo "Installation attempt $i for ${{ matrix.os }}..."
if apt install -y ./amd-smi-lib*99999-local_amd64.deb; then
echo "Installation successful on attempt $i"
ln -s /opt/rocm/bin/amd-smi /usr/local/bin
# Verify Installation
echo 'Verifying installation:'
amd-smi version
python3 -m pip list | grep amd
python3 -m pip list | grep pip
python3 -m pip list | grep setuptools
echo 'Completed installation on ${{ matrix.os }}'
break
else
echo "Installation failed on attempt $i"
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES installation attempts failed. Exiting."
exit 1
fi
sleep $((2 * i))
fi
done
echo "Build completed on ${{ matrix.os }}"
- name: Uninstall
if: always()
run: |
set -e
echo 'Uninstalling on ${{ matrix.os }}'
apt remove -y amd-smi-lib || true
rm -f /usr/local/bin/amd-smi
if [ -d /opt/rocm/share/amd_smi ]; then
echo '/opt/rocm/share/amd_smi exists. Removing.'
rm -rf /opt/rocm/share/amd_smi
fi
echo 'Uninstall done on ${{ matrix.os }}'
debian-test:
name: Tests
needs: debian-buildinstall
runs-on:
- self-hosted
- ${{ vars.RUNNER_TYPE }}
continue-on-error: true
strategy:
max-parallel: 10
matrix:
os: [Ubuntu20, Ubuntu22, Debian10]
container:
image: ${{ vars[format('{0}_DOCKER_IMAGE', matrix.os)] }}
options: --rm --privileged --device=/dev/kfd --device=/dev/dri --group-add video --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --shm-size=64G --cap-add=SYS_MODULE -v /lib/modules:/lib/modules
steps:
- uses: actions/checkout@v4
- name: Update repositories for Debian10
if: matrix.os == 'Debian10'
run: |
set -e
echo 'Updating repositories for Debian10 (archived)'
cat > /etc/apt/sources.list << EOF
deb http://archive.debian.org/debian buster main
deb http://archive.debian.org/debian-security buster/updates main
EOF
echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/99-disable-check-valid-until
apt update
- name: Build and Install for Test
run: |
set -e
echo 'Building for test on ${{ matrix.os }}'
BUILD_FOLDER=$GITHUB_WORKSPACE/build
RETRIES=3
for i in $(seq 1 $RETRIES); do
echo "Build attempt $i for ${{ matrix.os }} test..."
rm -rf $BUILD_FOLDER
mkdir -p $BUILD_FOLDER
cd $BUILD_FOLDER
if cmake $GITHUB_WORKSPACE -DBUILD_TESTS=ON -DENABLE_ESMI_LIB=ON && \
make -j $(nproc) && \
make package; then
echo "Build successful on attempt $i"
break
else
echo "Build failed on attempt $i"
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES build attempts failed. Exiting."
exit 1
fi
sleep $((2 * i))
fi
done
echo 'Installing for test on ${{ matrix.os }}'
for i in $(seq 1 $RETRIES); do
echo "Installation attempt $i for test on ${{ matrix.os }}..."
if apt install -y $BUILD_FOLDER/amd-smi-lib*99999-local_amd64.deb; then
echo "Installation successful on attempt $i"
ln -s /opt/rocm/bin/amd-smi /usr/local/bin
echo 'Install done for test on ${{ matrix.os }}'
break
else
echo "Installation failed on attempt $i"
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES installation attempts failed. Exiting."
exit 1
fi
sleep $((2 * i))
fi
done
- name: AMDSMI Command Tests
shell: bash
run: |
set -e
echo "Running AMDSMI commands on ${{ matrix.os }}"
mkdir -p /tmp/test-results-${{ matrix.os }}
commands=(
"amd-smi version"
"amd-smi list"
"amd-smi static"
"amd-smi firmware"
"amd-smi ucode"
"amd-smi bad-pages"
"amd-smi metric"
"amd-smi process"
"amd-smi topology"
"amd-smi monitor"
"amd-smi dmon"
"amd-smi xgmi"
"amd-smi partition"
)
for cmd in "${commands[@]}"; do
debug_cmd="$cmd --loglevel debug"
echo "Running: $debug_cmd"
if ! eval "$debug_cmd" > /tmp/test-results-${{ matrix.os }}/$(echo $cmd | tr ' ' '_').log 2>&1; then
echo "Command '$debug_cmd' failed."
cat /tmp/test-results-${{ matrix.os }}/$(echo $cmd | tr ' ' '_').log
exit 1
else
echo "$debug_cmd passed."
fi
done
echo "AMDSMI commands done on ${{ matrix.os }}"
- name: Upload AMDSMI Command Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: amdsmi-command-tests-${{ matrix.os }}
path: /tmp/test-results-${{ matrix.os }}
- name: Run AMDSMI, Python, and Example Tests
shell: bash
run: |
set -e
echo 'Running other tests on ${{ matrix.os }}'
# AMDSMI Tests
echo 'Running AMDSMI tests'
cd /opt/rocm/share/amd_smi/tests
source amdsmitst.exclude
AMDSMI_RETRIES=3
for attempt in $(seq 1 $AMDSMI_RETRIES); do
echo "AMDSMI test attempt $attempt for ${{ matrix.os }}..."
if ./amdsmitst --gtest_filter="-$(echo ${BLACKLIST_ALL_ASICS})" > /tmp/test-results-${{ matrix.os }}/amdsmi_tests.log 2>&1; then
echo "AMDSMI tests passed on attempt $attempt"
echo "=============== TEST OUTPUT ==============="
cat /tmp/test-results-${{ matrix.os }}/amdsmi_tests.log | grep -E "\[==========\]|\[ PASSED \]|\[ SKIPPED \]|\[ FAILED \]"
echo "=============================================="
echo "AMDSMI tests done"
break
else
TEST_EXIT_CODE=$?
echo "AMDSMI tests failed on attempt $attempt with exit code $TEST_EXIT_CODE"
if [ $attempt -eq $AMDSMI_RETRIES ]; then
echo "All $AMDSMI_RETRIES AMDSMI test attempts failed. Final failure."
echo "=============== TEST OUTPUT ==============="
cat /tmp/test-results-${{ matrix.os }}/amdsmi_tests.log | grep -E "\[==========\]|\[ PASSED \]|\[ SKIPPED \]|\[ FAILED \]"
echo "=============================================="
echo "AMDSMI tests failed"
exit $TEST_EXIT_CODE
else
echo "Retrying AMDSMI tests in $((2 * attempt)) seconds..."
sleep $((2 * attempt))
fi
fi
done
# Python Tests
echo 'Running Python tests'
cd /opt/rocm/share/amd_smi/tests/python_unittest
echo "Running integration tests..."
if ! ./integration_test.py -v > /tmp/test-results-${{ matrix.os }}/integration_test_output.txt 2>&1; then
echo "Integration tests failed!"
echo "=============== INTEGRATION TEST OUTPUT ==============="
tail -100 /tmp/test-results-${{ matrix.os }}/integration_test_output.txt
echo "======================================================="
exit 1
else
echo "Integration tests passed"
fi
echo "Running unit tests..."
if ! ./unit_tests.py -v > /tmp/test-results-${{ matrix.os }}/unit_test_output.txt 2>&1; then
echo "Unit tests failed!"
echo "=============== UNIT TEST OUTPUT ==============="
tail -100 /tmp/test-results-${{ matrix.os }}/unit_test_output.txt
echo "================================================"
exit 1
else
echo "Unit tests passed"
fi
echo "Python tests done"
# Example Tests
echo 'Running Example tests'
cd $GITHUB_WORKSPACE/example
rm -rf build
cmake -B build -DENABLE_ESMI_LIB=OFF
make -C build -j $(nproc)
cd build
./amd_smi_drm_ex > /tmp/test-results-${{ matrix.os }}/amd_smi_drm_ex.log 2>&1 || echo 'amd_smi_drm_ex failed'
./amd_smi_nodrm_ex > /tmp/test-results-${{ matrix.os }}/amd_smi_nodrm_ex.log 2>&1 || echo 'amd_smi_nodrm_ex failed'
echo "Example tests done"
- name: AMDSMI Test Results
if: always()
run: |
echo "Displaying AMDSMI test results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/amdsmi_tests.log || echo "No AMDSMI test results found for ${{ matrix.os }}"
- name: Integration Test Results
if: always()
run: |
echo "Displaying Integration test results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/integration_test_output.txt || echo "No integration test results found for ${{ matrix.os }}"
- name: Unit Test Results
if: always()
run: |
echo "Displaying Unit Test Results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/unit_test_output.txt || echo "No unit test results found for ${{ matrix.os }}"
- name: Example DRM Test Results
if: always()
run: |
echo "Displaying Example DRM test results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/amd_smi_drm_ex.log || echo "No DRM example test results found for ${{ matrix.os }}"
- name: Example NoDRM Test Results
if: always()
run: |
echo "Displaying Example NoDRM test results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/amd_smi_nodrm_ex.log || echo "No NoDRM example test results found for ${{ matrix.os }}"
rpm-buildinstall:
name: Build
runs-on:
- self-hosted
- ${{ vars.RUNNER_TYPE }}
continue-on-error: true
strategy:
max-parallel: 10
matrix:
os:
- SLES
- RHEL8
- RHEL9
- RHEL10
- AzureLinux3
- AlmaLinux8
container:
image: ${{ vars[format('{0}_DOCKER_IMAGE', matrix.os)] }}
options: --rm --privileged --device=/dev/kfd --device=/dev/dri --group-add video --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --shm-size=64G --cap-add=SYS_MODULE -v /lib/modules:/lib/modules
steps:
- uses: actions/checkout@v4
- name: Set PkgMgr
run: |
set -e
case "${{ matrix.os }}" in
SLES)
echo "PACKAGE_MANAGER=zypper" >> $GITHUB_ENV
;;
RHEL8|RHEL9|RHEL10|AlmaLinux8|AzureLinux3)
echo "PACKAGE_MANAGER=dnf" >> $GITHUB_ENV
;;
esac
- name: Add more_itertools
if: matrix.os == 'AzureLinux3'
run: |
set -e
echo 'Installing more_itertools on ${{ matrix.os }}'
python3 -m pip install more_itertools
- name: Build AMDSMI(RHEL10 & AlmaLinux8)
if: matrix.os == 'RHEL10' || matrix.os == 'AlmaLinux8'
run: |
set -e
echo 'Building on ${{ matrix.os }} with retries and QA_RPATHS'
BUILD_FOLDER=$GITHUB_WORKSPACE/build
RETRIES=5
# Set QA_RPATHS to ignore empty (0x0010) and invalid (0x0002) RPATHs
export QA_RPATHS=$((0x0010 | 0x0002))
for i in $(seq 1 $RETRIES); do
echo "Build attempt $i for ${{ matrix.os }} ..."
rm -rf $BUILD_FOLDER
mkdir -p $BUILD_FOLDER
cd $BUILD_FOLDER
if cmake $GITHUB_WORKSPACE -DBUILD_TESTS=ON -DENABLE_ESMI_LIB=ON && \
make -j $(nproc) && \
make package; then
echo "Build successful on attempt $i"
break
else
echo "Build failed on attempt $i"
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES build attempts failed. Exiting."
exit 1
fi
sleep $((2 * i))
fi
done
echo "Build completed on ${{ matrix.os }}"
- name: Build AMDSMI
if: matrix.os != 'RHEL10' && matrix.os != 'AlmaLinux8'
run: |
set -e
echo 'Building on ${{ matrix.os }}'
BUILD_FOLDER=$GITHUB_WORKSPACE/build
RETRIES=3
for i in $(seq 1 $RETRIES); do
echo "Build attempt $i for ${{ matrix.os }}..."
rm -rf $BUILD_FOLDER
mkdir -p $BUILD_FOLDER
cd $BUILD_FOLDER
# Capture build output to parse warnings
if cmake $GITHUB_WORKSPACE -DBUILD_TESTS=ON -DENABLE_ESMI_LIB=ON 2>&1 | tee cmake.log && \
make -j $(nproc) 2>&1 | tee make.log && \
make package 2>&1 | tee package.log; then
# Parse and report warnings as GitHub annotations
echo "::group::Build Warnings"
grep -i "warning" cmake.log make.log package.log | while read -r line; do
echo "::warning::$line"
done
echo "::endgroup::"
echo "Build successful on attempt $i"
break
else
echo "Build failed on attempt $i"
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES build attempts failed. Exiting."
exit 1
fi
sleep $((2 * i))
fi
done
echo "Build completed on ${{ matrix.os }}"
- name: Install AMDSMI(RHEL10 & AlmaLinux8)
if: matrix.os == 'RHEL10' || matrix.os == 'AlmaLinux8'
run: |
cd $GITHUB_WORKSPACE/build
dnf install python3-setuptools python3-wheel -y
RETRIES=3
for i in $(seq 1 $RETRIES); do
echo "RHEL10: Installation attempt $i..."
if timeout 10m dnf install -y --skip-broken --disablerepo=* ./amd-smi-lib-*99999-local*.rpm; then
echo "Installation successful on attempt $i"
ln -s /opt/rocm/bin/amd-smi /usr/local/bin
echo 'Verifying installation:'
amd-smi version
python3 -m pip list | grep amd
python3 -m pip list | grep pip
python3 -m pip list | grep setuptools
echo 'Completed installation on RHEL10'
break
else
echo "Installation failed on attempt $i"
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES installation attempts failed. Exiting."
exit 1
fi
sleep $((2 * i))
fi
done
- name: Install AMDSMI
if: matrix.os != 'RHEL10' && matrix.os != 'AlmaLinux8'
run: |
cd $GITHUB_WORKSPACE/build
case ${{ env.PACKAGE_MANAGER }} in
zypper)
timeout 10m zypper --no-refresh --no-gpg-checks install -y ./amd-smi-lib-*99999-local*.rpm
;;
dnf)
dnf install python3-setuptools python3-wheel -y
RETRIES=3
for i in $(seq 1 $RETRIES); do
echo "Attempt $i: Installing AMDSMI package..."
if timeout 10m dnf install -y --skip-broken --disablerepo=* ./amd-smi-lib-*99999-local*.rpm; then
echo "AMDSMI package installed successfully."
break
else
echo "Installation failed on attempt $i. Retrying..."
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES attempts failed. Exiting."
exit 1
fi
sleep 10
fi
done
;;
esac
ln -s /opt/rocm/bin/amd-smi /usr/local/bin
# Verify Installation
echo 'Verifying installation:'
amd-smi version
python3 -m pip list | grep amd
python3 -m pip list | grep pip
python3 -m pip list | grep setuptools
echo 'Completed installation on ${{ matrix.os }}'
- name: Uninstall
if: always()
run: |
set -e
echo 'Uninstalling on ${{ matrix.os }}'
case ${{ matrix.os }} in
SLES)
zypper remove -y amd-smi-lib || true
;;
RHEL8|RHEL9|RHEL10|AlmaLinux8|AzureLinux3)
dnf remove -y amd-smi-lib || true
;;
esac
rm -f /usr/local/bin/amd-smi
if [ -d /opt/rocm/share/amd_smi ]; then
echo '/opt/rocm/share/amd_smi exists. Removing.'
rm -rf /opt/rocm/share/amd_smi
fi
echo 'Uninstall done on ${{ matrix.os }}'
rpm-test:
name: Tests
needs: [rpm-buildinstall, debian-test] # debian-test is needed to complete before rpm-test starts (see comment about driver reloads)
runs-on:
- self-hosted
- ${{ vars.RUNNER_TYPE }}
continue-on-error: true
strategy:
max-parallel: 10
matrix:
os:
- SLES
- RHEL8
- RHEL9
- RHEL10
- AzureLinux3
- AlmaLinux8
container:
image: ${{ vars[format('{0}_DOCKER_IMAGE', matrix.os)] }}
options: --rm --privileged --device=/dev/kfd --device=/dev/dri --group-add video --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --shm-size=64G --cap-add=SYS_MODULE -v /lib/modules:/lib/modules
steps:
- uses: actions/checkout@v4
- name: Set PkgMgr
run: |
set -e
case "${{ matrix.os }}" in
SLES)
echo "PACKAGE_MANAGER=zypper" >> $GITHUB_ENV
;;
RHEL8|RHEL9|RHEL10|AlmaLinux8|AzureLinux3)
echo "PACKAGE_MANAGER=dnf" >> $GITHUB_ENV
;;
esac
- name: Add more_itertools
if: matrix.os == 'AzureLinux3'
run: |
set -e
echo 'Installing more_itertools on ${{ matrix.os }}'
python3 -m pip install more_itertools
- name: Build and Install for Tests (RHEL10 & AlmaLinux8)
if: matrix.os == 'RHEL10' || matrix.os == 'AlmaLinux8'
run: |
set -e
echo 'Building for test on RHEL10/AlmaLinux8 with retries and QA_RPATHS'
BUILD_FOLDER=$GITHUB_WORKSPACE/build
RETRIES=5
# Set QA_RPATHS to ignore empty (0x0010 | 0x0002) RPATHs
export QA_RPATHS=$((0x0010 | 0x0002))
for i in $(seq 1 $RETRIES); do
echo "Build attempt $i for RHEL10/AlmaLinux8 test..."
rm -rf $BUILD_FOLDER
mkdir -p $BUILD_FOLDER
cd $BUILD_FOLDER
if cmake $GITHUB_WORKSPACE -DBUILD_TESTS=ON -DENABLE_ESMI_LIB=ON && \
make -j $(nproc) && \
make package; then
echo "Build successful on attempt $i"
break
else
echo "Build failed on attempt $i"
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES build attempts failed. Exiting."
exit 1
fi
sleep $((2 * i))
fi
done
echo 'Installing for test on RHEL10/AlmaLinux8'
dnf install python3-setuptools python3-wheel -y
for i in $(seq 1 $RETRIES); do
echo "RHEL10/AlmaLinux8: Installation attempt $i for test..."
if timeout 10m dnf install -y --skip-broken --disablerepo=* $BUILD_FOLDER/amd-smi-lib-*99999-local*.rpm; then
echo "Installation successful on attempt $i"
ln -s /opt/rocm/bin/amd-smi /usr/local/bin
echo 'Install done for test on RHEL10/AlmaLinux8'
break
else
echo "Installation failed on attempt $i"
if [ $i -eq $RETRIES ]; then
echo "All $RETRIES installation attempts failed. Exiting."
exit 1
fi
sleep $((2 * i))
fi
done
- name: Build and Install for Tests
if: matrix.os != 'RHEL10' && matrix.os != 'AlmaLinux8'
run: |
set -e
echo 'Building for test on ${{ matrix.os }}'
BUILD_FOLDER=$GITHUB_WORKSPACE/build
rm -rf $BUILD_FOLDER
mkdir -p $BUILD_FOLDER
cd $BUILD_FOLDER
cmake $GITHUB_WORKSPACE -DBUILD_TESTS=ON -DENABLE_ESMI_LIB=ON
make -j $(nproc)
make package
echo 'Installing for test on ${{ matrix.os }}'
case ${{ env.PACKAGE_MANAGER }} in
zypper)
timeout 10m zypper --no-refresh --no-gpg-checks install -y $BUILD_FOLDER/amd-smi-lib-*99999-local*.rpm
;;
dnf)
dnf install python3-setuptools python3-wheel -y
RETRIES=3
for i in $(seq 1 $RETRIES); do
echo "Attempt $i: Installing..."
if timeout 10m dnf install -y --skip-broken --disablerepo=* $BUILD_FOLDER/amd-smi-lib-*99999-local*.rpm; then
echo "Install successful."
break
else
echo "Attempt $i failed. Retrying..."
if [ $i -eq $RETRIES ]; then
echo "All attempts failed."
exit 1
fi
sleep 10
fi
done
;;
esac
ln -s /opt/rocm/bin/amd-smi /usr/local/bin
echo 'Install done for test on ${{ matrix.os }}'
- name: AMDSMI Command Tests
shell: bash
run: |
set -e
echo "Running AMDSMI commands on ${{ matrix.os }}"
mkdir -p /tmp/test-results-${{ matrix.os }}
commands=(
"amd-smi version"
"amd-smi list"
"amd-smi static"
"amd-smi firmware"
"amd-smi ucode"
"amd-smi bad-pages"
"amd-smi metric"
"amd-smi process"
"amd-smi topology"
"amd-smi monitor"
"amd-smi dmon"
"amd-smi xgmi"
"amd-smi partition"
)
for cmd in "${commands[@]}"; do
debug_cmd="$cmd --loglevel debug"
echo "Running: $debug_cmd"
if ! eval "$debug_cmd" > /tmp/test-results-${{ matrix.os }}/$(echo $cmd | tr ' ' '_').log 2>&1; then
echo "Command '$debug_cmd' failed."
cat /tmp/test-results-${{ matrix.os }}/$(echo $cmd | tr ' ' '_').log
exit 1
else
echo "$debug_cmd passed."
fi
done
echo "AMDSMI commands done on ${{ matrix.os }}"
- name: Upload AMDSMI Command Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: amdsmi-command-tests-${{ matrix.os }}
path: /tmp/test-results-${{ matrix.os }}
- name: Run AMDSMI, Python, and Example Tests
shell: bash
run: |
set -e
echo 'Running other tests on ${{ matrix.os }}'
# AMDSMI Tests
echo 'Running AMDSMI tests'
cd /opt/rocm/share/amd_smi/tests
source amdsmitst.exclude
AMDSMI_RETRIES=3
for attempt in $(seq 1 $AMDSMI_RETRIES); do
echo "AMDSMI test attempt $attempt for ${{ matrix.os }}..."
if ./amdsmitst --gtest_filter="-$(echo ${BLACKLIST_ALL_ASICS})" > /tmp/test-results-${{ matrix.os }}/amdsmi_tests.log 2>&1; then
echo "AMDSMI tests passed on attempt $attempt"
echo "=============== TEST OUTPUT ==============="
cat /tmp/test-results-${{ matrix.os }}/amdsmi_tests.log | grep -E "\[==========\]|\[ PASSED \]|\[ SKIPPED \]|\[ FAILED \]"
echo "=============================================="
echo "AMDSMI tests done"
break
else
TEST_EXIT_CODE=$?
echo "AMDSMI tests failed on attempt $attempt with exit code $TEST_EXIT_CODE"
if [ $attempt -eq $AMDSMI_RETRIES ]; then
echo "All $AMDSMI_RETRIES AMDSMI test attempts failed. Final failure."
echo "=============== TEST OUTPUT ==============="
cat /tmp/test-results-${{ matrix.os }}/amdsmi_tests.log | grep -E "\[==========\]|\[ PASSED \]|\[ SKIPPED \]|\[ FAILED \]"
echo "=============================================="
echo "AMDSMI tests failed"
exit $TEST_EXIT_CODE
else
echo "Retrying AMDSMI tests in $((2 * attempt)) seconds..."
sleep $((2 * attempt))
fi
fi
done
# Python Tests
echo 'Running Python tests'
cd /opt/rocm/share/amd_smi/tests/python_unittest
echo "Running integration tests..."
if ! ./integration_test.py -v > /tmp/test-results-${{ matrix.os }}/integration_test_output.txt 2>&1; then
echo "Integration tests failed!"
echo "=============== INTEGRATION TEST OUTPUT ==============="
tail -100 /tmp/test-results-${{ matrix.os }}/integration_test_output.txt
echo "======================================================="
exit 1
else
echo "Integration tests passed"
fi
echo "Running unit tests..."
if ! ./unit_tests.py -v > /tmp/test-results-${{ matrix.os }}/unit_test_output.txt 2>&1; then
echo "Unit tests failed!"
echo "=============== UNIT TEST OUTPUT ==============="
tail -100 /tmp/test-results-${{ matrix.os }}/unit_test_output.txt
echo "================================================"
exit 1
else
echo "Unit tests passed"
fi
echo "Python tests done"
# Example Tests
echo 'Running Example tests'
cd $GITHUB_WORKSPACE/example
rm -rf build
cmake -B build -DENABLE_ESMI_LIB=OFF
make -C build -j $(nproc)
cd build
./amd_smi_drm_ex > /tmp/test-results-${{ matrix.os }}/amd_smi_drm_ex.log 2>&1 || echo 'amd_smi_drm_ex failed'
./amd_smi_nodrm_ex > /tmp/test-results-${{ matrix.os }}/amd_smi_nodrm_ex.log 2>&1 || echo 'amd_smi_nodrm_ex failed'
echo "Example tests done"
- name: AMDSMI Test Results
if: always()
run: |
echo "Displaying AMDSMI test results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/amdsmi_tests.log || echo "No AMDSMI test results found for ${{ matrix.os }}"
- name: Integration Test Results
if: always()
run: |
echo "Displaying Integration test results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/integration_test_output.txt || echo "No integration test results found for ${{ matrix.os }}"
- name: Unit Test Results
if: always()
run: |
echo "Displaying Unit Test Results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/unit_test_output.txt || echo "No unit test results found for ${{ matrix.os }}"
- name: Example DRM Test Results
if: always()
run: |
echo "Displaying Example DRM test results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/amd_smi_drm_ex.log || echo "No DRM example test results found for ${{ matrix.os }}"
- name: Example NoDRM Test Results
if: always()
run: |
echo "Displaying Example NoDRM test results for ${{ matrix.os }}"
cat /tmp/test-results-${{ matrix.os }}/amd_smi_nodrm_ex.log || echo "No NoDRM example test results found for ${{ matrix.os }}"
+319
View File
@@ -0,0 +1,319 @@
name: Auto Label PRs
on:
pull_request:
types: [opened, synchronize, reopened, closed]
workflow_run:
workflows: ["ABI Compliance Check"]
types: [completed]
jobs:
apply-labels:
runs-on: AMD-ROCm-Internal-dev1
permissions:
pull-requests: write
actions: read
contents: read
steps:
- name: Add/Remove labels based on branch names and ABI results
uses: actions/github-script@v6
with:
script: |
const pr = context.payload.pull_request;
let prNumber, headSha, baseBranch, headBranch;
// Handle different event types
if (context.eventName === 'pull_request') {
prNumber = pr.number;
headSha = pr.head.sha;
baseBranch = pr.base.ref;
headBranch = pr.head.ref;
} else if (context.eventName === 'workflow_run') {
// Find the associated PR for workflow_run events
const workflowRun = context.payload.workflow_run;
console.log(`Workflow run completed: ${workflowRun.name} with conclusion: ${workflowRun.conclusion}`);
if (workflowRun.event !== 'pull_request') {
console.log('Workflow run was not triggered by a pull request, skipping');
return;
}
const prs = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${context.repo.owner}:${workflowRun.head_branch}`
});
const associatedPr = prs.data.find(p => p.head.sha === workflowRun.head_sha);
if (!associatedPr) {
console.log('No associated PR found for this workflow run');
return;
}
prNumber = associatedPr.number;
headSha = associatedPr.head.sha;
baseBranch = associatedPr.base.ref;
headBranch = associatedPr.head.ref;
} else {
console.log('Unsupported event type');
return;
}
let labelsApplied = false;
// Debug information
console.log(`Processing PR #${prNumber}: Head: ${headBranch}, Base: ${baseBranch}`);
// Get current PR data to check existing labels
const { data: currentPr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
const existingLabels = currentPr.labels.map(label => label.name);
// Condition 1: PR targeting amd-mainline
if (baseBranch === 'amd-mainline' && context.eventName === 'pull_request') {
const labelToAdd = 'Merge amd-mainline';
try {
if (!existingLabels.includes(labelToAdd)) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: [labelToAdd]
});
console.log(`Added label "${labelToAdd}" to PR #${prNumber}`);
labelsApplied = true;
}
} catch (error) {
console.error(`Error adding label "${labelToAdd}": ${error.message}`);
}
}
// Condition 2: Cherry-pick based on head branch name or release target
if (context.eventName === 'pull_request') {
const isCherryPickHead = /cherry.*pick/i.test(headBranch);
const isReleaseTargetBase = baseBranch.startsWith('release/');
if (isCherryPickHead || isReleaseTargetBase) {
const labelToAdd = 'cherry-pick';
try {
if (!existingLabels.includes(labelToAdd)) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: [labelToAdd]
});
console.log(`Added label "${labelToAdd}" to PR #${prNumber}`);
labelsApplied = true;
} else {
console.log(`Label "${labelToAdd}" already exists on PR #${prNumber}`);
}
} catch (error) {
console.error(`Error adding label "${labelToAdd}": ${error.message}`);
}
}
}
// ABI BREAKAGE LOGIC: Check on both workflow_run AND pull_request events
let shouldCheckABI = false;
let hasMajorAbiBreakage = false;
let hasMinorAbiBreakage = false;
if (context.eventName === 'workflow_run') {
// Handle workflow_run events (existing logic)
const workflowRun = context.payload.workflow_run;
if (workflowRun.name === 'ABI Compliance Check') {
shouldCheckABI = true;
console.log(`ABI Compliance Check completed with conclusion: ${workflowRun.conclusion}`);
try {
const { data: jobs } = await github.rest.actions.listJobsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: workflowRun.id
});
// Check job conclusions for ABI breakage
for (const job of jobs.jobs) {
console.log(`Job: ${job.name}, Conclusion: ${job.conclusion}`);
if (job.name.includes('Major ABI') && job.conclusion === 'failure') {
hasMajorAbiBreakage = true;
console.log('Major ABI breakage detected from job failure');
}
if (job.name.includes('Minor ABI') && job.conclusion === 'failure') {
hasMinorAbiBreakage = true;
console.log('Minor ABI breakage detected from job failure');
}
}
// If workflow succeeded, no ABI breakage
if (workflowRun.conclusion === 'success') {
console.log('ABI Compliance Check succeeded - no ABI breakage');
hasMajorAbiBreakage = false;
hasMinorAbiBreakage = false;
}
} catch (error) {
console.log(`Could not fetch job details: ${error.message}`);
return;
}
}
} else if (context.eventName === 'pull_request') {
// NEW: Check if amdsmi.h has been reverted on PR events
const hasAbiLabels = existingLabels.includes('MAJOR ABI BREAKAGE') || existingLabels.includes('MINOR ABI BREAKAGE');
if (hasAbiLabels) {
console.log('PR has ABI labels, checking if amdsmi.h changes were reverted...');
shouldCheckABI = true;
try {
// Get the diff for amdsmi.h between base and head
const { data: comparison } = await github.rest.repos.compareCommits({
owner: context.repo.owner,
repo: context.repo.repo,
base: currentPr.base.sha,
head: currentPr.head.sha
});
// Check if amdsmi.h has any changes
const amdsmiFile = comparison.files?.find(file => file.filename === 'include/amd_smi/amdsmi.h');
if (!amdsmiFile) {
console.log('No changes to amdsmi.h found in this PR - removing ABI labels');
hasMajorAbiBreakage = false;
hasMinorAbiBreakage = false;
} else if (amdsmiFile.changes === 0) {
console.log('amdsmi.h file exists but has no changes - removing ABI labels');
hasMajorAbiBreakage = false;
hasMinorAbiBreakage = false;
} else {
console.log(`amdsmi.h has ${amdsmiFile.changes} changes - keeping existing ABI labels`);
// Keep existing labels since we can't determine ABI status without running the check
hasMajorAbiBreakage = existingLabels.includes('MAJOR ABI BREAKAGE');
hasMinorAbiBreakage = existingLabels.includes('MINOR ABI BREAKAGE');
}
} catch (error) {
console.log(`Error checking file changes: ${error.message}`);
// If we can't check, preserve existing labels
hasMajorAbiBreakage = existingLabels.includes('MAJOR ABI BREAKAGE');
hasMinorAbiBreakage = existingLabels.includes('MINOR ABI BREAKAGE');
}
}
}
// Manage ABI breakage labels (only if we determined ABI status)
if (shouldCheckABI) {
const abiLabels = {
'MAJOR ABI BREAKAGE': hasMajorAbiBreakage,
'MINOR ABI BREAKAGE': hasMinorAbiBreakage
};
const wasMajorAbiBreakage = existingLabels.includes('MAJOR ABI BREAKAGE');
const wasMinorAbiBreakage = existingLabels.includes('MINOR ABI BREAKAGE');
for (const [labelName, shouldHaveLabel] of Object.entries(abiLabels)) {
const hasLabel = existingLabels.includes(labelName);
if (shouldHaveLabel && !hasLabel) {
// Add label
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: [labelName]
});
console.log(`✅ Added label "${labelName}" to PR #${prNumber}`);
labelsApplied = true;
} catch (error) {
console.error(`❌ Error adding label "${labelName}": ${error.message}`);
}
} else if (!shouldHaveLabel && hasLabel) {
// Remove label
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
name: labelName
});
console.log(`🗑️ Removed label "${labelName}" from PR #${prNumber}`);
labelsApplied = true;
} catch (error) {
console.error(`❌ Error removing label "${labelName}": ${error.message}`);
}
}
}
// Add comments when ABI issues are detected or resolved
if (context.eventName === 'workflow_run') {
// Only add comments for workflow_run events (actual ABI check results)
if (hasMajorAbiBreakage && !wasMajorAbiBreakage) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: '⚠️ **MAJOR ABI BREAKAGE detected** in the latest ABI compliance check. Please review the ABI compliance report and fix any breaking changes.'
});
}
if (hasMinorAbiBreakage && !wasMinorAbiBreakage) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: '⚠️ **MINOR ABI BREAKAGE detected** in the latest ABI compliance check. Please review the ABI compliance report for details.'
});
}
if (!hasMajorAbiBreakage && wasMajorAbiBreakage) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: '✅ **MAJOR ABI BREAKAGE resolved** - ABI compliance check is now passing!'
});
}
if (!hasMinorAbiBreakage && wasMinorAbiBreakage) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: '✅ **MINOR ABI BREAKAGE resolved** - ABI compliance check is now passing!'
});
}
} else if (context.eventName === 'pull_request') {
// Add comment when labels are removed due to file reversion
if (!hasMajorAbiBreakage && wasMajorAbiBreakage) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: '✅ **MAJOR ABI BREAKAGE resolved** - `amdsmi.h` changes have been reverted.'
});
}
if (!hasMinorAbiBreakage && wasMinorAbiBreakage) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: '✅ **MINOR ABI BREAKAGE resolved** - `amdsmi.h` changes have been reverted.'
});
}
}
}
if (!labelsApplied && context.eventName === 'pull_request') {
console.log(`PR #${prNumber} did not match criteria for automatic labeling by this workflow.`);
}
+99
View File
@@ -0,0 +1,99 @@
# caution: most of this file was written using Claude 3.7 Sonnet
name: CMake Format Check
on:
push:
branches: [ amd-staging ]
paths:
- '**/*.cmake'
- '**/CMakeLists.txt'
- '**/*.cmake.in'
pull_request:
branches: [ amd-staging ]
paths:
- '**/*.cmake'
- '**/CMakeLists.txt'
- '**/*.cmake.in'
workflow_dispatch: # Allows manual triggering
defaults:
run:
shell: bash
jobs:
check-cmake-format:
name: Check CMake files formatting
runs-on: self-hosted
container: catthehacker/ubuntu:act-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for better diff context
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: 'pip'
- name: Install cmake-format
run: |
python -m pip install --upgrade pip
pip install cmake-format==0.6.13
- name: Check CMake formatting
id: check-format
run: |
echo "::group::Finding CMake files"
FILES=$(find . -type f \( -name "CMakeLists.txt" -o -name "*.cmake" -o -name "*.cmake.in" \) \
-not -path "*/esmi_ib_library/*" \
-not -path "*/\.*" \
-not -path "*/build/*")
echo "Found $(echo "$FILES" | wc -l) CMake files to check"
echo "::endgroup::"
# Create an array to store failed files
declare -a failed_files
# Check if files are formatted correctly
for file in $FILES; do
echo "Checking $file..."
if ! cmake-format --check "$file"; then
failed_files+=("$file")
echo "::error file=$file::File needs formatting"
fi
done
# Generate report and exit with error if any files failed
if [ ${#failed_files[@]} -ne 0 ]; then
echo "Failed files: ${failed_files[*]}"
echo "FAILED_FILES=${failed_files[*]}" >> $GITHUB_ENV
exit 1
else
echo "All CMake files are formatted correctly!"
fi
- name: Generate diff for failed files
if: failure() && env.FAILED_FILES != ''
run: |
echo "## CMake Format Check Failed" >> $GITHUB_STEP_SUMMARY
echo "The following files need formatting:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
for file in ${FAILED_FILES}; do
echo "### $file" >> $GITHUB_STEP_SUMMARY
done
cat << 'EOF' >> $GITHUB_STEP_SUMMARY
### How to fix
Run this command locally to fix formatting issues:
```bash
# Install cmake-format
pip install cmake-format==0.6.13
# Format files
cmake-format -i <file>
```
EOF
+92
View File
@@ -0,0 +1,92 @@
name: "CodeQL Advanced"
on:
pull_request:
branches:
- amd-staging
push:
branches:
- amd-staging
schedule:
- cron: '34 18 * * 5'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: c-cpp
build-mode: manual
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12.6'
- name: Install CMake
run: python3 -m pip install cmake
- name: Install Virtualenv
run: python3 -m pip install virtualenv
- name: Install g++
run: sudo apt-get install -y g++
- name: Install libdrm
run: sudo apt-get install -y libdrm-dev
- name: Install DOxygen
run: sudo apt-get install -y doxygen
- name: Install LaTeX
run: sudo apt-get install -y texlive
- name: Clean old ROCm directories
run: |
sudo rm -rf /opt/rocm
sudo rm -rf /opt/rocm-*
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
queries: security-extended
- name: Create build directory
run: mkdir -p build
- name: Build AMD SMI Library
run: |
cd build
cmake ..
make -j $(nproc)
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
+83
View File
@@ -0,0 +1,83 @@
name: Generate Documentation
on:
pull_request:
branches: [amd-staging, amd-mainline, release/rocm-rel-*]
push:
branches: [amd-staging, amd-mainline, release/rocm-rel-*]
workflow_dispatch:
permissions:
contents: read
env:
DEBIAN_FRONTEND: noninteractive
DEBCONF_NONINTERACTIVE_SEEN: true
BUILD_TYPE: Release
jobs:
generate-docs:
name: Generate Documentation
runs-on: AMD-ROCm-Internal-dev1
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Get branch name for artifact naming
id: get_branch_info
run: |
BRANCH_NAME=""
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
BRANCH_NAME="${{ github.head_ref }}"
else
BRANCH_NAME="${{ github.ref_name }}"
fi
SANITIZED_NAME=$(echo "$BRANCH_NAME" | sed -e 's|/|-|g' -e 's|[^a-zA-Z0-9._-]||g' -e 's|^-*||' -e 's|-*$||')
if [[ -z "$SANITIZED_NAME" ]]; then
SANITIZED_NAME="docs-$(date +%s)"
fi
echo "sanitized_name=${SANITIZED_NAME}" >> $GITHUB_OUTPUT
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install System Dependencies
run: |
sudo apt-get update
sudo apt-get install -y doxygen graphviz
- name: Set Up Python Environment
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r docs/sphinx/requirements.txt
- name: Build Documentation
run: |
if [ ! -e "docs/.git" ]; then
if [ -d ".git" ]; then
ln -s ../.git docs/.git
fi
fi
cd docs
python3 -m sphinx -T -E -b html -d _build/doctrees -D language=en . _build/html
- name: Upload Documentation
uses: actions/upload-artifact@v4
with:
name: documentation-${{ steps.get_branch_info.outputs.sanitized_name }}
path: docs/_build/html/
- name: Generate Job Summary
run: |
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
# 📚 Documentation Generated Successfully!
## 🚀 Quick Start
1. **📥 Download** the artifact `documentation-${{ steps.get_branch_info.outputs.sanitized_name }}`
2. **📂 Extract** the ZIP file
3. **🖱️ Double-click** `index.html`
4. **✅ Done!** Documentation opens with full formatting in your browser
EOF
+83
View File
@@ -0,0 +1,83 @@
name: GitHub to Gerrit Mirror
run-name: "Mirror to Gerrit: ${{ github.event.ref || inputs.branch }} ${{ github.event.after }}"
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to mirror (amd-staging or amd-mainline)'
required: true
default: 'amd-staging'
type: choice
options:
- amd-staging
- amd-mainline
pull_request:
branches:
- amd-staging
- amd-mainline
types: [closed]
env:
GERRIT_SERVER: "gerrit-git.amd.com"
GERRIT_PROJECT: "SYS-MGMT/ec/amd-smi"
GERRIT_USER: "z1_runner"
GERRIT_PORT: "29418"
jobs:
Setup:
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true
runs-on: banff-sc-cx43-29
steps:
- name: Fix workspace permissions
run: |
sudo chown -R $(id -u):$(id -g) ${{ github.workspace }}
sudo chmod -R u+rwX ${{ github.workspace }}
- name: Check out repository code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create SSH key
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/known_hosts
touch ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
printf "%s" "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
ssh-keyscan -p ${{ env.GERRIT_PORT }} ${{ env.GERRIT_SERVER }} >> ~/.ssh/known_hosts
- name: Debug SSH setup
run: |
ls -la ~/.ssh
ssh -p ${{ env.GERRIT_PORT }} ${{ env.GERRIT_USER }}@${{ env.GERRIT_SERVER }} || true
- name: Set Gerrit remote
run: |
cd ${{ github.workspace }}
if git remote | grep -q "gerrit"
then
git remote set-url gerrit ssh://${{ env.GERRIT_USER }}@${{ env.GERRIT_SERVER }}:${{ env.GERRIT_PORT }}/${{ env.GERRIT_PROJECT }}
else
git remote add gerrit ssh://${{ env.GERRIT_USER }}@${{ env.GERRIT_SERVER }}:${{ env.GERRIT_PORT }}/${{ env.GERRIT_PROJECT }}
fi
- name: Set committer identity for Gerrit
run: |
git config user.name "z1_runner"
git config user.email "z1_runner@amd.com"
- name: Fetch selected branch
run: |
BRANCH="${{ github.event.pull_request.base.ref || inputs.branch }}"
git fetch origin ${BRANCH}:refs/remotes/origin/${BRANCH}
git checkout ${BRANCH}
- name: Mirror selected branch to Gerrit
run: |
BRANCH="${{ github.event.pull_request.base.ref || inputs.branch }}"
git push gerrit refs/heads/${BRANCH}:refs/heads/${BRANCH}
+15
View File
@@ -0,0 +1,15 @@
name: Rocm Validation Suite KWS
on:
push:
branches: [amd-staging, amd-mainline]
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
jobs:
kws:
if: ${{ github.event_name == 'pull_request' }}
uses: AMD-ROCm-Internal/rocm_ci_infra/.github/workflows/kws.yml@mainline
secrets: inherit
with:
pr_number: ${{github.event.pull_request.number}}
base_branch: ${{github.base_ref}}
+25
View File
@@ -0,0 +1,25 @@
name: ROCm CI Caller
on:
pull_request:
branches: [amd-staging, release/rocm-rel-*, amd-mainline]
types: [opened, reopened, synchronize]
push:
branches: [amd-mainline]
workflow_dispatch:
issue_comment:
types: [created]
jobs:
call-workflow:
if: github.event_name != 'issue_comment' ||(github.event_name == 'issue_comment' && github.event.issue.pull_request && (startsWith(github.event.comment.body, '!verify') || startsWith(github.event.comment.body, '!verify release') || startsWith(github.event.comment.body, '!verify retest')))
uses: AMD-ROCm-Internal/rocm_ci_infra/.github/workflows/rocm_ci.yml@mainline
secrets: inherit
with:
input_sha: ${{github.event_name == 'pull_request' && github.event.pull_request.head.sha || (github.event_name == 'push' && github.sha) || (github.event_name == 'issue_comment' && github.event.issue.pull_request.head.sha) || github.sha}}
input_pr_num: ${{github.event_name == 'pull_request' && github.event.pull_request.number || (github.event_name == 'issue_comment' && github.event.issue.number) || 0}}
input_pr_url: ${{github.event_name == 'pull_request' && github.event.pull_request.html_url || (github.event_name == 'issue_comment' && github.event.issue.pull_request.html_url) || ''}}
input_pr_title: ${{github.event_name == 'pull_request' && github.event.pull_request.title || (github.event_name == 'issue_comment' && github.event.issue.pull_request.title) || ''}}
repository_name: ${{ github.repository }}
base_ref: ${{github.event_name == 'pull_request' && github.event.pull_request.base.ref || (github.event_name == 'issue_comment' && github.event.issue.pull_request.base.ref) || github.ref}}
trigger_event_type: ${{ github.event_name }}
comment_text: ${{ github.event_name == 'issue_comment' && github.event.comment.body || '' }}