SWDEV-465322: Adding support for Perfcounter SIMD Mask in ATT (#910)
* SWDEV-465322: Adding support for r Perfcounter SIMD Mask in ATT * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Benjamin Welton <bewelton@amd.com> * Adding unit tests * Adding counters check for gfx9 and SQ block only * Addressing review comments * changing the struct size * fixing header includes --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Benjamin Welton <bewelton@amd.com>
Αυτή η υποβολή περιλαμβάνεται σε:
υποβλήθηκε από
GitHub
γονέας
cfe3af9d7e
υποβολή
c49719649b
@@ -26,6 +26,7 @@
|
||||
#include <rocprofiler-sdk/defines.h>
|
||||
#include <rocprofiler-sdk/fwd.h>
|
||||
#include <rocprofiler-sdk/hsa.h>
|
||||
#include <cstdint>
|
||||
|
||||
ROCPROFILER_EXTERN_C_INIT
|
||||
|
||||
@@ -43,13 +44,23 @@ typedef enum
|
||||
ROCPROFILER_ATT_PARAMETER_BUFFER_SIZE, ///< Size of combined GPU buffer for ATT
|
||||
ROCPROFILER_ATT_PARAMETER_SIMD_SELECT, ///< Bitmask (GFX9) or ID (Navi) of SIMDs
|
||||
ROCPROFILER_ATT_PARAMETER_CODE_OBJECT_TRACE_ENABLE, ///< Enables Codeobj Markers IDs into ATT
|
||||
ROCPROFILER_ATT_PARAMETER_PERFCOUNTER, ///< Enables Perfcounter with simd mask (GFX9 only)
|
||||
ROCPROFILER_ATT_PARAMETER_PERFCOUNTERS_CTRL, ///< Defines the update period (GFX9 only)
|
||||
ROCPROFILER_ATT_PARAMETER_LAST
|
||||
} rocprofiler_att_parameter_type_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
rocprofiler_att_parameter_type_t type;
|
||||
uint64_t value;
|
||||
union
|
||||
{
|
||||
uint64_t value;
|
||||
struct
|
||||
{
|
||||
rocprofiler_counter_id_t counter_id;
|
||||
uint64_t simd_mask : 4;
|
||||
};
|
||||
};
|
||||
} rocprofiler_att_parameter_t;
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -216,20 +216,34 @@ ThreadTraceAQLPacketFactory::ThreadTraceAQLPacketFactory(const hsa::AgentCache&
|
||||
uint32_t shader_engine_mask = static_cast<uint32_t>(params.shader_engine_mask);
|
||||
uint32_t simd = static_cast<uint32_t>(params.simd_select);
|
||||
uint32_t buffer_size = static_cast<uint32_t>(params.buffer_size);
|
||||
uint32_t perf_ctrl = static_cast<uint32_t>(params.perfcounter_ctrl);
|
||||
|
||||
aql_params.clear();
|
||||
aql_params.push_back({HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_COMPUTE_UNIT_TARGET, cu});
|
||||
aql_params.push_back({HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_SE_MASK, shader_engine_mask});
|
||||
aql_params.push_back({HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_SIMD_SELECTION, simd});
|
||||
aql_params.push_back({HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_ATT_BUFFER_SIZE, buffer_size});
|
||||
aql_params.push_back({HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_PERFCOUNTER_CTRL, perf_ctrl});
|
||||
for(uint32_t perf_counter : params.perfcounters)
|
||||
{
|
||||
aql_params.push_back(
|
||||
{HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_PERFCOUNTER_NAME, perf_counter});
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<hsa_ven_amd_aqlprofile_parameter_t>&
|
||||
ThreadTraceAQLPacketFactory::get_aql_params()
|
||||
{
|
||||
return aql_params;
|
||||
}
|
||||
|
||||
std::unique_ptr<hsa::TraceControlAQLPacket>
|
||||
ThreadTraceAQLPacketFactory::construct_packet()
|
||||
{
|
||||
uint32_t num_params = static_cast<uint32_t>(aql_params.size());
|
||||
auto profile = aqlprofile_att_profile_t{tracepool.gpu_agent, aql_params.data(), num_params};
|
||||
auto packet = std::make_unique<hsa::TraceControlAQLPacket>(this->tracepool, profile);
|
||||
uint32_t num_params = static_cast<uint32_t>(get_aql_params().size());
|
||||
auto profile =
|
||||
aqlprofile_att_profile_t{tracepool.gpu_agent, get_aql_params().data(), num_params};
|
||||
auto packet = std::make_unique<hsa::TraceControlAQLPacket>(this->tracepool, profile);
|
||||
packet->clear();
|
||||
return packet;
|
||||
}
|
||||
|
||||
@@ -91,10 +91,11 @@ public:
|
||||
const thread_trace_parameter_pack& params,
|
||||
const CoreApiTable& coreapi,
|
||||
const AmdExtTable& ext);
|
||||
std::unique_ptr<hsa::TraceControlAQLPacket> construct_packet();
|
||||
std::unique_ptr<hsa::CodeobjMarkerAQLPacket> construct_load_marker_packet(uint64_t id,
|
||||
uint64_t addr,
|
||||
uint64_t size);
|
||||
const std::vector<hsa_ven_amd_aqlprofile_parameter_t>& get_aql_params();
|
||||
std::unique_ptr<hsa::TraceControlAQLPacket> construct_packet();
|
||||
std::unique_ptr<hsa::CodeobjMarkerAQLPacket> construct_load_marker_packet(uint64_t id,
|
||||
uint64_t addr,
|
||||
uint64_t size);
|
||||
std::unique_ptr<hsa::CodeobjMarkerAQLPacket> construct_unload_marker_packet(uint64_t id);
|
||||
|
||||
private:
|
||||
|
||||
@@ -195,6 +195,26 @@ getMetricIdMap()
|
||||
return id_map;
|
||||
}
|
||||
|
||||
const MetricIdMap*
|
||||
getPerfCountersIdMap()
|
||||
{
|
||||
// Only GFX9 counters in SQ Block are supported
|
||||
static MetricIdMap*& att_perf_counters_map =
|
||||
common::static_object<MetricIdMap>::construct([]() {
|
||||
MetricIdMap map;
|
||||
std::string agent_prefix{"gfx9"};
|
||||
auto is_gfx9 = [&](auto& agent_name) {
|
||||
return (agent_name.find(agent_prefix) != std::string::npos);
|
||||
};
|
||||
for(const auto& [agent_name, metrics] : *CHECK_NOTNULL(getMetricMap()))
|
||||
if(is_gfx9(agent_name))
|
||||
for(const auto& metric : metrics)
|
||||
if(metric.block() == "SQ") map.emplace(metric.id(), metric);
|
||||
return map;
|
||||
}());
|
||||
return att_perf_counters_map;
|
||||
}
|
||||
|
||||
const MetricMap*
|
||||
getMetricMap()
|
||||
{
|
||||
|
||||
@@ -114,6 +114,13 @@ getMetricsForAgent(const std::string&);
|
||||
const MetricIdMap*
|
||||
getMetricIdMap();
|
||||
|
||||
/**
|
||||
* Get the metrics for perfcounters options in thread trace
|
||||
* applicable only for GFX9 agents and SQ block counters
|
||||
*/
|
||||
const MetricIdMap*
|
||||
getPerfCountersIdMap();
|
||||
|
||||
/**
|
||||
* Checks if a metric is valid for a given agent
|
||||
**/
|
||||
|
||||
@@ -55,11 +55,13 @@ struct thread_trace_parameter_pack
|
||||
uint64_t buffer_size = DEFAULT_BUFFER_SIZE;
|
||||
|
||||
// GFX9 Only
|
||||
std::vector<std::string> perfcounters;
|
||||
std::vector<uint32_t> perfcounters;
|
||||
|
||||
static constexpr size_t DEFAULT_SIMD = 0x7;
|
||||
static constexpr size_t DEFAULT_SE_MASK = 0x21;
|
||||
static constexpr size_t DEFAULT_BUFFER_SIZE = 0x8000000;
|
||||
static constexpr size_t DEFAULT_SIMD = 0x7;
|
||||
static constexpr size_t DEFAULT_PERFCOUNTER_SIMD_MASK = 0xF;
|
||||
static constexpr size_t DEFAULT_SE_MASK = 0x21;
|
||||
static constexpr size_t DEFAULT_BUFFER_SIZE = 0x8000000;
|
||||
static constexpr size_t PERFCOUNTER_SIMD_MASK_SHIFT = 28;
|
||||
};
|
||||
|
||||
namespace hsa
|
||||
|
||||
@@ -20,12 +20,28 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include <rocprofiler-sdk/rocprofiler.h>
|
||||
#include <cstdint>
|
||||
|
||||
#include "lib/rocprofiler-sdk/aql/helpers.hpp"
|
||||
#include "lib/rocprofiler-sdk/context/context.hpp"
|
||||
#include "lib/rocprofiler-sdk/hsa/agent_cache.hpp"
|
||||
#include "lib/rocprofiler-sdk/registration.hpp"
|
||||
#include "rocprofiler-sdk/amd_detail/thread_trace.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
uint32_t
|
||||
get_mask(const rocprofiler::counters::Metric* metric, uint64_t simds_selected)
|
||||
{
|
||||
uint32_t mask = std::atoi(metric->event().c_str());
|
||||
if(simds_selected == 0)
|
||||
simds_selected = rocprofiler::thread_trace_parameter_pack::DEFAULT_PERFCOUNTER_SIMD_MASK;
|
||||
mask |= simds_selected << rocprofiler::thread_trace_parameter_pack::PERFCOUNTER_SIMD_MASK_SHIFT;
|
||||
return mask;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
rocprofiler_status_t ROCPROFILER_API
|
||||
@@ -51,6 +67,7 @@ rocprofiler_configure_thread_trace_service(rocprofiler_context_id_t
|
||||
param_pack.callback_userdata = callback_userdata;
|
||||
bool bEnableCodeobj = false;
|
||||
|
||||
const auto& id_map = *CHECK_NOTNULL(rocprofiler::counters::getPerfCountersIdMap());
|
||||
for(size_t p = 0; p < num_parameters; p++)
|
||||
{
|
||||
const rocprofiler_att_parameter_t& param = parameters[p];
|
||||
@@ -68,10 +85,16 @@ rocprofiler_configure_thread_trace_service(rocprofiler_context_id_t
|
||||
case ROCPROFILER_ATT_PARAMETER_CODE_OBJECT_TRACE_ENABLE:
|
||||
bEnableCodeobj = param.value != 0;
|
||||
break;
|
||||
case ROCPROFILER_ATT_PARAMETER_PERFCOUNTER:
|
||||
if(const auto* metric_ptr =
|
||||
rocprofiler::common::get_val(id_map, param.counter_id.handle))
|
||||
param_pack.perfcounters.push_back(get_mask(metric_ptr, param.simd_mask));
|
||||
break;
|
||||
case ROCPROFILER_ATT_PARAMETER_PERFCOUNTERS_CTRL:
|
||||
param_pack.perfcounter_ctrl = param.value;
|
||||
break;
|
||||
case ROCPROFILER_ATT_PARAMETER_LAST: return ROCPROFILER_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
// for(int i = 0; i < parameters.perfcounter_num; i++)
|
||||
// thread_tracer->perfcounters.emplace_back(parameters.perfcounter[i]);
|
||||
}
|
||||
|
||||
ctx->thread_trace = std::make_shared<rocprofiler::GlobalThreadTracer>(param_pack);
|
||||
|
||||
@@ -20,15 +20,28 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
#include "lib/rocprofiler-sdk/agent.hpp"
|
||||
#include "lib/rocprofiler-sdk/aql/helpers.hpp"
|
||||
#include "lib/rocprofiler-sdk/aql/packet_construct.hpp"
|
||||
#include "lib/rocprofiler-sdk/context/context.hpp"
|
||||
#include "lib/rocprofiler-sdk/counters/metrics.hpp"
|
||||
#include "lib/rocprofiler-sdk/counters/tests/hsa_tables.hpp"
|
||||
#include "lib/rocprofiler-sdk/hsa/agent_cache.hpp"
|
||||
#include "lib/rocprofiler-sdk/hsa/queue.hpp"
|
||||
#include "lib/rocprofiler-sdk/hsa/queue_controller.hpp"
|
||||
#include "lib/rocprofiler-sdk/registration.hpp"
|
||||
#include "lib/rocprofiler-sdk/thread_trace/att_core.hpp"
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <hsa/hsa.h>
|
||||
#include <hsa/hsa_api_trace.h>
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
@@ -127,10 +140,10 @@ TEST(thread_trace, configure_test)
|
||||
ROCPROFILER_CALL(rocprofiler_create_context(&ctx), "context creation failed");
|
||||
|
||||
std::vector<rocprofiler_att_parameter_t> params;
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_TARGET_CU, 1});
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_SHADER_ENGINE_MASK, 0xF});
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_BUFFER_SIZE, 0x1000000});
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_SIMD_SELECT, 0xF});
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_TARGET_CU, {1}});
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_SHADER_ENGINE_MASK, {0xF}});
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_BUFFER_SIZE, {0x1000000}});
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_SIMD_SELECT, {0xF}});
|
||||
|
||||
rocprofiler_configure_thread_trace_service(
|
||||
ctx,
|
||||
@@ -147,5 +160,88 @@ TEST(thread_trace, configure_test)
|
||||
ASSERT_EQ(hsa_init(), HSA_STATUS_SUCCESS);
|
||||
ROCPROFILER_CALL(rocprofiler_start_context(ctx), "context start failed");
|
||||
ROCPROFILER_CALL(rocprofiler_stop_context(ctx), "context stop failed");
|
||||
context::pop_client(1);
|
||||
hsa_shut_down();
|
||||
}
|
||||
|
||||
TEST(thread_trace, perfcounters_configure_test)
|
||||
{
|
||||
test_init();
|
||||
|
||||
registration::init_logging();
|
||||
registration::set_init_status(-1);
|
||||
context::push_client(1);
|
||||
rocprofiler_context_id_t ctx;
|
||||
ROCPROFILER_CALL(rocprofiler_create_context(&ctx), "context creation failed");
|
||||
|
||||
// Only GFX9 SQ Block counters are supported
|
||||
std::vector<std::pair<std::string, uint64_t>> perf_counters = {
|
||||
{"SQ_WAVES", 0x1}, {"SQ_WAVES", 0x2}, {"SQ_WAVES", 0x2}, {"GRBM_COUNT", 0x3}};
|
||||
std::set<uint32_t> expected;
|
||||
std::vector<rocprofiler_att_parameter_t> params;
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_PERFCOUNTERS_CTRL, {1}});
|
||||
auto metrics = rocprofiler::counters::getMetricsForAgent("gfx90a");
|
||||
|
||||
for(auto& [counter_name, simd_mask] : perf_counters)
|
||||
for(auto& metric : metrics)
|
||||
if(metric.name() == counter_name)
|
||||
{
|
||||
params.push_back({ROCPROFILER_ATT_PARAMETER_PERFCOUNTER,
|
||||
{.counter_id = {metric.id()}, .simd_mask = simd_mask}});
|
||||
expected.insert(std::atoi(metric.event().c_str()) | (simd_mask << 28));
|
||||
}
|
||||
|
||||
rocprofiler_configure_thread_trace_service(
|
||||
ctx,
|
||||
params.data(),
|
||||
params.size(),
|
||||
[](rocprofiler_queue_id_t,
|
||||
const rocprofiler_agent_t*,
|
||||
rocprofiler_correlation_id_t,
|
||||
rocprofiler_kernel_id_t,
|
||||
void*) { return ROCPROFILER_ATT_CONTROL_NONE; },
|
||||
[](int64_t, void*, size_t, void*) {},
|
||||
nullptr);
|
||||
|
||||
auto* context = rocprofiler::context::get_mutable_registered_context(ctx);
|
||||
thread_trace_parameter_pack _params = context->thread_trace->params;
|
||||
|
||||
ASSERT_EQ(_params.perfcounter_ctrl, 1);
|
||||
ASSERT_EQ(_params.perfcounters.size(), 3);
|
||||
for(uint32_t param : _params.perfcounters)
|
||||
EXPECT_TRUE(expected.find(param) != expected.end())
|
||||
<< "valid AQLprofile mask not generated for perfcounters";
|
||||
context::pop_client(1);
|
||||
hsa_shut_down();
|
||||
}
|
||||
|
||||
TEST(thread_trace, perfcounters_aql_options_test)
|
||||
{
|
||||
hsa_init();
|
||||
test_init();
|
||||
|
||||
registration::init_logging();
|
||||
registration::set_init_status(-1);
|
||||
context::push_client(1);
|
||||
|
||||
const std::uint8_t sqtt_default_num_options = 5;
|
||||
auto agents = hsa::get_queue_controller()->get_supported_agents();
|
||||
|
||||
thread_trace_parameter_pack _params = {};
|
||||
auto metrics = rocprofiler::counters::getMetricsForAgent("gfx90a");
|
||||
std::vector<std::pair<std::string, uint64_t>> perf_counters = {
|
||||
{"SQ_WAVES", 0x1}, {"SQ_WAVES", 0x2}, {"GRBM_COUNT", 0x3}};
|
||||
for(auto& [counter_name, simd_mask] : perf_counters)
|
||||
for(auto& metric : metrics)
|
||||
if(metric.name() == counter_name)
|
||||
_params.perfcounters.push_back(std::atoi(metric.event().c_str()) |
|
||||
(simd_mask << 28));
|
||||
_params.perfcounter_ctrl = 2;
|
||||
auto new_tracer = std::make_unique<AgentThreadTracer>(
|
||||
_params, begin(agents)->second, get_api_table(), get_ext_table());
|
||||
|
||||
ASSERT_EQ(new_tracer->factory->get_aql_params().size(),
|
||||
sqtt_default_num_options + perf_counters.size());
|
||||
context::pop_client(1);
|
||||
hsa_shut_down();
|
||||
}
|
||||
Αναφορά σε νέο ζήτημα
Block a user