diff --git a/inc/rocprofiler.h b/inc/rocprofiler.h index f7d5a73bb8..600b68dab7 100644 --- a/inc/rocprofiler.h +++ b/inc/rocprofiler.h @@ -71,9 +71,15 @@ extern "C" { #endif // __cplusplus //////////////////////////////////////////////////////////////////////////////// -// Profiling info +// Returning the error string method + +hsa_status_t rocprofiler_error_string( + const char** str); // [out] the API error string pointer returning + +//////////////////////////////////////////////////////////////////////////////// +// Profiling features and data // -// Profiling info objects have profiling feature info, type, parameters and data +// Profiling features objects have profiling feature info, type, parameters and data // Also profiling data samplaes can be iterated using a callback // Profiling feature kind @@ -232,6 +238,10 @@ hsa_status_t rocprofiler_start(rocprofiler_t* context, // [in/out] profiling hsa_status_t rocprofiler_stop(rocprofiler_t* context, // [in/out] profiling context uint32_t group_index); // group index +// Read profiling +hsa_status_t rocprofiler_read(rocprofiler_t* context, // [in/out] profiling context + uint32_t group_index); // group index + // Read profiling data hsa_status_t rocprofiler_get_data(rocprofiler_t* context, // [in/out] profiling context uint32_t group_index); // group index @@ -242,7 +252,7 @@ hsa_status_t rocprofiler_group_count(const rocprofiler_t* context, // [in] prof // Get profiling group for a given index hsa_status_t rocprofiler_get_group(rocprofiler_t* context, // [in] profiling context - uint32_t group_index, // [in] profiling group index + uint32_t group_index, // profiling group index rocprofiler_group_t* group); // [out] profiling group // Start profiling @@ -251,6 +261,9 @@ hsa_status_t rocprofiler_group_start(rocprofiler_group_t* group); // [in/out] p // Stop profiling hsa_status_t rocprofiler_group_stop(rocprofiler_group_t* group); // [in/out] profiling group +// Read profiling +hsa_status_t rocprofiler_group_read(rocprofiler_group_t* group); // [in/out] profiling group + // Get profiling data hsa_status_t rocprofiler_group_get_data(rocprofiler_group_t* group); // [in/out] profiling group @@ -263,14 +276,74 @@ typedef hsa_ven_amd_aqlprofile_data_callback_t rocprofiler_trace_data_callback_t // Method for iterating the events output data hsa_status_t rocprofiler_iterate_trace_data( rocprofiler_t* context, // [in] profiling context - rocprofiler_trace_data_callback_t callback, // [in] callback to iterate the output data + rocprofiler_trace_data_callback_t callback, // callback to iterate the output data void* data); // [in/out] callback data //////////////////////////////////////////////////////////////////////////////// -// Returning the error string method +// Profiling features and data +// +// Profiling features objects have profiling feature info, type, parameters and data +// Also profiling data samplaes can be iterated using a callback -hsa_status_t rocprofiler_error_string( - const char** str); // [out] the API error string pointer returning +// Profiling info kind +typedef enum { + ROCPROFILER_INFO_KIND_METRIC = 0, // metric info + ROCPROFILER_INFO_KIND_METRIC_COUNT = 1, // metric features count, int32 + ROCPROFILER_INFO_KIND_TRACE = 2, // trace info + ROCPROFILER_INFO_KIND_TRACE_COUNT = 3, // trace features count, int32 + ROCPROFILER_INFO_KIND_TRACE_PARAMETER = 4, // trace parameter info + ROCPROFILER_INFO_KIND_TRACE_PARAMETER_COUNT = 5 // trace parameter count, int32 +} rocprofiler_info_kind_t; + +// Profiling info query +typedef union { + rocprofiler_info_kind_t info_kind; // queried profiling info kind + struct { + const char* trace_name; // queried info trace name + } trace_parameter; +} rocprofiler_info_query_t; + +// Profiling info data +typedef struct { + rocprofiler_info_kind_t kind; // info data kind + union { + struct { + const char* name; // metric name + const char* description; // metric description + } metric; + struct { + const char* name; // trace name + const char* description; // trace description + uint32_t parameter_count; // supported by the trace number parameters + } trace; + struct { + uint32_t code; // parameter code + const char* trace_name; // trace name + const char* parameter_name; // parameter name + const char* description; // trace parameter description + } trace_parameter; + }; +} rocprofiler_info_data_t; + +// Return the info for a given info kind +hsa_status_t rocprofiler_get_info( + hsa_agent_t agent, // GFXIP handle + rocprofiler_info_kind_t kind, // kind of iterated info + void *data); // [in/out] returned data + +// Iterate over the info for a given info kind, and invoke an application-defined callback on every iteration +hsa_status_t rocprofiler_iterate_info( + hsa_agent_t agent, // GFXIP handle + rocprofiler_info_kind_t kind, // kind of iterated info + hsa_status_t (*callback)(const rocprofiler_info_data_t info, void *data), // callback + void *data); // [in/out] data passed to callback + +// Iterate over the info for a given info query, and invoke an application-defined callback on every iteration +hsa_status_t rocprofiler_query_info( + hsa_agent_t agent, // GFXIP handle + rocprofiler_info_query_t query, // iterated info query + hsa_status_t (*callback)(const rocprofiler_info_data_t info, void *data), // callback + void *data); // [in/out] data passed to callback #ifdef __cplusplus } // extern "C" block diff --git a/src/core/rocprofiler.cpp b/src/core/rocprofiler.cpp index 7c5073465f..9a678a776e 100644 --- a/src/core/rocprofiler.cpp +++ b/src/core/rocprofiler.cpp @@ -21,6 +21,7 @@ #define API_METHOD_PREFIX \ hsa_status_t status = HSA_STATUS_SUCCESS; \ try { + #define API_METHOD_SUFFIX \ } \ catch (std::exception & e) { \ @@ -29,6 +30,9 @@ } \ return status; +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Internal library methods +// namespace rocprofiler { decltype(hsa_queue_create)* hsa_queue_create_fn; decltype(hsa_queue_destroy)* hsa_queue_destroy_fn; @@ -112,12 +116,43 @@ hsa_status_t GetExcStatus(const std::exception& e) { : HSA_STATUS_ERROR; } +const MetricsDict* GetMetrics(const hsa_agent_t& agent) { + rocprofiler::util::HsaRsrcFactory* hsa_rsrc = &rocprofiler::util::HsaRsrcFactory::Instance(); + const rocprofiler::util::AgentInfo* agent_info = hsa_rsrc->GetAgentInfo(agent); + if (agent_info == NULL) { + EXC_RAISING(HSA_STATUS_ERROR, "agent is not found"); + } + const MetricsDict* metrics = MetricsDict::Create(agent_info); + if (metrics == NULL) EXC_RAISING(HSA_STATUS_ERROR, "MetricsDict create failed"); + return metrics; +} + util::Logger::mutex_t util::Logger::mutex_; util::Logger* util::Logger::instance_ = NULL; } +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Public library methods +// extern "C" { +// HSA-runtime tool on-load method +PUBLIC_API bool OnLoad(HsaApiTable* table, uint64_t runtime_version, uint64_t failed_tool_count, + const char* const* failed_tool_names) { + rocprofiler::SaveHsaApi(table); + rocprofiler::ProxyQueue::InitFactory(); + rocprofiler::InterceptQueue::SetTool(getenv("ROCP_TOOL_LIB")); + // HSA intercepting + if (getenv("ROCP_HSA_INTERCEPT") != NULL) { + rocprofiler::InterceptQueue::HsaIntercept(table); + rocprofiler::ProxyQueue::HsaIntercept(table); + } + return true; +} + +// HSA-runtime tool on-unload method +PUBLIC_API void OnUnload() { rocprofiler::RestoreHsaApi(); } + // Returns the last error message PUBLIC_API hsa_status_t rocprofiler_error_string(const char** str) { API_METHOD_PREFIX @@ -126,8 +161,8 @@ PUBLIC_API hsa_status_t rocprofiler_error_string(const char** str) { } // Create new profiling context -PUBLIC_API hsa_status_t rocprofiler_open(hsa_agent_t agent, rocprofiler_feature_t* info, - uint32_t info_count, rocprofiler_t** handle, uint32_t mode, +PUBLIC_API hsa_status_t rocprofiler_open(hsa_agent_t agent, rocprofiler_feature_t* features, + uint32_t feature_count, rocprofiler_t** handle, uint32_t mode, rocprofiler_properties_t* properties) { API_METHOD_PREFIX rocprofiler::util::HsaRsrcFactory* hsa_rsrc = &rocprofiler::util::HsaRsrcFactory::Instance(); @@ -151,7 +186,7 @@ PUBLIC_API hsa_status_t rocprofiler_open(hsa_agent_t agent, rocprofiler_feature_ } } - *handle = new rocprofiler::Context(agent_info, queue, info, info_count, properties->handler, + *handle = new rocprofiler::Context(agent_info, queue, features, feature_count, properties->handler, properties->handler_arg); API_METHOD_SUFFIX } @@ -268,21 +303,86 @@ PUBLIC_API hsa_status_t rocprofiler_iterate_trace_data( API_METHOD_SUFFIX } -// HSA-runtime tool on-load method -PUBLIC_API bool OnLoad(HsaApiTable* table, uint64_t runtime_version, uint64_t failed_tool_count, - const char* const* failed_tool_names) { - rocprofiler::SaveHsaApi(table); - rocprofiler::ProxyQueue::InitFactory(); - rocprofiler::InterceptQueue::SetTool(getenv("ROCP_TOOL_LIB")); - // HSA intercepting - if (getenv("ROCP_HSA_INTERCEPT") != NULL) { - rocprofiler::InterceptQueue::HsaIntercept(table); - rocprofiler::ProxyQueue::HsaIntercept(table); +// Return the info for a given info kind +PUBLIC_API hsa_status_t rocprofiler_get_info( + hsa_agent_t agent, + rocprofiler_info_kind_t kind, + void *data) +{ + API_METHOD_PREFIX + uint32_t* result_32bit_ptr = reinterpret_cast(data); + + switch (kind) { + case ROCPROFILER_INFO_KIND_METRIC_COUNT: + *result_32bit_ptr = rocprofiler::GetMetrics(agent)->Size(); + break; + case ROCPROFILER_INFO_KIND_TRACE_COUNT: + *result_32bit_ptr = 1; + break; + default: + EXC_RAISING(HSA_STATUS_ERROR, "unknown info kind(" << kind << ")"); } - return true; + API_METHOD_SUFFIX } -// HSA-runtime tool on-unload method -PUBLIC_API void OnUnload() { rocprofiler::RestoreHsaApi(); } +// Iterate over the info for a given info kind, and invoke an application-defined callback on every iteration +PUBLIC_API hsa_status_t rocprofiler_iterate_info( + hsa_agent_t agent, + rocprofiler_info_kind_t kind, + hsa_status_t (*callback)(const rocprofiler_info_data_t info, void *data), + void *data) +{ + API_METHOD_PREFIX + rocprofiler_info_data_t info{}; + info.kind = kind; + + switch (kind) { + case ROCPROFILER_INFO_KIND_METRIC: + { + const rocprofiler::MetricsDict* dict = rocprofiler::GetMetrics(agent); + rocprofiler::MetricsDict::const_iterator_t it = dict->Begin(); + rocprofiler::MetricsDict::const_iterator_t end = dict->End(); + while (it != end) { + const rocprofiler::Metric* metric = it->second; + std::string name = metric->GetName(); + const auto* expr = metric->GetExpr(); + std::string description = "Performance metric " + name + " " + ((expr == NULL) ? "basic" : "= " + expr->String()); + info.metric.name = strdup(name.c_str()); + info.metric.description = strdup(description.c_str()); + status = callback(info, data); + + ++it; + } + break; + } + case ROCPROFILER_INFO_KIND_TRACE: + { + info.trace.name = strdup("TT"); + info.trace.description = strdup("Thread Trace"); + info.trace.parameter_count = 5; + status = callback(info, data); + break; + } + default: + EXC_RAISING(HSA_STATUS_ERROR, "unknown info kind(" << kind << ")"); + } + + if (status == HSA_STATUS_INFO_BREAK) status = HSA_STATUS_SUCCESS; + if (status != HSA_STATUS_SUCCESS) ERR_LOGGING("iterate_info error, info kind(" << kind << ")"); + + API_METHOD_SUFFIX +} + +// Iterate over the info for a given info query, and invoke an application-defined callback on every iteration +PUBLIC_API hsa_status_t rocprofiler_query_info( + hsa_agent_t agent, + rocprofiler_info_query_t query, + hsa_status_t (*callback)(const rocprofiler_info_data_t info, void *data), + void *data) +{ + API_METHOD_PREFIX + EXC_RAISING(HSA_STATUS_ERROR, "Not implemented"); + API_METHOD_SUFFIX +} } // extern "C"