Skip to content

Update formatting.yml for Rocprofiler-sdk - #7

Merged
amd-hsivasun merged 8 commits into
developfrom
amd/hsivasun/rocprofiler-sdk-formatting
Jul 23, 2025
Merged

amd-hsivasun merged 8 commits into
developfrom
amd/hsivasun/rocprofiler-sdk-formatting

Conversation

@amd-hsivasun

Copy link
Copy Markdown
Collaborator

Changed runners to ubuntu-latest instead of AMD-ROCm-Internal-dev1

@amd-hsivasun amd-hsivasun changed the title Update formatting.yml Update formatting.yml for Rocprofiler-sdk Jul 23, 2025
@amd-hsivasun
amd-hsivasun requested a review from jharryma July 23, 2025 22:03

@jharryma jharryma left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

@amd-hsivasun
amd-hsivasun merged commit 61299d7 into develop Jul 23, 2025
@amd-hsivasun
amd-hsivasun deleted the amd/hsivasun/rocprofiler-sdk-formatting branch July 24, 2025 19:29
systems-assistant Bot pushed a commit that referenced this pull request Aug 5, 2025
Set execute permission for HSA allocated memory

We need execute permission for HSA memory (req for IB buffers).
Enforcement is upcoming which will break counter collection (see ticket).

Change-Id: Id939bbdd8686915407bc60d0dfcd5110b0e91e90

Co-authored-by: Benjamin Welton <bewelton@amd.com>
Co-authored-by: Bhardwaj, Gopesh <Gopesh.Bhardwaj@amd.com>
systems-assistant Bot pushed a commit that referenced this pull request Aug 5, 2025
* General logging updates

* ROCm 6.1.x fatal defect: unconditional abort if tool found but rocprofiler-sdk missing

- Adding rocprofiler-sdk support breaks backwards compatibility in ROCm 6.1.x because `rocprofiler_configure` symbol triggers looking for rocprofiler-sdk library (which was not released until ROCm 6.2)
- Bump version to 0.5.0

* revert to using fatal error

* Include header updates

* Fix CodeQL suggestions

* CMake and CI updates

- minimum cmake version is 3.22.0
- added requirements.txt
- improved rocprofiler_register_{formatting,linting}.cmake

* Disable deprecated declarations warnings

* Use "overwrite" instead of "override"

- override is a keyword in C++

* Disable REQUIRED for formatting and linting when BUILD_DEVELOPER=ON

---------

Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>
systems-assistant Bot pushed a commit that referenced this pull request Aug 5, 2025
* Obey CMAKE_BUILD_TYPE

Obey CMAKE_BUILD_TYPE when it is passed on the command line. Previous
behavior remains:

Debug by default
ROCRTST_BLD_TYPE can set build type

* External CI: change trigger from amd-master to amd-mainline

