Adding list-metrics (#585)

* Adding list-metrics

* cmake formatting (cmake-format) (#587)

Co-authored-by: SrirakshaNag <104580803+SrirakshaNag@users.noreply.github.com>

* source formatting (clang-format v11) (#586)

Co-authored-by: SrirakshaNag <104580803+SrirakshaNag@users.noreply.github.com>

* Fixing issues with validation tests

* python formatting (black) (#588)

Co-authored-by: SrirakshaNag <104580803+SrirakshaNag@users.noreply.github.com>

* source formatting (clang-format v11) (#589)

Co-authored-by: SrirakshaNag <104580803+SrirakshaNag@users.noreply.github.com>

* cmake formatting (cmake-format) (#590)

Co-authored-by: SrirakshaNag <104580803+SrirakshaNag@users.noreply.github.com>

* Update conftest.py

* Update validate.py

* python formatting (black) (#591)

Co-authored-by: SrirakshaNag <104580803+SrirakshaNag@users.noreply.github.com>

* python formatting (black) (#592)

Co-authored-by: SrirakshaNag <104580803+SrirakshaNag@users.noreply.github.com>

* Checking if agent-id in validate.py

* Fixing list metrics execute test

* cmake formatting (cmake-format) (#593)

Co-authored-by: SrirakshaNag <104580803+SrirakshaNag@users.noreply.github.com>

* Fixing CI failure

* cmake formatting (cmake-format) (#594)

Co-authored-by: SrirakshaNag <104580803+SrirakshaNag@users.noreply.github.com>

* Review Comments

* Update source/bin/rocprofv3

Support -L shorthand for --list-metrics

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonathan R. Madsen <jrmadsen@users.noreply.github.com>
This commit is contained in:
SrirakshaNag
2024-03-05 20:53:15 -06:00
committed by GitHub
parent b0a88d9124
commit c7407d0a9f
10 changed files with 392 additions and 24 deletions
+9
View File
@@ -39,6 +39,7 @@ usage() {
echo -e "\t#${GREY} usage e.g:(with custom dir): rocprofv3 --hsa-trace -d <out_dir> <executable>${RESET}"
echo -e "${GREEN}-M | --mangled-kernels ${RESET} Do not demangle the kernel names"
echo -e "${GREEN}-T | --truncate-kernels ${RESET} Truncate the demangled kernel names"
echo -e "${GREEN}-L | --list-metrics ${RESET} List metrics"
echo -e ""
exit ${EC}
}
@@ -75,6 +76,7 @@ while true; do
elif [[ "$1" == "-o" || "$1" == "--output-file-name" ]]; then
if [ "$2" ]; then
export ROCPROF_OUTPUT_FILE_NAME=$2
export ROCPROF_OUTPUT_LIST_METRICS_FILE=1
else
usage 1
fi
@@ -84,6 +86,7 @@ while true; do
if [ "$2" ]; then
ROCPROF_OUTPUT_PATH_INTERNAL=$2
export ROCPROF_OUTPUT_PATH=$ROCPROF_OUTPUT_PATH_INTERNAL
export ROCPROF_OUTPUT_LIST_METRICS_FILE=1
else
usage 1
fi
@@ -92,6 +95,12 @@ while true; do
elif [ "$1" == "--hsa-trace" ]; then
export ROCPROF_HSA_API_TRACE=1
shift
elif [[ "$1" == "-L" || "$1" == "--list-metrics" ]]; then
export ROCPROF_LIST_METRICS=1
ROCP_TOOL_LIBRARIES="${ROCM_DIR}/lib/rocprofiler-sdk/librocprofiler-sdk-tool.so" \
LD_LIBRARY_PATH=${ROCM_DIR}/lib:${LD_LIBRARY_PATH} \
LD_PRELOAD="${ROCPROF_PRELOAD}:${ROCM_DIR}/lib/librocprofiler-sdk.so" \
exec ${ROCM_DIR}/lib/rocprofiler-sdk/rocprofv3-trigger-list-metrics
elif [ "$1" == "--kernel-trace" ]; then
export ROCPROF_KERNEL_TRACE=1
shift
@@ -34,3 +34,18 @@ install(
DESTINATION ${CMAKE_INSTALL_LIBDIR}/rocprofiler-sdk
COMPONENT tools
EXPORT rocprofiler-sdk-tool-targets)
add_executable(rocprofv3-trigger-list-metrics)
target_sources(rocprofv3-trigger-list-metrics PRIVATE rocprofv3_trigger_list_metrics.cpp)
target_link_libraries(rocprofv3-trigger-list-metrics
PRIVATE rocprofiler::rocprofiler-hsa-runtime)
set_target_properties(
rocprofv3-trigger-list-metrics
PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/rocprofiler-sdk)
install(
TARGETS rocprofv3-trigger-list-metrics
DESTINATION ${CMAKE_INSTALL_LIBDIR}/rocprofiler-sdk
COMPONENT tools
EXPORT rocprofiler-sdk-tool-targets)
+13 -11
View File
@@ -57,17 +57,19 @@ struct config
{
config();
bool demangle = get_env("ROCPROF_DEMANGLE_KERNELS", true);
bool truncate = get_env("ROCPROF_TRUNCATE_KERNELS", false);
bool kernel_trace = get_env("ROCPROF_KERNEL_TRACE", false);
bool hsa_api_trace = get_env("ROCPROF_HSA_API_TRACE", false);
bool marker_api_trace = get_env("ROCPROF_MARKER_API_TRACE", false);
bool memory_copy_trace = get_env("ROCPROF_MEMORY_COPY_TRACE", false);
bool counter_collection = get_env("ROCPROF_COUNTER_COLLECTION", false);
bool hip_api_trace = get_env("ROCPROF_HIP_API_TRACE", false);
bool hip_compiler_api_trace = get_env("ROCPROF_HIP_COMPILER_API_TRACE", false);
int mpi_size = get_mpi_size();
int mpi_rank = get_mpi_rank();
bool demangle = get_env("ROCPROF_DEMANGLE_KERNELS", true);
bool truncate = get_env("ROCPROF_TRUNCATE_KERNELS", false);
bool kernel_trace = get_env("ROCPROF_KERNEL_TRACE", false);
bool hsa_api_trace = get_env("ROCPROF_HSA_API_TRACE", false);
bool marker_api_trace = get_env("ROCPROF_MARKER_API_TRACE", false);
bool memory_copy_trace = get_env("ROCPROF_MEMORY_COPY_TRACE", false);
bool counter_collection = get_env("ROCPROF_COUNTER_COLLECTION", false);
bool hip_api_trace = get_env("ROCPROF_HIP_API_TRACE", false);
bool hip_compiler_api_trace = get_env("ROCPROF_HIP_COMPILER_API_TRACE", false);
bool list_metrics = get_env("ROCPROF_LIST_METRICS", false);
bool list_metrics_output_file = get_env("ROCPROF_OUTPUT_LIST_METRICS_FILE", false);
int mpi_size = get_mpi_size();
int mpi_rank = get_mpi_rank();
std::string output_path = get_env("ROCPROF_OUTPUT_PATH", fs::current_path().string());
std::string output_file = get_env("ROCPROF_OUTPUT_FILE_NAME", std::to_string(getpid()));
std::vector<std::string> kernel_names = {};
+7 -5
View File
@@ -74,11 +74,13 @@ struct csv_encoder
}
};
using api_csv_encoder = csv_encoder<7>;
using kernel_trace_csv_encoder = csv_encoder<16>;
using counter_collection_csv_encoder = csv_encoder<15>;
using memory_copy_csv_encoder = csv_encoder<7>;
using marker_csv_encoder = csv_encoder<7>;
using api_csv_encoder = csv_encoder<7>;
using kernel_trace_csv_encoder = csv_encoder<16>;
using counter_collection_csv_encoder = csv_encoder<15>;
using memory_copy_csv_encoder = csv_encoder<7>;
using marker_csv_encoder = csv_encoder<7>;
using list_basic_metrics_csv_encoder = csv_encoder<5>;
using list_derived_metrics_csv_encoder = csv_encoder<5>;
} // namespace csv
} // namespace tool
} // namespace rocprofiler
@@ -0,0 +1,30 @@
// MIT License
//
// Copyright (c) 2023 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 <hsa/hsa.h>
int
main()
{
hsa_init();
return 0;
}
+166 -8
View File
@@ -200,6 +200,28 @@ get_marker_api_file()
return _v;
}
tool::output_file*&
get_list_basic_metrics_file()
{
static auto* _v =
new tool::output_file{"basic_metrics",
tool::csv::list_basic_metrics_csv_encoder{},
{"Agent-id", "Name", "Description", "Block", "Dimensions"}};
ADD_DESTRUCTOR(_v);
return _v;
}
tool::output_file*&
get_list_derived_metrics_file()
{
static auto* _v =
new tool::output_file{"derived_metrics",
tool::csv::list_derived_metrics_csv_encoder{},
{"Agent-id", "Name", "Description", "Expression", "Dimensions"}};
ADD_DESTRUCTOR(_v);
return _v;
}
#undef ADD_DESTRUCTOR
struct marker_entry
@@ -694,15 +716,25 @@ rocprofiler_status_t
dimensions_info_callback(rocprofiler_counter_id_t id,
const rocprofiler_record_dimension_info_t* dim_info,
long unsigned int num_dims,
void*)
void* user_data)
{
counter_dimension_data.wlock(
[&id, &dim_info, &num_dims](counter_dimension_info_map_t& counter_dimension_data_v) {
std::vector<rocprofiler_record_dimension_info_t> dimensions;
for(size_t dim = 0; dim < num_dims; dim++)
dimensions.emplace_back(dim_info[dim]);
counter_dimension_data_v.emplace(std::make_pair(id.handle, dimensions));
});
if(user_data != nullptr)
{
auto* dimensions_info =
static_cast<std::vector<rocprofiler_record_dimension_info_t>*>(user_data);
for(size_t j = 0; j < num_dims; j++)
dimensions_info->push_back(dim_info[j]);
}
else
{
counter_dimension_data.wlock(
[&id, &dim_info, &num_dims](counter_dimension_info_map_t& counter_dimension_data_v) {
std::vector<rocprofiler_record_dimension_info_t> dimensions;
for(size_t dim = 0; dim < num_dims; dim++)
dimensions.emplace_back(dim_info[dim]);
counter_dimension_data_v.emplace(std::make_pair(id.handle, dimensions));
});
}
return ROCPROFILER_STATUS_SUCCESS;
}
@@ -771,6 +803,111 @@ get_agent_profile(const rocprofiler_agent_t* agent)
return profile;
}
rocprofiler_status_t
list_metrics_iterate_agents(const rocprofiler_agent_t** agents, size_t num_agents, void*)
{
for(size_t idx = 0; idx < num_agents; idx++)
{
auto counters_v = counter_vec_t{};
uint32_t node_id = agents[idx]->node_id;
ROCPROFILER_CALL(
rocprofiler_iterate_agent_supported_counters(
agents[idx]->id,
[](rocprofiler_agent_id_t,
rocprofiler_counter_id_t* counters,
size_t num_counters,
void* user_data) {
auto* agent_node_id = static_cast<uint32_t*>(user_data);
for(size_t i = 0; i < num_counters; i++)
{
rocprofiler_counter_info_v0_t counter_info;
auto dimensions = std::vector<rocprofiler_record_dimension_info_t>{};
ROCPROFILER_CALL(
rocprofiler_iterate_counter_dimensions(counters[i],
dimensions_info_callback,
static_cast<void*>(&dimensions)),
"iterate_dimension_info");
ROCPROFILER_CALL(
rocprofiler_query_counter_info(counters[i],
ROCPROFILER_COUNTER_INFO_VERSION_0,
static_cast<void*>(&counter_info)),
"Could not query counter_id");
auto dimensions_info = std::stringstream{};
for(size_t j = 0; j != dimensions.size(); j++)
{
dimensions_info << dimensions[j].name
<< "[0:" << dimensions[j].instance_size - 1 << "]";
if(j != dimensions.size() - 1) dimensions_info << "\t";
}
if(!counter_info.is_derived && tool::get_config().list_metrics &&
!std::string(counter_info.block).empty())
{
auto counter_info_ss = std::stringstream{};
if(tool::get_config().list_metrics_output_file)
{
tool::csv::list_basic_metrics_csv_encoder::write_row(
counter_info_ss,
*agent_node_id,
counter_info.name,
counter_info.description,
counter_info.block,
dimensions_info.str());
get_dereference(get_list_basic_metrics_file())
<< counter_info_ss.str();
}
else
{
counter_info_ss << "gpu-agent" << *agent_node_id << ":"
<< "\t" << counter_info.name << "\n";
counter_info_ss << "Description:"
<< "\t" << counter_info.description << "\n";
counter_info_ss << "Block:"
<< "\t" << counter_info.block << "\n";
counter_info_ss << "Dimensions:"
<< "\t" << dimensions_info.str() << "\n";
counter_info_ss << "\n";
std::cout << counter_info_ss.str();
}
}
else if(counter_info.is_derived && tool::get_config().list_metrics)
{
auto counter_info_ss = std::stringstream{};
if(tool::get_config().list_metrics_output_file)
{
tool::csv::list_derived_metrics_csv_encoder::write_row(
counter_info_ss,
*agent_node_id,
counter_info.name,
counter_info.description,
counter_info.expression,
dimensions_info.str());
get_dereference(get_list_derived_metrics_file())
<< counter_info_ss.str();
}
else
{
counter_info_ss << "gpu-agent" << *agent_node_id << ":"
<< "\t" << counter_info.name << "\n"
<< "Description: " << counter_info.description
<< "\n";
counter_info_ss << "Expression: " << counter_info.expression
<< "\n";
counter_info_ss << "Dimensions: " << dimensions_info.str() << "\n";
counter_info_ss << "\n";
std::cout << counter_info_ss.str();
}
}
}
return ROCPROFILER_STATUS_SUCCESS;
},
reinterpret_cast<void*>(&node_id)),
"Iterate rocprofiler counters");
}
return ROCPROFILER_STATUS_SUCCESS;
}
void
dispatch_callback(rocprofiler_queue_id_t queue_id,
const rocprofiler_agent_t* agent,
@@ -1004,6 +1141,19 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
return 0;
}
void
api_registration_callback(rocprofiler_intercept_table_t,
uint64_t,
uint64_t,
void**,
uint64_t,
void*)
{
ROCPROFILER_CALL(rocprofiler_query_available_agents(
list_metrics_iterate_agents, sizeof(rocprofiler_agent_t), nullptr),
"Iterate rocporfiler agents")
}
void
tool_fini(void* tool_data)
{
@@ -1049,6 +1199,14 @@ rocprofiler_configure(uint32_t version,
uint32_t minor = (version % 10000) / 100;
uint32_t patch = version % 100;
if(tool::get_config().list_metrics)
{
ROCPROFILER_CALL(rocprofiler_at_intercept_table_registration(
api_registration_callback, ROCPROFILER_HSA_TABLE, nullptr),
"api registration");
return nullptr;
}
LOG(INFO) << id->name << " is using rocprofiler-sdk v" << major << "." << minor << "." << patch
<< " (" << runtime_version << ")";
@@ -5,3 +5,4 @@ endforeach()
add_subdirectory(input1)
add_subdirectory(input2)
add_subdirectory(list_metrics)
@@ -0,0 +1,81 @@
#
# rocprofv3 tool test
#
cmake_minimum_required(VERSION 3.21.0 FATAL_ERROR)
project(
rocprofiler-tests-counter-collection
LANGUAGES CXX
VERSION 0.0.0)
find_package(rocprofiler-sdk REQUIRED)
foreach(FILENAME validate.py conftest.py)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}
${CMAKE_CURRENT_BINARY_DIR}/${FILENAME} COPYONLY)
endforeach()
# basic-metrics
add_test(NAME rocprofv3-test-list-metrics-execute
COMMAND $<TARGET_FILE:rocprofiler-sdk::rocprofv3> -d
${CMAKE_CURRENT_BINARY_DIR}/out_cc_2 -o metrics --list-metrics)
# list-metrics-stdout
add_test(NAME rocprofv3-test-list-metrics-std-out-execute
COMMAND $<TARGET_FILE:rocprofiler-sdk::rocprofv3> --list-metrics)
string(REPLACE "LD_PRELOAD=" "ROCPROF_PRELOAD=" PRELOAD_ENV
"${ROCPROFILER_MEMCHECK_PRELOAD_ENV}")
if(ROCPROFILER_MEMCHECK STREQUAL "LeakSanitizer")
set(LOG_LEVEL "warning") # info produces memory leak
else()
set(LOG_LEVEL "info")
endif()
set(cc-env-list-metrics
"${PRELOAD_ENV}" "ROCPROF_LOG_LEVEL=${LOG_LEVEL}"
"ROCPROFILER_LOG_LEVEL=${LOG_LEVEL}"
"HSA_TOOLS_LIB=$<TARGET_FILE:rocprofiler::rocprofiler-shared-library>")
set_tests_properties(
rocprofv3-test-list-metrics-execute
PROPERTIES TIMEOUT 45 LABELS "integration-tests" ENVIRONMENT "${cc-env-list-metrics}"
FAIL_REGULAR_EXPRESSION "threw an exception")
set_tests_properties(
rocprofv3-test-list-metrics-std-out-execute
PROPERTIES
TIMEOUT
45
LABELS
"integration-tests"
ENVIRONMENT
"${cc-env-list-metrics}"
PASS_REGULAR_EXPRESSION
"gpu-agent[0-9]*:[a-zA-Z_]*\\n;Description:(.*)\\n*;Expression:(.)*\\n*;Block:[a-zA-Z]*\\n*;Dimensions:([A-Z_]*\\[[0-9]*:[0-9]*\\])*\\n*;"
)
set(VALIDATION_FILES ${CMAKE_CURRENT_BINARY_DIR}/out_cc_2/metrics_basic_metrics.csv
${CMAKE_CURRENT_BINARY_DIR}/out_cc_2/metrics_derived_metrics.csv)
add_test(
NAME rocprofv3-test-list-metrics-validate
COMMAND
${Python3_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/validate.py
--derived-metrics-input
${CMAKE_CURRENT_BINARY_DIR}/out_cc_2/metrics_derived_metrics.csv
--basic-metrics-input
${CMAKE_CURRENT_BINARY_DIR}/out_cc_2/metrics_basic_metrics.csv)
set_tests_properties(
rocprofv3-test-list-metrics-validate
PROPERTIES TIMEOUT
45
LABELS
"integration-tests"
DEPENDS
rocprofv3-test-list-metrics-execute
FAIL_REGULAR_EXPRESSION
"threw an exception"
ATTACHED_FILES_ON_FAIL
"${VALIDATION_FILES}")
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
import csv
import pytest
import pandas as pd
def pytest_addoption(parser):
parser.addoption("--basic-metrics-input", action="store", help="Path to csv file.")
parser.addoption("--derived-metrics-input", action="store", help="Path to csv file.")
@pytest.fixture
def derived_metrics_input_data(request):
filename = request.config.getoption("--derived-metrics-input")
data = []
if filename:
with open(filename, "r") as inp:
reader = csv.DictReader(inp)
for row in reader:
data.append(row)
return data
@pytest.fixture
def basic_metrics_input_data(request):
filename = request.config.getoption("--basic-metrics-input")
data = []
if filename:
with open(filename, "r") as inp:
reader = csv.DictReader(inp)
for row in reader:
data.append(row)
return data
@@ -0,0 +1,34 @@
import pandas as pd
import sys
import pytest
def test_validate_list_basic_metrics(basic_metrics_input_data):
for row in basic_metrics_input_data:
assert row["Agent-id"].isdigit() == True
assert row["Name"] != ""
assert row["Description"] != ""
assert row["Block"] != ""
assert row["Dimensions"] != ""
if row["Name"] == "SQ_WAVES":
row[
"Description"
] == "Count number of waves sent to SQs. (per-simd, emulated, global)"
row["Block"] == "SQ"
def test_validate_list_derived_metrics(derived_metrics_input_data):
for row in derived_metrics_input_data:
assert row["Agent-id"].isdigit() == True
assert row["Name"] != ""
assert row["Description"] != ""
assert row["Expression"] != ""
assert row["Dimensions"] != ""
if row["Name"] == "TA_BUSY_min":
row["Description"] == "TA block is busy. Min over TA instances."
row["Expression"] == "reduce(TA_TA_BUSY,min)"
if __name__ == "__main__":
exit_code = pytest.main(["-x", __file__] + sys.argv[1:])
sys.exit(exit_code)