[rocprofv3-benchmark] SDK and rocprofv3 Benchmarking Suite (#157)
* Adding Benchmarking Stg1
* config fix
* reset
* add jpeg and decode traces in iteration
* address comments benchmark config files.
* address comments.
* address comments.
* address comments: revert cntrl ctx.
* address comments: revert csv output.
* resolve merge conflits.
* format.
* build fix.
* fix hip runtime api traces.
* loop cb services.
* format.
* bug fix.
* Fix operator>
- public C++ comparison operator
* Update configuration options
- support selected regions (--selected-regions)
- support writing output config json (--output-config)
- update serialization data
* rocprofv3 tool library misc updates
- lambda for starting context
- support for writing config json
* Tool library updates
- Finished support for all benchmarking modes
- Added build spec support to config json
* Fix ROCPROFILER_SOVERSION
- this value should not be multiplied by 10,000
* Minor tweak to rocprofv3
* Benchmarking scripts
* formatting
* Fix duplicate include
* Add reproducible-dispatch-count test app
- used in benchmarking
* registration logging
- report number of registered contexts and active contexts after client initialization
* Serialize environment in rocprofv3 output config
* ROCPROFILER_BUILD_BENCHMARK CMake option
* Update benchmark SQL schema
- hash_id is text
- add md5sum to benchmarked_app
- remove app_id from benchmarked_sdk
- add sdk_id to benchmark_config
- separate hip_trace into hip_runtime_trace and hip_compiler_trace
- use INT instead of INTEGER for MySQL compatibility
- add count column in benchmark_statistics
- allow std_dev to be NULL in benchmark_statistics
* Update rocprofv3-benchmark.py
- use md5 instead of python hash (which includes random seed)
- use args.mysql_database
- compute md5sum of executable
- fix insert_benchmark_config
- marker trace fixes
- memory allocation fixes
- split hip_trace into hip_{runtime,compiler}_trace
- remove app_id from benchmarked_sdk
- support warmup runs
- count field in benchmark_statistics
* Support launcher and environment in YAML
* Update reproducible-dispatch-count.cpp
- support mode which doesn't use hip event timing
* Misc rocprofv3-benchmark.py updates
- fix some MySQL support
- remove some unnecessary logging
* support mysql db.
* Format.
* Updated SQL input files
- moved benchmark_schema.sql to benchmark_table.sql
- added benchmark_views.sql
- uses {{metric}} syntax for variable substitution
* cmake formatting
* update rocprofv3-benchmark.py
- benchmark config labels
- overhead views
* Encode rocprofv3-benchmark PID in rocprofv3 and timem output files
* Minor tweak to benchmark_views.sql
- include count
- reorder fields for readability
* split statements and use IS if values is NONE.
* use backtick instead of double quotes and add IS before NOT NULL.:
* Adding Mandelbrot Benchmark App
* Adding Dockerfile example
* Update dockerfile
* Update dockerfile
* [SDK] rocprofiler_query_external_correlation_id_request_kind_name
* Execution-profile benchmark mode
* Execution profile SQL support
* Rename mandlebrot folder + misc clang-tidy
* [rocprofv3-benchmark] Execution profile support
* Update installation
* add work dir when setting git revision, useful when building outside src.
* Set FULL_VERSION_STRING and ROCPROFILER_SDK_GIT_REVISION
- when benchmark folder is top-level
* Remove unused python packages from requirements.txt
* Use ldd/pyelftools to include linked libs for md5sum
- also add --filter-benchmark and --filter-rocprofv3 options
- support labeling the rocprofv3 options
- use more argparse groups
- more generic application of filters
- support variable substitution in environment, e.g. PATH=/some/path:$PATH
* Environment improvements
- improve reproducibility when env set via input file vs. shell
- support "environment-ignore" to remove environment variables
* Misc formatting
* Misc. fix
* use backticks for defining new columns name
* Support shuffling the order of benchmark modes/rocprofv3 args
* Address review comments
* Update Dockerfile
- rename to Dockerfile
- reduce to one layer
* Support docker build arg BRANCH
---------
Co-authored-by: Ammar ELWazir <aelwazir@amd.com>
Co-authored-by: Kandula, Venkateshwar reddy <Venkateshwarreddy.Kandula@amd.com>
Co-authored-by: Venkateshwar Reddy Kandula <vkandula@amd.com>
Co-authored-by: Madsen, Jonathan <Jonathan.Madsen@amd.com>
Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>
This commit is contained in:
@@ -248,6 +248,11 @@ For MPI applications (or other job launchers such as SLURM), place rocprofv3 ins
|
||||
choices=("csv", "json", "pftrace", "otf2"),
|
||||
type=str.lower,
|
||||
)
|
||||
add_parser_bool_argument(
|
||||
io_options,
|
||||
"--output-config",
|
||||
help="Generate a output file of the rocprofv3 configuration, e.g. out_config.json",
|
||||
)
|
||||
io_options.add_argument(
|
||||
"--log-level",
|
||||
help="Set the desired log level",
|
||||
@@ -518,6 +523,11 @@ For MPI applications (or other job launchers such as SLURM), place rocprofv3 ins
|
||||
type=str,
|
||||
choices=("hour", "min", "sec", "msec", "usec", "nsec"),
|
||||
)
|
||||
add_parser_bool_argument(
|
||||
filter_options,
|
||||
"--selected-regions",
|
||||
help="If set, rocprofv3 will only profile regions of code surrounded by roctxProfilerResume(0) and roctxProfilerPause(0)",
|
||||
)
|
||||
|
||||
perfetto_options = parser.add_argument_group("Perfetto-specific options")
|
||||
|
||||
@@ -592,6 +602,19 @@ For MPI applications (or other job launchers such as SLURM), place rocprofv3 ins
|
||||
"--realpath",
|
||||
help=argparse.SUPPRESS,
|
||||
)
|
||||
advanced_options.add_argument(
|
||||
"--benchmark-mode",
|
||||
choices=(
|
||||
"disabled-sdk-contexts",
|
||||
"sdk-buffer-overhead",
|
||||
"sdk-callback-overhead",
|
||||
"tool-runtime-overhead",
|
||||
"execution-profile",
|
||||
),
|
||||
help=argparse.SUPPRESS,
|
||||
default=None,
|
||||
type=str.lower,
|
||||
)
|
||||
advanced_options.add_argument(
|
||||
"-A",
|
||||
"--agent-index",
|
||||
@@ -1034,6 +1057,7 @@ def run(app_args, args, **kwargs):
|
||||
|
||||
update_env("ROCPROF_OUTPUT_FILE_NAME", _output_file)
|
||||
update_env("ROCPROF_OUTPUT_PATH", _output_path)
|
||||
update_env("ROCPROF_OUTPUT_CONFIG_FILE", args.output_config, overwrite_if_true=True)
|
||||
if app_pass is not None and args.sub_directory is not None:
|
||||
app_env["ROCPROF_OUTPUT_PATH"] = os.path.join(
|
||||
f"{_output_path}", f"{args.sub_directory}{app_pass}"
|
||||
@@ -1198,6 +1222,11 @@ def run(app_args, args, **kwargs):
|
||||
args.truncate_kernels,
|
||||
overwrite_if_true=True,
|
||||
)
|
||||
update_env(
|
||||
"ROCPROF_SELECTED_REGIONS",
|
||||
args.selected_regions,
|
||||
overwrite_if_true=True,
|
||||
)
|
||||
|
||||
if args.list_avail:
|
||||
update_env(
|
||||
@@ -1241,6 +1270,24 @@ def run(app_args, args, **kwargs):
|
||||
args.log_level,
|
||||
)
|
||||
|
||||
if args.benchmark_mode:
|
||||
if args.benchmark_mode == "execution-profile":
|
||||
if args.group_by_queue is None:
|
||||
update_env(
|
||||
"ROCPROF_GROUP_BY_QUEUE",
|
||||
False,
|
||||
overwrite=True,
|
||||
)
|
||||
elif args.group_by_queue:
|
||||
fatal_error(
|
||||
"rocprofv3 requires --group-by-queue=false for --benchmark-mode=execution-profile"
|
||||
)
|
||||
|
||||
update_env(
|
||||
"ROCPROF_BENCHMARK_MODE",
|
||||
args.benchmark_mode,
|
||||
)
|
||||
|
||||
for opt, env_val in dict(
|
||||
[
|
||||
["kernel_rename", "KERNEL_RENAME"],
|
||||
|
||||
@@ -46,4 +46,4 @@ To run the built samples, ``cd`` into the ``build-rocprofiler-sdk-samples`` dire
|
||||
|
||||
ctest -V
|
||||
|
||||
The `-V` option enables verbose output, providing detailed information about the test execution.
|
||||
The `-V` option enables verbose output, providing detailed information about the test execution.
|
||||
|
||||
@@ -126,4 +126,4 @@ If you have ROCm version 6.2 or higher installed, you can use the package manage
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo zypper install rocprofiler-sdk
|
||||
$ sudo zypper install rocprofiler-sdk
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
}
|
||||
|
||||
#define ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(TYPE) \
|
||||
inline bool operator>(TYPE lhs, TYPE rhs) { return (lhs == rhs || !(lhs < rhs)); } \
|
||||
inline bool operator>(TYPE lhs, TYPE rhs) { return !(lhs == rhs || lhs < rhs); } \
|
||||
inline bool operator<=(TYPE lhs, TYPE rhs) { return (lhs == rhs || lhs < rhs); } \
|
||||
inline bool operator>=(TYPE lhs, TYPE rhs) { return !(lhs < rhs); }
|
||||
|
||||
|
||||
@@ -135,6 +135,29 @@ rocprofiler_configure_external_correlation_id_request_service(
|
||||
rocprofiler_external_correlation_id_request_cb_t callback,
|
||||
void* callback_args) ROCPROFILER_API ROCPROFILER_NONNULL(4);
|
||||
|
||||
/**
|
||||
* @brief Query the name of the external correlation request kind. The name retrieved from this
|
||||
* function is a string literal that is encoded in the read-only section of the binary (i.e. it is
|
||||
* always "allocated" and never "deallocated").
|
||||
*
|
||||
* @param [in] kind External correlation id request domain
|
||||
* @param [out] name If non-null and the name is a constant string that does not require dynamic
|
||||
* allocation, this paramter will be set to the address of the string literal, otherwise it will
|
||||
* be set to nullptr
|
||||
* @param [out] name_len If non-null, this will be assigned the length of the name (regardless of
|
||||
* the name is a constant string or requires dynamic allocation)
|
||||
* @return ::rocprofiler_status_t
|
||||
* @retval ::ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND Returned if the domain id is not valid
|
||||
* @retval ::ROCPROFILER_STATUS_SUCCESS Returned if a valid domain, regardless if there is a
|
||||
* constant string or not.
|
||||
*/
|
||||
ROCPROFILER_SDK_EXPERIMENTAL
|
||||
rocprofiler_status_t
|
||||
rocprofiler_query_external_correlation_id_request_kind_name(
|
||||
rocprofiler_external_correlation_id_request_kind_t kind,
|
||||
const char** name,
|
||||
uint64_t* name_len) ROCPROFILER_API;
|
||||
|
||||
/**
|
||||
* @brief Push default value for `external` field in ::rocprofiler_correlation_id_t onto stack.
|
||||
*
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
#define ROCPROFILER_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
|
||||
#define ROCPROFILER_VERSION_MINOR @PROJECT_VERSION_MINOR@
|
||||
#define ROCPROFILER_VERSION_PATCH @PROJECT_VERSION_PATCH@
|
||||
#define ROCPROFILER_SOVERSION (10000 * @PROJECT_VERSION_MAJOR@)
|
||||
#define ROCPROFILER_SOVERSION @PROJECT_VERSION_MAJOR@
|
||||
#define ROCPROFILER_VERSION_STRING "@FULL_VERSION_STRING@"
|
||||
#define ROCPROFILER_GIT_DESCRIBE "@ROCPROFILER_SDK_GIT_DESCRIBE@"
|
||||
#define ROCPROFILER_GIT_REVISION "@ROCPROFILER_SDK_GIT_REVISION@"
|
||||
|
||||
@@ -130,6 +130,7 @@ output_config::save(ArchiveT& ar) const
|
||||
CFG_SERIALIZE_MEMBER(otf2_output);
|
||||
CFG_SERIALIZE_MEMBER(summary_output);
|
||||
CFG_SERIALIZE_MEMBER(kernel_rename);
|
||||
CFG_SERIALIZE_MEMBER(group_by_queue);
|
||||
|
||||
#undef CFG_SERIALIZE_MEMBER
|
||||
#undef CFG_SERIALIZE_NAMED_MEMBER
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
rocprofiler_activate_clang_tidy()
|
||||
|
||||
set(TOOL_HEADERS config.hpp helper.hpp stream_stack.hpp)
|
||||
set(TOOL_HEADERS config.hpp execution_profile.hpp helper.hpp stream_stack.hpp)
|
||||
|
||||
set(TOOL_SOURCES config.cpp main.c tool.cpp stream_stack.cpp)
|
||||
|
||||
|
||||
@@ -319,6 +319,23 @@ config::config()
|
||||
std::stoull(_config_params.at(2))});
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmarking Enable/Disable
|
||||
if(!benchmark_mode_env.empty())
|
||||
{
|
||||
const auto valid_options = std::unordered_map<std::string_view, config::benchmark>{
|
||||
{"disabled-sdk-contexts", benchmark::disabled_contexts_overhead},
|
||||
{"sdk-buffer-overhead", benchmark::sdk_buffered_overhead},
|
||||
{"sdk-callback-overhead", benchmark::sdk_callback_overhead},
|
||||
{"tool-runtime-overhead", benchmark::tool_runtime_overhead},
|
||||
{"execution-profile", benchmark::execution_profile},
|
||||
};
|
||||
|
||||
ROCP_FATAL_IF(valid_options.count(benchmark_mode_env) == 0)
|
||||
<< fmt::format("Invalid value for ROCPROF_BENCHMARK_MODE: {}", benchmark_mode_env);
|
||||
|
||||
benchmark_mode = valid_options.at(benchmark_mode_env);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
|
||||
@@ -87,6 +87,16 @@ struct config : output_config
|
||||
void save(ArchiveT& ar) const;
|
||||
};
|
||||
|
||||
enum class benchmark
|
||||
{
|
||||
none = 0,
|
||||
disabled_contexts_overhead,
|
||||
sdk_callback_overhead,
|
||||
sdk_buffered_overhead,
|
||||
tool_runtime_overhead,
|
||||
execution_profile,
|
||||
};
|
||||
|
||||
config();
|
||||
|
||||
~config() = default;
|
||||
@@ -114,11 +124,13 @@ struct config : output_config
|
||||
bool rocjpeg_api_trace = get_env("ROCPROF_ROCJPEG_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);
|
||||
bool pc_sampling_host_trap = false;
|
||||
bool advanced_thread_trace = get_env("ROCPROF_ADVANCED_THREAD_TRACE", false);
|
||||
bool pc_sampling_stochastic = false;
|
||||
bool att_serialize_all = get_env("ROCPROF_ATT_PARAM_SERIALIZE_ALL", false);
|
||||
bool enable_signal_handlers = get_env("ROCPROF_SIGNAL_HANDLERS", true);
|
||||
bool selected_regions = get_env("ROCPROF_SELECTED_REGIONS", false);
|
||||
bool output_config_file = get_env("ROCPROF_OUTPUT_CONFIG_FILE", false);
|
||||
bool pc_sampling_host_trap = false;
|
||||
bool pc_sampling_stochastic = false;
|
||||
size_t pc_sampling_interval = get_env("ROCPROF_PC_SAMPLING_INTERVAL", 1);
|
||||
rocprofiler_pc_sampling_method_t pc_sampling_method_value = ROCPROFILER_PC_SAMPLING_METHOD_NONE;
|
||||
rocprofiler_pc_sampling_unit_t pc_sampling_unit_value = ROCPROFILER_PC_SAMPLING_UNIT_NONE;
|
||||
@@ -148,6 +160,9 @@ struct config : output_config
|
||||
uint64_t counter_groups_interval = get_env("ROCPROF_COUNTER_GROUPS_INTERVAL", 1);
|
||||
uint64_t minimum_output_bytes = get_env("ROCPROF_MINIMUM_OUTPUT_BYTES", 0);
|
||||
|
||||
std::string benchmark_mode_env = get_env("ROCPROF_BENCHMARK_MODE", "");
|
||||
benchmark benchmark_mode = benchmark::none;
|
||||
|
||||
template <typename ArchiveT>
|
||||
void save(ArchiveT&) const;
|
||||
|
||||
@@ -180,6 +195,8 @@ template <typename ArchiveT>
|
||||
void
|
||||
config::save(ArchiveT& ar) const
|
||||
{
|
||||
CFG_SERIALIZE_NAMED_MEMBER("benchmark_mode", benchmark_mode_env);
|
||||
|
||||
CFG_SERIALIZE_MEMBER(kernel_trace);
|
||||
CFG_SERIALIZE_MEMBER(hsa_core_api_trace);
|
||||
CFG_SERIALIZE_MEMBER(hsa_amd_ext_api_trace);
|
||||
@@ -194,6 +211,7 @@ config::save(ArchiveT& ar) const
|
||||
CFG_SERIALIZE_MEMBER(hip_compiler_api_trace);
|
||||
CFG_SERIALIZE_MEMBER(rccl_api_trace);
|
||||
CFG_SERIALIZE_MEMBER(rocdecode_api_trace);
|
||||
CFG_SERIALIZE_MEMBER(rocjpeg_api_trace);
|
||||
|
||||
CFG_SERIALIZE_MEMBER(mpi_rank);
|
||||
CFG_SERIALIZE_MEMBER(mpi_size);
|
||||
@@ -207,7 +225,13 @@ config::save(ArchiveT& ar) const
|
||||
CFG_SERIALIZE_MEMBER(truncate);
|
||||
CFG_SERIALIZE_MEMBER(minimum_output_bytes);
|
||||
CFG_SERIALIZE_MEMBER(enable_signal_handlers);
|
||||
CFG_SERIALIZE_MEMBER(selected_regions);
|
||||
|
||||
CFG_SERIALIZE_MEMBER(counter_groups_random_seed);
|
||||
CFG_SERIALIZE_MEMBER(counter_groups_interval);
|
||||
|
||||
CFG_SERIALIZE_MEMBER(pc_sampling_host_trap);
|
||||
CFG_SERIALIZE_MEMBER(pc_sampling_stochastic);
|
||||
CFG_SERIALIZE_MEMBER(pc_sampling_method);
|
||||
CFG_SERIALIZE_MEMBER(pc_sampling_unit);
|
||||
CFG_SERIALIZE_MEMBER(pc_sampling_interval);
|
||||
@@ -222,8 +246,10 @@ config::save(ArchiveT& ar) const
|
||||
CFG_SERIALIZE_MEMBER(att_param_target_cu);
|
||||
CFG_SERIALIZE_MEMBER(att_capability);
|
||||
CFG_SERIALIZE_MEMBER(att_param_perfcounters);
|
||||
CFG_SERIALIZE_MEMBER(att_param_perf_ctrl);
|
||||
|
||||
static_cast<const base_type&>(*this).save(ar);
|
||||
// serialize the base class
|
||||
static_cast<const base_type*>(this)->save(ar);
|
||||
}
|
||||
|
||||
#undef CFG_SERIALIZE_MEMBER
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lib/output/metadata.hpp"
|
||||
|
||||
#include <rocprofiler-sdk/external_correlation.h>
|
||||
#include <rocprofiler-sdk/fwd.h>
|
||||
#include <rocprofiler-sdk/cxx/hash.hpp>
|
||||
#include <rocprofiler-sdk/cxx/operators.hpp>
|
||||
|
||||
#include <cereal/cereal.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace rocprofiler
|
||||
{
|
||||
namespace tool
|
||||
{
|
||||
struct execution_profile_data
|
||||
{
|
||||
using extern_corr_id_request_t = rocprofiler_external_correlation_id_request_kind_t;
|
||||
using operation_set_t = std::unordered_set<rocprofiler_tracing_operation_t>;
|
||||
|
||||
std::unordered_map<extern_corr_id_request_t, uint64_t> category_count = {};
|
||||
std::unordered_map<extern_corr_id_request_t, operation_set_t> category_op_count = {};
|
||||
std::unordered_set<rocprofiler_thread_id_t> threads = {};
|
||||
std::unordered_set<rocprofiler_context_id_t> contexts = {};
|
||||
};
|
||||
|
||||
struct execution_profile_category_data
|
||||
{
|
||||
uint64_t count = 0; // total invocations of a given category
|
||||
uint64_t unique = 0; // number of unique operations
|
||||
};
|
||||
} // namespace tool
|
||||
} // namespace rocprofiler
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
template <typename ArchiveT>
|
||||
void
|
||||
save(ArchiveT& ar, ::rocprofiler::tool::execution_profile_category_data data)
|
||||
{
|
||||
ar(cereal::make_nvp("count", data.count));
|
||||
ar(cereal::make_nvp("unique", data.unique));
|
||||
}
|
||||
|
||||
template <typename ArchiveT>
|
||||
void
|
||||
save(ArchiveT& ar, const ::rocprofiler::tool::execution_profile_data& data)
|
||||
{
|
||||
namespace tool = ::rocprofiler::tool;
|
||||
|
||||
using category_count_map_t = std::map<std::string, tool::execution_profile_category_data>;
|
||||
|
||||
auto _category_count = category_count_map_t{};
|
||||
for(auto itr : data.category_count)
|
||||
{
|
||||
const char* _name = nullptr;
|
||||
ROCPROFILER_CHECK(rocprofiler_query_external_correlation_id_request_kind_name(
|
||||
itr.first, &_name, nullptr));
|
||||
if(_name)
|
||||
{
|
||||
auto _unique_ops = data.category_op_count.at(itr.first).size();
|
||||
auto _kind_name = std::string{_name};
|
||||
std::for_each(
|
||||
_kind_name.begin(), _kind_name.end(), [](auto& v) { v = ::std::tolower(v); });
|
||||
|
||||
_category_count.emplace(_kind_name,
|
||||
tool::execution_profile_category_data{itr.second, _unique_ops});
|
||||
}
|
||||
}
|
||||
|
||||
ar(cereal::make_nvp("threads", data.threads.size()));
|
||||
ar(cereal::make_nvp("contexts", data.contexts.size()));
|
||||
for(auto itr : _category_count)
|
||||
ar(cereal::make_nvp(itr.first.c_str(), itr.second));
|
||||
}
|
||||
} // namespace cereal
|
||||
@@ -20,10 +20,13 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "rocprofiler-sdk/defines.h"
|
||||
#include "rocprofiler-sdk/dispatch_counting_service.h"
|
||||
#define _GNU_SOURCE 1
|
||||
#define _DEFAULT_SOURCE 1
|
||||
|
||||
#include "config.hpp"
|
||||
#include "execution_profile.hpp"
|
||||
#include "helper.hpp"
|
||||
#include "stream_stack.hpp"
|
||||
|
||||
@@ -50,6 +53,7 @@
|
||||
#include "lib/output/output_stream.hpp"
|
||||
#include "lib/output/statistics.hpp"
|
||||
#include "lib/output/stream_info.hpp"
|
||||
#include "lib/output/timestamps.hpp"
|
||||
#include "lib/output/tmp_file.hpp"
|
||||
#include "lib/output/tmp_file_buffer.hpp"
|
||||
|
||||
@@ -63,11 +67,13 @@
|
||||
#include <rocprofiler-sdk/internal_threading.h>
|
||||
#include <rocprofiler-sdk/marker/api_id.h>
|
||||
#include <rocprofiler-sdk/rocprofiler.h>
|
||||
#include <rocprofiler-sdk/version.h>
|
||||
#include <rocprofiler-sdk/cxx/hash.hpp>
|
||||
#include <rocprofiler-sdk/cxx/operators.hpp>
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@@ -146,14 +152,6 @@ add_destructor(Tp*& ptr)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#define ADD_DESTRUCTOR(PTR) \
|
||||
{ \
|
||||
static auto _once = std::once_flag{}; \
|
||||
std::call_once(_once, []() { add_destructor(PTR); }); \
|
||||
}
|
||||
|
||||
#undef ADD_DESTRUCTOR
|
||||
|
||||
struct chained_siginfo
|
||||
{
|
||||
int signo = 0;
|
||||
@@ -207,6 +205,11 @@ struct buffer_ids
|
||||
rocjpeg_api_trace,
|
||||
pc_sampling_stochastic};
|
||||
}
|
||||
auto pc_sampling_buffers_as_array() const
|
||||
{
|
||||
return std::array<rocprofiler_buffer_id_t, 2>{pc_sampling_host_trap,
|
||||
pc_sampling_stochastic};
|
||||
}
|
||||
};
|
||||
|
||||
buffer_ids&
|
||||
@@ -246,10 +249,11 @@ using kernel_iteration_t = std::unordered_map<rocprofiler_kernel_id_t, size_t
|
||||
using kernel_rename_map_t = std::unordered_map<uint64_t, uint64_t>;
|
||||
using kernel_rename_stack_t = std::stack<uint64_t>;
|
||||
|
||||
auto* tool_metadata = as_pointer<tool::metadata>(tool::metadata::inprocess{});
|
||||
auto target_kernels = common::Synchronized<targeted_kernels_map_t>{};
|
||||
std::mutex att_shader_data;
|
||||
auto* tool_metadata = as_pointer<tool::metadata>(tool::metadata::inprocess{});
|
||||
auto target_kernels = common::Synchronized<targeted_kernels_map_t>{};
|
||||
auto* execution_profile = as_pointer<common::Synchronized<tool::execution_profile_data>>();
|
||||
auto counter_collection_ctx = rocprofiler_context_id_t{0};
|
||||
std::mutex att_shader_data;
|
||||
|
||||
thread_local auto thread_dispatch_rename = as_pointer<kernel_rename_stack_t>();
|
||||
thread_local auto thread_dispatch_rename_dtor = common::scope_destructor{[]() {
|
||||
@@ -336,10 +340,12 @@ get_client_ctx()
|
||||
void
|
||||
flush()
|
||||
{
|
||||
constexpr auto null_buffer_id = rocprofiler_buffer_id_t{.handle = 0};
|
||||
|
||||
ROCP_INFO << "flushing buffers...";
|
||||
for(auto itr : get_buffers().as_array())
|
||||
{
|
||||
if(itr.handle > 0)
|
||||
if(itr > null_buffer_id)
|
||||
{
|
||||
ROCP_INFO << "flushing buffer " << itr.handle;
|
||||
ROCPROFILER_CALL(rocprofiler_flush_buffer(itr), "buffer flush");
|
||||
@@ -419,6 +425,32 @@ collection_period_cntrl(std::promise<void>&& _promise, rocprofiler_context_id_t
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
record_execution_profile(rocprofiler_thread_id_t thr_id,
|
||||
rocprofiler_context_id_t ctx_id,
|
||||
rocprofiler_external_correlation_id_request_kind_t kind,
|
||||
rocprofiler_tracing_operation_t op,
|
||||
uint64_t /*internal_corr_id*/,
|
||||
rocprofiler_user_data_t* /*external_corr_id*/,
|
||||
void* /*user_data*/)
|
||||
{
|
||||
auto _record_data = [](tool::execution_profile_data& _data,
|
||||
rocprofiler_thread_id_t _thr_id,
|
||||
rocprofiler_context_id_t _ctx_id,
|
||||
rocprofiler_external_correlation_id_request_kind_t _kind,
|
||||
rocprofiler_tracing_operation_t _op) {
|
||||
_data.category_count[_kind] += 1;
|
||||
_data.category_op_count[_kind].emplace(_op);
|
||||
_data.threads.emplace(_thr_id);
|
||||
_data.contexts.emplace(_ctx_id);
|
||||
};
|
||||
|
||||
if(execution_profile)
|
||||
execution_profile->wlock(std::move(_record_data), thr_id, ctx_id, kind, op);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
set_kernel_rename_and_stream_display_correlation_id(
|
||||
rocprofiler_thread_id_t thr_id,
|
||||
@@ -623,6 +655,27 @@ runtime_initialization_callback(rocprofiler_callback_tracing_record_t record,
|
||||
common::consume_args(user_data, data);
|
||||
}
|
||||
|
||||
void
|
||||
dummy_callback_tracing_callback(rocprofiler_callback_tracing_record_t /*record*/,
|
||||
rocprofiler_user_data_t* /*user_data*/,
|
||||
void* /*data*/)
|
||||
{}
|
||||
|
||||
void
|
||||
dummy_counter_dispatch_callback(rocprofiler_dispatch_counting_service_data_t,
|
||||
rocprofiler_profile_config_id_t*,
|
||||
rocprofiler_user_data_t*,
|
||||
void*)
|
||||
{}
|
||||
|
||||
void
|
||||
dummy_counter_record_callback(rocprofiler_dispatch_counting_service_data_t,
|
||||
rocprofiler_record_counter_t*,
|
||||
size_t,
|
||||
rocprofiler_user_data_t,
|
||||
void*)
|
||||
{}
|
||||
|
||||
void
|
||||
callback_tracing_callback(rocprofiler_callback_tracing_record_t record,
|
||||
rocprofiler_user_data_t* user_data,
|
||||
@@ -865,6 +918,10 @@ code_object_tracing_callback(rocprofiler_callback_tracing_record_t record,
|
||||
auto* sym_data = static_cast<tool::rocprofiler_kernel_symbol_info_t*>(record.payload);
|
||||
if(record.phase == ROCPROFILER_CALLBACK_PHASE_LOAD)
|
||||
{
|
||||
ROCP_TRACE << fmt::format("adding kernel symbol info for kernel_id={} :: {}",
|
||||
sym_data->kernel_id,
|
||||
sym_data->kernel_name);
|
||||
|
||||
auto success = CHECK_NOTNULL(tool_metadata)
|
||||
->add_kernel_symbol(kernel_symbol_info{
|
||||
get_dereference(sym_data),
|
||||
@@ -917,6 +974,15 @@ code_object_tracing_callback(rocprofiler_callback_tracing_record_t record,
|
||||
(void) data;
|
||||
}
|
||||
|
||||
void
|
||||
dummy_buffered_tracing_callback(rocprofiler_context_id_t /*context*/,
|
||||
rocprofiler_buffer_id_t /*buffer_id*/,
|
||||
rocprofiler_record_header_t** /*headers*/,
|
||||
size_t /*num_headers*/,
|
||||
void* /*user_data*/,
|
||||
uint64_t /*drop_count*/)
|
||||
{}
|
||||
|
||||
void
|
||||
buffered_tracing_callback(rocprofiler_context_id_t /*context*/,
|
||||
rocprofiler_buffer_id_t /*buffer_id*/,
|
||||
@@ -1234,12 +1300,12 @@ get_att_perfcounter_params(rocprofiler_agent_id_t agen
|
||||
}
|
||||
|
||||
void
|
||||
rocprofiler_pc_sampling_callback(rocprofiler_context_id_t /* context_id*/,
|
||||
rocprofiler_buffer_id_t /* buffer_id*/,
|
||||
rocprofiler_record_header_t** headers,
|
||||
size_t num_headers,
|
||||
void* /*data*/,
|
||||
uint64_t /* drop_count*/)
|
||||
pc_sampling_callback(rocprofiler_context_id_t /* context_id*/,
|
||||
rocprofiler_buffer_id_t /* buffer_id*/,
|
||||
rocprofiler_record_header_t** headers,
|
||||
size_t num_headers,
|
||||
void* /*data*/,
|
||||
uint64_t /* drop_count*/)
|
||||
{
|
||||
if(!headers) return;
|
||||
|
||||
@@ -1345,10 +1411,10 @@ att_dispatch_callback(rocprofiler_agent_id_t /* agent_id */,
|
||||
}
|
||||
|
||||
void
|
||||
dispatch_callback(rocprofiler_dispatch_counting_service_data_t dispatch_data,
|
||||
rocprofiler_counter_config_id_t* config,
|
||||
rocprofiler_user_data_t* user_data,
|
||||
void* /*callback_data_args*/)
|
||||
counter_dispatch_callback(rocprofiler_dispatch_counting_service_data_t dispatch_data,
|
||||
rocprofiler_counter_config_id_t* config,
|
||||
rocprofiler_user_data_t* user_data,
|
||||
void* /*callback_data_args*/)
|
||||
{
|
||||
static auto kernel_iteration = common::Synchronized<kernel_iteration_t, true>{};
|
||||
|
||||
@@ -1499,9 +1565,10 @@ if_pc_sample_config_match(rocprofiler_agent_id_t agent_id,
|
||||
}
|
||||
|
||||
void
|
||||
configure_pc_sampling_on_all_agents(uint64_t buffer_size,
|
||||
uint64_t buffer_watermark,
|
||||
void* tool_data)
|
||||
configure_pc_sampling_on_all_agents(uint64_t buffer_size,
|
||||
uint64_t buffer_watermark,
|
||||
void* tool_data,
|
||||
rocprofiler_buffer_tracing_cb_t pc_sampling_cb)
|
||||
{
|
||||
auto method = tool::get_config().pc_sampling_method_value;
|
||||
auto unit = tool::get_config().pc_sampling_unit_value;
|
||||
@@ -1515,7 +1582,7 @@ configure_pc_sampling_on_all_agents(uint64_t buffer_size,
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
rocprofiler_pc_sampling_callback,
|
||||
pc_sampling_cb,
|
||||
tool_data,
|
||||
buffer_id),
|
||||
"buffer creation");
|
||||
@@ -1544,9 +1611,81 @@ configure_pc_sampling_on_all_agents(uint64_t buffer_size,
|
||||
ROCP_FATAL << "Given PC sampling configuration is not supported on any of the agents";
|
||||
}
|
||||
|
||||
struct real_callbacks_t
|
||||
{};
|
||||
|
||||
struct dummy_callbacks_t
|
||||
{};
|
||||
|
||||
constexpr auto use_real_callbacks = real_callbacks_t{};
|
||||
constexpr auto use_dummy_callbacks = dummy_callbacks_t{};
|
||||
|
||||
struct tracing_callbacks_t
|
||||
{
|
||||
tracing_callbacks_t() = delete;
|
||||
|
||||
tracing_callbacks_t(real_callbacks_t)
|
||||
: code_object_tracing{code_object_tracing_callback}
|
||||
, cntrl_tracing{cntrl_tracing_callback}
|
||||
, kernel_rename{kernel_rename_callback}
|
||||
, hip_stream{hip_stream_display_callback}
|
||||
, callback_tracing{callback_tracing_callback}
|
||||
, buffered_tracing{buffered_tracing_callback}
|
||||
, pc_sampling{pc_sampling_callback}
|
||||
, att_dispatch{att_dispatch_callback}
|
||||
, att_shader_data{att_shader_data_callback}
|
||||
, counter_dispatch{counter_dispatch_callback}
|
||||
, counter_record{counter_record_callback}
|
||||
{}
|
||||
|
||||
explicit tracing_callbacks_t(dummy_callbacks_t)
|
||||
: code_object_tracing{dummy_callback_tracing_callback}
|
||||
, cntrl_tracing{dummy_callback_tracing_callback}
|
||||
, kernel_rename{dummy_callback_tracing_callback}
|
||||
, hip_stream{dummy_callback_tracing_callback}
|
||||
, callback_tracing{dummy_callback_tracing_callback}
|
||||
, buffered_tracing{dummy_buffered_tracing_callback}
|
||||
, pc_sampling{dummy_buffered_tracing_callback}
|
||||
, counter_dispatch{dummy_counter_dispatch_callback}
|
||||
, counter_record{dummy_counter_record_callback}
|
||||
{}
|
||||
|
||||
const rocprofiler_callback_tracing_cb_t code_object_tracing = nullptr;
|
||||
const rocprofiler_callback_tracing_cb_t cntrl_tracing = nullptr;
|
||||
const rocprofiler_callback_tracing_cb_t kernel_rename = nullptr;
|
||||
const rocprofiler_callback_tracing_cb_t hip_stream = nullptr;
|
||||
const rocprofiler_callback_tracing_cb_t callback_tracing = nullptr;
|
||||
const rocprofiler_buffer_tracing_cb_t buffered_tracing = nullptr;
|
||||
const rocprofiler_buffer_tracing_cb_t pc_sampling = nullptr;
|
||||
const rocprofiler_att_dispatch_callback_t att_dispatch = nullptr;
|
||||
const rocprofiler_att_shader_data_callback_t att_shader_data = nullptr;
|
||||
const rocprofiler_dispatch_counting_service_cb_t counter_dispatch = nullptr;
|
||||
const rocprofiler_dispatch_counting_record_cb_t counter_record = nullptr;
|
||||
};
|
||||
|
||||
auto
|
||||
get_tracing_callbacks()
|
||||
{
|
||||
// for the benchmarking modes of sdk buffer/callback overhead, we are measuring the cost
|
||||
// of the SDK invoking the callbacks to the tool. We do not want to include the overhead
|
||||
// of the tool doing any work so we use "dummy" callbacks (i.e. functions which just
|
||||
// immediately return)
|
||||
if(tool::get_config().benchmark_mode == tool::config::benchmark::sdk_buffered_overhead ||
|
||||
tool::get_config().benchmark_mode == tool::config::benchmark::sdk_callback_overhead ||
|
||||
tool::get_config().benchmark_mode == tool::config::benchmark::execution_profile)
|
||||
{
|
||||
return tracing_callbacks_t{use_dummy_callbacks};
|
||||
}
|
||||
|
||||
return tracing_callbacks_t{use_real_callbacks};
|
||||
}
|
||||
|
||||
int
|
||||
tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
|
||||
{
|
||||
static constexpr auto null_context_id = rocprofiler_context_id_t{.handle = 0};
|
||||
static constexpr auto null_buffer_id = rocprofiler_buffer_id_t{.handle = 0};
|
||||
|
||||
client_finalizer = fini_func;
|
||||
|
||||
const uint64_t buffer_size = 16 * common::units::get_page_size();
|
||||
@@ -1556,18 +1695,39 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_create_context(&get_client_ctx()), "create context failed");
|
||||
|
||||
auto code_obj_ctx = rocprofiler_context_id_t{0};
|
||||
auto code_obj_ctx = null_context_id;
|
||||
ROCPROFILER_CALL(rocprofiler_create_context(&code_obj_ctx), "failed to create context");
|
||||
|
||||
auto start_context = [](rocprofiler_context_id_t ctx_id, std::string_view msg) {
|
||||
using benchmark = tool::config::benchmark;
|
||||
// do not start context if we are benchmarking the overhead of a service
|
||||
// being available but unused by any contexts
|
||||
if(tool::get_config().benchmark_mode != benchmark::disabled_contexts_overhead &&
|
||||
ctx_id != null_context_id)
|
||||
{
|
||||
if(tool::get_config().benchmark_mode == benchmark::execution_profile)
|
||||
{
|
||||
ROCPROFILER_CHECK(rocprofiler_configure_external_correlation_id_request_service(
|
||||
ctx_id, nullptr, 0, record_execution_profile, nullptr));
|
||||
}
|
||||
|
||||
ROCP_INFO << fmt::format("starting {} context...", msg);
|
||||
ROCPROFILER_CHECK(rocprofiler_start_context(ctx_id));
|
||||
}
|
||||
};
|
||||
|
||||
auto callbacks = get_tracing_callbacks();
|
||||
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_configure_callback_tracing_service(code_obj_ctx,
|
||||
ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT,
|
||||
nullptr,
|
||||
0,
|
||||
code_object_tracing_callback,
|
||||
callbacks.code_object_tracing,
|
||||
nullptr),
|
||||
"code object tracing configure failed");
|
||||
ROCPROFILER_CALL(rocprofiler_start_context(code_obj_ctx), "start context failed");
|
||||
|
||||
start_context(code_obj_ctx, "code object");
|
||||
|
||||
if(tool::get_config().marker_api_trace)
|
||||
{
|
||||
@@ -1576,11 +1736,11 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
|
||||
ROCPROFILER_CALLBACK_TRACING_MARKER_CORE_API,
|
||||
nullptr,
|
||||
0,
|
||||
callback_tracing_callback,
|
||||
callbacks.callback_tracing,
|
||||
nullptr),
|
||||
"callback tracing service failed to configure");
|
||||
|
||||
auto pause_resume_ctx = rocprofiler_context_id_t{0};
|
||||
auto pause_resume_ctx = null_context_id;
|
||||
ROCPROFILER_CALL(rocprofiler_create_context(&pause_resume_ctx), "failed to create context");
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_configure_callback_tracing_service(
|
||||
@@ -1588,122 +1748,154 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
|
||||
ROCPROFILER_CALLBACK_TRACING_MARKER_CONTROL_API,
|
||||
nullptr,
|
||||
0,
|
||||
cntrl_tracing_callback,
|
||||
callbacks.cntrl_tracing,
|
||||
static_cast<void*>(&get_client_ctx())),
|
||||
"callback tracing service failed to configure");
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_start_context(pause_resume_ctx), "start context failed");
|
||||
start_context(pause_resume_ctx, "marker pause/resume");
|
||||
}
|
||||
|
||||
if(tool::get_config().kernel_trace)
|
||||
struct buffer_service_config
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
buffered_tracing_callback,
|
||||
tool_data,
|
||||
&get_buffers().kernel_trace),
|
||||
"buffer creation");
|
||||
bool option = false;
|
||||
rocprofiler_buffer_tracing_kind_t kind = ROCPROFILER_BUFFER_TRACING_NONE;
|
||||
rocprofiler_buffer_id_t& buffer_id;
|
||||
};
|
||||
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_configure_buffer_tracing_service(get_client_ctx(),
|
||||
ROCPROFILER_BUFFER_TRACING_KERNEL_DISPATCH,
|
||||
nullptr,
|
||||
0,
|
||||
get_buffers().kernel_trace),
|
||||
"buffer tracing service for kernel dispatch configure");
|
||||
}
|
||||
|
||||
if(tool::get_config().memory_copy_trace)
|
||||
for(auto&& itr : {buffer_service_config{tool::get_config().kernel_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_KERNEL_DISPATCH,
|
||||
get_buffers().kernel_trace},
|
||||
buffer_service_config{tool::get_config().memory_copy_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_MEMORY_COPY,
|
||||
get_buffers().memory_copy_trace},
|
||||
buffer_service_config{tool::get_config().scratch_memory_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_SCRATCH_MEMORY,
|
||||
get_buffers().scratch_memory},
|
||||
buffer_service_config{tool::get_config().hsa_core_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HSA_CORE_API,
|
||||
get_buffers().hsa_api_trace},
|
||||
buffer_service_config{tool::get_config().hsa_amd_ext_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HSA_AMD_EXT_API,
|
||||
get_buffers().hsa_api_trace},
|
||||
buffer_service_config{tool::get_config().hsa_image_ext_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HSA_IMAGE_EXT_API,
|
||||
get_buffers().hsa_api_trace},
|
||||
buffer_service_config{tool::get_config().hsa_finalizer_ext_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HSA_FINALIZE_EXT_API,
|
||||
get_buffers().hsa_api_trace},
|
||||
buffer_service_config{tool::get_config().hip_runtime_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HIP_RUNTIME_API_EXT,
|
||||
get_buffers().hip_api_trace},
|
||||
buffer_service_config{tool::get_config().hip_compiler_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HIP_COMPILER_API_EXT,
|
||||
get_buffers().hip_api_trace},
|
||||
buffer_service_config{tool::get_config().rccl_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_RCCL_API,
|
||||
get_buffers().rccl_api_trace},
|
||||
buffer_service_config{tool::get_config().memory_allocation_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_MEMORY_ALLOCATION,
|
||||
get_buffers().memory_allocation_trace},
|
||||
buffer_service_config{tool::get_config().rocdecode_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_ROCDECODE_API_EXT,
|
||||
get_buffers().rocdecode_api_trace},
|
||||
buffer_service_config{tool::get_config().rocjpeg_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_ROCJPEG_API,
|
||||
get_buffers().rocjpeg_api_trace}})
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
buffered_tracing_callback,
|
||||
nullptr,
|
||||
&get_buffers().memory_copy_trace),
|
||||
"create memory copy buffer");
|
||||
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_configure_buffer_tracing_service(get_client_ctx(),
|
||||
ROCPROFILER_BUFFER_TRACING_MEMORY_COPY,
|
||||
nullptr,
|
||||
0,
|
||||
get_buffers().memory_copy_trace),
|
||||
"buffer tracing service for memory copy configure");
|
||||
}
|
||||
|
||||
if(tool::get_config().memory_allocation_trace)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
buffered_tracing_callback,
|
||||
nullptr,
|
||||
&get_buffers().memory_allocation_trace),
|
||||
"create memory allocation buffer");
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_configure_buffer_tracing_service(
|
||||
get_client_ctx(),
|
||||
ROCPROFILER_BUFFER_TRACING_MEMORY_ALLOCATION,
|
||||
nullptr,
|
||||
0,
|
||||
get_buffers().memory_allocation_trace),
|
||||
"buffer tracing service for memory allocation configure");
|
||||
}
|
||||
|
||||
if(tool::get_config().scratch_memory_trace)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
buffered_tracing_callback,
|
||||
tool_data,
|
||||
&get_buffers().scratch_memory),
|
||||
"buffer creation");
|
||||
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_configure_buffer_tracing_service(get_client_ctx(),
|
||||
ROCPROFILER_BUFFER_TRACING_SCRATCH_MEMORY,
|
||||
nullptr,
|
||||
0,
|
||||
get_buffers().scratch_memory),
|
||||
"buffer tracing service for scratch memory configure");
|
||||
}
|
||||
|
||||
if(tool::get_config().hsa_core_api_trace || tool::get_config().hsa_amd_ext_api_trace ||
|
||||
tool::get_config().hsa_image_ext_api_trace || tool::get_config().hsa_finalizer_ext_api_trace)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
buffered_tracing_callback,
|
||||
tool_data,
|
||||
&get_buffers().hsa_api_trace),
|
||||
"buffer creation");
|
||||
|
||||
using optpair_t = std::pair<bool, rocprofiler_buffer_tracing_kind_t>;
|
||||
for(auto itr : {optpair_t{tool::get_config().hsa_core_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HSA_CORE_API},
|
||||
optpair_t{tool::get_config().hsa_amd_ext_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HSA_AMD_EXT_API},
|
||||
optpair_t{tool::get_config().hsa_image_ext_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HSA_IMAGE_EXT_API},
|
||||
optpair_t{tool::get_config().hsa_finalizer_ext_api_trace,
|
||||
ROCPROFILER_BUFFER_TRACING_HSA_FINALIZE_EXT_API}})
|
||||
if(itr.option)
|
||||
{
|
||||
if(itr.first)
|
||||
// in sdk callback overhead benchmarking, we don't want to use the buffer services
|
||||
if(tool::get_config().benchmark_mode == tool::config::benchmark::sdk_callback_overhead)
|
||||
continue;
|
||||
|
||||
if(itr.buffer_id == null_buffer_id)
|
||||
{
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_configure_buffer_tracing_service(
|
||||
get_client_ctx(), itr.second, nullptr, 0, get_buffers().hsa_api_trace),
|
||||
"buffer tracing service for hsa api configure");
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
callbacks.buffered_tracing,
|
||||
tool_data,
|
||||
&itr.buffer_id),
|
||||
"buffer creation");
|
||||
|
||||
ROCP_FATAL_IF(itr.buffer_id.handle == 0) << "failed to create buffer";
|
||||
|
||||
auto cb_thread = rocprofiler_callback_thread_t{};
|
||||
|
||||
ROCP_INFO << "creating dedicated callback thread for buffer "
|
||||
<< itr.buffer_id.handle;
|
||||
ROCPROFILER_CALL(rocprofiler_create_callback_thread(&cb_thread),
|
||||
"creating callback thread");
|
||||
|
||||
ROCP_INFO << "assigning buffer " << itr.buffer_id.handle << " to callback thread "
|
||||
<< cb_thread.handle;
|
||||
ROCPROFILER_CALL(rocprofiler_assign_callback_thread(itr.buffer_id, cb_thread),
|
||||
"assigning callback thread");
|
||||
}
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_configure_buffer_tracing_service(
|
||||
get_client_ctx(), itr.kind, nullptr, 0, itr.buffer_id),
|
||||
"buffer tracing service configure");
|
||||
}
|
||||
}
|
||||
|
||||
struct callback_service_config
|
||||
{
|
||||
bool option = false;
|
||||
rocprofiler_callback_tracing_kind_t kind = ROCPROFILER_CALLBACK_TRACING_NONE;
|
||||
rocprofiler_callback_tracing_cb_t callback = nullptr;
|
||||
};
|
||||
|
||||
for(auto&& itr : {callback_service_config{tool::get_config().kernel_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_KERNEL_DISPATCH,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().memory_copy_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_MEMORY_COPY,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().scratch_memory_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_SCRATCH_MEMORY,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().hsa_core_api_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_HSA_CORE_API,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().hsa_amd_ext_api_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_HSA_AMD_EXT_API,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().hsa_image_ext_api_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_HSA_IMAGE_EXT_API,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().hsa_finalizer_ext_api_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_HSA_FINALIZE_EXT_API,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().hip_runtime_api_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_HIP_RUNTIME_API,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().hip_compiler_api_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_HIP_COMPILER_API,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().rccl_api_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_RCCL_API,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().memory_allocation_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_MEMORY_ALLOCATION,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().rocdecode_api_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_ROCDECODE_API,
|
||||
dummy_callback_tracing_callback},
|
||||
callback_service_config{tool::get_config().rocjpeg_api_trace,
|
||||
ROCPROFILER_CALLBACK_TRACING_ROCJPEG_API,
|
||||
dummy_callback_tracing_callback}})
|
||||
{
|
||||
if(itr.option)
|
||||
{
|
||||
// in sdk callback overhead benchmarking, we don't want to use the buffer services
|
||||
if(tool::get_config().benchmark_mode != tool::config::benchmark::sdk_callback_overhead)
|
||||
continue;
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_configure_callback_tracing_service(
|
||||
get_client_ctx(), itr.kind, nullptr, 0, itr.callback, nullptr),
|
||||
"callback tracing service failed to configure");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1748,120 +1940,28 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
|
||||
id,
|
||||
agent_params.data(),
|
||||
agent_params.size(),
|
||||
att_dispatch_callback,
|
||||
att_shader_data_callback,
|
||||
callbacks.att_dispatch,
|
||||
callbacks.att_shader_data,
|
||||
tool_data),
|
||||
"thread trace service configure");
|
||||
}
|
||||
}
|
||||
|
||||
if(tool::get_config().hip_runtime_api_trace || tool::get_config().hip_compiler_api_trace)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
buffered_tracing_callback,
|
||||
tool_data,
|
||||
&get_buffers().hip_api_trace),
|
||||
"buffer creation");
|
||||
|
||||
if(tool::get_config().hip_runtime_api_trace)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_configure_buffer_tracing_service(
|
||||
get_client_ctx(),
|
||||
ROCPROFILER_BUFFER_TRACING_HIP_RUNTIME_API_EXT,
|
||||
nullptr,
|
||||
0,
|
||||
get_buffers().hip_api_trace),
|
||||
"buffer tracing service for hip api configure");
|
||||
}
|
||||
|
||||
if(tool::get_config().hip_compiler_api_trace)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_configure_buffer_tracing_service(
|
||||
get_client_ctx(),
|
||||
ROCPROFILER_BUFFER_TRACING_HIP_COMPILER_API_EXT,
|
||||
nullptr,
|
||||
0,
|
||||
get_buffers().hip_api_trace),
|
||||
"buffer tracing service for hip compiler api configure");
|
||||
}
|
||||
}
|
||||
|
||||
if(tool::get_config().rccl_api_trace)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
buffered_tracing_callback,
|
||||
tool_data,
|
||||
&get_buffers().rccl_api_trace),
|
||||
"buffer creation");
|
||||
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_configure_buffer_tracing_service(get_client_ctx(),
|
||||
ROCPROFILER_BUFFER_TRACING_RCCL_API,
|
||||
nullptr,
|
||||
0,
|
||||
get_buffers().rccl_api_trace),
|
||||
"buffer tracing service for rccl api configure");
|
||||
}
|
||||
|
||||
if(tool::get_config().counter_collection)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_context(&counter_collection_ctx),
|
||||
"failed to create context");
|
||||
"failed to create counter collection context");
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_configure_callback_dispatch_counting_service(counter_collection_ctx,
|
||||
dispatch_callback,
|
||||
callbacks.counter_dispatch,
|
||||
nullptr,
|
||||
counter_record_callback,
|
||||
callbacks.counter_record,
|
||||
nullptr),
|
||||
"Could not setup counting service");
|
||||
ROCPROFILER_CALL(rocprofiler_start_context(counter_collection_ctx), "start context failed");
|
||||
|
||||
start_context(counter_collection_ctx, "counter collection");
|
||||
}
|
||||
|
||||
if(tool::get_config().rocdecode_api_trace)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
buffered_tracing_callback,
|
||||
tool_data,
|
||||
&get_buffers().rocdecode_api_trace),
|
||||
"buffer creation");
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_configure_buffer_tracing_service(
|
||||
get_client_ctx(),
|
||||
ROCPROFILER_BUFFER_TRACING_ROCDECODE_API_EXT,
|
||||
nullptr,
|
||||
0,
|
||||
get_buffers().rocdecode_api_trace),
|
||||
"buffer tracing service for ROCDecode api configure");
|
||||
}
|
||||
|
||||
if(tool::get_config().rocjpeg_api_trace)
|
||||
{
|
||||
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
|
||||
buffer_size,
|
||||
buffer_watermark,
|
||||
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
|
||||
buffered_tracing_callback,
|
||||
tool_data,
|
||||
&get_buffers().rocjpeg_api_trace),
|
||||
"buffer creation");
|
||||
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_configure_buffer_tracing_service(get_client_ctx(),
|
||||
ROCPROFILER_BUFFER_TRACING_ROCJPEG_API,
|
||||
nullptr,
|
||||
0,
|
||||
get_buffers().rocjpeg_api_trace),
|
||||
"buffer tracing service for ROCDecode api configure");
|
||||
}
|
||||
if(tool::get_config().kernel_rename)
|
||||
{
|
||||
auto rename_ctx = rocprofiler_context_id_t{0};
|
||||
@@ -1877,34 +1977,38 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
|
||||
ROCPROFILER_CALLBACK_TRACING_MARKER_CORE_API,
|
||||
marker_core_api_kinds.data(),
|
||||
marker_core_api_kinds.size(),
|
||||
kernel_rename_callback,
|
||||
callbacks.kernel_rename,
|
||||
nullptr),
|
||||
"callback tracing service failed to configure");
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_start_context(rename_ctx), "start context failed");
|
||||
start_context(rename_ctx, "kernel rename");
|
||||
}
|
||||
|
||||
if(!tool::get_config().group_by_queue)
|
||||
{
|
||||
// Track stream ID information via callback service
|
||||
auto hip_stream_display_ctx = rocprofiler_context_id_t{0};
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_create_context(&hip_stream_display_ctx),
|
||||
"failed to create context");
|
||||
"failed to create hip stream context");
|
||||
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_configure_callback_tracing_service(hip_stream_display_ctx,
|
||||
ROCPROFILER_CALLBACK_TRACING_HIP_STREAM,
|
||||
nullptr,
|
||||
0,
|
||||
hip_stream_display_callback,
|
||||
callbacks.hip_stream,
|
||||
nullptr),
|
||||
"stream tracing configure failed");
|
||||
ROCPROFILER_CALL(rocprofiler_start_context(hip_stream_display_ctx), "start context failed");
|
||||
"hip stream tracing configure failed");
|
||||
|
||||
start_context(hip_stream_display_ctx, "hip stream");
|
||||
|
||||
// Track if HIP runtime has been initialized via runtime_intialization service
|
||||
auto runtime_initialization_ctx = rocprofiler_context_id_t{0};
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_create_context(&runtime_initialization_ctx),
|
||||
"failed to create context");
|
||||
"failed to create runtime initialization context");
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_configure_callback_tracing_service(
|
||||
runtime_initialization_ctx,
|
||||
ROCPROFILER_CALLBACK_TRACING_RUNTIME_INITIALIZATION,
|
||||
@@ -1912,11 +2016,13 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
|
||||
0,
|
||||
runtime_initialization_callback,
|
||||
nullptr),
|
||||
"stream tracing configure failed");
|
||||
ROCPROFILER_CALL(rocprofiler_start_context(runtime_initialization_ctx),
|
||||
"start context failed");
|
||||
"runtime initialization tracing configure failed");
|
||||
|
||||
start_context(runtime_initialization_ctx, "runtime initialization");
|
||||
}
|
||||
if(tool::get_config().kernel_rename || !tool::get_config().group_by_queue)
|
||||
|
||||
if((tool::get_config().kernel_rename || !tool::get_config().group_by_queue) &&
|
||||
tool::get_config().benchmark_mode != tool::config::benchmark::execution_profile)
|
||||
{
|
||||
auto external_corr_id_request_kinds =
|
||||
std::array<rocprofiler_external_correlation_id_request_kind_t, 2>{
|
||||
@@ -1949,16 +2055,18 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
|
||||
|
||||
if(tool::get_config().pc_sampling_host_trap)
|
||||
{
|
||||
configure_pc_sampling_on_all_agents(buffer_size, buffer_watermark, tool_data);
|
||||
configure_pc_sampling_on_all_agents(
|
||||
buffer_size, buffer_watermark, tool_data, callbacks.pc_sampling);
|
||||
}
|
||||
else if(tool::get_config().pc_sampling_stochastic)
|
||||
{
|
||||
configure_pc_sampling_on_all_agents(buffer_size, buffer_watermark, tool_data);
|
||||
configure_pc_sampling_on_all_agents(
|
||||
buffer_size, buffer_watermark, tool_data, callbacks.pc_sampling);
|
||||
}
|
||||
|
||||
for(auto itr : get_buffers().as_array())
|
||||
for(auto itr : get_buffers().pc_sampling_buffers_as_array())
|
||||
{
|
||||
if(itr.handle > 0)
|
||||
if(itr > null_buffer_id)
|
||||
{
|
||||
auto cb_thread = rocprofiler_callback_thread_t{};
|
||||
|
||||
@@ -1973,24 +2081,38 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
|
||||
}
|
||||
}
|
||||
|
||||
if(tool::get_config().collection_periods.empty())
|
||||
{
|
||||
ROCPROFILER_CHECK(rocprofiler_start_context(get_client_ctx()));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto _prom = std::promise<void>{};
|
||||
auto _fut = _prom.get_future();
|
||||
std::thread{collection_period_cntrl, std::move(_prom), get_client_ctx()}.detach();
|
||||
_fut.wait_for(std::chrono::seconds{1}); // wait for a max of 1 second
|
||||
}
|
||||
|
||||
// Handle kernel id of zero
|
||||
bool include = std::regex_search("0", std::regex(tool::get_config().kernel_filter_include));
|
||||
bool exclude = std::regex_search("0", std::regex(tool::get_config().kernel_filter_exclude));
|
||||
if(include && (!exclude || tool::get_config().kernel_filter_exclude.empty()))
|
||||
add_kernel_target(0, tool::get_config().kernel_filter_range);
|
||||
|
||||
if(tool::get_config().benchmark_mode == tool::config::benchmark::disabled_contexts_overhead)
|
||||
{
|
||||
ROCP_INFO << "rocprofv3 is not recording data because the overhead of inactive contexts is "
|
||||
"being benchmarked";
|
||||
}
|
||||
else if(tool::get_config().selected_regions)
|
||||
{
|
||||
ROCP_WARNING << "rocprofv3 is only recording profiling data within regions of code "
|
||||
"surrounded by roctxProfilerResume(0)/roctxProfilerPause";
|
||||
}
|
||||
else if(!tool::get_config().collection_periods.empty())
|
||||
{
|
||||
ROCP_INFO << "rocprofv3 will record data during the defined collection period(s)";
|
||||
|
||||
auto _prom = std::promise<void>{};
|
||||
auto _fut = _prom.get_future();
|
||||
std::thread{collection_period_cntrl, std::move(_prom), get_client_ctx()}.detach();
|
||||
_fut.wait_for(std::chrono::seconds{1}); // wait for a max of 1 second
|
||||
}
|
||||
else
|
||||
{
|
||||
ROCP_INFO << "rocprofv3 will record data starting now";
|
||||
|
||||
start_context(get_client_ctx(), "primary rocprofv3");
|
||||
}
|
||||
|
||||
tool_metadata->process_id = getpid();
|
||||
rocprofiler_get_timestamp(&(tool_metadata->process_start_ns));
|
||||
|
||||
@@ -2008,6 +2130,90 @@ struct output_data
|
||||
uint64_t num_bytes = 0;
|
||||
};
|
||||
|
||||
void
|
||||
generate_config_output(const tool::config& cfg, const tool::metadata& tool_metadata_v)
|
||||
{
|
||||
using JSONOutputArchive = ::cereal::PrettyJSONOutputArchive;
|
||||
|
||||
constexpr auto json_prec = 16;
|
||||
constexpr auto json_indent = JSONOutputArchive::Options::IndentChar::space;
|
||||
auto json_opts = JSONOutputArchive::Options{json_prec, json_indent, 2};
|
||||
auto filename = std::string_view{"config"};
|
||||
|
||||
auto stream = get_output_stream(cfg, filename, ".json");
|
||||
{
|
||||
auto archive = JSONOutputArchive{*stream.stream, json_opts};
|
||||
|
||||
archive.setNextName("rocprofiler-sdk-tool");
|
||||
archive.startNode();
|
||||
archive.makeArray();
|
||||
archive.startNode(); // first array entry
|
||||
|
||||
auto timestamps =
|
||||
tool::timestamps_t{tool_metadata_v.process_start_ns, tool_metadata_v.process_end_ns};
|
||||
|
||||
auto this_pid = tool_metadata_v.process_id;
|
||||
|
||||
archive.setNextName("metadata");
|
||||
archive.startNode();
|
||||
archive(cereal::make_nvp("pid", this_pid));
|
||||
archive(cereal::make_nvp("init_time", timestamps.app_start_time));
|
||||
archive(cereal::make_nvp("fini_time", timestamps.app_end_time));
|
||||
archive(cereal::make_nvp("config", cfg));
|
||||
archive(cereal::make_nvp("command", common::read_command_line(this_pid)));
|
||||
|
||||
{
|
||||
archive.setNextName("build_spec");
|
||||
archive.startNode();
|
||||
archive(cereal::make_nvp("version_major", ROCPROFILER_VERSION_MAJOR));
|
||||
archive(cereal::make_nvp("version_minor", ROCPROFILER_VERSION_MINOR));
|
||||
archive(cereal::make_nvp("version_patch", ROCPROFILER_VERSION_PATCH));
|
||||
archive(cereal::make_nvp("soversion", ROCPROFILER_SOVERSION));
|
||||
archive(cereal::make_nvp("compiler_id", std::string{ROCPROFILER_COMPILER_ID}));
|
||||
archive(
|
||||
cereal::make_nvp("compiler_version", std::string{ROCPROFILER_COMPILER_VERSION}));
|
||||
archive(cereal::make_nvp("git_describe", std::string{ROCPROFILER_GIT_DESCRIBE}));
|
||||
archive(cereal::make_nvp("git_revision", std::string{ROCPROFILER_GIT_REVISION}));
|
||||
archive(cereal::make_nvp("library_arch", std::string{ROCPROFILER_LIBRARY_ARCH}));
|
||||
archive(cereal::make_nvp("system_name", std::string{ROCPROFILER_SYSTEM_NAME}));
|
||||
archive(
|
||||
cereal::make_nvp("system_processor", std::string{ROCPROFILER_SYSTEM_PROCESSOR}));
|
||||
archive(cereal::make_nvp("system_version", std::string{ROCPROFILER_SYSTEM_VERSION}));
|
||||
archive.finishNode(); // build_spec
|
||||
}
|
||||
|
||||
// save the execution profile
|
||||
if(execution_profile) archive(cereal::make_nvp("profile", execution_profile->get()));
|
||||
|
||||
// save the environment variables
|
||||
{
|
||||
archive.setNextName("environment");
|
||||
archive.startNode();
|
||||
size_t idx = 0;
|
||||
while(true)
|
||||
{
|
||||
const auto* env_entry = environ[idx++];
|
||||
if(!env_entry)
|
||||
break;
|
||||
else if(std::string_view{env_entry}.find('=') != std::string_view::npos)
|
||||
{
|
||||
auto _entry = std::string{env_entry};
|
||||
auto _pos = _entry.find('=');
|
||||
auto _name = _entry.substr(0, _pos);
|
||||
auto _value = _entry.substr(_pos + 1);
|
||||
archive(cereal::make_nvp(_name.c_str(), _value));
|
||||
}
|
||||
}
|
||||
archive.finishNode();
|
||||
}
|
||||
|
||||
archive.finishNode(); // metadata
|
||||
archive.finishNode(); // first array entry
|
||||
archive.finishNode(); // rocprofiler-sdk-tool
|
||||
}
|
||||
stream.close();
|
||||
}
|
||||
|
||||
template <typename Tp, domain_type DomainT>
|
||||
void
|
||||
generate_output(tool::buffered_output<Tp, DomainT>& output_v,
|
||||
@@ -2019,6 +2225,9 @@ generate_output(tool::buffered_output<Tp, DomainT>& output_v,
|
||||
|
||||
if(!output_v) return;
|
||||
|
||||
// when benchmarking, we do not generate output
|
||||
if(tool::get_config().benchmark_mode != tool::config::benchmark::none) return;
|
||||
|
||||
// opens temporary file and sets read position to beginning
|
||||
output_v.read();
|
||||
|
||||
@@ -2104,6 +2313,12 @@ tool_fini(void* /*tool_data*/)
|
||||
cleanups.clear();
|
||||
};
|
||||
|
||||
// generate the configuration output regardless of whether there is any data
|
||||
if(tool::get_config().output_config_file)
|
||||
{
|
||||
generate_config_output(tool::get_config(), *tool_metadata);
|
||||
}
|
||||
|
||||
auto _dtor = common::scope_destructor{run_cleanup};
|
||||
|
||||
generate_output(kernel_dispatch_output, outdata, contributions, cleanups);
|
||||
@@ -2662,6 +2877,7 @@ rocprofiler_configure(uint32_t version,
|
||||
|
||||
// ensure these pointers are not leaked
|
||||
add_destructor(tool_metadata);
|
||||
add_destructor(execution_profile);
|
||||
|
||||
// in case main wrapper is not used
|
||||
::atexit([]() { finalize_rocprofv3("atexit"); });
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <rocprofiler-sdk/external_correlation.h>
|
||||
#include <rocprofiler-sdk/fwd.h>
|
||||
|
||||
#include "lib/rocprofiler-sdk/external_correlation.hpp"
|
||||
#include "lib/common/synchronized.hpp"
|
||||
#include "lib/common/utility.hpp"
|
||||
#include "lib/rocprofiler-sdk/context/context.hpp"
|
||||
#include "lib/rocprofiler-sdk/external_correlation.hpp"
|
||||
|
||||
#include <rocprofiler-sdk/external_correlation.h>
|
||||
#include <rocprofiler-sdk/fwd.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -36,6 +36,50 @@ namespace external_correlation
|
||||
{
|
||||
namespace
|
||||
{
|
||||
#define ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(CODE) \
|
||||
template <> \
|
||||
struct external_correlation_id_request_kind_string< \
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_##CODE> \
|
||||
{ \
|
||||
static constexpr auto value = \
|
||||
std::pair<const char*, size_t>{#CODE, std::string_view{#CODE}.length()}; \
|
||||
};
|
||||
|
||||
template <size_t Idx>
|
||||
struct external_correlation_id_request_kind_string;
|
||||
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(NONE)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(HSA_CORE_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(HSA_AMD_EXT_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(HSA_IMAGE_EXT_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(HSA_FINALIZE_EXT_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(HIP_RUNTIME_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(HIP_COMPILER_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(MARKER_CORE_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(MARKER_CONTROL_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(MARKER_NAME_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(MEMORY_COPY)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(MEMORY_ALLOCATION)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(KERNEL_DISPATCH)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(SCRATCH_MEMORY)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(RCCL_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(OMPT)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(ROCDECODE_API)
|
||||
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING(ROCJPEG_API)
|
||||
|
||||
#undef ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KIND_STRING
|
||||
|
||||
template <size_t Idx, size_t... Tail>
|
||||
std::pair<const char*, size_t>
|
||||
get_kind_name(rocprofiler_external_correlation_id_request_kind_t kind,
|
||||
std::index_sequence<Idx, Tail...>)
|
||||
{
|
||||
if(kind == Idx) return external_correlation_id_request_kind_string<Idx>::value;
|
||||
// recursion until tail empty
|
||||
if constexpr(sizeof...(Tail) > 0) return get_kind_name(kind, std::index_sequence<Tail...>{});
|
||||
return {nullptr, 0};
|
||||
}
|
||||
|
||||
auto
|
||||
get_default_tid()
|
||||
{
|
||||
@@ -249,6 +293,21 @@ rocprofiler_configure_external_correlation_id_request_service(
|
||||
callback, callback_args, kinds_v);
|
||||
}
|
||||
|
||||
rocprofiler_status_t
|
||||
rocprofiler_query_external_correlation_id_request_kind_name(
|
||||
rocprofiler_external_correlation_id_request_kind_t kind,
|
||||
const char** name,
|
||||
uint64_t* name_len)
|
||||
{
|
||||
auto&& val = rocprofiler::external_correlation::get_kind_name(
|
||||
kind, std::make_index_sequence<ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_LAST>{});
|
||||
|
||||
if(name) *name = val.first;
|
||||
if(name_len) *name_len = val.second;
|
||||
|
||||
return (val.first) ? ROCPROFILER_STATUS_SUCCESS : ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND;
|
||||
}
|
||||
|
||||
rocprofiler_status_t
|
||||
rocprofiler_push_external_correlation_id(rocprofiler_context_id_t context,
|
||||
rocprofiler_thread_id_t tid,
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace context
|
||||
{
|
||||
struct context;
|
||||
}
|
||||
|
||||
namespace external_correlation
|
||||
{
|
||||
static constexpr bool enable_const_wlock_v = true;
|
||||
|
||||
@@ -688,6 +688,33 @@ initialize()
|
||||
if(get_num_clients() > 0) internal_threading::initialize();
|
||||
// initialization is no longer available
|
||||
set_init_status(1);
|
||||
|
||||
if(get_num_clients() > 0)
|
||||
{
|
||||
for(const auto& itr : *get_clients())
|
||||
{
|
||||
if(!itr) continue;
|
||||
size_t _client_registered_ctx = 0;
|
||||
for(const auto* citr : context::get_registered_contexts())
|
||||
{
|
||||
if(citr->client_idx == itr->internal_client_id.handle) ++_client_registered_ctx;
|
||||
}
|
||||
|
||||
size_t _client_activated_ctx = 0;
|
||||
for(const auto* citr : context::get_active_contexts())
|
||||
{
|
||||
if(citr->client_idx == itr->internal_client_id.handle) ++_client_activated_ctx;
|
||||
}
|
||||
|
||||
ROCP_INFO << fmt::format("rocprofiler-sdk client '{}' registered {} context(s) and "
|
||||
"started {} context(s)",
|
||||
(itr->mutable_client_id.name)
|
||||
? std::string_view{itr->mutable_client_id.name}
|
||||
: std::string_view{"unspecified"},
|
||||
_client_registered_ctx,
|
||||
_client_activated_ctx);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user