* Added gfx94x and gfx11xx  IDs to enumerator (#5)

* Use idomatic approach to extending CMAKE_MODULE_PATH. (#7)

There are many reasons why there may already be a CMAKE_MODULE_PATH defined.
The idiomatic way to extend it in a project is via list(APPEND).

ROCm/rocminfo#97 submitted by @stellaraccident

Co-authored-by: Stella Laurenzo <Stella.Laurenzo@amd.com>

* Added release trigger for further releases

* Fix for typo in ISA_TO_ID table (#6)

Change-Id: Id0720988fb01079a3ca6f3287dc743d93db4fd0f

* Remove WSL checks for displaying UUID and BDFID

Signed-off-by: lyndonli <Lyndon.Li@amd.com>

* Added KWS check for amd-mainline (#9)

---------

Signed-off-by: lyndonli <Lyndon.Li@amd.com>
Co-authored-by: benrichard-amd <ben.richard@amd.com>
Co-authored-by: Su, Daniel <Daniel.Su@amd.com>
Co-authored-by: Stella Laurenzo <Stella.Laurenzo@amd.com>
Co-authored-by: Mallya, Ameya Keshava <AmeyaKeshava.Mallya@amd.com>
Co-authored-by: Yat Sin, David <David.YatSin@amd.com>
Co-authored-by: lyndonli <Lyndon.Li@amd.com>
jayhawk-commits pushed a commit that referenced this pull request Aug 5, 2025
* General logging updates

* ROCm 6.1.x fatal defect: unconditional abort if tool found but rocprofiler-sdk missing

- Adding rocprofiler-sdk support breaks backwards compatibility in ROCm 6.1.x because `rocprofiler_configure` symbol triggers looking for rocprofiler-sdk library (which was not released until ROCm 6.2)
- Bump version to 0.5.0

* revert to using fatal error

* Include header updates

* Fix CodeQL suggestions

* CMake and CI updates

- minimum cmake version is 3.22.0
- added requirements.txt
- improved rocprofiler_register_{formatting,linting}.cmake

* Disable deprecated declarations warnings

* Use "overwrite" instead of "override"

- override is a keyword in C++

* Disable REQUIRED for formatting and linting when BUILD_DEVELOPER=ON

---------

Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>

[ROCm/rocprofiler-register commit: cb1b430]
jayhawk-commits pushed a commit that referenced this pull request Aug 5, 2025
Set execute permission for HSA allocated memory

We need execute permission for HSA memory (req for IB buffers).
Enforcement is upcoming which will break counter collection (see ticket).

Change-Id: Id939bbdd8686915407bc60d0dfcd5110b0e91e90

Co-authored-by: Benjamin Welton <bewelton@amd.com>
Co-authored-by: Bhardwaj, Gopesh <Gopesh.Bhardwaj@amd.com>

[ROCm/rocprofiler commit: 6cc5501]
systems-assistant Bot pushed a commit that referenced this pull request Aug 10, 2025
jayhawk-commits pushed a commit that referenced this pull request Aug 11, 2025
There are many reasons why there may already be a CMAKE_MODULE_PATH defined.
The idiomatic way to extend it in a project is via list(APPEND).

ROCm/rocminfo#97 submitted by @stellaraccident

Co-authored-by: Stella Laurenzo <Stella.Laurenzo@amd.com>

[ROCm/rocminfo commit: 8503ec3]
jayhawk-commits pushed a commit that referenced this pull request Aug 11, 2025
* Obey CMAKE_BUILD_TYPE

Obey CMAKE_BUILD_TYPE when it is passed on the command line. Previous
behavior remains:

Debug by default
ROCRTST_BLD_TYPE can set build type

* External CI: change trigger from amd-master to amd-mainline

* Added gfx94x and gfx11xx  IDs to enumerator (#5)

* Use idomatic approach to extending CMAKE_MODULE_PATH. (#7)

There are many reasons why there may already be a CMAKE_MODULE_PATH defined.
The idiomatic way to extend it in a project is via list(APPEND).

ROCm/rocminfo#97 submitted by @stellaraccident

Co-authored-by: Stella Laurenzo <Stella.Laurenzo@amd.com>

* Added release trigger for further releases

* Fix for typo in ISA_TO_ID table (#6)

Change-Id: Id0720988fb01079a3ca6f3287dc743d93db4fd0f

* Remove WSL checks for displaying UUID and BDFID

Signed-off-by: lyndonli <Lyndon.Li@amd.com>

* Added KWS check for amd-mainline (#9)

---------

Signed-off-by: lyndonli <Lyndon.Li@amd.com>
Co-authored-by: benrichard-amd <ben.richard@amd.com>
Co-authored-by: Su, Daniel <Daniel.Su@amd.com>
Co-authored-by: Stella Laurenzo <Stella.Laurenzo@amd.com>
Co-authored-by: Mallya, Ameya Keshava <AmeyaKeshava.Mallya@amd.com>
Co-authored-by: Yat Sin, David <David.YatSin@amd.com>
Co-authored-by: lyndonli <Lyndon.Li@amd.com>

[ROCm/rocminfo commit: aec5d6f]
jayhawk-commits pushed a commit that referenced this pull request Aug 18, 2025
[ROCm/hipother commit: 3eb783e]
stellaraccident added a commit that referenced this pull request Feb 26, 2026
## Summary
- Wire `ElfVerifier` into `kpack_offload_binary()` so corrupt output is
caught at build time
- Runs after all transform phases, before writing output file
- Catches PHDR alignment violations, NOBITS collisions, and other
structural issues
- Verified: all 53 existing ELF tests pass, real binary transforms still
succeed

## Motivation

The kpack ELF transform has produced corrupt binaries in CI multiple
times. The verifier already exists and is used in unit tests, but was
never wired into the production code path. This means corruption is only
discovered at runtime (`hipErrorInvalidImage`) long after the binary was
generated.

Confirmed the verifier catches both errors found in the latest CI
artifacts:
```
Verification FAILED
Errors (2):
  - PT_LOAD segments 1 and 2 share file offset 0x0 (NOBITS collision)
  - PT_LOAD segment 12 has misaligned offset/vaddr
```

## Test plan
- [x] All 53 existing ELF tests pass
- [x] Pre-commit checks pass (black, etc.)
- [x] Verified local transform of real librocrand.so still passes
verification
- [x] Verified corrupt CI artifact is correctly rejected by verifier

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
jeffqjiangNew added a commit that referenced this pull request Mar 13, 2026
## Motivation

This PR adds entry and exit logs for core functions.

## Technical Details

- Info level (3) logs are added at core function entry and exit points.
- Monotonic clock stamp, process id, thread id, and file name are added
to the logs.
- The logs now have similar format to HIP logs for better viewing when
both are present.
- Direct error or warning logs to std::cerr. Other logs still go to
std::cout.

## JIRA ID

<!-- If applicable, mention the JIRA ID resolved by this PR (Example:
Resolves SWDEV-12345). -->
<!-- Do not post any JIRA links here. -->

## Test Plan

Set env variable ROCDEC_LOG_LEVEL to control log output.

All CTests and conformance tests must pass. Example summary of the test
results:
- CTests:

      Start  1: video_decodeRaw-HEVC
 1/15 Test  #1: video_decodeRaw-HEVC .............   Passed    2.05 sec
      Start  2: video_decodeRaw-AVC
 2/15 Test  #2: video_decodeRaw-AVC ..............   Passed    1.89 sec
      Start  3: video_decodeRaw-AV1
 3/15 Test  #3: video_decodeRaw-AV1 ..............   Passed    2.31 sec
      Start  4: video_decodeRaw-VP9
 4/15 Test  #4: video_decodeRaw-VP9 ..............   Passed    2.04 sec
      Start  5: rocdec_Decode-HEVC
 5/15 Test  #5: rocdec_Decode-HEVC ...............   Passed    0.92 sec
      Start  6: rocDecode_Negative_API_Tests
 6/15 Test  #6: rocDecode_Negative_API_Tests .....   Passed    0.78 sec
      Start  7: video_decode-HEVC
 7/15 Test  #7: video_decode-HEVC ................   Passed    2.74 sec
      Start  8: video_decode-AVC
 8/15 Test  #8: video_decode-AVC .................   Passed    2.64 sec
      Start  9: video_decode-AV1
 9/15 Test  #9: video_decode-AV1 .................   Passed    2.74 sec
      Start 10: video_decode-VP9
10/15 Test #10: video_decode-VP9 .................   Passed    2.78 sec
      Start 11: video_decodePerf-HEVC
11/15 Test #11: video_decodePerf-HEVC ............   Passed    2.92 sec
      Start 12: video_decodeBatch
12/15 Test #12: video_decodeBatch ................   Passed    4.34 sec
      Start 13: video_decodeRGB-HEVC
13/15 Test #13: video_decodeRGB-HEVC .............   Passed   33.51 sec
      Start 14: video_decodeMem-HEVC
14/15 Test #14: video_decodeMem-HEVC .............   Passed    2.09 sec
      Start 15: video_decodeRGB-Resize
15/15 Test #15: video_decodeRGB-Resize ...........   Passed   33.94 sec

100% tests passed, 0 tests failed out of 15

- AVC conformance test:
Conformance test completed on the 127 streams:
     - The number of passing streams is 127
     - The number of failing streams is 0
     - The number of streams that did not finish decoding is 0

- HEVC conformance test:
Conformance test completed on the 135 streams:
     - The number of passing streams is 135
     - The number of failing streams is 0
     - The number of streams that did not finish decoding is 0

- AV1 conformance test:
Conformance test completed on the 162 streams:
     - The number of passing streams is 162
     - The number of failing streams is 0
     - The number of streams that did not finish decoding is 0

- VP9 conformance test:
Conformance test completed on the 108 streams:
     - The number of passing streams is 108
     - The number of failing streams is 0
     - The number of streams that did not finish decoding is 0

## Test Result

Function entry/exit logs should show up when ROCDEC_LOG_LEVEL >= 3.

All conformance tests should pass.

## Submission Checklist

- [ ] Look over the contributing guidelines at
https://github.com/ROCm/ROCm/blob/develop/CONTRIBUTING.md#pull-requests.
Nikhil-Nunna pushed a commit that referenced this pull request Mar 13, 2026
## Motivation

This PR adds entry and exit logs for core functions.

## Technical Details

- Info level (3) logs are added at core function entry and exit points.
- Monotonic clock stamp, process id, thread id, and file name are added
to the logs.
- The logs now have similar format to HIP logs for better viewing when
both are present.
- Direct error or warning logs to std::cerr. Other logs still go to
std::cout.

## JIRA ID

<!-- If applicable, mention the JIRA ID resolved by this PR (Example:
Resolves SWDEV-12345). -->
<!-- Do not post any JIRA links here. -->

## Test Plan

Set env variable ROCDEC_LOG_LEVEL to control log output.

All CTests and conformance tests must pass. Example summary of the test
results:
- CTests:

      Start  1: video_decodeRaw-HEVC
 1/15 Test  #1: video_decodeRaw-HEVC .............   Passed    2.05 sec
      Start  2: video_decodeRaw-AVC
 2/15 Test  #2: video_decodeRaw-AVC ..............   Passed    1.89 sec
      Start  3: video_decodeRaw-AV1
 3/15 Test  #3: video_decodeRaw-AV1 ..............   Passed    2.31 sec
      Start  4: video_decodeRaw-VP9
 4/15 Test  #4: video_decodeRaw-VP9 ..............   Passed    2.04 sec
      Start  5: rocdec_Decode-HEVC
 5/15 Test  #5: rocdec_Decode-HEVC ...............   Passed    0.92 sec
      Start  6: rocDecode_Negative_API_Tests
 6/15 Test  #6: rocDecode_Negative_API_Tests .....   Passed    0.78 sec
      Start  7: video_decode-HEVC
 7/15 Test  #7: video_decode-HEVC ................   Passed    2.74 sec
      Start  8: video_decode-AVC
 8/15 Test  #8: video_decode-AVC .................   Passed    2.64 sec
      Start  9: video_decode-AV1
 9/15 Test  #9: video_decode-AV1 .................   Passed    2.74 sec
      Start 10: video_decode-VP9
10/15 Test #10: video_decode-VP9 .................   Passed    2.78 sec
      Start 11: video_decodePerf-HEVC
11/15 Test #11: video_decodePerf-HEVC ............   Passed    2.92 sec
      Start 12: video_decodeBatch
12/15 Test #12: video_decodeBatch ................   Passed    4.34 sec
      Start 13: video_decodeRGB-HEVC
13/15 Test #13: video_decodeRGB-HEVC .............   Passed   33.51 sec
      Start 14: video_decodeMem-HEVC
14/15 Test #14: video_decodeMem-HEVC .............   Passed    2.09 sec
      Start 15: video_decodeRGB-Resize
15/15 Test #15: video_decodeRGB-Resize ...........   Passed   33.94 sec

100% tests passed, 0 tests failed out of 15

- AVC conformance test:
Conformance test completed on the 127 streams:
     - The number of passing streams is 127
     - The number of failing streams is 0
     - The number of streams that did not finish decoding is 0

- HEVC conformance test:
Conformance test completed on the 135 streams:
     - The number of passing streams is 135
     - The number of failing streams is 0
     - The number of streams that did not finish decoding is 0

- AV1 conformance test:
Conformance test completed on the 162 streams:
     - The number of passing streams is 162
     - The number of failing streams is 0
     - The number of streams that did not finish decoding is 0

- VP9 conformance test:
Conformance test completed on the 108 streams:
     - The number of passing streams is 108
     - The number of failing streams is 0
     - The number of streams that did not finish decoding is 0

## Test Result

Function entry/exit logs should show up when ROCDEC_LOG_LEVEL >= 3.

All conformance tests should pass.

## Submission Checklist

- [ ] Look over the contributing guidelines at
https://github.com/ROCm/ROCm/blob/develop/CONTRIBUTING.md#pull-requests.
ammarwa added a commit that referenced this pull request Apr 21, 2026
Ships the informational diff variant (Confluence row #7):

  * ``perfxpert diff <baseline.db> <new.db> [--format …] [-o …] [-d …]``
    — always returns rc=0. Calls the shared ``trace_diff.diff_runs``
    engine and renders the result in one of four formats:
      - ``text``     — two-block overview + per-kernel table (stdout)
      - ``markdown`` — GitHub-flavored table + narrative (stdout)
      - ``json``     — the raw schema 0.3.1 dict
      - ``webview``  — standalone HTML with overview KPIs, stacked
                       delta-bars (red = regression, green = improvement),
                       sortable kernel table, narrative card
  * ``perfxpert analyze -i new.db --baseline baseline.db`` — end-of-
    session recap: after the agentic pipeline renders, splice a "Changed
    vs baseline" section into the main report. Works for all 4 formats
    (JSON adds a ``trace_diff`` top-level key; schema bumps to 0.3.1).

One engine, four call sites: CLI, MCP tool, analyze-splice, and the
upcoming ``perfxpert ci`` wrapper all route through
``trace_diff.diff_runs`` + ``cli.diff_cmd.render_diff``.

Tests: 9 new (``test_diff_cmd`` × 4, ``test_analyze_baseline_splice`` × 5).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ammarwa added a commit that referenced this pull request Apr 21, 2026
…SSION_THRESHOLD

Adds a standalone gate rule ``trace_diff_regression_rule`` to
``perfxpert.runtime.gate_cascade`` so the correctness cascade, the
``perfxpert ci`` subcommand, and any future agentic caller share the
same regression-detection engine.

Behavior:
  * Thin wrapper over ``tools.trace_diff.diff_runs``.
  * Verdict ``fail`` when ``wall_delta_pct > threshold``; otherwise ``pass``.
  * Threshold precedence: explicit ``threshold_pct=`` > env var
    ``PERFXPERT_CI_REGRESSION_THRESHOLD`` > :data:`DEFAULT_CI_REGRESSION_THRESHOLD_PCT`
    (5.0%). Invalid env values fall back to the default (no exceptions
    escape to the caller).
  * Returns a machine-readable dict including the full ``diff_runs``
    result so gate callers can show the same tables the CLI does.

The existing 5-gate ``evaluate()`` cascade is intentionally untouched —
this is a complementary standalone rule for the "compare two runs
without a candidate patch" flow that Confluence rows #7 + #8 need.

Tests: 8 new — threshold-resolution precedence (4) + verdict
correctness on baseline/tail-hurt/improved fixture pairs (4).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ammarwa added a commit that referenced this pull request Apr 21, 2026
…mped to 42 tools

Documents Confluence rows #5 (severity refinement), #7 (trace_diff
tool + subcommand + analyze splice), and #8 (perfxpert ci wrapper):

  - docs/guides/getting-started.md: new §7 "Compare runs + CI gating
    (``perfxpert diff`` / ``perfxpert ci``)" with GitHub Actions +
    GitLab CI snippets; remaining numbered sections shifted by +1.
  - docs/guides/python-api.md: document ``api.trace_diff_diff_runs``
    mirror + expected output shape.
  - docs/integration/mcp-server.md: tool count 41 → 42; add
    ``trace_diff.diff_runs`` to the classifier/knowledge snapshot
    (34 → 35).
  - docs/contributing/schemas.md: describe the 0.3.1 ``trace_diff``
    top-level field (shape, emission rules, own ``schema_version``);
    note severity + severity_label additions to
    ``hotspots[i].source_locations``.
  - docs/contributing/output_formats.md: contract checklist gains
    the conditional ``trace_diff`` top-level key; adds a severity-
    coloring section (bucket table + webview/text/markdown
    propagation rules) and a diff-reports contract requiring every
    format to surface regression-vs-improvement direction.

Validation:
  - scripts/lint.sh --strict         rc=0
  - scripts/link-checker.py --strict rc=0
  - scripts/test-samples.py --strict rc=0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ammarwa added a commit that referenced this pull request Apr 23, 2026
… polish + contributing docs (#5174)

## Summary

Proven-optimizations catalog, nightly benchmark harness, contributing
guides + RFC process + architecture refresh, `perfxpert doctor` polish,
Phase 7.1 `ai_analysis/` module deletion, and the convergence-review
fixes that establish real legacy-vs-agentic parity. This is the last PR
in the original retirement series; subsequent PRs (#5179, #5180) add the
bundled opencode fork and the docs-audit toolchain.

Stacks on #5173. Next in stack: #5179.

## What lands

### Phase 7.1 — `perfxpert/ai_analysis/` module removed
Commit `cb03e82c36` deletes the entire `ai_analysis/` module — **21
files, ~11.7 KLOC**. All execution now routes through
`perfxpert/agents/`; the dispatcher and the `PERFXPERT_LEGACY` env
toggle are gone. This completes the retirement started in #5173: there
is no longer a "legacy path" to opt back into.

### Proven-optimizations catalog (10 canonical case studies)
- `knowledge/proven_optimizations.yaml`: vgpr_reduction, lds_tiling,
mfma_enablement, memory_coalescing, fast_math, hip_stream_overlap,
kernel_fusion, device_sync_removal, warp_primitives, cache_blocking
- Dual-schema fixture integration: synthetic `duration_ns` + real
rocprofv3 UUID-suffixed `(end_ns - start_ns)` tables
- `tests/fixtures/*.db`: 5 fixtures re-profiled with `--pmc` on real
MI300X hardware

### Nightly benchmark harness + orchestration

### Contributing guides + RFC process + architecture refresh

### `perfxpert doctor` polish (8 checks incl. opencode bundled + LLM
providers)

## Review findings addressed (29 findings, 5 fix batches)

### Batch 1 — Gate cascade fidelity (3 commits)
- `gate-2-sol-signature`: `_run_sol_gate` took wrong keyword; unit tests
mocked the function so the TypeError went undetected. Two-tier check
now: hard cap on speedup ratio (>50× rejected arch-independent) +
optional absolute FLOPS check via `sol.sanity_check`. 13 new un-mocked
integration tests (`TestRunSolGateUnmocked`).
- `gate-4-hot-kernel-key-unit`: `regression.compare_runs` returns
`per_kernel_deltas` (list of dicts with `delta_pct` as a **fraction**,
not percent), not `hot_kernels`. Old code iterated a non-existent key so
Gate 4 silently treated all regressions as OK. Fraction↔percent
conversion corrected.
- `gate-5-skip-verdict`: verdict strings no longer misleading on skip
(`candidate_binary=None` path).

### Batch 2 — Schemas, validators, framework invariants (6 findings)
- #4: Pydantic cross-field validators on `GateVerdictModel`
(status/failing_gate coupling), `CorrectnessOutput` (verdict/action),
confidence clamps `Field(..., ge=0.0, le=1.0)`, typed `Literal` for
provider
- #12: `Agent` dataclass `frozen=True`; `__post_init__` validates layer
in (0,1,2)
- #7: `_parse_headers` raises `ValueError` on malformed JSON instead of
silent `{}`
- #10, #18: tasks module logs resolved store path; stale READ_ONLY
docstrings rewritten
- #17: README clarifies opencode is system dependency; doctor warns when
PERFXPERT_TASK_ROOT unset

### Batch 3 — External tool verifier + fence alignment (6 findings)
- N28: anthropic/openai SDK imports routed through `require_tool()` with
install-hint on missing
- N29: all 8 agent fence slices aligned to actual agent tool allowlists
- #5, #6, #9, #17: smoke-test opencode binary (not just presence),
hard-fail on bad `PERFXPERT_OPENCODE_PATH` override, skip subdirs in
config copy
- `tooldep`: user-home path search +
`PERFXPERT_ROCPROF_TRACE_DECODER_PATH` env support

### Batch 4 — Classifier + data-provenance fidelity (2 findings)
- **#1**: classifier no longer swallows DB errors silently (was
returning empty metrics → `data_insufficient`; now logs + propagates
error markers)
- **#26 (priority user-flagged)**: confidence now weighted by
`evidence_strength × match_ratio` instead of raw rule-count
normalization — partial-PMC classifications no longer over-confident.
New `test_partial_pmc_confidence` covers trace-only vs full-PMC paths.

### Batch 5 — Tests coverage gaps (9 findings)
- #20: gate cascade short-circuit coverage (Gates 2/3/4)
- #21: `_TraceAnalysisAdapter` shim delegation tests
- #22: trace-only `memcpy_pct` path in `classify_from_metrics`
- #23: `anthropic.APITimeoutError` normalization path
- #24: Root agent lambda stub guard
(`test_root.py::test_lambda_stubs_never_invoked`)
- #25: MCP tool coverage across 5 representative tools
- #27: flaky `time.sleep` → `proc.wait(timeout=5)`
- #14, #15, #16: stale comments + docstring rewrites (api.py,
__main__.py, recommendation.py)

## Parity story

**Problem found during review**: parity test wiring was toggling a dead
flag (`PERFXPERT_USE_AGENTS`) after the retirement PR flipped the
default — both legs were running the agentic path. "Parity" passed
vacuously.

**Fixes applied (Decision A+C):**
- **A**: Parity runner now toggles the operative legacy opt-out so
legacy and agentic paths are genuinely distinct; Tier-1 trace-only
fixtures `xfail`ed until re-profiled with `--pmc`.
- **C**: Re-profiled all 5 fixtures (`baseline`, `memory_bound`,
`compute_bound`, `latency_bound`, `regressed`) on real MI300X with
`rocprofv3 --pmc`:
- `compute_bound`: VALU-bound kernel (not MFMA, to legitimately match
Compute-Bound classification)
  - `memory_bound` / `baseline`: 128 MB H2D+D2H loop
  - `latency_bound` / `regressed`: 6,000 tiny kernels
- `_build_analysis_result` returns `api_overhead` (not `latency`) for
`overhead_pct > 25%` (legacy heuristic fix)
- E2E + dashboard tests updated for evidence-weighted classification

**Result**: `parity_snapshots/_aggregate.json` → **100% agreement on PMC
fixtures** (10/10 bottleneck + rec_technique signals). `rec_type` signal
skipped where the agentic path can't populate without an LLM (documented
asymmetric None).

## Convergence review round (2026-04-18)

- **Brand scrub**: zero-tolerance removal of the prior codename across
code, tests, patches, env-var names, and documentation.
- **CLI flag plumbing**: all 10 CLI flags (`--prompt`, `--llm`,
`--llm-model`, `--att-dir`, `--pc-sampling`, `--source-dir`, `--format`,
`-d/-o`) now wired end-to-end via an `analysis_options` side-channel on
`Context`.
- **PMC shard UNION** across multiple `.db` files uses
column-intersection and emits a `RuntimeWarning` listing dropped
columns.
- **FallbackProvider** has a typed exception taxonomy
(`LLMRateLimitError`, `LLMAuthenticationError`, `LLMTransientError`,
`LLMFatalError`). Auth/fatal errors surface immediately; only transient
+ rate-limit cascade. The provider is wired into `build_session`;
`PERFXPERT_LLM_FALLBACK_CHAIN` now has runtime effect.

## Test plan

- [x] 1036 pass / 3 skip / 0 fail from `experimental/python/perfxpert/`
- [x] Core suites — 100% pass: `tests/test_agents + test_providers +
test_runtime + test_tools`
- [x] Parity ship-gate — 100%: `tests/test_parity/` (12 passed, 5
rec_type skips documented)
- [x] Gate cascade — 100%: 28 tests including 13 new un-mocked SOL
integration tests (Batch 1 recovery)
- [x] E2E brain: `perfxpert-code run -m openai/gpt-4o-mini "..."` → MCP
→ Python → `81.7 TFLOPS` + AMD footer
- [x] `perfxpert doctor`: all 8 checks green (34 MCP tools at this PR
boundary; 43 after #5179+#5180; opencode 1.4.11 bundled; 3/5 LLM
providers configured)
- [x] No legacy opt-out path remains (Phase 7.1 removed the dispatcher
and the `PERFXPERT_LEGACY` toggle)
- [ ] Live MI300X nightly run (requires hardware; nightly workflow will
refresh baseline)
- [ ] Full interactive TUI (requires TTY; E2E can only prove
banner-emitted)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
vlaindic added a commit that referenced this pull request May 18, 2026
Translation parser (#3, #6):
  Replace the residual ROCP_FATAL on wave_id mismatch in the GFX1250 V2/V4 and
  stochastic copySample paths with ROCP_ERROR + returning a value-initialized
  record so it is filtered by is_invalid_sample() instead of aborting the
  process. Drop the redundant std::memset() that followed value-initialization
  of the invalid-sample sentinel in the GFX9/GFX12/GFX1250 V2 and GFX1250 V4
  paths, and document the timestamp-zero invariant.

query_agent_configurations_v2 (#5):
  Replace the dead "sort preferred-method configs first" pass with the same
  PREFER semantics already implemented by configure_v2: if any preferred-method
  config exists, return only those; otherwise fall back to returning all
  configs. REQUIRE remains a hard filter.

Callback signature:
  Change rocprofiler_available_pc_sampling_configurations_v2_cb_t to deliver
  configurations as a const T** array of pointers, matching the convention used
  by rocprofiler_query_available_agents_cb_t. Update the only consumer
  (samples/pc_sampling_v2/pcs.cpp) accordingly.

Documentation (#7, #8):
  Remove the V5 reference (only V0-V4 exist today); expand the api_flags doc
  with PREFER/REQUIRE behavior for both query and configure entry points and
  add per-enumerator @var blocks; add an Example 4 to configure_v2 showing
  conflicting flags being rejected; mark configuration_v2_t as output-only;
  add per-flag filtering rules and three usage examples to query_v2's doc;
  expand _get_parse_func_for_record_kind's docstring to specify when nullptr
  is returned.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@vlaindic vlaindic mentioned this pull request May 18, 2026
1 task
vlaindic added a commit that referenced this pull request May 27, 2026
Translation parser (#3, #6):
  Replace the residual ROCP_FATAL on wave_id mismatch in the GFX1250 V2/V4 and
  stochastic copySample paths with ROCP_ERROR + returning a value-initialized
  record so it is filtered by is_invalid_sample() instead of aborting the
  process. Drop the redundant std::memset() that followed value-initialization
  of the invalid-sample sentinel in the GFX9/GFX12/GFX1250 V2 and GFX1250 V4
  paths, and document the timestamp-zero invariant.

query_agent_configurations_v2 (#5):
  Replace the dead "sort preferred-method configs first" pass with the same
  PREFER semantics already implemented by configure_v2: if any preferred-method
  config exists, return only those; otherwise fall back to returning all
  configs. REQUIRE remains a hard filter.

Callback signature:
  Change rocprofiler_available_pc_sampling_configurations_v2_cb_t to deliver
  configurations as a const T** array of pointers, matching the convention used
  by rocprofiler_query_available_agents_cb_t. Update the only consumer
  (samples/pc_sampling_v2/pcs.cpp) accordingly.

Documentation (#7, #8):
  Remove the V5 reference (only V0-V4 exist today); expand the api_flags doc
  with PREFER/REQUIRE behavior for both query and configure entry points and
  add per-enumerator @var blocks; add an Example 4 to configure_v2 showing
  conflicting flags being rejected; mark configuration_v2_t as output-only;
  add per-flag filtering rules and three usage examples to query_v2's doc;
  expand _get_parse_func_for_record_kind's docstring to specify when nullptr
  is returned.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
AryanSalmanpour added a commit that referenced this pull request Jun 10, 2026
…error diagnostics in parser (#7010)

## Motivation

This PR enhances rocJPEG logging by adding structured, offset-annotated
debug logging for each major JPEG marker (SOF0, DQT, DHT, SOS, EOI),
improves clarity of error messages for unsupported formats, and
explicitly rejects progressive JPEGs (SOF2).

sample output:

```
ROCJPEG_LOG_LEVEL=4 ./jpegdecode -i  ~/install/share/rocjpeg/images/mug_420.jpg 
Reading images from disk, please wait!
Using GPU device 0: AMD Radeon RX 7900 XT[gfx1100] on PCI bus 03:00.0
[3, Info] rocjpeg_api.cpp:123: 2274381572050 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegCreate( 0, 0, 0x7fff0596b718 ): entry ...
[3, Info] rocjpeg_decoder.cpp:81: 2274381572066 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitializeDecoder(  ): entry ...
[3, Info] rocjpeg_decoder.cpp:50: 2274381572069 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitHIP( 0 ): entry ...
[3, Info] rocjpeg_decoder.cpp:50: 2274381592272 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitHIP( 0 ): exit (20203 us) ...
[3, Info] rocjpeg_vaapi_decoder.cpp:416: 2274381592356 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitializeDecoder(): gpu_uuids_to_render_nodes_map_: {e0b64ad979bec1fd: 128}
[3, Info] rocjpeg_vaapi_decoder.cpp:417: 2274381592362 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitializeDecoder(): Selected GPU UUID: e0b64ad979bec1fd
[3, Info] rocjpeg_vaapi_decoder.cpp:475: 2274381592366 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitVAAPI(): Opening DRM node: /dev/dri/renderD128
[3, Info] rocjpeg_vaapi_decoder.cpp:500: 2274381593624 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitVAAPI(): VA-API version 1.22
[3, Info] rocjpeg_vaapi_decoder.cpp:502: 2274381593634 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitVAAPI(): VA-API vendor: Mesa Gallium driver 26.0.0-devel for AMD Radeon RX 7900 XT (radeonsi, navi31, , DRM 3.64, 6.17.0-23-generic)
[3, Info] rocjpeg_vaapi_decoder.cpp:504: 2274381593638 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitVAAPI(): Trying to open /home/aryan/install/lib/rocm_sysdeps/lib/radeonsi_drv_video.so

[3, Info] rocjpeg_decoder.cpp:81: 2274381593728 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] InitializeDecoder(  ): exit (21662 us) ...
[3, Info] rocjpeg_api.cpp:123: 2274381593732 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegCreate( 0, 0, 0x7fff0596b718 ): exit (21682 us) ...
[3, Info] rocjpeg_api.cpp:40: 2274381593735 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegStreamCreate( 0x7fff0596b710 ): entry ...
[3, Info] rocjpeg_api.cpp:40: 2274381593738 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegStreamCreate( 0x7fff0596b710 ): exit (3 us) ...
Input file name: /home/aryan/install/share/rocjpeg/images/mug_420.jpg
[3, Info] rocjpeg_api.cpp:75: 2274381594731 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegStreamParse( 0x70b1f41c4010, 2340067, 0x55f2ebfec840 ): entry ...
[3, Info] rocjpeg_parser.cpp:48: 2274381594734 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseJpegStream( 0x70b1f41c4010, 2340067 ): entry ...
[4, Debug] rocjpeg_parser.cpp:408: 2274381594759 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseDQT(): 
*** Marker: DQT (xFFDB) ***
  Define a Quantization Table.
  OFFSET: 0x00001296
  Table length = 67
  ----
  Precision=8 bits
  Destination ID=0 (Luminance)
    DQT, Row #0:   1   1   1   1   1   1   1   1
    DQT, Row #1:   1   1   1   1   1   1   1   1
    DQT, Row #2:   1   1   1   1   1   1   1   1
    DQT, Row #3:   1   1   1   1   1   1   1   1
    DQT, Row #4:   1   1   1   1   1   1   1   1
    DQT, Row #5:   1   1   1   1   1   1   1   1
    DQT, Row #6:   1   1   1   1   1   1   1   1
    DQT, Row #7:   1   1   1   1   1   1   1   1
    Approx quality factor = 100.00 (scaling=2.99 variance=6.13)
[4, Debug] rocjpeg_parser.cpp:408: 2274381594772 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseDQT(): 
*** Marker: DQT (xFFDB) ***
  Define a Quantization Table.
  OFFSET: 0x000012DB
  Table length = 67
  ----
  Precision=8 bits
  Destination ID=1 (Chrominance)
    DQT, Row #0:   1   1   1   1   1   1   1   1
    DQT, Row #1:   1   1   1   1   1   1   1   1
    DQT, Row #2:   1   1   1   1   1   1   1   1
    DQT, Row #3:   1   1   1   1   1   1   1   1
    DQT, Row #4:   1   1   1   1   1   1   1   1
    DQT, Row #5:   1   1   1   1   1   1   1   1
    DQT, Row #6:   1   1   1   1   1   1   1   1
    DQT, Row #7:   1   1   1   1   1   1   1   1
    Approx quality factor = 100.00 (scaling=1.54 variance=1.58)
[4, Debug] rocjpeg_parser.cpp:297: 2274381594790 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseSOF(): 
*** Marker: SOF0 (Baseline DCT) (xFFC0) ***
  OFFSET: 0x00001320
  Frame header length = 17
  Precision = 8
  Number of Lines = 2160
  Samples per Line = 3840
  Image Size = 3840 x 2160
  Chroma subsampling: 4:2:0
  Raw Image Orientation = Landscape
  Number of Img components = 3
    Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y)
    Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb)
    Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr)
[4, Debug] rocjpeg_parser.cpp:515: 2274381594802 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseDHT(): 
*** Marker: DHT (Define Huffman Table) (xFFC4) ***
  OFFSET: 0x00001333
  Huffman table length = 31
  ----
  Destination ID = 0
  Class = 0 (DC / Lossless Table)
    Codes of length 01 bits (000 total): 
    Codes of length 02 bits (002 total): 03 04 
    Codes of length 03 bits (002 total): 01 02 
    Codes of length 04 bits (003 total): 00 05 06 
    Codes of length 05 bits (001 total): 07 
    Codes of length 06 bits (001 total): 08 
    Codes of length 07 bits (001 total): 09 
    Codes of length 08 bits (001 total): 0A 
    Codes of length 09 bits (001 total): 0B 
    Codes of length 0A bits (000 total): 
    Codes of length 11 bits (000 total): 
    Codes of length 12 bits (000 total): 
    Codes of length 13 bits (000 total): 
    Codes of length 14 bits (000 total): 
    Codes of length 15 bits (000 total): 
    Codes of length 16 bits (000 total): 
    Total number of codes: 012
[4, Debug] rocjpeg_parser.cpp:515: 2274381594816 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseDHT(): 
*** Marker: DHT (Define Huffman Table) (xFFC4) ***
  OFFSET: 0x00001354
  Huffman table length = 91
  ----
  Destination ID = 0
  Class = 1 (AC Table)
    Codes of length 01 bits (000 total): 
    Codes of length 02 bits (002 total): 01 02 
    Codes of length 03 bits (001 total): 11 
    Codes of length 04 bits (002 total): 03 21 
    Codes of length 05 bits (004 total): 00 04 12 31 
    Codes of length 06 bits (003 total): 05 41 51 
    Codes of length 07 bits (005 total): 06 13 22 61 71 
    Codes of length 08 bits (005 total): 32 81 91 A1 D1 
    Codes of length 09 bits (005 total): 07 52 B1 C1 F0 
    Codes of length 0A bits (005 total): 08 14 23 42 E1 
    Codes of length 0B bits (005 total): 62 72 92 A2 D2 
    Codes of length 0C bits (007 total): 09 15 33 53 82 E2 F1 
    Codes of length 0D bits (002 total): 24 B2 
    Codes of length 0E bits (001 total): C2 
    Codes of length 0F bits (002 total): 16 43 
    Codes of length 10 bits (023 total): 93 63 D3 0A 17 25 73 A3 34 54 83 18 19 B3 26 27 
                                         44 F2 35 64 C3 E3 46 
    Total number of codes: 072
[4, Debug] rocjpeg_parser.cpp:515: 2274381594829 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseDHT(): 
*** Marker: DHT (Define Huffman Table) (xFFC4) ***
  OFFSET: 0x000013B1
  Huffman table length = 29
  ----
  Destination ID = 1
  Class = 0 (DC / Lossless Table)
    Codes of length 01 bits (001 total): 00 
    Codes of length 02 bits (000 total): 
    Codes of length 03 bits (003 total): 01 02 03 
    Codes of length 04 bits (001 total): 04 
    Codes of length 05 bits (001 total): 05 
    Codes of length 06 bits (001 total): 06 
    Codes of length 07 bits (001 total): 07 
    Codes of length 08 bits (001 total): 08 
    Codes of length 09 bits (001 total): 09 
    Codes of length 0A bits (000 total): 
    Codes of length 11 bits (000 total): 
    Codes of length 12 bits (000 total): 
    Codes of length 13 bits (000 total): 
    Codes of length 14 bits (000 total): 
    Codes of length 15 bits (000 total): 
    Codes of length 16 bits (000 total): 
    Total number of codes: 010
[4, Debug] rocjpeg_parser.cpp:515: 2274381594842 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseDHT(): 
*** Marker: DHT (Define Huffman Table) (xFFC4) ***
  OFFSET: 0x000013D0
  Huffman table length = 83
  ----
  Destination ID = 1
  Class = 1 (AC Table)
    Codes of length 01 bits (000 total): 
    Codes of length 02 bits (001 total): 01 
    Codes of length 03 bits (001 total): 11 
    Codes of length 04 bits (004 total): 00 02 21 61 
    Codes of length 05 bits (007 total): 03 31 41 51 71 91 F0 
    Codes of length 06 bits (006 total): 12 22 52 81 A1 D1 
    Codes of length 07 bits (004 total): 04 62 B1 E1 
    Codes of length 08 bits (005 total): 13 32 82 A2 C1 
    Codes of length 09 bits (004 total): 05 42 92 F1 
    Codes of length 0A bits (000 total): 
    Codes of length 11 bits (004 total): 06 14 23 72 
    Codes of length 0C bits (004 total): 07 33 53 B2 
    Codes of length 0D bits (005 total): 15 43 C2 D2 E2 
    Codes of length 0E bits (001 total): 16 
    Codes of length 0F bits (001 total): 63 
    Codes of length 10 bits (017 total): 93 24 34 54 08 73 83 17 18 44 A3 35 F2 25 74 B3 
                                         D3 
    Total number of codes: 064
[4, Debug] rocjpeg_parser.cpp:606: 2274381594856 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseSOS(): 
*** Marker: SOS (Start of Scan) (xFFDA) ***
  OFFSET: 0x00001425
  Scan header length = 12
  Number of img components = 3
    Component[1]: selector=0x01, table=0(DC),0(AC)
    Component[2]: selector=0x02, table=1(DC),1(AC)
    Component[3]: selector=0x03, table=1(DC),1(AC)
  Spectral selection = 0 .. 63
  Successive approximation = 0x00
[4, Debug] rocjpeg_parser.cpp:669: 2274381595378 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseEOI(): 
*** Marker: EOI (End of Image) (xFFD9) ***
  OFFSET: 0x0023B4E1
[3, Info] rocjpeg_parser.cpp:48: 2274381595383 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] ParseJpegStream( 0x70b1f41c4010, 2340067 ): exit (649 us) ...
[3, Info] rocjpeg_api.cpp:75: 2274381595386 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegStreamParse( 0x70b1f41c4010, 2340067, 0x55f2ebfec840 ): exit (655 us) ...
[3, Info] rocjpeg_api.cpp:188: 2274381595393 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegGetImageInfo( 0x55f2ebf6dde0, 0x55f2ebfec840, 0x7fff0596b82a, 0x7fff0596b728, 0x7fff0596b810, 0x7fff0596b800 ): entry ...
[3, Info] rocjpeg_decoder.cpp:332: 2274381595397 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] GetImageInfo( 0x55f2ebfec840, 0x7fff0596b82a, 0x7fff0596b728, 0x7fff0596b810, 0x7fff0596b800 ): entry ...
[3, Info] rocjpeg_decoder.cpp:332: 2274381595400 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] GetImageInfo( 0x55f2ebfec840, 0x7fff0596b82a, 0x7fff0596b728, 0x7fff0596b810, 0x7fff0596b800 ): exit (3 us) ...
[3, Info] rocjpeg_api.cpp:188: 2274381595403 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegGetImageInfo( 0x55f2ebf6dde0, 0x55f2ebfec840, 0x7fff0596b82a, 0x7fff0596b728, 0x7fff0596b810, 0x7fff0596b800 ): exit (10 us) ...
Input image resolution: 3840x2160
Chroma subsampling: YUV 4:2:0
Decoding started, please wait! ... 
[3, Info] rocjpeg_api.cpp:222: 2274381595488 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegDecode( 0x55f2ebf6dde0, 0x55f2ebfec840, 0x7fff0596b6c0, 0x7fff0596b6e0 ): entry ...
[3, Info] rocjpeg_decoder.cpp:120: 2274381595492 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] Decode( 0x55f2ebfec840, 0x7fff0596b6c0, 0x7fff0596b6e0 ): entry ...
[3, Info] rocjpeg_decoder.cpp:120: 2274381607931 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] Decode( 0x55f2ebfec840, 0x7fff0596b6c0, 0x7fff0596b6e0 ): exit (12439 us) ...
[3, Info] rocjpeg_api.cpp:222: 2274381607937 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegDecode( 0x55f2ebf6dde0, 0x55f2ebfec840, 0x7fff0596b6c0, 0x7fff0596b6e0 ): exit (12449 us) ...
Average processing time per image (ms): 12.4542
Average images per sec: 80.2941
[3, Info] rocjpeg_api.cpp:154: 2274381608091 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegDestroy( 0x55f2ebf6dde0 ): entry ...
[3, Info] rocjpeg_api.cpp:154: 2274381610464 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegDestroy( 0x55f2ebf6dde0 ): exit (2373 us) ...
[3, Info] rocjpeg_api.cpp:99: 2274381610471 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegStreamDestroy( 0x55f2ebfec840 ): entry ...
[3, Info] rocjpeg_api.cpp:99: 2274381610474 us: [pid:1740825 tid:1740825 hashid:0xbc0a7] rocJpegStreamDestroy( 0x55f2ebfec840 ): exit (3 us) ...
Decoding completed!
```

## Technical Details

<!-- Explain the changes along with any relevant GitHub links. -->

## JIRA ID

<!-- If applicable, mention the JIRA ID resolved by this PR (Example:
Resolves SWDEV-12345). -->
<!-- Do not post any JIRA links here. -->

## Test Plan

<!-- Explain any relevant testing done to verify this PR. -->

## Test Result

<!-- Briefly summarize test outcomes. -->

## Submission Checklist

- [ ] Look over the contributing guidelines at
https://github.com/ROCm/ROCm/blob/develop/CONTRIBUTING.md#pull-requests.
abouteiller added a commit that referenced this pull request Jun 26, 2026
## Motivation

On certain test systems we do not have a shared filesystem, the
deadlock_analysis script harness would depend on a shared filesystem to
collect traces and artifacts. Remove that limitation.

## Technical Details

Use MPI stdout redirection to coalesce the trace artifacts to the
headnode in a headnode local output directory, perform analysis on the
headnode.

Prior filesystem based mode remains available and default. 

## JIRA ID


## Test Plan

Intentionally added a deadlock to a functional test, compiled with
Debug.
Run mpiexec_deadlock_attach script and observe artifacts.

## Test Result

```
 ROCSHMEM_DEBUG_LEVEL=trace:stats ~/ompi/bin/mpirun -n 2 tests/functional_tests/rocshmem_functional_tests -n 1 -a 26  & (sleep 2; /home/abouteil/rocm-systems/projects/rocshmem/scripts/debug/mpiexec_deadlock_analysis.sh  rocshmem_functional_tests --stats --color --no-shared-fs )
### Creating Test:      Blocking WG level Puts  B=ipc PE=2 W=1 Z=64 ###
Deploying deadlock analysis...
Executable:       rocshmem_functional_tests
Output directory: ./rocshmem_deadlock_analysis_20260530_013437
Filesystem mode:  no shared fs (--output-filename)
Stats:            yes
Color:            --color

Found 4 process(es) matching 'rocshmem_functional_tests': 717472 717473 751554 751555
Output directory: /tmp/rocshmem_deadlock_20260530_013437
Per-process timeout: 120s

Analyzing PID 717472 (PE 0) ... OK
Analyzing PID 717473 (PE 1) ... OK (no GPU threads)
Analyzing PID 751554 (PE 0) ... OK
Analyzing PID 751555 (PE 1) ... OK (no GPU threads)

=== Attach and Analyze Summary ===
Processes analyzed: 4 / 4

  PE 0     PID 751554    groups=1    \033[1;31m1\033[0m wf(s) in rocSHMEM; \033[1;36mWaiting for remote PE memory update (barrier/sync or user rocshmem_wait_until). Check if the remote PE is alive and making progress. (at: #0  0x0000792efa5af3c8 in rocshmem::Context::wait_until<long> (this=0x792eed407000, ivars=0x792efac04008, cmp=0, val=1) at src/context_tmpl_device.hpp:224)\033[0m
  PE 1     PID 751555    groups=?    (no GPU threads found)
=== BEGIN FILE: pe0_pid_717472.txt ===
[New LWP 717493]
[New LWP 717490]
[New LWP 717488]
[New LWP 717485]
[New LWP 717481]
[New LWP 717480]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x000077a09e06695f in ?? () from /opt/rocm-7.2.1/lib/libhsa-runtime64.so.1
=== rocSHMEM Deadlock Analysis ===
Process(es): 717472
Total GPU wavefronts analyzed: 1
Unique backtrace groups: 1

--- Group 1 (1 wavefront(s)) ---
  WFs: (0,0,0)/0
  Backtrace:
    #0  0x0000776005fafce0 in rocshmem::uncached_load<long volatile> (src=0x776006604008) at src/assembly.hpp:125
    #1  rocshmem::Context::test<long> (this=0x775ff8e07000, ivars=0x776006604008, cmp=0, val=1) at src/context_tmpl_device.hpp:432
    #2  rocshmem::Context::wait_until<long> (this=0x775ff8e07000, ivars=0x776006604008, cmp=0, val=1) at src/context_tmpl_device.hpp:224
    #3  rocshmem::IPCContext::internal_direct_barrier (this=0x775ff8e07000, pe=0, PE_start=0, stride=1, n_pes=2, pSync=0x776006604000) at build/src/ipc/context_ipc_device_coll.cpp:44
    #4  0x0000776005fb7c24 in rocshmem::IPCContext::internal_sync_wg (this=0x775ff8e07000, pe=0, PE_start=0, stride=1, PE_size=2, pSync=0x776006604000) at build/src/ipc/context_ipc_device_coll.cpp:115
    #5  0x000077600603d018 in rocshmem::IPCContext::sync_all_wg (this=0x775ff8e07000) at build/src/ipc/context_ipc_device_coll.cpp:168
    #6  0x000077600603d558 in rocshmem::IPCContext::barrier_all_wg (this=0x775ff8e07000) at build/src/ipc/context_ipc_device_coll.cpp:187
    #7  0x000077600603dedc in rocshmem::Context::barrier_all_wg (this=0x775ff8e07000) at build/src/context_device.cpp:151
    #8  0x000077600603e33c in rocshmem::rocshmem_barrier_all_wg () at build/src/rocshmem_gpu.cpp:885
    #9  0x00007760060437cc in WorkGroupPrimitiveTest (loop=1, skip=10, start_time=0x775ff8e31000, end_time=0x775ff8e32000, source=0x776013c00480 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr"..., dest=0x776013d00500 "1", size=1, type=WGPutTestType, ctx_type=4) at /home/abouteil/rocm-systems/projects/rocshmem/tests/functional_tests/workgroup_primitives.cpp:72
  [HINT] Waiting for remote PE memory update (barrier/sync or user rocshmem_wait_until). Check if the remote PE is alive and making progress. (at: #2  rocshmem::Context::wait_until<long> (this=0x775ff8e07000, ivars=0x776006604008, cmp=0, val=1) at src/context_tmpl_device.hpp:224)
...
=== END FILE: pe1_pid_751555.txt ===

Reconstructing per-PE output files from mpiexec output...
Reconstructed output from 1 rank file(s).

Running cross-rank coalescing pass...

=== Cross-Rank Deadlock Analysis ===
Directory: ./rocshmem_deadlock_analysis_20260530_013437
Ranks with analysis files: 2  (0, 1)
Unique backtrace patterns: 2

--- Pattern 1 [UNIQUE: rank 0] ---
  Ranks: 0
  Total wavefronts: 1
  Backtrace:
    #0  0x0000776005fafce0 in rocshmem::uncached_load<long volatile> (src=0x776006604008) at src/assembly.hpp:125
    #1  rocshmem::Context::test<long> (this=0x775ff8e07000, ivars=0x776006604008, cmp=0, val=1) at src/context_tmpl_device.hpp:432
    #2  rocshmem::Context::wait_until<long> (this=0x775ff8e07000, ivars=0x776006604008, cmp=0, val=1) at src/context_tmpl_device.hpp:224
    #3  rocshmem::IPCContext::internal_direct_barrier (this=0x775ff8e07000, pe=0, PE_start=0, stride=1, n_pes=2, pSync=0x776006604000) at build/src/ipc/context_ipc_device_coll.cpp:44
    #4  0x0000776005fb7c24 in rocshmem::IPCContext::internal_sync_wg (this=0x775ff8e07000, pe=0, PE_start=0, stride=1, PE_size=2, pSync=0x776006604000) at build/src/ipc/context_ipc_device_coll.cpp:115
    #5  0x000077600603d018 in rocshmem::IPCContext::sync_all_wg (this=0x775ff8e07000) at build/src/ipc/context_ipc_device_coll.cpp:168
    #6  0x000077600603d558 in rocshmem::IPCContext::barrier_all_wg (this=0x775ff8e07000) at build/src/ipc/context_ipc_device_coll.cpp:187
    #7  0x000077600603dedc in rocshmem::Context::barrier_all_wg (this=0x775ff8e07000) at build/src/context_device.cpp:151
    #8  0x000077600603e33c in rocshmem::rocshmem_barrier_all_wg () at build/src/rocshmem_gpu.cpp:885
    #9  0x00007760060437cc in WorkGroupPrimitiveTest (loop=1, skip=10, start_time=0x775ff8e31000, end_time=0x775ff8e32000, source=0x776013c00480 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr"..., dest=0x776013d00500 "1", size=1, type=WGPutTestType, ctx_type=4) at /home/abouteil/rocm-systems/projects/rocshmem/tests/functional_tests/workgroup_primitives.cpp:72
  [HINT] Waiting for remote PE memory update (barrier/sync or user rocshmem_wait_until). Check if the remote PE is alive and making progress. (at: #2  rocshmem::Context::wait_until<long> (this=0x775ff8e07000, ivars=0x776006604008, cmp=0, val=1) at src/context_tmpl_device.hpp:224)

=== Per-Rank rocSHMEM Wavefront Count ===
  Rank 0: 2 wf(s) inside rocSHMEM
  Rank 1: 0 wf(s) inside rocSHMEM

=== Summary ===
  0 pattern(s) common to all 2 rank(s)
  1 pattern(s) present in exactly one rank
  Most common hint: Waiting for remote PE memory update (barrier/sync or user rocshmem_wait_until). Check if the remote PE is alive and making progress. (at: #2  rocshmem::Context::wait_until<long> (this=0x775ff8e07000, ivars=0x776006604008, cmp=0, val=1) at src/context_tmpl_device.hpp:224)
```
abouteiller added a commit that referenced this pull request Jun 29, 2026
… progress tracker (#6616)

## Motivation

When the program deadlocks it can be hard to know how much work was
performed thus far, for example did it deadlock after only a couple of
communication calls or after a long time, is there only 1 call of 1
type? etc.

## Technical Details

builds with PROFILE=ON can produce call statistics (slowing down
execution btw), this can be triggered from the gdb attachement to get
the stat dump.

## JIRA ID

<!-- If applicable, mention the JIRA ID resolved by this PR (Example:
Resolves SWDEV-12345). -->
<!-- Do not post any JIRA links here. -->

## Test Plan

modified a functional test to intentionally deadlock. build with Debug
and PROFILE=ON.

```
ROCSHMEM_DEBUG_LEVEL=trace:stats ~/ompi/bin/mpirun -n 2 tests/functional_tests/rocshmem_functional_tests -n 1 -a 26  & (sleep 2; ../scripts/debug/attach_deadlock_analysis.sh rocshmem_functional_tests --stats )
```

Output file
```
=== rocSHMEM Deadlock Analysis ===
Process(es): 845512
Total GPU wavefronts analyzed: 1
Unique backtrace groups: 1

--- Group 1 (1 wavefront(s)) ---
  WFs: (0,0,0)/0
  Backtrace:
    #0  0x00007ae55f5afcf0 in rocshmem::uncached_load<long volatile> (src=0x7ae55fc04008) at src/assembly.hpp:125
    #1  rocshmem::Context::test<long> (this=0x7ae552407000, ivars=0x7ae55fc04008, cmp=0, val=1) at src/context_tmpl_device.hpp:432
    #2  rocshmem::Context::wait_until<long> (this=0x7ae552407000, ivars=0x7ae55fc04008, cmp=0, val=1) at src/context_tmpl_device.hpp:224
    #3  rocshmem::IPCContext::internal_direct_barrier (this=0x7ae552407000, pe=0, PE_start=0, stride=1, n_pes=2, pSync=0x7ae55fc04000) at build/src/ipc/context_ipc_device_coll.cpp:44
    #4  0x00007ae55f5b7c24 in rocshmem::IPCContext::internal_sync_wg (this=0x7ae552407000, pe=0, PE_start=0, stride=1, PE_size=2, pSync=0x7ae55fc04000) at build/src/ipc/context_ipc_device_coll.cpp:115
    #5  0x00007ae55f63d018 in rocshmem::IPCContext::sync_all_wg (this=0x7ae552407000) at build/src/ipc/context_ipc_device_coll.cpp:168
    #6  0x00007ae55f63d558 in rocshmem::IPCContext::barrier_all_wg (this=0x7ae552407000) at build/src/ipc/context_ipc_device_coll.cpp:187
    #7  0x00007ae55f63dedc in rocshmem::Context::barrier_all_wg (this=0x7ae552407000) at build/src/context_device.cpp:151
    #8  0x00007ae55f63e33c in rocshmem::rocshmem_barrier_all_wg () at build/src/rocshmem_gpu.cpp:885
    #9  0x00007ae55f6437cc in WorkGroupPrimitiveTest (loop=1, skip=10, start_time=0x7ae552431000, end_time=0x7ae552432000, source=0x7ae56d200480 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr"..., dest=0x7ae56d300500 "1", size=1, type=WGPutTestType, ctx_type=4) at /home/abouteil/rocm-systems/projects/rocshmem/tests/functional_tests/workgroup_primitives.cpp:72
  [HINT] Waiting for remote PE memory update (barrier/sync or user rocshmem_wait_until). Check if the remote PE is alive and making progress. (at: #2  rocshmem::Context::wait_until<long> (this=0x7ae552407000, ivars=0x7ae55fc04008, cmp=0, val=1) at src/context_tmpl_device.hpp:224)

=== rocSHMEM Stats ===
  PE 0
  (counters reflect activity since process start)
  Device:
    quiet   1
    put_wg  704
  Host: (all zero)

=== Summary ===
  1 wavefront(s) inside rocSHMEM
  0 wavefront(s) in user code / other
```
Note the == rocshmem Stats == section contains the number of put and
quiet calls.


## Submission Checklist

- [ ] Look over the contributing guidelines at
https://github.com/ROCm/ROCm/blob/develop/CONTRIBUTING.md#pull-requests.

---------

Signed-off-by: Aurelien Bouteiller <aurelien.bouteiller@amd.com>
Signed-off-by: Aurelien Bouteiller <abouteil@amd.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
dlamd1dai referenced this pull request in dlamd1dai/rocm-systems Jun 29, 2026
300x, 350x, 355x machines.

Several issues combined to produce null/invalid pointer writes on MI350X (and could affect any MI300-class
machine in containers or with partial builds):

Host/device struct skew — ncclGinAnvilSdmaGPUContext gained layoutMagic, queueHandles, and sdmaDirty at the front.
Without layoutMagic set on the host, the device read wrong fields as signals → near-null pointer.
Fused OSS7 copy+signal (#7) — putSignal() on MI350X (__gfx950__) with an invalid remote signal VA.
Silent HIP failures — gin_anvil_factory logged errors but still returned success, leaving null queueHandles/sdmaDirty.
getOamId() throws — missing sysfs xgmi_physical_id in Docker broke Anvil connect on some machines.
readSignal on line 1 of GinAlltoAllKernel — generic readSignal dereferences GetSignalPtr with no null guard.

	modified:   projects/rccl/src/gin/gin_plugin_rocshmem_anvil.cc
	modified:   projects/rccl/src/include/nccl_device/gin/anvil_sdma/gin_anvil_sdma.h
	modified:   projects/rccl/src/include/nccl_device/gin/anvil_sdma/gin_anvil_sdma_device_host_common.h
	modified:   projects/rocshmem/src/sdma/anvil.cpp
	modified:   projects/rocshmem/src/sdma/gin_anvil_factory.cpp
dlamd1dai referenced this pull request in dlamd1dai/rocm-systems Jul 5, 2026
300x, 350x, 355x machines.

Several issues combined to produce null/invalid pointer writes on MI350X (and could affect any MI300-class
machine in containers or with partial builds):

Host/device struct skew — ncclGinAnvilSdmaGPUContext gained layoutMagic, queueHandles, and sdmaDirty at the front.
Without layoutMagic set on the host, the device read wrong fields as signals → near-null pointer.
Fused OSS7 copy+signal (#7) — putSignal() on MI350X (__gfx950__) with an invalid remote signal VA.
Silent HIP failures — gin_anvil_factory logged errors but still returned success, leaving null queueHandles/sdmaDirty.
getOamId() throws — missing sysfs xgmi_physical_id in Docker broke Anvil connect on some machines.
readSignal on line 1 of GinAlltoAllKernel — generic readSignal dereferences GetSignalPtr with no null guard.

	modified:   projects/rccl/src/gin/gin_plugin_rocshmem_anvil.cc
	modified:   projects/rccl/src/include/nccl_device/gin/anvil_sdma/gin_anvil_sdma.h
	modified:   projects/rccl/src/include/nccl_device/gin/anvil_sdma/gin_anvil_sdma_device_host_common.h
	modified:   projects/rocshmem/src/sdma/anvil.cpp
	modified:   projects/rocshmem/src/sdma/gin_anvil_factory.cpp
prasanna-amd added a commit that referenced this pull request Aug 20, 2026
… real headers

- Fix double-deref in KernelCh stop: combine per-channel and
  kernel-completion ref drops into a single atomic operation under the
  coll mutex, preventing negative refcount and use-after-free (#1)

- Add mutex to ProxyOpInfo, protect step timing accumulation from
  concurrent proxy thread writes (#2)

- Lock ProxyOp before memcpy into coll->proxyOps to prevent reading
  partially-written step data (#3)

- Move all pools (coll, proxyOp, proxyStep) from process-global statics
  into per-communicator acclCommContext, eliminating cross-comm pool
  starvation (#4)

- Fix fmt_size to show fractional values (1.5M instead of 1M) (#6)

- Fix bottleneck classifier denominator to use
  launch + max(kernel, proxy) instead of exec + launch, preventing
  percentages exceeding 100% due to kernel/proxy overlap (#7)

- Add --output flag to 'single' subcommand and clean up hasattr
  guard (#8)

- Switch output file from append to write mode to avoid stale data
  from PID reuse (#9)

- Replace vendored nccl/profiler.h with accl_shim.h that provides
  minimal types and includes RCCL's real profiler_v5.h; add
  CMakeLists.txt for in-tree builds (#10)
pvallem added a commit that referenced this pull request Aug 25, 2026
Defaulting --jobs to 4 broke the Jenkins precheckin Test stage. That pipeline
invokes the runner as

  test_runner.py -c configs/ci-precheckin.json --skip-mpi-check \
      --rerun-failed --stop-on-rerun-failure --verbose

with no --jobs, so validate_arg_combinations rejected --rerun-failed against the
new default and exited 1. Build #8 failed in 833 ms / 1405 ms / 2167 ms across
the three arch legs -- an argument-validation exit, not a test failure -- where
build #7 ran the identical command and passed in 428-1880 s.

Reverting rather than relaxing the guard, because on the evidence the default
bought nothing. The only current consumers of this runner are that precheckin
job and .github/workflows/ainic_test_runner.yml; CoCo has migrated off it (see
its own scripts/convert_test_runner_config.py, which reads the "legacy
test_runner/configs/*.json format"). ainic.json is now entirely serial_only, and
62 of ci-precheckin's 66 tests are single-process gtests that enumerate all 8
GPUs, so each fills the co-tenancy budget and runs alone regardless -- only 4 of
its tests could ever share the node. Concurrency stays available behind an
explicit --jobs N for anyone running a full functional config directly, which is
where the measured 13.7% (1 node) / 15.9% (2 nodes) actually came from.

Keeps two things from the reverted commit that stand on their own: -j/--jobs and
--max-parallel-gpus are now listed in the README options table, which they were
not before.

JIRA ID: AICOMRCCL-2053
prasanna-amd added a commit that referenced this pull request Aug 26, 2026
…ntegration

Add monotonic generation counter per pool slot to detect stale callbacks
from reclaimed collectives, resolving the 0==0 race in pool reclaim and
all callback-lifetime concerns (threads #4, #6, #8, #9).

Add atomic ref-count to acclCommContext so acclPluginFinalize defers free()
until all outstanding callbacks have drained (thread #2).

Wire accl plugin into the parent RCCL CMake build (thread #20), add
CXX_VISIBILITY_PRESET/VISIBILITY_INLINES_HIDDEN (thread #1), and bump
ACCL_MAX_CHANNELS from 64 to 256 (thread #11).

Fix acclShouldFinalize: nChannels==0 collectives (onerank path) finalize
immediately on coll stop; guard channelId against nChannels (thread #10, #12).
Free leaked ProxyOp when coll's proxyOpIndices is full (thread #13).
Rename firstCpuStart to firstKernelCpuStartUs for clarity (thread #14).

Fix warmup off-by-one (sn <= warmup → sn < warmup, thread #7), use
try/finally for output file handle (thread #15), fix test fixtures to
start at coll_sn=0 (thread #16), remove stale ACCL_PROFILER_WARMUP_ITERS
docs (thread #17), sync bottleneck categories with classify() (thread #18),
add NVIDIA Apache-2.0 header to accl_shim.h (thread #19).

Add tests: ProxyStep lifecycle, channel bounds, kernel timing assertions
(threads #3, #12, #21).
mch added a commit that referenced this pull request Aug 26, 2026
Add Test #6 -- when credit is available for every op in a PutSignalGroup,
ncclRmaProxyPollNonPersistDesc issues all of them in one pass, moves the group
descriptor to the in-progress queue, and advances the consumer index once.
Adds the PushPendingPutGroup fixture helper the group-path tests (#7/#8) build
on.

Co-authored-by: Pi Agent
bwelton added a commit that referenced this pull request Aug 27, 2026
…blished pipe first and is re-probed under the backstop
bwelton added a commit that referenced this pull request Aug 31, 2026
…blished pipe first and is re-probed under the backstop
bwelton added a commit that referenced this pull request Aug 31, 2026
…blished pipe first and is re-probed under the backstop
bwelton added a commit that referenced this pull request Sep 1, 2026
…blished pipe first and is re-probed under the backstop
bwelton added a commit that referenced this pull request Sep 1, 2026
…blished pipe first and is re-probed under the backstop
venkat1361 pushed a commit that referenced this pull request Sep 1, 2026
…10809)

## Summary
Addresses a 15-point static re-review of the KFD dispatch-log
signal-less path (on top of `review-fixes`). Each finding was evaluated
against the code and the prior design history; this PR **fixes the
genuine correctness/safety/resource issues** (potential misattribution,
UAF on terminal teardown, unbounded pairer-map growth, plus
FATAL-handling, env-race, and robustness items) and **documents the ones
intentionally left as accepted residuals or pre-existing**, with
rationale. `+365 / −49` across 9 files.

## Fixed

- **#4 (misattribution) — validate identity before claiming an
unknown-START EOP.** The unknown-START path in
`dispatch_hub.hpp::record_kernel_end` took the sole first-owner entry
with no timestamp check, and terminal-time validation ran only *after*
the entry was consumed/retired — so a stale EOP could claim a newer
dispatch's entry. Now rejects an EOP whose `end_ticks <= window.t_open`
(a kernel cannot end at/before its window opened; same GPU-tick domain
the known-START path already uses) **before** taking the entry, so a
rejected EOP consumes/retires nothing. Fail-first verified.
- **#3 + #2 (UAF) — the terminal fences are now truly terminal
(fail-closed).** `signal_less_fence_completions()` previously quiesced
visible work but did not stop the reader on success, so a still-PENDING
kernel could complete after the client's callback/buffer state
(detach/finalize, F23) or the HSA runtime (final `hsa_shut_down`, F24)
was freed. A new `signal_less_terminal_stop()` (factored from teardown)
latches disable → stops+joins the reader/processor → drains+ledgers
PENDING, and is called from the F23/F24 sites. Verified deadlock-free
(never joins its own task group, holds no lock across the join, joined
threads never block on the joiner) and 5/5 clean under a shutdown
watchdog. The existing `get_fini_status()` re-entry guard (the earlier
crash fix) is preserved.
- **#11 (unbounded growth) — hard size cap on the pairer START map.**
`pair_state::pending_starts` was bounded only by a 30-minute age timer.
Added `ROCPROFILER_KFD_DISPATCH_LOG_MAX_PENDING_STARTS` (default 2M,
shared reject-and-default parser) with oldest-first eviction (recurring
key exempted so the `ambiguous` latch is preserved).
- **#7 (coverage) + #10 (liveness) — FATAL handling.** FATAL now latches
admission and waits for the processor to consume the already-published
pipe **before** draining the hub (so a fatal session's final EOP and
healthy-GPU EOPs behind it aren't dropped), and the FATAL status is
re-probed while the empty-wake backstop is tripped (so a fatal stream
that produces no records is still detected).
- **#5 (robustness) — master switch is a strict fail-closed opt-in.**
`ROCPROFILER_KFD_DISPATCH_LOG_SIGNAL_LESS` now accepts only explicit
true values; anything else is disabled with a one-time warning (no throw
on malformed input).
- **#9 (arg-order) — deterministic GC-gate operand ordering.**
`gc_gate_open`'s two operands are read into named locals in the intended
order rather than relying on unspecified argument-evaluation order.
- **#12 (race) — env knobs primed at serialized init.** The
age/cap/quiesce/switch env reads are populated during reader start-up
rather than lazily on a worker thread.
- **#14(b) — fork child no longer hangs in `interposition_fini()`.** A
normal (non-exec) child now short-circuits `interposition_fini()` under
the existing `fork_stale()` guard, avoiding a wlock on a registry a
vanished parent thread may hold.

## Intentionally not changed (accepted residuals / design decisions /
pre-existing)

- **#1 — teardown coverage loss** (a kernel in flight at exit may emit
no record): the accepted D8/F1 coverage residual. The *UAF* variant of
this concern is #3, which is fixed.
- **#8 — equal-tick START/EOP**: the accepted D1 residual. The code
emits a **no-timing / zero-duration drop**, not a fabricated 1 ns; no
misattribution.
- **#9-main — GC gate "race"**: the copied-but-still-in-ring window is
the accepted **R10** residual (an EOP still in the ring is intentionally
not gated), and cap-eviction's bypass of the in-flight gate is D9's
documented coverage-loss residual. The operand-ordering nit is fixed
(#9-arg above); the residual is by design (coverage loss, never
misattribution).
- **#13 — cross-batch inversion**: the explicitly-accepted D1 residual
(coverage loss under queue churn, never misattribution). A cross-batch
reorder buffer is a larger design change weighed against measured
coverage impact, which the benchmarks do not show hitting.
- **#6 — completion-callback self-deadlock**: a **pre-existing**
reentrancy defect on the generic signal path (a client callback that
calls its own finalize). The new terminal-stop path was specifically
designed **not** to add another instance of it.
- **#14(a) — session mid-construction skipped by a concurrent fork**: a
child-lifetime resource leak (not a hang); the parent is unaffected and
the child drops it at exit. The "fix" would introduce a formal data race
on an `smap` pointer a vanished thread was mid-write on, to reclaim
memory about to be freed — not worth it. Left as-is.
- **#15 — eager arming on a registered (vs active) context**: an
efficiency consideration, not a correctness issue; arming stays gated on
a registered kernel-dispatch context.

## Known residuals in the fixes (documented)
- #4 adds no upper time bound (an implausibly-future EOP is still taken
and rejected by the finalizer as no-timing, never misattributed).
- #10 restores FATAL *detection* under the backstop; a *persistently
failing* status ioctl still isn't fail-closed (separate follow-up).
- #11 eviction is O(live) per over-cap insert (same tradeoff as the D9
cap; only reached under pathological EOP loss).

## Testing (MI350, host ROCm 7.2.1, build `fd06e1407c`)
- Build clean at the project warning level — **0 new warnings**.
- `ctest -L kfd-dlog` — **90/90 pass** (incl. 2 new tests: pairer-map
cap, strict opt-in).
- ThreadSanitizer, all 8 kfd-dlog suites — **90/90, zero reports**
(covers the terminal-stop join, FATAL drain-wait, GC-gate ordering).
- Shutdown crash/hang reproducer (1040), **5 runs under a watchdog — 5/5
clean, no hang, no crash** (the decisive check for the terminal-stop
rework).
- 1041-d (20k kernels ×3), 1031, 1041-a, 1041-c — all pass, no
attribution regression.
- graph-perf — **−44.21%** overhead reduction,
`register-refused=0`/block (no throughput regression).

## Tracking
JIRA ID: AIPROFSDK-1012 AIPROFSDK-1040 AIPROFSDK-1041
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants