Query callback and buffered tracing names (#135)

* Update include/rocprofiler/buffer_tracing.h

- add query functions for kind name, and kind operation name
- tweak iterate functions to not be specifically dedicated to names

* Update include/rocprofiler/callback_tracing.h

- add query functions for kind name, and kind operation name
- tweak iterate functions to not be specifically dedicated to names

* Update lib/rocprofiler/callback_tracing.cpp

- implement rocprofiler_query_callback_tracing_kind_name
- implement rocprofiler_query_callback_tracing_kind_name_buf
- implement rocprofiler_query_callback_tracing_kind_operation_name
- implement rocprofiler_query_callback_tracing_kind_operation_name_buf
- implement rocprofiler_iterate_callback_tracing_kinds
- implement rocprofiler_iterate_callback_tracing_kind_operations

* Update lib/rocprofiler/buffer_tracing.cpp

- implement rocprofiler_query_buffer_tracing_kind_name
- implement rocprofiler_query_buffer_tracing_kind_name_buf
- implement rocprofiler_query_buffer_tracing_kind_operation_name
- implement rocprofiler_query_buffer_tracing_kind_operation_name_buf
- implement rocprofiler_iterate_buffer_tracing_kinds
- implement rocprofiler_iterate_buffer_tracing_kind_operations

* Update lib/rocprofiler/tests/registration.cpp

- use new implementation for getting callback/buffer tracing names

* Update samples/api_buffered_tracing

- use new implementation for getting callback/buffer tracing names

* Update samples/api_callback_tracing

- use new implementation for getting callback/buffer tracing names

* Remove buffered query functions

- *_buf variants of the rocprofiler_query_X_tracing_Y functions were removed since we currently have no names requiring these functions

* Rename ROCPROFILER_STATUS_ERROR_DOMAIN_NOT_FOUND

- "DOMAIN" changed to "KIND" since former is more specific tracing whereas kind is used more generically
This commit is contained in:
Jonathan R. Madsen
2023-10-19 15:21:07 -05:00
committed by GitHub
orang tua de685246a7
melakukan 87cc748c3d
10 mengubah file dengan 619 tambahan dan 232 penghapusan
+74 -36
Melihat File
@@ -49,6 +49,7 @@
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <mutex>
#include <string>
#include <string_view>
@@ -77,7 +78,16 @@ struct source_location
std::string context = {};
};
using call_stack_t = std::vector<source_location>;
using call_stack_t = std::vector<source_location>;
using buffer_kind_names_t = std::map<rocprofiler_service_buffer_tracing_kind_t, const char*>;
using buffer_kind_operation_names_t =
std::map<rocprofiler_service_buffer_tracing_kind_t, std::map<uint32_t, const char*>>;
struct buffer_name_info
{
buffer_kind_names_t kind_names = {};
buffer_kind_operation_names_t operation_names = {};
};
rocprofiler_client_id_t* client_id = nullptr;
rocprofiler_client_finalize_t client_fini_func = nullptr;
@@ -129,48 +139,53 @@ print_call_stack(const call_stack_t& _call_stack)
if(cleanup) cleanup(ofs);
}
void
store_buffer_id_names(call_stack_t* tool_data)
buffer_name_info
get_buffer_tracing_names()
{
auto cb_name_info = buffer_name_info{};
//
// buffered for each kind operation
// callback for each kind operation
//
static auto tracing_operation_names_cb = [](rocprofiler_service_buffer_tracing_kind_t /*kindv*/,
uint32_t /*operation*/,
const char* operation_name,
void* data_v) {
static_cast<call_stack_t*>(data_v)->emplace_back(
source_location{"rocprofiler_iterate_buffer_trace_kind_operation_names",
__FILE__,
__LINE__,
std::string{" "} + std::string{operation_name}});
return 0;
};
static auto tracing_kind_operation_cb =
[](rocprofiler_service_buffer_tracing_kind_t kindv, uint32_t operation, void* data_v) {
auto* name_info_v = static_cast<buffer_name_info*>(data_v);
if(kindv == ROCPROFILER_SERVICE_BUFFER_TRACING_HSA_API)
{
const char* name = nullptr;
ROCPROFILER_CALL(rocprofiler_query_buffer_tracing_kind_operation_name(
kindv, operation, &name, nullptr),
"query buffer tracing kind operation name");
if(name) name_info_v->operation_names[kindv][operation] = name;
}
return 0;
};
//
// callback for each buffer kind (i.e. domain)
//
static auto tracing_kind_names_cb =
[](rocprofiler_service_buffer_tracing_kind_t kind, const char* kind_name, void* data) {
// store the buffer kind name
static_cast<call_stack_t*>(data)->emplace_back(
source_location{"rocprofiler_iterate_buffer_trace_kind_names ",
__FILE__,
__LINE__,
kind_name});
static auto tracing_kind_cb = [](rocprofiler_service_buffer_tracing_kind_t kind, void* data) {
// store the buffer kind name
auto* name_info_v = static_cast<buffer_name_info*>(data);
const char* name = nullptr;
ROCPROFILER_CALL(rocprofiler_query_buffer_tracing_kind_name(kind, &name, nullptr),
"query buffer tracing kind operation name");
if(name) name_info_v->kind_names[kind] = name;
// store the operation names for the HSA API
if(kind == ROCPROFILER_SERVICE_BUFFER_TRACING_HSA_API)
{
rocprofiler_iterate_buffer_tracing_kind_operation_names(
kind, tracing_operation_names_cb, data);
}
if(kind == ROCPROFILER_SERVICE_BUFFER_TRACING_HSA_API)
{
ROCPROFILER_CALL(rocprofiler_iterate_buffer_tracing_kind_operations(
kind, tracing_kind_operation_cb, static_cast<void*>(data)),
"iterating buffer tracing kind operations");
}
return 0;
};
return 0;
};
ROCPROFILER_CALL(rocprofiler_iterate_buffer_tracing_kinds(tracing_kind_cb,
static_cast<void*>(&cb_name_info)),
"iterating buffer tracing kinds");
rocprofiler_iterate_buffer_tracing_kind_names(tracing_kind_names_cb,
static_cast<void*>(tool_data));
return cb_name_info;
}
void
@@ -256,10 +271,33 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
{
assert(tool_data != nullptr);
static_cast<call_stack_t*>(tool_data)->emplace_back(
source_location{__FUNCTION__, __FILE__, __LINE__, ""});
auto* call_stack_v = static_cast<call_stack_t*>(tool_data);
store_buffer_id_names(static_cast<call_stack_t*>(tool_data));
call_stack_v->emplace_back(source_location{__FUNCTION__, __FILE__, __LINE__, ""});
buffer_name_info name_info = get_buffer_tracing_names();
for(const auto& itr : name_info.operation_names)
{
auto name_idx = std::stringstream{};
name_idx << " [" << std::setw(3) << static_cast<int32_t>(itr.first) << "]";
call_stack_v->emplace_back(
source_location{"rocprofiler_buffer_tracing_kind_names " + name_idx.str(),
__FILE__,
__LINE__,
name_info.kind_names.at(itr.first)});
for(const auto& ditr : itr.second)
{
auto operation_idx = std::stringstream{};
operation_idx << " [" << std::setw(3) << static_cast<int32_t>(ditr.first) << "]";
call_stack_v->emplace_back(source_location{
"rocprofiler_buffer_tracing_kind_operation_names" + operation_idx.str(),
__FILE__,
__LINE__,
std::string{"- "} + std::string{ditr.second}});
}
}
client_fini_func = fini_func;
+87 -37
Melihat File
@@ -37,6 +37,7 @@
#include <rocprofiler/rocprofiler.h>
#include <cassert>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <cstdio>
@@ -45,7 +46,9 @@
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <mutex>
#include <ratio>
#include <string>
#include <string_view>
#include <vector>
@@ -72,7 +75,16 @@ struct source_location
std::string context = {};
};
using call_stack_t = std::vector<source_location>;
using call_stack_t = std::vector<source_location>;
using callback_kind_names_t = std::map<rocprofiler_service_callback_tracing_kind_t, const char*>;
using callback_kind_operation_names_t =
std::map<rocprofiler_service_callback_tracing_kind_t, std::map<uint32_t, const char*>>;
struct callback_name_info
{
callback_kind_names_t kind_names = {};
callback_kind_operation_names_t operation_names = {};
};
rocprofiler_client_id_t* client_id = nullptr;
rocprofiler_client_finalize_t client_fini_func = nullptr;
@@ -109,11 +121,12 @@ print_call_stack(const call_stack_t& _call_stack)
std::cout << "Outputting collected data to " << ofname << "...\n" << std::flush;
size_t n = 0;
*ofs << std::left;
for(const auto& itr : _call_stack)
{
*ofs << std::setw(2) << ++n << "/" << std::setw(2) << _call_stack.size() << " ";
*ofs << "[" << fs::path{itr.file}.filename() << ":" << itr.line << "] " << std::setw(20)
<< std::left << itr.function;
<< itr.function;
if(!itr.context.empty()) *ofs << " :: " << itr.context;
*ofs << "\n";
}
@@ -123,60 +136,74 @@ print_call_stack(const call_stack_t& _call_stack)
if(cleanup) cleanup(ofs);
}
void
store_callback_id_names(call_stack_t* tool_data)
callback_name_info
get_callback_id_names()
{
auto cb_name_info = callback_name_info{};
//
// callback for each kind operation
//
static auto tracing_operation_names_cb =
[](rocprofiler_service_callback_tracing_kind_t /*kindv*/,
uint32_t /*operation*/,
const char* operation_name,
void* data_v) {
static_cast<call_stack_t*>(data_v)->emplace_back(
source_location{"rocprofiler_iterate_callback_tracing_kind_operation_names",
__FILE__,
__LINE__,
std::string{" "} + std::string{operation_name}});
static auto tracing_kind_operation_cb =
[](rocprofiler_service_callback_tracing_kind_t kindv, uint32_t operation, void* data_v) {
auto* name_info_v = static_cast<callback_name_info*>(data_v);
if(kindv == ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API)
{
const char* name = nullptr;
ROCPROFILER_CALL(rocprofiler_query_callback_tracing_kind_operation_name(
kindv, operation, &name, nullptr),
"query callback tracing kind operation name");
if(name) name_info_v->operation_names[kindv][operation] = name;
}
return 0;
};
//
// callback for each callback kind (i.e. domain)
//
static auto tracing_kind_names_cb = [](rocprofiler_service_callback_tracing_kind_t kind,
const char* kind_name,
void* data) {
static auto tracing_kind_cb = [](rocprofiler_service_callback_tracing_kind_t kind, void* data) {
// store the callback kind name
static_cast<call_stack_t*>(data)->emplace_back(source_location{
"rocprofiler_iterate_callback_tracing_kind_names ", __FILE__, __LINE__, kind_name});
auto* name_info_v = static_cast<callback_name_info*>(data);
const char* name = nullptr;
ROCPROFILER_CALL(rocprofiler_query_callback_tracing_kind_name(kind, &name, nullptr),
"query callback tracing kind operation name");
if(name) name_info_v->kind_names[kind] = name;
// store the operation names for the HSA API
if(kind == ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API)
{
rocprofiler_iterate_callback_tracing_kind_operation_names(
kind, tracing_operation_names_cb, data);
ROCPROFILER_CALL(rocprofiler_iterate_callback_tracing_kind_operations(
kind, tracing_kind_operation_cb, static_cast<void*>(data)),
"iterating callback tracing kind operations");
}
return 0;
};
rocprofiler_iterate_callback_tracing_kind_names(tracing_kind_names_cb,
static_cast<void*>(tool_data));
ROCPROFILER_CALL(rocprofiler_iterate_callback_tracing_kinds(tracing_kind_cb,
static_cast<void*>(&cb_name_info)),
"iterating callback tracing kinds");
return cb_name_info;
}
void
tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
rocprofiler_user_data_t*,
void* user_data)
rocprofiler_user_data_t* user_data,
void* callback_data)
{
assert(user_data != nullptr);
assert(callback_data != nullptr);
auto now = std::chrono::steady_clock::now().time_since_epoch().count();
uint64_t dt = 0;
if(record.phase == ROCPROFILER_SERVICE_CALLBACK_PHASE_ENTER)
user_data->value = now;
else
dt = (now - user_data->value);
auto info = std::stringstream{};
info << "tid=" << record.thread_id << ", cid=" << record.correlation_id.internal
<< ", kind=" << record.kind << ", operation=" << record.operation
<< ", phase=" << record.phase;
info << std::left << "tid=" << record.thread_id << ", cid=" << std::setw(3)
<< record.correlation_id.internal << ", kind=" << record.kind
<< ", operation=" << std::setw(3) << record.operation << ", phase=" << record.phase
<< ", dt_nsec=" << std::setw(6) << dt;
auto info_data_cb = [](rocprofiler_service_callback_tracing_kind_t,
uint32_t,
@@ -193,7 +220,7 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
};
auto info_data = std::stringstream{};
ROCPROFILER_CALL(rocprofiler_iterate_callback_tracing_operation_args(
ROCPROFILER_CALL(rocprofiler_iterate_callback_tracing_kind_operation_args(
record, info_data_cb, static_cast<void*>(&info_data)),
"Failure iterating trace operation args");
@@ -202,8 +229,8 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
static auto _mutex = std::mutex{};
_mutex.lock();
static_cast<call_stack_t*>(user_data)->emplace_back(
source_location{__FUNCTION__, __FILE__, __LINE__, info.str()});
static_cast<call_stack_t*>(callback_data)
->emplace_back(source_location{__FUNCTION__, __FILE__, __LINE__, info.str()});
_mutex.unlock();
}
@@ -212,10 +239,33 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
{
assert(tool_data != nullptr);
static_cast<call_stack_t*>(tool_data)->emplace_back(
source_location{__FUNCTION__, __FILE__, __LINE__, ""});
auto* call_stack_v = static_cast<call_stack_t*>(tool_data);
store_callback_id_names(static_cast<call_stack_t*>(tool_data));
call_stack_v->emplace_back(source_location{__FUNCTION__, __FILE__, __LINE__, ""});
callback_name_info name_info = get_callback_id_names();
for(const auto& itr : name_info.operation_names)
{
auto name_idx = std::stringstream{};
name_idx << " [" << std::setw(3) << static_cast<int32_t>(itr.first) << "]";
call_stack_v->emplace_back(
source_location{"rocprofiler_callback_tracing_kind_names " + name_idx.str(),
__FILE__,
__LINE__,
name_info.kind_names.at(itr.first)});
for(const auto& ditr : itr.second)
{
auto operation_idx = std::stringstream{};
operation_idx << " [" << std::setw(3) << static_cast<int32_t>(ditr.first) << "]";
call_stack_v->emplace_back(source_location{
"rocprofiler_callback_tracing_kind_operation_names" + operation_idx.str(),
__FILE__,
__LINE__,
std::string{"- "} + std::string{ditr.second}});
}
}
client_fini_func = fini_func;
+57 -16
Melihat File
@@ -206,20 +206,17 @@ typedef struct
* @brief Callback function for mapping @ref rocprofiler_service_buffer_tracing_kind_t ids to
* string names. @see rocprofiler_iterate_buffer_trace_kind_names.
*/
typedef int (*rocprofiler_buffer_tracing_kind_name_cb_t)(
rocprofiler_service_buffer_tracing_kind_t kind,
const char* kind_name,
void* data);
typedef int (*rocprofiler_buffer_tracing_kind_cb_t)(rocprofiler_service_buffer_tracing_kind_t kind,
void* data);
/**
* @brief Callback function for mapping the operations of a given @ref
* rocprofiler_service_buffer_tracing_kind_t to string names. @see
* rocprofiler_iterate_buffer_trace_kind_operation_names.
*/
typedef int (*rocprofiler_buffer_tracing_operation_name_cb_t)(
typedef int (*rocprofiler_buffer_tracing_kind_operation_cb_t)(
rocprofiler_service_buffer_tracing_kind_t kind,
uint32_t operation,
const char* operation_name,
void* data);
/**
@@ -241,7 +238,52 @@ rocprofiler_configure_buffer_tracing_service(rocprofiler_context_id_t
rocprofiler_buffer_id_t buffer_id);
/**
* @brief Iterate over all the mappings of the callback tracing kinds and get a callback with the id
* @brief Query the name of the buffer tracing 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 kind [in] Buffer tracing domain
* @param name [out] 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 name_len [out] 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 Returns @ref ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND if the
* domain id is not valid. Returns @ref ROCPROFILER_STATUS_SUCCESS for a valid domain regardless if
* there is a constant string or not.
*/
rocprofiler_status_t
rocprofiler_query_buffer_tracing_kind_name(rocprofiler_service_buffer_tracing_kind_t kind,
const char** name,
uint64_t* name_len) ROCPROFILER_API;
/**
* @brief Query the name of the buffer tracing 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 kind [in] Buffer tracing domain
* @param operation [in] Enumeration id value which maps to a specific API function or event type
* @param name [out] 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 name_len [out] 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 Returns @ref ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND on an invalid
* domain id. Returns @ref ROCPROFILER_STATUS_ERROR_OPERATION_NOT_FOUND if the operation number is
* not recognized for the given domain. Returns @ref ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED if
* rocprofiler does not support providing the operation name within this domain. Returns @ref
* ROCPROFILER_STATUS_SUCCESS for valid domain and operation regardless of whether there is a
* constant string or not.
*/
rocprofiler_status_t
rocprofiler_query_buffer_tracing_kind_operation_name(rocprofiler_service_buffer_tracing_kind_t kind,
uint32_t operation,
const char** name,
uint64_t* name_len) ROCPROFILER_API;
/**
* @brief Iterate over all the mappings of the buffer tracing kinds and get a buffer with the id
* mapped to a constant string. The strings provided in the arg will be valid pointers for the
* entire duration of the program. It is recommended to call this function once and cache this data
* in the client instead of making multiple on-demand calls.
@@ -251,15 +293,14 @@ rocprofiler_configure_buffer_tracing_service(rocprofiler_context_id_t
* @param [in] data User data passed back into the callback
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_iterate_buffer_tracing_kind_names(rocprofiler_buffer_tracing_kind_name_cb_t callback,
void* data) ROCPROFILER_NONNULL(1);
rocprofiler_iterate_buffer_tracing_kinds(rocprofiler_buffer_tracing_kind_cb_t callback, void* data)
ROCPROFILER_NONNULL(1);
/**
* @brief Iterates over all the mappings of the operations for a given @ref
* rocprofiler_service_buffer_tracing_kind_t and invokes the callback with the kind, operation id,
* and the string mapping to the operation id. The strings provided in the callback arg will be
* valid pointers for the entire duration of the program. It is recommended to call this function
* once per kind, and cache this data in the client instead of making multiple on-demand calls.
* @brief Iterates over all the operations for a given @ref
* rocprofiler_service_buffer_tracing_kind_t and invokes the callback with the kind and operation
* id. This is useful to build a map of the operation names during tool initialization instead of
* querying rocprofiler everytime in the callback hotpath.
*
* @param [in] kind which buffer tracing kind operations to iterate over
* @param [in] callback Callback function invoked for each operation associated with @ref
@@ -267,9 +308,9 @@ rocprofiler_iterate_buffer_tracing_kind_names(rocprofiler_buffer_tracing_kind_na
* @param [in] data User data passed back into the callback
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_iterate_buffer_tracing_kind_operation_names(
rocprofiler_iterate_buffer_tracing_kind_operations(
rocprofiler_service_buffer_tracing_kind_t kind,
rocprofiler_buffer_tracing_operation_name_cb_t callback,
rocprofiler_buffer_tracing_kind_operation_cb_t callback,
void* data) ROCPROFILER_NONNULL(2);
/** @} */
@@ -157,9 +157,8 @@ typedef void (*rocprofiler_callback_tracing_cb_t)(rocprofiler_callback_tracing_r
* @brief Callback function for mapping @ref rocprofiler_service_callback_tracing_kind_t ids to
* string names. @see rocprofiler_iterate_callback_tracing_kind_names.
*/
typedef int (*rocprofiler_callback_tracing_kind_name_cb_t)(
typedef int (*rocprofiler_callback_tracing_kind_cb_t)(
rocprofiler_service_callback_tracing_kind_t kind,
const char* kind_name,
void* data);
/**
@@ -167,10 +166,9 @@ typedef int (*rocprofiler_callback_tracing_kind_name_cb_t)(
* rocprofiler_service_callback_tracing_kind_t to string names. @see
* rocprofiler_iterate_callback_tracing_kind_operation_names.
*/
typedef int (*rocprofiler_callback_tracing_operation_name_cb_t)(
typedef int (*rocprofiler_callback_tracing_kind_operation_cb_t)(
rocprofiler_service_callback_tracing_kind_t kind,
uint32_t operation,
const char* operation_name,
void* data);
/**
@@ -231,6 +229,47 @@ rocprofiler_configure_callback_tracing_service(rocprofiler_context_id_t context_
rocprofiler_callback_tracing_cb_t callback,
void* callback_args);
/**
* @brief Query the name of the callback tracing 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 kind [in] Callback tracing domain
* @param name [out] 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 name_len [out] 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
*/
rocprofiler_status_t
rocprofiler_query_callback_tracing_kind_name(rocprofiler_service_callback_tracing_kind_t kind,
const char** name,
uint64_t* name_len) ROCPROFILER_API;
/**
* @brief Query the name of the callback tracing 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 kind [in] Callback tracing domain
* @param operation [in] Enumeration id value which maps to a specific API function or event type
* @param name [out] 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 name_len [out] 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 Returns @ref ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND if the
* domain id is not valid. Returns @ref ROCPROFILER_STATUS_SUCCESS for a valid domain regardless if
* there is a constant string or not.
*/
rocprofiler_status_t
rocprofiler_query_callback_tracing_kind_operation_name(
rocprofiler_service_callback_tracing_kind_t kind,
uint32_t operation,
const char** name,
uint64_t* name_len) ROCPROFILER_API;
/**
* @brief Iterate over all the mappings of the callback tracing kinds and get a callback with the id
* mapped to a constant string. The strings provided in the arg will be valid pointers for the
@@ -240,11 +279,16 @@ rocprofiler_configure_callback_tracing_service(rocprofiler_context_id_t context_
* @param [in] callback Callback function invoked for each enumeration value in @ref
* rocprofiler_service_callback_tracing_kind_t with the exception of the `NONE` and `LAST` values.
* @param [in] data User data passed back into the callback
* @return rocprofiler_status_t Returns @ref ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND on an invalid
* domain id. Returns @ref ROCPROFILER_STATUS_ERROR_OPERATION_NOT_FOUND if the operation number is
* not recognized for the given domain. Returns @ref ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED if
* rocprofiler does not support providing the operation name within this domain. Returns @ref
* ROCPROFILER_STATUS_SUCCESS for valid domain and operation regardless of whether there is a
* constant string or not.
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_iterate_callback_tracing_kind_names(
rocprofiler_callback_tracing_kind_name_cb_t callback,
void* data) ROCPROFILER_NONNULL(1);
rocprofiler_iterate_callback_tracing_kinds(rocprofiler_callback_tracing_kind_cb_t callback,
void* data) ROCPROFILER_NONNULL(1);
/**
* @brief Iterates over all the mappings of the operations for a given @ref
@@ -259,9 +303,9 @@ rocprofiler_iterate_callback_tracing_kind_names(
* @param [in] data User data passed back into the callback
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_iterate_callback_tracing_kind_operation_names(
rocprofiler_iterate_callback_tracing_kind_operations(
rocprofiler_service_callback_tracing_kind_t kind,
rocprofiler_callback_tracing_operation_name_cb_t callback,
rocprofiler_callback_tracing_kind_operation_cb_t callback,
void* data) ROCPROFILER_NONNULL(2);
/**
@@ -274,7 +318,7 @@ rocprofiler_iterate_callback_tracing_kind_operation_names(
* @param[in] user_data Data to be passed to each invocation of the callback
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_iterate_callback_tracing_operation_args(
rocprofiler_iterate_callback_tracing_kind_operation_args(
rocprofiler_callback_tracing_record_t record,
rocprofiler_callback_tracing_operation_args_cb_t callback,
void* user_data) ROCPROFILER_NONNULL(2);
+1 -1
Melihat File
@@ -51,7 +51,7 @@ typedef enum // NOLINT(performance-enum-size)
ROCPROFILER_STATUS_ERROR, ///< Generalized error
ROCPROFILER_STATUS_ERROR_CONTEXT_NOT_FOUND, ///< No valid context for given context id
ROCPROFILER_STATUS_ERROR_BUFFER_NOT_FOUND, ///< No valid buffer for given buffer id
ROCPROFILER_STATUS_ERROR_DOMAIN_NOT_FOUND, ///< Domain identifier is invalid
ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND, ///< Kind identifier is invalid
ROCPROFILER_STATUS_ERROR_OPERATION_NOT_FOUND, ///< Operation identifier is invalid for domain
ROCPROFILER_STATUS_ERROR_THREAD_NOT_FOUND, ///< No valid thread for given thread id
ROCPROFILER_STATUS_ERROR_AGENT_NOT_FOUND, ///< Agent identifier not found
+87 -32
Melihat File
@@ -40,6 +40,46 @@
return _status; \
}
namespace rocprofiler
{
namespace buffer_tracing
{
namespace
{
#define ROCPROFILER_BUFFER_TRACING_KIND_STRING(CODE) \
template <> \
struct buffer_tracing_kind_string<ROCPROFILER_SERVICE_BUFFER_TRACING_##CODE> \
{ \
static constexpr auto value = \
std::pair<const char*, size_t>{#CODE, std::string_view{#CODE}.length()}; \
};
template <size_t Idx>
struct buffer_tracing_kind_string;
ROCPROFILER_BUFFER_TRACING_KIND_STRING(NONE)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(HSA_API)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(HIP_API)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(MARKER_API)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(MEMORY_COPY)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(KERNEL_DISPATCH)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(PAGE_MIGRATION)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(SCRATCH_MEMORY)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(EXTERNAL_CORRELATION)
template <size_t Idx, size_t... Tail>
std::pair<const char*, size_t>
get_kind_name(rocprofiler_service_buffer_tracing_kind_t kind, std::index_sequence<Idx, Tail...>)
{
if(kind == Idx) return buffer_tracing_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};
}
} // namespace
} // namespace buffer_tracing
} // namespace rocprofiler
extern "C" {
rocprofiler_status_t
rocprofiler_configure_buffer_tracing_service(rocprofiler_context_id_t context_id,
@@ -86,51 +126,66 @@ rocprofiler_configure_buffer_tracing_service(rocprofiler_context_id_t
}
rocprofiler_status_t
rocprofiler_iterate_buffer_tracing_kind_names(rocprofiler_buffer_tracing_kind_name_cb_t callback,
void* data)
rocprofiler_query_buffer_tracing_kind_name(rocprofiler_service_buffer_tracing_kind_t kind,
const char** name,
uint64_t* name_len)
{
// TODO(jrmadsen): need to add for other kinds
size_t n = 0;
bool premature = false;
using pair_t = std::pair<rocprofiler_service_buffer_tracing_kind_t, const char*>;
for(auto [eitr, sitr] : {
pair_t{ROCPROFILER_SERVICE_BUFFER_TRACING_HSA_API, "HSA_API"},
pair_t{ROCPROFILER_SERVICE_BUFFER_TRACING_HIP_API, "HIP_API"},
pair_t{ROCPROFILER_SERVICE_BUFFER_TRACING_MARKER_API, "MARKER_API"},
pair_t{ROCPROFILER_SERVICE_BUFFER_TRACING_MEMORY_COPY, "MEMORY_COPY"},
pair_t{ROCPROFILER_SERVICE_BUFFER_TRACING_KERNEL_DISPATCH, "KERNEL_DISPATCH"},
pair_t{ROCPROFILER_SERVICE_BUFFER_TRACING_PAGE_MIGRATION, "PAGE_MIGRATION"},
pair_t{ROCPROFILER_SERVICE_BUFFER_TRACING_SCRATCH_MEMORY, "SCRATCH_MEMORY"},
pair_t{ROCPROFILER_SERVICE_BUFFER_TRACING_EXTERNAL_CORRELATION, "EXTERNAL_CORRELATION"},
})
auto&& val = rocprofiler::buffer_tracing::get_kind_name(
kind, std::make_index_sequence<ROCPROFILER_SERVICE_BUFFER_TRACING_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_query_buffer_tracing_kind_operation_name(rocprofiler_service_buffer_tracing_kind_t kind,
uint32_t operation,
const char** name,
uint64_t* name_len)
{
if(kind < ROCPROFILER_SERVICE_BUFFER_TRACING_NONE ||
kind >= ROCPROFILER_SERVICE_BUFFER_TRACING_LAST)
return ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND;
if(kind == ROCPROFILER_SERVICE_BUFFER_TRACING_HSA_API)
{
auto _success = callback(eitr, sitr, data);
if(_success != 0)
const auto* val = rocprofiler::hsa::name_by_id(operation);
if(!val)
{
premature = true;
break;
if(name) *name = nullptr;
if(name_len) *name_len = 0;
return ROCPROFILER_STATUS_ERROR_OPERATION_NOT_FOUND;
}
++n;
if(name) *name = val;
if(name_len) *name_len = strnlen(val, 4096);
return ROCPROFILER_STATUS_SUCCESS;
}
#if defined(ROCPROFILER_CI)
if(!premature)
return ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED;
}
rocprofiler_status_t
rocprofiler_iterate_buffer_tracing_kinds(rocprofiler_buffer_tracing_kind_cb_t callback, void* data)
{
for(uint32_t i = 0; i < ROCPROFILER_SERVICE_BUFFER_TRACING_LAST; ++i)
{
LOG_ASSERT(n == ROCPROFILER_SERVICE_BUFFER_TRACING_LAST - 1)
<< " :: new enumeration value added. Update this function";
auto _success = callback(static_cast<rocprofiler_service_buffer_tracing_kind_t>(i), data);
if(_success != 0) break;
}
#else
(void) n;
(void) premature;
#endif
return ROCPROFILER_STATUS_SUCCESS;
}
rocprofiler_status_t
rocprofiler_iterate_buffer_tracing_kind_operation_names(
rocprofiler_iterate_buffer_tracing_kind_operations(
rocprofiler_service_buffer_tracing_kind_t kind,
rocprofiler_buffer_tracing_operation_name_cb_t callback,
rocprofiler_buffer_tracing_kind_operation_cb_t callback,
void* data)
{
if(kind == ROCPROFILER_SERVICE_BUFFER_TRACING_HSA_API)
@@ -138,7 +193,7 @@ rocprofiler_iterate_buffer_tracing_kind_operation_names(
auto ops = rocprofiler::hsa::get_ids();
for(const auto& itr : ops)
{
auto _success = callback(kind, itr, rocprofiler::hsa::name_by_id(itr), data);
auto _success = callback(kind, itr, data);
if(_success != 0) break;
}
return ROCPROFILER_STATUS_SUCCESS;
+88 -31
Melihat File
@@ -20,6 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <rocprofiler/fwd.h>
#include <rocprofiler/rocprofiler.h>
#include "lib/rocprofiler/context/context.hpp"
@@ -38,6 +39,43 @@
return _status; \
}
namespace rocprofiler
{
namespace callback_tracing
{
namespace
{
#define ROCPROFILER_CALLBACK_TRACING_KIND_STRING(CODE) \
template <> \
struct callback_tracing_kind_string<ROCPROFILER_SERVICE_CALLBACK_TRACING_##CODE> \
{ \
static constexpr auto value = \
std::pair<const char*, size_t>{#CODE, std::string_view{#CODE}.length()}; \
};
template <size_t Idx>
struct callback_tracing_kind_string;
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(NONE)
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(HSA_API)
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(HIP_API)
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(MARKER_API)
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(CODE_OBJECT)
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(KERNEL_DISPATCH)
template <size_t Idx, size_t... Tail>
std::pair<const char*, size_t>
get_kind_name(rocprofiler_service_callback_tracing_kind_t kind, std::index_sequence<Idx, Tail...>)
{
if(kind == Idx) return callback_tracing_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};
}
} // namespace
} // namespace callback_tracing
} // namespace rocprofiler
extern "C" {
rocprofiler_status_t
rocprofiler_configure_callback_tracing_service(rocprofiler_context_id_t context_id,
@@ -79,49 +117,68 @@ rocprofiler_configure_callback_tracing_service(rocprofiler_context_id_t context_
}
rocprofiler_status_t
rocprofiler_iterate_callback_tracing_kind_names(
rocprofiler_callback_tracing_kind_name_cb_t callback,
void* data)
rocprofiler_query_callback_tracing_kind_name(rocprofiler_service_callback_tracing_kind_t kind,
const char** name,
uint64_t* name_len)
{
// TODO(jrmadsen): need to add for other kinds
size_t n = 0;
bool premature = false;
using pair_t = std::pair<rocprofiler_service_callback_tracing_kind_t, const char*>;
for(auto [eitr, sitr] : {
pair_t{ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API, "HSA_API"},
pair_t{ROCPROFILER_SERVICE_CALLBACK_TRACING_HIP_API, "HIP_API"},
pair_t{ROCPROFILER_SERVICE_CALLBACK_TRACING_MARKER_API, "MARKER_API"},
pair_t{ROCPROFILER_SERVICE_CALLBACK_TRACING_CODE_OBJECT, "CODE_OBJECT"},
pair_t{ROCPROFILER_SERVICE_CALLBACK_TRACING_KERNEL_DISPATCH, "KERNEL_DISPATCH"},
})
auto&& val = rocprofiler::callback_tracing::get_kind_name(
kind, std::make_index_sequence<ROCPROFILER_SERVICE_CALLBACK_TRACING_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_query_callback_tracing_kind_operation_name(
rocprofiler_service_callback_tracing_kind_t kind,
uint32_t operation,
const char** name,
uint64_t* name_len)
{
if(kind < ROCPROFILER_SERVICE_CALLBACK_TRACING_NONE ||
kind >= ROCPROFILER_SERVICE_CALLBACK_TRACING_LAST)
return ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND;
if(kind == ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API)
{
auto _success = callback(eitr, sitr, data);
if(_success != 0)
const auto* val = rocprofiler::hsa::name_by_id(operation);
if(!val)
{
premature = true;
break;
if(name) *name = nullptr;
if(name_len) *name_len = 0;
return ROCPROFILER_STATUS_ERROR_OPERATION_NOT_FOUND;
}
++n;
if(name) *name = val;
if(name_len) *name_len = strnlen(val, 4096);
return ROCPROFILER_STATUS_SUCCESS;
}
#if defined(ROCPROFILER_CI)
if(!premature)
return ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED;
}
rocprofiler_status_t
rocprofiler_iterate_callback_tracing_kinds(rocprofiler_callback_tracing_kind_cb_t callback,
void* data)
{
for(uint32_t i = 0; i < ROCPROFILER_SERVICE_CALLBACK_TRACING_LAST; ++i)
{
LOG_ASSERT(n == ROCPROFILER_SERVICE_CALLBACK_TRACING_LAST - 1)
<< " :: new enumeration value added. Update this function";
auto _success = callback(static_cast<rocprofiler_service_callback_tracing_kind_t>(i), data);
if(_success != 0) break;
}
#else
(void) n;
(void) premature;
#endif
return ROCPROFILER_STATUS_SUCCESS;
}
rocprofiler_status_t
rocprofiler_iterate_callback_tracing_kind_operation_names(
rocprofiler_iterate_callback_tracing_kind_operations(
rocprofiler_service_callback_tracing_kind_t kind,
rocprofiler_callback_tracing_operation_name_cb_t callback,
rocprofiler_callback_tracing_kind_operation_cb_t callback,
void* data)
{
if(kind == ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API)
@@ -129,7 +186,7 @@ rocprofiler_iterate_callback_tracing_kind_operation_names(
auto ops = rocprofiler::hsa::get_ids();
for(const auto& itr : ops)
{
auto _success = callback(kind, itr, rocprofiler::hsa::name_by_id(itr), data);
auto _success = callback(kind, itr, data);
if(_success != 0) break;
}
return ROCPROFILER_STATUS_SUCCESS;
@@ -139,7 +196,7 @@ rocprofiler_iterate_callback_tracing_kind_operation_names(
}
rocprofiler_status_t
rocprofiler_iterate_callback_tracing_operation_args(
rocprofiler_iterate_callback_tracing_kind_operation_args(
rocprofiler_callback_tracing_record_t record,
rocprofiler_callback_tracing_operation_args_cb_t callback,
void* user_data)
+2 -2
Melihat File
@@ -47,7 +47,7 @@ rocprofiler_status_t
add_domain(domain_context<DomainT>& _cfg, DomainT _domain)
{
if(_domain <= domain_info<DomainT>::none || _domain >= domain_info<DomainT>::last)
return ROCPROFILER_STATUS_ERROR_DOMAIN_NOT_FOUND;
return ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND;
_cfg.domains |= (1 << _domain);
return ROCPROFILER_STATUS_SUCCESS;
@@ -58,7 +58,7 @@ rocprofiler_status_t
add_domain_op(domain_context<DomainT>& _cfg, DomainT _domain, uint32_t _op)
{
if(_domain <= domain_info<DomainT>::none || _domain >= domain_info<DomainT>::last)
return ROCPROFILER_STATUS_ERROR_DOMAIN_NOT_FOUND;
return ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND;
if(_op >= domain_info<DomainT>::padding) return ROCPROFILER_STATUS_ERROR_OPERATION_NOT_FOUND;
+1 -1
Melihat File
@@ -44,7 +44,7 @@ ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_SUCCESS, "Success")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR, "General error")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_CONTEXT_NOT_FOUND, "Context ID not found")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_BUFFER_NOT_FOUND, "Buffer ID not found")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_DOMAIN_NOT_FOUND, "Domain ID not found")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND, "Kind ID not found")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_OPERATION_NOT_FOUND, "Operation ID not found")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_THREAD_NOT_FOUND, "Thread ID not found")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_CONTEXT_ERROR, "General context error")
+168 -66
Melihat File
@@ -31,6 +31,7 @@
#include <dlfcn.h>
#include <pthread.h>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <filesystem>
@@ -39,6 +40,7 @@
#include <sstream>
#include <string_view>
#include <typeinfo>
#include <unordered_map>
#include <vector>
#define ROCPROFILER_CALL(ARG, MSG) \
@@ -58,6 +60,7 @@ struct callback_data
rocprofiler_callback_thread_t client_thread = {};
uint64_t client_workflow_count = {};
uint64_t client_callback_count = {};
uint64_t client_elapsed = {};
int64_t current_depth = 0;
int64_t max_depth = 0;
};
@@ -68,48 +71,147 @@ struct agent_data
std::vector<hsa_device_type_t> agents = {};
};
void
tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
rocprofiler_user_data_t*,
void* client_data)
using callback_kind_names_t = std::map<rocprofiler_service_callback_tracing_kind_t, const char*>;
using callback_kind_operation_names_t =
std::map<rocprofiler_service_callback_tracing_kind_t, std::map<uint32_t, const char*>>;
struct callback_name_info
{
using name_map_t = std::unordered_map<rocprofiler_service_callback_tracing_kind_t,
std::unordered_map<uint32_t, const char*>>;
callback_kind_names_t kind_names = {};
callback_kind_operation_names_t operation_names = {};
};
auto* cb_data = static_cast<callback_data*>(client_data);
auto
get_callback_tracing_names()
{
auto cb_name_info = callback_name_info{};
//
// callback for each kind operation
//
static auto tracing_kind_operation_cb =
[](rocprofiler_service_callback_tracing_kind_t kindv, uint32_t operation, void* data_v) {
auto* name_info_v = static_cast<callback_name_info*>(data_v);
static auto name_map = []() {
auto outer_cb = [](rocprofiler_service_callback_tracing_kind_t kind_v,
const char* /*kind_name*/,
void* data_v) {
auto inner_cb = [](rocprofiler_service_callback_tracing_kind_t kind,
uint32_t operation,
const char* operation_name,
void* data) {
auto& mdata = *static_cast<name_map_t*>(data);
mdata[kind][operation] = operation_name;
return 0;
};
auto& mdata_v = *static_cast<name_map_t*>(data_v);
mdata_v.emplace(kind_v, std::unordered_map<uint32_t, const char*>{});
rocprofiler_iterate_callback_tracing_kind_operation_names(kind_v, inner_cb, data_v);
if(kindv == ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API)
{
const char* name = nullptr;
ROCPROFILER_CALL(rocprofiler_query_callback_tracing_kind_operation_name(
kindv, operation, &name, nullptr),
"query callback tracing kind operation name");
if(name) name_info_v->operation_names[kindv][operation] = name;
}
return 0;
};
auto tmp = name_map_t{};
rocprofiler_iterate_callback_tracing_kind_names(outer_cb, static_cast<void*>(&tmp));
//
// callback for each callback kind (i.e. domain)
//
static auto tracing_kind_cb = [](rocprofiler_service_callback_tracing_kind_t kind, void* data) {
// store the callback kind name
auto* name_info_v = static_cast<callback_name_info*>(data);
const char* name = nullptr;
ROCPROFILER_CALL(rocprofiler_query_callback_tracing_kind_name(kind, &name, nullptr),
"query callback tracing kind operation name");
if(name) name_info_v->kind_names[kind] = name;
EXPECT_EQ(tmp.size(), ROCPROFILER_SERVICE_CALLBACK_TRACING_LAST - 1);
EXPECT_EQ(tmp.at(ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API).size(),
ROCPROFILER_HSA_API_ID_LAST);
if(kind == ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API)
{
ROCPROFILER_CALL(rocprofiler_iterate_callback_tracing_kind_operations(
kind, tracing_kind_operation_cb, static_cast<void*>(data)),
"iterating callback tracing kind operations");
}
return 0;
};
return tmp;
}();
ROCPROFILER_CALL(rocprofiler_iterate_callback_tracing_kinds(tracing_kind_cb,
static_cast<void*>(&cb_name_info)),
"iterating callback tracing kinds");
return cb_name_info;
}
using buffer_kind_names_t = std::map<rocprofiler_service_buffer_tracing_kind_t, const char*>;
using buffer_kind_operation_names_t =
std::map<rocprofiler_service_buffer_tracing_kind_t, std::map<uint32_t, const char*>>;
struct buffer_name_info
{
buffer_kind_names_t kind_names = {};
buffer_kind_operation_names_t operation_names = {};
};
buffer_name_info
get_buffer_tracing_names()
{
auto cb_name_info = buffer_name_info{};
//
// callback for each kind operation
//
static auto tracing_kind_operation_cb =
[](rocprofiler_service_buffer_tracing_kind_t kindv, uint32_t operation, void* data_v) {
auto* name_info_v = static_cast<buffer_name_info*>(data_v);
if(kindv == ROCPROFILER_SERVICE_BUFFER_TRACING_HSA_API)
{
const char* name = nullptr;
ROCPROFILER_CALL(rocprofiler_query_buffer_tracing_kind_operation_name(
kindv, operation, &name, nullptr),
"query buffer tracing kind operation name");
if(name) name_info_v->operation_names[kindv][operation] = name;
}
return 0;
};
//
// callback for each buffer kind (i.e. domain)
//
static auto tracing_kind_cb = [](rocprofiler_service_buffer_tracing_kind_t kind, void* data) {
// store the buffer kind name
auto* name_info_v = static_cast<buffer_name_info*>(data);
const char* name = nullptr;
ROCPROFILER_CALL(rocprofiler_query_buffer_tracing_kind_name(kind, &name, nullptr),
"query buffer tracing kind operation name");
if(name) name_info_v->kind_names[kind] = name;
if(kind == ROCPROFILER_SERVICE_BUFFER_TRACING_HSA_API)
{
ROCPROFILER_CALL(rocprofiler_iterate_buffer_tracing_kind_operations(
kind, tracing_kind_operation_cb, static_cast<void*>(data)),
"iterating buffer tracing kind operations");
}
return 0;
};
ROCPROFILER_CALL(rocprofiler_iterate_buffer_tracing_kinds(tracing_kind_cb,
static_cast<void*>(&cb_name_info)),
"iterating buffer tracing kinds");
return cb_name_info;
}
void
tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
rocprofiler_user_data_t* user_data,
void* client_data)
{
auto* cb_data = static_cast<callback_data*>(client_data);
auto get_timestamp = []() {
return std::chrono::steady_clock::now().time_since_epoch().count();
};
if(record.phase == ROCPROFILER_SERVICE_CALLBACK_PHASE_ENTER && cb_data->current_depth == 0)
{
user_data->value = get_timestamp();
}
static auto name_map = get_callback_tracing_names();
EXPECT_EQ(name_map.kind_names.size(), ROCPROFILER_SERVICE_CALLBACK_TRACING_LAST);
EXPECT_EQ(name_map.operation_names.at(ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API).size(),
ROCPROFILER_HSA_API_ID_LAST);
std::cout << "[" << __FILE__ << ":" << __LINE__ << "] "
<< name_map[record.kind][record.operation] << "\n"
<< name_map.operation_names[record.kind][record.operation] << "\n"
<< std::flush;
cb_data->client_callback_count++;
@@ -151,7 +253,7 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
return 0;
};
ROCPROFILER_CALL(rocprofiler_iterate_callback_tracing_operation_args(
ROCPROFILER_CALL(rocprofiler_iterate_callback_tracing_kind_operation_args(
record, info_data_cb, static_cast<void*>(&info_data_v)),
"Failure iterating trace operation args");
if(record.kind == ROCPROFILER_SERVICE_CALLBACK_TRACING_HSA_API &&
@@ -159,7 +261,12 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
record.operation == ROCPROFILER_HSA_API_ID_hsa_shut_down))
{
EXPECT_GT(info_data_v.num_args, 0)
<< name_map[record.kind][record.operation] << info_data_v.arg_ss.str();
<< name_map.operation_names[record.kind][record.operation] << info_data_v.arg_ss.str();
}
if(record.phase == ROCPROFILER_SERVICE_CALLBACK_PHASE_EXIT && cb_data->current_depth == 0)
{
cb_data->client_elapsed += (get_timestamp() - user_data->value);
}
}
@@ -171,36 +278,13 @@ tool_tracing_buffered(rocprofiler_context_id_t context,
void* buffer_data,
uint64_t drop_count)
{
using name_map_t = std::unordered_map<rocprofiler_service_buffer_tracing_kind_t,
std::unordered_map<uint32_t, const char*>>;
std::cout << __FUNCTION__ << "...\n" << std::endl;
auto* cb_data = static_cast<callback_data*>(buffer_data);
static auto name_map = []() {
auto tmp = name_map_t{};
//
static auto tracing_kind_names_cb = [](rocprofiler_service_buffer_tracing_kind_t kind,
const char* /*kind_name*/,
void* data) {
auto tracing_operation_names_cb = [](rocprofiler_service_buffer_tracing_kind_t kindv,
uint32_t operation,
const char* operation_name,
void* data_v) {
(*static_cast<name_map_t*>(data_v))[kindv][operation] = operation_name;
return 0;
};
static auto name_map = get_buffer_tracing_names();
rocprofiler_iterate_buffer_tracing_kind_operation_names(
kind, tracing_operation_names_cb, data);
return 0;
};
rocprofiler_iterate_buffer_tracing_kind_names(tracing_kind_names_cb,
static_cast<void*>(&tmp));
return tmp;
}();
EXPECT_EQ(name_map.kind_names.size(), ROCPROFILER_SERVICE_BUFFER_TRACING_LAST);
EXPECT_EQ(name_map.operation_names.at(ROCPROFILER_SERVICE_BUFFER_TRACING_HSA_API).size(),
ROCPROFILER_HSA_API_ID_LAST);
auto v_records = std::vector<rocprofiler_buffer_tracing_hsa_api_record_t*>{};
v_records.reserve(num_headers);
@@ -230,9 +314,10 @@ tool_tracing_buffered(rocprofiler_context_id_t context,
auto info = std::stringstream{};
info << "tid=" << record->thread_id << ", context=" << context.handle
<< ", buffer_id=" << buffer_id.handle << ", cid=" << record->correlation_id.internal
<< ", kind=" << record->kind << ", operation=" << record->operation
<< ", drop_count=" << drop_count << ", start=" << record->start_timestamp
<< ", stop=" << record->end_timestamp;
<< ", kind=" << name_map.kind_names.at(record->kind) << "(" << record->kind
<< "), operation=" << name_map.operation_names.at(record->kind).at(record->operation)
<< "(" << record->operation << "), drop_count=" << drop_count
<< ", start=" << record->start_timestamp << ", stop=" << record->end_timestamp;
static int64_t last_corr_id = -1;
auto corr_id = static_cast<int64_t>(record->correlation_id.internal);
@@ -295,6 +380,7 @@ TEST(rocprofiler_lib, callback_registration_lambda_with_result)
using hsa_iterate_agents_cb_t = hsa_status_t (*)(hsa_agent_t, void*);
auto cmd_line = rocprofiler::common::read_command_line(getpid());
ASSERT_FALSE(cmd_line.empty());
static init_func_t tool_init = [](rocprofiler_client_finalize_t fini_func,
@@ -360,6 +446,10 @@ TEST(rocprofiler_lib, callback_registration_lambda_with_result)
return &cfg_result;
};
auto get_timestamp = []() {
return std::chrono::steady_clock::now().time_since_epoch().count();
};
auto ctx = rocprofiler_context_id_t{};
EXPECT_NE(rocprofiler_create_context(&ctx), ROCPROFILER_STATUS_SUCCESS);
EXPECT_EQ(rocprofiler_force_configure(rocp_init), ROCPROFILER_STATUS_SUCCESS);
@@ -377,14 +467,26 @@ TEST(rocprofiler_lib, callback_registration_lambda_with_result)
return status;
};
auto _agent_data = agent_data{};
hsa_init();
hsa_status_t itr_status = hsa_iterate_agents(agent_cb, static_cast<void*>(&_agent_data));
auto _agent_data = agent_data{};
auto begin_ts = get_timestamp();
hsa_status_t itr_status = hsa_iterate_agents(agent_cb, static_cast<void*>(&_agent_data));
auto end_ts = get_timestamp();
auto elapsed = (end_ts - begin_ts);
EXPECT_EQ(itr_status, HSA_STATUS_SUCCESS);
EXPECT_GT(_agent_data.agent_count, 0);
EXPECT_EQ(_agent_data.agent_count, _agent_data.agents.size());
#if !defined(__OPTIMIZE__) || (defined(CODECOV) && CODECOV > 0)
EXPECT_GT(cb_data.client_elapsed, 0);
EXPECT_GT(elapsed, 0);
#else
decltype(elapsed) elapsed_tolerance = 0.25 * elapsed;
EXPECT_NEAR(elapsed, cb_data.client_elapsed, elapsed_tolerance)
<< "it is possible this failed due to noise on the machine";
#endif
ASSERT_NE(cb_data.client_id, nullptr);
ASSERT_NE(cb_data.client_fini_func, nullptr);