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>
[ROCm/rocprofiler-sdk commit: 3eb6a27bc6]
This commit is contained in:
@@ -62,7 +62,7 @@ kernelC(T* C_d, const T* A_d, size_t N)
|
||||
void
|
||||
launchKernels()
|
||||
{
|
||||
const int NUM_LAUNCH = 50000;
|
||||
const int NUM_LAUNCH = 20000;
|
||||
// Normal HIP Calls
|
||||
int* gpuMem;
|
||||
[[maybe_unused]] hipDeviceProp_t devProp;
|
||||
|
||||
+130
-10
@@ -13,6 +13,8 @@
|
||||
#include <rocprofiler-sdk/registration.h>
|
||||
#include <rocprofiler-sdk/rocprofiler.h>
|
||||
|
||||
#define PRINT_ONLY_FAILING true
|
||||
|
||||
/**
|
||||
* Tests the collection of all counters on the agent the test is run on.
|
||||
*/
|
||||
@@ -55,13 +57,92 @@ get_buffer()
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Struct to validate that all dimension values are present. Does
|
||||
// so by creating a tree of dimension values expected. If all are marked as
|
||||
// having values, then all values are present in the output.
|
||||
struct validate_dim_presence
|
||||
{
|
||||
validate_dim_presence() {}
|
||||
|
||||
void maybe_forward(const rocprofiler_record_dimension_info_t& dim)
|
||||
{
|
||||
if(sub_vectors.empty())
|
||||
{
|
||||
for(size_t i = 0; i < dim.instance_size; i++)
|
||||
{
|
||||
sub_vectors.emplace_back(std::make_unique<validate_dim_presence>());
|
||||
sub_vectors.back()->vector_pos = std::make_pair(dim, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto& vec : sub_vectors)
|
||||
{
|
||||
vec->maybe_forward(dim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mark_seen(const rocprofiler_counter_instance_id_t& id)
|
||||
{
|
||||
if(sub_vectors.empty())
|
||||
{
|
||||
has_value = true;
|
||||
return;
|
||||
}
|
||||
size_t pos = 0;
|
||||
ROCPROFILER_CALL(rocprofiler_query_record_dimension_position(
|
||||
id, sub_vectors.at(0)->vector_pos.first.id, &pos),
|
||||
"Could not query position");
|
||||
sub_vectors.at(pos)->mark_seen(id);
|
||||
}
|
||||
|
||||
bool check_seen(std::stringstream& out,
|
||||
std::vector<std::pair<rocprofiler_record_dimension_info_t, size_t>>& pos_stack)
|
||||
{
|
||||
bool ret = true;
|
||||
if(sub_vectors.empty())
|
||||
{
|
||||
if(!has_value)
|
||||
{
|
||||
ret = false;
|
||||
out << "\tMissing Value at [";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "\tHas Value at [";
|
||||
}
|
||||
for(const auto& [dim, pos] : pos_stack)
|
||||
{
|
||||
out << dim.name << ":" << pos << ",";
|
||||
}
|
||||
out << "]\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < sub_vectors.size(); i++)
|
||||
{
|
||||
pos_stack.push_back(sub_vectors[i]->vector_pos);
|
||||
if(!sub_vectors[i]->check_seen(out, pos_stack)) ret = false;
|
||||
pos_stack.pop_back();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::pair<rocprofiler_record_dimension_info_t, size_t> vector_pos;
|
||||
std::vector<std::unique_ptr<validate_dim_presence>> sub_vectors;
|
||||
bool has_value{false};
|
||||
};
|
||||
|
||||
struct CaptureRecords
|
||||
{
|
||||
std::shared_mutex m_mutex{};
|
||||
// <counter id handle, expected instances>
|
||||
std::map<uint64_t, size_t> expected{};
|
||||
std::map<uint64_t, std::string> expected_counter_names{};
|
||||
std::vector<rocprofiler_counter_id_t> remaining{};
|
||||
std::map<uint64_t, size_t> expected{};
|
||||
// expected dims that we should see data for
|
||||
std::map<uint64_t, validate_dim_presence> expected_data_dims{};
|
||||
std::map<uint64_t, std::string> expected_counter_names{};
|
||||
std::vector<rocprofiler_counter_id_t> remaining{};
|
||||
// <counter_id handle, instances seen>
|
||||
std::map<uint64_t, size_t> captured{};
|
||||
};
|
||||
@@ -82,8 +163,9 @@ buffered_callback(rocprofiler_context_id_t,
|
||||
void*,
|
||||
uint64_t)
|
||||
{
|
||||
auto& cap = *get_capture();
|
||||
auto wlock = std::unique_lock{cap.m_mutex};
|
||||
auto& cap = *get_capture();
|
||||
auto wlock = std::unique_lock{cap.m_mutex};
|
||||
|
||||
std::map<uint64_t, size_t> seen_counters;
|
||||
for(size_t i = 0; i < num_headers; ++i)
|
||||
{
|
||||
@@ -95,6 +177,7 @@ buffered_callback(rocprofiler_context_id_t,
|
||||
rocprofiler_counter_id_t counter;
|
||||
auto* record = static_cast<rocprofiler_record_counter_t*>(header->payload);
|
||||
rocprofiler_query_record_counter_id(record->id, &counter);
|
||||
cap.expected_data_dims.at(counter.handle).mark_seen(record->id);
|
||||
seen_counters.emplace(counter.handle, 0).first->second++;
|
||||
}
|
||||
}
|
||||
@@ -146,15 +229,38 @@ dispatch_callback(rocprofiler_queue_id_t /*queue_id*/,
|
||||
|
||||
for(auto& found_counter : counters_needed)
|
||||
{
|
||||
size_t expected = 0;
|
||||
rocprofiler_query_counter_instance_count(agent->id, found_counter, &expected);
|
||||
cap.remaining.push_back(found_counter);
|
||||
cap.expected.emplace(found_counter.handle, expected);
|
||||
const char* name;
|
||||
size_t name_size;
|
||||
ROCPROFILER_CALL(rocprofiler_query_counter_name(found_counter, &name, &name_size),
|
||||
"Could not query name");
|
||||
cap.expected_counter_names.emplace(found_counter.handle, std::string(name));
|
||||
size_t expected = 0;
|
||||
ROCPROFILER_CALL(
|
||||
rocprofiler_query_counter_instance_count(agent->id, found_counter, &expected),
|
||||
"COULD NOT QUERY INSTANCES");
|
||||
cap.remaining.push_back(found_counter);
|
||||
cap.expected.emplace(found_counter.handle, expected);
|
||||
|
||||
auto& info_vector =
|
||||
cap.expected_data_dims.emplace(found_counter.handle, validate_dim_presence{})
|
||||
.first->second;
|
||||
|
||||
ROCPROFILER_CALL(rocprofiler_iterate_counter_dimensions(
|
||||
found_counter,
|
||||
[](rocprofiler_counter_id_t,
|
||||
const rocprofiler_record_dimension_info_t* dim_info,
|
||||
size_t num_dims,
|
||||
void* user_data) {
|
||||
validate_dim_presence* dim_presence =
|
||||
static_cast<validate_dim_presence*>(user_data);
|
||||
for(size_t i = 0; i < num_dims; i++)
|
||||
{
|
||||
dim_presence->maybe_forward(dim_info[i]);
|
||||
}
|
||||
return ROCPROFILER_STATUS_SUCCESS;
|
||||
},
|
||||
static_cast<void*>(&info_vector)),
|
||||
"Could not fetch dimension info");
|
||||
}
|
||||
if(cap.expected.empty())
|
||||
{
|
||||
@@ -247,11 +353,25 @@ tool_fini(void*)
|
||||
<< " (" << name << ")"
|
||||
<< " expected " << expected << " instances and got " << *actual_size << "\n";
|
||||
}
|
||||
else
|
||||
else if(!actual_size)
|
||||
{
|
||||
std::clog << "[ERROR] Counter ID: " << counter_id << " (" << name
|
||||
<< ") is missing from output\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Counter collected OK
|
||||
std::stringstream ss;
|
||||
std::vector<std::pair<rocprofiler_record_dimension_info_t, size_t>> stack;
|
||||
bool passed = cap.expected_data_dims.at(counter_id).check_seen(ss, stack);
|
||||
if(!PRINT_ONLY_FAILING || !passed)
|
||||
{
|
||||
std::clog << (passed ? "[OK] " : "[ERROR] ") << "Counter ID: " << counter_id << " ("
|
||||
<< name << ")"
|
||||
<< " Expected: " << expected << " Got: " << *actual_size << "\n";
|
||||
std::clog << ss.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user