HIP Streams to Queues Translation (#235)

* rocprofiler_stream_id_t: opaque handle for a stream

- e.g. HIP stream
- the same HIP stream may map to different HSA queues at different points in the application
- added to:
  - rocprofiler_buffer_tracing_hip_api_record_t
  - rocprofiler_buffer_tracing_memory_copy_record_t
  - rocprofiler_callback_tracing_hip_api_data_t
  - rocprofiler_callback_tracing_memory_copy_data_t
---------

Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>
Co-authored-by: Mark Meserve <mark.meserve@amd.com>
Co-authored-by: Elwazir, Ammar <Ammar.Elwazir@amd.com>
Co-authored-by: Ammar ELWazir <aelwazir@amd.com>
Co-authored-by: Jakaraddi, Manjunath <Manjunath.Jakaraddi@amd.com>
Co-authored-by: Bhardwaj, Gopesh <Gopesh.Bhardwaj@amd.com>
Co-authored-by: Nagaraj, Sriraksha <Sriraksha.Nagaraj@amd.com>
Co-authored-by: U, Srihari <Srihari.U@amd.com>
Co-authored-by: Madsen, Jonathan <Jonathan.Madsen@amd.com>
Co-authored-by: Welton, Benjamin <Benjamin.Welton@amd.com>
Co-authored-by: Benjamin Welton <ben@amd.com>
Co-authored-by: Indic, Vladimir <Vladimir.Indic@amd.com>
Co-authored-by: Benjamin Welton <bewelton@amd.com>

[ROCm/rocprofiler-sdk commit: ccd1e54293]
This commit is contained in:
50 files changed
+1812 -220

No files matched your search

@@ -41,4 +41,5 @@ add_subdirectory(rocjpeg-trace)
if(TARGET att_decoder_testing)
add_subdirectory(advanced-thread-trace)
endif()
add_subdirectory(hip-stream-display)
add_subdirectory(agent-index)
@@ -0,0 +1,59 @@
#
#
#
cmake_minimum_required(VERSION 3.21.0 FATAL_ERROR)
project(
rocprofiler-tests-rocprofv3-hip-stream-display
LANGUAGES CXX
VERSION 0.0.0)
find_package(rocprofiler-sdk REQUIRED)
find_package(rocDecode)
rocprofiler_configure_pytest_files(CONFIG pytest.ini COPY validate.py conftest.py)
string(REPLACE "LD_PRELOAD=" "ROCPROF_PRELOAD=" PRELOAD_ENV
"${ROCPROFILER_MEMCHECK_PRELOAD_ENV}")
set(hip-stream-display-env "${PRELOAD_ENV}")
add_test(
NAME rocprofv3-test-hip-stream-display-execute
COMMAND
$<TARGET_FILE:rocprofiler-sdk::rocprofv3> --kernel-rename -d
${CMAKE_CURRENT_BINARY_DIR}/%tag%-trace -o out --output-format json pftrace
--log-level env -- $<TARGET_FILE:transpose>)
set_tests_properties(
rocprofv3-test-hip-stream-display-execute
PROPERTIES TIMEOUT
45
LABELS
"integration-tests"
ENVIRONMENT
"${hip-stream-display-env}"
FAIL_REGULAR_EXPRESSION
"threw an exception"
DISABLED
$<NOT:$<TARGET_EXISTS:transpose>>)
add_test(
NAME rocprofv3-test-hip-stream-display-validate
COMMAND
${Python3_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/validate.py --json-input
${CMAKE_CURRENT_BINARY_DIR}/hip-stream-display/out_results.json --pftrace-input
${CMAKE_CURRENT_BINARY_DIR}/hip-stream-display/out_results.pftrace)
set_tests_properties(
rocprofv3-test-hip-stream-display-validate
PROPERTIES TIMEOUT
45
LABELS
"integration-tests"
DEPENDS
rocprofv3-test-hip-stream-display-execute
FAIL_REGULAR_EXPRESSION
"AssertionError"
DISABLED
$<NOT:$<TARGET_EXISTS:transpose>>)
@@ -0,0 +1,42 @@
#!/usr/bin/env python3
import csv
import json
import os
import pytest
from rocprofiler_sdk.pytest_utils.dotdict import dotdict
from rocprofiler_sdk.pytest_utils import collapse_dict_list
from rocprofiler_sdk.pytest_utils.perfetto_reader import PerfettoReader
def pytest_addoption(parser):
parser.addoption(
"--json-input",
action="store",
default="hip-stream-display/out_results.json",
help="Input JSON",
)
parser.addoption(
"--pftrace-input",
action="store",
default="hip-stream-display/out_results.pftrace",
help="Input pftrace file",
)
@pytest.fixture
def json_data(request):
filename = request.config.getoption("--json-input")
if not os.path.isfile(filename):
return pytest.skip("stream tracing unavailable")
with open(filename, "r") as inp:
return dotdict(collapse_dict_list(json.load(inp)))
@pytest.fixture
def pftrace_data(request):
filename = request.config.getoption("--pftrace-input")
if not os.path.isfile(filename):
return pytest.skip("stream tracing unavailable")
return PerfettoReader(filename).read()[0]
@@ -0,0 +1,5 @@
[pytest]
addopts = --durations=20 -rA -s -vv
testpaths = validate.py
pythonpath = @ROCPROFILER_SDK_TESTS_BINARY_DIR@/pytest-packages
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
import sys
import pytest
import json
from collections import defaultdict
# helper function
def node_exists(name, data, min_len=1):
assert name in data
assert data[name] is not None
if isinstance(data[name], (list, tuple, dict, set)):
assert len(data[name]) >= min_len
def get_operation(record, kind_name, op_name=None):
for idx, itr in enumerate(record["strings"]["buffer_records"]):
if kind_name == itr["kind"]:
if op_name is None:
return idx, itr["operations"]
else:
for oidx, oname in enumerate(itr["operations"]):
if op_name == oname:
return oidx
return None
def test_stream_trace(json_data):
data = json_data["rocprofiler-sdk-tool"]
buffer_records = data["buffer_records"]
kernel_dispatch_data = buffer_records["kernel_dispatch"]
memory_copies_data = buffer_records["memory_copies"]
assert len(kernel_dispatch_data) > 0
assert len(memory_copies_data) > 0
# Expect stream ids to be set to 1 or 2 for transpose executable
expected_stream_ids = set((1, 2))
# check buffering data
for titr in (kernel_dispatch_data, memory_copies_data):
for node in rocdecode_data:
assert "size" in node
assert "kind" in node
assert "operation" in node
assert "correlation_id" in node
assert "end_timestamp" in node
assert "start_timestamp" in node
assert "thread_id" in node
assert "_stream_id" in node
assert node.size > 0
assert node.thread_id > 0
assert node.start_timestamp > 0
assert node.end_timestamp > 0
assert node.start_timestamp < node.end_timestamp
assert node._stream_id.handle in expected_stream_ids
def test_perfetto_data(pftrace_data, json_data):
import rocprofiler_sdk.tests.rocprofv3 as rocprofv3
assert pftrace_data != None
rocprofv3.test_perfetto_data(
pftrace_data,
json_data,
("kernel", "memory_copy"),
)
if __name__ == "__main__":
exit_code = pytest.main(["-x", __file__] + sys.argv[1:])
sys.exit(exit_code)
@@ -137,7 +137,7 @@ def test_kernel_trace(json_data):
external_corr_id = dispatch["correlation_id"]["external"]
assert external_corr_id > 0
kernel_rename = get_kernel_rename(external_corr_id)
kernel_rename = get_kernel_rename(dispatch.kernel_rename_val)
assert kernel_rename is not None, f"{dispatch}"
assert kernel_rename != kernel_name, f"{dispatch}"
assert (
@@ -75,6 +75,7 @@ def test_kernel_trace(json_data):
def get_kernel_rename(corr_id):
for itr in data.strings.correlation_id.external:
print(itr)
if itr.key == corr_id:
return itr.value
return None
@@ -113,7 +114,7 @@ def test_kernel_trace(json_data):
external_corr_id = dispatch["correlation_id"]["external"]
assert external_corr_id > 0
kernel_rename = get_kernel_rename(external_corr_id)
kernel_rename = get_kernel_rename(dispatch.kernel_rename_val)
assert kernel_rename is not None, f"{dispatch}"
assert kernel_rename != kernel_name, f"{dispatch}"
assert (