2
0

Test using HIP Graphs (#835)

* Test using hip graphs

* Remove assert for api_end < async_end

* Update rocprofv3/tracing-hip-in-libraries::test_api_trace

* Update rocprofv3/tracing-hip-in-libraries::test_api_trace

* Increase rocprofv3-test-trace-hip-in-libraries-validate timeout

* Update rocprofv3/tracing-hip-in-libraries::test_api_trace

* Remove submit retry

* Update rocprofv3/tracing-hip-in-libraries::test_api_trace

* Increase rocprofv3-test-trace-hip-in-libraries-validate timeout

* Update lib/common/container/record_header_buffer.hpp

- minor tweaks

* Update lib/rocprofiler-sdk/buffer.hpp

- tweak ROCPROFILER_BUFFER_POLICY_LOSSLESS flush behavior

* Increase rocprofv3-test-trace-hip-in-libraries-validate timeout

* Update rocprofv3/tracing-hip-in-libraries::test_api_trace

* Revert rocprofv3-test-trace-hip-in-libraries-validate timeout

* Update run-ci.py

- RETRY_COUNT set to zero

[ROCm/rocprofiler-sdk commit: 1f96593b4f]
Este cometimento está contido em:
Jonathan R. Madsen
2024-05-07 15:10:22 -05:00
cometido por GitHub
ascendente ea56f79495
cometimento 4cd076b9cc
14 ficheiros modificados com 635 adições e 23 eliminações
@@ -257,10 +257,10 @@ record_header_buffer::emplace(uint64_t _hash, Tp& _v)
// placement new
new(_addr) Tp{_v};
rocprofiler_record_header_t record = {};
record.hash = _hash;
record.payload = _addr;
m_headers.at(idx) = record;
auto record = rocprofiler_record_header_t{};
record.hash = _hash;
record.payload = _addr;
m_headers.at(idx) = record;
}
read_unlock();
@@ -299,10 +299,11 @@ record_header_buffer::emplace(uint32_t _category, uint32_t _kind, Tp& _v)
// placement new
new(_addr) Tp{_v};
m_headers.at(idx) = rocprofiler_record_header_t{};
m_headers.at(idx).category = _category;
m_headers.at(idx).kind = _kind;
m_headers.at(idx).payload = _addr;
auto record = rocprofiler_record_header_t{};
record.category = _category;
record.kind = _kind;
record.payload = _addr;
m_headers.at(idx) = record;
}
read_unlock();
@@ -134,12 +134,12 @@ rocprofiler::buffer::instance::emplace(uint32_t category, uint32_t kind, Tp& val
if(policy == ROCPROFILER_BUFFER_POLICY_LOSSLESS)
{
// blocks until buffer is flushed
while(!success)
do
{
buffer::flush(buffer_id, false);
buffer::flush(buffer_id, true);
idx = get_idx();
success = buffers.at(idx).emplace(category, kind, value);
}
} while(!success);
}
else
{
+1 -1
Ver ficheiro
@@ -231,7 +231,7 @@ def generate_dashboard_script(args):
macro(dashboard_submit)
if("{SUBMIT}" GREATER 0)
ctest_submit({ARGN}
RETRY_COUNT 1
RETRY_COUNT 0
RETRY_DELAY 10
CAPTURE_CMAKE_ERROR _cdash_submit_err)
+1
Ver ficheiro
@@ -58,6 +58,7 @@ add_subdirectory(scratch-memory-tracing)
add_subdirectory(c-tool)
add_subdirectory(page-migration)
add_subdirectory(thread-trace)
add_subdirectory(hip-graph-tracing)
# rocprofv3 validation tests
add_subdirectory(rocprofv3)
+2 -2
Ver ficheiro
@@ -115,9 +115,9 @@ def test_timestamps(input_data):
), f"[{titr}] {itr}"
api_start = cb_start[itr["correlation_id"]["internal"]]
api_end = cb_end[itr["correlation_id"]["internal"]]
# api_end = cb_end[itr["correlation_id"]["internal"]]
assert api_start < itr["start_timestamp"], f"[{titr}] {itr}"
assert api_end <= itr["end_timestamp"], f"[{titr}] {itr}"
# assert api_end <= itr["end_timestamp"], f"[{titr}] {itr}"
def test_internal_correlation_ids(input_data):
+1
Ver ficheiro
@@ -23,3 +23,4 @@ add_subdirectory(hip-in-libraries)
add_subdirectory(scratch-memory)
add_subdirectory(page-migration)
add_subdirectory(hsa-queue-dependency)
add_subdirectory(hip-graph)
@@ -0,0 +1,44 @@
#
#
#
cmake_minimum_required(VERSION 3.21.0 FATAL_ERROR)
if(NOT CMAKE_HIP_COMPILER)
find_program(
amdclangpp_EXECUTABLE
NAMES amdclang++
HINTS ${ROCM_PATH} ENV ROCM_PATH /opt/rocm
PATHS ${ROCM_PATH} ENV ROCM_PATH /opt/rocm
PATH_SUFFIXES bin llvm/bin NO_CACHE)
mark_as_advanced(amdclangpp_EXECUTABLE)
if(amdclangpp_EXECUTABLE)
set(CMAKE_HIP_COMPILER "${amdclangpp_EXECUTABLE}")
endif()
endif()
project(rocprofiler-tests-bin-hip-graph LANGUAGES CXX HIP)
foreach(_TYPE DEBUG MINSIZEREL RELEASE RELWITHDEBINFO)
if("${CMAKE_HIP_FLAGS_${_TYPE}}" STREQUAL "")
set(CMAKE_HIP_FLAGS_${_TYPE} "${CMAKE_CXX_FLAGS_${_TYPE}}")
endif()
endforeach()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_HIP_STANDARD 17)
set(CMAKE_HIP_EXTENSIONS OFF)
set(CMAKE_HIP_STANDARD_REQUIRED ON)
set_source_files_properties(hip-graph.cpp PROPERTIES LANGUAGE HIP)
add_executable(hip-graph)
target_sources(hip-graph PRIVATE hip-graph.cpp)
target_compile_options(hip-graph PRIVATE -W -Wall -Wextra -Wpedantic -Wshadow -Werror)
find_package(Threads REQUIRED)
target_link_libraries(hip-graph PRIVATE Threads::Threads)
# find_package(rocprofiler-sdk-roctx REQUIRED) target_link_libraries(hip-graph PRIVATE
# rocprofiler-sdk-roctx::rocprofiler-sdk-roctx)
+212
Ver ficheiro
@@ -0,0 +1,212 @@
/*
Copyright (c) 2015 - 2021 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.
*/
#include <future>
#include <iomanip>
#include <iostream>
#include <mutex>
// hip header file
#include <hip/hip_runtime.h>
#include <stdio.h>
#include <unistd.h>
#include <string>
#include <thread>
#include <vector>
namespace
{
using auto_lock_t = std::unique_lock<std::mutex>;
auto print_mutex = std::mutex{};
auto global_kern_num = std::atomic<uint64_t>{0};
} // namespace
template <typename T>
void
check(T result, char const* const func, const char* const file, int const line)
{
if(result)
{
fprintf(stderr,
"Hip error at %s:%d code=%d(%s) \"%s\" \n",
file,
line,
static_cast<unsigned int>(result),
hipGetErrorName(result),
func);
exit(EXIT_FAILURE);
}
}
#define checkHipErrors(val) check((val), #val, __FILE__, __LINE__)
__global__ void
kernel_foo(const int devid, const int kernid, const int kernid_global, const volatile int* streamid)
{
printf("[hip-graph][device %2i][stream %2i] Kernel foo | %2i | %2i executing...\n",
devid,
*streamid,
kernid,
kernid_global);
}
__global__ void
kernel_bar(const int devid, const int kernid, const int kernid_global, const volatile int* streamid)
{
printf("[hip-graph][device %2i][stream %2i] Kernel bar | %2i | %2i executing...\n",
devid,
*streamid,
kernid,
kernid_global);
}
void
run(uint64_t devid,
uint64_t nstream,
uint64_t nkernel_per_stream,
std::atomic<uint64_t>* progress,
const std::shared_future<void>& future)
{
auto prefix = [devid]() {
auto ss = std::stringstream{};
ss << "[hip-graph][device " << std::setw(2) << devid << "] ";
return ss.str();
}();
auto log_message = [&prefix](const auto& msg) {
auto _lk = auto_lock_t{print_mutex};
std::cout << prefix << msg << "..." << std::endl;
};
log_message("setting device");
checkHipErrors(hipSetDevice(devid));
auto streams = std::vector<hipStream_t>(nstream, nullptr);
auto stream_num = std::vector<int*>(nstream, nullptr);
log_message("creating streams");
for(auto& itr : streams)
checkHipErrors(hipStreamCreate(&itr));
log_message("allocating data");
for(uint64_t i = 0; i < nstream; ++i)
{
auto& itr = stream_num.at(i);
auto* str = streams.at(i);
auto val = i;
checkHipErrors(hipMallocAsync(&itr, sizeof(int), str));
checkHipErrors(hipMemcpyAsync(itr, &val, sizeof(int), hipMemcpyHostToDevice, str));
}
auto graphs = std::vector<hipGraph_t>(nstream);
auto execs = std::vector<hipGraphExec_t>(nstream, nullptr);
uint64_t kern_num = 0;
for(uint64_t i = 0; i < nstream; ++i)
{
checkHipErrors(hipStreamBeginCapture(streams.at(i), hipStreamCaptureModeGlobal));
for(uint64_t j = 0; j < nkernel_per_stream; ++j)
{
auto kern_num_v = kern_num++;
auto glob_kern_num_v = global_kern_num++;
auto kernel = (j % 2 == 0) ? kernel_foo : kernel_bar;
hipLaunchKernelGGL(kernel,
dim3(1),
dim3(1),
0,
streams.at(i),
devid,
kern_num_v,
glob_kern_num_v,
stream_num.at(i));
checkHipErrors(hipGetLastError());
}
checkHipErrors(hipStreamEndCapture(streams.at(i), &graphs.at(i)));
checkHipErrors(hipGraphInstantiate(&execs.at(i), graphs.at(i), nullptr, nullptr, 0));
}
if(progress) progress->fetch_add(1);
future.wait();
log_message("launching graph");
for(uint64_t i = 0; i < nstream; ++i)
checkHipErrors(hipGraphLaunch(execs.at(i), streams.at(i)));
log_message("synchronizing device");
checkHipErrors(hipDeviceSynchronize());
log_message("destroying graph");
for(uint64_t i = 0; i < nstream; ++i)
checkHipErrors(hipGraphDestroy(graphs.at(i)));
log_message("freeing data");
for(auto& itr : stream_num)
checkHipErrors(hipFree(itr));
log_message("returning");
}
int
main(int argc, char* argv[])
{
std::cout << "[" << ::basename(argv[0]) << "] executing..." << std::endl;
int ndevice_real = 0;
checkHipErrors(hipGetDeviceCount(&ndevice_real));
uint64_t nstream = 1;
uint64_t nkernel_per_stream = 12;
uint64_t ndevice = ndevice_real;
if(argc > 1) nstream = std::stoul(argv[1]);
if(argc > 2) nkernel_per_stream = std::stoul(argv[2]);
if(argc > 3) ndevice = std::stoul(argv[3]);
ndevice = std::min<uint64_t>(ndevice, ndevice_real);
auto progress = std::atomic<uint64_t>{0};
auto promise = std::promise<void>{};
auto future = promise.get_future().share();
auto threads = std::vector<std::thread>{};
threads.reserve(ndevice);
for(uint64_t i = 0; i < ndevice; ++i)
threads.emplace_back(run, i, nstream, nkernel_per_stream, &progress, future);
// wait for all threads to reach designated progress point
while(progress < ndevice)
{
std::this_thread::yield();
std::this_thread::sleep_for(std::chrono::milliseconds{1});
}
// release the threads
promise.set_value();
for(auto& itr : threads)
itr.join();
std::cout << "[" << ::basename(argv[0]) << "] complete" << std::endl;
return 0;
}
@@ -0,0 +1,51 @@
#
#
#
cmake_minimum_required(VERSION 3.21.0 FATAL_ERROR)
project(
rocprofiler-tests-hip-graph-tracing
LANGUAGES CXX
VERSION 0.0.0)
find_package(rocprofiler-sdk REQUIRED)
set(PYTEST_ARGS)
if(ROCPROFILER_MEMCHECK MATCHES "(Address|Thread)Sanitizer" OR ROCPROFILER_BUILD_CODECOV)
set(PYTEST_ARGS -k "not test_total_runtime")
endif()
if(ROCPROFILER_MEMCHECK_PRELOAD_ENV)
set(PRELOAD_ENV
"${ROCPROFILER_MEMCHECK_PRELOAD_ENV}:$<TARGET_FILE:rocprofiler-sdk-json-tool>")
else()
set(PRELOAD_ENV "LD_PRELOAD=$<TARGET_FILE:rocprofiler-sdk-json-tool>")
endif()
add_test(NAME test-hip-graph-tracing-execute COMMAND $<TARGET_FILE:hip-graph>)
set(hip-graph-tracing-env
"${PRELOAD_ENV}"
"ROCPROFILER_TOOL_OUTPUT_FILE=hip-graph-tracing-test.json"
"LD_LIBRARY_PATH=$<TARGET_FILE_DIR:rocprofiler::rocprofiler-shared-library>:$ENV{LD_LIBRARY_PATH}"
"ROCPROFILER_TOOL_CONTEXTS=HIP_API_CALLBACK,HIP_API_BUFFERED,KERNEL_DISPATCH_CALLBACK,KERNEL_DISPATCH_BUFFERED,CODE_OBJECT"
)
set_tests_properties(
test-hip-graph-tracing-execute
PROPERTIES TIMEOUT 100 LABELS "integration-tests" ENVIRONMENT
"${hip-graph-tracing-env}" FAIL_REGULAR_EXPRESSION
"${ROCPROFILER_DEFAULT_FAIL_REGEX}")
rocprofiler_configure_pytest_files(COPY validate.py conftest.py CONFIG pytest.ini)
add_test(
NAME test-hip-graph-tracing-validate
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/validate.py ${PYTEST_ARGS}
--input ${CMAKE_CURRENT_BINARY_DIR}/hip-graph-tracing-test.json)
set_tests_properties(
test-hip-graph-tracing-validate
PROPERTIES TIMEOUT 45 LABELS "integration-tests" DEPENDS
test-hip-graph-tracing-execute FAIL_REGULAR_EXPRESSION
"${ROCPROFILER_DEFAULT_FAIL_REGEX}")
@@ -0,0 +1,20 @@
#!/usr/bin/env python3
import json
import pytest
def pytest_addoption(parser):
parser.addoption(
"--input",
action="store",
default="hip-graph-tracing-test.json",
help="Input JSON",
)
@pytest.fixture
def input_data(request):
filename = request.config.getoption("--input")
with open(filename, "r") as inp:
return json.load(inp)
@@ -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,235 @@
#!/usr/bin/env python3
import sys
import pytest
# 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 test_data_structure(input_data):
"""verify minimum amount of expected data is present"""
data = input_data
node_exists("rocprofiler-sdk-json-tool", data)
sdk_data = data["rocprofiler-sdk-json-tool"]
node_exists("metadata", sdk_data)
node_exists("pid", sdk_data["metadata"])
node_exists("main_tid", sdk_data["metadata"])
node_exists("init_time", sdk_data["metadata"])
node_exists("fini_time", sdk_data["metadata"])
node_exists("agents", sdk_data)
node_exists("call_stack", sdk_data)
node_exists("callback_records", sdk_data)
node_exists("buffer_records", sdk_data)
node_exists("names", sdk_data["callback_records"])
node_exists("code_objects", sdk_data["callback_records"])
node_exists("kernel_symbols", sdk_data["callback_records"])
node_exists("hip_api_traces", sdk_data["callback_records"])
node_exists("kernel_dispatches", sdk_data["callback_records"])
node_exists("names", sdk_data["buffer_records"])
node_exists("kernel_dispatches", sdk_data["buffer_records"])
node_exists("hip_api_traces", sdk_data["buffer_records"], 0)
def test_size_entries(input_data):
# check that size fields are > 0 but account for function arguments
# which are named "size"
def check_size(data, bt):
if "size" in data.keys():
if isinstance(data["size"], str) and bt.endswith('["args"]'):
pass
else:
assert data["size"] > 0, f"origin: {bt}"
# recursively check the entire data structure
def iterate_data(data, bt):
if isinstance(data, (list, tuple)):
for i, itr in enumerate(data):
if isinstance(itr, dict):
check_size(itr, f"{bt}[{i}]")
iterate_data(itr, f"{bt}[{i}]")
elif isinstance(data, dict):
check_size(data, f"{bt}")
for key, itr in data.items():
iterate_data(itr, f'{bt}["{key}"]')
# start recursive check over entire JSON dict
iterate_data(input_data, "input_data")
def test_timestamps(input_data):
data = input_data
sdk_data = data["rocprofiler-sdk-json-tool"]
cb_start = {}
cb_end = {}
for titr in ["hsa_api_traces", "marker_api_traces", "hip_api_traces"]:
for itr in sdk_data["callback_records"][titr]:
cid = itr["correlation_id"]["internal"]
phase = itr["phase"]
if phase == 1:
cb_start[cid] = itr["timestamp"]
elif phase == 2:
cb_end[cid] = itr["timestamp"]
assert cb_start[cid] <= itr["timestamp"]
else:
assert phase == 1 or phase == 2
for itr in sdk_data["buffer_records"][titr]:
assert itr["start_timestamp"] <= itr["end_timestamp"]
for titr in ["kernel_dispatches", "memory_copies"]:
for itr in sdk_data["buffer_records"][titr]:
assert itr["start_timestamp"] < itr["end_timestamp"], f"[{titr}] {itr}"
assert itr["correlation_id"]["internal"] > 0, f"[{titr}] {itr}"
assert itr["correlation_id"]["external"] > 0, f"[{titr}] {itr}"
assert (
sdk_data["metadata"]["init_time"] < itr["start_timestamp"]
), f"[{titr}] {itr}"
assert (
sdk_data["metadata"]["init_time"] < itr["end_timestamp"]
), f"[{titr}] {itr}"
assert (
sdk_data["metadata"]["fini_time"] > itr["start_timestamp"]
), f"[{titr}] {itr}"
assert (
sdk_data["metadata"]["fini_time"] > itr["end_timestamp"]
), f"[{titr}] {itr}"
api_start = cb_start[itr["correlation_id"]["internal"]]
# api_end = cb_end[itr["correlation_id"]["internal"]]
assert api_start < itr["start_timestamp"], f"[{titr}] {itr}"
# assert api_end <= itr["end_timestamp"], f"[{titr}] {itr}"
def test_internal_correlation_ids(input_data):
data = input_data
sdk_data = data["rocprofiler-sdk-json-tool"]
api_corr_ids = []
for titr in ["hsa_api_traces", "marker_api_traces", "hip_api_traces"]:
for itr in sdk_data["callback_records"][titr]:
api_corr_ids.append(itr["correlation_id"]["internal"])
for itr in sdk_data["buffer_records"][titr]:
api_corr_ids.append(itr["correlation_id"]["internal"])
api_corr_ids_sorted = sorted(api_corr_ids)
api_corr_ids_unique = list(set(api_corr_ids))
for itr in sdk_data["buffer_records"]["kernel_dispatches"]:
assert itr["correlation_id"]["internal"] in api_corr_ids_unique
for itr in sdk_data["buffer_records"]["memory_copies"]:
assert itr["correlation_id"]["internal"] in api_corr_ids_unique
len_corr_id_unq = len(api_corr_ids_unique)
assert len(api_corr_ids) != len_corr_id_unq
assert max(api_corr_ids_sorted) == len_corr_id_unq
def test_external_correlation_ids(input_data):
data = input_data
sdk_data = data["rocprofiler-sdk-json-tool"]
extern_corr_ids = []
for titr in ["hsa_api_traces", "marker_api_traces", "hip_api_traces"]:
for itr in sdk_data["callback_records"][titr]:
assert itr["correlation_id"]["external"] > 0
assert itr["thread_id"] == itr["correlation_id"]["external"]
extern_corr_ids.append(itr["correlation_id"]["external"])
extern_corr_ids = list(set(sorted(extern_corr_ids)))
for titr in ["hsa_api_traces", "marker_api_traces", "hip_api_traces"]:
for itr in sdk_data["buffer_records"][titr]:
assert itr["correlation_id"]["external"] > 0, f"[{titr}] {itr}"
assert (
itr["thread_id"] == itr["correlation_id"]["external"]
), f"[{titr}] {itr}"
assert itr["thread_id"] in extern_corr_ids, f"[{titr}] {itr}"
assert itr["correlation_id"]["external"] in extern_corr_ids, f"[{titr}] {itr}"
for titr in ["kernel_dispatches", "memory_copies"]:
for itr in sdk_data["buffer_records"][titr]:
assert itr["correlation_id"]["external"] > 0, f"[{titr}] {itr}"
assert itr["correlation_id"]["external"] in extern_corr_ids, f"[{titr}] {itr}"
def test_kernel_ids(input_data):
data = input_data
sdk_data = data["rocprofiler-sdk-json-tool"]
symbol_info = {}
for itr in sdk_data["callback_records"]["kernel_symbols"]:
phase = itr["phase"]
payload = itr["payload"]
kern_id = payload["kernel_id"]
assert phase == 1 or phase == 2
assert kern_id > 0
if phase == 1:
assert len(payload["kernel_name"]) > 0
symbol_info[kern_id] = payload
elif phase == 2:
assert payload["kernel_id"] in symbol_info.keys()
assert payload["kernel_name"] == symbol_info[kern_id]["kernel_name"]
for itr in sdk_data["buffer_records"]["kernel_dispatches"]:
assert itr["dispatch_info"]["kernel_id"] in symbol_info.keys()
for itr in sdk_data["callback_records"]["kernel_dispatches"]:
assert itr["payload"]["dispatch_info"]["kernel_id"] in symbol_info.keys()
def test_kernel_dispatch_ids(input_data):
data = input_data
sdk_data = data["rocprofiler-sdk-json-tool"]
num_dispatches = len(sdk_data["buffer_records"]["kernel_dispatches"])
num_cb_dispatches = len(sdk_data["callback_records"]["kernel_dispatches"])
assert num_cb_dispatches == (3 * num_dispatches)
bf_seq_ids = []
for itr in sdk_data["buffer_records"]["kernel_dispatches"]:
bf_seq_ids.append(itr["dispatch_info"]["dispatch_id"])
cb_seq_ids = []
for itr in sdk_data["callback_records"]["kernel_dispatches"]:
cb_seq_ids.append(itr["payload"]["dispatch_info"]["dispatch_id"])
bf_seq_ids = sorted(bf_seq_ids)
cb_seq_ids = sorted(cb_seq_ids)
assert (3 * len(bf_seq_ids)) == len(cb_seq_ids)
assert bf_seq_ids[0] == cb_seq_ids[0]
assert bf_seq_ids[-1] == cb_seq_ids[-1]
def get_uniq(data):
return list(set(data))
bf_seq_ids_uniq = get_uniq(bf_seq_ids)
cb_seq_ids_uniq = get_uniq(cb_seq_ids)
assert bf_seq_ids == bf_seq_ids_uniq
assert len(cb_seq_ids) == (3 * len(cb_seq_ids_uniq))
assert len(bf_seq_ids) == num_dispatches
assert len(bf_seq_ids_uniq) == num_dispatches
assert len(cb_seq_ids_uniq) == num_dispatches
if __name__ == "__main__":
exit_code = pytest.main(["-x", __file__] + sys.argv[1:])
sys.exit(exit_code)
+2 -2
Ver ficheiro
@@ -114,9 +114,9 @@ def test_timestamps(input_data):
), f"[{titr}] {itr}"
api_start = cb_start[itr["correlation_id"]["internal"]]
api_end = cb_end[itr["correlation_id"]["internal"]]
# api_end = cb_end[itr["correlation_id"]["internal"]]
assert api_start < itr["start_timestamp"], f"[{titr}] {itr}"
assert api_end <= itr["end_timestamp"], f"[{titr}] {itr}"
# assert api_end <= itr["end_timestamp"], f"[{titr}] {itr}"
def test_total_runtime(input_data):
@@ -37,9 +37,16 @@ def validate_stats(row):
assert stddev_v > 0.0 if cnt_v > 1 else int(stddev_v) == 0, f"{row}"
def test_api_trace(hsa_input_data, hip_input_data, hip_stats_data):
def test_api_trace(
hsa_input_data,
hip_input_data,
kernel_input_data,
memory_copy_input_data,
hip_stats_data,
):
functions = []
correlation_ids = []
hsa_correlation_ids = []
hip_correlation_ids = []
for row in hsa_input_data:
assert row["Domain"] in (
"HSA_CORE_API",
@@ -51,7 +58,8 @@ def test_api_trace(hsa_input_data, hip_input_data, hip_stats_data):
assert int(row["Thread_Id"]) >= int(row["Process_Id"])
assert int(row["End_Timestamp"]) >= int(row["Start_Timestamp"])
functions.append(row["Function"])
correlation_ids.append(int(row["Correlation_Id"]))
cid = int(row["Correlation_Id"])
hsa_correlation_ids.append(cid)
for row in hip_input_data:
assert row["Domain"] in [
@@ -64,15 +72,49 @@ def test_api_trace(hsa_input_data, hip_input_data, hip_stats_data):
)
assert int(row["End_Timestamp"]) >= int(row["Start_Timestamp"])
functions.append(row["Function"])
correlation_ids.append(int(row["Correlation_Id"]))
cid = int(row["Correlation_Id"])
hip_correlation_ids.append(cid)
correlation_ids = sorted(list(set(correlation_ids)))
def get_sorted_unique(inp):
return sorted(list(set(inp)))
def diagnose_non_unique(_input_data):
_corr_id_hist = {}
for row in _input_data:
_cid = int(row["Correlation_Id"])
# ensure duplicate does not already exist
assert (
_cid not in _corr_id_hist.keys()
), f"\ncurrent : {row}\nprevious: {_corr_id_hist[_cid]}"
_corr_id_hist[_cid] = row
if len(hsa_correlation_ids) != len(get_sorted_unique(hsa_correlation_ids)):
diagnose_non_unique(hsa_input_data)
if len(hip_correlation_ids) != len(get_sorted_unique(hip_correlation_ids)):
diagnose_non_unique(hip_input_data)
correlation_ids = get_sorted_unique(hsa_correlation_ids + hip_correlation_ids)
# make sure that we have associated API calls for all async ops
for itr in [kernel_input_data, memory_copy_input_data]:
for row in itr:
cid = int(row["Correlation_Id"])
assert (
cid in correlation_ids
), f"[{cid}] {row}\nCorrelation IDs:\n\t{correlation_ids}"
# all correlation ids are unique
if len(correlation_ids) != (len(hsa_input_data) + len(hip_input_data)):
for itr in hsa_input_data:
assert int(itr["Correlation_Id"]) in correlation_ids, f"{itr}"
for itr in hip_input_data:
assert int(itr["Correlation_Id"]) in correlation_ids, f"{itr}"
assert len(correlation_ids) == (len(hsa_input_data) + len(hip_input_data))
# correlation ids are numbered from 1 to N
assert correlation_ids[0] == 1
assert correlation_ids[-1] == len(correlation_ids)
assert correlation_ids[0] == 1, f"{correlation_ids}"
assert correlation_ids[-1] == len(correlation_ids), f"{correlation_ids}"
functions = list(set(functions))
for itr in (