Repository navigation
rocprofv3: add rocprofv3 --doctor self-diagnostic option - #12889
Conversation
❌ PR Check — Action Required
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
|
🚫 Please fix the failed policies before requesting reviews. The following policy checks failed:
The |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved issues affect package selection, counter database validation, process isolation, and diagnostic accuracy.
Review effort: Balanced
Findings: 1
Open (12)
Run sqlite3 probes in an isolated subprocess · New Report hypervisor detection without asserting GPU virtualization · New Exclude the dispatching parent from profiler process detection · New Include primary GID when checking group membership · New Recognize HIP_VISIBLE_DEVICES=-1 as hiding all GPUs · New Clear all inspected visibility variables in remediation · New Check versioned SDK libraries in the loader cache · New Mirror SDK search paths and fallback for metrics configuration · New Validate the counter configuration file actually consumed by the SDK · New Mark checks invoking imports or SQLite as process probes · New Limit high confidence to masks that hide all devices · New Format entry and entries correctly in user messages · New
What changed in this PR
Adds the rocprofv3-doctor diagnostic CLI, including installation discovery, system checks, actionable reporting, integration with rocprofv3, documentation, and extensive tests.
Changes:
- Adds 53 extensible diagnostic checks with text/JSON reporting.
- Integrates
rocprofv3 --doctorand installation targets. - Adds unit, system-boundary, integration, and layout tests.
| File | Description |
|---|---|
projects/rocprofiler-sdk/CHANGELOG.md |
Documents the diagnostic tool. |
projects/rocprofiler-sdk/cmake/Templates/rocprofiler-sdk/config.cmake.in |
Exports the doctor target. |
projects/rocprofiler-sdk/source/bin/CMakeLists.txt |
Configures and installs the CLI. |
projects/rocprofiler-sdk/source/bin/rocprofv3-doctor.py |
Implements the standalone entry point. |
projects/rocprofiler-sdk/source/bin/rocprofv3.py |
Adds --doctor dispatch. |
projects/rocprofiler-sdk/source/docs/_toc.yml.in |
Adds documentation navigation. |
projects/rocprofiler-sdk/source/docs/index.rst |
Links the how-to page. |
projects/rocprofiler-sdk/source/docs/how-to/using-rocprofv3-doctor.rst |
Documents usage and diagnostics. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/CMakeLists.txt |
Installs doctor modules. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor.py |
Runs checks and renders reports. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_diagnose.py |
Diagnoses known failures. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_env.py |
Provides isolated system access. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_layout.py |
Detects installation layouts. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_registry.py |
Implements check registration and execution. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_result.py |
Defines result and probe types. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_container.py |
Adds container checks. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_counters.py |
Adds counter checks. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_driver.py |
Adds driver/device checks. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_environ.py |
Adds environment checks. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_filesystem.py |
Adds filesystem checks. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_install.py |
Adds installation checks. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_python_env.py |
Adds Python checks. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_runtime.py |
Adds runtime loading checks. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_smoke.py |
Adds opt-in smoke tests. |
projects/rocprofiler-sdk/source/lib/python/rocprofv3/doctor_checks_tools.py |
Adds companion-tool checks. |
projects/rocprofiler-sdk/tests/CMakeLists.txt |
Enables the test directory. |
projects/rocprofiler-sdk/tests/rocprofv3-doctor/CMakeLists.txt |
Registers doctor tests. |
projects/rocprofiler-sdk/tests/rocprofv3-doctor/conftest.py |
Provides synthetic-system fixtures. |
projects/rocprofiler-sdk/tests/rocprofv3-doctor/pytest.ini |
Configures test discovery. |
projects/rocprofiler-sdk/tests/rocprofv3-doctor/test_doctor_checks.py |
Tests individual checks. |
projects/rocprofiler-sdk/tests/rocprofv3-doctor/test_doctor_diagnose.py |
Tests failure diagnosis. |
projects/rocprofiler-sdk/tests/rocprofv3-doctor/test_doctor_framework.py |
Tests framework behavior. |
projects/rocprofiler-sdk/tests/rocprofv3-doctor/test_doctor_layout.py |
Tests installation layouts. |
projects/rocprofiler-sdk/tests/rocprofv3-doctor/test_doctor_system.py |
Tests real system boundaries. |
projects/rocprofiler-sdk/tests/rocprofv3-doctor/validate.py |
Tests CLI contracts. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The tool no longer installs a separate `rocprofv3-doctor` command (#12889): `rocprofv3 --doctor` is the only entry point. - SKILL.md finds and runs `rocprofv3 --doctor`, from PATH, a ROCm prefix, or a source checkout's rocprofv3.py for ROCm releases whose rocprofv3 rejects the option, and uses that command throughout. - It tells the agent to run the check as the user who runs rocprofv3, never with sudo, matching the tool's new run-as-user warning. - summarize_report.py, its tests, the skill card, and the evals use the new command; the behavior-graded evals also require `--doctor` in the logs and treat running the check as root as a mistake. The skill keeps its name, rocprofv3-doctor, until the flag's name is settled. Co-Authored-By: Claude <noreply@anthropic.com>
Reviewer (venkat1361):
- WSL2: accept /dev/dxg when /dev/kfd is absent (KFD still wins when
both exist). kfd-readable checks /dev/dxg; dri-devices, amdgpu-module
and the render/video group checks SKIP; gpu-topology verifies
libdxcore.so and librocdxg.so and HSA_ENABLE_DXG_DETECTION. The
container passthrough check and the OUT_OF_RESOURCES diagnosis are
WSL-aware.
- Remove the standalone aqlprofile check: it is linked statically by
default, and a separate one is covered by the SDK load test.
- install.kokkosp-library is an error: rocprofv3.py resolves it with
required=True on every launch.
- The bootstrap honors CMAKE_INSTALL_LIBDIR, then lib64 and lib.
Copilot:
- Probe sqlite3 in an isolated child interpreter so a broken native
extension fails one check instead of the doctor.
- Python import checks declare probe=PROBE_PROCESS.
- Resolve versioned SONAMEs through LD_LIBRARY_PATH and the ldconfig
cache too; SDK libraries keep the exact-version rule.
- ROCPROFILER_METRICS_PATH is a ':'-separated list with a fallback to
the install path, and the metrics file is config.yaml.
- Count the primary GID in the group checks.
- HIP_VISIBLE_DEVICES=-1 hides every GPU; the remediation unsets every
visibility variable that is set; hipErrorNoDevice blames a partial
mask only as a possible cause.
- The hypervisor message no longer claims GPU passthrough.
- Proper singular/plural text instead of "entr(y|ies)".
Unit tests cover each change, and the doctor docs are updated.
Co-Authored-By: Claude <noreply@anthropic.com>
- GPU visibility: one helper, gpu_visibility_masks() in doctor_env,
now feeds both environ.gpu-visibility and the hipErrorNoDevice
diagnosis. It follows CLR and ROCr: an empty ROCR_VISIBLE_DEVICES
hides every GPU, but an empty HIP/CUDA_VISIBLE_DEVICES restricts
nothing; -1 hides every GPU in all three; a non-empty
HIP_VISIBLE_DEVICES overrides CUDA_VISIBLE_DEVICES.
- install.rocm-root fails when detection found no ROCm
(SOURCE_NOT_FOUND) or the root has no ROCm libraries, so the library
checks SKIP behind one root cause instead of each failing.
driver.kfd-device no longer depends on it: the driver checks do not
use the ROCm root and still run when none is found.
- python.sqlite3 is a warning: only the rocpd CLI needs Python sqlite3;
rocprofv3 writes rocpd output from C++.
Tests cover each change, and the doctor docs are updated.
Co-Authored-By: Claude <noreply@anthropic.com>
|
@bwelton and @venkat1361 Thanks for the review. I have addressed the feedback. Please re-review. |
Adds `rocprofv3-doctor`, a self-diagnostic CLI that inspects the machine
and the rocprofiler-sdk installation, reports what is healthy versus
broken, and tells the user how to fix each problem. Usable standalone or
as `rocprofv3 --doctor`.
53 checks across 10 groups (51 run by default; 2 smoke checks that run
rocprofv3 itself are opt-in via --run-smoke-test or --only):
- installation: SDK/tool/roctx/kokkosp/avail/rocattach libraries with
exact-soversion resolution, tool-vs-library version skew, conflicting ROCm
installs on the search path, counter metrics database
- driver/device: /dev/kfd, DRI render nodes, render/video group
membership, amdgpu driver, KFD topology GPU enumeration
- runtime: ROCr, HIP, aqlprofile (required for --pmc and ATT), ATT
trace decoder, rocprofiler-register, and a load test that loads
each ROCm library in a child process with RTLD_NOW
- counters: CAP_PERFMON/CAP_SYS_ADMIN (device locking), competing
profiler holding the device, counter enumeration
- environment: LD_PRELOAD conflicts, HSA_TOOLS_LIB, GPU visibility
masking, beta gates, ROCPROF_*/ROCPROFILER_* dump
- container: containerization detection, device passthrough, virt GPU
- python: interpreter version, sqlite3/ctypes/importlib, optional
pyyaml/pandas/otf2, rocprofv3 package importability
- filesystem: output directory writability, disk space, /tmp
- tools: rocprofv3, rocprofv3-avail, rocprof-attach, rocpd
Design notes:
- All system access is funnelled through a single injectable
SystemAccessor, so every check is unit-testable without a GPU and
the suite runs green in CI.
- Checks declare prerequisites, which always run first and are pulled
into --only selections; when one does not pass, its dependents
report `skip` naming it, so a single root cause produces a single
red line. An --only pattern matching no check is an error.
- Each check is isolated: an exception becomes an `error` (a doctor
bug) carrying the traceback, never a `fail` about the system. Every
child process has a timeout that kills its whole process tree;
native library loads and Python package imports run in children.
- Every check declares its probe category (passive, process, gpu),
published in --list-checks and JSON. The only file written is an
exclusively-created temporary probe; smoke output goes to a private
temporary directory.
- Severity is deliberately conservative: ambiguous conditions report
`warn` rather than `fail` to avoid false alarms.
- Install-layout aware: ROCm is not assumed to live under /opt/rocm.
The root is located from the script's install prefix,
ROCM_PATH/ROCM_HOME/ROCM_DIR, rocprofv3 on PATH, an importable
TheRock Python package (_rocm_sdk_core), then /opt/rocm and the
newest /opt/rocm/core-X.Y. Legacy system packages, TheRock system
packages, TheRock Python wheels, distro packages, and standalone
trees (tarballs, source builds, custom prefixes) are classified,
installations are compared by the files they resolve to rather than
by path text, and remediation commands match the install type.
- Diagnoses rather than only inventories: libraries are actually
loaded, so missing dependencies (all of them, via ldd), mixed ROCm
versions, old libstdc++, and corrupt files are caught. When a
command the doctor runs fails or crashes, its output is matched
against known loader, ROCr, HIP, SDK, and Python error messages
and the report names the cause and fix instead of the exit code.
A match is evidence, not a conclusion: each diagnosis separates the
observation from the candidate cause, rates the cause `likely` only
when facts on the machine corroborate it, and remediates only the
mechanism actually implicated.
Output is grouped human-readable text with a copy-pasteable remediation
section, or versioned-schema JSON (--format json) for CI and bug
reports. Supports --only/--skip with glob matching, --list-checks,
--verbose/--quiet, --no-color (honouring NO_COLOR and non-TTY stdout),
--rocm-root and --output. Exit codes: 0 pass/warn-only, 1 at least one
failure, 2 tool error, unmatched --only, or a broken check with no
failure.
Includes 243 tests (unit, system-boundary, and integration) under
tests/rocprofv3-doctor,
a how-to doc page, and CHANGELOG entry.
Co-Authored-By: Claude <noreply@anthropic.com>
Optional Python packages are imported in a child interpreter so that a native extension that aborts or hangs costs one check, not the report. That child ran as `python -c`, which puts the current directory first on sys.path: a stray rocprofv3.py, pandas.py, or yaml.py in the directory the doctor was run from shadowed the real module and was executed. Running from /tmp with a leftover /tmp/rocprofv3.py made python.rocprofv3-package report that file as the loaded package. Run the child isolated (-I) and hand it the doctor's exact sys.path instead of passing it through PYTHONPATH, so module resolution matches an in-process import and nothing in the working directory is imported. Co-Authored-By: Claude <noreply@anthropic.com>
The doctor is meant to run as the user who runs rocprofv3, but nothing
noticed when it did not. Under sudo, root opens /dev/kfd regardless of
group membership (hiding the real user's access problem), the group
checks told the user to add root to render/video, the capability check
described root, and sudo's reset environment changed what the
environment and layout checks saw. Root inside a container -- the
default for ROCm images, and legitimate there -- drew warnings that the
render/video groups do not exist.
- New check environ.run-as-user warns when the process is root on
behalf of another account: SUDO_USER for sudo, and the audit login
uid in /proc/self/loginuid for su, doas, and pkexec. A direct root
login (loginuid 0) and containers and services (loginuid unset) are
genuinely root and pass.
- The render/video group checks pass for root, which does not need
them; driver.kfd-readable still verifies real access.
- A root process that cannot open /dev/kfd is pointed at user
namespaces / rootless containers instead of usermod.
- The how-to states who should run the tool.
Co-Authored-By: Claude <noreply@anthropic.com>
The checks were reachable two ways: a separate `rocprofv3-doctor` command
in bin/ and `rocprofv3 --doctor`, which spawned that command. Keep one:
`rocprofv3 --doctor`. Users already have rocprofv3 on PATH, there is no
second top-level command to name and package, and it matches how other
tools are expected to expose the shared checks (`<tool> --doctor`).
rocprofv3 imports only the standard library and dispatches before
parsing arguments, so `--doctor` still starts in the broken setups it
exists to diagnose.
- The script moves to source/libexec/rocprofiler-sdk/rocprofv3-doctor/
and installs to <libexecdir>/rocprofiler-sdk/rocprofv3-doctor, off
PATH, following rocprofiler-sdk-launch-compiler. The exported
rocprofiler-sdk::rocprofv3-doctor target points there.
- rocprofv3 finds it through the configured libexec dir (falling back
to the source-checkout path) and execs it instead of running it as a
child, so signals and the exit status pass straight through and no
rocprofv3 process lingers to be mistaken for a running profiler.
- counters.no-profiler-lock recognizes doctor runs exactly -- the
script, or rocprofv3 with --doctor among its own options -- replacing
a substring match that missed `rocprofv3 --doctor` and the shell that
launched it. `rocprofv3 ... -- app --doctor` is still a profiler.
- The command name lives in one place per component (DOCTOR_COMMAND /
DOCTOR_FLAG, COMMAND in the script, DOCTOR_FLAG in rocprofv3.py) and
every message that tells the user what to run uses it. `--doctor` is
a placeholder pending naming; renaming it is a three-constant change
plus docs.
- Root detection derives the install prefix from the libexec location.
- The CTest execute tests run through `rocprofv3 --doctor`; the docs,
help text, and CHANGELOG describe a single option.
Co-Authored-By: Claude <noreply@anthropic.com>
Three unit tests that load the rocprofv3 launcher failed in CI with
FileNotFoundError on <build>/source/bin/rocprofv3.py:
- CTest runs the tests from their copy in the build tree, but the
unit-test registration passed only --rocprofv3-package-dir. The
rocprofv3_path fixture then fell back to a source-tree path computed
relative to the copy, which does not exist there.
- Given the real path, loading still failed: the configured launcher is
plain `rocprofv3`, and spec_from_file_location returns None for a
file without a .py suffix.
Pass --rocprofv3-path and --doctor-path (the imported targets'
locations) to the unit tests as the validate test already does, load the
launcher with an explicit SourceFileLoader, and make the path fixtures
fail with a clear message instead of guessing a nonexistent path.
Verified in a reproduction of the CI layout (tests copied into the build
tree, extensionless configured rocprofv3): the same three tests failed
before and pass after, with the full unit and validate suites green.
Co-Authored-By: Claude <noreply@anthropic.com>
Reviewer (venkat1361):
- WSL2: accept /dev/dxg when /dev/kfd is absent (KFD still wins when
both exist). kfd-readable checks /dev/dxg; dri-devices, amdgpu-module
and the render/video group checks SKIP; gpu-topology verifies
libdxcore.so and librocdxg.so and HSA_ENABLE_DXG_DETECTION. The
container passthrough check and the OUT_OF_RESOURCES diagnosis are
WSL-aware.
- Remove the standalone aqlprofile check: it is linked statically by
default, and a separate one is covered by the SDK load test.
- install.kokkosp-library is an error: rocprofv3.py resolves it with
required=True on every launch.
- The bootstrap honors CMAKE_INSTALL_LIBDIR, then lib64 and lib.
Copilot:
- Probe sqlite3 in an isolated child interpreter so a broken native
extension fails one check instead of the doctor.
- Python import checks declare probe=PROBE_PROCESS.
- Resolve versioned SONAMEs through LD_LIBRARY_PATH and the ldconfig
cache too; SDK libraries keep the exact-version rule.
- ROCPROFILER_METRICS_PATH is a ':'-separated list with a fallback to
the install path, and the metrics file is config.yaml.
- Count the primary GID in the group checks.
- HIP_VISIBLE_DEVICES=-1 hides every GPU; the remediation unsets every
visibility variable that is set; hipErrorNoDevice blames a partial
mask only as a possible cause.
- The hypervisor message no longer claims GPU passthrough.
- Proper singular/plural text instead of "entr(y|ies)".
Unit tests cover each change, and the doctor docs are updated.
Co-Authored-By: Claude <noreply@anthropic.com>
- GPU visibility: one helper, gpu_visibility_masks() in doctor_env,
now feeds both environ.gpu-visibility and the hipErrorNoDevice
diagnosis. It follows CLR and ROCr: an empty ROCR_VISIBLE_DEVICES
hides every GPU, but an empty HIP/CUDA_VISIBLE_DEVICES restricts
nothing; -1 hides every GPU in all three; a non-empty
HIP_VISIBLE_DEVICES overrides CUDA_VISIBLE_DEVICES.
- install.rocm-root fails when detection found no ROCm
(SOURCE_NOT_FOUND) or the root has no ROCm libraries, so the library
checks SKIP behind one root cause instead of each failing.
driver.kfd-device no longer depends on it: the driver checks do not
use the ROCm root and still run when none is found.
- python.sqlite3 is a warning: only the rocpd CLI needs Python sqlite3;
rocprofv3 writes rocpd output from C++.
Tests cover each change, and the doctor docs are updated.
Co-Authored-By: Claude <noreply@anthropic.com>
CI formats with black 26 (--required-version 26); these files had been
formatted with black 23:
- rocprofv3.py: hug the multi-line warning() string in parse_input,
matching develop.
- test_doctor_framework.py: drop the parentheses around a tuple
unpacking target.
Also remove the unused `import pytest` from validate.py (flake8 F401).
Co-Authored-By: Claude <noreply@anthropic.com>
b151c1f to
150b7aa
Compare
The tool no longer installs a separate `rocprofv3-doctor` command (#12889): `rocprofv3 --doctor` is the only entry point. - SKILL.md finds and runs `rocprofv3 --doctor`, from PATH, a ROCm prefix, or a source checkout's rocprofv3.py for ROCm releases whose rocprofv3 rejects the option, and uses that command throughout. - It tells the agent to run the check as the user who runs rocprofv3, never with sudo, matching the tool's new run-as-user warning. - summarize_report.py, its tests, the skill card, and the evals use the new command; the behavior-graded evals also require `--doctor` in the logs and treat running the check as root as a mistake. The skill keeps its name, rocprofv3-doctor, until the flag's name is settled. Co-Authored-By: Claude <noreply@anthropic.com>
Follow the project's tier + feature labeling (as rocpd, pc-sampling and
kfd do): every doctor test now carries the rocprofv3-doctor label next to
unittests or integration-tests, so `ctest -L rocprofv3-doctor` selects
them all while CI's existing -L unittests / integration-tests selections
are unchanged.
Name the discovered unit tests rocprofv3-doctor.<function> and trim the
repeated "test_doctor_" prefix, so
rocprofv3-doctor-unit-tests.test_doctor_checks_kfd_device_pass
becomes
rocprofv3-doctor.checks_kfd_device_pass
The integration tests keep the tests.integration.{execute,validate}.*
names their macros generate.
Verified with the real pytest discovery module: 294 tests discovered,
all labeled unittests and rocprofv3-doctor, all passing.
Co-Authored-By: Claude <noreply@anthropic.com>
Conflict in projects/rocprofiler-sdk/CHANGELOG.md: develop added an "HSA API tracing support for hsa_amd_enable_high_precision_timestamps" entry under Unreleased -> Added, where this branch adds the rocprofv3 --doctor entry. Keep both, develop's first. Co-Authored-By: Claude <noreply@anthropic.com>
The tool no longer installs a separate `rocprofv3-doctor` command (#12889): `rocprofv3 --doctor` is the only entry point. - SKILL.md finds and runs `rocprofv3 --doctor`, from PATH, a ROCm prefix, or a source checkout's rocprofv3.py for ROCm releases whose rocprofv3 rejects the option, and uses that command throughout. - It tells the agent to run the check as the user who runs rocprofv3, never with sudo, matching the tool's new run-as-user warning. - summarize_report.py, its tests, the skill card, and the evals use the new command; the behavior-graded evals also require `--doctor` in the logs and treat running the check as root as a mistake. The skill keeps its name, rocprofv3-doctor, until the flag's name is settled. Co-Authored-By: Claude <noreply@anthropic.com>
The tool no longer installs a separate `rocprofv3-doctor` command (#12889): `rocprofv3 --doctor` is the only entry point. - SKILL.md finds and runs `rocprofv3 --doctor`, from PATH, a ROCm prefix, or a source checkout's rocprofv3.py for ROCm releases whose rocprofv3 rejects the option, and uses that command throughout. - It tells the agent to run the check as the user who runs rocprofv3, never with sudo, matching the tool's new run-as-user warning. - summarize_report.py, its tests, the skill card, and the evals use the new command; the behavior-graded evals also require `--doctor` in the logs and treat running the check as root as a mistake. The skill keeps its name, rocprofv3-doctor, until the flag's name is settled. Co-Authored-By: Claude <noreply@anthropic.com>
## Motivation Adds a `rocprofv3-doctor` agent skill that teaches AI coding agents to work out why rocprofv3 does not work on a machine. The agent runs `rocprofv3 --doctor`, finds the root causes in its report, and gives the user an ordered list of fixes. Like the `rocprofv3` skill in #12814, it is meant to be pulled into the amd/skills catalog from this repo. The two skills split the work. `rocprofv3` covers profiling once the setup works. `rocprofv3-doctor` covers what to do when rocprofv3 fails, crashes, finds no GPU, or will not start. > **Stacked on #12889**, which adds the `rocprofv3 --doctor` option this skill runs. This PR's base is that branch; it will be retargeted to `develop` once #12889 merges, and should not merge before it. ## Technical Details New folder `projects/rocprofiler-sdk/skills/rocprofv3-doctor/`, in the same layout as `skills/rocprofv3/` from #12814: - `SKILL.md`: - finds `rocprofv3 --doctor`: on `PATH`, under ROCm and TheRock prefixes, or from a source checkout's `rocprofv3.py` for ROCm releases whose `rocprofv3` rejects the option - runs it as the user who runs `rocprofv3`, never with `sudo` - runs it with JSON output and reads the exit codes - presents ordered fixes, with these rules: - act on `likely` causes; for `possible` ones, propose the step that tells causes apart - never run `sudo`, `usermod`, `sysctl`, package managers, or `pip` on the user's behalf - never add remediations the report does not give; in particular, no `perf_event_paranoid` changes and no `setcap` on the `rocprofv3` Python script - Its description routes plain profiling questions to the `rocprofv3` skill. - `scripts/summarize_report.py`: turns the doctor's JSON report (`schema_version` 1) into a markdown triage. It lists: - root causes, failures first, each with the checks it blocked - diagnoses, with their confidence and evidence - doctor errors, kept apart from findings about the system - what the run did not verify It uses only the Python standard library, and on input it cannot read it exits 2 with a message instead of a traceback. - `tests/test_summarize_report.py`: unit tests that need no GPU. - `evals/evals.json`: - 5 should-trigger cases, 2 of them graded on behavior: a readiness check, and a pasted `HSA_STATUS_ERROR_OUT_OF_RESOURCES` error that must be corroborated before a cause is named - 3 should-not cases: profiling hot kernels and choosing counters (the `rocprofv3` skill's job), and a PyTorch profiler trace - `evals/machine.yml`: `os: [Linux]`, `labels: [gpu, rocm]`. - `skill-card.md`. ## Issue Tracking JIRA ID: <TODO> ## Test Plan - Ran the skill's unit tests with Python 3.8 and 3.10. - Ran the skill's steps against #12889 on a ROCm 6.2.0 machine: the installed `rocprofv3` rejects `--doctor` as the skill expects, the source-checkout fallback runs, and the script summarizes the real report. - Ran amd/skills structural validation: `skillscope structural` v0.1.2, the version and arguments its `check.sh` uses, with the skill copied into a catalog checkout. - Confirmed that the same validation rejects a deliberately broken dataset. - Ran black. ## Test Result - 11 unit tests pass on both Python versions, and black is clean. - The script folds skipped checks into their root causes and separates informational findings. - Catalog structural checks pass: 11 skill folders and 85 cases in shape. - Routing and behavioral evals (`skillscope routing` / `behavioral`) have not been run yet; they need the `claude` CLI and a ROCm machine. ## Submission Checklist - [ ] Look over the contributing guidelines at https://github.com/ROCm/rocm-systems/blob/develop/CONTRIBUTING.md. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude <noreply@anthropic.com>
TheRock Submodule Bump ActivityNewest first
|
Resolve the CHANGELOG conflict by keeping the rocprofv3 --doctor (#12889) and hsa_amd_queue_create (#13720) entries from develop alongside this PR's Unreleased entries. Replace the queue-interposition, SPM agent-scoping, and kernel replay iteration-range entries with more detailed versions (#11967-#11970, #11335). Co-Authored-By: Claude <noreply@anthropic.com>



Motivation
When
rocprofv3fails on first use, the cause is usually the environment rather than the profiler: a missing or mismatched library,/dev/kfdpermissions, GPU devices not passed into a container, a conflictingLD_PRELOAD, or a broken Python environment. Today users have to work through each of these by hand.rocprofv3 --doctorchecks all of them in one command, explains what it found, and prints a copy-pasteable fix for each problem. It is an option ofrocprofv3, so there is nothing separate to install or find, and it works with every ROCm installation layout, not only/opt/rocm.Technical Details
How it works
flowchart TD A["rocprofv3 --doctor [options]<br/>(only rocprofv3 options before -- count;<br/>rocprofv3 execs libexec/rocprofiler-sdk/rocprofv3-doctor)"] --> B subgraph LOCATE["1. Locate the ROCm installation"] B["--rocm-root, if given"] -.->|else first hit| B2["install prefix of this script"] B2 -.-> B3["ROCM_PATH / ROCM_HOME / ROCM_DIR"] B3 -.-> B4["rocprofv3 on PATH"] B4 -.-> B5["TheRock Python package _rocm_sdk_core"] B5 -.-> B6["/opt/rocm, then newest /opt/rocm/core-X.Y"] B6 --> K["classify install kind<br/>system-package | therock-package |<br/>python-wheel | distro-package | standalone"] end K --> S subgraph SELECT["2. Select and schedule checks"] S["--only / --skip globs<br/>opt-in smoke checks via --run-smoke-test or --only"] --> S2{"every --only pattern<br/>matches a check?"} S2 -->|no| X2["exit 2: selection error"] S2 -->|yes| S3["add prerequisites of selected checks"] S3 --> S4["order so prerequisites run first"] end S4 --> R subgraph RUN["3. Run each check through SystemAccessor"] R{"prerequisites<br/>all passed?"} -->|no| SK["SKIP: names the prerequisite"] R -->|yes| P{"probe category"} P -->|passive| P1["read files, /sys, /proc, env;<br/>ldconfig -p; exclusive temp-file probe"] P -->|process| P2["child process with timeout:<br/>load libraries RTLD_NOW, import packages,<br/>run rocprofv3-avail --help"] P -->|gpu| P3["child process with timeout:<br/>rocprofv3-avail info --pmc,<br/>opt-in smoke checks"] P2 --> D{"command failed<br/>or crashed?"} P3 --> D D -->|yes| DG["diagnose the output<br/>(see next diagram)"] P1 --> RES D -->|no| RES DG --> RES P -.->|check raised an exception| ER["ERROR: doctor bug,<br/>not a system finding"] end RES["PASS / WARN / FAIL<br/>+ detail, remediation, data"] --> OUT SK --> OUT ER --> OUT subgraph REPORT["4. Report"] OUT["grouped text report + How to Fix<br/>or --format json (schema_version 1)"] --> EC{"exit code"} EC -->|any FAIL| E1["1"] EC -->|no FAIL, any ERROR| E2["2"] EC -->|otherwise| E0["0"] endWhen a command the doctor runs fails, its output is turned into a diagnosis. A matched error message is treated as evidence, not as a conclusion:
flowchart LR O["exit status + stdout/stderr<br/>of the failed command"] --> M{"matches a known<br/>message?"} M -->|no| U["keep last output line as evidence;<br/>suggest ROCPROFILER_LOG_LEVEL=info"] M -->|yes| OB["observation<br/>what the output literally says"] OB --> C["corroborate with machine facts<br/>/dev/kfd access, LD_LIBRARY_PATH / LD_PRELOAD,<br/>*_VISIBLE_DEVICES, injected tools"] C --> H{"facts support<br/>one cause?"} H -->|yes| L["likely cause<br/>confidence: high"] H -->|no| PO["possible cause<br/>confidence: possible"] L --> F["remediation for that mechanism only<br/>+ related checks"] PO --> N["next check that tells<br/>the causes apart"]For example, ROCr reports
HSA_STATUS_ERROR_OUT_OF_RESOURCESboth when/dev/kfdcannot be opened and for genuine allocation failures. The doctor checks/dev/kfdbefore naming a cause, and suggests group-membership fixes only when the device really is inaccessible.Usage
Checks
54 checks in 10 groups. 52 run by default; the 2 smoke checks are opt-in.
installdriver/dev/kfd, DRI render nodes,render/videomembership (account vs. current session), amdgpu driver, KFD topologyruntimecountersenvironsudo,su),LD_PRELOAD/HSA_TOOLS_LIB/ROCP_TOOL_LIBRARIESconflicts, GPU visibility masks, beta gates,ROCPROF_*dumpcontainerpythonsqlite3/ctypes/importlib, optionalpyyaml/pandas/otf2, therocprofv3packagefilesystem/tmptoolsrocprofv3,rocprofv3-avail,rocprof-attach,rocpd, androcprofv3-avail --helprunssmoke(opt-in)rocprofv3-avail infofinds a GPU;rocprofv3starts, injects its tool, and runs a programWhat a run does to the machine
Every check declares a probe category, shown in
--list-checksand in the JSON output.passive/sys,/proc, and the environment;ldconfig -p. The output-directory checks create and delete one exclusively-created temporary file.processRTLD_NOW, imports Python packages, runsrocprofv3-avail --help.gpurocprofv3-avail info --pmc.--skip counters.avail-enumerationto avoid itsmokechecks runrocprofv3-avail infoandrocprofv3itself.--run-smoke-test, or naming them with--onlyThere is no
--fixmode and nothing is changed persistently. On timeout, a child's whole process tree is killed. Run it as the user who runsrocprofv3, withoutsudo; it warns when run as root on behalf of another account, and inside a root container the group-membership checks pass because they do not apply.Finding the ROCm installation
ROCm is not assumed to live in
/opt/rocm. The doctor recognizes the following layouts and tailors its fix commands to each:/opt/rocmlinked to/opt/rocm-X.Y.Z)/opt/rocm/core-X.Y, with/opt/rocm/{bin,lib}as compatibility links)_rocm_sdk_corein a virtualenv)/usr)For example, a missing library in a pip install suggests
pip, notapt. Installations are compared by the files their paths resolve to, so/opt/rocmand/opt/rocm/core-X.Ycount as one installation.Results and exit codes
PASS/WARN/FAILSKIP--skipERRORExit codes:
0: no failures1: at least oneFAIL2: the doctor could not run, an--onlypattern matched no check, or a check broke and nothing failedJSON output carries
schema_version: 1.Changes to existing files
source/bin/rocprofv3.py:--doctorexecs the doctor script (no lingeringrocprofv3process; signals and exit status pass through) and is recognized only among rocprofv3's own options, so inrocprofv3 -- app --doctorthe flag is still passed toapp. The diff also contains black-only formatting changes: removed blank lines and one reflowed string.<libexecdir>/rocprofiler-sdk/rocprofv3-doctor(offPATH, likerocprofiler-sdk-launch-compiler) and its Python modules, and exports therocprofiler-sdk::rocprofv3-doctortarget throughconfig.cmake.infor the tests.docs/how-to/using-rocprofv3-doctor.rst, added to the TOC and index.CHANGELOG.md: new entry under rocprofv3.New Python modules are prefixed
doctor_, becauserocprofiler_rocprofv3_python()installs into one flat directory. All system access goes throughSystemAccessor(doctor_env.py), which is what makes every check testable without a GPU.Issue Tracking
Test Plan
Tests live in
tests/rocprofv3-doctor/. None require a GPU.test_doctor_framework.py--doctordispatchrocprofv3-doctor-unit-tests(labelunittests)test_doctor_checks.pytest_doctor_layout.pytest_doctor_diagnose.pytest_doctor_system.pyvalidate.py--rocm-root,rocprofv3 --doctorhelp and passthrough match the scriptrocprofv3-doctor(labelintegration-tests)In addition, these were run by hand:
Test Result
black --checkis clean.Submission Checklist
🤖 Generated with Claude Code