Add 'projects/rdc/' from commit '5ae7eeb3550d4cb14cbc31d3022e545b054f1ad1'
git-subtree-dir: projects/rdc git-subtree-mainline:a68afa42a1git-subtree-split:5ae7eeb355
@@ -0,0 +1,40 @@
|
||||
resources:
|
||||
repositories:
|
||||
- repository: pipelines_repo
|
||||
type: github
|
||||
endpoint: ROCm
|
||||
name: ROCm/ROCm
|
||||
|
||||
variables:
|
||||
- group: common
|
||||
- template: /.azuredevops/variables-global.yml@pipelines_repo
|
||||
|
||||
trigger:
|
||||
batch: true
|
||||
branches:
|
||||
include:
|
||||
- amd-staging
|
||||
paths:
|
||||
exclude:
|
||||
- .github
|
||||
- docs
|
||||
- '.*.y*ml'
|
||||
- '*.md'
|
||||
- LICENSE
|
||||
|
||||
pr:
|
||||
autoCancel: true
|
||||
branches:
|
||||
include:
|
||||
- amd-staging
|
||||
paths:
|
||||
exclude:
|
||||
- .github
|
||||
- docs
|
||||
- '.*.y*ml'
|
||||
- '*.md'
|
||||
- LICENSE
|
||||
drafts: false
|
||||
|
||||
jobs:
|
||||
- template: ${{ variables.CI_COMPONENT_PATH }}/rdc.yml@pipelines_repo
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: Google
|
||||
ColumnLimit: 100
|
||||
|
||||
# Force pointers to the type for C++.
|
||||
# For some reason Google style doesn't specify this..
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
@@ -0,0 +1,22 @@
|
||||
# EditorConfig standardizes spacing in all editors: https://EditorConfig.org
|
||||
# Please get a plugin for your editor to match the formatting
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Matches multiple files with brace expansion notation
|
||||
# Set default charset
|
||||
[*.{c,cc,cpp,h,hh,hpp}]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.py]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.proto]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/BlankSpruce/gersemi/0.20.1/gersemi/configuration.schema.json
|
||||
|
||||
warn_about_unknown_commands: false
|
||||
indent: 4
|
||||
line_length: 100
|
||||
@@ -0,0 +1,4 @@
|
||||
# ignore formatting commit
|
||||
434e40305d6771040caec164b6b1369cc0ef51ad
|
||||
# ignore cmake formatting commit (gersemi rocks)
|
||||
40545dcb49ebcfa0a6fe040a8862cf8b338ad6b5
|
||||
@@ -0,0 +1,5 @@
|
||||
* @dmitrii-galantsev @bill-shuzhou-liu
|
||||
|
||||
docs/* @ROCm/rocm-documentation
|
||||
*.md @ROCm/rocm-documentation
|
||||
*.rst @ROCm/rocm-documentation
|
||||
@@ -0,0 +1,114 @@
|
||||
# Contributing to RDC #
|
||||
|
||||
We welcome contributions to RDC. 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 your amdgpu driver version, GPUs used, and commands ran. 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 RDC project is to provide a remote control tool with optional
|
||||
modules.
|
||||
|
||||
Contributors wanting to submit additional plugins must follow the guidelines
|
||||
below.
|
||||
|
||||
* New modules/
|
||||
* Modules must be loaded at runtime with a `dlopen` call.
|
||||
* Modules must have an option to disable them in CMake.
|
||||
|
||||
## Code Structure ##
|
||||
|
||||
Modules:
|
||||
|
||||
└── rdc_libs
|
||||
└── rdc_modules
|
||||
|
||||
Module interfaces: (see RdcRasLib.h for example)
|
||||
|
||||
└── include
|
||||
└── rdc_lib
|
||||
└── impl
|
||||
|
||||
Client executable (rdci) source:
|
||||
|
||||
└── rdci
|
||||
|
||||
Server executable (rdcd) source:
|
||||
|
||||
└── server
|
||||
|
||||
Protos for protobuf and gRPC:
|
||||
|
||||
└── protos
|
||||
└── rdc.proto
|
||||
|
||||
## 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 **develop** branch, which serves as our
|
||||
integration branch.
|
||||
|
||||
### Deliverables ###
|
||||
|
||||
For each new file in repository,
|
||||
Please include the licensing header
|
||||
|
||||
/*
|
||||
Copyright (c) 20xx - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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
|
||||
|
||||
RDC 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 RDC. 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)
|
||||
@@ -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: "monthly"
|
||||
labels:
|
||||
- "documentation"
|
||||
- "dependencies"
|
||||
- "ci:docs-only"
|
||||
reviewers:
|
||||
- "samjwu"
|
||||
@@ -0,0 +1,5 @@
|
||||
disabled: false
|
||||
scmId: gh-emu-rocm
|
||||
branchesToScan:
|
||||
- amd-staging
|
||||
- amd-mainline
|
||||
@@ -0,0 +1,97 @@
|
||||
# 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'
|
||||
pull_request:
|
||||
branches: [ amd-staging ]
|
||||
paths:
|
||||
- '**/*.cmake'
|
||||
- '**/CMakeLists.txt'
|
||||
workflow_dispatch: # Allows manual triggering
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
check-gersemi:
|
||||
name: Check CMake files formatting
|
||||
runs-on: lstt
|
||||
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 gersemi
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install gersemi==0.20.1
|
||||
|
||||
- name: Check CMake formatting
|
||||
id: check-format
|
||||
run: |
|
||||
echo "::group::Finding CMake files"
|
||||
FILES=$(find . -type f \( -name "CMakeLists.txt" -o -name "*.cmake" \) \
|
||||
-not -name "*.in" \
|
||||
-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 ! gersemi --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 gersemi
|
||||
pip install gersemi==0.20.1
|
||||
|
||||
# Format files
|
||||
gersemi -i <file>
|
||||
```
|
||||
EOF
|
||||
@@ -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}}
|
||||
@@ -0,0 +1,47 @@
|
||||
# caution: this whole file was written using Claude 3.7 Sonnet
|
||||
name: Auto Label Cherry-Pick
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
add-label:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: node:16-alpine
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Add label to cherry-pick PRs
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const pr = context.payload.pull_request;
|
||||
const headBranch = pr.head.ref;
|
||||
const baseBranch = pr.base.ref;
|
||||
|
||||
// Check if head branch contains cherry-pick pattern or base branch starts with release/
|
||||
const isCherryPick = /cherry.*pick/i.test(headBranch);
|
||||
const isReleaseTarget = baseBranch.startsWith('release/');
|
||||
|
||||
if (isCherryPick || isReleaseTarget) {
|
||||
// Label to apply
|
||||
const labelToAdd = 'cherry-pick';
|
||||
|
||||
// Try to add the label
|
||||
try {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
labels: [labelToAdd]
|
||||
});
|
||||
console.log(`Added label "${labelToAdd}" to PR #${pr.number}`);
|
||||
} catch (error) {
|
||||
console.error(`Error adding label: ${error.message}`);
|
||||
}
|
||||
} else {
|
||||
console.log('PR does not match criteria for automatic labeling');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
name: Build RDC
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ 'dgalants/ci', 'amd-staging', 'amd-mainline' ]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
DEBCONF_NONINTERACTIVE_SEEN: true
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: RelWithDebInfo
|
||||
ROCM_DIR: /opt/rocm
|
||||
# Use vars for internal URLs
|
||||
JOB_NAME: ${{ vars.JOB_NAME }}
|
||||
AMDGPU_REPO_DEB: ${{ vars.AMDGPU_REPO_DEB }}
|
||||
AMDGPU_REPO_URL: ${{ vars.AMDGPU_REPO_URL }}
|
||||
ROCM_CI_URL: ${{ vars.ROCM_CI_URL }}
|
||||
# Set env vars to values of config vars
|
||||
env_var: ${{ vars.ENV_CONTEXT_VAR }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: lstt
|
||||
container: rocm/rocm-build-ubuntu-22.04:6.3
|
||||
outputs:
|
||||
BUILD_NUM: ${{ steps.build_number.outputs.BUILD_NUM }}
|
||||
TODAY: ${{ steps.build_number.outputs.TODAY }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up apt repos
|
||||
run: |
|
||||
test "$AMDGPU_REPO_URL" = "" && echo "Error! AMDGPU_REPO_URL is EMPTY!" && exit 1
|
||||
cat /etc/os-release
|
||||
apt update -y
|
||||
# provides add-apt-repository and support for caching actions
|
||||
apt install -y software-properties-common jq curl
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||
apt install -y nodejs
|
||||
add-apt-repository -y ppa:apt-fast/stable
|
||||
apt update -y
|
||||
apt install -y apt-fast
|
||||
# provides amdgpu-repo
|
||||
wget "$AMDGPU_REPO_URL/$AMDGPU_REPO_DEB"
|
||||
apt-fast install -y "./$AMDGPU_REPO_DEB"
|
||||
|
||||
- name: Get latest build number
|
||||
id: build_number
|
||||
run: |
|
||||
curl -Ls "${ROCM_CI_URL}/${JOB_NAME}/lastStableBuild/api/json?depth=1" -o /tmp/build_info.json
|
||||
cat /tmp/build_info.json | jq '.actions[] | .buildsByBranchName."refs/remotes/origin/amd-mainline".buildNumber | select(. != null)' > /tmp/build_num.txt
|
||||
BUILD_NUM="$(cat /tmp/build_num.txt)"
|
||||
echo "BUILD_NUM=$BUILD_NUM" >> "$GITHUB_ENV"
|
||||
echo "BUILD_NUM=$BUILD_NUM" >> "$GITHUB_OUTPUT"
|
||||
amdgpu-repo --rocm-build="$JOB_NAME"/"$BUILD_NUM"
|
||||
apt-fast update -y
|
||||
# useful for date-based caches
|
||||
TODAY="$(date +%Y_%m_%d)"
|
||||
echo "TODAY=$TODAY" >> "$GITHUB_ENV"
|
||||
echo "TODAY=$TODAY" >> "$GITHUB_OUTPUT"
|
||||
|
||||
|
||||
- name: Get apt packages
|
||||
run: |
|
||||
apt install -y \
|
||||
rocm-core \
|
||||
amd-smi-lib \
|
||||
rocblas \
|
||||
rocblas-dev \
|
||||
rocm-developer-tools \
|
||||
rocm-device-libs \
|
||||
rocm-smi-lib \
|
||||
rocm-validation-suite \
|
||||
rocprofiler-dev \
|
||||
rocprofiler-plugins \
|
||||
rocprofiler-register \
|
||||
rocprofiler-sdk \
|
||||
hip-dev \
|
||||
hip-runtime-amd \
|
||||
hipcc \
|
||||
build-essential \
|
||||
ccache \
|
||||
cmake \
|
||||
curl \
|
||||
git \
|
||||
gzip \
|
||||
jq \
|
||||
libcap-dev \
|
||||
tar \
|
||||
unzip \
|
||||
wget \
|
||||
zip \
|
||||
zstd
|
||||
|
||||
- name: Cache .ccache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/ccache
|
||||
# only create one cache per day to save time during upload
|
||||
key: ${{ runner.os }}-ccache-${{ github.ref_name }}-${{ env.TODAY }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-ccache-${{ github.ref_name }}-
|
||||
${{ runner.os }}-ccache-
|
||||
|
||||
- name: Build RDC
|
||||
run: |
|
||||
pwd
|
||||
cmake \
|
||||
-B build \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DGRPC_DESIRED_VERSION=1.61.0 \
|
||||
-DGRPC_ROOT=/usr/grpc \
|
||||
-DBUILD_RUNTIME=ON \
|
||||
-DGPU_TARGETS=gfx942 \
|
||||
-DBUILD_PROFILER=ON \
|
||||
-DBUILD_RVS=OFF \
|
||||
-DBUILD_TESTS=ON \
|
||||
-DCPACK_GENERATOR="DEB" \
|
||||
-DCMAKE_INSTALL_PREFIX=${ROCM_DIR}
|
||||
make -C build -j $(nproc)
|
||||
make -C build -j $(nproc) package
|
||||
|
||||
- name: Install RDC
|
||||
run: |
|
||||
echo "pre: "
|
||||
ls -lah /opt
|
||||
make -C build -j $(nproc) install
|
||||
echo "post: "
|
||||
ls -lah /opt
|
||||
|
||||
# important to use v3 because v4 doesn't work with act:
|
||||
# https://github.com/nektos/act/issues/329
|
||||
- name: Package RDC
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: rdc
|
||||
path: build/rdc*.deb
|
||||
if-no-files-found: error
|
||||
retention-days: 5
|
||||
|
||||
test:
|
||||
needs: build
|
||||
runs-on: lstt
|
||||
container: rocm/rocm-build-ubuntu-22.04:6.3
|
||||
|
||||
steps:
|
||||
- name: Set up apt repos
|
||||
run: |
|
||||
cat /etc/os-release
|
||||
apt update -y
|
||||
# provides add-apt-repository and support for caching actions
|
||||
apt install -y software-properties-common jq curl
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||
apt install -y nodejs
|
||||
|
||||
- name: Package RDC
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: rdc
|
||||
path: /opt/
|
||||
|
||||
- name: Test RDC installation
|
||||
shell: bash
|
||||
run: |
|
||||
COUNT=$(find /opt/ -iname 'rdc*.deb' | wc -l)
|
||||
test "$COUNT" -eq '2'
|
||||
dpkg --force-all -i /opt/rdc*.deb
|
||||
# confirm binaries are installed
|
||||
find $ROCM_DIR/bin -maxdepth 1 -iname rdcd
|
||||
find $ROCM_DIR/bin -maxdepth 1 -iname rdci
|
||||
find $ROCM_DIR/share/rdc -iname rdctst
|
||||
# confirm that libraries are installed
|
||||
MISSING_LIBS=()
|
||||
for lib in librdc.so librdc_bootstrap.so librdc_client.so; do
|
||||
test -e "$ROCM_DIR/lib/$lib" || MISSING_LIBS+=("$lib")
|
||||
done
|
||||
for lib in librdc_rocr.so librdc_rocp.so; do
|
||||
test -e "$ROCM_DIR/lib/rdc/$lib" || MISSING_LIBS+=("$lib")
|
||||
done
|
||||
|
||||
if test "${#MISSING_LIBS[@]}" != "0"; then
|
||||
echo "Missing libs found!"
|
||||
for lib in "${MISSING_LIBS[@]}"; do
|
||||
echo "- $lib"
|
||||
done
|
||||
exit 1
|
||||
else
|
||||
echo "No missing libs found!"
|
||||
fi
|
||||
@@ -0,0 +1,21 @@
|
||||
name: ROCm CI Caller
|
||||
on:
|
||||
pull_request:
|
||||
branches: [amd-mainline]
|
||||
types: [opened, reopened, synchronize]
|
||||
push:
|
||||
branches: [amd-mainline]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call-workflow:
|
||||
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.sha }}
|
||||
input_pr_num: ${{ github.event_name == 'pull_request' && github.event.pull_request.number || 0 }}
|
||||
input_pr_url: ${{ github.event_name == 'pull_request' && github.event.pull_request.html_url || '' }}
|
||||
input_pr_title: ${{ github.event_name == 'pull_request' && github.event.pull_request.title || '' }}
|
||||
repository_name: ${{ github.repository }}
|
||||
base_ref: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref }}
|
||||
trigger_event_type: ${{ github.event_name }}
|
||||
@@ -0,0 +1,33 @@
|
||||
# build artifacts
|
||||
.cache/
|
||||
build/
|
||||
DEBIAN/postinst
|
||||
DEBIAN/prerm
|
||||
RPM/
|
||||
include/rdc/rdc64Config.h
|
||||
|
||||
# documentation artifacts
|
||||
_build/
|
||||
_images/
|
||||
_static/
|
||||
_templates/
|
||||
_toc.yml
|
||||
docBin/
|
||||
docs/_doxygen/
|
||||
|
||||
# VisualStudioCode
|
||||
.vscode
|
||||
|
||||
# do NOT ignore these files
|
||||
!.clang-format
|
||||
!.editorconfig
|
||||
!.cmake-format
|
||||
!.pre-commit-config.yaml
|
||||
|
||||
# misc
|
||||
__pycache__/
|
||||
authentication/CA/
|
||||
|
||||
# act
|
||||
act.variables
|
||||
act.secrets
|
||||
@@ -0,0 +1,23 @@
|
||||
# - How to use:
|
||||
# python3 -m pip install pre-commit
|
||||
# pre-commit install --install hooks
|
||||
# Upon a new commit - the hooks should automagically run
|
||||
#
|
||||
# - How to skip:
|
||||
# git commit --no-verify
|
||||
# or
|
||||
# SKIP=clang-format git commit
|
||||
# SKIP=gersemi git commit
|
||||
|
||||
fail_fast: false
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v20.1.7
|
||||
hooks:
|
||||
- id: clang-format
|
||||
types_or: [c++, c]
|
||||
|
||||
- repo: https://github.com/BlankSpruce/gersemi
|
||||
rev: 0.20.1
|
||||
hooks:
|
||||
- id: gersemi
|
||||
@@ -0,0 +1,18 @@
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
version: 2
|
||||
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
formats: [htmlzip, pdf, epub]
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/sphinx/requirements.txt
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.10"
|
||||
@@ -0,0 +1,48 @@
|
||||
# Change Log for RDC
|
||||
|
||||
Full documentation for RDC is available at [ROCm DataCenter Tool User Guide](https://rocm.docs.amd.com/projects/rdc/en/latest/).
|
||||
|
||||
## RDC for ROCm 6.4.0
|
||||
|
||||
### Added
|
||||
|
||||
- RDC policy feature
|
||||
- Power and thermal throttling metrics
|
||||
- RVS [IET](https://github.com/ROCm/ROCmValidationSuite/tree/a6177fc5e3f2679f98bbbc80dc536d535a43fb69/iet.so), [PEBB](https://github.com/ROCm/ROCmValidationSuite/tree/a6177fc5e3f2679f98bbbc80dc536d535a43fb69/pebb.so), and [memory bandwidth tests](https://github.com/ROCm/ROCmValidationSuite/tree/a6177fc5e3f2679f98bbbc80dc536d535a43fb69/babel.so)
|
||||
- Link status
|
||||
- RDC_FI_PROF_SM_ACTIVE metric
|
||||
|
||||
### Changed
|
||||
|
||||
- Migrated from [rocprofiler v1](https://github.com/ROCm/rocprofiler) to [rocprofiler-sdk](https://github.com/ROCm/rocprofiler-sdk)
|
||||
- Improved README.md for better usability
|
||||
- Moved `rdc_options` into `share/rdc/conf/`
|
||||
- Fixed ABSL in clang18+
|
||||
|
||||
## RDC for ROCm 6.3.0
|
||||
|
||||
### Added
|
||||
|
||||
- [RVS](https://github.com/ROCm/ROCmValidationSuite) integration
|
||||
- Real time logging for diagnostic command
|
||||
- `--version` command
|
||||
- `XGMI_TOTAL_READ_KB` and `XGMI_TOTAL_WRITE_KB` monitoring metrics
|
||||
|
||||
## RDC for ROCm 6.2.0
|
||||
|
||||
- Added [rocprofiler](https://github.com/ROCm/rocprofiler) dmon metrics
|
||||
- Added new ECC metrics
|
||||
- Added [ROCmValidationSuite](https://github.com/ROCm/ROCmValidationSuite) diagnostic command
|
||||
- Fully migrated to [AMDSMI](https://github.com/ROCm/amdsmi)
|
||||
- Removed RASLIB dependency and blobs
|
||||
- Removed [rocm_smi_lib](https://github.com/ROCm/rocm_smi_lib) dependency
|
||||
|
||||
## RDC for ROCm 6.1.0
|
||||
|
||||
- Added `--address` flag to rdcd
|
||||
- Upgraded from C++11 to C++17
|
||||
- Upgraded gRPC
|
||||
|
||||
## RDC for ROCm 5.5.0
|
||||
|
||||
- Added new profiling metrics for RDC dmon module.
|
||||
@@ -0,0 +1,568 @@
|
||||
# Copyright (c) 2019 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
#
|
||||
# Minimum version of cmake required
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
set(RDC "rdc" CACHE INTERNAL "")
|
||||
set(RDC_PACKAGE ${RDC} CACHE STRING "")
|
||||
|
||||
# ROCM_DIR should be passed in via command line
|
||||
set(ROCM_DIR "/opt/rocm" CACHE PATH "ROCm directory.")
|
||||
if(DEFINED ROCM_PATH)
|
||||
message(
|
||||
WARNING
|
||||
"ROCM_PATH is not used by the build process! Did you mean to set ROCM_DIR instead?"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Default libdir to "lib", this skips GNUInstallDirs from trying to take a guess if it's unset:
|
||||
set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory")
|
||||
|
||||
# Usually ROCM tools are installed into /opt/rocm
|
||||
set(CMAKE_INSTALL_PREFIX ${ROCM_DIR} CACHE PATH "Default installation directory.")
|
||||
|
||||
set(CMAKE_BUILD_TYPE
|
||||
"RelWithDebInfo"
|
||||
CACHE STRING
|
||||
"Choose the type of build to perform: Debug, Release, RelWithDebInfo, MinSizeRel"
|
||||
)
|
||||
# Set the possible values of build type
|
||||
set_property(
|
||||
CACHE CMAKE_BUILD_TYPE
|
||||
PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo" "MinSizeRel"
|
||||
)
|
||||
|
||||
# Set compile flags
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -m64 -msse -msse2")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG
|
||||
"${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -DDEBUG"
|
||||
CACHE STRING
|
||||
"Flags for Debug builds"
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} -O2 -s -DNDEBUG"
|
||||
CACHE STRING
|
||||
"Flags for Release builds"
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -g -DNDEBUG"
|
||||
CACHE STRING
|
||||
"Flags for RelWithDebInfo builds"
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
"${CMAKE_CXX_FLAGS_MINSIZEREL} -Os -DNDEBUG"
|
||||
CACHE STRING
|
||||
"Flags for MinSizeRel builds"
|
||||
)
|
||||
|
||||
set(CMAKE_MODULE_PATH
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/"
|
||||
CACHE INTERNAL
|
||||
"Default module path."
|
||||
)
|
||||
# Include common cmake modules
|
||||
include(utils)
|
||||
# Setup the package version based on git tags
|
||||
set(PKG_VERSION_GIT_TAG_PREFIX "rdc_pkg_ver")
|
||||
# Provide git to utilities
|
||||
find_program(GIT NAMES git)
|
||||
get_version_from_tag("1.1.0" ${PKG_VERSION_GIT_TAG_PREFIX} GIT)
|
||||
# VERSION_* variables should be set by get_version_from_tag
|
||||
message("Package version: ${VERSION_STRING}")
|
||||
|
||||
# When cmake -DBUILD_STANDALONE=off, it will not build rdcd and rdci
|
||||
# which requires the gRPC
|
||||
option(BUILD_STANDALONE "Build targets for rdci and rdcd" ON)
|
||||
|
||||
# When cmake -DBUILD_RUNTIME=off, it will not build the librdc_rocr.so
|
||||
# which requires the Rocm run time.
|
||||
option(BUILD_RUNTIME "Build targets for librdc_rocr.so" ON)
|
||||
|
||||
# When cmake -DBUILD_PROFILER=off, it will not build the librdc_rocp.so
|
||||
# which requires the Rocm profiler.
|
||||
option(BUILD_PROFILER "Build targets for librdc_rocp.so" OFF)
|
||||
|
||||
# When cmake -DBUILD_RVS=off, it will not build the librdc_rvs.so
|
||||
# which requires the RocmValidationSuite
|
||||
option(BUILD_RVS "Build targets for librdc_rvs.so" ON)
|
||||
|
||||
# When cmake -DBUILD_TESTS=off, it will not build RDC tests.
|
||||
option(BUILD_TESTS "Build test suite" OFF)
|
||||
|
||||
# When cmake -DBUILD_EXAMPLES=off, it will not build RDC examples
|
||||
option(BUILD_EXAMPLES "Build examples" OFF)
|
||||
|
||||
# Enable shared libraries for gtest
|
||||
option(BUILD_SHARED_LIBS "Build shared library (.so) or not." ON)
|
||||
|
||||
# Enable address sanitizer
|
||||
set(ADDRESS_SANITIZER_DEFAULT OFF)
|
||||
if(DEFINED ENV{ADDRESS_SANITIZER})
|
||||
set(ADDRESS_SANITIZER_DEFAULT $ENV{ADDRESS_SANITIZER})
|
||||
endif()
|
||||
option(ADDRESS_SANITIZER "Enable address sanitizer" ${ADDRESS_SANITIZER_DEFAULT})
|
||||
|
||||
option(CMAKE_VERBOSE_MAKEFILE "Enable verbose output" OFF)
|
||||
|
||||
option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile commands for linters and autocompleters" ON)
|
||||
|
||||
execute_process(
|
||||
COMMAND ${GIT} rev-parse --short HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
message(
|
||||
"The HASH value of the current HEAD submission in this RDC code repository is : "
|
||||
${GIT_HASH}
|
||||
)
|
||||
|
||||
# Don't print 'Up-to-date' when installing
|
||||
set(CMAKE_INSTALL_MESSAGE LAZY)
|
||||
|
||||
# this must go after some CMAKE_* variables
|
||||
project(${RDC} VERSION "${VERSION_STRING}" HOMEPAGE_URL "https://github.com/RadeonOpenCompute/rdc")
|
||||
|
||||
# Include CMAKE_INSTALL_* variables
|
||||
# this must go after project()
|
||||
include(GNUInstallDirs)
|
||||
|
||||
set(COMMON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/common")
|
||||
|
||||
set(GRPC_ROOT_DEFAULT "/usr")
|
||||
set(GRPC_ROOT ${GRPC_ROOT_DEFAULT} CACHE PATH "GRPC installation directory.")
|
||||
set(GRPC_DESIRED_VERSION 1.67.1 CACHE STRING "GRPC desired package version.")
|
||||
|
||||
# add package search paths
|
||||
list(APPEND CMAKE_PREFIX_PATH ${GRPC_ROOT} /usr/local)
|
||||
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/lib64 /usr/lib/x86_64-linux-gnu)
|
||||
|
||||
# configure packaging
|
||||
# cpack version is populated with CMAKE_PROJECT_VERSION implicitly
|
||||
set(CPACK_PACKAGE_NAME ${RDC_PACKAGE} CACHE INTERNAL "")
|
||||
set(CPACK_PACKAGE_VENDOR "Advanced Micro Devices, Inc." CACHE STRING "")
|
||||
set(CPACK_PACKAGE_CONTACT "RDC Support <rdc.support@amd.com>" CACHE STRING "")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Radeon Data Center Tools" CACHE STRING "")
|
||||
set(CPACK_PACKAGE_DESCRIPTION
|
||||
"This package contains the AMD ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}."
|
||||
CACHE STRING
|
||||
""
|
||||
)
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Default packaging prefix.")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" CACHE INTERNAL "")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "MIT" CACHE INTERNAL "")
|
||||
set(CPACK_GENERATOR "DEB;RPM" CACHE STRING "Default packaging generators.")
|
||||
set(CPACK_DEB_COMPONENT_INSTALL ON)
|
||||
set(CPACK_RPM_COMPONENT_INSTALL ON)
|
||||
mark_as_advanced(
|
||||
CPACK_PACKAGE_VENDOR
|
||||
CPACK_PACKAGE_CONTACT
|
||||
CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
||||
CPACK_PACKAGE_DESCRIPTION
|
||||
CPACK_GENERATOR
|
||||
)
|
||||
|
||||
# check if libcap exists
|
||||
# needed for sys/capabilities.h
|
||||
find_library(LIB_CAP NAMES cap REQUIRED)
|
||||
|
||||
if(BUILD_STANDALONE AND GRPC_ROOT STREQUAL GRPC_ROOT_DEFAULT)
|
||||
message(
|
||||
WARNING
|
||||
"GRPC_ROOT is left default. Cannot install gRPC from default root!
|
||||
Please specify -DGRPC_ROOT=<gRPC installation directory>
|
||||
Continuing without gRPC install"
|
||||
)
|
||||
endif()
|
||||
|
||||
find_package(amd_smi 26.0.0 NAMES amd_smi HINTS ${ROCM_DIR}/lib/cmake CONFIG REQUIRED)
|
||||
|
||||
if(NOT EXISTS "${AMD_SMI_INCLUDE_DIR}" OR NOT EXISTS "${AMD_SMI_LIB_DIR}")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"amd_smi not found in ${AMD_SMI_INCLUDE_DIR}. Please
|
||||
make sure amd_smi is installed and present in ${AMD_SMI_INCLUDE_DIR}."
|
||||
)
|
||||
endif()
|
||||
|
||||
set(${RDC}_VERSION_MAJOR "${VERSION_MAJOR}")
|
||||
set(${RDC}_VERSION_MINOR "${VERSION_MINOR}")
|
||||
set(${RDC}_VERSION_PATCH "0")
|
||||
set(${RDC}_VERSION_BUILD "0")
|
||||
set(CPACK_PACKAGE_VERSION ${VERSION_STRING})
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "The C++ standard to use")
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.4.0)
|
||||
message("Compiler version is " ${CMAKE_CXX_COMPILER_VERSION})
|
||||
message(FATAL_ERROR "Require at least gcc-5.4.0")
|
||||
endif()
|
||||
|
||||
message("Build Configuration:")
|
||||
|
||||
if(BUILD_STANDALONE)
|
||||
message("-----------GRPC ROOT: " ${GRPC_ROOT})
|
||||
endif()
|
||||
message("-----------ROCM_DIR : " ${ROCM_DIR})
|
||||
|
||||
# this is needed for INSTALL_RPATH "\$ORIGIN" property to work correctly
|
||||
# please note that because of --enable-new-dtags - this actually sets RUNPATH and not RPATH.
|
||||
# this means LD_LIBRARY_PATH can override the library locations
|
||||
set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE CACHE BOOL "Set all RPATH to be ORIGIN-based")
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE CACHE BOOL "Use link path for RPATH")
|
||||
|
||||
## Add address sanitizer
|
||||
if(${ADDRESS_SANITIZER})
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -g")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
message(STATUS "ADDRESS_SANITIZE: CMAKE_CXX_FLAGS=: ${CMAKE_CXX_FLAGS}")
|
||||
message(STATUS "ADDRESS_SANITIZE: CMAKE_EXE_LINKER_FLAGS=: ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -g")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -shared-libasan")
|
||||
message(STATUS "ADDRESS_SANITIZE: CMAKE_CXX_FLAGS=: ${CMAKE_CXX_FLAGS}")
|
||||
message(STATUS "ADDRESS_SANITIZE: CMAKE_EXE_LINKER_FLAGS=: ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Create a configure file to get version info from within library
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/src/${RDC}64Config.in"
|
||||
"${PROJECT_SOURCE_DIR}/include/rdc/${RDC}64Config.h"
|
||||
)
|
||||
|
||||
if(BUILD_STANDALONE)
|
||||
# Compile .proto files
|
||||
file(GLOB PROTOB_DEF_SRC_FILES "protos/*.proto")
|
||||
set(PROTOB_SRC_DIR "${PROJECT_SOURCE_DIR}/protos")
|
||||
set(PROTOB_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
find_program(PROTOB_CMD NAMES protoc REQUIRED)
|
||||
find_program(GRPC_PLUGIN NAMES grpc_cpp_plugin REQUIRED)
|
||||
set(GRPC_LIB_DIR "${GRPC_ROOT}/lib")
|
||||
|
||||
set(ENV{LD_LIBRARY_PATH} ${GRPC_LIB_DIR}:${GRPC_LIB_DIR}64:$ENV{LD_LIBRARY_PATH})
|
||||
message("LD_LIBRARY_PATH = $ENV{LD_LIBRARY_PATH}")
|
||||
foreach(file ${PROTOB_DEF_SRC_FILES})
|
||||
execute_process(
|
||||
COMMAND ${PROTOB_CMD} --proto_path=${PROTOB_SRC_DIR} --cpp_out=${PROTOB_OUT_DIR} ${file}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE PROTOB_RESULT
|
||||
OUTPUT_VARIABLE PROTOB_OUT_VAR
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
message("protoc command returned: ${PROTOB_RESULT}")
|
||||
|
||||
message("GRPC_PLUGIN=${GRPC_PLUGIN})")
|
||||
message("protoc cmd:")
|
||||
message(" $ ${PROTOB_CMD} --proto_path=${PROTOB_SRC_DIR}")
|
||||
message(" --grpc_out=${PROTOB_OUT_DIR}")
|
||||
message("....--plugin=protoc-gen-grpc=\"${GRPC_PLUGIN}\" ${file}")
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${PROTOB_CMD} --proto_path=${PROTOB_SRC_DIR} --grpc_out=${PROTOB_OUT_DIR}
|
||||
--plugin=protoc-gen-grpc=${GRPC_PLUGIN} ${file}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE PROTOB_RESULT
|
||||
OUTPUT_VARIABLE PROTOB_OUT_VAR
|
||||
)
|
||||
message("protoc command returned: ${PROTOB_RESULT}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# define all the install component labels to install
|
||||
set(SERVER_COMPONENT "server")
|
||||
set(CLIENT_COMPONENT "client")
|
||||
set(TESTS_COMPONENT "tests")
|
||||
|
||||
# Standalone only folders
|
||||
if(BUILD_STANDALONE)
|
||||
# these packages are later used in server and client targets
|
||||
find_package(protobuf HINTS ${GRPC_ROOT} CONFIG REQUIRED)
|
||||
find_package(gRPC ${GRPC_DESIRED_VERSION} HINTS ${GRPC_ROOT} CONFIG REQUIRED)
|
||||
|
||||
# Don't print grpc install because it floods the terminal
|
||||
set(OLD_CMAKE_INSTALL_MESSAGE ${CMAKE_INSTALL_MESSAGE})
|
||||
set(CMAKE_INSTALL_MESSAGE NEVER)
|
||||
# Only allow installation when GRPC_ROOT is not default
|
||||
# The alternative is installing all libraries and binaries from
|
||||
# GRPC_ROOT_DEFAULT (/usr), which is incorrect behavior.
|
||||
# This is needed because it's very difficult to track all gRPC dependencies
|
||||
if(NOT GRPC_ROOT STREQUAL GRPC_ROOT_DEFAULT)
|
||||
install(
|
||||
DIRECTORY ${GRPC_ROOT}/lib
|
||||
USE_SOURCE_PERMISSIONS
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${RDC}/grpc
|
||||
COMPONENT ${SERVER_COMPONENT}
|
||||
)
|
||||
# In SLES, The libprotobuf is created under lib64 folder, install it as well
|
||||
if(EXISTS ${GRPC_ROOT}/lib64)
|
||||
install(
|
||||
DIRECTORY ${GRPC_ROOT}/lib64/
|
||||
USE_SOURCE_PERMISSIONS
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${RDC}/grpc/lib
|
||||
COMPONENT ${SERVER_COMPONENT}
|
||||
)
|
||||
endif()
|
||||
# Also include dev setup for people do not want to build grpc
|
||||
file(GLOB install_bin_files "${GRPC_ROOT}/bin/*")
|
||||
foreach(ITEM ${install_bin_files})
|
||||
list(APPEND bin_files "${ITEM}")
|
||||
endforeach()
|
||||
install(
|
||||
FILES ${bin_files}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${RDC}/grpc/bin
|
||||
COMPONENT ${SERVER_COMPONENT}
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY ${GRPC_ROOT}/include
|
||||
USE_SOURCE_PERMISSIONS
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${RDC}/grpc
|
||||
COMPONENT ${SERVER_COMPONENT}
|
||||
)
|
||||
endif()
|
||||
# Restore printing verbosity
|
||||
set(CMAKE_INSTALL_MESSAGE ${OLD_CMAKE_INSTALL_MESSAGE})
|
||||
unset(OLD_CMAKE_INSTALL_MESSAGE)
|
||||
|
||||
add_subdirectory("server")
|
||||
add_subdirectory("rdci")
|
||||
|
||||
if(BUILD_TESTS)
|
||||
add_subdirectory("tests/rdc_tests")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Folders for both standalone and embedded
|
||||
add_subdirectory("rdc_libs")
|
||||
|
||||
if(BUILD_EXAMPLES)
|
||||
add_subdirectory("example")
|
||||
endif()
|
||||
|
||||
# Export the package for use from the build-tree
|
||||
# (this registers the build-tree with a global CMake-registry)
|
||||
export(PACKAGE rdc)
|
||||
|
||||
set(CONF_LIBS "librdc_bootstrap.so")
|
||||
set(CONF_LIB_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
# Create the rdc-config.cmake and rdc-config-version files
|
||||
configure_file(
|
||||
cmake_modules/rdc-config-version.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/rdc-config-version.cmake"
|
||||
@ONLY
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
set(CONFIG_PACKAGE_INSTALL_DIR ${CONF_LIB_DIR}/cmake/${RDC})
|
||||
configure_package_config_file(
|
||||
cmake_modules/rdc-config.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/rdc-config.cmake
|
||||
INSTALL_DESTINATION ${CONFIG_PACKAGE_INSTALL_DIR}
|
||||
)
|
||||
|
||||
# Install the rdc-config.cmake and rdc-config-version.cmake
|
||||
install(
|
||||
FILES "${PROJECT_BINARY_DIR}/rdc-config.cmake" "${PROJECT_BINARY_DIR}/rdc-config-version.cmake"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${RDC}"
|
||||
COMPONENT dev
|
||||
)
|
||||
|
||||
# Install the export set for use with the install-tree
|
||||
install(EXPORT rdcTargets DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${RDC}" COMPONENT dev)
|
||||
|
||||
# License file
|
||||
install(
|
||||
FILES ${CPACK_RESOURCE_FILE_LICENSE}
|
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR}
|
||||
RENAME LICENSE.txt
|
||||
COMPONENT dev
|
||||
)
|
||||
|
||||
# Python binding
|
||||
install(
|
||||
DIRECTORY ${PROJECT_SOURCE_DIR}/python_binding
|
||||
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${RDC}
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
install(
|
||||
DIRECTORY ${PROJECT_SOURCE_DIR}/authentication
|
||||
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${RDC}
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
install(
|
||||
DIRECTORY ${PROJECT_SOURCE_DIR}/example
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${RDC}
|
||||
COMPONENT dev
|
||||
)
|
||||
|
||||
#Identify between SLES and Centos for setting symlink for rdc.service
|
||||
#SLES need serice file in /usr/lib/systemd/system/rdc.service
|
||||
#CENTOS/RHEL Require file in /lib/systemd/system/rdc.service
|
||||
file(STRINGS /etc/os-release LINUX_DISTRO LIMIT_COUNT 1 REGEX "NAME=")
|
||||
message("Using Linux Distro: ${LINUX_DISTRO}")
|
||||
if(LINUX_DISTRO MATCHES "SLES")
|
||||
set(DISTRO_ROOT "/usr/lib/systemd/system")
|
||||
else()
|
||||
set(DISTRO_ROOT "/lib/systemd/system")
|
||||
endif()
|
||||
|
||||
# 755 permissions
|
||||
set(INST_SCR_PERM
|
||||
OWNER_READ
|
||||
OWNER_WRITE
|
||||
OWNER_EXECUTE
|
||||
GROUP_READ
|
||||
GROUP_EXECUTE
|
||||
WORLD_READ
|
||||
WORLD_EXECUTE
|
||||
)
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/src/DEBIAN_postinst.in"
|
||||
"${PROJECT_SOURCE_DIR}/DEBIAN/postinst"
|
||||
FILE_PERMISSIONS ${INST_SCR_PERM}
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/src/DEBIAN_prerm.in"
|
||||
"${PROJECT_SOURCE_DIR}/DEBIAN/prerm"
|
||||
FILE_PERMISSIONS ${INST_SCR_PERM}
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/src/RPM_rpm_post.in"
|
||||
"${PROJECT_SOURCE_DIR}/RPM/rpm_post"
|
||||
FILE_PERMISSIONS ${INST_SCR_PERM}
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/src/RPM_preun.in"
|
||||
"${PROJECT_SOURCE_DIR}/RPM/rpm_preun"
|
||||
FILE_PERMISSIONS ${INST_SCR_PERM}
|
||||
@ONLY
|
||||
)
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/src/RPM_postun.in"
|
||||
"${PROJECT_SOURCE_DIR}/RPM/rpm_postun"
|
||||
FILE_PERMISSIONS ${INST_SCR_PERM}
|
||||
@ONLY
|
||||
)
|
||||
if(DEFINED ENV{ROCM_LIBPATCH_VERSION})
|
||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.$ENV{ROCM_LIBPATCH_VERSION}")
|
||||
message("Using CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}")
|
||||
else()
|
||||
set(ROCM_LIBPATCH_VERSION)
|
||||
endif()
|
||||
|
||||
# Debian package specific variables
|
||||
if(DEFINED ENV{CPACK_DEBIAN_PACKAGE_RELEASE})
|
||||
set(CPACK_DEBIAN_PACKAGE_RELEASE $ENV{CPACK_DEBIAN_PACKAGE_RELEASE})
|
||||
else()
|
||||
set(CPACK_DEBIAN_PACKAGE_RELEASE "local")
|
||||
endif()
|
||||
message("Using CPACK_DEBIAN_PACKAGE_RELEASE ${CPACK_DEBIAN_PACKAGE_RELEASE}")
|
||||
set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
|
||||
|
||||
# Only add extras to RUNTIME package (not tests)
|
||||
# It makes no sense to modify RDCD service when installing tests
|
||||
# https://cmake.org/cmake/help/latest/cpack_gen/deb.html#variable:CPACK_DEBIAN_%3CCOMPONENT%3E_PACKAGE_CONTROL_EXTRA
|
||||
set(CPACK_DEBIAN_RUNTIME_PACKAGE_CONTROL_EXTRA
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/DEBIAN/postinst"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/DEBIAN/prerm"
|
||||
)
|
||||
|
||||
option(ROCM_DEP_ROCMCORE "Add debian dependency on rocm-core" OFF)
|
||||
mark_as_advanced(ROCM_DEP_ROCMCORE)
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "amd-smi-lib, libc6")
|
||||
if(ROCM_DEP_ROCMCORE)
|
||||
string(APPEND CPACK_DEBIAN_PACKAGE_DEPENDS ", rocm-core")
|
||||
endif()
|
||||
# rdc-tests need rdc
|
||||
set(CPACK_DEBIAN_TESTS_PACKAGE_DEPENDS "${CPACK_PACKAGE_NAME}")
|
||||
|
||||
# RPM package specific variables
|
||||
if(DEFINED ENV{CPACK_RPM_PACKAGE_RELEASE})
|
||||
set(CPACK_RPM_PACKAGE_RELEASE $ENV{CPACK_RPM_PACKAGE_RELEASE})
|
||||
else()
|
||||
set(CPACK_RPM_PACKAGE_RELEASE "local")
|
||||
endif()
|
||||
message("Using CPACK_RPM_PACKAGE_RELEASE ${CPACK_RPM_PACKAGE_RELEASE}")
|
||||
set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
|
||||
|
||||
## 'dist' breaks manual builds on debian systems due to empty Provides
|
||||
execute_process(
|
||||
COMMAND rpm --eval %{?dist}
|
||||
RESULT_VARIABLE PROC_RESULT
|
||||
OUTPUT_VARIABLE EVAL_RESULT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(PROC_RESULT EQUAL "0" AND NOT EVAL_RESULT STREQUAL "")
|
||||
string(APPEND CPACK_RPM_PACKAGE_RELEASE "%{?dist}")
|
||||
endif()
|
||||
|
||||
set(CPACK_RPM_PACKAGE_AUTOREQ 0)
|
||||
set(CPACK_RPM_PACKAGE_AUTOPROV 0)
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "amd-smi-lib")
|
||||
# rdc-tests need rdc
|
||||
set(CPACK_RPM_TESTS_PACKAGE_REQUIRES "${CPACK_PACKAGE_NAME}")
|
||||
list(
|
||||
APPEND
|
||||
CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
|
||||
"/lib"
|
||||
"/usr/sbin"
|
||||
"/lib/systemd"
|
||||
"/lib/systemd/system"
|
||||
"/usr"
|
||||
"/opt"
|
||||
)
|
||||
|
||||
# Only add extras to RUNTIME package (not tests)
|
||||
# It makes no sense to modify RDCD service when installing tests
|
||||
# https://cmake.org/cmake/help/latest/cpack_gen/rpm.html#variable:CPACK_RPM_PRE_INSTALL_SCRIPT_FILE
|
||||
set(CPACK_RPM_RUNTIME_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/RPM/rpm_post")
|
||||
set(CPACK_RPM_RUNTIME_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/RPM/rpm_preun")
|
||||
set(CPACK_RPM_RUNTIME_POST_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/RPM/rpm_postun")
|
||||
|
||||
# Treat runtime group as package base.
|
||||
# Without it - the base package would be named 'rdc-runtime'
|
||||
# resulting in rdc-runtime*.deb and rdc-runtime*.rpm
|
||||
set(CPACK_DEBIAN_RUNTIME_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")
|
||||
set(CPACK_RPM_RUNTIME_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")
|
||||
|
||||
include(CPack)
|
||||
|
||||
# rdc package, no postfix
|
||||
cpack_add_component_group("runtime")
|
||||
cpack_add_component(${CLIENT_COMPONENT} GROUP runtime)
|
||||
cpack_add_component(${SERVER_COMPONENT} GROUP runtime)
|
||||
cpack_add_component(dev GROUP runtime)
|
||||
|
||||
# rdc-tests package, -tests postfix
|
||||
cpack_add_component_group("tests")
|
||||
cpack_add_component(${TESTS_COMPONENT} GROUP tests)
|
||||
@@ -0,0 +1,3 @@
|
||||
set noparent
|
||||
linelength=100
|
||||
filter=-build/include_subdir,-legal/copyright,-runtime/printf,-build/c++11,-runtime/int,-build/header_guard
|
||||
@@ -0,0 +1,8 @@
|
||||
Package: rdc
|
||||
Architecture: amd64
|
||||
Maintainer: Advanced Micro Devices (AMD) <rdc.support@amd.com>
|
||||
Depends:
|
||||
Priority: optional
|
||||
Version: MODULE_VERSION
|
||||
Description: AMD Radeon Data Center
|
||||
This package contains the Radeon Data Center tools.
|
||||
@@ -0,0 +1,107 @@
|
||||
# Use amdsmi base image
|
||||
FROM amdsmi-image
|
||||
|
||||
# Sync ROCm repositories
|
||||
RUN apt-get update && apt-get install -y wget gnupg2 && \
|
||||
wget -qO - http://repo.radeon.com/rocm/rocm.gpg.key | apt-key add - && \
|
||||
echo 'deb [arch=amd64] http://repo.radeon.com/rocm/apt/debian/ jammy main' | tee /etc/apt/sources.list.d/rocm.list
|
||||
|
||||
# Install ROCm runtime and dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
rocm-smi-lib \
|
||||
cmake \
|
||||
make \
|
||||
g++ \
|
||||
doxygen \
|
||||
texlive-latex-base \
|
||||
automake \
|
||||
unzip \
|
||||
build-essential \
|
||||
autoconf \
|
||||
libtool \
|
||||
pkg-config \
|
||||
libgflags-dev \
|
||||
libgtest-dev \
|
||||
clang \
|
||||
libc++-dev \
|
||||
curl \
|
||||
libcap-dev \
|
||||
python3-argcomplete \
|
||||
python3-pip \
|
||||
bash && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Update setuptools
|
||||
RUN python3 -m pip install --upgrade setuptools==59.6.0
|
||||
|
||||
# Check for modprobe
|
||||
RUN command -v modprobe || echo "modprobe not found"
|
||||
|
||||
# Set environment variables
|
||||
ENV GRPC_ROOT=/opt/grpc
|
||||
ENV RDC_LIB_DIR=/opt/rocm/lib/rdc
|
||||
ENV CMAKE_ROOT=/usr/bin/cmake
|
||||
|
||||
# Install gRPC
|
||||
RUN git clone -b v1.61.0 https://github.com/grpc/grpc --depth=1 --shallow-submodules --recurse-submodules && \
|
||||
cd grpc && \
|
||||
cmake -B build \
|
||||
-DgRPC_INSTALL=ON \
|
||||
-DgRPC_BUILD_TESTS=OFF \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCMAKE_INSTALL_PREFIX="$GRPC_ROOT" \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib \
|
||||
-DCMAKE_BUILD_TYPE=Release && \
|
||||
make -C build -j $(nproc) && \
|
||||
make -C build install && \
|
||||
echo "$GRPC_ROOT" | tee /etc/ld.so.conf.d/grpc.conf
|
||||
|
||||
# Build and install RDC
|
||||
RUN git clone https://github.com/ROCm/rdc && \
|
||||
cd rdc && \
|
||||
cmake -B build -DGRPC_ROOT="$GRPC_ROOT" \
|
||||
-DSMIDIR="$SMI_DIR" \
|
||||
-DBUILD_TESTS=OFF \
|
||||
-DBUILD_PROFILER=OFF \
|
||||
-DBUILD_RUNTIME=OFF \
|
||||
-DBUILD_RVS=OFF && \
|
||||
make -C build -j $(nproc) && \
|
||||
make -C build install
|
||||
|
||||
# Update system library path
|
||||
RUN export RDC_LIB_DIR=/opt/rocm/lib/rdc && \
|
||||
export GRPC_LIB_DIR="/opt/grpc/lib" && \
|
||||
echo "${RDC_LIB_DIR}" | tee /etc/ld.so.conf.d/x86_64-librdc_client.conf && \
|
||||
echo "${GRPC_LIB_DIR}" | tee -a /etc/ld.so.conf.d/x86_64-librdc_client.conf && \
|
||||
ldconfig
|
||||
|
||||
# Expose the port for Prometheus
|
||||
EXPOSE 50051
|
||||
|
||||
# Expose the prometheus plugin port
|
||||
EXPOSE 5000
|
||||
|
||||
# Set working directory to /opt/rocm/libexec/rdc/python_binding
|
||||
WORKDIR /opt/rocm/libexec/rdc/python_binding
|
||||
|
||||
# Install Prometheus
|
||||
RUN wget https://github.com/prometheus/prometheus/releases/download/v2.41.0/prometheus-2.41.0.linux-amd64.tar.gz && \
|
||||
tar xvfz prometheus-2.41.0.linux-amd64.tar.gz && \
|
||||
mv prometheus-2.41.0.linux-amd64/prometheus /usr/local/bin/ && \
|
||||
rm -rf prometheus-2.41.0.linux-amd64*
|
||||
|
||||
# Install Grafana
|
||||
RUN wget https://dl.grafana.com/oss/release/grafana-9.3.2.linux-amd64.tar.gz && \
|
||||
tar -zxvf grafana-9.3.2.linux-amd64.tar.gz && \
|
||||
mv grafana-9.3.2 /usr/local/grafana && \
|
||||
rm grafana-9.3.2.linux-amd64.tar.gz
|
||||
|
||||
# Install Prometheus client for Python
|
||||
RUN python3 -m pip install prometheus_client
|
||||
|
||||
# Ensure sudo can run without a password for the rdcd command
|
||||
RUN echo "ALL ALL=(ALL) NOPASSWD: /opt/rocm/bin/rdcd" >> /etc/sudoers
|
||||
|
||||
# Set the entry point to run the rdcd command
|
||||
ENTRYPOINT ["sudo", "/opt/rocm/bin/rdcd", "-u"]
|
||||
@@ -0,0 +1,77 @@
|
||||
# Setup Instructions for AMDSMI and RDC Images
|
||||
|
||||
Follow these steps to set up both the AMDSMI and RDC images.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Ensure you have the necessary permissions and tools installed to clone repositories and build Docker images.
|
||||
|
||||
## Step 1: Clone Repositories
|
||||
|
||||
Download the latest AMDSMI and RDC repositories using the following commands:
|
||||
|
||||
### AMDSMI
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ROCm/amdsmi.git
|
||||
```
|
||||
|
||||
### RDC
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ROCm/rdc.git
|
||||
```
|
||||
|
||||
## Step 2: Build AMDSMI Base Image
|
||||
|
||||
1. Navigate to the `amdsmi` directory on your system.
|
||||
2. Build the Docker image using the following command:
|
||||
|
||||
```bash
|
||||
docker build -t amdsmi-image .
|
||||
```
|
||||
|
||||
## Step 3: Build RDC Image
|
||||
|
||||
1. Navigate to the `rdc` directory on your system.
|
||||
2. Navigate into the `/Docker` directory.
|
||||
3. Build the Docker image using the following command:
|
||||
|
||||
```bash
|
||||
docker build -t rdc-image .
|
||||
```
|
||||
|
||||
## Step 4: Run RDC Image
|
||||
|
||||
To run the RDC image, use the following command:
|
||||
|
||||
```bash
|
||||
docker run rdc-image
|
||||
```
|
||||
|
||||
If the above command does not work, try the following:
|
||||
|
||||
1. Run the image with a bash entry point:
|
||||
|
||||
```bash
|
||||
docker run -it --entrypoint /bin/bash rdc-image
|
||||
```
|
||||
|
||||
2. Once inside the container, run the following command:
|
||||
|
||||
```bash
|
||||
sudo /opt/rocm/bin/rdcd -u
|
||||
```
|
||||
|
||||
## Step 5: Run AMDSMI Image (optional)
|
||||
|
||||
To be able to run AMDSMI commands inside of the image run the following:
|
||||
|
||||
```bash
|
||||
sudo docker run --rm -ti \
|
||||
--privileged \
|
||||
--volume $(realpath ./):/src:rw \
|
||||
amdsmi-image
|
||||
```
|
||||
> [!IMPORTANT]
|
||||
> Make sure that you are in the `amdsmi` directory before running.
|
||||
@@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019-2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,632 @@
|
||||
# ROCm™ Data Center Tool (RDC) 🚀
|
||||
|
||||
The ROCm™ Data Center Tool (RDC) simplifies administration and addresses key infrastructure challenges in AMD GPUs within cluster and datacenter environments. RDC offers a suite of features to enhance your GPU management and monitoring.
|
||||
|
||||
## 🌟 Main Features
|
||||
|
||||
- **GPU Telemetry** 📊
|
||||
- **GPU Statistics for Jobs** 📈
|
||||
- **Integration with Third-Party Tools** 🔗
|
||||
- **Open Source** 🛠️
|
||||
|
||||
> [!NOTE]
|
||||
> The published documentation is available at [ROCm Data Center Tool](https://rocm.docs.amd.com/projects/rdc/en/latest/index.html) in an organized, easy-to-read format, with search and a table of contents. The documentation source files reside in the `rdc/docs` folder of this repository. As with all ROCm projects, the documentation is open source. For more information on contributing to the documentation, see [Contribute to ROCm documentation](https://rocm.docs.amd.com/en/latest/contribute/contributing.html).
|
||||
|
||||
## 🛠️ Installation Guide
|
||||
|
||||
### 📋 Prerequisites
|
||||
|
||||
Before setting up RDC, ensure your system meets the following requirements:
|
||||
|
||||
- **Supported Platforms**: RDC runs on AMD ROCm-supported platforms. Refer to the [List of Supported Operating Systems](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html#supported-operating-systems) for details.
|
||||
- **Dependencies**:
|
||||
- **CMake** ≥ 3.15
|
||||
- **g++** (5.4.0)
|
||||
- **Doxygen** (1.8.11)
|
||||
- **LaTeX** (pdfTeX 3.14159265-2.6-1.40.16)
|
||||
- **gRPC and protoc**
|
||||
- **libcap-dev**
|
||||
- **AMD ROCm Platform** ([GitHub](https://github.com/ROCm/ROCm))
|
||||
- **AMDSMI Library** ([GitHub](https://github.com/ROCm/amdsmi))
|
||||
- **ROCK Kernel Driver** ([GitHub](https://github.com/ROCm/ROCK-Kernel-Driver))
|
||||
|
||||
### 🔐 Certificate Generation
|
||||
|
||||
For certificate generation, refer to the [**RDC Developer Handbook (Generate Files for Authentication)**](https://rocm.docs.amd.com/projects/rdc/en/latest/install/handbook.html#generate-files-for-authentication) or consult the concise guide located at `authentication/readme.txt`.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Running RDC
|
||||
|
||||
RDC supports two primary modes of operation: **Standalone** and **Embedded**. Choose the mode that best fits your deployment needs.
|
||||
|
||||
### 🗂️ Standalone Mode
|
||||
|
||||
Standalone mode allows RDC to run independently with all its components installed.
|
||||
|
||||
1. **Start RDCD with Authentication (Monitor-Only Capabilities):**
|
||||
|
||||
```bash
|
||||
/opt/rocm/bin/rdcd
|
||||
```
|
||||
|
||||
2. **Start RDCD with Authentication (Full Capabilities):**
|
||||
|
||||
```bash
|
||||
sudo /opt/rocm/bin/rdcd
|
||||
```
|
||||
|
||||
3. **Start RDCD without Authentication (Monitor-Only):**
|
||||
|
||||
```bash
|
||||
/opt/rocm/bin/rdcd -u
|
||||
```
|
||||
|
||||
4. **Start RDCD without Authentication (Full Capabilities):**
|
||||
|
||||
```bash
|
||||
sudo /opt/rocm/bin/rdcd -u
|
||||
```
|
||||
|
||||
### 🔗 Embedded Mode
|
||||
|
||||
Embedded mode integrates RDC directly into your existing management tools using its library format.
|
||||
|
||||
- **Run RDC in Embedded Mode:**
|
||||
|
||||
```bash
|
||||
python your_management_tool.py --rdc_embedded
|
||||
```
|
||||
|
||||
**Note:** Ensure that the `rdcd` daemon is not running separately when using embedded mode.
|
||||
|
||||
### 🛠️ Starting RDCD Using systemd
|
||||
|
||||
1. **Copy the Service File:**
|
||||
|
||||
```bash
|
||||
sudo cp /opt/rocm/libexec/rdc/rdc.service /etc/systemd/system/
|
||||
```
|
||||
|
||||
2. **Configure Capabilities:**
|
||||
|
||||
- **Full Capabilities:** Ensure the following lines are **uncommented** in `/etc/systemd/system/rdc.service`:
|
||||
|
||||
```ini
|
||||
CapabilityBoundingSet=CAP_DAC_OVERRIDE
|
||||
AmbientCapabilities=CAP_DAC_OVERRIDE
|
||||
```
|
||||
|
||||
- **Monitor-Only Capabilities:** **Comment out** the above lines to restrict RDCD to monitoring.
|
||||
|
||||
3. **Start the Service:**
|
||||
|
||||
```bash
|
||||
sudo systemctl start rdc
|
||||
sudo systemctl status rdc
|
||||
```
|
||||
|
||||
4. **Modify RDCD Options:**
|
||||
|
||||
Edit `/opt/rocm/share/rdc/conf/rdc_options.conf` to append any additional RDCD parameters.
|
||||
|
||||
```bash
|
||||
sudo nano /opt/rocm/share/rdc/conf/rdc_options.conf
|
||||
```
|
||||
|
||||
**Example Configuration:**
|
||||
|
||||
```bash
|
||||
RDC_OPTS="-p 50051 -u -d"
|
||||
```
|
||||
|
||||
- **Flags:**
|
||||
- `-p 50051` : Use port 50051
|
||||
- `-u` : Unauthenticated mode
|
||||
- `-d` : Enable debug messages
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Building RDC from Source
|
||||
|
||||
If you prefer to build RDC from source, follow the steps below.
|
||||
|
||||
### 🔧 Building gRPC and protoc
|
||||
|
||||
**Important:** RDC requires gRPC and protoc to be built from source as pre-built packages are not available.
|
||||
|
||||
1. **Install Required Tools:**
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install automake make cmake g++ unzip build-essential autoconf libtool pkg-config libgflags-dev libgtest-dev clang libc++-dev curl libcap-dev
|
||||
```
|
||||
|
||||
2. **Clone and Build gRPC:**
|
||||
|
||||
```bash
|
||||
git clone -b v1.67.1 https://github.com/grpc/grpc --depth=1 --shallow-submodules --recurse-submodules
|
||||
cd grpc
|
||||
export GRPC_ROOT=/opt/grpc
|
||||
cmake -B build \
|
||||
-DgRPC_INSTALL=ON \
|
||||
-DgRPC_BUILD_TESTS=OFF \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCMAKE_SHARED_LINKER_FLAGS_INIT=-Wl,--enable-new-dtags,--build-id=sha1,--rpath,'$ORIGIN' \
|
||||
-DCMAKE_INSTALL_PREFIX="$GRPC_ROOT" \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
make -C build -j $(nproc)
|
||||
sudo make -C build install
|
||||
echo "$GRPC_ROOT" | sudo tee /etc/ld.so.conf.d/grpc.conf
|
||||
sudo ldconfig
|
||||
cd ..
|
||||
```
|
||||
|
||||
### 🔧 Building RDC
|
||||
|
||||
1. **Clone the RDC Repository:**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ROCm/rdc
|
||||
cd rdc
|
||||
```
|
||||
|
||||
2. **Configure the Build:**
|
||||
|
||||
```bash
|
||||
cmake -B build -DGRPC_ROOT="$GRPC_ROOT"
|
||||
```
|
||||
|
||||
- **Optional Features:**
|
||||
- **Enable ROCm Profiler:**
|
||||
|
||||
```bash
|
||||
cmake -B build -DBUILD_PROFILER=ON
|
||||
```
|
||||
|
||||
- **Enable RVS:**
|
||||
|
||||
```bash
|
||||
cmake -B build -DBUILD_RVS=ON
|
||||
```
|
||||
|
||||
- **Build RDC Library Only (without rdci and rdcd):**
|
||||
|
||||
```bash
|
||||
cmake -B build -DBUILD_STANDALONE=OFF
|
||||
```
|
||||
|
||||
- **Build RDC Library Without ROCm Run-time:**
|
||||
|
||||
```bash
|
||||
cmake -B build -DBUILD_RUNTIME=OFF
|
||||
```
|
||||
|
||||
3. **Build and Install:**
|
||||
|
||||
```bash
|
||||
make -C build -j $(nproc)
|
||||
sudo make -C build install
|
||||
```
|
||||
|
||||
4. **Update System Library Path:**
|
||||
|
||||
```bash
|
||||
export RDC_LIB_DIR=/opt/rocm/lib/rdc
|
||||
export GRPC_LIB_DIR="/opt/grpc/lib"
|
||||
echo "${RDC_LIB_DIR}" | sudo tee /etc/ld.so.conf.d/x86_64-librdc_client.conf
|
||||
echo "${GRPC_LIB_DIR}" | sudo tee -a /etc/ld.so.conf.d/x86_64-librdc_client.conf
|
||||
sudo ldconfig
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Features Overview
|
||||
|
||||
### 🔍 Discovery
|
||||
|
||||
Locate and display information about GPUs present in a compute node.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
rdci discovery <host_name> -l
|
||||
```
|
||||
|
||||
**Output:**
|
||||
|
||||
```
|
||||
2 GPUs found
|
||||
|
||||
+-----------+----------------------------------------------+
|
||||
| GPU Index | Device Information |
|
||||
+-----------+----------------------------------------------+
|
||||
| 0 | Name: AMD Radeon Instinct MI50 Accelerator |
|
||||
| 1 | Name: AMD Radeon Instinct MI50 Accelerator |
|
||||
+-----------+----------------------------------------------+
|
||||
```
|
||||
|
||||
## 👥 Groups
|
||||
|
||||
#### 🖥️ GPU Groups
|
||||
|
||||
Create, delete, and list logical groups of GPUs.
|
||||
|
||||
**Create a Group:**
|
||||
|
||||
```bash
|
||||
rdci group -c GPU_GROUP
|
||||
```
|
||||
|
||||
**Add GPUs to Group:**
|
||||
|
||||
```bash
|
||||
rdci group -g 1 -a 0,1
|
||||
```
|
||||
|
||||
**List Groups:**
|
||||
|
||||
```bash
|
||||
rdci group -l
|
||||
```
|
||||
|
||||
**Delete a Group:**
|
||||
|
||||
```bash
|
||||
rdci group -d 1
|
||||
```
|
||||
|
||||
#### 🗂️ Field Groups
|
||||
|
||||
Manage field groups to monitor specific GPU metrics.
|
||||
|
||||
**Create a Field Group:**
|
||||
|
||||
```bash
|
||||
rdci fieldgroup -c <fgroup> -f 150,155
|
||||
```
|
||||
|
||||
**List Field Groups:**
|
||||
|
||||
```bash
|
||||
rdci fieldgroup -l
|
||||
```
|
||||
|
||||
**Delete a Field Group:**
|
||||
|
||||
```bash
|
||||
rdci fieldgroup -d 1
|
||||
```
|
||||
> [!IMPORTANT]
|
||||
>### 🛑 Monitor Errors
|
||||
>
|
||||
>Define fields to monitor RAS ECC counters.
|
||||
>
|
||||
>- **Correctable ECC Errors:**
|
||||
>
|
||||
> ```bash
|
||||
> 312 RDC_FI_ECC_CORRECT_TOTAL
|
||||
> ```
|
||||
>
|
||||
>- **Uncorrectable ECC Errors:**
|
||||
>
|
||||
> ```bash
|
||||
> 313 RDC_FI_ECC_UNCORRECT_TOTAL
|
||||
> ```
|
||||
|
||||
### 📈 Device Monitoring
|
||||
|
||||
Monitor GPU fields such as temperature, power usage, and utilization.
|
||||
|
||||
**Command:**
|
||||
|
||||
```bash
|
||||
rdci dmon -f <field_group> -g <gpu_group> -c 5 -d 1000
|
||||
```
|
||||
|
||||
**Sample Output:**
|
||||
|
||||
```
|
||||
1 group found
|
||||
|
||||
+-----------+-------------+---------------+
|
||||
| GPU Index | TEMP (m°C) | POWER (µW) |
|
||||
+-----------+-------------+---------------+
|
||||
| 0 | 25000 | 520500 |
|
||||
+-----------+-------------+---------------+
|
||||
```
|
||||
|
||||
### 📊 Job Stats
|
||||
|
||||
Display GPU statistics for any given workload.
|
||||
|
||||
**Start Recording Stats:**
|
||||
|
||||
```bash
|
||||
rdci stats -s 2 -g 1
|
||||
```
|
||||
|
||||
**Stop Recording Stats:**
|
||||
|
||||
```bash
|
||||
rdci stats -x 2
|
||||
```
|
||||
|
||||
**Display Job Stats:**
|
||||
|
||||
```bash
|
||||
rdci stats -j 2
|
||||
```
|
||||
|
||||
**Sample Output:**
|
||||
|
||||
```
|
||||
Summary:
|
||||
Executive Status:
|
||||
|
||||
Start time: 1586795401
|
||||
End time: 1586795445
|
||||
Total execution time: 44
|
||||
|
||||
Energy Consumed (Joules): 21682
|
||||
Power Usage (Watts): Max: 49 Min: 13 Avg: 34
|
||||
GPU Clock (MHz): Max: 1000 Min: 300 Avg: 903
|
||||
GPU Utilization (%): Max: 69 Min: 0 Avg: 2
|
||||
Max GPU Memory Used (bytes): 524320768
|
||||
Memory Utilization (%): Max: 12 Min: 11 Avg: 12
|
||||
```
|
||||
|
||||
### 🩺 Diagnostic
|
||||
|
||||
Run diagnostics on a GPU group to ensure system health.
|
||||
|
||||
**Command:**
|
||||
|
||||
```bash
|
||||
rdci diag -g <gpu_group>
|
||||
```
|
||||
|
||||
**Sample Output:**
|
||||
|
||||
```
|
||||
No compute process: Pass
|
||||
Node topology check: Pass
|
||||
GPU parameters check: Pass
|
||||
Compute Queue ready: Pass
|
||||
System memory check: Pass
|
||||
=============== Diagnostic Details ==================
|
||||
No compute process: No processes running on any devices.
|
||||
Node topology check: No link detected.
|
||||
GPU parameters check: GPU 0 Critical Edge temperature in range.
|
||||
Compute Queue ready: Run binary search task on GPU 0 Pass.
|
||||
System memory check: Max Single Allocation Memory Test for GPU 0 Pass. CPUAccessToGPUMemoryTest for GPU 0 Pass. GPUAccessToCPUMemoryTest for GPU 0 Pass.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Integration with Third-Party Tools
|
||||
|
||||
RDC integrates seamlessly with tools like **Prometheus**, **Grafana**, and **Reliability, Availability, and Serviceability (RAS)** to enhance monitoring and visualization.
|
||||
|
||||
### 🐍 Python Bindings
|
||||
|
||||
RDC provides a generic Python class `RdcReader` to simplify telemetry gathering.
|
||||
|
||||
**Sample Program:**
|
||||
|
||||
```python
|
||||
from RdcReader import RdcReader
|
||||
from RdcUtil import RdcUtil
|
||||
from rdc_bootstrap import *
|
||||
import time
|
||||
|
||||
default_field_ids = [
|
||||
rdc_field_t.RDC_FI_POWER_USAGE,
|
||||
rdc_field_t.RDC_FI_GPU_UTIL
|
||||
]
|
||||
|
||||
class SimpleRdcReader(RdcReader):
|
||||
def __init__(self):
|
||||
super().__init__(ip_port=None, field_ids=default_field_ids, update_freq=1000000)
|
||||
|
||||
def handle_field(self, gpu_index, value):
|
||||
field_name = self.rdc_util.field_id_string(value.field_id).lower()
|
||||
print(f"{value.ts} {gpu_index}:{field_name} {value.value.l_int}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
reader = SimpleRdcReader()
|
||||
while True:
|
||||
time.sleep(1)
|
||||
reader.process()
|
||||
```
|
||||
|
||||
**Running the Example:**
|
||||
|
||||
```bash
|
||||
# Ensure RDC shared libraries are in the library path and RdcReader.py is in PYTHONPATH
|
||||
python SimpleReader.py
|
||||
```
|
||||
|
||||
### 📈 Prometheus Plugin
|
||||
|
||||
The Prometheus plugin allows you to monitor events and send alerts.
|
||||
|
||||
**Installation:**
|
||||
|
||||
1. **Install Prometheus Client:**
|
||||
|
||||
```bash
|
||||
pip install prometheus_client
|
||||
```
|
||||
|
||||
2. **Run the Prometheus Plugin:**
|
||||
|
||||
```bash
|
||||
python rdc_prometheus.py
|
||||
```
|
||||
|
||||
3. **Verify Plugin:**
|
||||
|
||||
```bash
|
||||
curl localhost:5000
|
||||
```
|
||||
|
||||
**Integration Steps:**
|
||||
|
||||
1. **Download and Install Prometheus:**
|
||||
- [Prometheus GitHub](https://github.com/prometheus/prometheus)
|
||||
|
||||
2. **Configure Prometheus Targets:**
|
||||
- Modify `prometheus_targets.json` to point to your compute nodes.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"targets": [
|
||||
"rdc_test1.amd.com:5000",
|
||||
"rdc_test2.amd.com:5000"
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
3. **Start Prometheus with Configuration File:**
|
||||
|
||||
```bash
|
||||
prometheus --config.file=/path/to/rdc_prometheus_example.yml
|
||||
```
|
||||
|
||||
4. **Access Prometheus UI:**
|
||||
- Open [http://localhost:9090](http://localhost:9090) in your browser.
|
||||
|
||||
### 📊 Grafana Integration
|
||||
|
||||
Grafana provides advanced visualization capabilities for RDC metrics.
|
||||
|
||||
**Installation:**
|
||||
|
||||
1. **Download Grafana:**
|
||||
- [Grafana Download](https://grafana.com/grafana/download)
|
||||
|
||||
2. **Install Grafana:**
|
||||
- Follow the [Installation Instructions](https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/).
|
||||
|
||||
3. **Start Grafana Server:**
|
||||
|
||||
```bash
|
||||
sudo systemctl start grafana-server
|
||||
sudo systemctl status grafana-server
|
||||
```
|
||||
|
||||
4. **Access Grafana:**
|
||||
- Open [http://localhost:3000](http://localhost:3000/) in your browser and log in with the default credentials (`admin`/`admin`).
|
||||
|
||||
**Configuration Steps:**
|
||||
|
||||
1. **Add Prometheus Data Source:**
|
||||
- Navigate to **Configuration → Data Sources → Add data source → Prometheus**.
|
||||
- Set the URL to [http://localhost:9090](http://localhost:9090) and save.
|
||||
|
||||
2. **Import RDC Dashboard:**
|
||||
- Click the **+** icon and select **Import**.
|
||||
- Upload `rdc_grafana_dashboard_example.json` from the `python_binding` folder.
|
||||
- Select the desired compute node for visualization.
|
||||
|
||||
### 🛡️ Reliability, Availability, and Serviceability (RAS) Plugin
|
||||
|
||||
The RAS plugin enables monitoring and counting of ECC (Error-Correcting Code) errors.
|
||||
|
||||
**Installation:**
|
||||
|
||||
1. **Ensure GPU Supports RAS:**
|
||||
- The GPU must support RAS features.
|
||||
|
||||
2. **RDC Installation Includes RAS Library:**
|
||||
- `librdc_ras.so` is located in `/opt/rocm-4.2.0/rdc/lib`.
|
||||
|
||||
**Usage:**
|
||||
|
||||
- **Monitor ECC Errors:**
|
||||
|
||||
```bash
|
||||
rdci dmon -i 0 -e 600,601
|
||||
```
|
||||
|
||||
**Sample Output:**
|
||||
|
||||
```
|
||||
GPU ECC_CORRECT ECC_UNCORRECT
|
||||
0 0 0
|
||||
```
|
||||
|
||||
---
|
||||
> [!IMPORTANT]
|
||||
>## 🐞 Troubleshooting
|
||||
>
|
||||
> ### Known Issues
|
||||
>#### 🛑 dmon Fields Return N/A
|
||||
>
|
||||
>1. **Missing Libraries:**
|
||||
> - Verify `/opt/rocm/lib/rdc/librdc_*.so` exists.
|
||||
> - Ensure all related libraries (rocprofiler, rocruntime, etc.) are present.
|
||||
>
|
||||
>2. **Unsupported GPU:**
|
||||
> - Most metrics work on MI300 and newer.
|
||||
> - Limited metrics on MI200.
|
||||
> - Consumer GPUs (e.g., RX6800) have fewer supported metrics.
|
||||
>
|
||||
>#### 🐍 dmon RocProfiler Fields Return Zeros
|
||||
>
|
||||
>**Error Message:**
|
||||
>
|
||||
>```
|
||||
>terminate called after throwing an instance of 'std::runtime_error'
|
||||
> what(): hsa error code: 4104 HSA_STATUS_ERROR_OUT_OF_RESOURCES: The runtime failed to allocate the necessary resources. This error may also occur when the core runtime library needs to spawn threads or create internal OS-specific events.
|
||||
>Aborted (core dumped)
|
||||
>```
|
||||
>
|
||||
>**Solution:**
|
||||
>
|
||||
>1. **Missing Groups:**
|
||||
> - Ensure `video` and `render` groups exist.
|
||||
>
|
||||
> ```bash
|
||||
> sudo usermod -aG video,render $USER
|
||||
> ```
|
||||
>
|
||||
> - Log out and log back in to apply group changes.
|
||||
>
|
||||
>### 🐛 Troubleshooting RDCD
|
||||
>
|
||||
>- **View RDCD Logs:**
|
||||
>
|
||||
> ```bash
|
||||
> sudo journalctl -u rdc
|
||||
> ```
|
||||
>
|
||||
>- **Run RDCD with Debug Logs:**
|
||||
>
|
||||
> ```bash
|
||||
> RDC_LOG=DEBUG /opt/rocm/bin/rdcd
|
||||
> ```
|
||||
>
|
||||
> - **Logging Levels Supported:** ERROR, INFO, DEBUG
|
||||
>
|
||||
>- **Enable Additional Logging Messages:**
|
||||
>
|
||||
> ```bash
|
||||
> export RSMI_LOGGING=3
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 📄 License
|
||||
|
||||
RDC is open-source and available under the [MIT License](https://opensource.org/licenses/MIT).
|
||||
|
||||
---
|
||||
|
||||
## 📧 Support
|
||||
|
||||
For support and further inquiries, please refer to the [**ROCm Documentation**](https://rocm.docs.amd.com/projects/rdc/en/latest/) or contact the maintainers through the repository's issue tracker.
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script should be called only once to generate a root
|
||||
# certificate
|
||||
|
||||
mkdir -p CA
|
||||
pushd CA
|
||||
mkdir private newcerts
|
||||
chmod 700 private newcerts
|
||||
|
||||
# Our next step is to create a database for the certificates we will sign:
|
||||
echo '01' >serial
|
||||
touch index.txt
|
||||
|
||||
# openssl_part1.cnf
|
||||
|
||||
# Create the Root Certificate
|
||||
# This call of openssl encrypts the keys
|
||||
# openssl req -new -x509 extensions v3_ca -keyout private/rdc_cakey.pem \
|
||||
# -out rdc_cacert.pem -days 3650 -config ../openssl.cnf
|
||||
|
||||
# This call of openssl does not encrypt the keys
|
||||
openssl req -new -x509 -nodes -extensions v3_ca -keyout private/rdc_cakey.pem \
|
||||
-out rdc_cacert.pem -days 3650 -config ../openssl.cnf
|
||||
# This generates:
|
||||
# A private key in private/rdc_cakey.pem
|
||||
# A root CA certificate in rdc_cacert.pem (distribute to clients)
|
||||
|
||||
popd
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script generates ssl keys and self-signed certificates
|
||||
|
||||
INSTALL_RT="artifacts"
|
||||
|
||||
generate_artifacts() {
|
||||
HOST=$1
|
||||
echo "**********************************"
|
||||
echo "*** Generating $HOST artifacts ***"
|
||||
echo "**********************************"
|
||||
|
||||
mkdir -p ${INSTALL_RT}/${HOST}/private
|
||||
mkdir -p ${INSTALL_RT}/${HOST}/certs
|
||||
|
||||
echo "Generate CSR..."
|
||||
openssl req -new -nodes -out rdc_csr.pem -config ../openssl.cnf
|
||||
echo "Sign Certificate..."
|
||||
openssl ca -out rdc_${HOST}_cert.pem -config ../openssl.cnf -infiles rdc_csr.pem
|
||||
mv rdc_${HOST}_cert.pem ${INSTALL_RT}/${HOST}/certs/
|
||||
mv key.pem ${INSTALL_RT}/${HOST}/private/rdc_${HOST}_cert.key
|
||||
cp rdc_cacert.pem ${INSTALL_RT}/${HOST}/certs/
|
||||
}
|
||||
|
||||
pushd CA
|
||||
echo
|
||||
echo "**********************"
|
||||
echo "IMPORTANT:"
|
||||
echo " * Make sure to use the same hostname (wildcards accepted) each"
|
||||
echo " time when prompted for \"Common Name\""
|
||||
echo " * Make sure to select \"y\" when you are asked whether you want"
|
||||
echo " to sign the certificates"
|
||||
echo "**********************"
|
||||
echo
|
||||
generate_artifacts "server"
|
||||
generate_artifacts "client"
|
||||
rm rdc_cacert.pem
|
||||
cp ../install_client.sh ../install_server.sh $INSTALL_RT
|
||||
|
||||
popd
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Note:
|
||||
# * This script should reside in the artifacts directory
|
||||
# when executed.
|
||||
# * This script may require root privilege
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Need to specify a installation root directory (e.g., /etc/rdc)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INSTALL_DIR=$1
|
||||
mkdir -p $INSTALL_DIR
|
||||
cp -R client $INSTALL_DIR
|
||||
chown -R rdc:rdc $INSTALL_DIR/client
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Note:
|
||||
# * This script should reside in the artifacts directory
|
||||
# when executed.
|
||||
# * This script may require root privilege
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Need to specify a installation root directory (e.g., /etc/rdc)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INSTALL_DIR=$1
|
||||
mkdir -p $INSTALL_DIR
|
||||
cp -R server $INSTALL_DIR
|
||||
mkdir -p $INSTALL_DIR/client/certs
|
||||
cp client/certs/rdc_cacert.pem $INSTALL_DIR/client/certs
|
||||
chmod 700 $INSTALL_DIR/server/private
|
||||
chown -R rdc:rdc $INSTALL_DIR/server
|
||||
chown -R rdc:rdc $INSTALL_DIR/client
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#
|
||||
# OpenSSL configuration file.
|
||||
#
|
||||
|
||||
# Establish working directory.
|
||||
|
||||
dir = .
|
||||
|
||||
[ ca ]
|
||||
default_ca = CA_default
|
||||
|
||||
[ CA_default ]
|
||||
serial = $dir/serial
|
||||
database = $dir/index.txt
|
||||
new_certs_dir = $dir/newcerts
|
||||
certificate = $dir/rdc_cacert.pem
|
||||
private_key = $dir/private/rdc_cakey.pem
|
||||
default_days = 365
|
||||
default_md = sha512
|
||||
preserve = no
|
||||
email_in_dn = no
|
||||
nameopt = default_ca
|
||||
certopt = default_ca
|
||||
policy = policy_match
|
||||
unique_subject = no
|
||||
copy_extensions = copyall
|
||||
|
||||
[ policy_match ]
|
||||
countryName = match
|
||||
stateOrProvinceName = match
|
||||
organizationName = match
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
[ req ]
|
||||
default_bits = 4096 # Size of keys
|
||||
default_keyfile = key.pem # name of generated keys
|
||||
default_md = sha512 # message digest algorithm
|
||||
string_mask = nombstr # permitted characters
|
||||
distinguished_name = req_distinguished_name
|
||||
req_extensions = v3_req
|
||||
|
||||
[ req_distinguished_name ]
|
||||
# Variable name Prompt string
|
||||
#---------------------- ----------------------------------
|
||||
0.organizationName = Organization Name (company)
|
||||
organizationalUnitName = Organizational Unit Name (department, division)
|
||||
emailAddress = Email Address
|
||||
emailAddress_max = 40
|
||||
localityName = Locality Name (city, district)
|
||||
stateOrProvinceName = State or Province Name (full name)
|
||||
countryName = Country Name (2 letter code)
|
||||
countryName_min = 2
|
||||
countryName_max = 2
|
||||
commonName = Common Name (hostname, IP, or your name)
|
||||
commonName_max = 64
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Specify default values below for the fields above. This speeds things up if
|
||||
# and is more consistent if you have to run the openssl commands repeatedly.
|
||||
#-------------------------------------------------------------------------------
|
||||
# < ** REPLACE VALUES IN THIS SECTION WITH APPROPRIATE VALUES FOR YOUR ORG. **>
|
||||
0.organizationName_default = MyCompany
|
||||
organizationalUnitName_default = MyCompanyUnit
|
||||
emailAddress_default = MyEmailAddress
|
||||
localityName_default = MyCity
|
||||
stateOrProvinceName_default = MyStateProvince
|
||||
countryName_default = MC
|
||||
# wildcards are acceptable for domain; e.g., *.amd.com
|
||||
commonName_default = Mydomain
|
||||
|
||||
[ v3_ca ]
|
||||
basicConstraints = CA:TRUE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer:always
|
||||
|
||||
[ v3_req ]
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[ req_ext ]
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
# < ** MODIFY BELOW TO YOUR NEEDS. WILDCARDS ARE ACCEPTED. **>
|
||||
DNS.1 = localhost
|
||||
DNS.2 = *.amd.com
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# How-to generate authentication files
|
||||
|
||||
1. Modify openssl.cnf to match your company info
|
||||
2. ./01gen_root_cert.sh
|
||||
3. ./02gen_ssl_artifacts.sh
|
||||
4. cd CA/artifacts
|
||||
5. sudo ./install_client.sh /etc/rdc
|
||||
6. sudo ./install_server.sh /etc/rdc
|
||||
|
||||
For a full guide refer to:
|
||||
https://rocm.docs.amd.com/projects/rdc/en/latest/install/handbook.html#generate-files-for-authentication
|
||||
@@ -0,0 +1,38 @@
|
||||
# This module provides a rocprofiler::rocprofiler package
|
||||
# You can specify the ROCM directory by setting ROCM_DIR
|
||||
|
||||
set(NAME rocprofiler)
|
||||
|
||||
if(NOT DEFINED ROCM_DIR)
|
||||
set(ROCM_DIR "/opt/rocm")
|
||||
endif()
|
||||
list(APPEND CMAKE_PREFIX_PATH ${ROCM_DIR})
|
||||
|
||||
find_library(${NAME}_LIBRARY NAMES ${NAME} ${NAME}64 REQUIRED REGISTRY_VIEW BOTH PATH_SUFFIXES lib)
|
||||
|
||||
if(NOT DEFINED (${NAME}_INCLUDE_DIR))
|
||||
find_path(
|
||||
${NAME}_INCLUDE_DIR
|
||||
NAMES ${NAME}.h
|
||||
HINTS "${ROCM_DIR}/include"
|
||||
PATH_SUFFIXES ${NAME} ${NAME}/inc
|
||||
)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
${NAME}
|
||||
FOUND_VAR ${NAME}_FOUND
|
||||
REQUIRED_VARS ${NAME}_LIBRARY ${NAME}_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if(${NAME}_FOUND AND NOT TARGET ${NAME}::${NAME})
|
||||
add_library(${NAME}::${NAME} UNKNOWN IMPORTED)
|
||||
set_target_properties(
|
||||
${NAME}::${NAME}
|
||||
PROPERTIES
|
||||
IMPORTED_LOCATION "${${NAME}_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_${NAME}_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${${NAME}_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,68 @@
|
||||
# This module provides a rvs::rvs package
|
||||
# You can specify the ROCM directory by setting ROCM_DIR
|
||||
|
||||
set(NAME rvs)
|
||||
|
||||
if(NOT DEFINED ROCM_DIR)
|
||||
set(ROCM_DIR "/opt/rocm")
|
||||
endif()
|
||||
list(APPEND CMAKE_PREFIX_PATH ${ROCM_DIR})
|
||||
|
||||
find_library(
|
||||
${NAME}_LIBRARY
|
||||
NAMES
|
||||
${NAME}
|
||||
${NAME}64
|
||||
${NAME}lib # RVS is special and is named librvslib.so
|
||||
REQUIRED
|
||||
REGISTRY_VIEW
|
||||
BOTH
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
|
||||
if(NOT DEFINED (${NAME}_INCLUDE_DIR))
|
||||
find_path(
|
||||
${NAME}_INCLUDE_DIR
|
||||
NAMES ${NAME}.h
|
||||
HINTS "${ROCM_DIR}/include"
|
||||
PATH_SUFFIXES ${NAME} ${NAME}/inc
|
||||
)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
${NAME}
|
||||
FOUND_VAR ${NAME}_FOUND
|
||||
REQUIRED_VARS ${NAME}_LIBRARY ${NAME}_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if(${NAME}_FOUND AND NOT TARGET ${NAME}::${NAME})
|
||||
add_library(${NAME}::${NAME} UNKNOWN IMPORTED)
|
||||
set_target_properties(
|
||||
${NAME}::${NAME}
|
||||
PROPERTIES
|
||||
IMPORTED_LOCATION "${${NAME}_LIBRARY}"
|
||||
INTERFACE_COMPILE_OPTIONS "${PC_${NAME}_CFLAGS_OTHER}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${${NAME}_INCLUDE_DIR}"
|
||||
)
|
||||
find_library(rocm-core NAMES rocm-core REQUIRED)
|
||||
find_package(yaml-cpp REQUIRED)
|
||||
find_package(rocblas REQUIRED)
|
||||
find_package(hipblaslt REQUIRED)
|
||||
find_package(hsakmt REQUIRED)
|
||||
find_package(hip REQUIRED)
|
||||
find_package(hsa-runtime64 REQUIRED)
|
||||
find_package(amd_smi REQUIRED)
|
||||
target_link_libraries(
|
||||
${NAME}::${NAME}
|
||||
INTERFACE
|
||||
${rocm-core}
|
||||
yaml-cpp
|
||||
roc::rocblas
|
||||
roc::hipblaslt
|
||||
hsakmt::hsakmt
|
||||
hip::amdhip64
|
||||
hsa-runtime64::hsa-runtime64
|
||||
amd_smi
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,11 @@
|
||||
set(PACKAGE_VERSION "@RDC_VERSION@")
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,19 @@
|
||||
# - Config file for the rdc package
|
||||
# It defines the following variables
|
||||
# RDC_INCLUDE_DIRS - include directories for rdc
|
||||
# RDC_LIBRARIES - libraries to link against
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
# Compute paths
|
||||
get_filename_component(RDC_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
set(ROCM_RDC_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
set(ROCM_RDC_LIB_DIR "${PACKAGE_PREFIX_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
# Our library dependencies (contains definitions for IMPORTED targets)
|
||||
if(NOT TARGET rdc_libs AND NOT rdc_BINARY_DIR)
|
||||
include("${RDC_CMAKE_DIR}/rdcTargets.cmake")
|
||||
endif()
|
||||
|
||||
# These are IMPORTED targets created by rdcTargets.cmake
|
||||
set(ROCM_RDC_LIBRARIES "@CONF_LIBS@")
|
||||
@@ -0,0 +1,126 @@
|
||||
################################################################################
|
||||
##
|
||||
## The University of Illinois/NCSA
|
||||
## Open Source License (NCSA)
|
||||
##
|
||||
## Copyright (c) 2014-2017, Advanced Micro Devices, Inc. All rights reserved.
|
||||
##
|
||||
## Developed by:
|
||||
##
|
||||
## AMD Research and AMD HSA Software Development
|
||||
##
|
||||
## Advanced Micro Devices, Inc.
|
||||
##
|
||||
## www.amd.com
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to
|
||||
## deal with 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:
|
||||
##
|
||||
## - Redistributions of source code must retain the above copyright notice,
|
||||
## this list of conditions and the following disclaimers.
|
||||
## - Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimers in
|
||||
## the documentation and#or other materials provided with the distribution.
|
||||
## - Neither the names of Advanced Micro Devices, Inc,
|
||||
## nor the names of its contributors may be used to endorse or promote
|
||||
## products derived from this Software without specific prior written
|
||||
## permission.
|
||||
##
|
||||
## 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 CONTRIBUTORS 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 WITH THE SOFTWARE.
|
||||
##
|
||||
################################################################################
|
||||
|
||||
## Parses the VERSION_STRING variable and places
|
||||
## the first, second and third number values in
|
||||
## the major, minor and patch variables.
|
||||
function(parse_version VERSION_STRING)
|
||||
string(FIND ${VERSION_STRING} "-" STRING_INDEX)
|
||||
|
||||
if(${STRING_INDEX} GREATER -1)
|
||||
math(EXPR STRING_INDEX "${STRING_INDEX} + 1")
|
||||
string(SUBSTRING ${VERSION_STRING} ${STRING_INDEX} -1 VERSION_BUILD)
|
||||
endif()
|
||||
|
||||
string(REGEX MATCHALL "[0123456789]+" VERSIONS ${VERSION_STRING})
|
||||
list(LENGTH VERSIONS VERSION_COUNT)
|
||||
|
||||
if(${VERSION_COUNT} GREATER 0)
|
||||
list(GET VERSIONS 0 MAJOR)
|
||||
set(VERSION_MAJOR ${MAJOR} PARENT_SCOPE)
|
||||
set(TEMP_VERSION_STRING "${MAJOR}")
|
||||
endif()
|
||||
|
||||
if(${VERSION_COUNT} GREATER 1)
|
||||
list(GET VERSIONS 1 MINOR)
|
||||
set(VERSION_MINOR ${MINOR} PARENT_SCOPE)
|
||||
set(TEMP_VERSION_STRING "${TEMP_VERSION_STRING}.${MINOR}")
|
||||
endif()
|
||||
|
||||
if(${VERSION_COUNT} GREATER 2)
|
||||
list(GET VERSIONS 2 PATCH)
|
||||
set(VERSION_PATCH ${PATCH} PARENT_SCOPE)
|
||||
set(TEMP_VERSION_STRING "${TEMP_VERSION_STRING}.${PATCH}")
|
||||
endif()
|
||||
|
||||
set(VERSION_STRING "${TEMP_VERSION_STRING}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
## Gets the current version of the repository
|
||||
## using versioning tags and git describe.
|
||||
## Passes back a packaging version string
|
||||
## and a library version string.
|
||||
function(get_version_from_tag DEFAULT_VERSION_STRING VERSION_PREFIX GIT)
|
||||
parse_version(${DEFAULT_VERSION_STRING})
|
||||
|
||||
if(GIT)
|
||||
execute_process(
|
||||
COMMAND git describe --tags --dirty --long --match ${VERSION_PREFIX}-[0-9.]*
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_TAG_STRING
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE RESULT
|
||||
)
|
||||
if(${RESULT} EQUAL 0)
|
||||
parse_version(${GIT_TAG_STRING})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(VERSION_STRING "${VERSION_STRING}" PARENT_SCOPE)
|
||||
set(VERSION_MAJOR "${VERSION_MAJOR}" PARENT_SCOPE)
|
||||
set(VERSION_MINOR "${VERSION_MINOR}" PARENT_SCOPE)
|
||||
set(VERSION_PATCH "${VERSION_PATCH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(num_change_since_prev_pkg VERSION_PREFIX)
|
||||
find_program(get_commits NAMES version_util.sh PATHS ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules)
|
||||
if(get_commits)
|
||||
execute_process(
|
||||
COMMAND ${get_commits} -c ${VERSION_PREFIX}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE NUM_COMMITS
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE RESULT
|
||||
)
|
||||
|
||||
set(NUM_COMMITS "${NUM_COMMITS}" PARENT_SCOPE)
|
||||
|
||||
if(${RESULT} EQUAL 0)
|
||||
message("${NUM_COMMITS} were found since previous release")
|
||||
else()
|
||||
message("Unable to determine number of commits since previous release")
|
||||
endif()
|
||||
else()
|
||||
message("WARNING: Didn't find version_util.sh")
|
||||
set(NUM_COMMITS "unknown" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Handle commandline args
|
||||
while [ "$1" != "" ]; do
|
||||
case $1 in
|
||||
-c ) # Commits since prevous tag
|
||||
TARGET="count" ;;
|
||||
* )
|
||||
TARGET="count"
|
||||
break ;;
|
||||
esac
|
||||
shift 1
|
||||
done
|
||||
TAG_PREFIX=$1
|
||||
reg_ex="${TAG_PREFIX}*"
|
||||
|
||||
commits_since_last_tag() {
|
||||
TAG_ARR=(`git tag --sort=committerdate -l ${reg_ex} | tail -2`)
|
||||
# if we don't have 2 tags, just say there were 0 commits since
|
||||
# last tag
|
||||
if [ ${#TAG_ARR[@]} != 2 ]; then
|
||||
echo 0
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PREVIOUS_TAG=${TAG_ARR[0]}
|
||||
CURRENT_TAG=${TAG_ARR[1]}
|
||||
|
||||
PREV_CMT_NUM=`git rev-list --count $PREVIOUS_TAG`
|
||||
CURR_CMT_NUM=`git rev-list --count $CURRENT_TAG`
|
||||
|
||||
# Commits since prevous tag:
|
||||
let NUM_COMMITS="${CURR_CMT_NUM}-${PREV_CMT_NUM}"
|
||||
echo $NUM_COMMITS
|
||||
}
|
||||
|
||||
case $TARGET in
|
||||
count) commits_since_last_tag ;;
|
||||
*) die "Invalid target $target" ;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright (c) 2021 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "common/rdc_capabilities.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/capability.h>
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
int GetCapability(cap_value_t cap, cap_flag_t cap_type, bool* enabled) {
|
||||
cap_t caps;
|
||||
|
||||
assert(enabled != nullptr);
|
||||
|
||||
if (enabled == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get process's current capabilities
|
||||
caps = cap_get_proc();
|
||||
if (caps == nullptr) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
cap_flag_value_t val;
|
||||
if (cap_get_flag(caps, cap, cap_type, &val) == -1) {
|
||||
int ret = errno;
|
||||
cap_free(caps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cap_free(caps) == -1) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
*enabled = (val == CAP_SET ? true : false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// !enable means disable;
|
||||
int ModifyCapability(cap_value_t cap, cap_flag_t cap_type, bool enable) {
|
||||
cap_t caps;
|
||||
cap_value_t cap_list[1];
|
||||
|
||||
// Get process's current capabilities
|
||||
caps = cap_get_proc();
|
||||
if (caps == nullptr) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
// the 1 in the call below is the size of the cap_list array
|
||||
cap_list[0] = cap;
|
||||
if (cap_set_flag(caps, cap_type, 1, cap_list, enable ? CAP_SET : CAP_CLEAR) == -1) {
|
||||
int ret = errno;
|
||||
cap_free(caps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cap_set_proc(caps) == -1) {
|
||||
int ret = errno;
|
||||
cap_free(caps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cap_free(caps) == -1) {
|
||||
return errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright (c) 2021 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_RDC_CAPABILITIES_H_
|
||||
#define COMMON_RDC_CAPABILITIES_H_
|
||||
|
||||
#include <sys/capability.h>
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
int GetCapability(cap_value_t cap, cap_flag_t cap_type, bool* enabled);
|
||||
int ModifyCapability(cap_value_t cap, cap_flag_t cap_type, bool enable);
|
||||
|
||||
struct ScopedCapability {
|
||||
ScopedCapability(cap_value_t cp, cap_flag_t cpt) : cap_(cp), cap_type_(cpt), error_(0) {
|
||||
error_ = ModifyCapability(cap_, cap_type_, true);
|
||||
}
|
||||
~ScopedCapability() { error_ = ModifyCapability(cap_, cap_type_, false); }
|
||||
void Relinquish(void) { error_ = ModifyCapability(cap_, cap_type_, false); }
|
||||
int error(void) { return error_; }
|
||||
|
||||
private:
|
||||
cap_value_t cap_;
|
||||
cap_flag_t cap_type_;
|
||||
int error_;
|
||||
};
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // COMMON_RDC_CAPABILITIES_H_
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
|
||||
// Description Fields:
|
||||
// Arg # Type Meaning
|
||||
// -------------------------------------------------
|
||||
// 1 rdc_field_t enum of field
|
||||
// 2 string description of enum
|
||||
// 3 string rdci display label
|
||||
// 4 bool do or do not display in rdci
|
||||
// rdc_field_t Description rdci label To Display
|
||||
// =========== =========== ========= ==========
|
||||
#ifndef FLD_DESC_ENT
|
||||
#define FLD_DESC_ENT(ID, DESC, LABEL, DISPLAY)
|
||||
#endif
|
||||
|
||||
FLD_DESC_ENT(RDC_FI_INVALID, "Unknown/Invalid field", "INVALID", false)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_COUNT, "GPU count in the system", "GPU_COUNT", true)
|
||||
FLD_DESC_ENT(RDC_FI_DEV_NAME, "Name of the device", "DEV_NAME", true)
|
||||
FLD_DESC_ENT(RDC_FI_OAM_ID, "OAM ID of the device", "OAM_ID", true)
|
||||
|
||||
FLD_DESC_ENT(RDC_FI_DEV_ID, "ID of the device", "DEV_ID", true)
|
||||
FLD_DESC_ENT(RDC_FI_REV_ID, "Revision ID of the device", "REV_ID", true)
|
||||
FLD_DESC_ENT(RDC_FI_TARGET_GRAPHICS_VERSION, "GFX version of the device", "GFX", true)
|
||||
FLD_DESC_ENT(RDC_FI_NUM_OF_COMPUTE_UNITS, "Number of Compute Units", "COMPUTE_UNITS", true)
|
||||
FLD_DESC_ENT(RDC_FI_UUID, "Unique ID of the device AKA asic_serial", "UUID", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_PARTITION_COUNT, "GPU partition count", "PARTITION_COUNT", true)
|
||||
|
||||
FLD_DESC_ENT(RDC_FI_GPU_CLOCK, "Current GPU clock frequencies", "GPU_CLOCK", true)
|
||||
FLD_DESC_ENT(RDC_FI_MEM_CLOCK, "Current Memory clock frequencies", "MEM_CLOCK", true)
|
||||
FLD_DESC_ENT(RDC_FI_MEMORY_TEMP, "Memory temperature in millidegrees Celsius", "MEMORY_TEMP", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_TEMP, "GPU temperature in millidegrees Celsius", "GPU_TEMP", true)
|
||||
FLD_DESC_ENT(RDC_FI_POWER_USAGE, "Power usage in microwatts", "POWER_USAGE", true)
|
||||
FLD_DESC_ENT(RDC_FI_PCIE_TX, "PCIe Tx utilization in bytes/second", "PCIE_TX", true)
|
||||
FLD_DESC_ENT(RDC_FI_PCIE_RX, "PCIe Rx utilization in bytes/second", "PCIE_RX", true)
|
||||
FLD_DESC_ENT(RDC_FI_PCIE_BANDWIDTH, "PCIe bandwidth in Mbps", "PCIE_BANDWIDTH", true)
|
||||
|
||||
FLD_DESC_ENT(RDC_FI_GPU_UTIL, "GPU busy percentage", "GPU_UTIL", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_MEMORY_USAGE, "Memory usage of the GPU instance in bytes", "GPU_MEMORY_USAGE", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_MEMORY_TOTAL, "Total memory of the GPU instance", "GPU_MEMORY_TOTAL", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_MM_ENC_UTIL, "Mutilmedia encoder busy percentage", "GPU_MM_ENC_UTIL", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_MM_DEC_UTIL, "Mutilmedia decoder busy percentage", "GPU_MM_DEC_UTIL", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_MEMORY_ACTIVITY, "Memory busy percentage", "GPU_MEM_UTIL", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_MEMORY_MAX_BANDWIDTH, "Memory max bandwidth", "GPU_MEM_MAX_BANDWIDTH", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_MEMORY_CUR_BANDWIDTH, "Memory current bandwidth", "GPU_MEM_CUR_BANDWIDTH", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_BUSY_PERCENT, "GPU busy percentage", "GPU_BUSY_PERCENT", true)
|
||||
FLD_DESC_ENT(RDC_FI_GPU_PAGE_RETRIED, "Retried page of the GPU instance", "GPU_PAGE_RETRIED", true)
|
||||
|
||||
// ECC totals
|
||||
FLD_DESC_ENT(RDC_FI_ECC_CORRECT_TOTAL, "Accumulated Single Error Correction", "ECC_CORRECT", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_UNCORRECT_TOTAL, "Accumulated Double Error Detection", "ECC_UNCORRECT", true)
|
||||
|
||||
// ECC blocks
|
||||
FLD_DESC_ENT(RDC_FI_ECC_SDMA_CE, "SDMA Correctable Error", "ECC_SDMA_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_SDMA_UE, "SDMA Uncorrectable Error", "ECC_SDMA_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_GFX_CE, "GFX Correctable Error", "ECC_GFX_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_GFX_UE, "GFX Uncorrectable Error", "ECC_GFX_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MMHUB_CE, "MMHUB Correctable Error", "ECC_MMHUB_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MMHUB_UE, "MMHUB Uncorrectable Error", "ECC_MMHUB_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_ATHUB_CE, "ATHUB Correctable Error", "ECC_ATHUB_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_ATHUB_UE, "ATHUB Uncorrectable Error", "ECC_ATHUB_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_PCIE_BIF_CE, "PCIE_BIF Correctable Error", "ECC_PCIE_BIF_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_PCIE_BIF_UE, "PCIE_BIF Uncorrectable Error", "ECC_PCIE_BIF_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_HDP_CE, "HDP Correctable Error", "ECC_HDP_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_HDP_UE, "HDP Uncorrectable Error", "ECC_HDP_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_XGMI_WAFL_CE, "XGMI_WAFL Correctable Error", "ECC_XGMI_WAFL_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_XGMI_WAFL_UE, "XGMI_WAFL Uncorrectable Error", "ECC_XGMI_WAFL_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_DF_CE, "DF Correctable Error", "ECC_DF_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_DF_UE, "DF Uncorrectable Error", "ECC_DF_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_SMN_CE, "SMN Correctable Error", "ECC_SMN_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_SMN_UE, "SMN Uncorrectable Error", "ECC_SMN_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_SEM_CE, "SEM Correctable Error", "ECC_SEM_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_SEM_UE, "SEM Uncorrectable Error", "ECC_SEM_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MP0_CE, "MP0 Correctable Error", "ECC_MP0_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MP0_UE, "MP0 Uncorrectable Error", "ECC_MP0_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MP1_CE, "MP1 Correctable Error", "ECC_MP1_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MP1_UE, "MP1 Uncorrectable Error", "ECC_MP1_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_FUSE_CE, "FUSE Correctable Error", "ECC_FUSE_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_FUSE_UE, "FUSE Uncorrectable Error", "ECC_FUSE_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_UMC_CE, "UMC Correctable Error", "ECC_UMC_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_UMC_UE, "UMC Uncorrectable Error", "ECC_UMC_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MCA_CE, "MCA Correctable Error", "ECC_MCA_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MCA_UE, "MCA Uncorrectable Error", "ECC_MCA_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_VCN_CE, "VCN Correctable Error", "ECC_VCN_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_VCN_UE, "VCN Uncorrectable Error", "ECC_VCN_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_JPEG_CE, "JPEG Correctable Error", "ECC_JPEG_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_JPEG_UE, "JPEG Uncorrectable Error", "ECC_JPEG_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_IH_CE, "IH Correctable Error", "ECC_IH_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_IH_UE, "IH Uncorrectable Error", "ECC_IH_UE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MPIO_CE, "MPIO Correctable Error", "ECC_MPIO_CE", true)
|
||||
FLD_DESC_ENT(RDC_FI_ECC_MPIO_UE, "MPIO Uncorrectable Error", "ECC_MPIO_UE", true)
|
||||
|
||||
// XGMI
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_0_READ_KB, "XGMI0 accumulated data read size (KB)", "XGMI_0_READ", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_1_READ_KB, "XGMI1 accumulated data read size (KB)", "XGMI_1_READ", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_2_READ_KB, "XGMI2 accumulated data read size (KB)", "XGMI_2_READ", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_3_READ_KB, "XGMI3 accumulated data read size (KB)", "XGMI_3_READ", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_4_READ_KB, "XGMI4 accumulated data read size (KB)", "XGMI_4_READ", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_5_READ_KB, "XGMI5 accumulated data read size (KB)", "XGMI_5_READ", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_6_READ_KB, "XGMI6 accumulated data read size (KB)", "XGMI_6_READ", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_7_READ_KB, "XGMI7 accumulated data read size (KB)", "XGMI_7_READ", true)
|
||||
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_0_WRITE_KB, "XGMI0 accumulated data write size (KB)", "XGMI_0_WRITE", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_1_WRITE_KB, "XGMI1 accumulated data write size (KB)", "XGMI_1_WRITE", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_2_WRITE_KB, "XGMI2 accumulated data write size (KB)", "XGMI_2_WRITE", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_3_WRITE_KB, "XGMI3 accumulated data write size (KB)", "XGMI_3_WRITE", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_4_WRITE_KB, "XGMI4 accumulated data write size (KB)", "XGMI_4_WRITE", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_5_WRITE_KB, "XGMI5 accumulated data write size (KB)", "XGMI_5_WRITE", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_6_WRITE_KB, "XGMI6 accumulated data write size (KB)", "XGMI_6_WRITE", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_7_WRITE_KB, "XGMI7 accumulated data write size (KB)", "XGMI_7_WRITE", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_TOTAL_READ_KB, "XGMI accumlated data read size across all lanes (KB)", "XGMI_TOTAL_READ", true)
|
||||
FLD_DESC_ENT(RDC_FI_XGMI_TOTAL_WRITE_KB, "XGMI accumlated data write size across all lanes (KB)", "XGMI_TOTAL_WRITE", true)
|
||||
|
||||
|
||||
// ROCProfiler fields
|
||||
// This doesn't map to rocprofiler counters directly
|
||||
// See counter_map in rdc/include/rdc_libs/rdc_modules/rdc_rocp/RdcRocpBase.h
|
||||
// See metrics.xml in rocprofiler
|
||||
FLD_DESC_ENT(RDC_FI_PROF_OCCUPANCY_PERCENT, "Percent of GPU occupancy", "OCCUPANCY_PERCENT", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_ACTIVE_CYCLES, "Number of Active Cycles", "ACTIVE_CYCLES", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_ACTIVE_WAVES, "Number of Active Waves", "ACTIVE_WAVES", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_ELAPSED_CYCLES, "Number of Elapsed Cycles over all SMs", "ELAPSED_CYCLES", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_TENSOR_ACTIVE_PERCENT, "Percent of Active Pipe Tensors", "TENSOR_PERCENT", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_GPU_UTIL_PERCENT, "Percent of GPU Utilization", "GPU_UTIL_PERCENT", true)
|
||||
// metrics with EVAL are divided by time passed
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_MEM_R_BW, "Fetched from video memory kb / ms", "MEM_R_BW", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_MEM_W_BW, "Written to video memory kb / ms", "MEM_W_BW", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_FLOPS_16, "Number of fp16 OPS / ms", "FLOPS_16", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_FLOPS_32, "Number of fp32 OPS / ms", "FLOPS_32", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_FLOPS_64, "Number of fp64 OPS / ms", "FLOPS_64", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_VALU_PIPE_ISSUE_UTIL, "Percent of Active Pipe VALU", "VALU_UTILIZATION", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_SM_ACTIVE, "Ratio of Cycles with active warp on SM","VALUBusy", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_OCC_PER_ACTIVE_CU, "Mean occ per active compute unit", "OCC_CU", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_OCC_ELAPSED, "Mean occ per active cu over elapsed", "OCC_CU_ELAPSED", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_FLOPS_16_PERCENT, "Number of fp16 OPS percent of max", "FLOPS_16_PERCENT", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_FLOPS_32_PERCENT, "Number of fp32 OPS percent of max", "FLOPS_32_PERCENT", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_EVAL_FLOPS_64_PERCENT, "Number of fp64 OPS percent of max", "FLOPS_64_PERCENT", true)
|
||||
// CPC
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CPC_STAT_BUSY, "", "CPC_CPC_STAT_BUSY", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CPC_STAT_IDLE, "", "CPC_CPC_STAT_IDLE", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CPC_STAT_STALL, "", "CPC_CPC_STAT_STALL", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CPC_TCIU_BUSY, "", "CPC_CPC_TCIU_BUSY", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CPC_TCIU_IDLE, "", "CPC_CPC_TCIU_IDLE", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CPC_UTCL2IU_BUSY, "", "CPC_CPC_UTCL2IU_BUSY", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CPC_UTCL2IU_IDLE, "", "CPC_CPC_UTCL2IU_IDLE", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CPC_UTCL2IU_STALL, "", "CPC_CPC_UTCL2IU_STALL", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_ME1_BUSY_FOR_PACKET_DECODE, "", "CPC_ME1_BUSY_FOR_PACKET_DECODE", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_ME1_DC0_SPI_BUSY, "", "CPC_ME1_DC0_SPI_BUSY", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_UTCL1_STALL_ON_TRANSLATION, "", "CPC_UTCL1_STALL_ON_TRANSLATION", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_ALWAYS_COUNT, "", "CPC_ALWAYS_COUNT", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_ADC_VALID_CHUNK_NOT_AVAIL, "", "CPC_ADC_VALID_CHUNK_NOT_AVAIL", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_ADC_DISPATCH_ALLOC_DONE, "", "CPC_ADC_DISPATCH_ALLOC_DONE", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_ADC_VALID_CHUNK_END, "", "CPC_ADC_VALID_CHUNK_END", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_SYNC_FIFO_FULL_LEVEL, "", "CPC_SYNC_FIFO_FULL_LEVEL", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_SYNC_FIFO_FULL, "", "CPC_SYNC_FIFO_FULL", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_GD_BUSY, "", "CPC_GD_BUSY", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_TG_SEND, "", "CPC_TG_SEND", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_WALK_NEXT_CHUNK, "", "CPC_WALK_NEXT_CHUNK", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_STALLED_BY_SE0_SPI, "", "CPC_STALLED_BY_SE0_SPI", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_STALLED_BY_SE1_SPI, "", "CPC_STALLED_BY_SE1_SPI", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_STALLED_BY_SE2_SPI, "", "CPC_STALLED_BY_SE2_SPI", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_STALLED_BY_SE3_SPI, "", "CPC_STALLED_BY_SE3_SPI", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_LTE_ALL, "", "CPC_LTE_ALL", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_SYNC_WRREQ_FIFO_BUSY, "", "CPC_SYNC_WRREQ_FIFO_BUSY", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CANE_BUSY, "", "CPC_CANE_BUSY", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPC_CANE_STALL, "", "CPC_CANE_STALL", false)
|
||||
// CPF
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPF_CMP_UTCL1_STALL_ON_TRANSLATION, "", "CPF_CMP_UTCL1_STALL_ON_TRANSLATION", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_STAT_BUSY, "", "CPF_CPF_STAT_BUSY", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_STAT_IDLE, "", "CPF_CPF_STAT_IDLE", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_STAT_STALL, "", "CPF_CPF_STAT_STALL", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_TCIU_BUSY, "", "CPF_CPF_TCIU_BUSY", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_TCIU_IDLE, "", "CPF_CPF_TCIU_IDLE", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_CPF_CPF_TCIU_STALL, "", "CPF_CPF_TCIU_STALL", false)
|
||||
// Misc
|
||||
FLD_DESC_ENT(RDC_FI_PROF_SIMD_UTILIZATION, "Fraction of time the SIMDs are being utilized", "SIMD_UTILIZATION", false)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_UUID, "UUID from rocprofiler", "PROF_UUID", true)
|
||||
FLD_DESC_ENT(RDC_FI_PROF_KFD_ID, "GPU_ID from rocprofiler, same as KFD_ID", "PROF_KFD_ID", true)
|
||||
|
||||
// Events
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_0_NOP_TX, "NOPs sent to neighbor 0", "XGMI_NOP_0", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_0_REQ_TX, "Outgoing requests to neighbor 0", "XGMI_REQ_0", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_0_RESP_TX, "Outgoing responses to neighbor 0", "XGMI_RES_0", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_0_BEATS_TX, "Data sent to neighbor 0 (32 byte pkts)", "XGMI_BTS_0", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_1_NOP_TX, "NOPs sent to neighbor 1", "XGMI_NOP_1", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_1_REQ_TX, "Outgoing requests to neighbor 1", "XGMI_REQ_1", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_1_RESP_TX, "Outgoing responses to neighbor 1", "XGMI_RES_1", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_1_BEATS_TX, "Data sent to neighbor 1 (32 byte pkts)", "XGMI_BTS_1", false)
|
||||
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_0_THRPUT, "Tx throughput to XGMI neighbor 0 in b/s", "XGMI_0_T", true)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_1_THRPUT, "Tx throughput to XGMI neighbor 1 in b/s", "XGMI_1_T", true)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_2_THRPUT, "Tx throughput to XGMI neighbor 2 in b/s", "XGMI_2_T", true)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_3_THRPUT, "Tx throughput to XGMI neighbor 3 in b/s", "XGMI_3_T", true)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_4_THRPUT, "Tx throughput to XGMI neighbor 4 in b/s", "XGMI_4_T", true)
|
||||
FLD_DESC_ENT(RDC_EVNT_XGMI_5_THRPUT, "Tx throughput to XGMI neighbor 5 in b/s", "XGMI_5_T", true)
|
||||
|
||||
// Asynchronous event notifications
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_VMFAULT, "VM page fault", "VM_PAGE_FAULT", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_THERMAL_THROTTLE, "Clk freq decrease due to temp", "THERMAL_THROT", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_PRE_RESET, "GPU reset is about to occur", "GPU_PRE_RESET", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_POST_RESET, "GPU reset just occurred", "GPU_POST_RESET", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_MIGRATE_START, "GPU migrate has started", "MIGRATE_START", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_MIGRATE_END, "GPU migrate has ended", "MIGRATE_END", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_PAGE_FAULT_START, "GPU page fault started", "PAGE_FAULT_START", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_PAGE_FAULT_END, "GPU page fault ended", "PAGE_FAULT_END", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_QUEUE_EVICTION, "GPU queue eviction occured", "QUEUE_EVICITION", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_QUEUE_RESTORE, "GPU queue restore occured", "QUEUE_RESTORE", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_UNMAP_FROM_GPU, "GPU unmap occured", "UNMAP_FROM_GPU", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_PROCESS_START, "GPU process started", "PROCESS_START", false)
|
||||
FLD_DESC_ENT(RDC_EVNT_NOTIF_PROCESS_END, "GPU process ended", "PROCESS_END", false)
|
||||
|
||||
// RDC health related fields
|
||||
FLD_DESC_ENT(RDC_HEALTH_XGMI_ERROR, "XGMI one or more errors detected", "XGMI_ERROR", true)
|
||||
FLD_DESC_ENT(RDC_HEALTH_PCIE_REPLAY_COUNT, "Total PCIE replay count", "PCIE_REPLAY_COUNT", true)
|
||||
FLD_DESC_ENT(RDC_HEALTH_RETIRED_PAGE_NUM, "Retired page number", "RETIRED_PAGE_NUM", true)
|
||||
FLD_DESC_ENT(RDC_HEALTH_PENDING_PAGE_NUM, "Pending page number", "PENDING_PAGE_NUM", true)
|
||||
FLD_DESC_ENT(RDC_HEALTH_RETIRED_PAGE_LIMIT, "Retired page limit", "RETIRED_PAGE_LIMIT", true)
|
||||
FLD_DESC_ENT(RDC_HEALTH_EEPROM_CONFIG_VALID, "Verify checksum of EEPROM", "EEPROM_CONFIG_VALID", true)
|
||||
FLD_DESC_ENT(RDC_HEALTH_POWER_THROTTLE_TIME, "Power throttle status counter", "POWER_THROTTLE_TIME", true)
|
||||
FLD_DESC_ENT(RDC_HEALTH_THERMAL_THROTTLE_TIME, "Total time(ms) in thermal throttle status", "THERMAL_THROTTLE_TIME", true)
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#include "common/rdc_fields_supported.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
#define FLD_DESC_ENT(ID, DESC, LABEL, DISPLAY) \
|
||||
{static_cast<uint32_t>(ID), {#ID, (DESC), (LABEL), (DISPLAY)}},
|
||||
static const fld_id2name_map_t field_id_to_descript = {
|
||||
#include "common/rdc_field.data"
|
||||
};
|
||||
#undef FLD_DESC_ENT
|
||||
|
||||
#define FLD_DESC_ENT(ID, DESC, LABEL, DISPLAY) {#ID, (ID)},
|
||||
static fld_name2id_map_t field_name_to_id = {
|
||||
#include "common/rdc_field.data" // NOLINT
|
||||
};
|
||||
#undef FLD_DESC_ENT
|
||||
|
||||
amd::rdc::fld_id2name_map_t& get_field_id_description_from_id(void) { return field_id_to_descript; }
|
||||
|
||||
bool get_field_id_from_name(const std::string name, rdc_field_t* value) {
|
||||
assert(value != nullptr);
|
||||
auto id = field_name_to_id.find(name);
|
||||
if (id == field_name_to_id.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*value = static_cast<rdc_field_t>(id->second);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_field_valid(rdc_field_t field_id) {
|
||||
if (field_id == RDC_FI_INVALID) {
|
||||
return false;
|
||||
}
|
||||
return field_id_to_descript.find(static_cast<uint32_t>(field_id)) != field_id_to_descript.end();
|
||||
}
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef COMMON_RDC_FIELDS_SUPPORTED_H_
|
||||
#define COMMON_RDC_FIELDS_SUPPORTED_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
typedef struct {
|
||||
std::string enum_name;
|
||||
std::string description;
|
||||
std::string label;
|
||||
bool do_display;
|
||||
} field_id_descript;
|
||||
|
||||
typedef const std::map<uint32_t, const field_id_descript> fld_id2name_map_t;
|
||||
typedef std::unordered_map<std::string, uint32_t> fld_name2id_map_t;
|
||||
|
||||
bool get_field_id_from_name(const std::string name, rdc_field_t* value);
|
||||
fld_id2name_map_t& get_field_id_description_from_id(void); // NOLINT
|
||||
bool is_field_valid(rdc_field_t field_id);
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // COMMON_RDC_FIELDS_SUPPORTED_H_
|
||||
@@ -0,0 +1,90 @@
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#include "common/rdc_utils.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
bool FileExists(char const* filename) {
|
||||
struct stat buf;
|
||||
return (stat(filename, &buf) == 0);
|
||||
}
|
||||
|
||||
int ReadFile(std::string path, std::string* retStr, bool chop_newline) {
|
||||
std::stringstream ss;
|
||||
int ret = 0;
|
||||
|
||||
assert(retStr != nullptr);
|
||||
|
||||
std::ifstream fs;
|
||||
fs.open(path);
|
||||
|
||||
if (!fs.is_open()) {
|
||||
ret = errno;
|
||||
errno = 0;
|
||||
return ret;
|
||||
}
|
||||
ss << fs.rdbuf();
|
||||
fs.close();
|
||||
|
||||
*retStr = ss.str();
|
||||
|
||||
if (chop_newline) {
|
||||
retStr->erase(std::remove(retStr->begin(), retStr->end(), '\n'), retStr->end());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ReadFile(const char* path, std::string* retStr, bool chop_newline) {
|
||||
assert(path != nullptr);
|
||||
assert(retStr != nullptr);
|
||||
|
||||
std::string file_path(path);
|
||||
|
||||
return amd::rdc::ReadFile(file_path, retStr, chop_newline);
|
||||
}
|
||||
|
||||
bool IsNumber(const std::string& s) {
|
||||
return !s.empty() && std::all_of(s.begin(), s.end(), ::isdigit);
|
||||
}
|
||||
|
||||
bool IsIP(const std::string& s) {
|
||||
struct sockaddr_in sa;
|
||||
int result = inet_pton(AF_INET, s.c_str(), &sa);
|
||||
// inet_pton returns 1 on success
|
||||
return result == 1;
|
||||
}
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_RDC_UTILS_H_
|
||||
#define COMMON_RDC_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define debug_print(fmt, ...) \
|
||||
do { \
|
||||
} while (false)
|
||||
#else
|
||||
#define debug_print(fmt, ...) \
|
||||
do { \
|
||||
fprintf(stderr, fmt, ##__VA_ARGS__); \
|
||||
} while (false)
|
||||
#endif
|
||||
|
||||
bool FileExists(char const* filename);
|
||||
|
||||
int ReadFile(std::string path, std::string* retStr, bool chop_newline = false);
|
||||
int ReadFile(const char* path, std::string* retStr, bool chop_newline = false);
|
||||
|
||||
bool IsNumber(const std::string& s);
|
||||
bool IsIP(const std::string& s);
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // COMMON_RDC_UTILS_H_
|
||||
@@ -0,0 +1,35 @@
|
||||
.. meta::
|
||||
:description: documentation of the installation, configuration, and use of the ROCm Data Center tool
|
||||
:keywords: ROCm Data Center tool, RDC, ROCm, API, reference, data type, support
|
||||
|
||||
.. _components:
|
||||
|
||||
***************
|
||||
RDC components
|
||||
***************
|
||||
|
||||
The components of the RDC tool are illustrated in the following figure.
|
||||
|
||||
.. figure:: ../data/install_components.png
|
||||
|
||||
High-level diagram of RDC components
|
||||
|
||||
RDC (API) library
|
||||
-----------------
|
||||
|
||||
This library is the central piece, which interacts with different modules and provides all the features described. This shared library provides C API and Python bindings so that third-party tools should be able to use it directly if required.
|
||||
|
||||
RDC daemon (``rdcd``)
|
||||
---------------------
|
||||
|
||||
The ``rdcd`` daemon records telemetry information from GPUs. It also provides an interface to RDC command-line tool (``rdci``) running locally or remotely. It relies on the above RDC Library for all the core features.
|
||||
|
||||
RDC command-line tool (``rdci``)
|
||||
--------------------------------
|
||||
|
||||
A command-line tool to invoke all the features of the RDC tool. This CLI can be run locally or remotely.
|
||||
|
||||
AMDSMI library
|
||||
--------------
|
||||
|
||||
A stateless system management library that provides low-level interfaces to access GPU information
|
||||
@@ -0,0 +1,25 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# for PDF output on Read the Docs
|
||||
project = "ROCm Data Center tool"
|
||||
author = "Advanced Micro Devices, Inc."
|
||||
copyright = "Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved."
|
||||
|
||||
html_theme = "rocm_docs_theme"
|
||||
html_theme_options = {"flavor": "rocm"}
|
||||
html_title = f"RDC documentation"
|
||||
external_toc_path = "./sphinx/_toc.yml"
|
||||
|
||||
external_projects_current_project = "rdc"
|
||||
extensions = ["rocm_docs", "rocm_docs.doxygen"]
|
||||
|
||||
doxygen_root = "doxygen"
|
||||
doxysphinx_enabled = True
|
||||
doxygen_project = {
|
||||
"name": "ROCm Data Center Tool API reference",
|
||||
"path": "doxygen/xml",
|
||||
}
|
||||
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,2 @@
|
||||
html/
|
||||
xml/
|
||||
@@ -0,0 +1,575 @@
|
||||
.. meta::
|
||||
:description: The ROCm Data Center tool (RDC) addresses key infrastructure challenges regarding AMD GPUs in cluster and data center environments and simplifies their administration
|
||||
:keywords: RDC plugins, ROCm Data Center plugins, Integrating RDC, Integrating ROCm Data Center
|
||||
|
||||
.. _rdc-3rd-party:
|
||||
|
||||
**************************
|
||||
Third party integration
|
||||
**************************
|
||||
|
||||
This section lists available third-party plugins for the RDC tool such as Prometheus, Grafana, and Reliability, Availability and Serviceability (RAS).
|
||||
|
||||
Python bindings
|
||||
================
|
||||
|
||||
The RDC tool provides a generic Python class ``RdcReader``, which simplifies telemetry gathering by providing the following functionalities:
|
||||
|
||||
* ``RdcReader`` creates the necessary groups and fieldgroups, watch the fields, and fetch the fields for the telemetry fields specified by the user.
|
||||
* ``RdcReader`` can support embedded and standalone mode. The standalone mode can be with or without authentication.
|
||||
* In standalone mode, the ``RdcReader`` can automatically reconnect to ``rdcd`` if the connection is lost.
|
||||
* Restarting ``rdcd`` can lead to loss of previously created group and fieldgroup. The ``RdcReader`` can recreate them and watch the fields after reconnecting.
|
||||
* If the client is restarted, ``RdcReader`` can detect the previously created groups and fieldgroups and avoid recreating them.
|
||||
* A custom unit converter can be passed to ``RdcReader`` to override the default RDC unit.
|
||||
|
||||
Here is a sample program to monitor the power and GPU utilization using the ``RdcReader``:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
from RdcReader import RdcReader
|
||||
from RdcUtil import RdcUtil
|
||||
from rdc_bootstrap import *
|
||||
|
||||
default_field_ids = [
|
||||
rdc_field_t.RDC_FI_POWER_USAGE,
|
||||
rdc_field_t.RDC_FI_GPU_UTIL
|
||||
]
|
||||
|
||||
class SimpleRdcReader(RdcReader):
|
||||
def __init__(self):
|
||||
RdcReader.__init__(self,ip_port=None, field_ids = default_field_ids, update_freq=1000000)
|
||||
def handle_field(self, gpu_index, value):
|
||||
field_name = self.rdc_util.field_id_string(value.field_id).lower()
|
||||
print("%d %d:%s %d" % (value.ts, gpu_index, field_name, value.value.l_int))
|
||||
|
||||
if __name__ == '__main__':
|
||||
reader = SimpleRdcReader()
|
||||
while True:
|
||||
time.sleep(1)
|
||||
reader.process()
|
||||
|
||||
In the sample program,
|
||||
|
||||
* Class ``SimpleRdcReader`` is derived from the ``RdcReader``.
|
||||
* The field ``ip_port=None`` in ``RdcReader`` dictates that RDC runs in the embedded mode.
|
||||
* ``SimpleRdcReader::process()`` fetches fields specified in ``default_field_ids``.
|
||||
|
||||
.. note::
|
||||
``RdcReader.py`` can be found in the ``python_binding`` folder located at RDC install path.
|
||||
|
||||
To run the example, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
# Ensure that RDC shared libraries are in the library path and
|
||||
# RdcReader.py is in PYTHONPATH
|
||||
|
||||
$ python SimpleReader.py
|
||||
|
||||
.. _prometheus:
|
||||
|
||||
Prometheus plugin
|
||||
==================
|
||||
|
||||
The Prometheus plugin helps to monitor events and send alerts. Prometheus installation and integration details are explained in the following sections.
|
||||
|
||||
Prometheus plugin installation
|
||||
-------------------------------
|
||||
|
||||
RDC's Prometheus plugin ``rdc_prometheus.py`` can be found in the ``python_binding`` folder.
|
||||
|
||||
Here are the steps to install Prometheus:
|
||||
|
||||
1. Install Prometheus client:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ pip install prometheus_client
|
||||
|
||||
2. Run the Prometheus plugin:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ python rdc_prometheus.py
|
||||
|
||||
3. Verify plugin:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ curl localhost:5000
|
||||
|
||||
gpu_util{gpu_index="0"} 0.0
|
||||
gpu_clock{gpu_index="0"} 300.0
|
||||
gpu_memory_total{gpu_index="0"} 4294.0
|
||||
power_usage{gpu_index="0"} 9.0
|
||||
gpu_memory_usage{gpu_index="0"} 134.0
|
||||
|
||||
By default, the plugin runs in the standalone mode and connects to ``rdcd`` at ``localhost:50051`` to fetch fields. Ensure that the plugin uses the same authentication mode as ``rdcd``, for example, if ``rdcd`` runs with ``-u/--unauth`` option, the plugin must also use ``--rdc_unauth`` option.
|
||||
|
||||
**Useful options:**
|
||||
|
||||
- To run the plugin in unauthenticated mode, use the ``--rdc_unauth`` option.
|
||||
|
||||
- To use the plugin in the embedded mode without ``rdcd``, set the ``--rdc_embedded`` option.
|
||||
|
||||
- To override the default fields that are monitored, use the ``--rdc_fields`` option to specify the list of fields.
|
||||
|
||||
- To fetch field's list from a file conveniently, use the ``--rdc_fields_file`` option, if the field's list is long.
|
||||
|
||||
- To control how the fields are cached, use the ``max_keep_age`` and ``max_keep_samples`` options.
|
||||
|
||||
- To see the metrics of the plugin itself, including the plugin process CPU, memory, file descriptor usage, native threads count, process start and uptimes, set ``--enable_plugin_monitoring`` option.
|
||||
|
||||
To view the options provided with the plugin, use ``--help``.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
% python rdc_prometheus.py --help
|
||||
usage: rdc_prometheus.py [-h] [--listen_port LISTEN_PORT] [--rdc_embedded]
|
||||
[--rdc_ip_port RDC_IP_PORT] [--rdc_unauth]
|
||||
[--rdc_update_freq RDC_UPDATE_FREQ]
|
||||
[--rdc_max_keep_age RDC_MAX_KEEP_AGE]
|
||||
[--rdc_max_keep_samples RDC_MAX_KEEP_SAMPLES]
|
||||
[--rdc_fields RDC_FIELDS [RDC_FIELDS ...]]
|
||||
[--rdc_fields_file RDC_FIELDS_FILE]
|
||||
[--rdc_gpu_indexes RDC_GPU_INDEXES [RDC_GPU_INDEXES ...]]
|
||||
[--enable_plugin_monitoring]
|
||||
|
||||
RDC Prometheus plugin.
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--listen_port LISTEN_PORT
|
||||
The listen port of the plugin (default: 5000)
|
||||
--rdc_embedded Run RDC in embedded mode (default: standalone mode)
|
||||
--rdc_ip_port RDC_IP_PORT
|
||||
The rdcd IP and port in standalone mode (default:
|
||||
localhost:50051)
|
||||
--rdc_unauth Set this option if the rdcd is running with unauth in
|
||||
standalone mode (default: false)
|
||||
--rdc_update_freq RDC_UPDATE_FREQ
|
||||
The fields update frequency in seconds (default: 10))
|
||||
--rdc_max_keep_age RDC_MAX_KEEP_AGE
|
||||
The max keep age of the fields in seconds (default:
|
||||
3600)
|
||||
--rdc_max_keep_samples RDC_MAX_KEEP_SAMPLES
|
||||
The max samples to keep for each field in the cache
|
||||
(default: 1000)
|
||||
--rdc_fields RDC_FIELDS [RDC_FIELDS ...]
|
||||
The list of fields name needs to be watched, for
|
||||
example, " --rdc_fields RDC_FI_GPU_TEMP
|
||||
RDC_FI_POWER_USAGE " (default: fields in the
|
||||
plugin)
|
||||
--rdc_fields_file RDC_FIELDS_FILE
|
||||
The list of fields name can also be read from a file
|
||||
with each field name in a separated line (default:
|
||||
None)
|
||||
--rdc_gpu_indexes RDC_GPU_INDEXES [RDC_GPU_INDEXES ...]
|
||||
The list of GPUs to be watched (default: All GPUs)
|
||||
--enable_plugin_monitoring
|
||||
Set this option to collect process metrics of
|
||||
the plugin itself (default: false)
|
||||
|
||||
Prometheus integration
|
||||
-----------------------
|
||||
|
||||
To integrate Prometheus plugin in RDC, follow these steps:
|
||||
|
||||
1. `Download and install Prometheus plugin <https://github.com/prometheus/prometheus>`_ in the management machine.
|
||||
|
||||
2. Configure Prometheus targets:
|
||||
|
||||
Use the example configuration file ``rdc_prometheus_example.yml`` in the ``python_binding`` folder. This file refers to ``prometheus_targets.json``. Modify ``prometheus_targets.json`` to point to your compute nodes.
|
||||
Ensure that this is modified to point to the correct compute nodes.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
// Sample file: prometheus_targets.json
|
||||
// Replace rdc_test*.amd.com to point the correct compute nodes
|
||||
// Add as many compute nodes as necessary
|
||||
[
|
||||
{
|
||||
"targets": [
|
||||
"rdc_test1.amd.com:5000",
|
||||
"rdc_test2.amd.com:5000"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
.. note::
|
||||
|
||||
In the above example, there are two compute nodes, ``rdc_test1.adm.com`` and ``rdc_test2.adm.com``. Ensure that the Prometheus plugin is running on those compute nodes.
|
||||
|
||||
3. Start the Prometheus plugin.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
% prometheus --config.file=<full path of the rdc_prometheus_example.yml>
|
||||
|
||||
4. From the management node, open the URL http://localhost:9090 in the browser.
|
||||
|
||||
5. Select one of the available metrics.
|
||||
|
||||
.. figure:: ../data/integration_gpu_clock.png
|
||||
|
||||
Prometheus image showing GPU clock for both rdc_test1 and rdc_test2.
|
||||
|
||||
Grafana plugin
|
||||
===============
|
||||
|
||||
Grafana is a common monitoring stack used for storing and visualizing time series data. Prometheus acts as the storage backend, and Grafana is used as the interface for analysis and visualization. Grafana has a plethora of visualization options and can be integrated with Prometheus for RDC's dashboard.
|
||||
|
||||
Grafana plugin installation
|
||||
----------------------------
|
||||
|
||||
To install Grafana plugin, follow these steps:
|
||||
|
||||
1. `Download Grafana <https://grafana.com/grafana/download>`_.
|
||||
|
||||
2. Follow the instructions to `install Grafana <https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/>`_.
|
||||
|
||||
3. To start Grafana, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo systemctl start grafana-server
|
||||
$ sudo systemctl status grafana-server
|
||||
|
||||
4. Open http://localhost:3000/ in the browser.
|
||||
|
||||
5. Login using the default username and password (``admin``/``admin``) as shown in the following image:
|
||||
|
||||
.. figure:: ../data/integration_login.png
|
||||
|
||||
Grafana integration
|
||||
--------------------
|
||||
|
||||
As a prerequisite, ensure:
|
||||
|
||||
* The :ref:`RDC Prometheus plugin <prometheus>` is running in each compute node.
|
||||
* Prometheus is set up to collect metrics from the plugin.
|
||||
|
||||
Grafana configuration
|
||||
---------------------
|
||||
|
||||
Firstly, add Prometheus as data source using the following steps:
|
||||
|
||||
1. Go to "Configuration".
|
||||
|
||||
.. image:: ../data/integration_config1.png
|
||||
|
||||
2. Select "Data Sources".
|
||||
|
||||
.. image:: ../data/integration_config2.png
|
||||
|
||||
3. Go to "Add data source".
|
||||
|
||||
.. image:: ../data/integration_config3.png
|
||||
|
||||
4. Select "Prometheus".
|
||||
|
||||
.. image:: ../data/integration_config4.png
|
||||
|
||||
.. note::
|
||||
|
||||
Ensure the name of the data source is `Prometheus`. If `Prometheus` and `Grafana` are running on the same machine, use the default URL http://localhost:9090. Otherwise, ensure the URL matches the `Prometheus` URL, save, and test it.
|
||||
|
||||
.. image:: ../data/integration_config5.png
|
||||
|
||||
Then, import RDC dashboard using the following steps:
|
||||
|
||||
1. Go to "+" and select "Import".
|
||||
|
||||
2. Upload ``rdc_grafana_dashboard_example.json`` from the ``python_binding`` folder.
|
||||
|
||||
3. Select the desired compute node for visualization.
|
||||
|
||||
.. image:: ../data/integration_config6.png
|
||||
|
||||
Prometheus (Grafana) integration with automatic node detection
|
||||
==============================================================
|
||||
|
||||
RDC provides Consul to discover the ``rdc_prometheus`` service automatically. Consul is a service mesh solution providing a fully featured control plane with service discovery, configuration, and segmentation functionality. For more information, see `Consul <https://developer.hashicorp.com/consul/docs/intro>`_.
|
||||
|
||||
RDC uses Consul for health checks of RDC's integration with the Prometheus plugin (``rdc_prometheus``). These checks provide information on its efficiency.
|
||||
|
||||
With the Consul agent integration, a new compute node can be discovered automatically, which saves users from manually changing ``prometheus_targets.json`` to use Consul.
|
||||
|
||||
Installing the Consul agent for compute and management nodes
|
||||
------------------------------------------------------------
|
||||
|
||||
To install the latest Consul agent for compute and management nodes, follow these steps:
|
||||
|
||||
1. To download and install the Consul agent, set up the ``apt`` repository:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
|
||||
$ sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
|
||||
$ sudo apt-get update && sudo apt-get install consul
|
||||
|
||||
2. Generate a key to encrypt the communication between Consul agents. The same key is used by both the compute and management nodes for communication.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ consul keygen
|
||||
|
||||
For demonstration purposes, the following key is used in the configuration file:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ consul keygen
|
||||
4lgGQXr3/R2QeTi5vEp7q5Xs1KoYBhCsk9+VgJZZHAo=
|
||||
|
||||
Setting up the Consul server in management nodes
|
||||
-------------------------------------------------
|
||||
|
||||
While Consul can function with one server, it's recommended to use three to five servers to avoid failure scenarios leading to data loss.
|
||||
|
||||
.. note::
|
||||
For demonstration purposes, the configuration settings documented below are for a single server.
|
||||
|
||||
To set up ``Consul`` server, follow these steps:
|
||||
|
||||
1. Create a configuration file ``/etc/consul.d/server.hcl``.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
server = true
|
||||
encrypt = "<CONSUL_ENCRYPTION_KEY>"
|
||||
bootstrap_expect = 1
|
||||
ui = true
|
||||
client_addr = "0.0.0.0"
|
||||
bind_addr = "<The IP address can be reached by client>"
|
||||
|
||||
Here is how to use the variables in the configuration file:
|
||||
|
||||
* Run the agent in server mode by setting ``server`` to ``true``.
|
||||
* Set ``encrypt`` to the key generated in the first step.
|
||||
* The ``bootstrap_expect`` variable indicates the number of servers required to form the first Consul cluster. Set this variable to ``1`` to allow a cluster with a single server.
|
||||
* The User Interface (``ui``) variable when set to ``true`` enables the Consul web UI.
|
||||
* The ``client_addr`` variable is used to connect the API and UI.
|
||||
* The ``bind_addr`` variable is used to connect the client to the server. If you have multiple private IP addresses, use the address that can connect to a client.
|
||||
|
||||
2. Start the agent.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo consul agent -config-dir=/etc/consul.d/
|
||||
|
||||
3. Browse to http://localhost:8500/ on the management node to see a single instance running.
|
||||
|
||||
Setting up the Consul client in compute nodes
|
||||
---------------------------------------------
|
||||
|
||||
To set up Consul client, follow these steps:
|
||||
|
||||
1. Create a configuration file ``/etc/consul.d/client.hcl``.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
server = false
|
||||
encrypt = "<CONSUL_ENCRYPTION_KEY>"
|
||||
retry_join = ["<The consul server address>"]
|
||||
client_addr = "0.0.0.0"
|
||||
bind_addr = "<The IP address can reach server>"
|
||||
|
||||
.. note::
|
||||
|
||||
Use the same ``CONSUL_ENCRYPTION_KEY`` as the servers. In the ``retry_join``, use the IP address of the management nodes.
|
||||
|
||||
2. Start the Consul agent.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo consul agent -config-dir=/etc/consul.d/
|
||||
|
||||
To see if the client has joined the Consul, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ consul members
|
||||
Node Address Status Type Build Protocol DC Segment
|
||||
management-node 10.4.22.70:8301 alive server 1.9.3 2 dc1 <all>
|
||||
compute-node 10.4.22.112:8301 alive client 1.9.3 2 dc1 <default>
|
||||
|
||||
3. Set up the Consul client to monitor the health of the RDC Prometheus plugin.
|
||||
|
||||
4. Start the RDC Prometheus plugin.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ python rdc_prometheus.py --rdc_embedded
|
||||
|
||||
5. Add the configuration file ``/etc/consul.d/rdc_prometheus.hcl``.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
{
|
||||
"service": {
|
||||
"name": "rdc_prometheus",
|
||||
"tags": [
|
||||
"rdc_prometheus",
|
||||
"rdc"
|
||||
],
|
||||
"port": 5000,
|
||||
"check": {
|
||||
"id": "rdc_plugin",
|
||||
"name": "RDC Prometheus plugin on port 5000",
|
||||
"http": "http://localhost:5000",
|
||||
"method": "GET",
|
||||
"interval": "15s",
|
||||
"timeout": "1s"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
By default, the Prometheus plugin uses port 5000. If you don't use the default setting, change the configuration file accordingly.
|
||||
|
||||
6. After updating the configuration file, restart the Consul client agent.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo consul agent -config-dir=/etc/consul.d/
|
||||
|
||||
7. Enable the :ref:`Prometheus <prometheus>` integration in the management node.
|
||||
|
||||
8. In the management node, inspect the service.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ consul catalog nodes -service=rdc_prometheus
|
||||
|
||||
Node ID Address DC
|
||||
compute-node 76694ab1 10.4.22.112 dc1
|
||||
|
||||
9. Create a new Prometheus configuration ``rdc_prometheus_consul.yml`` file for the Consul integration.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
global:
|
||||
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
|
||||
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
|
||||
scrape_configs:
|
||||
- job_name: 'consul'
|
||||
consul_sd_configs:
|
||||
- server: 'localhost:8500'
|
||||
relabel_configs:
|
||||
- source_labels: [__meta_consul_tags]
|
||||
regex: .*,rdc,.*
|
||||
action: keep
|
||||
- source_labels: [__meta_consul_service]
|
||||
target_label: job
|
||||
|
||||
.. note::
|
||||
|
||||
When running the Consul server and Prometheus on the same machine, change the server under ``consul_sd_configs`` to your Consul server address.
|
||||
|
||||
10. Start Prometheus.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ ./prometheus --config.file="rdc_prometheus_consul.yml"
|
||||
|
||||
11. Browse the Prometheus UI at http://localhost:9090 on the management node and query RDC Prometheus metrics. Ensure that the plugin starts before running the query.
|
||||
|
||||
Reliability, Availability, and Serviceability plugin
|
||||
=====================================================
|
||||
|
||||
The Reliability, Availability, and Serviceability plugin (RAS) plugin helps to monitor and count ECC (Error-Correcting Code) errors. The following sections provide information on integrating RAS with RDC.
|
||||
|
||||
RAS plugin installation
|
||||
------------------------
|
||||
|
||||
With the RAS feature enabled in the graphic card, you can use RDC to monitor RAS errors.
|
||||
|
||||
Prerequisite
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
- Ensure that the GPU supports RAS.
|
||||
|
||||
.. note::
|
||||
|
||||
The RAS library is installed as part of the RDC installation. No additional configuration is required for RDC.
|
||||
|
||||
- RDC installation dynamically loads the RAS library ``librdc_ras.so``. The configuration files required by the RAS library are installed in the ``sp3`` and ``config`` folders.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
% ls /opt/rocm-4.2.0/rdc/lib
|
||||
... librdc_ras.so ...
|
||||
... sp3 ... config ...
|
||||
|
||||
RAS integration
|
||||
----------------
|
||||
|
||||
RAS exposes a list of ECC correctable and uncorrectable errors for different IP blocks and helps to troubleshoot issues.
|
||||
|
||||
**Example:**
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci dmon -i 0 -e 600,601
|
||||
|
||||
Where, the ``dmon`` command monitors GPU index 0, and fields 600 and 601, where 600 is the field ID for the ``ECC_CORRECT`` counter and 601 for the ``ECC_UNCORRECT`` counter.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
% rdci dmon -l
|
||||
... ...
|
||||
600 RDC_FI_ECC_CORRECT_TOTAL : Accumulated Single Error Correction
|
||||
601 RDC_FI_ECC_UNCORRECT_TOTAL : Accumulated Double Error Detection
|
||||
602 RDC_FI_ECC_SDMA_CE : SDMA Correctable Error
|
||||
603 RDC_FI_ECC_SDMA_UE : SDMA Uncorrectable Error
|
||||
604 RDC_FI_ECC_GFX_CE : GFX Correctable Error
|
||||
605 RDC_FI_ECC_GFX_UE : GFX Uncorrectable Error
|
||||
606 RDC_FI_ECC_MMHUB_CE : MMHUB Correctable Error
|
||||
607 RDC_FI_ECC_MMHUB_UE : MMHUB Uncorrectable Error
|
||||
608 RDC_FI_ECC_ATHUB_CE : ATHUB Correctable Error
|
||||
609 RDC_FI_ECC_ATHUB_UE : ATHUB Uncorrectable Error
|
||||
610 RDC_FI_ECC_PCIE_BIF_CE : PCIE_BIF Correctable Error
|
||||
611 RDC_FI_ECC_PCIE_BIF_UE : PCIE_BIF Uncorrectable Error
|
||||
612 RDC_FI_ECC_HDP_CE : HDP Correctable Error
|
||||
613 RDC_FI_ECC_HDP_UE : HDP Uncorrectable Error
|
||||
614 RDC_FI_ECC_XGMI_WAFL_CE : XGMI WAFL Correctable Error
|
||||
615 RDC_FI_ECC_XGMI_WAFL_UE : XGMI WAFL Uncorrectable Error
|
||||
616 RDC_FI_ECC_DF_CE : DF Correctable Error
|
||||
617 RDC_FI_ECC_DF_UE : DF Uncorrectable Error
|
||||
618 RDC_FI_ECC_SMN_CE : SMN Correctable Error
|
||||
619 RDC_FI_ECC_SMN_UE : SMN Uncorrectable Error
|
||||
620 RDC_FI_ECC_SEM_CE : SEM Correctable Error
|
||||
621 RDC_FI_ECC_SEM_UE : SEM Uncorrectable Error
|
||||
622 RDC_FI_ECC_MP0_CE : MP0 Correctable Error
|
||||
623 RDC_FI_ECC_MP0_UE : MP0 Uncorrectable Error
|
||||
624 RDC_FI_ECC_MP1_CE : MP1 Correctable Error
|
||||
625 RDC_FI_ECC_MP1_UE : MP1 Uncorrectable Error
|
||||
626 RDC_FI_ECC_FUSE_CE : FUSE Correctable Error
|
||||
627 RDC_FI_ECC_FUSE_UE : FUSE Uncorrectable Error
|
||||
628 RDC_FI_ECC_UMC_CE : UMC Correctable Error
|
||||
629 RDC_FI_ECC_UMC_UE : UMC Uncorrectable Error
|
||||
630 RDC_FI_ECC_MCA_CE : MCA Correctable Error
|
||||
631 RDC_FI_ECC_MCA_UE : MCA Uncorrectable Error
|
||||
632 RDC_FI_ECC_VCN_CE : VCN Correctable Error
|
||||
633 RDC_FI_ECC_VCN_UE : VCN Uncorrectable Error
|
||||
634 RDC_FI_ECC_JPEG_CE : JPEG Correctable Error
|
||||
635 RDC_FI_ECC_JPEG_UE : JPEG Uncorrectable Error
|
||||
636 RDC_FI_ECC_IH_CE : IH Correctable Error
|
||||
637 RDC_FI_ECC_IH_UE : IH Uncorrectable Error
|
||||
638 RDC_FI_ECC_MPIO_CE : MPIO Correctable Error
|
||||
639 RDC_FI_ECC_MPIO_UE : MPIO Uncorrectable Error
|
||||
... ...
|
||||
|
||||
To access the ECC correctable and uncorrectable error counters, use:
|
||||
|
||||
.. _error-correction:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
% rdci dmon -i 0 -e 600,601
|
||||
|
||||
GPU ECC_CORRECT ECC_UNCORRECT
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
@@ -0,0 +1,71 @@
|
||||
.. meta::
|
||||
:description: documentation of the installation, configuration, and use of the ROCm Data Center tool
|
||||
:keywords: ROCm Data Center tool, RDC, ROCm, API, reference, data type, support
|
||||
|
||||
.. _rdc-use:
|
||||
|
||||
******************************************
|
||||
Introduction to the RDC tool
|
||||
******************************************
|
||||
|
||||
The ROCm Data Center tool (RDC) simplifies the administration and addresses key infrastructure challenges in AMD GPUs in cluster and datacenter environments. The main features are:
|
||||
|
||||
* GPU telemetry
|
||||
* GPU statistics for jobs
|
||||
* Integration with third-party tools
|
||||
* Open source
|
||||
|
||||
You can use the RDC tool in standalone mode if all components are installed. However, the existing management tools can use the same set of features available in a library format.
|
||||
|
||||
For details on different modes of operation, refer to *Starting RDC* in :ref:`rdc-install`.
|
||||
|
||||
Target Audience
|
||||
===============
|
||||
|
||||
The audience for the AMD RDC tool consists of:
|
||||
|
||||
* Administrators: RDC provides the cluster administrator with the capability of monitoring, validating, and configuring policies.
|
||||
* HPC Users: Provides GPU-centric feedback for their workload submissions.
|
||||
* OEM: Add GPU information to their existing cluster management software.
|
||||
* Open source Contributors: RDC is open source and accepts contributions from the community.
|
||||
|
||||
Objective
|
||||
=========
|
||||
|
||||
This documentation will:
|
||||
|
||||
#. Introduce the tool features in :ref:`rdc-features`
|
||||
#. Describe integration with external tools in :ref:`rdc-3rd-party`
|
||||
#. Provide an open source handbook in :ref:`rdc-handbook`
|
||||
#. Introduce elements of the tool API in :ref:`api-intro`
|
||||
|
||||
Terminology
|
||||
===========
|
||||
|
||||
.. list-table:: Terminologies and Abbreviations
|
||||
|
||||
* - **Terms**
|
||||
- **Description**
|
||||
|
||||
* - RDC
|
||||
- ROCm Data Center tool
|
||||
|
||||
* - Compute node (CN)
|
||||
- One of many nodes containing one or more GPUs in the Data Center on which compute jobs are run
|
||||
|
||||
* - Management node (MN) or Main console
|
||||
- A machine running system administration applications to administer and manage the Data Center
|
||||
|
||||
* - GPU Groups
|
||||
- Logical grouping of one or more GPUs in a compute node
|
||||
|
||||
* - Fields
|
||||
- A metric that can be monitored by the RDC, such as GPU temperature, memory usage, and power usage
|
||||
|
||||
* - Field Groups
|
||||
- Logical grouping of multiple fields
|
||||
|
||||
* - Job
|
||||
- A workload that is submitted to one or more compute nodes
|
||||
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
.. meta::
|
||||
:description: The ROCm Data Center tool (RDC) addresses key infrastructure challenges regarding AMD GPUs in cluster and data center environments and simplifies their administration
|
||||
:keywords: ROCm Data Center usage, RDC usage, RDC user manual, ROCm Data Center user manual, RDC tutorial, ROCm Data Center tutorial, RDC user guide, ROCm Data Center user guide
|
||||
|
||||
.. _using-RDC:
|
||||
|
||||
***********
|
||||
Using RDC
|
||||
***********
|
||||
|
||||
This topic provides useful information for the following audience on using RDC:
|
||||
|
||||
* Administrators: RDC provides the cluster administrator with the capability of monitoring, validating, and configuring policies.
|
||||
* HPC users: RDC provides GPU-centric feedback for their workload submissions.
|
||||
* OEM: RDC adds GPU information to their existing cluster management software.
|
||||
* Open source contributors: RDC is open source and accepts contributions from the community.
|
||||
|
||||
Starting RDC
|
||||
============
|
||||
|
||||
You can start RDC from command line using ``systemctl`` command or directly as a user. Both these options are explained in the following sections. The capability of RDC can be configured by modifying the ``rdc.service`` system configuration file. RDC reads the ``rdc.service`` file from ``/etc/systemd/system``. If multiple RDC versions are installed, copy ``/opt/rocm-<x.y.z>/libexec/rdc/rdc.service`` from the desired RDC version, to the ``/etc/systemd/system`` folder.
|
||||
|
||||
Starting RDC using systemctl
|
||||
-----------------------------
|
||||
|
||||
Here are the steps to start RDC using ``systemctl`` command, which runs RDC in the background:
|
||||
|
||||
1. Copy the service file:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo cp /opt/rocm/libexec/rdc/rdc.service /etc/systemd/system/
|
||||
|
||||
2. Configure capabilities:
|
||||
|
||||
- Full capabilities: Uncomment the following lines in ``/etc/systemd/system/rdc.service``:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
CapabilityBoundingSet=CAP_DAC_OVERRIDE
|
||||
AmbientCapabilities=CAP_DAC_OVERRIDE
|
||||
|
||||
- Monitor-only capabilities: Comment out the preceding lines in ``/etc/systemd/system/rdc.service``.
|
||||
|
||||
3. Start the service:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo systemctl start rdc
|
||||
sudo systemctl status rdc
|
||||
|
||||
4. Modify RDCD options:
|
||||
|
||||
Edit ``/opt/rocm/etc/rdc_options`` to append any additional RDCD parameters.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo nano /opt/rocm/etc/rdc_options
|
||||
|
||||
Example configuration:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
RDC_OPTS="-p 50051 -u -d"
|
||||
|
||||
Flags:
|
||||
|
||||
- `-p 50051` : Use port 50051
|
||||
- `-u` : Unauthenticated mode
|
||||
- `-d` : Enable debug messages
|
||||
|
||||
Starting RDC using command line as a user
|
||||
------------------------------------------
|
||||
|
||||
While ``systemctl`` is the preferred way to start RDC, you can also start RDC directly from the command line as a user, which runs RDC in the user's current terminal. By default, the user is defined as ``rdc`` in the ``rdc.service`` file:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
[Service]
|
||||
User=rdc
|
||||
Group=rdc
|
||||
|
||||
To change the user, you can edit the ``User`` in the ``rdc.service`` file.
|
||||
To start RDC server daemon (``rdcd``) as a user such as ``rdc`` or as ``root``, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
#Start as user rdc
|
||||
$ sudo -u rdc rdcd
|
||||
|
||||
# Start as root
|
||||
$ sudo rdcd
|
||||
|
||||
The RDC capability is determined by the privilege of the user starting ``rdcd``. For example, ``rdcd`` running under a normal user account has monitor-only capability and ``rdcd`` running as root has full capability.
|
||||
|
||||
.. note::
|
||||
|
||||
If a user other than rdc or root starts the ``rdcd`` daemon, the file ownership of the SSL keys mentioned in the :ref:`authentication <authentication>` section must be modified to allow read and write access.
|
||||
|
||||
.. _authentication:
|
||||
|
||||
Authentication
|
||||
===============
|
||||
|
||||
RDC supports encrypted communications between clients and servers.
|
||||
|
||||
You can enable or disable authentication for the communication between the client and server. By default, authentication is enabled.
|
||||
|
||||
To disable authentication, use the ``--unauth_comm`` or ``-u`` flag when starting the server. You must also use ``-u`` in ``rdci`` to access unauthenticated ``rdcd``. You can edit the ``rdc.service`` file to specify arguments to be passed while starting ``rdcd``. On the client side, the ``secure`` argument must be set to ``False`` when calling ``rdc_channel_create()``.
|
||||
The following sections provide information for setting up the ``rdcd`` server for authentication.
|
||||
|
||||
Generating keys and certificates using scripts
|
||||
------------------------------------------------
|
||||
|
||||
RDC users manage their own keys and certificates. However, some scripts generate self-signed certificates in the RDC source tree in the authentication directory for test purposes. The following flowchart depicts how to generate the root certificates using the ``openssl`` command in ``01gen_root_cert.sh``:
|
||||
|
||||
.. figure:: ../data/handbook_openssl.png
|
||||
|
||||
Generation of root certificates using openssl command
|
||||
|
||||
You can specify the default responses to ``openssl`` questions in a section in the ``openssl.conf`` file. To locate the section in the ``openssl.conf`` file, look for the following comment:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
# < ** REPLACE VALUES IN THIS SECTION WITH APPROPRIATE VALUES FOR YOUR ORG. **>
|
||||
|
||||
Modifying this section with values appropriate for your organization is helpful in cases where this script is called multiple times. Additionally, you must replace the dummy values and update the ``alt_names`` section for your environment.
|
||||
|
||||
To generate the keys and certificates using these scripts, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ 01gen_root_cert.sh
|
||||
# provide answers to posed questions
|
||||
$ 02gen_ssl_artifacts.sh
|
||||
# provide answers to posed questions
|
||||
|
||||
On running the preceding scripts, the keys and certificates are generated in the newly created ``CA/artifacts`` directory.
|
||||
|
||||
.. important::
|
||||
You must delete this directory before rerunning the scripts.
|
||||
|
||||
To install the keys and certificates, access the artifacts directory and run the ``install.sh`` script as root along with specifying the install location. The default install location is ``/etc/rdc``:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ cd CA/artifacts
|
||||
$ sudo install_<client|server>.sh /etc/rdc
|
||||
|
||||
These files must be copied and installed on all client and server machines expected to communicate with each other.
|
||||
|
||||
Known limitation
|
||||
-----------------
|
||||
|
||||
The client and server are hardcoded to look for the ``openssl`` certificate and key files in ``/etc/rdc``. No workaround is available for this.
|
||||
|
||||
Keys and certificates for authentication
|
||||
-----------------------------------------
|
||||
|
||||
Several SSL keys and certificates must be generated and installed on clients and servers for authentication to work properly. By default, the RDC server looks in the ``/etc/rdc`` folder for the following keys and certificates:
|
||||
|
||||
Client
|
||||
+++++++
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo tree /etc/rdc
|
||||
/etc/rdc
|
||||
|-- client
|
||||
|-- certs
|
||||
| |-- rdc_cacert.pem
|
||||
| |-- rdc_client_cert.pem
|
||||
|-- private
|
||||
|-- rdc_client_cert.key
|
||||
|
||||
Server
|
||||
+++++++
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo tree /etc/rdc
|
||||
/etc/rdc
|
||||
|-- server
|
||||
|-- certs
|
||||
| |-- rdc_cacert.pem
|
||||
| |-- rdc_server_cert.pem
|
||||
|-- private
|
||||
|-- rdc_server_cert.key
|
||||
|
||||
.. note::
|
||||
|
||||
Machines acting as both client and server consist of both directory structures.
|
||||
|
||||
Modes of operation
|
||||
===================
|
||||
|
||||
RDC supports two primary modes of operation: *Standalone* and *Embedded*. The feature set is similar in both the cases. Choose the mode that best fits your deployment needs.
|
||||
|
||||
The capability in each mode depends on the user privileges while starting the RDC tool. A normal user has access only to monitor (GPU telemetry) capabilities. A privileged user can run the tool with full capabilities. In the full capability mode, GPU configuration features can be invoked. The full capability mode might affect all the users and processes sharing the GPU.
|
||||
|
||||
Standalone mode
|
||||
-----------------
|
||||
|
||||
Standalone mode allows you to run RDC independently with all its components installed.
|
||||
This is the preferred mode of operation, as it does not have any external dependencies. To start RDC in standalone mode, ``rdcd`` must run on each compute node.
|
||||
|
||||
- Starting RDCD as a privileged user: A privileged user can run RDC with full capabilities.
|
||||
|
||||
- With authentication:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo /opt/rocm/bin/rdcd
|
||||
|
||||
- Without authentication:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo /opt/rocm/bin/rdcd -u
|
||||
|
||||
- Starting RDC as a normal user: A normal user can run RDC with monitor-only capabilities only.
|
||||
|
||||
- With authentication:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
/opt/rocm/bin/rdcd
|
||||
|
||||
- Without authentication:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
/opt/rocm/bin/rdcd -u
|
||||
|
||||
Embedded mode
|
||||
--------------
|
||||
|
||||
Embedded mode integrates RDC directly into your existing management tools using its library format.
|
||||
The embedded mode is especially useful for a monitoring agent running on the compute node. The monitoring agent can directly use the RDC library to achieve a fine-grain control on how and when to invoke the RDC features. For example, if the monitoring agent has a facility to synchronize across multiple nodes, it can synchronize GPU telemetry across these nodes.
|
||||
|
||||
The RDC daemon ``rdcd`` can be used as a reference code for this purpose. The dependency on ``gRPC`` is also eliminated, if the RDC library is directly used.
|
||||
|
||||
To run RDC in embedded mode, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python your_management_tool.py --rdc_embedded
|
||||
|
||||
.. note::
|
||||
|
||||
Ensure that the ``rdcd`` daemon is not running separately, when using embedded mode.
|
||||
|
||||
.. caution::
|
||||
|
||||
RDC command-line ``rdci`` doesn't function in this mode. Third-party monitoring software is responsible for providing the user interface and remote access or monitoring.
|
||||
|
||||
Troubleshooting RDC
|
||||
====================
|
||||
|
||||
The RDCD logs provide useful status and debugging information. The logs can also help debug problems like ``rdcd`` failing to start, communication issues with a client, and many more.
|
||||
|
||||
- View logs:
|
||||
|
||||
When ``rdcd`` is started using ``systemctl``, you can view the logs using:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ journalctl -u rdc
|
||||
|
||||
- Run RDCD with debug logs:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
RDC_LOG=DEBUG /opt/rocm/bin/rdcd
|
||||
|
||||
Logging levels supported: `ERROR`, `INFO`, `DEBUG`.
|
||||
|
||||
- Enable additional logging messages:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
export RSMI_LOGGING=3
|
||||
|
||||
If the GPU reset fails, restart the server. Note that restarting the server also initiates ``rdcd``. You might then encounter the following two scenarios:
|
||||
|
||||
- ``rdcd`` returns the correct GPU information to ``rdci``
|
||||
|
||||
- ``rdcd`` returns the `No GPUs found on the system` error to ``rdci``. To resolve this error, restart ``rdcd`` using:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo systemctl restart rdcd
|
||||
|
||||
Known issues
|
||||
-------------
|
||||
|
||||
- dmon fields return N/A
|
||||
|
||||
**Reasons:**
|
||||
|
||||
- Missing libraries:
|
||||
|
||||
- Verify ``/opt/rocm/lib/rdc/librdc_*.so`` exists.
|
||||
- Ensure all related libraries such as ``rocprofiler``, ``rocruntime``, and others are present.
|
||||
|
||||
- Unsupported GPU:
|
||||
|
||||
- Most metrics work on MI300 and newer.
|
||||
- Limited metrics on MI200.
|
||||
- Consumer GPUs such as RX6800 have fewer supported metrics.
|
||||
|
||||
- HSA_STATUS_ERROR_OUT_OF_RESOURCES
|
||||
|
||||
**Error message:**
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
terminate called after throwing an instance of 'std::runtime_error'
|
||||
what(): hsa error code: 4104 HSA_STATUS_ERROR_OUT_OF_RESOURCES: The runtime failed to allocate the necessary resources. This error may also occur when the core runtime library needs to spawn threads or create internal OS-specific events.
|
||||
Aborted (core dumped)
|
||||
|
||||
**Solution:**
|
||||
|
||||
Follow these steps to check for missing groups:
|
||||
|
||||
1. Ensure video and render groups exist.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo usermod -aG video,render $USER
|
||||
|
||||
2. Logout and login to apply group changes.
|
||||
@@ -0,0 +1,286 @@
|
||||
.. meta::
|
||||
:description: The ROCm Data Center tool (RDC) addresses key infrastructure challenges regarding AMD GPUs in cluster and data center environments and simplifies their administration
|
||||
:keywords: RDC features, ROCm Data Center features, RDC functionalities, ROCm Data Center functionalities
|
||||
|
||||
.. _rdc-features:
|
||||
|
||||
********************
|
||||
Using RDC features
|
||||
********************
|
||||
|
||||
This topic provides information related to the features of the RDC tool.
|
||||
|
||||
.. figure:: ../data/features.png
|
||||
|
||||
RDC components and framework for describing features
|
||||
|
||||
Discovery
|
||||
==========
|
||||
|
||||
The discovery feature is used to locate and display information of GPUs present in the compute node.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci discovery <host_name> -l
|
||||
2 GPUs found
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - **GPU index**
|
||||
- **Device information**
|
||||
|
||||
* - 0
|
||||
- Name: AMD Radeon Instinct MI50 accelerator
|
||||
|
||||
* - 1
|
||||
- Name: AMD Radeon Instinct MI50 accelerator
|
||||
|
||||
To list available GPUs, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci -l : list available GPUs
|
||||
|
||||
Groups
|
||||
=======
|
||||
|
||||
This section explains the GPU and field groups features.
|
||||
|
||||
GPU groups
|
||||
-----------
|
||||
|
||||
With the GPU groups feature, you can create, delete, and list logical groups of GPU.
|
||||
|
||||
|
||||
- To create a group, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci group -c GPU_GROUP
|
||||
Successfully created a group with a group ID 1
|
||||
|
||||
- To add GPUs to a group, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci group -g 1 -a 0,1
|
||||
Successfully added the GPU 0,1 to group 1
|
||||
|
||||
- To delete a group, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci group -d 1
|
||||
Successfully removed group 1
|
||||
|
||||
- To list groups, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci group –l
|
||||
1 group found
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - **Group ID**
|
||||
- **Group name**
|
||||
- **GPU index**
|
||||
|
||||
* - 1
|
||||
- GPU_GROUP
|
||||
- 0, 1
|
||||
|
||||
Field groups
|
||||
-------------
|
||||
|
||||
The field groups feature provides you the options to create, delete, list field groups, and monitor specific GPU metrics.
|
||||
|
||||
- To create a field group, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci fieldgroup -c <fgroup> -f 150,155
|
||||
Successfully created a field group with a group ID 1
|
||||
|
||||
- To list field groups, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci fieldgroup -l
|
||||
1 group found
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - **Group ID**
|
||||
- **Group Name**
|
||||
- **Field IDs**
|
||||
|
||||
* - 1
|
||||
- Fgroup
|
||||
- 150, 155
|
||||
|
||||
- To delete a field group, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci fieldgroup -d 1
|
||||
Successfully removed field group 1
|
||||
|
||||
Monitor errors
|
||||
===============
|
||||
|
||||
To get the Reliability, Availability, and Serviceability (RAS) Error-Correcting Code (ECC) counter, define the following fields:
|
||||
|
||||
- Correctable ECC errors:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
312 ``RDC_FI_ECC_CORRECT_TOTAL``
|
||||
|
||||
- Uncorrectable ECC errors:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
313 ``RDC_FI_ECC_UNCORRECT_TOTAL``
|
||||
|
||||
Device monitoring
|
||||
==================
|
||||
|
||||
The device monitoring feature is used to monitor the GPU fields such as temperature, power usage, and utilization.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci dmon -f <field_group> -g <gpu_group> -c 5 -d 1000
|
||||
1 group found
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - **GPU index**
|
||||
- **TEMP (m°C)**
|
||||
- **POWER (µW)**
|
||||
|
||||
* - 0
|
||||
- 25000
|
||||
- 520500
|
||||
|
||||
.. _job-stats:
|
||||
|
||||
Job stats
|
||||
==========
|
||||
|
||||
The job stats is used to display GPU statistics for any given workload.
|
||||
|
||||
- To start recording stats, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci stats -s 2 -g 1
|
||||
Successfully started recording job 2 with a group ID 1
|
||||
|
||||
- To stop recording stats, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci stats -x 2
|
||||
Successfully stopped recording job 2
|
||||
|
||||
- To display job stats, use:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci stats -j 2
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - **Summary**
|
||||
- **Executive status**
|
||||
|
||||
* - Start time
|
||||
- 1586795401
|
||||
|
||||
* - End time
|
||||
- 1586795445
|
||||
|
||||
* - Total execution time
|
||||
- 44
|
||||
|
||||
* - Energy consumed (Joules)
|
||||
- 21682
|
||||
|
||||
* - Power usage (Watts)
|
||||
- Max: 49 Min: 13 Avg: 34
|
||||
|
||||
* - GPU clock (MHz)
|
||||
- Max: 1000 Min: 300 Avg: 903
|
||||
|
||||
* - GPU utilization (%)
|
||||
- Max: 69 Min: 0 Avg: 2
|
||||
|
||||
* - Max GPU memory used (bytes)
|
||||
- 524320768
|
||||
|
||||
* - Memory utilization (%)
|
||||
- Max: 12 Min: 11 Avg: 12
|
||||
|
||||
Job stats use case
|
||||
-------------------
|
||||
|
||||
A common job stats use case is to record GPU statistics associated with any job or workload. The following figure illustrates how all RDC features can be put together for this use case:
|
||||
|
||||
.. figure:: ../data/features_jobs.png
|
||||
|
||||
An example showing how job statistics can be recorded
|
||||
|
||||
Here are the ``rdci`` commands for this use case:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci group -c group1
|
||||
|
||||
successfully created a group with a group ID 1
|
||||
|
||||
$ rdci group -g 1 -a 0,1
|
||||
|
||||
GPU 0,1 is added to group 1 successfully.
|
||||
|
||||
rdci stats -s 123 -g 1
|
||||
|
||||
job 123 recorded successfully with the group ID
|
||||
|
||||
rdci stats -x 123
|
||||
|
||||
job 123 stops recording successfully
|
||||
|
||||
rdci stats -j 123
|
||||
|
||||
job stats printed
|
||||
|
||||
Error-correcting code output
|
||||
=============================
|
||||
|
||||
In the job output, this feature prints out the Error-Correcting Code (ECC) errors while running the job.
|
||||
|
||||
To see the ECC correctable and uncorrectable error counters, see this :ref:`example <error-correction>`.
|
||||
|
||||
Diagnostic
|
||||
===========
|
||||
|
||||
The diagnostic feature when run on a GPU group provides the following details:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ rdci diag -g <gpu_group>
|
||||
|
||||
No compute process: Pass
|
||||
Node topology check: Pass
|
||||
GPU parameters check: Pass
|
||||
Compute Queue ready: Pass
|
||||
System memory check: Pass
|
||||
=============== Diagnostic Details ==================
|
||||
No compute process: No processes running on any devices.
|
||||
Node topology check: No link detected.
|
||||
GPU parameters check: GPU 0 Critical Edge temperature in range.
|
||||
Compute Queue ready: Run binary search task on GPU 0 Pass.
|
||||
System memory check: Max Single Allocation Memory Test for GPU 0 Pass. CPUAccessToGPUMemoryTest for GPU 0 Pass. GPUAccessToCPUMemoryTest for GPU 0 Pass.
|
||||
@@ -0,0 +1,47 @@
|
||||
.. meta::
|
||||
:description: The ROCm Data Center tool (RDC) addresses key infrastructure challenges regarding AMD GPUs in cluster and data center environments and simplifies their administration
|
||||
:keywords: ROCm Data Center tool, RDC, Data Center
|
||||
|
||||
.. _index:
|
||||
|
||||
*************************************
|
||||
ROCm Data Center tool documentation
|
||||
*************************************
|
||||
|
||||
The ROCm Data Center tool (RDC) addresses key infrastructure challenges regarding AMD GPUs in cluster and data center environments and simplifies their administration.
|
||||
Here are the main RDC features:
|
||||
|
||||
* GPU telemetry
|
||||
* GPU statistics for jobs
|
||||
* Integration with third-party tools
|
||||
* Open source
|
||||
|
||||
The code is open and hosted at `<https://github.com/ROCm/rdc>`_.
|
||||
|
||||
.. grid:: 2
|
||||
:gutter: 3
|
||||
|
||||
.. grid-item-card:: Install
|
||||
|
||||
* :ref:`rdc-install`
|
||||
|
||||
.. grid-item-card:: How to
|
||||
|
||||
* :ref:`using-RDC`
|
||||
* :ref:`rdc-features`
|
||||
* :ref:`rdc-3rd-party`
|
||||
|
||||
.. grid-item-card:: API reference
|
||||
|
||||
* :ref:`api-intro`
|
||||
* :ref:`rdc-ref`
|
||||
|
||||
.. grid-item-card:: Tutorial
|
||||
|
||||
* :ref:`job-stats-sample`
|
||||
|
||||
To contribute to the documentation, refer to
|
||||
`Contributing to ROCm <https://rocm.docs.amd.com/en/latest/contribute/contributing.html>`_.
|
||||
|
||||
You can find licensing information on the
|
||||
`Licensing <https://rocm.docs.amd.com/en/latest/about/license.html>`_ page.
|
||||
@@ -0,0 +1,69 @@
|
||||
.. meta::
|
||||
:description: documentation of the installation, configuration, and use of the ROCm Data Center tool
|
||||
:keywords: ROCm Data Center tool, RDC, ROCm, API, reference, data type, support
|
||||
|
||||
.. _rdc-handbook:
|
||||
|
||||
***************************************************
|
||||
Building and testing RDC
|
||||
***************************************************
|
||||
|
||||
RDC is open source and available under the MIT License. This section is helpful for open source developers. Third-party integrators may also find this information useful.
|
||||
|
||||
|
||||
Build and Install RDC
|
||||
=====================
|
||||
|
||||
To build and install, clone the RDC source code from GitHub and use CMake.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ git clone <GitHub for RDC>
|
||||
$ cd rdc
|
||||
$ mkdir -p build; cd build
|
||||
$ cmake -DROCM_DIR=/opt/rocm -DGRPC_ROOT="$GRPC_PROTOC_ROOT"..
|
||||
$ make
|
||||
#Install library file and header and the default location is /opt/rocm
|
||||
$ make install
|
||||
|
||||
|
||||
Build Documentation
|
||||
-------------------
|
||||
|
||||
You can generate PDF documentation after a successful build. The reference manual, refman.pdf, appears in the latex directory.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ make doc
|
||||
$ cd latex
|
||||
$ make
|
||||
|
||||
|
||||
Build Unit Tests for RDC Tool
|
||||
-----------------------------
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ cd rdc/tests/rdc_tests
|
||||
$ mkdir -p build; cd build
|
||||
$ cmake -DROCM_DIR=/opt/rocm -DGRPC_ROOT="$GRPC_PROTOC_ROOT"..
|
||||
$ make
|
||||
|
||||
# To run the tests
|
||||
|
||||
$ cd build/rdctst_tests
|
||||
$ ./rdctst
|
||||
|
||||
|
||||
Test
|
||||
----
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
# Run rdcd daemon
|
||||
$ LD_LIBRARY_PATH=$PWD/rdc_libs/ ./server/rdcd -u
|
||||
|
||||
# In another console run the RDC command-line
|
||||
$ LD_LIBRARY_PATH=$PWD/rdc_libs/ ./rdci/rdci discovery -l -u
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
.. meta::
|
||||
:description: The ROCm Data Center tool (RDC) addresses key infrastructure challenges regarding AMD GPUs in cluster and data center environments and simplifies their administration
|
||||
:keywords: RDC installation, Install RDC, Install ROCm Data Center tool, Building ROCm Data Center, Building RDC
|
||||
|
||||
.. _rdc-install:
|
||||
|
||||
******************
|
||||
RDC installation
|
||||
******************
|
||||
|
||||
RDC is part of the AMD ROCm software and available on the distributions supported by AMD ROCm. This topic provides information required to install RDC from prebuilt packages and source.
|
||||
|
||||
Prerequisites
|
||||
==============
|
||||
|
||||
To install RDC from source, ensure that your system meets the following requirements:
|
||||
|
||||
- **Supported platforms:** AMD ROCm-supported platform. See the `list of supported operating systems <https://rocm.docs.amd.com/projects/install-on-linux/en/latest/reference/system-requirements.html#supported-operating-systems>`_.
|
||||
|
||||
- **Dependencies:**
|
||||
|
||||
- CMake >= 3.15
|
||||
|
||||
- g++ (5.4.0)
|
||||
|
||||
- gRPC and protoc
|
||||
|
||||
- libcap-dev
|
||||
|
||||
- :doc:`AMD ROCm platform <rocm:index>` including:
|
||||
|
||||
- :doc:`AMDSMI library <amdsmi:index>`
|
||||
- `ROCK kernel driver <https://github.com/ROCm/ROCK-Kernel-Driver>`_
|
||||
|
||||
For building latest documentation:
|
||||
|
||||
- Doxygen (1.8.11)
|
||||
|
||||
- LaTeX (pdfTeX 3.14159265-2.6-1.40.16)
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo apt install libcap-dev
|
||||
$ sudo apt install -y doxygen
|
||||
|
||||
Build RDC from source
|
||||
======================
|
||||
|
||||
The following sections provide steps to build RDC from source.
|
||||
|
||||
Build gRPC and Protoc
|
||||
----------------------
|
||||
|
||||
gRPC and Protoc must be built from source as the prebuilt packages are not available for the same. Here are the steps:
|
||||
|
||||
1. Install the required tools:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install automake make g++ unzip build-essential autoconf libtool pkg-config libgflags-dev libgtest-dev clang libc++-dev curl libcap-dev
|
||||
|
||||
2. Clone and build gRPC:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git clone -b v1.67.1 https://github.com/grpc/grpc --depth=1 --shallow-submodules --recurse-submodules
|
||||
cd grpc
|
||||
export GRPC_ROOT=/opt/grpc
|
||||
cmake -B build \
|
||||
-DgRPC_INSTALL=ON \
|
||||
-DgRPC_BUILD_TESTS=OFF \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCMAKE_INSTALL_PREFIX="$GRPC_ROOT" \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
make -C build -j $(nproc)
|
||||
sudo make -C build install
|
||||
echo "$GRPC_ROOT" | sudo tee /etc/ld.so.conf.d/grpc.conf
|
||||
sudo ldconfig
|
||||
cd ..
|
||||
|
||||
Build RDC
|
||||
-----------
|
||||
|
||||
1. Clone the RDC repository:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git clone https://github.com/ROCm/rdc
|
||||
cd rdc
|
||||
|
||||
2. Configure the build:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cmake -B build -DGRPC_ROOT="$GRPC_ROOT"
|
||||
|
||||
3. You can also enable the following optional features:
|
||||
|
||||
- ROCm profiler:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cmake -B build -DBUILD_PROFILER=ON
|
||||
|
||||
- ROCm Validation Suite (RVS):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cmake -B build -DBUILD_RVS=ON
|
||||
|
||||
- RDC library only (without ``rdci`` and ``rdcd``):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cmake -B build -DBUILD_STANDALONE=OFF
|
||||
|
||||
- RDC library without ROCm runtime:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cmake -B build -DBUILD_RUNTIME=OFF
|
||||
|
||||
4. Build and install:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
make -C build -j $(nproc)
|
||||
sudo make -C build install
|
||||
|
||||
5. Update system library path:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
export RDC_LIB_DIR=/opt/rocm/lib/rdc
|
||||
export GRPC_LIB_DIR="/opt/grpc/lib"
|
||||
echo "${RDC_LIB_DIR}" | sudo tee /etc/ld.so.conf.d/x86_64-librdc_client.conf
|
||||
echo "${GRPC_LIB_DIR}" | sudo tee -a /etc/ld.so.conf.d/x86_64-librdc_client.conf
|
||||
sudo ldconfig
|
||||
|
||||
Installing RDC using prebuilt packages
|
||||
=======================================
|
||||
|
||||
RDC is packaged as part of the ROCm software repository. To install RDC using prebuilt package, first :doc:`install the AMD ROCm software <rocm-install-on-linux:index>`, then use the following instructions:
|
||||
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: Ubuntu
|
||||
:sync: ubuntu-tab
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo apt-get install rdc
|
||||
# or, to install a specific version
|
||||
$ sudo apt-get install rdc<x.y.z>
|
||||
|
||||
.. tab-item:: SLES 15 Service Pack 3
|
||||
:sync: sles-tab
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo zypper install rdc
|
||||
# or, to install a specific version
|
||||
$ sudo zypper install rdc<x.y.z>
|
||||
@@ -0,0 +1,4 @@
|
||||
# License
|
||||
|
||||
```{include} ../LICENSE
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
.. meta::
|
||||
:description: The ROCm Data Center tool (RDC) addresses key infrastructure challenges regarding AMD GPUs in cluster and data center environments and simplifies their administration
|
||||
:keywords: ROCm Data Center tool API, RDC API
|
||||
|
||||
.. _api-intro:
|
||||
|
||||
*************************
|
||||
Introduction to RDC API
|
||||
*************************
|
||||
|
||||
.. note::
|
||||
This is the alpha version of RDC API and is subject to change without notice. The primary purpose of this API is to solicit feedback. AMD accepts no responsibility for any software breakage caused by API changes.
|
||||
|
||||
RDC API
|
||||
========
|
||||
|
||||
RDC API is the core library that provides all the RDC features.
|
||||
|
||||
RDC API includes the following libraries:
|
||||
|
||||
* ``librdc_bootstrap.so``: Loads one of the following two libraries during runtime, depending on the mode.
|
||||
|
||||
- ``rdci`` mode: Loads ``librdc_client.so``
|
||||
- ``rdcd`` mode: Loads ``librdc.so``
|
||||
|
||||
* ``librdc_client.so``: Exposes RDC functionality using ``gRPC`` client.
|
||||
|
||||
* ``librdc.so``: RDC API. This depends on ``libamd_smi.so``.
|
||||
|
||||
* ``libamd_smi.so``: Stateless low overhead access to GPU data.
|
||||
|
||||
.. figure:: ../data/api_libs.png
|
||||
|
||||
Different libraries and how they are linked.
|
||||
@@ -0,0 +1,11 @@
|
||||
.. meta::
|
||||
:description: The ROCm Data Center tool (RDC) addresses key infrastructure challenges regarding AMD GPUs in cluster and data center environments and simplifies their administration
|
||||
:keywords: ROCm Data Center library, RDC library, RDC API, ROCm Data Center API
|
||||
|
||||
.. _rdc-ref:
|
||||
|
||||
****************
|
||||
RDC API library
|
||||
****************
|
||||
|
||||
.. doxygenindex::
|
||||
@@ -0,0 +1,29 @@
|
||||
# Anywhere {branch} is used, the branch name will be substituted.
|
||||
# These comments will also be removed.
|
||||
defaults:
|
||||
numbered: False
|
||||
root: index
|
||||
subtrees:
|
||||
- caption: Install
|
||||
entries:
|
||||
- file: install/install
|
||||
title: Installing RDC
|
||||
|
||||
- caption: How to
|
||||
entries:
|
||||
- file: how-to/using_RDC
|
||||
- file: how-to/using_RDC_features
|
||||
- file: how-to/integration
|
||||
|
||||
- caption: API reference
|
||||
entries:
|
||||
- file: reference/api_intro
|
||||
- file: reference/api_ref
|
||||
|
||||
- caption: Tutorial
|
||||
entries:
|
||||
- file: tutorial/job_stats_sample
|
||||
|
||||
- caption: About
|
||||
entries:
|
||||
- file: license
|
||||
@@ -0,0 +1 @@
|
||||
rocm-docs-core[api-reference]==1.20.0
|
||||
@@ -0,0 +1,319 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.10
|
||||
# by the following command:
|
||||
#
|
||||
# pip-compile docs/sphinx/requirements.in
|
||||
#
|
||||
accessible-pygments==0.0.5
|
||||
# via pydata-sphinx-theme
|
||||
alabaster==1.0.0
|
||||
# via sphinx
|
||||
asttokens==3.0.0
|
||||
# via stack-data
|
||||
attrs==25.3.0
|
||||
# via
|
||||
# jsonschema
|
||||
# jupyter-cache
|
||||
# referencing
|
||||
babel==2.17.0
|
||||
# via
|
||||
# pydata-sphinx-theme
|
||||
# sphinx
|
||||
beautifulsoup4==4.13.3
|
||||
# via pydata-sphinx-theme
|
||||
breathe==4.36.0
|
||||
# via rocm-docs-core
|
||||
certifi==2025.1.31
|
||||
# via requests
|
||||
cffi==1.17.1
|
||||
# via
|
||||
# cryptography
|
||||
# pynacl
|
||||
charset-normalizer==3.4.1
|
||||
# via requests
|
||||
click==8.1.8
|
||||
# via
|
||||
# click-log
|
||||
# doxysphinx
|
||||
# jupyter-cache
|
||||
# sphinx-external-toc
|
||||
click-log==0.4.0
|
||||
# via doxysphinx
|
||||
comm==0.2.2
|
||||
# via ipykernel
|
||||
contourpy==1.3.1
|
||||
# via matplotlib
|
||||
cryptography==44.0.2
|
||||
# via pyjwt
|
||||
cycler==0.12.1
|
||||
# via matplotlib
|
||||
debugpy==1.8.13
|
||||
# via ipykernel
|
||||
decorator==5.2.1
|
||||
# via ipython
|
||||
deprecated==1.2.18
|
||||
# via pygithub
|
||||
docutils==0.21.2
|
||||
# via
|
||||
# myst-parser
|
||||
# pydata-sphinx-theme
|
||||
# sphinx
|
||||
doxysphinx==3.3.12
|
||||
# via rocm-docs-core
|
||||
exceptiongroup==1.2.2
|
||||
# via ipython
|
||||
executing==2.2.0
|
||||
# via stack-data
|
||||
fastjsonschema==2.21.1
|
||||
# via
|
||||
# nbformat
|
||||
# rocm-docs-core
|
||||
fonttools==4.56.0
|
||||
# via matplotlib
|
||||
gitdb==4.0.12
|
||||
# via gitpython
|
||||
gitpython==3.1.44
|
||||
# via rocm-docs-core
|
||||
greenlet==3.1.1
|
||||
# via sqlalchemy
|
||||
idna==3.10
|
||||
# via requests
|
||||
imagesize==1.4.1
|
||||
# via sphinx
|
||||
importlib-metadata==8.6.1
|
||||
# via
|
||||
# jupyter-cache
|
||||
# myst-nb
|
||||
ipykernel==6.29.5
|
||||
# via myst-nb
|
||||
ipython==8.34.0
|
||||
# via
|
||||
# ipykernel
|
||||
# myst-nb
|
||||
jedi==0.19.2
|
||||
# via ipython
|
||||
jinja2==3.1.6
|
||||
# via
|
||||
# myst-parser
|
||||
# sphinx
|
||||
jsonschema==4.23.0
|
||||
# via nbformat
|
||||
jsonschema-specifications==2024.10.1
|
||||
# via jsonschema
|
||||
jupyter-cache==1.0.1
|
||||
# via myst-nb
|
||||
jupyter-client==8.6.3
|
||||
# via
|
||||
# ipykernel
|
||||
# nbclient
|
||||
jupyter-core==5.7.2
|
||||
# via
|
||||
# ipykernel
|
||||
# jupyter-client
|
||||
# nbclient
|
||||
# nbformat
|
||||
kiwisolver==1.4.8
|
||||
# via matplotlib
|
||||
libsass==0.22.0
|
||||
# via doxysphinx
|
||||
lxml==5.2.1
|
||||
# via doxysphinx
|
||||
markdown-it-py==3.0.0
|
||||
# via
|
||||
# mdit-py-plugins
|
||||
# myst-parser
|
||||
markupsafe==3.0.2
|
||||
# via jinja2
|
||||
matplotlib==3.10.1
|
||||
# via doxysphinx
|
||||
matplotlib-inline==0.1.7
|
||||
# via
|
||||
# ipykernel
|
||||
# ipython
|
||||
mdit-py-plugins==0.4.2
|
||||
# via myst-parser
|
||||
mdurl==0.1.2
|
||||
# via markdown-it-py
|
||||
mpire==2.10.2
|
||||
# via doxysphinx
|
||||
myst-nb==1.2.0
|
||||
# via rocm-docs-core
|
||||
myst-parser==4.0.1
|
||||
# via myst-nb
|
||||
nbclient==0.10.2
|
||||
# via
|
||||
# jupyter-cache
|
||||
# myst-nb
|
||||
nbformat==5.10.4
|
||||
# via
|
||||
# jupyter-cache
|
||||
# myst-nb
|
||||
# nbclient
|
||||
nest-asyncio==1.6.0
|
||||
# via ipykernel
|
||||
numpy==1.26.4
|
||||
# via
|
||||
# contourpy
|
||||
# doxysphinx
|
||||
# matplotlib
|
||||
packaging==24.2
|
||||
# via
|
||||
# ipykernel
|
||||
# matplotlib
|
||||
# pydata-sphinx-theme
|
||||
# sphinx
|
||||
parso==0.8.4
|
||||
# via jedi
|
||||
pexpect==4.9.0
|
||||
# via ipython
|
||||
pillow==11.1.0
|
||||
# via matplotlib
|
||||
platformdirs==4.3.6
|
||||
# via jupyter-core
|
||||
prompt-toolkit==3.0.50
|
||||
# via ipython
|
||||
psutil==7.0.0
|
||||
# via ipykernel
|
||||
ptyprocess==0.7.0
|
||||
# via pexpect
|
||||
pure-eval==0.2.3
|
||||
# via stack-data
|
||||
pycparser==2.22
|
||||
# via cffi
|
||||
pydata-sphinx-theme==0.15.4
|
||||
# via
|
||||
# rocm-docs-core
|
||||
# sphinx-book-theme
|
||||
pygithub==2.6.1
|
||||
# via rocm-docs-core
|
||||
pygments==2.19.1
|
||||
# via
|
||||
# accessible-pygments
|
||||
# ipython
|
||||
# mpire
|
||||
# pydata-sphinx-theme
|
||||
# sphinx
|
||||
pyjson5==1.6.8
|
||||
# via doxysphinx
|
||||
pyjwt[crypto]==2.10.1
|
||||
# via pygithub
|
||||
pynacl==1.5.0
|
||||
# via pygithub
|
||||
pyparsing==3.2.1
|
||||
# via
|
||||
# doxysphinx
|
||||
# matplotlib
|
||||
python-dateutil==2.9.0.post0
|
||||
# via
|
||||
# jupyter-client
|
||||
# matplotlib
|
||||
pyyaml==6.0.2
|
||||
# via
|
||||
# jupyter-cache
|
||||
# myst-nb
|
||||
# myst-parser
|
||||
# rocm-docs-core
|
||||
# sphinx-external-toc
|
||||
pyzmq==26.3.0
|
||||
# via
|
||||
# ipykernel
|
||||
# jupyter-client
|
||||
referencing==0.36.2
|
||||
# via
|
||||
# jsonschema
|
||||
# jsonschema-specifications
|
||||
requests==2.32.3
|
||||
# via
|
||||
# pygithub
|
||||
# sphinx
|
||||
rocm-docs-core[api-reference]==1.20.0
|
||||
# via -r requirements.in
|
||||
rpds-py==0.23.1
|
||||
# via
|
||||
# jsonschema
|
||||
# referencing
|
||||
six==1.17.0
|
||||
# via python-dateutil
|
||||
smmap==5.0.2
|
||||
# via gitdb
|
||||
snowballstemmer==2.2.0
|
||||
# via sphinx
|
||||
soupsieve==2.6
|
||||
# via beautifulsoup4
|
||||
sphinx==8.1.3
|
||||
# via
|
||||
# breathe
|
||||
# myst-nb
|
||||
# myst-parser
|
||||
# pydata-sphinx-theme
|
||||
# rocm-docs-core
|
||||
# sphinx-book-theme
|
||||
# sphinx-copybutton
|
||||
# sphinx-design
|
||||
# sphinx-external-toc
|
||||
# sphinx-notfound-page
|
||||
sphinx-book-theme==1.1.4
|
||||
# via rocm-docs-core
|
||||
sphinx-copybutton==0.5.2
|
||||
# via rocm-docs-core
|
||||
sphinx-design==0.6.1
|
||||
# via rocm-docs-core
|
||||
sphinx-external-toc==1.0.1
|
||||
# via rocm-docs-core
|
||||
sphinx-notfound-page==1.1.0
|
||||
# via rocm-docs-core
|
||||
sphinxcontrib-applehelp==2.0.0
|
||||
# via sphinx
|
||||
sphinxcontrib-devhelp==2.0.0
|
||||
# via sphinx
|
||||
sphinxcontrib-htmlhelp==2.1.0
|
||||
# via sphinx
|
||||
sphinxcontrib-jsmath==1.0.1
|
||||
# via sphinx
|
||||
sphinxcontrib-qthelp==2.0.0
|
||||
# via sphinx
|
||||
sphinxcontrib-serializinghtml==2.0.0
|
||||
# via sphinx
|
||||
sqlalchemy==2.0.39
|
||||
# via jupyter-cache
|
||||
stack-data==0.6.3
|
||||
# via ipython
|
||||
tabulate==0.9.0
|
||||
# via jupyter-cache
|
||||
tomli==2.2.1
|
||||
# via sphinx
|
||||
tornado==6.4.2
|
||||
# via
|
||||
# ipykernel
|
||||
# jupyter-client
|
||||
tqdm==4.67.1
|
||||
# via mpire
|
||||
traitlets==5.14.3
|
||||
# via
|
||||
# comm
|
||||
# ipykernel
|
||||
# ipython
|
||||
# jupyter-client
|
||||
# jupyter-core
|
||||
# matplotlib-inline
|
||||
# nbclient
|
||||
# nbformat
|
||||
typing-extensions==4.12.2
|
||||
# via
|
||||
# beautifulsoup4
|
||||
# ipython
|
||||
# myst-nb
|
||||
# pydata-sphinx-theme
|
||||
# pygithub
|
||||
# referencing
|
||||
# sqlalchemy
|
||||
urllib3==2.3.0
|
||||
# via
|
||||
# pygithub
|
||||
# requests
|
||||
wcwidth==0.2.13
|
||||
# via prompt-toolkit
|
||||
wrapt==1.17.2
|
||||
# via deprecated
|
||||
zipp==3.21.0
|
||||
# via importlib-metadata
|
||||
@@ -0,0 +1,62 @@
|
||||
.. meta::
|
||||
:description: The ROCm Data Center tool (RDC) addresses key infrastructure challenges regarding AMD GPUs in cluster and data center environments and simplifies their administration
|
||||
:keywords: Job stats use case, RDC feature example, ROCm Data Center feature sample, RDC feature sample, ROCm Data Center feature example
|
||||
|
||||
.. _job-stats-sample:
|
||||
|
||||
**********************
|
||||
Job stats sample code
|
||||
**********************
|
||||
|
||||
The following pseudocode shows how RDC API can be directly used to record GPU statistics associated with any job or workload. Refer to the `example code <https://github.com/ROCm/rdc/tree/amd-staging/example>`_ on how to build it.
|
||||
|
||||
For more information on Job stats, see :ref:`Job stats <job-stats>`.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
//Initialize the RDC
|
||||
rdc_handle_t rdc_handle;
|
||||
rdc_status_t result=rdc_init(0);
|
||||
|
||||
//Dynamically choose to run in standalone or embedded mode
|
||||
bool standalone = false;
|
||||
std::cin>> standalone;
|
||||
if (standalone)
|
||||
result = rdc_connect("127.0.0.1:50051", &rdc_handle, nullptr, nullptr, nullptr); //It will connect to the daemon
|
||||
else
|
||||
result = rdc_start_embedded(RDC_OPERATION_MODE_MANUAL, &rdc_handle); //call library directly, here we run embedded in manual mode
|
||||
|
||||
//Now we can use the same API for both standalone and embedded
|
||||
//(1) create group
|
||||
rdc_gpu_group_t groupId;
|
||||
result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_EMPTY, "MyGroup1", &groupId);
|
||||
|
||||
//(2) Add the GPUs to the group
|
||||
result = rdc_group_gpu_add(rdc_handle, groupId, 0); //Add GPU 0
|
||||
result = rdc_group_gpu_add(rdc_handle, groupId, 1); //Add GPU 1
|
||||
|
||||
//(3) start the recording the Slurm job 123. Set the sample frequency to once per second
|
||||
result = rdc_job_start_stats(rdc_handle, group_id,
|
||||
"123", 1000000);
|
||||
|
||||
//For standalone mode, the daemon will update and cache the samples
|
||||
//In manual mode, we must call rdc_field_update_all periodically to take samples
|
||||
if (!standalone) { //embedded manual mode
|
||||
for (int i=5; i>0; i--) { //As an example, we will take 5 samples
|
||||
result = rdc_field_update_all(rdc_handle, 0);
|
||||
usleep(1000000);
|
||||
}
|
||||
} else { //standalone mode, do nothing
|
||||
usleep(5000000); //sleep 5 seconds before fetch the stats
|
||||
}
|
||||
|
||||
//(4) stop the Slurm job 123, which will stop the watch
|
||||
// Note: we do not have to stop the job to get stats. The rdc_job_get_stats can be called at any time before stop
|
||||
result = rdc_job_stop_stats(rdc_handle, "123");
|
||||
|
||||
//(5) Get the stats
|
||||
rdc_job_info_t job_info;
|
||||
result = rdc_job_get_stats(rdc_handle, "123", &job_info);
|
||||
std::cout<<"Average Memory Utilization: " <<job_info.summary.memoryUtilization.average <<std::endl;
|
||||
|
||||
//The cleanup and shutdown ....
|
||||
@@ -0,0 +1,148 @@
|
||||
# Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# WARN: This is a standalone CMake project! Do not include as a subdirectory!
|
||||
|
||||
# This project is meant to demo RDC library
|
||||
# See README.md for more information
|
||||
|
||||
#
|
||||
# Minimum version of cmake required
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
option(CMAKE_VERBOSE_MAKEFILE "Enable verbose output" ON)
|
||||
option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile commands for linters and autocompleters" ON)
|
||||
|
||||
# Set compile flags
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -m64 -msse -msse2")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG
|
||||
"${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -DDEBUG"
|
||||
CACHE STRING
|
||||
"Flags for Debug builds"
|
||||
)
|
||||
# note: no '-s' here unlike other CMakeLists.txt
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} -O2 -DNDEBUG"
|
||||
CACHE STRING
|
||||
"Flags for Release builds"
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -g -DNDEBUG"
|
||||
CACHE STRING
|
||||
"Flags for RelWithDebInfo builds"
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
"${CMAKE_CXX_FLAGS_MINSIZEREL} -Os -DNDEBUG"
|
||||
CACHE STRING
|
||||
"Flags for MinSizeRel builds"
|
||||
)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "The C++ standard to use")
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.4.0)
|
||||
message("Compiler version is " ${CMAKE_CXX_COMPILER_VERSION})
|
||||
message(FATAL_ERROR "Require at least gcc-5.4.0")
|
||||
endif()
|
||||
|
||||
project(RDC_example)
|
||||
|
||||
# provides cmake_print_variables(VAR)
|
||||
include(CMakePrintHelpers)
|
||||
|
||||
# required variables
|
||||
if(DEFINED ENV{ROCM_PATH})
|
||||
set(ROCM_DIR "$ENV{ROCM_PATH}" CACHE STRING "ROCm directory.")
|
||||
else()
|
||||
set(ROCM_DIR "/opt/rocm" CACHE STRING "ROCm directory.")
|
||||
endif()
|
||||
|
||||
# add package search paths
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${ROCM_DIR})
|
||||
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} ${ROCM_DIR}/lib ${ROCM_DIR}/lib64)
|
||||
|
||||
# RDC provides librdc_bootstrap
|
||||
find_package(rdc CONFIG REQUIRED)
|
||||
|
||||
message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
|
||||
message(" Cmake Example ")
|
||||
message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
|
||||
|
||||
message("")
|
||||
message("Build Configuration:")
|
||||
message("-----------BuildType: " ${CMAKE_BUILD_TYPE})
|
||||
message("------------Compiler: " ${CMAKE_CXX_COMPILER})
|
||||
message("-------------Version: " ${CMAKE_CXX_COMPILER_VERSION})
|
||||
message("------------ROCM_DIR: " ${ROCM_DIR})
|
||||
message("")
|
||||
|
||||
set(JOBSTATS_EXAMPLE_SRC_LIST "job_stats_example.cc")
|
||||
cmake_print_variables(JOBSTATS_EXAMPLE_SRC_LIST)
|
||||
set(JOBSTATS_EXAMPLE_EXE "jobstats")
|
||||
add_executable(${JOBSTATS_EXAMPLE_EXE} "${JOBSTATS_EXAMPLE_SRC_LIST}")
|
||||
target_link_libraries(${JOBSTATS_EXAMPLE_EXE} pthread dl rdc_bootstrap)
|
||||
|
||||
set(FIELDVALUE_EXAMPLE_SRC_LIST "field_value_example.cc")
|
||||
cmake_print_variables(FIELDVALUE_EXAMPLE_SRC_LIST)
|
||||
set(FIELDVALUE_EXAMPLE_EXE "fieldvalue")
|
||||
add_executable(${FIELDVALUE_EXAMPLE_EXE} "${FIELDVALUE_EXAMPLE_SRC_LIST}")
|
||||
target_link_libraries(${FIELDVALUE_EXAMPLE_EXE} pthread dl rdc_bootstrap)
|
||||
|
||||
set(DIAGNOSTIC_EXAMPLE_SRC_LIST "diagnostic_example.cc")
|
||||
cmake_print_variables(DIAGNOSTIC_EXAMPLE_SRC_LIST)
|
||||
set(DIAGNOSTIC_EXAMPLE_EXE "diagnostic")
|
||||
add_executable(${DIAGNOSTIC_EXAMPLE_EXE} "${DIAGNOSTIC_EXAMPLE_SRC_LIST}")
|
||||
target_link_libraries(${DIAGNOSTIC_EXAMPLE_EXE} pthread dl rdc_bootstrap)
|
||||
|
||||
set(ROCPROFILER_EXAMPLE_SRC_LIST "rocprofiler_example.cc")
|
||||
cmake_print_variables(ROCPROFILER_EXAMPLE_SRC_LIST)
|
||||
set(ROCPROFILER_EXAMPLE_EXE "rocprofiler")
|
||||
add_executable(${ROCPROFILER_EXAMPLE_EXE} "${ROCPROFILER_EXAMPLE_SRC_LIST}")
|
||||
target_link_libraries(${ROCPROFILER_EXAMPLE_EXE} pthread dl rdc_bootstrap)
|
||||
|
||||
set(POLICY_EXAMPLE_SRC_LIST "policy_example.cc")
|
||||
cmake_print_variables(POLICY_EXAMPLE_SRC_LIST)
|
||||
set(POLICY_EXAMPLE_EXE "policy")
|
||||
add_executable(${POLICY_EXAMPLE_EXE} "${POLICY_EXAMPLE_SRC_LIST}")
|
||||
target_link_libraries(${POLICY_EXAMPLE_EXE} pthread dl rdc_bootstrap)
|
||||
|
||||
set(HEALTH_EXAMPLE_SRC_LIST "health_example.cc")
|
||||
cmake_print_variables(HEALTH_EXAMPLE_SRC_LIST)
|
||||
set(HEALTH_EXAMPLE_EXE "health")
|
||||
add_executable(${HEALTH_EXAMPLE_EXE} "${HEALTH_EXAMPLE_SRC_LIST}")
|
||||
target_link_libraries(${HEALTH_EXAMPLE_EXE} pthread dl rdc_bootstrap)
|
||||
|
||||
set(CONFIG_EXAMPLE_SRC_LIST "config_example.cc")
|
||||
cmake_print_variables(CONFIG_EXAMPLE_SRC_LIST)
|
||||
set(CONFIG_EXAMPLE_EXE "config")
|
||||
add_executable(${CONFIG_EXAMPLE_EXE} "${CONFIG_EXAMPLE_SRC_LIST}")
|
||||
target_link_libraries(${CONFIG_EXAMPLE_EXE} pthread dl rdc_bootstrap)
|
||||
|
||||
set(TOPOLOGYLINK_EXAMPLE_SRC_LIST "topologylink_example.cc")
|
||||
cmake_print_variables(TOPOLOGYLINK_EXAMPLE_SRC_LIST)
|
||||
set(TOPOLOGYLINK_EXAMPLE_EXE "topologylink")
|
||||
add_executable(${TOPOLOGYLINK_EXAMPLE_EXE} "${TOPOLOGYLINK_EXAMPLE_SRC_LIST}")
|
||||
target_link_libraries(${TOPOLOGYLINK_EXAMPLE_EXE} pthread dl rdc_bootstrap)
|
||||
|
||||
message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
|
||||
message(" Finished Cmake Example ")
|
||||
message("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")
|
||||
@@ -0,0 +1,57 @@
|
||||
# Examples
|
||||
|
||||
|
||||
### How to compile examples?
|
||||
|
||||
***NOTE: You have to have RDC installed somewhere.***
|
||||
|
||||
If you have rocm (and RDC) installed under `/opt/rocm` - then you can simply do:
|
||||
|
||||
```bash
|
||||
# same as 'mkdir -p build; cd build; cmake ../; cd ../'
|
||||
cmake -B build
|
||||
# same as 'cd build; make; cd ../'
|
||||
make -C build
|
||||
```
|
||||
|
||||
If you have rocm installed under a different directory, then you will have to
|
||||
add that path with one of the following ways:
|
||||
|
||||
- `cmake -DROCM_DIR=/custom/rocm/path -B build`
|
||||
- `ROCM_PATH=/custom/rocm/path cmake -B build`
|
||||
|
||||
followed by `make -C build`
|
||||
|
||||
You can also set ROCM\_PATH environment variable.
|
||||
|
||||
|
||||
### I can't find rdc!
|
||||
|
||||
- Is RDC installed?
|
||||
- Is RDC installed under `/opt/rocm`?
|
||||
- Can you find `/opt/rocm/lib/cmake/rdc/rdcTargets.cmake`?
|
||||
|
||||
|
||||
### Where is rdc?
|
||||
|
||||
```bash
|
||||
ldd build/diagnostic
|
||||
```
|
||||
|
||||
Look for `librdc_bootstrap.so`
|
||||
|
||||
|
||||
### `diagnostic` is halted, but other examples work
|
||||
|
||||
Did you wait long enough?
|
||||
|
||||
It takes a while to run. 46 seconds on my machine with 2 GPUs.
|
||||
|
||||
|
||||
### `Couldn't find the platform configure..`
|
||||
|
||||
### `Couldn't find the config for the Device...`
|
||||
|
||||
That's probably ok. The examples will still run.
|
||||
|
||||
Try to `cd` into the config directory and call these examples from there.
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
Copyright (C) Advanced Micro Devices. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
int main() {
|
||||
rdc_gpu_group_t group_id;
|
||||
rdc_status_t result;
|
||||
bool standalone = false;
|
||||
rdc_handle_t rdc_handle;
|
||||
uint32_t count = 0;
|
||||
rdc_config_setting_list_t settings_list;
|
||||
rdc_config_setting_t setting;
|
||||
uint64_t watts;
|
||||
|
||||
char hostIpAddress[] = {"localhost:50051"};
|
||||
char group_name[] = {"group1"};
|
||||
|
||||
// Select the embedded mode and standalone mode dynamically.
|
||||
std::cout << "Start rdci in: \n";
|
||||
std::cout << "0 - Embedded mode \n";
|
||||
std::cout << "1 - Standalone mode \n";
|
||||
while (!(std::cin >> standalone)) {
|
||||
std::cout << "Invalid input.\n";
|
||||
std::cin.clear();
|
||||
std::cin.ignore();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << (standalone ? "Standalone mode selected.\n" : "Embedded mode selected.\n");
|
||||
|
||||
// Init the rdc
|
||||
result = rdc_init(0);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error initializing RDC. Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << "RDC Initialized.\n";
|
||||
}
|
||||
|
||||
if (standalone) { // standalone
|
||||
result = rdc_connect(hostIpAddress, &rdc_handle, nullptr, nullptr, nullptr);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error connecting to remote rdcd. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
} else { // embedded
|
||||
result = rdc_start_embedded(RDC_OPERATION_MODE_AUTO, &rdc_handle);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error starting embedded RDC engine. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can use the same API for both standalone and embedded
|
||||
// Get the list of devices in the system
|
||||
uint32_t gpu_index_list[RDC_MAX_NUM_DEVICES];
|
||||
result = rdc_device_get_all(rdc_handle, gpu_index_list, &count);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error to find devices on the system. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
if (count == 0) {
|
||||
std::cout << "No GPUs find on the sytem ";
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << count << " GPUs found in the system.\n";
|
||||
}
|
||||
|
||||
// Create the group
|
||||
result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_EMPTY, group_name, &group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error creating group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Created the GPU group " << group_id << std::endl;
|
||||
|
||||
// Add all GPUs to the group
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
result = rdc_group_gpu_add(rdc_handle, group_id, gpu_index_list[i]); // Add GPU 0
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error adding group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
rdc_device_attributes_t attribute;
|
||||
result = rdc_device_get_attributes(rdc_handle, gpu_index_list[i], &attribute);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get GPU attribute. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Add GPU " << gpu_index_list[i] << ":" << attribute.device_name << " to group "
|
||||
<< group_id << std::endl;
|
||||
}
|
||||
|
||||
setting.type = RDC_CFG_POWER_LIMIT;
|
||||
// Our targeted value is 195 Watts, which will be converted into Microwatts inside of
|
||||
// rdc_config_set
|
||||
setting.target_value = 195;
|
||||
result = rdc_config_set(rdc_handle, group_id, setting);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error set config RDC_CFG_POWER_LIMIT, Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = rdc_config_get(rdc_handle, group_id, &settings_list);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get config, Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Prompt user to change amd-smi to other value, and watch rdc config change it back
|
||||
|
||||
std::cout << "Config before wait:" << std::endl;
|
||||
|
||||
result = rdc_config_get(rdc_handle, group_id, &settings_list);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get config, Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
std::cout << "The config will keep the power limit to 195 Watts" << std::endl;
|
||||
std::cout << "You can change the power limit using amd-smi, the RDC config module should be able "
|
||||
"to detect it and set it back"
|
||||
<< std::endl;
|
||||
std::cout << "Waiting 3 minutes before exit ..." << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::minutes(3));
|
||||
|
||||
result = rdc_config_clear(rdc_handle, group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error clear config, Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
//... clean up
|
||||
cleanup:
|
||||
std::cout << "Cleaning up.\n";
|
||||
|
||||
result = rdc_group_gpu_destroy(rdc_handle, group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error delete GPU group. Return: " << rdc_status_string(result);
|
||||
}
|
||||
std::cout << "Deleted the GPU group " << group_id << std::endl;
|
||||
|
||||
if (standalone)
|
||||
rdc_disconnect(rdc_handle);
|
||||
else
|
||||
rdc_stop_embedded(rdc_handle);
|
||||
rdc_shutdown();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
Copyright (c) 2021 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
static std::string get_test_name(rdc_diag_test_cases_t test_case) {
|
||||
const std::map<rdc_diag_test_cases_t, std::string> test_desc = {
|
||||
{RDC_DIAG_COMPUTE_PROCESS, "No compute process"},
|
||||
{RDC_DIAG_COMPUTE_QUEUE, "Compute Queue ready"},
|
||||
{RDC_DIAG_SYS_MEM_CHECK, "System memory check"},
|
||||
{RDC_DIAG_NODE_TOPOLOGY, "Node topology check"},
|
||||
{RDC_DIAG_RVS_GST_TEST, "RVS check"},
|
||||
{RDC_DIAG_GPU_PARAMETERS, "GPU parameters check"},
|
||||
{RDC_DIAG_TEST_LAST, "Unknown"}};
|
||||
|
||||
auto test_name = test_desc.find(test_case);
|
||||
if (test_name == test_desc.end()) {
|
||||
return "Unknown Test";
|
||||
}
|
||||
return test_name->second;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
rdc_status_t result;
|
||||
rdc_handle_t rdc_handle;
|
||||
bool standalone = false;
|
||||
char hostIpAddress[] = {"127.0.0.1:50051"};
|
||||
char group_name[] = {"diag_group"};
|
||||
|
||||
// Select the embedded mode and standalone mode dynamically.
|
||||
std::cout << "Start rdci in: \n";
|
||||
std::cout << "0 - Embedded mode \n";
|
||||
std::cout << "1 - Standalone mode \n";
|
||||
while (!(std::cin >> standalone)) {
|
||||
std::cout << "Invalid input.\n";
|
||||
std::cin.clear();
|
||||
std::cin.ignore();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << (standalone ? "Standalone mode selected.\n" : "Embedded mode selected.\n");
|
||||
|
||||
// Init the rdc
|
||||
result = rdc_init(0);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error initializing RDC. Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << "RDC Initialized.\n";
|
||||
}
|
||||
|
||||
if (standalone) { // standalone
|
||||
result = rdc_connect(hostIpAddress, &rdc_handle, nullptr, nullptr, nullptr);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error connecting to remote rdcd. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
} else { // embedded
|
||||
result = rdc_start_embedded(RDC_OPERATION_MODE_AUTO, &rdc_handle);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error starting embedded RDC engine. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can use the same API for both standalone and embedded
|
||||
// (1) create group for all GPUs
|
||||
rdc_gpu_group_t group_id;
|
||||
result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_DEFAULT, group_name, &group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error creating group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// (2) start to run short diagnostic.
|
||||
rdc_diag_response_t response;
|
||||
result = rdc_diagnostic_run(rdc_handle, group_id, RDC_DIAG_LVL_SHORT, nullptr, 0, &response, nullptr);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error run RDC_DIAG_LVL_SHORT diagnostic. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// (3) Check diagnostic results
|
||||
for (uint32_t i = 0; i < response.results_count; i++) {
|
||||
const rdc_diag_test_result_t& test_result = response.diag_info[i];
|
||||
std::cout << std::setw(22) << std::left << get_test_name(test_result.test_case) + ":"
|
||||
<< rdc_diagnostic_result_string(test_result.status) << "\n";
|
||||
}
|
||||
|
||||
// (4) diagnostic detail information
|
||||
std::cout << " =============== Diagnostic Details ==================\n";
|
||||
for (uint32_t i = 0; i < response.results_count; i++) {
|
||||
const rdc_diag_test_result_t& test_result = response.diag_info[i];
|
||||
if (test_result.info[0] != '\0') {
|
||||
std::cout << std::setw(22) << std::left << get_test_name(test_result.test_case) + ":"
|
||||
<< test_result.info << "\n";
|
||||
}
|
||||
for (uint32_t j = 0; j < test_result.per_gpu_result_count; j++) {
|
||||
const rdc_diag_per_gpu_result_t& gpu_result = test_result.gpu_results[j];
|
||||
if (strlen(gpu_result.gpu_result.msg) > 0) {
|
||||
std::cout << " GPU " << gpu_result.gpu_index << " " << gpu_result.gpu_result.msg << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (5) run one test case
|
||||
std::cout << " ============== Run individual diagnostic test ===========\n";
|
||||
rdc_diag_test_result_t test_result;
|
||||
result =
|
||||
rdc_test_case_run(rdc_handle, group_id, RDC_DIAG_COMPUTE_PROCESS, nullptr, 0, &test_result, nullptr);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error run RDC_DIAG_COMPUTE_PROCESS diagnostic. Return: "
|
||||
<< rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
std::cout << std::setw(22) << std::left << get_test_name(RDC_DIAG_COMPUTE_PROCESS) + ":"
|
||||
<< test_result.info << "\n";
|
||||
|
||||
// Cleanup consists of shutting down RDC.
|
||||
cleanup:
|
||||
std::cout << "Cleaning up.\n";
|
||||
if (standalone)
|
||||
rdc_disconnect(rdc_handle);
|
||||
else
|
||||
rdc_stop_embedded(rdc_handle);
|
||||
rdc_shutdown();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
int main(int, char**) {
|
||||
rdc_status_t result;
|
||||
rdc_handle_t rdc_handle;
|
||||
bool standalone = false;
|
||||
char hostIpAddress[] = {"127.0.0.1:50051"};
|
||||
char group_name[] = {"group1"};
|
||||
char field_group_name[] = {"fieldgroup1"};
|
||||
uint64_t since_timestamp = 0;
|
||||
uint64_t next_timestamp = 0;
|
||||
uint64_t start_timestamp = 0;
|
||||
uint32_t count = 0;
|
||||
|
||||
// Select the embedded mode and standalone mode dynamically.
|
||||
std::cout << "Start rdci in: \n";
|
||||
std::cout << "0 - Embedded mode \n";
|
||||
std::cout << "1 - Standalone mode \n";
|
||||
while (!(std::cin >> standalone)) {
|
||||
std::cout << "Invalid input.\n";
|
||||
std::cin.clear();
|
||||
std::cin.ignore();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << (standalone ? "Standalone mode selected.\n" : "Embedded mode selected.\n");
|
||||
|
||||
// Init the rdc
|
||||
result = rdc_init(0);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error initializing RDC. Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << "RDC Initialized.\n";
|
||||
}
|
||||
|
||||
if (standalone) { // standalone
|
||||
result = rdc_connect(hostIpAddress, &rdc_handle, nullptr, nullptr, nullptr);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error connecting to remote rdcd. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
} else { // embedded
|
||||
result = rdc_start_embedded(RDC_OPERATION_MODE_AUTO, &rdc_handle);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error starting embedded RDC engine. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can use the same API for both standalone and embedded
|
||||
// Get the list of devices in the system
|
||||
uint32_t gpu_index_list[RDC_MAX_NUM_DEVICES];
|
||||
result = rdc_device_get_all(rdc_handle, gpu_index_list, &count);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error to find devices on the system. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
if (count == 0) {
|
||||
std::cout << "No GPUs find on the sytem ";
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << count << " GPUs found in the system.\n";
|
||||
}
|
||||
|
||||
// Create the group
|
||||
rdc_gpu_group_t group_id;
|
||||
result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_EMPTY, group_name, &group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error creating group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Created the GPU group " << group_id << std::endl;
|
||||
|
||||
// Add all GPUs to the group
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
result = rdc_group_gpu_add(rdc_handle, group_id, gpu_index_list[i]); // Add GPU 0
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error adding group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
rdc_device_attributes_t attribute;
|
||||
result = rdc_device_get_attributes(rdc_handle, gpu_index_list[i], &attribute);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get GPU attribute. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Add GPU " << gpu_index_list[i] << ":" << attribute.device_name << " to group "
|
||||
<< group_id << std::endl;
|
||||
}
|
||||
|
||||
// Create the field groups to monitor POWER and TEMP
|
||||
rdc_field_grp_t field_group_id;
|
||||
rdc_field_t field_ids[2];
|
||||
field_ids[0] = RDC_FI_GPU_MEMORY_USAGE;
|
||||
field_ids[1] = RDC_FI_POWER_USAGE;
|
||||
result = rdc_group_field_create(rdc_handle, 2, &field_ids[0], field_group_name, &field_group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error create field group, Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Created the field group " << field_group_id << ": "
|
||||
<< field_id_string(RDC_FI_GPU_MEMORY_USAGE) << ", "
|
||||
<< field_id_string(RDC_FI_POWER_USAGE) << std::endl;
|
||||
|
||||
// Let the RDC to watch the fields and groups. The fields will be updated
|
||||
// once per second, the max keep age is 1 minutes and only keep 10 samples.
|
||||
result = rdc_field_watch(rdc_handle, group_id, field_group_id, 1000000, 60, 10);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error watch group fields. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Start to watch group:" << group_id << ", field_group:" << field_group_id
|
||||
<< std::endl;
|
||||
std::cout << "Sleep a few seconds before retreive the data ...\n";
|
||||
|
||||
// Since we are running the RDC_OPERATION_MODE_AUTO mode, the rdc_update_
|
||||
// all_fields() will be called periodically at background. If running as
|
||||
// RDC_OPERATION_MODE_MANUAL mode, we must call rdc_field_update_all()
|
||||
// periodically to take samples.
|
||||
usleep(5000000); // sleep 5 seconds before fetch the stats
|
||||
|
||||
// Retreive the field and group information from RDC
|
||||
rdc_group_info_t group_info;
|
||||
rdc_field_group_info_t field_info;
|
||||
result = rdc_group_gpu_get_info(rdc_handle, group_id, &group_info);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get gpu group info. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
result = rdc_group_field_get_info(rdc_handle, field_group_id, &field_info);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get field group info. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Get the latest metrics
|
||||
std::cout << "Get the latest metrics for group:" << group_id << " field_group:" << field_group_id
|
||||
<< std::endl;
|
||||
std::cout << "time_stamp\t"
|
||||
<< "GPU_index\t"
|
||||
<< "field_name\t\t"
|
||||
<< "field_value\n";
|
||||
for (uint32_t gindex = 0; gindex < group_info.count; gindex++) {
|
||||
for (uint32_t findex = 0; findex < field_info.count; findex++) {
|
||||
rdc_field_value value;
|
||||
result = rdc_field_get_latest_value(rdc_handle, group_info.entity_ids[gindex],
|
||||
field_info.field_ids[findex], &value);
|
||||
if (result == RDC_ST_NOT_FOUND) {
|
||||
continue;
|
||||
}
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get least value. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
// We only support the integer metrics so far
|
||||
std::cout << value.ts << "\t" << group_info.entity_ids[gindex] << "\t\t" << std::left
|
||||
<< std::setw(16) << field_id_string(value.field_id) << "\t" << value.value.l_int
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop watching the field group
|
||||
result = rdc_field_unwatch(rdc_handle, group_id, field_group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error stop watch fields. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Stop watch group:" << group_id << ", field_group:" << field_group_id << std::endl;
|
||||
|
||||
// Get the history data last 10 seconds
|
||||
std::cout << "Get last 10 seconds metrics for group:" << group_id
|
||||
<< " field_group:" << field_group_id << std::endl;
|
||||
std::cout << "time_stamp\t"
|
||||
<< "GPU_index\t"
|
||||
<< "field_name\t\t"
|
||||
<< "field_value\n";
|
||||
start_timestamp = static_cast<uint64_t>(time(nullptr) - 10) * 1000;
|
||||
for (uint32_t gindex = 0; gindex < group_info.count; gindex++) {
|
||||
for (uint32_t findex = 0; findex < field_info.count; findex++) {
|
||||
since_timestamp = start_timestamp;
|
||||
while (true) {
|
||||
rdc_field_value value;
|
||||
result = rdc_field_get_value_since(rdc_handle, group_info.entity_ids[gindex],
|
||||
field_info.field_ids[findex], since_timestamp,
|
||||
&next_timestamp, &value);
|
||||
if (result == RDC_ST_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get history data. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << value.ts << "\t" << group_info.entity_ids[gindex] << "\t\t" << std::left
|
||||
<< std::setw(16) << field_id_string(value.field_id) << "\t" << value.value.l_int
|
||||
<< std::endl;
|
||||
since_timestamp = next_timestamp;
|
||||
} // while
|
||||
} // for findex
|
||||
} // for gindex
|
||||
|
||||
// Delete the field group and GPU group
|
||||
result = rdc_group_field_destroy(rdc_handle, field_group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error delete field group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Deleted the field group " << field_group_id << std::endl;
|
||||
|
||||
result = rdc_group_gpu_destroy(rdc_handle, group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error delete GPU group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Deleted the GPU group " << group_id << std::endl;
|
||||
|
||||
// Cleanup consists of shutting down RDC.
|
||||
cleanup:
|
||||
std::cout << "Cleaning up.\n";
|
||||
if (standalone)
|
||||
rdc_disconnect(rdc_handle);
|
||||
else
|
||||
rdc_stop_embedded(rdc_handle);
|
||||
rdc_shutdown();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
Copyright (c) 2024 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
rdc_status_t get_watches(rdc_handle_t rdc_handle, rdc_gpu_group_t group_id) {
|
||||
unsigned int components;
|
||||
rdc_status_t result = rdc_health_get(rdc_handle, group_id, &components);
|
||||
if (result == RDC_ST_OK) {
|
||||
std::string on = "On";
|
||||
std::string off = "Off";
|
||||
|
||||
std::cout << "Health monitor systems status:" << std::endl;
|
||||
std::cout << "+--------------------+" //"-" width :20
|
||||
<< "---------------------------------------------------+\n"; //-" width :51
|
||||
std::cout << "|" << std::setw(20) << std::left << " PCIe" << "| "
|
||||
<< std::setw(50) << std::left << ((components & RDC_HEALTH_WATCH_PCIE) ? on : off).c_str() << "|\n";
|
||||
std::cout << "|" << std::setw(20) << std::left << " XGMI" << "| "
|
||||
<< std::setw(50) << std::left << ((components & RDC_HEALTH_WATCH_XGMI) ? on : off).c_str() << "|\n";
|
||||
std::cout << "|" << std::setw(20) << std::left << " Memory" << "| "
|
||||
<< std::setw(50) << std::left << ((components & RDC_HEALTH_WATCH_MEM) ? on : off).c_str() << "|\n";
|
||||
std::cout << "|" << std::setw(20) << std::left << " EEPROM" << "| "
|
||||
<< std::setw(50) << std::left << ((components & RDC_HEALTH_WATCH_EEPROM) ? on : off).c_str() << "|\n";
|
||||
std::cout << "|" << std::setw(20) << std::left << " Thermal" << "| "
|
||||
<< std::setw(50) << std::left << ((components & RDC_HEALTH_WATCH_THERMAL) ? on : off).c_str() << "|\n";
|
||||
std::cout << "|" << std::setw(20) << std::left << " Power" << "| "
|
||||
<< std::setw(50) << std::left << ((components & RDC_HEALTH_WATCH_POWER) ? on : off).c_str() << "|\n";
|
||||
std::cout << "+--------------------+" //"-" width :20
|
||||
<< "---------------------------------------------------+\n"; //-" width :51
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string health_string(rdc_health_result_t health) {
|
||||
switch (health) {
|
||||
case RDC_HEALTH_RESULT_PASS:
|
||||
return "Pass";
|
||||
|
||||
case RDC_HEALTH_RESULT_WARN:
|
||||
return "Warning";
|
||||
|
||||
case RDC_HEALTH_RESULT_FAIL:
|
||||
return "Fail";
|
||||
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string component_string(rdc_health_system_t component) {
|
||||
switch (component) {
|
||||
case RDC_HEALTH_WATCH_PCIE:
|
||||
return "PCIe system: ";
|
||||
|
||||
case RDC_HEALTH_WATCH_XGMI:
|
||||
return"XGMI system: ";
|
||||
|
||||
case RDC_HEALTH_WATCH_MEM:
|
||||
return "Memory system: ";
|
||||
|
||||
case RDC_HEALTH_WATCH_EEPROM:
|
||||
return "EEPROM system: ";
|
||||
|
||||
case RDC_HEALTH_WATCH_THERMAL:
|
||||
return "Thermal system:";
|
||||
|
||||
case RDC_HEALTH_WATCH_POWER:
|
||||
return "Power system: ";
|
||||
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void output_errstr(const std::string& input) {
|
||||
std::string word, line_str;
|
||||
unsigned int width = 60, line_size = 0;
|
||||
std::istringstream iss(input);
|
||||
|
||||
while (iss >> word) {
|
||||
if (line_size + word.size() >= width) {
|
||||
std::cout << "|" << std::setw(20) << " " << "| "
|
||||
<< std::setw(width) << std::left << line_str << "|\n";
|
||||
|
||||
//add new line string
|
||||
line_str = word;
|
||||
line_size = word.size();
|
||||
} else {
|
||||
if (line_size > 0) {
|
||||
line_str += " ";
|
||||
line_str += word;
|
||||
line_size += word.size() + 1;
|
||||
} else {
|
||||
line_str += word;
|
||||
line_size += word.size();
|
||||
}
|
||||
}
|
||||
} //end while
|
||||
|
||||
if (0 < line_size)
|
||||
std::cout << "|" << std::setw(20) << " " << "| "
|
||||
<< std::setw(width) << std::left << line_str << "|\n";
|
||||
}
|
||||
|
||||
unsigned int handle_one_component(rdc_health_response_t &response,
|
||||
unsigned int start_index,
|
||||
uint32_t gpu_index,
|
||||
rdc_health_system_t component,
|
||||
rdc_health_result_t &component_health,
|
||||
std::vector<std::string> &err_str) {
|
||||
unsigned int count = 0;
|
||||
rdc_health_incidents_t *incident;
|
||||
std::string all_err_str;
|
||||
|
||||
for (unsigned int i = start_index; i < response.incidents_count; i++) {
|
||||
incident = &response.incidents[i];
|
||||
|
||||
//same GPU Index, same component
|
||||
if ((incident->gpu_index != gpu_index) ||
|
||||
(incident->component != component))
|
||||
break;
|
||||
|
||||
//set component health
|
||||
if (incident->health > component_health)
|
||||
component_health = incident->health;
|
||||
|
||||
all_err_str = " - ";
|
||||
all_err_str += incident->error.msg;
|
||||
err_str.push_back(all_err_str);
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned int handle_one_gpu(rdc_health_response_t &response,
|
||||
unsigned int start_index,
|
||||
uint32_t gpu_index) {
|
||||
unsigned int count = 0, comp_count = 0;
|
||||
rdc_health_incidents_t *incident;
|
||||
rdc_health_result_t gpu_health = RDC_HEALTH_RESULT_PASS;
|
||||
std::string component_str, health_str, gpu_health_str;
|
||||
typedef struct {
|
||||
rdc_health_result_t component_health;
|
||||
std::vector<std::string> err_str;
|
||||
} component_detail_t;
|
||||
std::map<rdc_health_system_t, component_detail_t> component_detail_map;
|
||||
|
||||
for (unsigned int i = start_index; i < response.incidents_count; i++) {
|
||||
incident = &response.incidents[i];
|
||||
|
||||
//same GPU Index
|
||||
if (incident->gpu_index != gpu_index)
|
||||
break;
|
||||
|
||||
//set gpu health
|
||||
if (incident->health > gpu_health)
|
||||
gpu_health = incident->health;
|
||||
|
||||
//handle smae component
|
||||
component_detail_t detail;
|
||||
detail.component_health = RDC_HEALTH_RESULT_PASS;
|
||||
detail.err_str.clear();
|
||||
|
||||
comp_count = handle_one_component(response, i, gpu_index, incident->component, detail.component_health, detail.err_str);
|
||||
i += comp_count - 1;
|
||||
count += comp_count;
|
||||
|
||||
// Add to the component detail map
|
||||
component_detail_map.insert({incident->component, detail});
|
||||
}
|
||||
|
||||
//output gpu_index health result
|
||||
gpu_health_str = health_string(gpu_health);
|
||||
|
||||
std::cout << "|" << std::setw(20) << " GPU ID: " + std::to_string(gpu_index) << "| "
|
||||
<< std::setw(60) << std::left << gpu_health_str << "|\n";
|
||||
std::cout << "|" << std::setw(20) << " " << "| "
|
||||
<< std::setw(60) << " " << "|\n";
|
||||
|
||||
for (auto ite : component_detail_map) {
|
||||
component_str = component_string(ite.first);
|
||||
health_str = health_string(ite.second.component_health);
|
||||
std::cout << "|" << std::setw(20) << " " << "| "
|
||||
<< std::setw(60) << std::left << component_str + health_str << "|\n";
|
||||
|
||||
for (auto msg : ite.second.err_str)
|
||||
output_errstr(msg);
|
||||
|
||||
std::cout << "|" << std::setw(20) << " " << "| "
|
||||
<< std::setw(60) << " " << "|\n";
|
||||
}
|
||||
std::cout << "+--------------------+-" //"-" width :20
|
||||
<< "------------------------------------------------------------+\n"; //-" width :60
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
rdc_status_t result;
|
||||
rdc_handle_t rdc_handle;
|
||||
char hostIpAddress[] = {"127.0.0.1:50051"};
|
||||
char group_name[] = {"healthgroup1"};
|
||||
|
||||
std::cout << "Start rdci in Standalone mode\n";
|
||||
|
||||
// Init the rdc
|
||||
result = rdc_init(0);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error initializing RDC. Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << "RDC Initialized.\n";
|
||||
}
|
||||
|
||||
result = rdc_connect(hostIpAddress, &rdc_handle, nullptr, nullptr, nullptr);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error connecting to remote rdcd. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Now we can use the same API for standalone
|
||||
// (1) create group and add GPUs
|
||||
rdc_gpu_group_t group_id;
|
||||
result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_EMPTY, group_name, &group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error creating group. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Created the GPU group " << group_id << std::endl;
|
||||
|
||||
result = rdc_group_gpu_add(rdc_handle, group_id, 0); // Add GPU 0
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error adding group. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto destroygroup;
|
||||
}
|
||||
|
||||
rdc_device_attributes_t attribute;
|
||||
result = rdc_device_get_attributes(rdc_handle, 0, &attribute);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get GPU attribute. Return: " << rdc_status_string(result);
|
||||
goto destroygroup;
|
||||
}
|
||||
std::cout << "Add GPU 0: " << attribute.device_name << " to group "
|
||||
<< group_id << std::endl;
|
||||
|
||||
// (2) get heath current watches before setting
|
||||
result = get_watches(rdc_handle, group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error getting health watches. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto destroygroup;
|
||||
}
|
||||
|
||||
// (3) set health watches.
|
||||
unsigned int components;
|
||||
components = RDC_HEALTH_WATCH_PCIE | RDC_HEALTH_WATCH_XGMI | RDC_HEALTH_WATCH_MEM
|
||||
| RDC_HEALTH_WATCH_EEPROM | RDC_HEALTH_WATCH_THERMAL
|
||||
| RDC_HEALTH_WATCH_POWER;
|
||||
result = rdc_health_set(rdc_handle, group_id, components);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error setting health watches. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto destroygroup;
|
||||
}
|
||||
std::cout << "Set health watches to all." << std::endl;
|
||||
|
||||
// (4) get heath current watches after setting
|
||||
result = get_watches(rdc_handle, group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error getting health watches. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto destroygroup;
|
||||
}
|
||||
|
||||
std::cout << "Start to health monitor group:" << group_id
|
||||
<< std::endl;
|
||||
std::cout << "Sleep a few seconds before retreive the data ...\n";
|
||||
// For standalone mode, the daemon will update and cache the samples
|
||||
// take samples, standalone mode, do nothing
|
||||
usleep(5000000); // sleep 5 seconds before fetch the stats
|
||||
|
||||
// (5) Get the health stats
|
||||
rdc_health_response_t response;
|
||||
result = rdc_health_check(rdc_handle, group_id, &response);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error health check. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto destroygroup;
|
||||
} else {
|
||||
//output headline
|
||||
std::string overall_str = health_string(response.overall_health);
|
||||
std::cout << "Health monitor report:" << std::endl;
|
||||
std::cout << "+--------------------+-" //"-" width :20
|
||||
<< "------------------------------------------------------------+\n"; //-" width :60
|
||||
std::cout << "|" << std::setw(20) << std::left << " Group " + std::to_string(group_id) << "| "
|
||||
<< std::setw(60) << std::left << "Overall Health: " + overall_str << "|\n";
|
||||
std::cout << "+====================+=" //"=" width :20
|
||||
<< "============================================================+\n"; //"=" width :60
|
||||
|
||||
//output health of per GPU
|
||||
unsigned int index = 0;
|
||||
while (index < response.incidents_count) {
|
||||
uint32_t gpu_index = response.incidents[index].gpu_index;
|
||||
|
||||
unsigned int count = handle_one_gpu(response, index, gpu_index);
|
||||
index += count;
|
||||
}
|
||||
}
|
||||
|
||||
// (6) Clear the health
|
||||
result = rdc_health_clear(rdc_handle, group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error clear health. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto destroygroup;
|
||||
}
|
||||
std::cout << "Clear Group " << group_id << " all health monitor systems." << std::endl;
|
||||
|
||||
destroygroup:
|
||||
// Delete the GPU group
|
||||
result = rdc_group_gpu_destroy(rdc_handle, group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error delete GPU group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Deleted the GPU group " << group_id << std::endl;
|
||||
|
||||
// Cleanup consists of shutting down RDC.
|
||||
cleanup:
|
||||
std::cout << "Cleaning up.\n";
|
||||
rdc_disconnect(rdc_handle);
|
||||
rdc_shutdown();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
int main(int, char**) {
|
||||
rdc_status_t result;
|
||||
rdc_handle_t rdc_handle;
|
||||
bool standalone = false;
|
||||
char hostIpAddress[] = {"127.0.0.1:50051"};
|
||||
char group_name[] = {"group1"};
|
||||
char job_id[] = {"123"};
|
||||
|
||||
// Select the embedded mode and standalone mode dynamically.
|
||||
std::cout << "Start rdci in: \n";
|
||||
std::cout << "0 - Embedded mode \n";
|
||||
std::cout << "1 - Standalone mode \n";
|
||||
while (!(std::cin >> standalone)) {
|
||||
std::cout << "Invalid input.\n";
|
||||
std::cin.clear();
|
||||
std::cin.ignore();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << (standalone ? "Standalone mode selected.\n" : "Embedded mode selected.\n");
|
||||
|
||||
// Init the rdc
|
||||
result = rdc_init(0);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error initializing RDC. Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << "RDC Initialized.\n";
|
||||
}
|
||||
|
||||
if (standalone) { // standalone
|
||||
result = rdc_connect(hostIpAddress, &rdc_handle, nullptr, nullptr, nullptr);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error connecting to remote rdcd. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
} else { // embedded
|
||||
result = rdc_start_embedded(RDC_OPERATION_MODE_MANUAL, &rdc_handle);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error starting embedded RDC engine. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can use the same API for both standalone and embedded
|
||||
// (1) create group and add GPUs
|
||||
rdc_gpu_group_t group_id;
|
||||
result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_EMPTY, group_name, &group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error creating group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = rdc_group_gpu_add(rdc_handle, group_id, 0); // Add GPU 0
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error adding group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// (2) start the recording. Set the sample frequency to once per second.
|
||||
result = rdc_job_start_stats(rdc_handle, group_id, job_id, 1000000);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error start job stats. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// For standalone mode, the daemon will update and cache the samples
|
||||
// In manual mode, we must call rdc_field_update_all periodically to
|
||||
// take samples.
|
||||
if (!standalone) { // embedded manual mode
|
||||
for (int i = 5; i > 0; i--) { // As an example, we will take 5 samples
|
||||
result = rdc_field_update_all(rdc_handle, 0);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error update all fields. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
usleep(1000000);
|
||||
}
|
||||
} else { // standalone mode, do nothing
|
||||
usleep(5000000); // sleep 5 seconds before fetch the stats
|
||||
}
|
||||
|
||||
// (3) stop the Slurm job, which will stop the watch
|
||||
// We do not have to stop the job to get stats. The rdc_job_get_stats can be
|
||||
// called at any time before stop
|
||||
result = rdc_job_stop_stats(rdc_handle, job_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error stop job stats. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// (4) Get the stats
|
||||
rdc_job_info_t job_info;
|
||||
result = rdc_job_get_stats(rdc_handle, job_id, &job_info);
|
||||
|
||||
if (result == RDC_ST_OK) {
|
||||
std::cout << "|------- Execution Stats ----------+"
|
||||
<< "------------------------------------\n";
|
||||
std::cout << "| Start Time * | " << job_info.summary.start_time << "\n";
|
||||
std::cout << "| End Time * | " << job_info.summary.end_time << "\n";
|
||||
std::cout << "| Total Execution Time (sec) * | "
|
||||
<< (job_info.summary.end_time - job_info.summary.start_time) << "\n";
|
||||
std::cout << "+------- Performance Stats --------+"
|
||||
<< "------------------------------------\n";
|
||||
std::cout << "| Energy Consumed (Joules) | " << job_info.summary.energy_consumed
|
||||
<< "\n";
|
||||
std::cout << "| Power Usage (Watts) | "
|
||||
<< "Max: " << job_info.summary.power_usage.max_value
|
||||
<< " Min: " << job_info.summary.power_usage.min_value
|
||||
<< " Avg: " << job_info.summary.power_usage.average << "\n";
|
||||
std::cout << "| GPU Clock (MHz) | "
|
||||
<< "Max: " << job_info.summary.gpu_clock.max_value
|
||||
<< " Min: " << job_info.summary.gpu_clock.min_value
|
||||
<< " Avg: " << job_info.summary.gpu_clock.average << "\n";
|
||||
std::cout << "| GPU Utilization (%) | "
|
||||
<< "Max: " << job_info.summary.gpu_utilization.max_value
|
||||
<< " Min: " << job_info.summary.gpu_utilization.min_value
|
||||
<< " Avg: " << job_info.summary.gpu_utilization.average << "\n";
|
||||
std::cout << "| Max GPU Memory Used (bytes) * | " << job_info.summary.max_gpu_memory_used
|
||||
<< "\n";
|
||||
std::cout << "| Memory Utilization (%) | "
|
||||
<< "Max: " << job_info.summary.memory_utilization.max_value
|
||||
<< " Min: " << job_info.summary.memory_utilization.min_value
|
||||
<< " Avg: " << job_info.summary.memory_utilization.average << "\n";
|
||||
std::cout << "+----------------------------------+"
|
||||
<< "------------------------------------\n";
|
||||
} else {
|
||||
std::cout << "No data for job stats found." << std::endl;
|
||||
}
|
||||
|
||||
// Cleanup consists of shutting down RDC.
|
||||
cleanup:
|
||||
std::cout << "Cleaning up.\n";
|
||||
if (standalone)
|
||||
rdc_disconnect(rdc_handle);
|
||||
else
|
||||
rdc_stop_embedded(rdc_handle);
|
||||
rdc_shutdown();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
Copyright (C) Advanced Micro Devices. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
static const char* condition_type_to_str(rdc_policy_condition_type_t type) {
|
||||
if (type == RDC_POLICY_COND_MAX_PAGE_RETRIED) return "Retried Page Limit";
|
||||
if (type == RDC_POLICY_COND_THERMAL) return "Temperature Limit";
|
||||
if (type == RDC_POLICY_COND_POWER) return "Power Limit";
|
||||
return "Unknown_Type";
|
||||
}
|
||||
|
||||
static time_t last_time = 0; // last time to print message
|
||||
int rdc_policy_callback(rdc_policy_callback_response_t* userData) {
|
||||
if (userData == nullptr) {
|
||||
std::cerr << "The rdc_policy_callback returns null data\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// To avoid flooding too many messages, only print message every 5 seconds
|
||||
time_t now = time(NULL);
|
||||
if (difftime(now, last_time) < 5) {
|
||||
return 0;
|
||||
}
|
||||
std::cout << "The " << condition_type_to_str(userData->condition.type)
|
||||
<< " exceeds the threshold " << userData->condition.value << " with the value "
|
||||
<< userData->value << std::endl;
|
||||
last_time = now; // update the last time
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
rdc_gpu_group_t group_id;
|
||||
rdc_status_t result;
|
||||
bool standalone = false;
|
||||
rdc_handle_t rdc_handle;
|
||||
uint32_t count = 0;
|
||||
|
||||
char hostIpAddress[] = {"localhost:50051"};
|
||||
char group_name[] = {"group1"};
|
||||
|
||||
// Select the embedded mode and standalone mode dynamically.
|
||||
std::cout << "Start rdci in: \n";
|
||||
std::cout << "0 - Embedded mode \n";
|
||||
std::cout << "1 - Standalone mode \n";
|
||||
while (!(std::cin >> standalone)) {
|
||||
std::cout << "Invalid input.\n";
|
||||
std::cin.clear();
|
||||
std::cin.ignore();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << (standalone ? "Standalone mode selected.\n" : "Embedded mode selected.\n");
|
||||
|
||||
// Init the rdc
|
||||
result = rdc_init(0);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error initializing RDC. Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << "RDC Initialized.\n";
|
||||
}
|
||||
|
||||
if (standalone) { // standalone
|
||||
result = rdc_connect(hostIpAddress, &rdc_handle, nullptr, nullptr, nullptr);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error connecting to remote rdcd. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
} else { // embedded
|
||||
result = rdc_start_embedded(RDC_OPERATION_MODE_AUTO, &rdc_handle);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error starting embedded RDC engine. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can use the same API for both standalone and embedded
|
||||
// Get the list of devices in the system
|
||||
uint32_t gpu_index_list[RDC_MAX_NUM_DEVICES];
|
||||
result = rdc_device_get_all(rdc_handle, gpu_index_list, &count);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error to find devices on the system. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
if (count == 0) {
|
||||
std::cout << "No GPUs find on the sytem ";
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << count << " GPUs found in the system.\n";
|
||||
}
|
||||
|
||||
// Create the group
|
||||
result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_EMPTY, group_name, &group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error creating group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Created the GPU group " << group_id << std::endl;
|
||||
|
||||
// Add all GPUs to the group
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
result = rdc_group_gpu_add(rdc_handle, group_id, gpu_index_list[i]); // Add GPU 0
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error adding group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
rdc_device_attributes_t attribute;
|
||||
result = rdc_device_get_attributes(rdc_handle, gpu_index_list[i], &attribute);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get GPU attribute. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Add GPU " << gpu_index_list[i] << ":" << attribute.device_name << " to group "
|
||||
<< group_id << std::endl;
|
||||
}
|
||||
|
||||
// Define a policy to print out message when temperature is above 30 degree
|
||||
// or power usage is more than 150W
|
||||
rdc_policy_t policy;
|
||||
policy.condition = {RDC_POLICY_COND_THERMAL, 30 * 1000}; // convert to milli degree
|
||||
policy.action = RDC_POLICY_ACTION_NONE; // Notify only
|
||||
result = rdc_policy_set(rdc_handle, group_id, policy);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error set policy RDC_POLICY_COND_THERMAL, Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
policy.condition = {RDC_POLICY_COND_POWER, 150000}; // convert to milli degree
|
||||
policy.action = RDC_POLICY_ACTION_NONE; // Notify only
|
||||
result = rdc_policy_set(rdc_handle, group_id, policy);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error set policy RDC_POLICY_COND_POWER, Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
policy.condition = {RDC_POLICY_COND_MAX_PAGE_RETRIED, 100}; // convert to milli degree
|
||||
policy.action = RDC_POLICY_ACTION_NONE; // Notify only
|
||||
result = rdc_policy_set(rdc_handle, group_id, policy);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error set policy RDC_POLICY_COND_MAX_PAGE_RETRIED, Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rdc_policy_t policy_get[RDC_MAX_POLICY_SETTINGS];
|
||||
result = rdc_policy_get(rdc_handle, group_id, &count, policy_get);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get policy, Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Register a function to listen to the events
|
||||
result = rdc_policy_register(rdc_handle, group_id, rdc_policy_callback);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error register policy, Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
std::cout << "Wait 30 seconds for the events happening ...\n" << std::endl;
|
||||
|
||||
// If the events happening, the callback rdc_policy_register_callback will be called.
|
||||
usleep(30 * 1000000); // sleep 30 seconds
|
||||
|
||||
// Un-register the events
|
||||
result = rdc_policy_unregister(rdc_handle, group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error unregister policy, Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// clear the events
|
||||
rdc_policy_condition_type_t condition_type;
|
||||
condition_type = RDC_POLICY_COND_THERMAL;
|
||||
result = rdc_policy_delete(rdc_handle, group_id, condition_type);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error clear policy, Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
//... clean up
|
||||
cleanup:
|
||||
std::cout << "Cleaning up.\n";
|
||||
if (standalone)
|
||||
rdc_disconnect(rdc_handle);
|
||||
else
|
||||
rdc_stop_embedded(rdc_handle);
|
||||
rdc_shutdown();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
Copyright (c) 2024 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
rdc_handle_t rdc_handle;
|
||||
rdc_status_t result;
|
||||
|
||||
const std::string value_to_string(rdc_field_value value) {
|
||||
switch (value.type) {
|
||||
case INTEGER:
|
||||
return std::to_string(value.value.l_int);
|
||||
case DOUBLE:
|
||||
return std::to_string(value.value.dbl);
|
||||
case STRING:
|
||||
return value.value.str;
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup consists of shutting down RDC.
|
||||
rdc_status_t cleanup() {
|
||||
std::cout << "Cleaning up.\n";
|
||||
rdc_stop_embedded(rdc_handle);
|
||||
rdc_shutdown();
|
||||
return result;
|
||||
}
|
||||
|
||||
int run() {
|
||||
char group_name[] = {"group1"};
|
||||
char field_group_name[] = {"fieldgroup1"};
|
||||
uint64_t since_timestamp = 0;
|
||||
uint64_t next_timestamp = 0;
|
||||
uint64_t start_timestamp = 0;
|
||||
uint32_t count = 0;
|
||||
|
||||
// Select the embedded mode and standalone mode dynamically.
|
||||
std::cout << "Starting rdci in Embedded mode\n";
|
||||
|
||||
// Init the rdc
|
||||
result = rdc_init(0);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error initializing RDC. Return: " << rdc_status_string(result) << std::endl;
|
||||
return cleanup();
|
||||
} else {
|
||||
std::cout << "RDC Initialized.\n";
|
||||
}
|
||||
|
||||
result = rdc_start_embedded(RDC_OPERATION_MODE_AUTO, &rdc_handle);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error starting embedded RDC engine. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
return cleanup();
|
||||
}
|
||||
|
||||
// Get the list of devices in the system
|
||||
uint32_t gpu_index_list[RDC_MAX_NUM_DEVICES];
|
||||
result = rdc_device_get_all(rdc_handle, gpu_index_list, &count);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error to find devices on the system. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
if (count == 0) {
|
||||
std::cout << "No GPUs find on the sytem ";
|
||||
return cleanup();
|
||||
} else {
|
||||
std::cout << count << " GPUs found in the system.\n";
|
||||
}
|
||||
|
||||
// Create the group
|
||||
rdc_gpu_group_t group_id = 0;
|
||||
result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_EMPTY, group_name, &group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error creating group. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
std::cout << "Created the GPU group " << group_id << std::endl;
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
result = rdc_group_gpu_add(rdc_handle, group_id, gpu_index_list[i]); // Add GPU 0
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error adding group. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
rdc_device_attributes_t attribute;
|
||||
result = rdc_device_get_attributes(rdc_handle, gpu_index_list[i], &attribute);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get GPU attribute. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
std::cout << "Add GPU " << gpu_index_list[i] << ":" << attribute.device_name << " to group "
|
||||
<< group_id << std::endl;
|
||||
}
|
||||
|
||||
// Create a field group to monitor multiple fields
|
||||
rdc_field_grp_t field_group_id = 0;
|
||||
std::vector<rdc_field_t> field_ids{};
|
||||
|
||||
field_ids.push_back(RDC_FI_GPU_MEMORY_USAGE);
|
||||
field_ids.push_back(RDC_FI_POWER_USAGE);
|
||||
// profiler metrics
|
||||
field_ids.push_back(RDC_FI_PROF_OCCUPANCY_PERCENT);
|
||||
field_ids.push_back(RDC_FI_PROF_ACTIVE_CYCLES);
|
||||
field_ids.push_back(RDC_FI_PROF_ACTIVE_WAVES);
|
||||
field_ids.push_back(RDC_FI_PROF_ELAPSED_CYCLES);
|
||||
// profiler metrics divided over time
|
||||
field_ids.push_back(RDC_FI_PROF_EVAL_MEM_R_BW);
|
||||
field_ids.push_back(RDC_FI_PROF_EVAL_MEM_W_BW);
|
||||
field_ids.push_back(RDC_FI_PROF_EVAL_FLOPS_16);
|
||||
field_ids.push_back(RDC_FI_PROF_EVAL_FLOPS_32);
|
||||
field_ids.push_back(RDC_FI_PROF_EVAL_FLOPS_64);
|
||||
field_ids.push_back(RDC_FI_PROF_SM_ACTIVE);
|
||||
result = rdc_group_field_create(rdc_handle, field_ids.size(), field_ids.data(), field_group_name,
|
||||
&field_group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error create field group, Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
std::cout << "Created the field group " << field_group_id << "\n";
|
||||
std::cout << "fields: ";
|
||||
for (auto field_id : field_ids) {
|
||||
std::cout << "- " << field_id << "\n";
|
||||
}
|
||||
|
||||
// Let the RDC to watch the fields and groups. The fields will be updated
|
||||
// once per second, the max keep age is 1 minutes and only keep 10 samples.
|
||||
result = rdc_field_watch(rdc_handle, group_id, field_group_id,
|
||||
static_cast<uint64_t>(1) * 10 * 1000, 60, 10);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error watch group fields. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
std::cout << "Start to watch group:" << group_id << ", field_group:" << field_group_id
|
||||
<< std::endl;
|
||||
std::cout << "Sleep a few seconds before retreive the data ...\n";
|
||||
|
||||
// Since we are running the RDC_OPERATION_MODE_AUTO mode, the rdc_update_
|
||||
// all_fields() will be called periodically at background. If running as
|
||||
// RDC_OPERATION_MODE_MANUAL mode, we must call rdc_field_update_all()
|
||||
// periodically to take samples.
|
||||
usleep(5 * 10 * 1000); // sleep 0.05 seconds before fetch the stats
|
||||
|
||||
// Retreive the field and group information from RDC
|
||||
rdc_group_info_t group_info;
|
||||
rdc_field_group_info_t field_info;
|
||||
result = rdc_group_gpu_get_info(rdc_handle, group_id, &group_info);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get gpu group info. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
result = rdc_group_field_get_info(rdc_handle, field_group_id, &field_info);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get field group info. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
|
||||
// Get the latest metrics
|
||||
std::cout << "Get the latest metrics for group:" << group_id << " field_group:" << field_group_id
|
||||
<< std::endl;
|
||||
std::cout << "time_stamp\t"
|
||||
<< "GPU_index\t"
|
||||
<< "field_name\t\t"
|
||||
<< "field_value\n";
|
||||
for (uint32_t gindex = 0; gindex < group_info.count; gindex++) {
|
||||
for (uint32_t findex = 0; findex < field_info.count; findex++) {
|
||||
rdc_field_value value;
|
||||
result = rdc_field_get_latest_value(rdc_handle, group_info.entity_ids[gindex],
|
||||
field_info.field_ids[findex], &value);
|
||||
if (result == RDC_ST_NOT_FOUND) {
|
||||
continue;
|
||||
}
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get least value. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
// We only support the integer metrics so far
|
||||
std::cout << value.ts << "\t" << group_info.entity_ids[gindex] << "\t\t" << std::left
|
||||
<< std::setw(16) << field_id_string(value.field_id) << "\t"
|
||||
<< value_to_string(value) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop watching the field group
|
||||
result = rdc_field_unwatch(rdc_handle, group_id, field_group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error stop watch fields. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
std::cout << "Stop watch group:" << group_id << ", field_group:" << field_group_id << std::endl;
|
||||
|
||||
// Get the history data last 0.1 seconds
|
||||
std::cout << "Get last 0.1 seconds metrics for group:" << group_id
|
||||
<< " field_group:" << field_group_id << std::endl;
|
||||
std::cout << "time_stamp\t"
|
||||
<< "GPU_index\t"
|
||||
<< "field_name\t\t"
|
||||
<< "field_value\n";
|
||||
start_timestamp = static_cast<uint64_t>(time(nullptr) - 10) * 1000;
|
||||
for (uint32_t gindex = 0; gindex < group_info.count; gindex++) {
|
||||
for (uint32_t findex = 0; findex < field_info.count; findex++) {
|
||||
since_timestamp = start_timestamp;
|
||||
while (true) {
|
||||
rdc_field_value value;
|
||||
result = rdc_field_get_value_since(rdc_handle, group_info.entity_ids[gindex],
|
||||
field_info.field_ids[findex], since_timestamp,
|
||||
&next_timestamp, &value);
|
||||
if (result == RDC_ST_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get history data. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
std::cout << value.ts << "\t" << group_info.entity_ids[gindex] << "\t\t" << std::left
|
||||
<< std::setw(16) << field_id_string(value.field_id) << "\t"
|
||||
<< value_to_string(value) << std::endl;
|
||||
since_timestamp = next_timestamp;
|
||||
} // while
|
||||
} // for findex
|
||||
} // for gindex
|
||||
|
||||
// Delete the field group and GPU group
|
||||
result = rdc_group_field_destroy(rdc_handle, field_group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error delete field group. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
std::cout << "Deleted the field group " << field_group_id << std::endl;
|
||||
|
||||
result = rdc_group_gpu_destroy(rdc_handle, group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error delete GPU group. Return: " << rdc_status_string(result);
|
||||
return cleanup();
|
||||
}
|
||||
std::cout << "Deleted the GPU group " << group_id << std::endl;
|
||||
|
||||
return cleanup();
|
||||
}
|
||||
|
||||
int main(int, char**) { return run(); }
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
Copyright (C) Advanced Micro Devices. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
static const char* topology_link_type_to_str(rdc_topology_link_type_t type) {
|
||||
if (type == RDC_IOLINK_TYPE_PCIEXPRESS) return "RDC_IOLINK_TYPE_PCIEXPRESS";
|
||||
if (type == RDC_IOLINK_TYPE_XGMI) return "RDC_IOLINK_TYPE_XGMI";
|
||||
return "Unknown_Type";
|
||||
}
|
||||
int main() {
|
||||
rdc_gpu_group_t group_id;
|
||||
rdc_status_t result;
|
||||
bool standalone = false;
|
||||
rdc_handle_t rdc_handle;
|
||||
uint32_t count = 0;
|
||||
|
||||
char hostIpAddress[] = {"localhost:50051"};
|
||||
char group_name[] = {"group1"};
|
||||
|
||||
// Select the embedded mode and standalone mode dynamically.
|
||||
std::cout << "Start rdci in: \n";
|
||||
std::cout << "0 - Embedded mode \n";
|
||||
std::cout << "1 - Standalone mode \n";
|
||||
while (!(std::cin >> standalone)) {
|
||||
std::cout << "Invalid input.\n";
|
||||
std::cin.clear();
|
||||
std::cin.ignore();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << (standalone ? "Standalone mode selected.\n" : "Embedded mode selected.\n");
|
||||
|
||||
// Init the rdc
|
||||
result = rdc_init(0);
|
||||
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error initializing RDC. Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << "RDC Initialized.\n";
|
||||
}
|
||||
|
||||
if (standalone) { // standalone
|
||||
result = rdc_connect(hostIpAddress, &rdc_handle, nullptr, nullptr, nullptr);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error connecting to remote rdcd. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
} else { // embedded
|
||||
result = rdc_start_embedded(RDC_OPERATION_MODE_AUTO, &rdc_handle);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error starting embedded RDC engine. Return: " << rdc_status_string(result)
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can use the same API for both standalone and embedded
|
||||
// Get the list of devices in the system
|
||||
uint32_t gpu_index_list[RDC_MAX_NUM_DEVICES];
|
||||
result = rdc_device_get_all(rdc_handle, gpu_index_list, &count);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error to find devices on the system. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
if (count == 0) {
|
||||
std::cout << "No GPUs find on the sytem ";
|
||||
goto cleanup;
|
||||
} else {
|
||||
std::cout << count << " GPUs found in the system.\n";
|
||||
}
|
||||
|
||||
// Create the group
|
||||
result = rdc_group_gpu_create(rdc_handle, RDC_GROUP_EMPTY, group_name, &group_id);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error creating group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Created the GPU group " << group_id << std::endl;
|
||||
|
||||
// Add all GPUs to the group
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
result = rdc_group_gpu_add(rdc_handle, group_id, gpu_index_list[i]); // Add GPU 0
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error adding group. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
rdc_device_attributes_t attribute;
|
||||
result = rdc_device_get_attributes(rdc_handle, gpu_index_list[i], &attribute);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get GPU attribute. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "Add GPU " << gpu_index_list[i] << ":" << attribute.device_name << " to group "
|
||||
<< group_id << std::endl;
|
||||
}
|
||||
rdc_group_info_t group_info;
|
||||
result = rdc_group_gpu_get_info(rdc_handle, group_id, &group_info);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error get gpu group info. Return: " << rdc_status_string(result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rdc_device_topology_t topo;
|
||||
result = rdc_device_topology_get(rdc_handle, group_info.entity_ids[0], &topo);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error clear topology, Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < topo.num_of_gpus; i++) {
|
||||
std::cout << "Topology Information Return \n "
|
||||
<< "gpu_index: " << std::to_string(topo.link_infos[i].gpu_index) << "\n"
|
||||
<< "weight: " << std::to_string(topo.link_infos[i].weight) << "\n"
|
||||
<< "min_bandwidth: " << std::to_string(topo.link_infos[i].min_bandwidth) << "\n"
|
||||
<< "max_bandwidth: " << std::to_string(topo.link_infos[i].max_bandwidth) << "\n"
|
||||
<< "hops: " << std::to_string(topo.link_infos[i].hops) << "\n"
|
||||
<< "link_type: " << topology_link_type_to_str(topo.link_infos[i].link_type) << "\n"
|
||||
<< "is_p2p_accessible: " << std::to_string(topo.link_infos[i].is_p2p_accessible)
|
||||
<< "\n"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
rdc_link_status_t link_status;
|
||||
result = rdc_link_status_get(rdc_handle, &link_status);
|
||||
if (result != RDC_ST_OK) {
|
||||
std::cout << "Error clear topology, Return: " << rdc_status_string(result) << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
//... clean up
|
||||
cleanup:
|
||||
std::cout << "Cleaning up.\n";
|
||||
if (standalone)
|
||||
rdc_disconnect(rdc_handle);
|
||||
else
|
||||
rdc_stop_embedded(rdc_handle);
|
||||
rdc_shutdown();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
#ifndef INCLUDE_RDC_RDC_PRIVATE_H_
|
||||
#define INCLUDE_RDC_RDC_PRIVATE_H_
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
// cstddef include causes issues on older GCC
|
||||
// use stddef.h instead
|
||||
#if __GNUC__ < 9
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#endif // __GNUC__
|
||||
|
||||
#include <cstdint>
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#endif // __cplusplus
|
||||
|
||||
/**
|
||||
* @brief The maximum string length occupied by version information.
|
||||
*/
|
||||
#define USR_MAX_VERSION_STR_LENGTH 60
|
||||
|
||||
/**
|
||||
* @brief Version information of mixed components
|
||||
*/
|
||||
typedef struct {
|
||||
char version[USR_MAX_VERSION_STR_LENGTH];
|
||||
} mixed_component_version_t;
|
||||
|
||||
/**
|
||||
* @brief Type of Components
|
||||
*/
|
||||
typedef enum {
|
||||
RDCD_COMPONENT
|
||||
//If needed later, add them one by one
|
||||
} mixed_component_t;
|
||||
|
||||
/**
|
||||
* @brief Get ersion information of mixed components.
|
||||
*
|
||||
* @details Given a component type, return its version information.
|
||||
*
|
||||
* @param[in] p_rdc_handle The RDC handler.
|
||||
*
|
||||
* @param[in] component Component type.
|
||||
*
|
||||
* @param[out] p_mixed_compv Version information of the corresponding component.
|
||||
*
|
||||
* @retval ::RDC_ST_OK is returned upon successful call.
|
||||
*/
|
||||
rdc_status_t get_mixed_component_version(rdc_handle_t p_rdc_handle, mixed_component_t component, mixed_component_version_t* p_mixed_compv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // INCLUDE_RDC_RDC_PRIVATE_H_
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCCACHEMANAGER_H_
|
||||
#define INCLUDE_RDC_LIB_RDCCACHEMANAGER_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
#include "rdc_lib/rdc_common.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
class RdcCacheManager {
|
||||
public:
|
||||
virtual rdc_status_t rdc_field_get_latest_value(uint32_t gpu_index, rdc_field_t field,
|
||||
rdc_field_value* value) = 0;
|
||||
virtual rdc_status_t rdc_field_get_value_since(uint32_t gpu_index, rdc_field_t field,
|
||||
uint64_t since_time_stamp,
|
||||
uint64_t* next_since_time_stamp,
|
||||
rdc_field_value* value) = 0;
|
||||
virtual rdc_status_t rdc_update_cache(uint32_t gpu_index, const rdc_field_value& value) = 0;
|
||||
virtual rdc_status_t evict_cache(uint32_t gpu_index, rdc_field_t field_id,
|
||||
uint64_t max_keep_samples, double max_keep_age) = 0;
|
||||
virtual std::string get_cache_stats() = 0;
|
||||
|
||||
virtual rdc_status_t rdc_job_get_stats(const char job_id[64], const rdc_gpu_gauges_t& gpu_gauges,
|
||||
rdc_job_info_t* p_job_info) = 0;
|
||||
virtual rdc_status_t rdc_job_start_stats(const char job_id[64], const rdc_group_info_t& group,
|
||||
const rdc_field_group_info_t& finfo,
|
||||
const rdc_gpu_gauges_t& gpu_gauges) = 0;
|
||||
virtual rdc_status_t rdc_job_stop_stats(const char job_id[64],
|
||||
const rdc_gpu_gauges_t& gpu_gauge) = 0;
|
||||
virtual rdc_status_t rdc_update_job_stats(uint32_t gpu_index, const std::string& job_id,
|
||||
const rdc_field_value& value) = 0;
|
||||
virtual rdc_status_t rdc_job_remove(const char job_id[64]) = 0;
|
||||
virtual rdc_status_t rdc_job_remove_all() = 0;
|
||||
|
||||
virtual rdc_status_t rdc_health_set(rdc_gpu_group_t group_id,
|
||||
uint32_t gpu_index,
|
||||
const rdc_field_value& value) = 0;
|
||||
virtual rdc_status_t rdc_health_get_values(rdc_gpu_group_t group_id,
|
||||
uint32_t gpu_index,
|
||||
rdc_field_t field_id,
|
||||
uint64_t start_timestamp,
|
||||
uint64_t end_timestamp,
|
||||
rdc_field_value* start_value,
|
||||
rdc_field_value* end_value) = 0;
|
||||
virtual rdc_status_t rdc_health_clear(rdc_gpu_group_t group_id) = 0;
|
||||
virtual rdc_status_t rdc_update_health_stats(rdc_gpu_group_t group_id,
|
||||
uint32_t gpu_index,
|
||||
const rdc_field_value& value) = 0;
|
||||
|
||||
virtual ~RdcCacheManager() {}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<RdcCacheManager> RdcCacheManagerPtr;
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCCACHEMANAGER_H_
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (c) 2024 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCCONFIGSETTINGS_H_
|
||||
#define INCLUDE_RDC_LIB_RDCCONFIGSETTINGS_H_
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
class RdcConfigSettings {
|
||||
public:
|
||||
// Set one configure
|
||||
virtual rdc_status_t rdc_config_set(rdc_gpu_group_t group_id, rdc_config_setting_t setting) = 0;
|
||||
|
||||
// Get the setting
|
||||
virtual rdc_status_t rdc_config_get(rdc_gpu_group_t group_id,
|
||||
rdc_config_setting_list_t* settings) = 0;
|
||||
|
||||
// Clear the setting
|
||||
virtual rdc_status_t rdc_config_clear(rdc_gpu_group_t group_id) = 0;
|
||||
|
||||
virtual ~RdcConfigSettings() {}
|
||||
};
|
||||
typedef std::shared_ptr<RdcConfigSettings> RdcConfigSettingsPtr;
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCCONFIGSETTINGS_H_
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright (c) 2021 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCDIAGNOSTIC_H_
|
||||
#define INCLUDE_RDC_LIB_RDCDIAGNOSTIC_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
class RdcDiagnostic {
|
||||
public:
|
||||
// get support test cases
|
||||
virtual rdc_status_t rdc_diag_test_cases_query(rdc_diag_test_cases_t test_cases[MAX_TEST_CASES],
|
||||
uint32_t* test_case_count) = 0;
|
||||
|
||||
// Run a specific test case
|
||||
virtual rdc_status_t rdc_test_case_run(rdc_diag_test_cases_t test_case,
|
||||
uint32_t gpu_index[RDC_MAX_NUM_DEVICES],
|
||||
uint32_t gpu_count, const char* config, size_t config_size,
|
||||
rdc_diag_test_result_t* result, rdc_diag_callback_t* callback) = 0;
|
||||
|
||||
// Run multiple test cases
|
||||
virtual rdc_status_t rdc_diagnostic_run(const rdc_group_info_t& gpus, rdc_diag_level_t level,
|
||||
const char* config, size_t config_size,
|
||||
rdc_diag_response_t* response, rdc_diag_callback_t* callback) = 0;
|
||||
|
||||
virtual rdc_status_t rdc_diag_init(uint64_t flags) = 0;
|
||||
virtual rdc_status_t rdc_diag_destroy() = 0;
|
||||
|
||||
virtual ~RdcDiagnostic() {}
|
||||
};
|
||||
typedef std::shared_ptr<RdcDiagnostic> RdcDiagnosticPtr;
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCDIAGNOSTIC_H_
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCDIAGNOSTICLIBINTERFACE_H_
|
||||
#define INCLUDE_RDC_LIB_RDCDIAGNOSTICLIBINTERFACE_H_
|
||||
|
||||
// The telemetry interface for libraries, for example, AMD-SMI.
|
||||
#include <rdc/rdc.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
// The library will implement below function
|
||||
|
||||
// Which test cases are supported in the library
|
||||
rdc_status_t rdc_diag_test_cases_query(rdc_diag_test_cases_t test_cases[MAX_TEST_CASES],
|
||||
uint32_t* test_case_count);
|
||||
|
||||
// Run a specific test case
|
||||
|
||||
rdc_status_t rdc_diag_test_case_run(rdc_diag_test_cases_t test_case,
|
||||
uint32_t gpu_index[RDC_MAX_NUM_DEVICES], uint32_t gpu_count,
|
||||
const char* config, size_t config_size,
|
||||
rdc_diag_test_result_t* result, rdc_diag_callback_t* callback);
|
||||
|
||||
rdc_status_t rdc_diag_init(uint64_t flags);
|
||||
|
||||
rdc_status_t rdc_diag_destroy();
|
||||
}
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCDIAGNOSTICLIBINTERFACE_H_
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) 2025 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCENTITYCODEC_H_
|
||||
#define INCLUDE_RDC_LIB_RDCENTITYCODEC_H_
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
/*
|
||||
*
|
||||
* See rdc.h for description of entity_index
|
||||
* Shifts and masks help get only the bits in question to decode/encode
|
||||
*
|
||||
* Ex, RDC_ENTITY_TYPE_SHIFT = 29 helps shift the 29 irrelevant bits, so we're
|
||||
* only left with the top 3 type bits.
|
||||
* Then, the corresponding 3 type bits are anded with the RDC_ENTITY_TYPE_MASK = 0x7
|
||||
* which = 111 in binary, "copying" the type bits.
|
||||
*
|
||||
*
|
||||
*/
|
||||
static constexpr uint32_t RDC_ENTITY_TYPE_SHIFT = 29;
|
||||
static constexpr uint32_t RDC_ENTITY_ROLE_SHIFT = 27;
|
||||
static constexpr uint32_t RDC_ENTITY_INSTANCE_SHIFT = 11;
|
||||
static constexpr uint32_t RDC_ENTITY_DEVICE_SHIFT = 0;
|
||||
|
||||
static constexpr uint32_t RDC_ENTITY_TYPE_MASK = 0x7; // 3 bits for type.
|
||||
static constexpr uint32_t RDC_ENTITY_ROLE_MASK = 0x3; // 2 bits for role.
|
||||
static constexpr uint32_t RDC_ENTITY_INSTANCE_MASK = 0x3FF; // 10 bits for instance.
|
||||
static constexpr uint32_t RDC_ENTITY_DEVICE_MASK = 0x3FF; // 10 bits for device.
|
||||
|
||||
rdc_entity_info_t rdc_get_info_from_entity_index(uint32_t entity_index);
|
||||
uint32_t rdc_get_entity_index_from_info(rdc_entity_info_t info);
|
||||
bool rdc_is_partition_string(const char* s);
|
||||
bool rdc_parse_partition_string(const char* s, uint32_t* physicalGpu, uint32_t* partition);
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCENTITYCODEC_H_
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2019 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_RDC_LIB_RDCEXCEPTION_H_
|
||||
#define INCLUDE_RDC_LIB_RDCEXCEPTION_H_
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
class RdcException : public std::exception {
|
||||
public:
|
||||
RdcException(rdc_status_t error, const std::string description)
|
||||
: err_(error), desc_(description) {}
|
||||
rdc_status_t error_code() const noexcept { return err_; }
|
||||
const char* what() const noexcept override { return desc_.c_str(); }
|
||||
|
||||
private:
|
||||
rdc_status_t err_;
|
||||
std::string desc_;
|
||||
};
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCEXCEPTION_H_
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCGROUPSETTINGS_H_
|
||||
#define INCLUDE_RDC_LIB_RDCGROUPSETTINGS_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
#include "rdc_lib/rdc_common.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
class RdcGroupSettings {
|
||||
public:
|
||||
virtual rdc_status_t rdc_group_gpu_create(const char* group_name,
|
||||
rdc_gpu_group_t* p_rdc_group_id) = 0;
|
||||
virtual rdc_status_t rdc_group_gpu_destroy(rdc_gpu_group_t p_rdc_group_id) = 0;
|
||||
virtual rdc_status_t rdc_group_gpu_add(rdc_gpu_group_t groupId, uint32_t gpu_index) = 0;
|
||||
virtual rdc_status_t rdc_group_gpu_get_info(rdc_gpu_group_t p_rdc_group_id,
|
||||
rdc_group_info_t* p_rdc_group_info) = 0;
|
||||
virtual rdc_status_t rdc_group_get_all_ids(rdc_gpu_group_t group_id_list[], uint32_t* count) = 0;
|
||||
|
||||
virtual rdc_status_t rdc_group_field_create(uint32_t num_field_ids, rdc_field_t* field_ids,
|
||||
const char* field_group_name,
|
||||
rdc_field_grp_t* rdc_field_group_id) = 0;
|
||||
virtual rdc_status_t rdc_group_field_destroy(rdc_field_grp_t rdc_field_group_id) = 0;
|
||||
virtual rdc_status_t rdc_group_field_get_info(rdc_field_grp_t rdc_field_group_id,
|
||||
rdc_field_group_info_t* field_group_info) = 0;
|
||||
virtual rdc_status_t rdc_group_field_get_all_ids(rdc_field_grp_t field_group_id_list[],
|
||||
uint32_t* count) = 0;
|
||||
|
||||
virtual ~RdcGroupSettings() {}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<RdcGroupSettings> RdcGroupSettingsPtr;
|
||||
const uint32_t JOB_FIELD_ID = 0;
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCGROUPSETTINGS_H_
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCHANDLER_H_
|
||||
#define INCLUDE_RDC_LIB_RDCHANDLER_H_
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
#include "rdc/rdc_private.h"
|
||||
#include "rdc_lib/rdc_common.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
// Interface class
|
||||
class RdcHandler {
|
||||
public:
|
||||
// Job API
|
||||
virtual rdc_status_t rdc_job_start_stats(rdc_gpu_group_t groupId, const char job_id[64],
|
||||
uint64_t update_freq) = 0;
|
||||
virtual rdc_status_t rdc_job_get_stats(const char jobId[64], rdc_job_info_t* p_job_info) = 0;
|
||||
virtual rdc_status_t rdc_job_stop_stats(const char job_id[64]) = 0;
|
||||
virtual rdc_status_t rdc_job_remove(const char job_id[64]) = 0;
|
||||
virtual rdc_status_t rdc_job_remove_all() = 0;
|
||||
|
||||
// Discovery API
|
||||
virtual rdc_status_t rdc_device_get_all(uint32_t gpu_index_list[RDC_MAX_NUM_DEVICES],
|
||||
uint32_t* count) = 0;
|
||||
virtual rdc_status_t rdc_device_get_attributes(uint32_t gpu_index,
|
||||
rdc_device_attributes_t* p_rdc_attr) = 0;
|
||||
virtual rdc_status_t rdc_device_get_component_version(rdc_component_t component,
|
||||
rdc_component_version_t* p_rdc_compv) = 0;
|
||||
|
||||
// Group API
|
||||
virtual rdc_status_t rdc_group_gpu_create(rdc_group_type_t type, const char* group_name,
|
||||
rdc_gpu_group_t* p_rdc_group_id) = 0;
|
||||
virtual rdc_status_t rdc_group_gpu_add(rdc_gpu_group_t groupId, uint32_t gpu_index) = 0;
|
||||
virtual rdc_status_t rdc_group_field_create(uint32_t num_field_ids, rdc_field_t* field_ids,
|
||||
const char* field_group_name,
|
||||
rdc_field_grp_t* rdc_field_group_id) = 0;
|
||||
virtual rdc_status_t rdc_group_field_get_info(rdc_field_grp_t rdc_field_group_id,
|
||||
rdc_field_group_info_t* field_group_info) = 0;
|
||||
virtual rdc_status_t rdc_group_gpu_get_info(rdc_gpu_group_t p_rdc_group_id,
|
||||
rdc_group_info_t* p_rdc_group_info) = 0;
|
||||
virtual rdc_status_t rdc_group_get_all_ids(rdc_gpu_group_t group_id_list[], uint32_t* count) = 0;
|
||||
virtual rdc_status_t rdc_group_field_get_all_ids(rdc_field_grp_t field_group_id_list[],
|
||||
uint32_t* count) = 0;
|
||||
virtual rdc_status_t rdc_group_gpu_destroy(rdc_gpu_group_t p_rdc_group_id) = 0;
|
||||
virtual rdc_status_t rdc_group_field_destroy(rdc_field_grp_t rdc_field_group_id) = 0;
|
||||
|
||||
// Field API
|
||||
virtual rdc_status_t rdc_field_watch(rdc_gpu_group_t group_id, rdc_field_grp_t field_group_id,
|
||||
uint64_t update_freq, double max_keep_age,
|
||||
uint32_t max_keep_samples) = 0;
|
||||
virtual rdc_status_t rdc_field_get_latest_value(uint32_t gpu_index, rdc_field_t field,
|
||||
rdc_field_value* value) = 0;
|
||||
virtual rdc_status_t rdc_field_get_value_since(uint32_t gpu_index, rdc_field_t field,
|
||||
uint64_t since_time_stamp,
|
||||
uint64_t* next_since_time_stamp,
|
||||
rdc_field_value* value) = 0;
|
||||
virtual rdc_status_t rdc_field_unwatch(rdc_gpu_group_t group_id,
|
||||
rdc_field_grp_t field_group_id) = 0;
|
||||
|
||||
// Diagnostic API
|
||||
virtual rdc_status_t rdc_diagnostic_run(rdc_gpu_group_t group_id, rdc_diag_level_t level,
|
||||
const char* config, size_t config_size,
|
||||
rdc_diag_response_t* response,
|
||||
rdc_diag_callback_t* callback) = 0;
|
||||
|
||||
virtual rdc_status_t rdc_test_case_run(rdc_gpu_group_t group_id, rdc_diag_test_cases_t test_case,
|
||||
const char* config, size_t config_size,
|
||||
rdc_diag_test_result_t* result,
|
||||
rdc_diag_callback_t* callback) = 0;
|
||||
|
||||
// Control API
|
||||
virtual rdc_status_t rdc_field_update_all(uint32_t wait_for_update) = 0;
|
||||
|
||||
// It is just a client interface under the GRPC framework and is not used as an RDC API.
|
||||
// The reason is that RdcEmbeddedHandler::get_mixed_component_version does not need to be called.
|
||||
virtual rdc_status_t get_mixed_component_version(mixed_component_t component,
|
||||
mixed_component_version_t* p_mixed_compv) = 0;
|
||||
// Policy API
|
||||
virtual rdc_status_t rdc_policy_set(rdc_gpu_group_t group_id, rdc_policy_t policy) = 0;
|
||||
|
||||
virtual rdc_status_t rdc_policy_get(rdc_gpu_group_t group_id, uint32_t* count,
|
||||
rdc_policy_t policies[RDC_MAX_POLICY_SETTINGS]) = 0;
|
||||
|
||||
virtual rdc_status_t rdc_policy_delete(rdc_gpu_group_t group_id,
|
||||
rdc_policy_condition_type_t condition_type) = 0;
|
||||
|
||||
virtual rdc_status_t rdc_policy_register(rdc_gpu_group_t group_id,
|
||||
rdc_policy_register_callback callback) = 0;
|
||||
|
||||
virtual rdc_status_t rdc_policy_unregister(rdc_gpu_group_t group_id) = 0;
|
||||
|
||||
// Health API
|
||||
virtual rdc_status_t rdc_health_set(rdc_gpu_group_t group_id, unsigned int components) = 0;
|
||||
virtual rdc_status_t rdc_health_get(rdc_gpu_group_t group_id, unsigned int* components) = 0;
|
||||
virtual rdc_status_t rdc_health_check(rdc_gpu_group_t group_id,
|
||||
rdc_health_response_t* response) = 0;
|
||||
virtual rdc_status_t rdc_health_clear(rdc_gpu_group_t group_id) = 0;
|
||||
// topology API
|
||||
virtual rdc_status_t rdc_device_topology_get(uint32_t gpu_index,
|
||||
rdc_device_topology_t* results) = 0;
|
||||
virtual rdc_status_t rdc_link_status_get(rdc_link_status_t* results) = 0;
|
||||
|
||||
// Set one configure
|
||||
virtual rdc_status_t rdc_config_set(rdc_gpu_group_t group_id, rdc_config_setting_t setting) = 0;
|
||||
|
||||
// Get the setting
|
||||
virtual rdc_status_t rdc_config_get(rdc_gpu_group_t group_id,
|
||||
rdc_config_setting_list_t* settings) = 0;
|
||||
|
||||
// Clear the setting
|
||||
virtual rdc_status_t rdc_config_clear(rdc_gpu_group_t group_id) = 0;
|
||||
|
||||
virtual rdc_status_t rdc_get_num_partition(uint32_t index, uint16_t* num_partition) = 0;
|
||||
|
||||
virtual rdc_status_t rdc_instance_profile_get(uint32_t entity_index,
|
||||
rdc_instance_resource_type_t resource_type,
|
||||
rdc_resource_profile_t* profile) = 0;
|
||||
|
||||
virtual ~RdcHandler() {}
|
||||
};
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCHANDLER_H_
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCLIBRARYLOADER_H_
|
||||
#define INCLUDE_RDC_LIB_RDCLIBRARYLOADER_H_
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <mutex> // NOLINT(build/c++11)
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
#include "rdc_lib/RdcException.h"
|
||||
#include "rdc_lib/RdcLogger.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
class RdcLibraryLoader {
|
||||
public:
|
||||
RdcLibraryLoader();
|
||||
|
||||
// throws RdcException if lib not found
|
||||
rdc_status_t load(const char* filename);
|
||||
|
||||
template <typename T>
|
||||
rdc_status_t load_symbol(T* func_handler, const char* func_name);
|
||||
|
||||
template <typename T>
|
||||
rdc_status_t load(const char* filename, T* func_make_handler);
|
||||
|
||||
rdc_status_t unload();
|
||||
|
||||
~RdcLibraryLoader();
|
||||
|
||||
private:
|
||||
void* libHandler_;
|
||||
std::mutex library_mutex_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
rdc_status_t RdcLibraryLoader::load_symbol(T* func_handler, const char* func_name) {
|
||||
if (!libHandler_) {
|
||||
RDC_LOG(RDC_ERROR, "Must load the library before loading the symbol");
|
||||
return RDC_ST_FAIL_LOAD_MODULE;
|
||||
}
|
||||
|
||||
if (!func_handler || !func_name) {
|
||||
return RDC_ST_FAIL_LOAD_MODULE;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(library_mutex_);
|
||||
|
||||
*reinterpret_cast<void**>(func_handler) = dlsym(libHandler_, func_name);
|
||||
if (*func_handler == nullptr) {
|
||||
char* error = dlerror();
|
||||
RDC_LOG(RDC_ERROR, "RdcLibraryLoader: Fail to load the symbol " << func_name << ": " << error);
|
||||
return RDC_ST_FAIL_LOAD_MODULE;
|
||||
}
|
||||
|
||||
return RDC_ST_OK;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
rdc_status_t RdcLibraryLoader::load(const char* filename, T* func_make_handler) {
|
||||
if (filename == nullptr || func_make_handler == nullptr) {
|
||||
return RDC_ST_FAIL_LOAD_MODULE;
|
||||
}
|
||||
|
||||
try {
|
||||
rdc_status_t status = load(filename);
|
||||
if (status != RDC_ST_OK) {
|
||||
return status;
|
||||
}
|
||||
} catch (RdcException& e) {
|
||||
RDC_LOG(RDC_ERROR, e.what());
|
||||
return e.error_code();
|
||||
}
|
||||
|
||||
return load_symbol(func_make_handler, "make_handler");
|
||||
}
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCLIBRARYLOADER_H_
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCLOGGER_H_
|
||||
#define INCLUDE_RDC_LIB_RDCLOGGER_H_
|
||||
#include <chrono> // NOLINT
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#define RDC_ERROR 0
|
||||
#define RDC_INFO 1
|
||||
#define RDC_DEBUG 2
|
||||
|
||||
#define RDC_LOG(debug_level, msg) \
|
||||
do { \
|
||||
auto& logger = amd::rdc::RdcLogger::getLogger(); \
|
||||
if (logger.should_log((debug_level))) { \
|
||||
logger.get_ostream() << logger.get_log_header((debug_level), __FILE__, __LINE__) << msg \
|
||||
<< std::endl; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
class RdcLogger {
|
||||
public:
|
||||
explicit RdcLogger(std::ostream& os);
|
||||
|
||||
static RdcLogger& getLogger() {
|
||||
static RdcLogger logger(std::cout);
|
||||
return logger;
|
||||
}
|
||||
|
||||
bool should_log(uint32_t severity) { return log_level_ >= severity; }
|
||||
|
||||
std::ostream& get_ostream() { return os_; }
|
||||
|
||||
std::string get_log_header(uint32_t severity, const char* file, int line);
|
||||
|
||||
private:
|
||||
std::ostream& os_;
|
||||
uint32_t log_level_;
|
||||
};
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCLOGGER_H_
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCMETRICFETCHER_H_
|
||||
#define INCLUDE_RDC_LIB_RDCMETRICFETCHER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "rdc/rdc.h"
|
||||
#include "rdc_lib/RdcTelemetryLibInterface.h"
|
||||
#include "rdc_lib/rdc_common.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
class RdcMetricFetcher {
|
||||
public:
|
||||
virtual rdc_status_t acquire_smi_handle(RdcFieldKey fk) = 0;
|
||||
virtual rdc_status_t delete_smi_handle(RdcFieldKey fk) = 0;
|
||||
|
||||
virtual rdc_status_t fetch_smi_field(uint32_t gpu_index, rdc_field_t field_id,
|
||||
rdc_field_value* value) = 0;
|
||||
|
||||
virtual rdc_status_t bulk_fetch_smi_fields(
|
||||
rdc_gpu_field_t* fields, uint32_t fields_count,
|
||||
std::vector<rdc_gpu_field_value_t>& results) = 0; // NOLINT
|
||||
virtual ~RdcMetricFetcher() {}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<RdcMetricFetcher> RdcMetricFetcherPtr;
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCMETRICFETCHER_H_
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCMETRICSUPDATER_H_
|
||||
#define INCLUDE_RDC_LIB_RDCMETRICSUPDATER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
class RdcMetricsUpdater {
|
||||
public:
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<RdcMetricsUpdater> RdcMetricsUpdaterPtr;
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCMETRICSUPDATER_H_
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright (c) 2020 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
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.
|
||||
*/
|
||||
#ifndef INCLUDE_RDC_LIB_RDCMODULEMGR_H_
|
||||
#define INCLUDE_RDC_LIB_RDCMODULEMGR_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "rdc_lib/RdcDiagnostic.h"
|
||||
#include "rdc_lib/RdcTelemetry.h"
|
||||
|
||||
namespace amd {
|
||||
namespace rdc {
|
||||
|
||||
class RdcModuleMgr {
|
||||
public:
|
||||
virtual ~RdcModuleMgr() = default;
|
||||
virtual RdcTelemetryPtr get_telemetry_module() = 0;
|
||||
virtual RdcDiagnosticPtr get_diagnostic_module() = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<RdcModuleMgr> RdcModuleMgrPtr;
|
||||
|
||||
} // namespace rdc
|
||||
} // namespace amd
|
||||
|
||||
#endif // INCLUDE_RDC_LIB_RDCMODULEMGR_H_
|
||||