Repository navigation
Conversation
9b94390 to
9c9c52e
Compare
vlaindic
left a comment
There was a problem hiding this comment.
1st part of the review commends impacting a sample
- Update license years from 2025 to 2026 in all sample files - Increase buffer size from 8KB to 4MB - Set watermark to 3/4 of buffer (was 1/4) - Memoize arbiter field names in a LUT on tool_agent_info to avoid per-sample name API calls in the buffer callback - Extract print_sample_common_fields template helper for shared V1/V2 record fields (pc, timestamp, exec, workgroup, wave, chiplet, dispatch_id, correlation_id) - Pass tool_agent_info* as buffer client_data so the callback has direct access to per-agent arbiter field IDs and name map without iterating the global agent list (recommended policy, documented) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
5f7bdda to
d0c1724
Compare
d0c1724 to
2de30d8
Compare
2de30d8 to
7034f2f
Compare
da4f8b9 to
7a8d666
Compare
- Update license years from 2025 to 2026 in all sample files - Increase buffer size from 8KB to 4MB - Set watermark to 3/4 of buffer (was 1/4) - Memoize arbiter field names in a LUT on tool_agent_info to avoid per-sample name API calls in the buffer callback - Extract print_sample_common_fields template helper for shared V1/V2 record fields (pc, timestamp, exec, workgroup, wave, chiplet, dispatch_id, correlation_id) - Pass tool_agent_info* as buffer client_data so the callback has direct access to per-agent arbiter field IDs and name map without iterating the global agent list (recommended policy, documented) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
7a8d666 to
8d56620
Compare
8d56620 to
a9de24a
Compare
- Update license years from 2025 to 2026 in all sample files - Increase buffer size from 8KB to 4MB - Set watermark to 3/4 of buffer (was 1/4) - Memoize arbiter field names in a LUT on tool_agent_info to avoid per-sample name API calls in the buffer callback - Extract print_sample_common_fields template helper for shared V1/V2 record fields (pc, timestamp, exec, workgroup, wave, chiplet, dispatch_id, correlation_id) - Pass tool_agent_info* as buffer client_data so the callback has direct access to per-agent arbiter field IDs and name map without iterating the global agent list (recommended policy, documented) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
a9de24a to
0df8262
Compare
vlaindic
left a comment
There was a problem hiding this comment.
PC Sampling v2 API — Code Review
8 findings: 4 IMPORTANT, 4 SUGGESTIONS. No CRITICAL.
⚠️ IMPORTANT
1. Verify runtime feature gating for v2 entry points
The ROCPROFILER_SDK_EXPERIMENTAL annotation on configure_pc_sampling_service_v2 and query_agent_configurations_v2 is compile-time only. Runtime gating via ROCPROFILER_PC_SAMPLING_BETA_ENABLED is what actually protects users from picking up the experimental surface by accident.
Action: Confirm the env-flag check is enforced at both v2 API entry points, or add it.
2. is_invalid_sample<v2> / <v4> may drop legitimately predicated waves
In parser/correlation.hpp, the V2 and V4 specializations treat timestamp == 0 && exec_mask == 0 as the invalid sentinel. A legitimately predicated wave can have exec_mask == 0, which would silently drop a valid stochastic sample.
Action: Either use a dedicated sentinel field, or document the HW guarantee that valid samples always carry a non-zero timestamp and drop the exec_mask == 0 term.
3. ROCP_FATAL on wave_id mismatch terminates the entire process
In the GFX1250 copySample path, a wave_id mismatch triggers ROCP_FATAL. A parser-level sanity check disagreement on a single record should not be a process-killer — one malformed record from HW would take down all consumers in the process.
Action: Replace ROCP_FATAL with ROCP_ERROR (or ROCP_WARNING) and mark the record invalid via mark_sample_invalid so the buffer pipeline continues.
4. _get_parse_func_for_record_kind nullptr return must be checked
_get_parse_func_for_record_kind<GFXIP> returns nullptr for V3/V4 on non-GFX1250 architectures. If the caller in parse() does not null-check before dispatching the function pointer, this is a segfault on a misconfigured client.
Action: Verify the call site in parser/pc_record_interface.cpp::parse() null-checks the returned function pointer; otherwise add the check and return an explicit error status (e.g., ROCPROFILER_STATUS_ERROR_INCOMPATIBLE_KERNEL or equivalent).
💡 SUGGESTIONS
5. Dead code in query_agent_configurations_v2
In pc_sampling.cpp:
- Unused variable
preferred_endwith(void) preferred_end; - Empty conditional:
if (!is_required) { /* For soft preferences ... but include all */ }
Action: Delete the dead variable and either implement or delete the empty conditional.
6. Redundant zero-init pattern in parser/translation.hpp
rocprofiler_pc_sampling_record_v2_t invalid{};
std::memset(&invalid, 0, sizeof(invalid));The {} value-initializes the struct to zero already. The memset is redundant.
Action: Drop the memset.
7. Doc inconsistencies — V0-V5 / V3-V5 references in comments
Comments reference "V3-V5 reserved" and "V0-V5", but the enum defines only V0-V4.
Action: Reconcile comments to match the enum (V0-V4).
8. _get_parse_func_for_record_kind docstring does not document nullptr return
The docstring does not state that the function returns nullptr for V3/V4 on non-GFX1250 architectures. Callers cannot tell from the signature that null-checking is required.
Action: Add a @return nullptr if the requested record kind is not supported by the GFXIP line to the docstring.
Thanks for the careful review! For findings 1, 2, and 4, I believe the 1. Runtime env gating at v2 entry pointsBoth v2 API entry points call
The helper itself reads 2.
|
- Update license years from 2025 to 2026 in all sample files - Increase buffer size from 8KB to 4MB - Set watermark to 3/4 of buffer (was 1/4) - Memoize arbiter field names in a LUT on tool_agent_info to avoid per-sample name API calls in the buffer callback - Extract print_sample_common_fields template helper for shared V1/V2 record fields (pc, timestamp, exec, workgroup, wave, chiplet, dispatch_id, correlation_id) - Pass tool_agent_info* as buffer client_data so the callback has direct access to per-agent arbiter field IDs and name map without iterating the global agent list (recommended policy, documented) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
0df8262 to
ff347ad
Compare
…parser Refactors the v2 PC sampling path so the sampling method (host-trap vs stochastic) drives record parsing, and makes invalid-sample delivery an explicit, caller-controlled policy. Addresses PR #4548 review comments. API & validation (pc_sampling.h, pc_sampling.cpp): - Document that REQUIRE_HOST_TRAP combined with a stochastic-only record kind (V2/V4) is rejected, and that PREFER_HOST_TRAP is silently honored as stochastic for stochastic-only records. Mirror both in the configure and query docs. - Add validate_record_kinds_against_flags() rejecting REQUIRE_HOST_TRAP + V2/V4, wired into both configure and query after the existing validators. - Add is_stochastic_only_record_kind() and honor the PREFER_HOST_TRAP soft-fallback in method inference. - Suppress the host-trap fallback (configure) and force a hard method filter (query) for stochastic-only records, so an unsatisfiable request surfaces honestly instead of configuring an unparseable session. Parser (pc_record_interface.*, translation.hpp, correlation.hpp): - Make PCSamplingParserContext stateless w.r.t. v2 config: drop the _requested_record_kind field, its setter, and is_v2(). The requested record kind and deliver-invalid flag are passed per parse() call. - Dispatch on (record_kind, method); template copySample, is_invalid_sample, add_upcoming_samples, and _parse on the method. Add stochastic copySample specializations for the host-trap-layout records (V0/V1/V3). - Collapse the four emplace_records_in_buffer variants into one method-aware template with a record_kind_for<> trait and a runtime deliver_invalid argument; drop invalid samples unless opted in. Wiring (service.cpp, hsa_adapter.cpp, types.hpp): - Capture deliver_invalid on PCSAgentSession at configure time and forward it, together with the requested record kind, to parser->parse(). Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Allow a client to request only INVALID_SAMPLE records (no valid version
kind) — useful for debugging. The request set is now passed to the parser,
which derives the carrier record kind and the deliver/drop policy from it.
Parser (pc_record_interface.*):
- parse() takes the requested_record_kinds vector instead of a single
resolved record kind + deliver_invalid bool. It derives the kind to
parse, deliver_invalid, and a new deliver_valid flag:
- empty set -> legacy v1 method dispatch;
- one V0..V4 kind -> parse that kind, deliver invalids iff requested;
- INVALID_SAMPLE -> parse with a V0 carrier, deliver only invalids
alone and drop the valid carriers.
- Thread deliver_valid through _parse -> generate_upcoming_pc_record ->
emplace_records_in_buffer (runtime arg, not a template axis), which now
drops valid records when deliver_valid is false.
Wiring (service.cpp, hsa_adapter.cpp, types.hpp):
- Forward PCSAgentSession::requested_record_kinds verbatim to parse().
- Drop the now-redundant deliver_invalid field and the get_valid_record_kind
/ wants_invalid_samples helpers; the derivation lives in parse().
API (pc_sampling.cpp):
- Document that INVALID-only requests need no special-casing in configure
or query: method selection follows the normal flag/stochastic-default +
fallback path, and the carrier decision is a parse-time concern.
Notes: under host-trap, is_invalid_sample is a compile-time false, so an
INVALID-only host-trap session currently yields an empty stream; this is
intentional and extensible if host-trap ever flags invalid samples.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
The following comment addresses the my review from here: #4548 (review) Thanks for the thorough review. All of the implementation-level findings are now addressed across a few commits on this branch (the sample-file comments — Method is now threaded through the parserSeveral findings shared one root cause: the parser hardcoded the host-trap vs stochastic assumption per record kind ("the rest of this code assumes V0, V1, and V3 are only used for host-trap", "no one prevents the user from picking V0 and stochastic", "I suppose we're missing v3 and v4?").
Flag / record method conflicts are validatedAddresses "what would happen if there's a conflict between a flag and a record in terms of method?" and the host-trap-with-stochastic-record scenario.
Invalid-sample handling unified + INVALID-only delivery
Specific findings
Answers to the open questions
Intentionally left as-is (suggestions)
VerificationClean build; the
|
Follow-up fixes from the PR #4548 review, covering the implementation (not the sample files): - correct_pc_address is now method-aware. The GFX950 mid-macro correction reads the stochastic-only perf_snapshot_data1 register, so applying it to a host-trap sample would alias reserved bytes and corrupt a valid PC. Only the STOCHASTIC GFX950 specializations apply it; added V0/V1 (and kept V2 / stochastic_v0) so all stochastic record layouts get corrected, while host-trap falls through to the no-op default. - Replace assert(buffer != nullptr) in the alloc() specializations with ROCP_FATAL_IF, so the null-output contract is enforced in release builds too. - Move <optional> to the standard-library include group in pc_sampling.cpp. - Align infer_method_from_record_kinds_and_flags' docstring with the pc_sampling.h compatibility matrix (V0-V4 + INVALID-only, prefer/fallback semantics). Verified: clean build, pc-sampling-v2 sample delivers samples with zero unexpected drops, and all 13 parser unit tests pass (incl. GFX950 mid-macro). Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Addresses the sample-focused review for PR #4548, plus one supporting library fix the sample relies on. Sample (samples/pc_sampling_v2/): - client.cpp: reorder headers (project before SDK); replace assert() with utils::pcs_assert; remove the dead setup()/shutdown() (the client is a preloaded library, so rocprofiler auto-discovers rocprofiler_configure). - main.cpp: drop the run_migrate / run_scratch workloads and everything they exclusively used (test_page_migrate, test_kern_*), keeping the transpose benchmark. - pcs.cpp/.hpp: manage gpu_agents as a heap pointer with a get_gpu_agents() accessor (created in init(), freed in fini()), mirroring buffer_ids, to avoid static-destruction-order issues. - pcs.cpp: query snapshot ext fields unconditionally and treat an empty result as "not applicable" rather than special-casing host-trap; factor the duplicated V2/V4 snapshot_information and ext_data printing into print_snapshot_information() / print_snapshot_ext_data() helpers; document that INVALID_SAMPLE is method-agnostic at the query/configure sites; note the top-down record-discovery assumption. Library (pc_sampling.cpp, pc_sampling.h): - rocprofiler_pc_sampling_query_snapshot_ext_fields now honors its documented contract: record kinds with no snapshot information (host-trap V0/V1/V3 and INVALID_SAMPLE) return SUCCESS with an empty field list instead of INVALID_ARGUMENT; unrecognized kinds are still rejected. Header doc updated to match. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
Reply to the previous sample review (#4548 (review)) Thanks for the detailed pass over the sample. All comments are addressed in the latest commit client.cpp
main.cpp
pcs.cpp / pcs.hpp
VerificationClean build;
|
There was a problem hiding this comment.
Pull request overview
This PR refactors the v2 PC sampling API to be ABI-stable and extensible across GPU architectures. It introduces versioned record kinds (V0–V4), a packed ext_data field with query/extract helpers, and API flags that decouple method selection from record layout. The legacy v1 entry points are preserved; v2 dispatch is added alongside via a separate parser parameter and per-(record_kind, method) template specializations.
Changes:
- New public v2 API in
pc_sampling.h(*_configure_service_v2,*_query_agent_configurations_v2,*_query_snapshot_ext_fields,*_extract_snapshot_ext_field_values) plus new record/enum types. - Parser refactor:
copySample,correct_pc_address,is_invalid_sample, and_parseare now templated on(GFXIP, RecordT, Method);parse()takes arequested_record_kindsset and applies a deliver/drop policy. - New
pc_sampling_v2sample demonstrating the top-down record-kind discovery, ext-field extraction, and buffer callback decoding.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| source_code_formatter.sh | New developer-local formatter helper script (appears unrelated). |
| projects/rocprofiler-sdk/source/include/rocprofiler-sdk/pc_sampling.h | Adds v2 API surface, record kinds V0–V4, snapshot ext-field enum, query/extract entry points. |
| projects/rocprofiler-sdk/source/include/rocprofiler-sdk/fwd.h | Adds V0–V4 record-kind enum values. |
| projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/enum_string.hpp | Registers new record-kind labels and updates the LAST static_assert. |
| projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling.cpp | Implements v2 configure/query/extract entry points, flag/record validation, method inference, ext-field tables. |
| projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/service.{hpp,cpp} | Adds configure_pc_sampling_service_v2. |
| projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/types.hpp | Tracks requested_record_kinds on PCSAgentSession. |
| projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp | Forwards requested_record_kinds to parser->parse(). |
| projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/parser/pc_record_interface.{hpp,cpp} | Method-aware _parse, v2 alloc specializations, record-kind→dispatch table, deliver/drop policy. |
| projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/parser/translation.hpp | Adds (RecordT, Method)-templated copySample/correct_pc_address specializations and ext_data packing helpers per GFX. |
| projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/parser/correlation.hpp | Adds is_invalid_sample/mark_sample_invalid traits and Method-templated add_upcoming_samples. |
| projects/rocprofiler-sdk/samples/pc_sampling_v2/* | New v2 sample (client, pcs, utils, main, CMakeLists). |
| projects/rocprofiler-sdk/samples/CMakeLists.txt | Adds the new sample subdirectory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| bool | ||
| is_record_kind_supported_on_agent(rocprofiler_pc_sampling_record_kind_t kind, | ||
| const rocprofiler_agent_t* agent) | ||
| { | ||
| if(kind == ROCPROFILER_PC_SAMPLING_RECORD_V3_SAMPLE || | ||
| kind == ROCPROFILER_PC_SAMPLING_RECORD_V4_SAMPLE) | ||
| { | ||
| auto gfxip_major = (agent->gfx_target_version / 10000) % 100; | ||
| return gfxip_major == 12; | ||
| } | ||
| return true; | ||
| } |
| * @brief Check whether a record kind is supported on the given agent's architecture. | ||
| * | ||
| * V3 and V4 record kinds require GFX12+ (gfxip_major == 12). | ||
| * All other record kinds (V0, V1, V2, INVALID_SAMPLE) are universally supported. |
| template <> | ||
| inline void | ||
| mark_sample_invalid<rocprofiler_pc_sampling_record_v0_t>( | ||
| rocprofiler_pc_sampling_record_v0_t& sample) | ||
| { | ||
| std::memset(&sample, 0, sizeof(sample)); | ||
| } | ||
|
|
||
| template <> | ||
| inline void | ||
| mark_sample_invalid<rocprofiler_pc_sampling_record_v1_t>( | ||
| rocprofiler_pc_sampling_record_v1_t& sample) | ||
| { | ||
| std::memset(&sample, 0, sizeof(sample)); | ||
| } | ||
|
|
||
| template <> | ||
| inline void | ||
| mark_sample_invalid<rocprofiler_pc_sampling_record_v2_t>( | ||
| rocprofiler_pc_sampling_record_v2_t& sample) | ||
| { | ||
| std::memset(&sample, 0, sizeof(sample)); | ||
| } | ||
|
|
||
| template <> | ||
| inline void | ||
| mark_sample_invalid<rocprofiler_pc_sampling_record_v3_t>( | ||
| rocprofiler_pc_sampling_record_v3_t& sample) | ||
| { | ||
| std::memset(&sample, 0, sizeof(sample)); | ||
| } | ||
|
|
||
| template <> | ||
| inline void | ||
| mark_sample_invalid<rocprofiler_pc_sampling_record_v4_t>( | ||
| rocprofiler_pc_sampling_record_v4_t& sample) | ||
| { | ||
| std::memset(&sample, 0, sizeof(sample)); | ||
| } |
Pure formatting pass over the PC sampling v2 changes to satisfy the CI FORMAT jobs (clang-format 11, cmake-format with default width). No functional changes. Also adds source_code_formatter.sh, a helper that runs the same tools and invocation as CI (clang-format -style=file; cmake-format with no config), so formatting can be applied/checked locally without pre-commit fetching a mismatched clang-format version. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
5281a78 to
9dbd16d
Compare
|
This pull request has been inactive for 25 days and will be marked as stale. If you would like to keep this PR open, please:
This PR will be automatically closed in 5 days if no further activity occurs. |
|
This pull request has been automatically closed due to inactivity (30 days with no updates). If you'd like to continue working on this, feel free to reopen the PR or create a new one. |
❌ 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 |
|
This pull request has been inactive for 25 days and will be marked as stale. If you would like to keep this PR open, please:
This PR will be automatically closed in 5 days if no further activity occurs. |
|
This pull request has been automatically closed due to inactivity (30 days with no updates). If you'd like to continue working on this, feel free to reopen the PR or create a new one. |



Motivation
This PR redesigns the v2 PC sampling API to be ABI backward-compatible and easily extensible as new GPU architectures introduce additional PC sampling details. The old API exposed per-architecture stochastic snapshot fields through explicit bitfields (arbiter state, dual issue, etc.), which required breaking ABI changes every time a new field appeared. The new approach replaces explicit bitfields with versioned record types (V0 through V4) of increasing detail, a packed ext_data field for snapshot information decoded through query/extract helpers, and API flags that decouple method selection from record layout. Record kinds are gated at the API level so unsupported versions are cleanly rejected per-architecture, allowing client code to iterate from the most detailed record kind downward and gracefully fall back to what the hardware supports. Together, these changes ensure that future architectures can add new fields, counters, or cluster information without breaking existing tools compiled against earlier versions of the SDK.
Technical Details
This work requires refactoring of the whole PC sampling service. To ease PR reviewing process,
we decided to only propose API updates, implementation and a sample. Unit and integration tests will be added later.
PC sampling not supported on the GFX11 yet, and the TODOs remain from previous work.
Pending work to support clusters on the ROCr side blocks clusters support in this PR, that's why the fields are zero initialized.
JIRA ID
AIPROFSDK-178
Test Plan
Will be provided by forthcoming PRs.
Test Result
Please check section above.
Submission Checklist