Add support for AQL dimensions (#262)

* Add support for AQL dimension changes

Adds support for returning dimensions from AQLProfile through rocprofiler
to tools. Includes a much larger expanded test suite that covers nearly
all files in counter collection.

Specific changes below:

samples/counter_collection/print_functional_counters: Modified to check
the validity of dimensions returned in comparison to the actual underlying
data obtained from a kernel execution.

rocprofiler-sdk/aql/helpers: adds function calls to support fetching
dimension information from AQLProfile.

rocprofiler-sdk/aql/packet_construct: modified to allow for events
to be exported to aid evaluate_ast in decoding the output buffer.

lib/rocprofiler-sdk/counters: Instance count now derived from dimension
sizes. rocprofiler_query_counter_dimensions now moved to a callback format
to improve usability.

rocprofiler-sdk/counters/core: Code migrations and exports of functions
for testing.

rocprofiler-sdk/counters/dimensions: Generates a dimension cache to be
used when querying dimension information for a counter id.

rocprofiler-sdk/counters/evaluate_ast: Modified to pass back correct
dimension information and to check/determine output dimensions for derived
counters.

rocprofiler-sdk/counters/id_decode: Modified to have a map between
dimension name -> dimension along with a conversion from the aql profile
id for a dimension (string) -> integer based id (happens only once during
init).

rocprofiler-sdk/hsa/queue: Modified to allow for making testing easier.
Specifically to allow Queue to now be mocked in unit tests for counter
collection.

* Merge with changes for serialization

* Added suggestions

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

Co-authored-by: bwelton <bwelton@users.noreply.github.com>

* Minor fix

* Test change

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: bwelton <bwelton@users.noreply.github.com>
Αυτή η υποβολή περιλαμβάνεται σε:
authored and GitHub committed 2024-02-07 22:03:21 -06:00
1 γονέας 8a25b239bc
υποβολή 3eb6a27bc6
29 files changed
+1670 -293

No files matched your search

@@ -25,9 +25,12 @@
#include <fmt/core.h>
#include "lib/common/container/small_vector.hpp"
#include "lib/common/static_object.hpp"
#include "lib/common/synchronized.hpp"
#include "lib/rocprofiler-sdk/agent.hpp"
#include "lib/rocprofiler-sdk/aql/helpers.hpp"
#include "lib/rocprofiler-sdk/counters/dimensions.hpp"
#include "lib/rocprofiler-sdk/counters/evaluate_ast.hpp"
#include "lib/rocprofiler-sdk/counters/id_decode.hpp"
#include "lib/rocprofiler-sdk/counters/metrics.hpp"
@@ -73,55 +76,27 @@ rocprofiler_query_counter_name(rocprofiler_counter_id_t counter_id, const char**
* @return rocprofiler_status_t
*/
rocprofiler_status_t
rocprofiler_query_counter_instance_count(rocprofiler_agent_id_t agent_id,
rocprofiler_query_counter_instance_count(rocprofiler_agent_id_t,
rocprofiler_counter_id_t counter_id,
size_t* instance_count)
{
const rocprofiler_agent_t* agent = rocprofiler::agent::get_agent(agent_id);
if(!agent) return ROCPROFILER_STATUS_ERROR_AGENT_NOT_FOUND;
if(agent->type != ROCPROFILER_AGENT_TYPE_GPU) return ROCPROFILER_STATUS_ERROR;
const auto& id_map = *CHECK_NOTNULL(rocprofiler::counters::getMetricIdMap());
const auto* metric_ptr = rocprofiler::common::get_val(id_map, counter_id.handle);
if(!metric_ptr) return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
*instance_count = 0;
// Special counters do not have hardware metrics and will always have an instance
// count of 1 (i.e. MAX_WAVE_SIZE)
if(!metric_ptr->special().empty())
if(rocprofiler::counters::get_dimension_cache().empty())
{
*instance_count = 1;
return ROCPROFILER_STATUS_SUCCESS;
return ROCPROFILER_STATUS_ERROR_HSA_NOT_LOADED;
}
// Returns the set of hardware counters needed to evaluate the metric.
// For derived metrics, this can be more than one counter. In that case,
// we return the maximum instance count among all underlying counters.
auto req_counters = rocprofiler::counters::get_required_hardware_counters(
rocprofiler::counters::get_ast_map(), std::string(agent->name), *metric_ptr);
if(!req_counters) return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
const auto* dims = rocprofiler::common::get_val(rocprofiler::counters::get_dimension_cache(),
counter_id.handle);
if(!dims) return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
for(const auto& counter : *req_counters)
for(const auto& metric_dim : *dims)
{
if(!counter.special().empty())
{
*instance_count = std::max(size_t(1), *instance_count);
continue;
}
try
{
auto dims = rocprofiler::counters::getBlockDimensions(agent->name, counter);
for(const auto& dim : dims)
{
*instance_count = std::max(static_cast<size_t>(dim.size()), *instance_count);
}
} catch(std::runtime_error& err)
{
LOG(ERROR) << fmt::format("Could not lookup instance count for counter {}", counter);
return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
}
if(*instance_count == 0)
*instance_count = metric_dim.size();
else if(metric_dim.size() > 0)
*instance_count = metric_dim.size() * *instance_count;
}
return ROCPROFILER_STATUS_SUCCESS;
@@ -180,20 +155,36 @@ rocprofiler_query_record_dimension_position(rocprofiler_counter_instance_id_t i
}
rocprofiler_status_t
rocprofiler_query_record_dimension_info(rocprofiler_counter_id_t,
rocprofiler_counter_dimension_id_t dim,
rocprofiler_record_dimension_info_t* info)
rocprofiler_iterate_counter_dimensions(rocprofiler_counter_id_t id,
rocprofiler_available_dimensions_cb_t info_cb,
void* user_data)
{
if(const auto* ptr = rocprofiler::common::get_val(
rocprofiler::counters::dimension_map(),
static_cast<rocprofiler::counters::rocprofiler_profile_counter_instance_types>(dim)))
if(rocprofiler::counters::get_dimension_cache().empty())
{
info->name = ptr->c_str();
// TODO: Needs info on the instance size per block to fill in.
// counter_id will be used to lookup this information.
info->instance_size = 0;
return ROCPROFILER_STATUS_SUCCESS;
return ROCPROFILER_STATUS_ERROR_HSA_NOT_LOADED;
}
return ROCPROFILER_STATUS_ERROR;
const auto* dims =
rocprofiler::common::get_val(rocprofiler::counters::get_dimension_cache(), id.handle);
if(!dims) return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
// This is likely faster than a map lookup given the limited number of dims.
rocprofiler::common::container::small_vector<rocprofiler_record_dimension_info_t, 6> user_dims;
for(const auto& internal_dim : *dims)
{
auto& dim = user_dims.emplace_back();
dim.name = internal_dim.name().c_str();
dim.instance_size = internal_dim.size();
dim.id = static_cast<rocprofiler_counter_dimension_id_t>(internal_dim.type());
}
if(user_dims.empty())
{
return ROCPROFILER_STATUS_ERROR_DIM_NOT_FOUND;
}
info_cb(id, user_dims.data(), user_dims.size(), user_data);
return ROCPROFILER_STATUS_SUCCESS;
}
}