Skip to content

fix(hipblaslt): tolerate AMDSMI_STATUS_NOT_SUPPORTED for BDF-based device matching on WSL - #11987

Merged
tony-davis merged 2 commits into
developfrom
users/tony-davis/fix-wsl-amdsmi-not-supported-crash
Sep 14, 2026
Merged

tony-davis merged 2 commits into
developfrom
users/tony-davis/fix-wsl-amdsmi-not-supported-crash

Conversation

@tony-davis

Copy link
Copy Markdown
Contributor

JIRA ID : ROCM-30983

Motivation

On WSL2 (DXG paravirtualized GPU passthrough), running hipblaslt-bench
crashes on startup. EfficiencyMonitor::setDeviceId() unconditionally
tries to match the target GPU via AMD-SMI's PCI BDF, but WSL2/DXG does
not expose a real PCI BDF to the guest, so amdsmi_get_gpu_bdf_id()
returns AMDSMI_STATUS_NOT_SUPPORTED. AMDSMI_CHECK_EXC throws
unconditionally on any non-success status, so this turns into an
uncaught std::runtime_error that takes down the whole client, even
on a completely ordinary run where the user never asked for GPU
telemetry.

Technical Details

  • clients/bench/src/client.cpp: only call setDeviceId() when the
    perf monitor is actually enabled(), matching the existing
    enabled()-gating pattern used elsewhere (e.g.
    argument_model.cpp). An ordinary run (no HIPBLASLT_BENCH_FREQ /
    HIPBLASLT_BENCH_PERF env vars) now never touches AMD-SMI at all.
  • efficiency_monitor.hpp: added isAmdsmiTelemetryUnavailable(), a
    small pure function that classifies AMDSMI_STATUS_NOT_SUPPORTED as
    "telemetry not available on this platform" rather than a real error.
  • efficiency_monitor.cpp (GetAMDSMIIndex()): even when a user does
    explicitly request telemetry, tolerate AMDSMI_STATUS_NOT_SUPPORTED
    from amdsmi_get_gpu_bdf_id() by warning once (via hipblaslt_cerr)
    and falling back to processor 0 instead of throwing. Other AMD-SMI
    failures still go through AMDSMI_CHECK_EXC and abort as before.
  • clients/tests/src/efficiency_monitor_gtest.cpp (new): host-only
    gtest covering the classifier (NOT_SUPPORTED tolerated,
    SUCCESS/UNKNOWN_ERROR not), registered in
    clients/tests/src/CMakeLists.txt, so the fix has an actual
    regression test instead of relying on WSL hardware being present in
    CI.

Test Plan

  • New EfficiencyMonitorSmoke gtest suite compiled into
    hipblaslt-test, so it runs wherever the gating Math CI
    precheckin job already runs hipblaslt-test.
  • No WSL2/DXG box was available in this environment, so I verified
    locally instead: configured and built hipblaslt-bench and
    hipblaslt-test in host-only mode (HIPBLASLT_ENABLE_DEVICE=OFF,
    no Tensile device libs) against a fetched ROCm 10.1.0 toolchain, to
    compile-check the changed files and run the new tests plus the
    existing host-only smoke suites.

Test Result

  • ./hipblaslt-test --gtest_filter=EfficiencyMonitorSmoke.* -> 3/3
    passed.
  • Reran alongside the existing SecureEnv and ArchRevisionSmoke
    host-only suites -> 12/12 passed, no regressions.
  • hipblaslt-clients-common, hipblaslt-bench, and hipblaslt-test
    all built clean with the changes.
  • Not run: the full GPU matmul suite, or an actual WSL2/DXG
    reproduction (no such host was available here) - that's why the
    regression test targets the pure classifier logic rather than the
    runtime crash path itself.

Submission Checklist

Risk level

Low. The change only affects an optional benchmark telemetry path
(EfficiencyMonitor), which is opt-in via env vars in the common
case, and it only adds tolerance for one specific AMD-SMI status
code - every other AMD-SMI failure still throws as before.

