CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
143 lines
5.8 KiB
Python
143 lines
5.8 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# MIT License
|
|
#
|
|
# Copyright (c) 2024-2025 Advanced Micro Devices, Inc. All rights reserved.
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
# THE SOFTWARE.
|
|
|
|
"""JSON-output smoke tests for HIP graph attribution.
|
|
|
|
Validates that rocprofv3's --output-format json carries through:
|
|
- graph_exec_id / graph_node_id at the top level of KERNEL_DISPATCH records
|
|
(siblings of stream_id, populated by the tool-layer ext record).
|
|
- HIP_GRAPH summary records with the full field set.
|
|
|
|
The CSV validator (validate.py) does the heavier semantic checking.
|
|
"""
|
|
|
|
import sys
|
|
import pytest
|
|
|
|
|
|
def _buffer_records(json_input_data):
|
|
return json_input_data["rocprofiler-sdk-tool"]["buffer_records"]
|
|
|
|
|
|
def test_kernel_dispatch_records_have_graph_fields(json_input_data):
|
|
"""Every KERNEL_DISPATCH JSON record must expose graph_exec_id and
|
|
graph_node_id at the top level (siblings of stream_id, not under
|
|
dispatch_info)."""
|
|
kernel_dispatch = _buffer_records(json_input_data)["kernel_dispatch"]
|
|
assert len(kernel_dispatch) > 0, "no kernel_dispatch records in JSON"
|
|
for rec in kernel_dispatch:
|
|
assert "graph_exec_id" in rec, f"record missing top-level graph_exec_id: {rec}"
|
|
assert "graph_node_id" in rec, f"record missing top-level graph_node_id: {rec}"
|
|
|
|
|
|
def test_some_kernel_dispatches_have_nonzero_graph_exec_id(
|
|
json_input_data,
|
|
expected_iterations,
|
|
expected_execs,
|
|
expected_nodes_per_launch,
|
|
):
|
|
"""The graph dispatches in the workload must carry nonzero graph_exec_id.
|
|
Count should match (iterations*execs + 1) * nodes_per_launch — the +1 is
|
|
the one extra successful exec_b launch after the failed launch."""
|
|
kernel_dispatch = _buffer_records(json_input_data)["kernel_dispatch"]
|
|
graph_rows = [r for r in kernel_dispatch if int(r["graph_exec_id"]) != 0]
|
|
expected_launches = expected_iterations * expected_execs + 1
|
|
expected = expected_launches * expected_nodes_per_launch
|
|
assert (
|
|
len(graph_rows) == expected
|
|
), f"expected {expected} graph-attributed dispatches in JSON, got {len(graph_rows)}"
|
|
|
|
|
|
def test_graph_launch_records_present(
|
|
json_input_data,
|
|
expected_iterations,
|
|
expected_execs,
|
|
):
|
|
"""HIP_GRAPH summary records must appear in the JSON output's
|
|
buffer_records.graph_launch array. One per *successful* hipGraphLaunch."""
|
|
buffer_records = _buffer_records(json_input_data)
|
|
assert (
|
|
"hip_graph" in buffer_records
|
|
), f"buffer_records missing 'hip_graph' key; got {list(buffer_records.keys())}"
|
|
graph_launch = buffer_records["hip_graph"]
|
|
expected_launches = expected_iterations * expected_execs + 1
|
|
assert (
|
|
len(graph_launch) == expected_launches
|
|
), f"expected {expected_launches} HIP_GRAPH records, got {len(graph_launch)}"
|
|
|
|
|
|
def test_graph_launch_record_shape(json_input_data, expected_nodes_per_launch):
|
|
"""Each HIP_GRAPH record carries the expected field set with sane values."""
|
|
graph_launch = _buffer_records(json_input_data)["hip_graph"]
|
|
required_fields = (
|
|
"size",
|
|
"kind",
|
|
"operation",
|
|
"thread_id",
|
|
"correlation_id",
|
|
"start_timestamp",
|
|
"end_timestamp",
|
|
"agent_id",
|
|
"queue_id",
|
|
"graph_exec_id",
|
|
"kernel_dispatch_count",
|
|
)
|
|
for rec in graph_launch:
|
|
for f in required_fields:
|
|
assert f in rec, f"HIP_GRAPH record missing '{f}': {rec}"
|
|
# graph_exec_id is a typed handle ({"handle": N}) on the HIP_GRAPH record.
|
|
assert (
|
|
int(rec["graph_exec_id"]["handle"]) > 0
|
|
), f"graph_exec_id must be nonzero: {rec}"
|
|
assert (
|
|
int(rec["kernel_dispatch_count"]) == expected_nodes_per_launch
|
|
), f"kernel_dispatch_count {rec['kernel_dispatch_count']} != {expected_nodes_per_launch}: {rec}"
|
|
assert int(rec["end_timestamp"]) >= int(rec["start_timestamp"])
|
|
assert (
|
|
int(rec["correlation_id"]["internal"]) > 0
|
|
), f"HIP_GRAPH must have nonzero internal correlation_id: {rec}"
|
|
|
|
|
|
def test_graph_launch_exec_ids_match_kernel_dispatch_records(json_input_data):
|
|
"""The set of graph_exec_ids on HIP_GRAPH records must equal the set
|
|
of nonzero graph_exec_ids on the KERNEL_DISPATCH records — the two views
|
|
must agree."""
|
|
buffer_records = _buffer_records(json_input_data)
|
|
# HIP_GRAPH carries graph_exec_id as a typed handle; kernel_dispatch ext records
|
|
# carry it as a raw uint64.
|
|
launch_ids = {int(r["graph_exec_id"]["handle"]) for r in buffer_records["hip_graph"]}
|
|
kernel_ids = {
|
|
int(r["graph_exec_id"])
|
|
for r in buffer_records["kernel_dispatch"]
|
|
if int(r["graph_exec_id"]) != 0
|
|
}
|
|
assert (
|
|
launch_ids == kernel_ids
|
|
), f"HIP_GRAPH ids {launch_ids} != graph-KERNEL_DISPATCH ids {kernel_ids}"
|
|
|
|
|
|
if __name__ == "__main__":
|
|
exit_code = pytest.main(["-x", __file__] + sys.argv[1:])
|
|
sys.exit(exit_code)
|