…nitor

On WSL2/DXG, AMD-SMI can't expose a real PCI BDF to the guest, so
amdsmi_get_gpu_bdf_id() returns AMDSMI_STATUS_NOT_SUPPORTED.
AMDSMI_CHECK_EXC throws unconditionally on any non-success status,
so an ordinary hipblaslt-bench run crashed on startup even when no
telemetry was requested.

- client.cpp: only call setDeviceId() when the efficiency monitor is
  actually enabled(), matching the gating pattern used elsewhere.
- efficiency_monitor.hpp/.cpp: add isAmdsmiTelemetryUnavailable() and
  use it in GetAMDSMIIndex() so NOT_SUPPORTED warns once and falls
  back to processor 0 instead of aborting, even when telemetry is
  explicitly requested. Other AMD-SMI failures still throw as before.
- Add efficiency_monitor_gtest.cpp covering the classifier.

JIRA ID : ROCM-30983

Co-authored-by: Cursor <cursoragent@cursor.com>
@tony-davis
tony-davis requested review from a team as code owners September 11, 2026 16:40
Copilot AI lite review requested due to automatic review settings September 11, 2026 16:40
@therock-pr-bot

therock-pr-bot Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass —
🔎 pre-commit ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —
🤖 therock-pr-bot ✅ Pass —

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

One or more issues must be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Hardens optional hipBLASLt benchmark telemetry on WSL/DXG by avoiding unnecessary AMD-SMI access and tolerating unavailable PCI BDFs.

Changes:

  • Gate device matching on telemetry being enabled.
  • Fall back to processor 0 for AMDSMI_STATUS_NOT_SUPPORTED.
  • Add and register host-only classifier tests.
File summaries
File Description
projects/hipblaslt/clients/tests/src/efficiency_monitor_gtest.cpp Updated as part of this pull request.
projects/hipblaslt/clients/tests/src/CMakeLists.txt Updated as part of this pull request.
projects/hipblaslt/clients/common/src/efficiency_monitor.cpp Updated as part of this pull request.
projects/hipblaslt/clients/common/include/efficiency_monitor.hpp Updated as part of this pull request.
projects/hipblaslt/clients/bench/src/client.cpp Updated as part of this pull request.
Review details

Suppressed comments (3)

projects/hipblaslt/clients/common/src/efficiency_monitor.cpp:499

  • The added gtests only exercise the classifier, so they still pass if this call-site handling is removed (or if return 0 is changed back to throwing), which would reintroduce the WSL startup crash. Please add a test seam around the AMD-SMI lookup/status handling—or extract the fallback decision into a helper and test that the NOT_SUPPORTED path returns processor 0—so the regression test fails for the actual runtime bug rather than only for a classifier mutation.
                if(isAmdsmiTelemetryUnavailable(bdfStatus))
                {

projects/hipblaslt/clients/common/src/efficiency_monitor.cpp:515

  • Returning literal 0 ignores hipDeviceIndex. If WSL exposes more than one HIP device and the user runs --device 1, the matmul runs on device 1 but collect() indexes m_processorHandles[0], so the reported clocks and efficiency come from a different GPU. Please either establish a validated HIP-to-AMD-SMI ordering or disable telemetry when BDF mapping is unavailable instead of silently selecting processor 0.
                    return 0;

projects/hipblaslt/clients/tests/src/efficiency_monitor_gtest.cpp:17

  • The quick/shared smoke lane invokes --gtest_filter=*smoke* (see test/therock/test_hipblaslt.py:92-99 and clients/tests/test_categories.yaml:30-39), but these test names contain only the capitalized Smoke in the suite and no lowercase smoke token. Consequently none of the three new regression tests runs in that lane; use the existing smoke_ test-name convention (for example, caching_library_gtest.cpp:69-73) so the guard executes in CI.
    TEST(EfficiencyMonitorSmoke, NotSupportedIsTolerated)
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

…D fix

- Link amd_smi PUBLIC (not PRIVATE) from hipblaslt-clients-common, since
  efficiency_monitor.hpp is a public header that now includes
  <amd_smi/amdsmi.h> directly, and hipblaslt-bench only links
  hipblaslt-clients-common, not amd_smi itself.
- Extract GetAMDSMIIndex()'s per-iteration BDF-status decision into a
  pure decideBdfMatch() helper so the NOT_SUPPORTED-tolerance policy is
  directly unit tested, not just the isAmdsmiTelemetryUnavailable()
  classifier. A reverted fix now fails
  smoke_NotSupportedFallsBackInsteadOfThrowing.
- Add selectFallbackAmdsmiIndex() so the WSL fallback tracks
  hipDeviceIndex instead of always guessing processor 0, which could
  attribute telemetry to the wrong GPU on a multi-GPU WSL host.
- Rename tests to the smoke_ naming convention so they run in the
  --gtest_filter=*smoke* CI quick lane (they didn't before: gtest
  filters are case-sensitive and "Smoke" != "smoke").

JIRA ID : ROCM-30983

Co-authored-by: Cursor <cursoragent@cursor.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

Only minor documentation and test-report nits remain; no blocking implementation issues were identified.

Review details

Suppressed comments (1)

projects/hipblaslt/clients/common/src/efficiency_monitor.cpp:511

  • The Technical Details says the unsupported-BDF path falls back to processor 0, but this implementation selects hipDeviceIndex and clamps it with selectFallbackAmdsmiIndex(). Please update the PR description to document the actual multi-GPU behavior; otherwise the stated device-selection behavior is inaccurate.
                    if(isAmdsmiTelemetryUnavailable(bdfStatus))
                    {
                        // No PCI BDF to match against on this platform; warn once
                        // and use a best-effort processor index instead of aborting.
                        static bool warned = false;
  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Lite

@Alex-Vasile Alex-Vasile left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CMakeList changes look good.

@tony-davis
tony-davis requested a review from newling September 11, 2026 18:09
@tony-davis
tony-davis enabled auto-merge (squash) September 11, 2026 18:22

@newling newling left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the details, but the general shape looks good to me.

An agent raised one issue (see here)

The issue is related to some unreliable performance numbers is an edge case, which seems less important than not crashing. So I think it can be addressed in a follow-up (or ignored).

@tony-davis

Copy link
Copy Markdown
Contributor Author

Thanks for looking, and thanks to your agent for the catch. Confirmed: selectFallbackAmdsmiIndex()'s per-socket clamp can pick the wrong physical GPU on a multi-socket host if the BDF-unsupported socket isn't the one hipDeviceIndex is actually on.

Deliberately leaving this as-is for now rather than fixing it here. The reported bug (WSL2/DXG, single GPU, crash on every run) is fully fixed by this PR either way - the fallback only kicks in when BDF is unsupported, and for a single visible GPU it's unambiguous regardless of socket layout. The multi-socket case is a narrower, untested edge case (no multi-socket WSL/DXG hardware available to validate a real fix against), and fixing it properly would add meaningfully more complexity (a second identity signal via amdsmi_get_gpu_enumeration_info(), tracking processor handles across sockets, a path to disable telemetry rather than guess) for a scenario that only affects benchmark telemetry accuracy, not correctness or crashes.

Recording it here for whoever hits it next: the fix would be to search all sockets before falling back, and use AMD-SMI's HIP enumeration ID as a secondary identity check when BDF is unavailable, only guessing an ordinal index when there's exactly one candidate GPU.

@codecov

codecov Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 45 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ipblaslt/clients/common/src/efficiency_monitor.cpp 0.00% 24 Missing ⚠️
...aslt/clients/common/include/efficiency_monitor.hpp 0.00% 21 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #11987      +/-   ##
===========================================
- Coverage    70.55%   70.54%   -0.00%     
===========================================
  Files         2810     2810              
  Lines       462506   462530      +24     
  Branches     68099    68098       -1     
===========================================
+ Hits        326279   326288       +9     
- Misses      112684   112699      +15     
  Partials     23543    23543              
Flag Coverage Δ *Carryforward flag
TensileLite-CPP 46.40% <ø> (ø) Carriedforward from 67eb75d
TensileLite-Unit 76.06% <ø> (-<0.01%) ⬇️ Carriedforward from 67eb75d
hipBLAS 90.62% <ø> (ø) Carriedforward from 67eb75d
hipBLASLt 35.27% <0.00%> (+0.04%) ⬆️
hipCUB 82.68% <ø> (ø) Carriedforward from 67eb75d
hipDNN 87.02% <ø> (ø) Carriedforward from 67eb75d
hipFFT 42.66% <ø> (ø) Carriedforward from 67eb75d
hipRAND 76.12% <ø> (ø) Carriedforward from 67eb75d
hipSOLVER 68.92% <ø> (ø) Carriedforward from 67eb75d
hipSPARSE 86.99% <ø> (ø) Carriedforward from 67eb75d
rocBLAS 48.31% <ø> (ø) Carriedforward from 67eb75d
rocFFT 51.72% <ø> (ø) Carriedforward from 67eb75d
rocRAND 56.90% <ø> (ø) Carriedforward from 67eb75d
rocSOLVER 76.83% <ø> (ø) Carriedforward from 67eb75d
rocSPARSE 74.61% <ø> (ø) Carriedforward from 67eb75d
rocThrust 91.60% <ø> (ø) Carriedforward from 67eb75d

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...aslt/clients/common/include/efficiency_monitor.hpp 0.00% <0.00%> (ø)
...ipblaslt/clients/common/src/efficiency_monitor.cpp 0.00% <0.00%> (ø)

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@tony-davis
tony-davis disabled auto-merge September 12, 2026 02:00
@tony-davis

Copy link
Copy Markdown
Contributor Author

Dug into the 0% patch coverage report. Two different things are going on here, so here's our own estimate of what's actually exercised, since codecov's number understates one file and is honestly accurate for the other.

efficiency_monitor.hpp (the pure decision functions - isAmdsmiTelemetryUnavailable(), decideBdfMatch(), selectFallbackAmdsmiIndex()): by our own count, roughly 13 of the 14 executable statements added here are exercised by the EfficiencyMonitorSmoke gtest suite (10 tests), covering every branch except one - selectFallbackAmdsmiIndex()'s defensive amdsmiDeviceCount == 0 guard is never hit by a test. Call it ~90% real coverage on this file, not 0%. The reason it shows as 0% here: our tests are tagged smoke_* per hipBLASLt's own test-tiering convention (test_categories.yaml), and the Jenkins codecov job (hipblaslt/codecov.groovy) filters to gfilter = "*pre_checkin*..." only - it never runs smoke-tier tests at all, so this file's tests are structurally invisible to that job regardless of what we do here. That looks like a pre-existing gap in the coverage job's scope, not specific to this PR.

efficiency_monitor.cpp (GetAMDSMIIndex()'s new BDF/fallback handling and the warning-log block): this one's genuinely close to 0%, and codecov is right. It calls real AMD-SMI/HIP APIs and only runs inside hipblaslt-bench on live hardware with monitoring enabled; no unit test here can exercise it without a GPU, which is exactly why the decision logic was factored out into the header in the first place.

Net: patch coverage is real but partial - strong on the testable decision logic, intentionally absent on the hardware-dependent glue around it, plus one small untested defensive branch we can add a test for if useful.

@tony-davis
tony-davis merged commit 62d6012 into develop Sep 14, 2026
179 of 186 checks passed
@tony-davis
tony-davis deleted the users/tony-davis/fix-wsl-amdsmi-not-supported-crash branch September 14, 2026 14:57
@assistant-librarian

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

marbre pushed a commit that referenced this pull request Sep 16, 2026
…vice matching on WSL (#11987) (#12133)

Cherry-picks commit 62d6012 into the ROCm 10.1 release branch.

JIRA ID: AIRDEL-56

---

JIRA ID : ROCM-30983

## Motivation
On WSL2 (DXG paravirtualized GPU passthrough), running hipblaslt-bench
crashes on startup. `EfficiencyMonitor::setDeviceId()` unconditionally
tries to match the target GPU via AMD-SMI's PCI BDF, but WSL2/DXG does
not expose a real PCI BDF to the guest, so `amdsmi_get_gpu_bdf_id()`
returns `AMDSMI_STATUS_NOT_SUPPORTED`. `AMDSMI_CHECK_EXC` throws
unconditionally on any non-success status, so this turns into an
uncaught `std::runtime_error` that takes down the whole client, even
on a completely ordinary run where the user never asked for GPU
telemetry.

## Technical Details
- `clients/bench/src/client.cpp`: only call `setDeviceId()` when the
  perf monitor is actually `enabled()`, matching the existing
  `enabled()`-gating pattern used elsewhere (e.g.
  `argument_model.cpp`). An ordinary run (no `HIPBLASLT_BENCH_FREQ` /
  `HIPBLASLT_BENCH_PERF` env vars) now never touches AMD-SMI at all.
- `efficiency_monitor.hpp`: added `isAmdsmiTelemetryUnavailable()`, a
  small pure function that classifies `AMDSMI_STATUS_NOT_SUPPORTED` as
  "telemetry not available on this platform" rather than a real error.
- `efficiency_monitor.cpp` (`GetAMDSMIIndex()`): even when a user does
  explicitly request telemetry, tolerate `AMDSMI_STATUS_NOT_SUPPORTED`
  from `amdsmi_get_gpu_bdf_id()` by warning once (via `hipblaslt_cerr`)
  and falling back to a HIP-device-index-based processor slot
  (`selectFallbackAmdsmiIndex()`, clamped to the AMD-SMI device count)
  instead of throwing. Other AMD-SMI
  failures still go through `AMDSMI_CHECK_EXC` and abort as before.
- `clients/tests/src/efficiency_monitor_gtest.cpp` (new): host-only
  gtest covering the classifier (`NOT_SUPPORTED` tolerated,
  `SUCCESS`/`UNKNOWN_ERROR` not), registered in
  `clients/tests/src/CMakeLists.txt`, so the fix has an actual
  regression test instead of relying on WSL hardware being present in
  CI.

## Test Plan
- New `EfficiencyMonitorSmoke` gtest suite (10 tests) compiled into
  `hipblaslt-test`, so it runs wherever the gating Math CI
  `precheckin` job already runs `hipblaslt-test`.
- No WSL2/DXG box was available in this environment, so I verified
  locally instead: configured and built `hipblaslt-bench` and
  `hipblaslt-test` in host-only mode (`HIPBLASLT_ENABLE_DEVICE=OFF`,
  no Tensile device libs) against a fetched ROCm 10.1.0 toolchain, to
  compile-check the changed files and run the new tests plus the
  existing host-only smoke suites.

## Test Result
- `./hipblaslt-test --gtest_filter=EfficiencyMonitorSmoke.*` -> 10/10
  passed.
- Reran alongside the existing `SecureEnv` (5 tests) and
  `ArchRevisionSmoke` (4 tests) host-only suites -> 19/19 passed, no
  regressions.
- `hipblaslt-clients-common`, `hipblaslt-bench`, and `hipblaslt-test`
  all built clean with the changes.
- Not run: the full GPU matmul suite, or an actual WSL2/DXG
  reproduction (no such host was available here) - that's why the
  regression test targets the pure classifier logic rather than the
  runtime crash path itself.

## Submission Checklist
- [x] Look over the contributing guidelines at
https://github.com/ROCm/TheRock/blob/main/CONTRIBUTING.md.

## Risk level
Low. The change only affects an optional benchmark telemetry path
(`EfficiencyMonitor`), which is opt-in via env vars in the common
case, and it only adds tolerance for one specific AMD-SMI status
code - every other AMD-SMI failure still throws as before.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants