API update, rev 1.2.3

[ROCm/rocprofiler commit: ac529c96e1]
Tento commit je obsažen v:
Evgeny
2017-11-27 16:51:03 -06:00
rodič 586b8773e9
revize 9824189d37
8 změnil soubory, kde provedl 193 přidání a 187 odebrání
+59 -63
Zobrazit soubor
@@ -79,48 +79,48 @@ extern "C" {
// Profiling feature type
typedef enum {
ROCPROFILER_TYPE_METRIC = 0,
ROCPROFILER_TYPE_TRACE = 1
} rocprofiler_type_t;
ROCPROFILER_FEATURE_KIND_METRIC = 0,
ROCPROFILER_FEATURE_KIND_TRACE = 1
} rocprofiler_feature_kind_t;
// Profiling feture parameter
typedef hsa_ven_amd_aqlprofile_parameter_t rocprofiler_parameter_t;
// Profiling data kind
typedef enum {
ROCPROFILER_UNINIT = 0,
ROCPROFILER_INT32 = 1,
ROCPROFILER_INT64 = 2,
ROCPROFILER_FLOAT = 3,
ROCPROFILER_DOUBLE = 4,
ROCPROFILER_BYTES = 5
} rocprofiler_metric_kind_t;
ROCPROFILER_DATA_KIND_UNINIT = 0,
ROCPROFILER_DATA_KIND_INT32 = 1,
ROCPROFILER_DATA_KIND_INT64 = 2,
ROCPROFILER_DATA_KIND_FLOAT = 3,
ROCPROFILER_DATA_KIND_DOUBLE = 4,
ROCPROFILER_DATA_KIND_BYTES = 5
} rocprofiler_data_kind_t;
// Profiling data type
typedef struct {
rocprofiler_metric_kind_t kind; // result kind
rocprofiler_data_kind_t kind; // result kind
union {
uint32_t result_int32; // 32bit integer result
uint64_t result_int64; // 64bit integer result
float result_float; // float single-precision result
double result_double; // float double-precision result
uint32_t result_int32; // 32bit integer result
uint64_t result_int64; // 64bit integer result
float result_float; // float single-precision result
double result_double; // float double-precision result
struct {
void* ptr;
uint32_t size;
uint32_t instance_count;
bool copy;
} result_bytes; // data by ptr and byte size
} result_bytes; // data by ptr and byte size
};
} rocprofiler_data_t;
// Profiling feature info
typedef struct {
rocprofiler_type_t type; // feature type
const char* name; // [in] feature name
rocprofiler_feature_kind_t kind; // feature kind
const char* name; // feature name
const rocprofiler_parameter_t* parameters; // feature parameters array
uint32_t parameter_count; // feature parameters count
rocprofiler_data_t data; // [out] profiling data
} rocprofiler_info_t;
rocprofiler_data_t data; // profiling data
} rocprofiler_feature_t;
////////////////////////////////////////////////////////////////////////////////
// Profiling context
@@ -132,17 +132,17 @@ typedef void rocprofiler_t;
// Profiling group object
typedef struct {
unsigned index; // group index
rocprofiler_info_t** info; // profiling info array
uint32_t info_count; // profiling info count
rocprofiler_t* context; // context object
unsigned index; // group index
rocprofiler_feature_t** features; // profiling info array
uint32_t feature_count; // profiling info count
rocprofiler_t* context; // context object
} rocprofiler_group_t;
// Profiling mode mask
typedef enum {
ROCPROFILER_MODE_STANDALONE = 1,
ROCPROFILER_MODE_CREATEQUEUE = 2,
ROCPROFILER_MODE_SINGLEGROUP = 4
ROCPROFILER_MODE_STANDALONE = 1, // standalone mode when ROC profiler supports a queue
ROCPROFILER_MODE_CREATEQUEUE = 2, // ROC profiler creates queue in standalone mode
ROCPROFILER_MODE_SINGLEGROUP = 4 // only one group is allowed, failed otherwise
} rocprofiler_mode_t;
// Profiling handler, calling on profiling completion
@@ -159,21 +159,21 @@ typedef struct {
// Create new profiling context
hsa_status_t rocprofiler_open(
unsigned gpu_index, // GPU index
rocprofiler_info_t* info, // [in] profiling info array
uint32_t info_count, // profiling info count
rocprofiler_t** context, // [out] context object
uint32_t mode, // profiling mode mask
rocprofiler_properties_t* properties); // profiling properties
hsa_agent_t agent, // GPU handle
rocprofiler_feature_t* features, // [in] profiling info array
uint32_t feature_count, // profiling info count
rocprofiler_t** context, // [out] context object
uint32_t mode, // profiling mode mask
rocprofiler_properties_t* properties); // profiling properties
// Delete profiling info
hsa_status_t rocprofiler_close(
rocprofiler_t* context); // [in] profiling context
rocprofiler_t* context); // [in] profiling context
// Context reset before reusing
hsa_status_t rocprofiler_reset(
rocprofiler_t* context, // [in] profiling context
uint32_t group_index); // group index
rocprofiler_t* context, // [in] profiling context
uint32_t group_index); // group index
////////////////////////////////////////////////////////////////////////////////
// Runtime API observer
@@ -182,33 +182,24 @@ hsa_status_t rocprofiler_reset(
// Profiling callback data
typedef struct {
hsa_agent_t agent;
uint64_t kernel_object;
uint64_t queue_index;
uint32_t gpu_index;
} rocprofiler_callback_data_t;
// Profiling callback type
typedef hsa_status_t (*rocprofiler_callback_t)(
const rocprofiler_callback_data_t* callback_data, // [in] callback data union, data depends on
// the callback API id
void* user_data, // [in/out] user data passed to the callback
rocprofiler_group_t** group); // [out] profiling group
// Provided standard profiling callback
static inline hsa_status_t rocprofiler_set_dispatch_callback(
const rocprofiler_callback_data_t* callback_data,
void* user_data,
rocprofiler_group_t** group) {
*group = reinterpret_cast<rocprofiler_group_t*>(user_data);
return HSA_STATUS_SUCCESS;
}
const rocprofiler_callback_data_t* callback_data, // [in] callback data union, data depends on
// the callback API id
void* user_data, // [in/out] user data passed to the callback
rocprofiler_group_t* group); // [out] profiling group
// Set/remove kernel dispatch observer
hsa_status_t rocprofiler_set_dispatch_observer(
rocprofiler_callback_t callback, // observer callback
void* data); // [in/out] passed callback data
hsa_status_t rocprofiler_set_dispatch_callback(
rocprofiler_callback_t callback, // observer callback
void* data); // [in/out] passed callback data
hsa_status_t rocprofiler_remove_dispatch_observer();
hsa_status_t rocprofiler_remove_dispatch_callback();
////////////////////////////////////////////////////////////////////////////////
// Start/stop profiling
@@ -231,22 +222,27 @@ hsa_status_t rocprofiler_get_data(
rocprofiler_t* context, // [in/out] profiling context
uint32_t group_index = 0); // group index
// Get profiling groups
hsa_status_t rocprofiler_get_groups(
rocprofiler_t* context, // [in] profiling context
rocprofiler_group_t** groups, // [out] profiling groups
// Get profiling groups count
hsa_status_t rocprofiler_group_count(
const rocprofiler_t* context, // [in] profiling context
uint32_t* group_count); // [out] profiling groups count
// 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
rocprofiler_group_t* group); // [out] profiling group
// Start profiling
hsa_status_t rocprofiler_start_group(
hsa_status_t rocprofiler_group_start(
rocprofiler_group_t* group); // [in/out] profiling group
// Stop profiling
hsa_status_t rocprofiler_stop_group(
hsa_status_t rocprofiler_group_stop(
rocprofiler_group_t* group); // [in/out] profiling group
// Get profiling data
hsa_status_t rocprofiler_get_group_data(
hsa_status_t rocprofiler_group_get_data(
rocprofiler_group_t* group); // [in/out] profiling group
// Get metrics data
@@ -258,9 +254,9 @@ 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_t* context, // [in] profiling context
rocprofiler_trace_data_callback_t callback, // [in] callback to iterate the output data
void* data); // [in/out] callback data
void* data); // [in/out] callback data
////////////////////////////////////////////////////////////////////////////////
// Returning the error string method
+32 -32
Zobrazit soubor
@@ -47,14 +47,14 @@ class MetricArgs : public xml::args_cache_t {
public:
MetricArgs(const Map& map) : map_(map) {}
bool Lookup(const std::string& name, uint64_t& result) const {
rocprofiler_info_t* info = NULL;
rocprofiler_feature_t* info = NULL;
auto it = map_.find(name);
if (it == map_.end()) EXC_RAISING(HSA_STATUS_ERROR, "var '" << name << "' is not found");
info = it->second;
if (info) {
result = info->data.result_int64;
if (info->data.kind == ROCPROFILER_UNINIT) EXC_RAISING(HSA_STATUS_ERROR, "var '" << name << "' is uninitialized");
if (info->data.kind != ROCPROFILER_INT64) EXC_RAISING(HSA_STATUS_ERROR, "var '" << name << "' is of incompatible type, not INT64");
if (info->data.kind == ROCPROFILER_DATA_KIND_UNINIT) EXC_RAISING(HSA_STATUS_ERROR, "var '" << name << "' is uninitialized");
if (info->data.kind != ROCPROFILER_DATA_KIND_INT64) EXC_RAISING(HSA_STATUS_ERROR, "var '" << name << "' is of incompatible type, not INT64");
} else EXC_RAISING(HSA_STATUS_ERROR, "var '" << name << "' info is NULL");
return (info != NULL);
}
@@ -75,17 +75,17 @@ class Group {
{}
void Insert(const profile_info_t& info) {
const rocprofiler_type_t type = info.rinfo->type;
const rocprofiler_feature_kind_t kind = info.rinfo->kind;
info_vector_.push_back(info.rinfo);
switch (type) {
case ROCPROFILER_TYPE_METRIC:
switch (kind) {
case ROCPROFILER_FEATURE_KIND_METRIC:
pmc_profile_.Insert(info);
break;
case ROCPROFILER_TYPE_TRACE:
case ROCPROFILER_FEATURE_KIND_TRACE:
sqtt_profile_.Insert(info);
break;
default:
EXC_RAISING(HSA_STATUS_ERROR, "bad rocprofiler type (" << type << ")");
EXC_RAISING(HSA_STATUS_ERROR, "bad rocprofiler feature kind (" << kind << ")");
}
}
@@ -141,9 +141,9 @@ class Group {
class Context {
public:
typedef std::mutex mutex_t;
typedef std::map<std::string, rocprofiler_info_t*> info_map_t;
typedef std::map<std::string, rocprofiler_feature_t*> info_map_t;
Context(const util::AgentInfo* agent_info, Queue* queue, rocprofiler_info_t* info, const uint32_t info_count, rocprofiler_handler_t handler, void* handler_arg) :
Context(const util::AgentInfo* agent_info, Queue* queue, rocprofiler_feature_t* info, const uint32_t info_count, rocprofiler_handler_t handler, void* handler_arg) :
agent_(agent_info->dev_id),
agent_info_(agent_info),
queue_(queue),
@@ -177,22 +177,22 @@ class Context {
~Context() {
for (const auto& v : info_map_) {
const std::string& name = v.first;
const rocprofiler_info_t* info = v.second;
if ((info->type == ROCPROFILER_TYPE_METRIC) && (metrics_map_.find(name) == metrics_map_.end())) {
const rocprofiler_feature_t* info = v.second;
if ((info->kind == ROCPROFILER_FEATURE_KIND_METRIC) && (metrics_map_.find(name) == metrics_map_.end())) {
delete info;
}
}
}
// Initialize rocprofiler context
void Initialize(rocprofiler_info_t* info_array, const uint32_t info_count) {
void Initialize(rocprofiler_feature_t* info_array, const uint32_t info_count) {
// Set input features filter, to not duplicate referenced features
// Set iput features data as uninitialized
info_map_t input_map;
for (unsigned i = 0; i < info_count; ++i) {
rocprofiler_info_t* info = &info_array[i];
rocprofiler_feature_t* info = &info_array[i];
input_map[info->name] = info;
info->data.kind = ROCPROFILER_UNINIT;
info->data.kind = ROCPROFILER_DATA_KIND_UNINIT;
}
// Adding zero group, always present
@@ -200,13 +200,13 @@ class Context {
// Processing input features
for (unsigned i = 0; i < info_count; ++i) {
rocprofiler_info_t* info = &info_array[i];
info->data.kind = ROCPROFILER_UNINIT;
rocprofiler_feature_t* info = &info_array[i];
info->data.kind = ROCPROFILER_DATA_KIND_UNINIT;
info_map_[info->name] = info;
const rocprofiler_type_t type = info->type;
const rocprofiler_feature_kind_t kind = info->kind;
const char* name = info->name;
if (type == ROCPROFILER_TYPE_METRIC) { // Processing metrics features
if (kind == ROCPROFILER_FEATURE_KIND_METRIC) { // Processing metrics features
const Metric* metric = metrics_->Get(name);
if (metric == NULL) EXC_RAISING(HSA_STATUS_ERROR, "input metric '" << name << "' is not found");
auto ret = metrics_map_.insert({name, metric});
@@ -254,10 +254,10 @@ class Context {
const uint32_t group_index = block_status.group_index;
set_[group_index].Insert(profile_info_t{event, NULL, 0, info});
}
} else if (type == ROCPROFILER_TYPE_TRACE) { // Processing traces features
} else if (kind == ROCPROFILER_FEATURE_KIND_TRACE) { // Processing traces features
set_[0].Insert(profile_info_t{NULL, info->parameters, info->parameter_count, info});
} else {
EXC_RAISING(HSA_STATUS_ERROR, "bad rocprofiler type (" << type << ")");
EXC_RAISING(HSA_STATUS_ERROR, "bad rocprofiler feature kind (" << kind << ")");
}
}
}
@@ -278,8 +278,8 @@ class Context {
rocprofiler_group_t GetGroupInfo(const uint32_t& index) {
rocprofiler::info_vector_t& info_vector = set_[index].GetInfoVector();
rocprofiler_group_t group = {};
group.info_count = info_vector.size();
group.info = &info_vector[0];
group.feature_count = info_vector.size();
group.features = &info_vector[0];
group.context = reinterpret_cast<rocprofiler_t*>(this);
group.index = index;
return group;
@@ -336,9 +336,9 @@ class Context {
if (expr) {
auto it = info_map_.find(name);
if (it == info_map_.end()) EXC_RAISING(HSA_STATUS_ERROR, "metric '" << name << "', rocprofiler info is not found");
rocprofiler_info_t* info = it->second;
rocprofiler_feature_t* info = it->second;
info->data.result_int64 = expr->Eval(args);
info->data.kind = ROCPROFILER_INT64;
info->data.kind = ROCPROFILER_DATA_KIND_INT64;
}
}
}
@@ -389,11 +389,11 @@ class Context {
callback_data->index = index;
if (index < info_vector.size()) {
rocprofiler_info_t* rinfo = info_vector[index];
rocprofiler_feature_t* rinfo = info_vector[index];
if (ainfo_type == HSA_VEN_AMD_AQLPROFILE_INFO_PMC_DATA) {
if (ainfo_data->sample_id == 0) rinfo->data.result_int64 = 0;
rinfo->data.result_int64 += ainfo_data->pmc_data.result;
rinfo->data.kind = ROCPROFILER_INT64;
rinfo->data.kind = ROCPROFILER_DATA_KIND_INT64;
} else if (ainfo_type == HSA_VEN_AMD_AQLPROFILE_INFO_SQTT_DATA) {
if (rinfo->data.result_bytes.copy) {
char* result_bytes_ptr = reinterpret_cast<char*>(rinfo->data.result_bytes.ptr);
@@ -408,14 +408,14 @@ class Context {
hsa_status_t status = hsa_memory_copy(dest, src, size);
if (status == HSA_STATUS_SUCCESS) {
*header = size;
rinfo->data.kind = ROCPROFILER_BYTES;
rinfo->data.kind = ROCPROFILER_DATA_KIND_BYTES;
rinfo->data.result_bytes.instance_count = sample_id + 1;
callback_data->ptr = dest + align_size(size, sizeof(uint64_t));
}
} else status = HSA_STATUS_ERROR;
} else {
if (sample_id == 0) {
rinfo->data.kind = ROCPROFILER_BYTES;
rinfo->data.kind = ROCPROFILER_DATA_KIND_BYTES;
rinfo->data.result_bytes.ptr = ainfo_data->sqtt_data.ptr;
rinfo->data.result_bytes.instance_count = UINT32_MAX;
}
@@ -427,9 +427,9 @@ class Context {
return status;
}
rocprofiler_info_t* NewCounterInfo(const counter_t* counter) {
rocprofiler_info_t* info = new rocprofiler_info_t{};
info->type = ROCPROFILER_TYPE_METRIC;
rocprofiler_feature_t* NewCounterInfo(const counter_t* counter) {
rocprofiler_feature_t* info = new rocprofiler_feature_t{};
info->kind = ROCPROFILER_FEATURE_KIND_METRIC;
info->name = counter->name.c_str();
return info;
}
+6 -6
Zobrazit soubor
@@ -88,14 +88,14 @@ class InterceptQueue {
const packet_t* packet = &packets_arr[j];
if ((GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH) && (on_dispatch_cb_ != NULL)) {
rocprofiler_group_t* group = NULL;
rocprofiler_group_t group = {};
const hsa_kernel_dispatch_packet_t* dispatch_packet = reinterpret_cast<const hsa_kernel_dispatch_packet_t*>(packet);
rocprofiler_callback_data_t data = {dispatch_packet->kernel_object, user_que_idx, obj->agent_info_->dev_index};
rocprofiler_callback_data_t data = {obj->agent_info_->dev_id, dispatch_packet->kernel_object, user_que_idx};
hsa_status_t status = on_dispatch_cb_(&data, on_dispatch_cb_data_, &group);
if ((status == HSA_STATUS_SUCCESS) && (group != NULL)) {
Context* context = reinterpret_cast<Context*>(group->context);
const pkt_vector_t& start_vector = context->StartPackets(group->index);
const pkt_vector_t& stop_vector = context->StopPackets(group->index);
if (status == HSA_STATUS_SUCCESS) {
Context* context = reinterpret_cast<Context*>(group.context);
const pkt_vector_t& start_vector = context->StartPackets(group.index);
const pkt_vector_t& stop_vector = context->StopPackets(group.index);
pkt_vector_t packets = start_vector;
packets.insert(packets.end(), *packet);
+2 -2
Zobrazit soubor
@@ -15,9 +15,9 @@ struct profile_info_t {
const event_t* event;
const parameter_t* parameters;
uint32_t parameter_count;
rocprofiler_info_t* rinfo;
rocprofiler_feature_t* rinfo;
};
typedef std::vector<rocprofiler_info_t*> info_vector_t;
typedef std::vector<rocprofiler_feature_t*> info_vector_t;
typedef std::vector<packet_t> pkt_vector_t;
struct profile_tuple_t {
const profile_t* profile;
+20 -16
Zobrazit soubor
@@ -99,8 +99,8 @@ PUBLIC_API hsa_status_t rocprofiler_error_string(const char** str) {
// Create new profiling context
PUBLIC_API hsa_status_t rocprofiler_open(
unsigned agent_id,
rocprofiler_info_t* info,
hsa_agent_t agent,
rocprofiler_feature_t* info,
uint32_t info_count,
rocprofiler_t** handle,
uint32_t mode,
@@ -108,9 +108,9 @@ PUBLIC_API hsa_status_t rocprofiler_open(
{
API_METHOD_PREFIX
rocprofiler::util::HsaRsrcFactory* hsa_rsrc = &rocprofiler::util::HsaRsrcFactory::Instance();
const rocprofiler::util::AgentInfo* agent_info;
if (!hsa_rsrc->GetGpuAgentInfo(agent_id, &agent_info)) {
EXC_RAISING(HSA_STATUS_ERROR, "agent[" << agent_id << "] is not found");
const rocprofiler::util::AgentInfo* agent_info = hsa_rsrc->GetAgentInfo(agent);
if (agent_info == NULL) {
EXC_RAISING(HSA_STATUS_ERROR, "agent is not found");
}
rocprofiler::Queue* queue = NULL;
@@ -127,7 +127,7 @@ PUBLIC_API hsa_status_t rocprofiler_open(
}
}
*handle = (void*) new rocprofiler::Context(agent_info, queue, info, info_count, properties->handler, properties->handler_arg);
*handle = new rocprofiler::Context(agent_info, queue, info, info_count, properties->handler, properties->handler_arg);
API_METHOD_SUFFIX
}
@@ -149,15 +149,19 @@ PUBLIC_API hsa_status_t rocprofiler_reset(rocprofiler_t* handle, uint32_t group_
API_METHOD_SUFFIX
}
// Get profiling groups
PUBLIC_API hsa_status_t rocprofiler_get_groups(rocprofiler_t* handle, rocprofiler_group_t** group_array, uint32_t* group_count) {
// Get profiling group count
PUBLIC_API hsa_status_t rocprofiler_group_count(const rocprofiler_t* handle, uint32_t* group_count) {
API_METHOD_PREFIX
const rocprofiler::Context* context = reinterpret_cast<const rocprofiler::Context*>(handle);
*group_count = context->GetGroupCount();
API_METHOD_SUFFIX
}
// Get profiling group for a given group index
PUBLIC_API hsa_status_t rocprofiler_get_group(rocprofiler_t* handle, uint32_t group_index, rocprofiler_group_t* group) {
API_METHOD_PREFIX
rocprofiler::Context* context = reinterpret_cast<rocprofiler::Context*>(handle);
const uint32_t count = context->GetGroupCount();
rocprofiler_group_t* groups = (rocprofiler_group_t*) calloc(count, sizeof(rocprofiler_group_t));
for (unsigned i = 0; i < count; ++i) groups[i] = context->GetGroupInfo(i);
*group_array = groups;
*group_count = count;
*group = context->GetGroupInfo(group_index);
API_METHOD_SUFFIX
}
@@ -200,7 +204,7 @@ PUBLIC_API hsa_status_t rocprofiler_group_stop(rocprofiler_group_t* group) {
}
// Get profiling data
PUBLIC_API hsa_status_t rocprofiler_get_group_data(rocprofiler_group_t* group) {
PUBLIC_API hsa_status_t rocprofiler_group_get_data(rocprofiler_group_t* group) {
API_METHOD_PREFIX
rocprofiler::Context* context = reinterpret_cast<rocprofiler::Context*>(group->context);
context->GetData(group->index);
@@ -216,14 +220,14 @@ PUBLIC_API hsa_status_t rocprofiler_get_metrics(const rocprofiler_t* handle) {
}
// Set kernel dispatch observer
PUBLIC_API hsa_status_t rocprofiler_set_dispatch_observer(rocprofiler_callback_t callback, void* data) {
PUBLIC_API hsa_status_t rocprofiler_set_dispatch_callback(rocprofiler_callback_t callback, void* data) {
API_METHOD_PREFIX
rocprofiler::InterceptQueue::SetDispatchCB(callback, data);
API_METHOD_SUFFIX
}
// Set kernel dispatch observer
PUBLIC_API hsa_status_t rocprofiler_remove_dispatch_observer() {
PUBLIC_API hsa_status_t rocprofiler_remove_dispatch_callback() {
API_METHOD_PREFIX
rocprofiler::InterceptQueue::UnsetDispatchCB();
API_METHOD_SUFFIX
+1 -1
Zobrazit soubor
@@ -86,7 +86,7 @@ int main(int argc, char** argv) {
for (rocprofiler_info_t* p = info; p < info + info_count; ++p) {
std::cout << (p - info) << ": " << p->name;
switch (p->data.kind) {
case ROCPROFILER_INT64:
case ROCPROFILER_DATA_KIND_INT64:
std::cout << std::dec << " result64 (" << p->data.result64 << ")" << std::endl;
break;
case ROCPROFILER_BYTES: {
+1 -1
Zobrazit soubor
@@ -56,7 +56,7 @@ void print_info(FILE* file, const rocprofiler_info_t* info, const unsigned info_
const rocprofiler_info_t* p = &info[i];
fprintf(file, " %s ", p->name);
switch (p->data.kind) {
case ROCPROFILER_INT64:
case ROCPROFILER_DATA_KIND_INT64:
fprintf(file, "(%lu)\n", p->data.result64);
break;
case ROCPROFILER_BYTES: {
+72 -66
Zobrazit soubor
@@ -24,8 +24,8 @@
// Disoatch callback data type
struct dispatch_data_t {
rocprofiler_info_t* info;
unsigned info_count;
rocprofiler_feature_t* features;
unsigned feature_count;
unsigned group_index;
FILE* file_handle;
};
@@ -33,9 +33,9 @@ struct dispatch_data_t {
// Context stored entry type
struct context_entry_t {
uint32_t index;
rocprofiler_group_t* group;
rocprofiler_info_t* info;
unsigned info_count;
rocprofiler_group_t group;
rocprofiler_feature_t* features;
unsigned feature_count;
rocprofiler_callback_data_t data;
FILE* file_handle;
};
@@ -49,9 +49,7 @@ context_entry_t* context_array = NULL;
// Number of stored contexts
unsigned context_array_count = 0;
// Profiling results output file name
const char* result_file_name = NULL;
// SQTT output file base name
const char* sqtt_file_name = "thread_trace";
const char* result_prefix = NULL;
// Check returned HSA API status
void check_status(hsa_status_t status) {
@@ -91,19 +89,21 @@ context_entry_t* alloc_context_entry() {
// Dump trace data to file
void dump_sqtt_trace(const uint32_t chunk, const void* data, const uint32_t& size) {
// Opening SQTT file
std::ostringstream oss;
oss << sqtt_file_name << ".se" << chunk << ".out";
FILE* file = fopen(oss.str().c_str(), "w");
if (file == NULL) {
perror("result file fopen");
exit(1);
}
// Write the buffer in terms of shorts (16 bits)
const unsigned short* ptr = reinterpret_cast<const unsigned short*>(data);
for (uint32_t i = 0; i < (size / sizeof(short)); ++i) {
fprintf(file, "%04x\n", ptr[i]);
if (result_prefix != NULL) {
// Opening SQTT file
std::ostringstream oss;
oss << result_prefix << "/thread_trace.se" << chunk << ".out";
FILE* file = fopen(oss.str().c_str(), "w");
if (file == NULL) {
perror("result file fopen");
exit(1);
}
// Write the buffer in terms of shorts (16 bits)
const unsigned short* ptr = reinterpret_cast<const unsigned short*>(data);
for (uint32_t i = 0; i < (size / sizeof(short)); ++i) {
fprintf(file, "%04x\n", ptr[i]);
}
}
}
@@ -127,18 +127,18 @@ hsa_status_t trace_data_cb(
unsigned align_size(unsigned size, unsigned alignment) { return ((size + alignment - 1) & ~(alignment - 1)); }
// Output profiling results for input features
void output_results(FILE* file, const rocprofiler_info_t* info, const unsigned info_count, rocprofiler_t* context, const char* str) {
void output_results(FILE* file, const rocprofiler_feature_t* features, const unsigned feature_count, rocprofiler_t* context, const char* str) {
if (str) fprintf(file, "%s:\n", str);
for (unsigned i= 0; i < info_count; ++i) {
const rocprofiler_info_t* p = &info[i];
for (unsigned i= 0; i < feature_count; ++i) {
const rocprofiler_feature_t* p = &features[i];
fprintf(file, " %s ", p->name);
switch (p->data.kind) {
// Output metrics results
case ROCPROFILER_INT64:
case ROCPROFILER_DATA_KIND_INT64:
fprintf(file, "(%lu)\n", p->data.result_int64);
break;
// Output trace results
case ROCPROFILER_BYTES: {
case ROCPROFILER_DATA_KIND_BYTES: {
if (p->data.result_bytes.copy) {
uint64_t size = 0;
@@ -173,36 +173,36 @@ void output_results(FILE* file, const rocprofiler_info_t* info, const unsigned i
// Output group intermeadate profiling results, created internally for complex metrics
void output_group(FILE* file, const rocprofiler_group_t* group, const char* str) {
if (str) fprintf(file, "%s:\n", str);
for (unsigned i= 0; i < group->info_count; ++i) {
output_results(file, group->info[i], 1, group->context, NULL);
for (unsigned i= 0; i < group->feature_count; ++i) {
output_results(file, group->features[i], 1, group->context, NULL);
}
}
// Dump stored context profiling output data
void dump_context(context_entry_t* entry) {
hsa_status_t status = HSA_STATUS_ERROR;
rocprofiler_group_t* group = entry->group;
const rocprofiler_feature_t* features = entry->features;
if (group) {
if (features) {
rocprofiler_group_t group = entry->group;
uint32_t index = entry->index;
const rocprofiler_info_t* info = entry->info;
const unsigned info_count = entry->info_count;
const unsigned feature_count = entry->feature_count;
FILE* file_handle = entry->file_handle;
fprintf(file_handle, "Dispatch[%u], kernel_object(0x%lx):\n", index, entry->data.kernel_object);
status = rocprofiler_get_group_data(group);
status = rocprofiler_group_get_data(&group);
check_status(status);
//output_group(file, group, "Group[0] data");
status = rocprofiler_get_metrics(group->context);
status = rocprofiler_get_metrics(group.context);
check_status(status);
output_results(file_handle, info, info_count, group->context, NULL);
output_results(file_handle, features, feature_count, group.context, NULL);
// Finishing cleanup
// Deleting profiling context will delete all allocated resources
rocprofiler_close(group->context);
entry->group = NULL;
rocprofiler_close(group.context);
entry->features = NULL;
}
}
@@ -243,7 +243,7 @@ void handler(rocprofiler_group_t group, void* arg) {
hsa_status_t dispatch_callback(
const rocprofiler_callback_data_t* callback_data,
void* user_data,
rocprofiler_group_t** group) {
rocprofiler_group_t* group) {
// HSA status
hsa_status_t status = HSA_STATUS_ERROR;
// Passed tool data
@@ -254,23 +254,27 @@ hsa_status_t dispatch_callback(
context_entry_t* entry = alloc_context_entry();
// context properties
rocprofiler_properties_t properties{};
properties.handler = (result_file_name != NULL) ? handler : NULL;
properties.handler = (result_prefix != NULL) ? handler : NULL;
properties.handler_arg = (void*)entry;
// Open profiling context
status = rocprofiler_open(0, tool_data->info, tool_data->info_count, &context, 0/*ROCPROFILER_MODE_SINGLEGROUP*/, &properties);
status = rocprofiler_open(callback_data->agent, tool_data->features, tool_data->feature_count, &context, 0/*ROCPROFILER_MODE_SINGLEGROUP*/, &properties);
check_status(status);
rocprofiler_group_t* groups = NULL;
// Check that we have only one profiling group
uint32_t group_count = 0;
status = rocprofiler_get_groups(context, &groups, &group_count);
status = rocprofiler_group_count(context, &group_count);
check_status(status);
assert(group_count == 1);
// Get group[0]
const uint32_t group_index = 0;
status = rocprofiler_get_group(context, group_index, group);
check_status(status);
*group = &groups[0];
// Fill profiling context entry
entry->group = *group;
entry->info = tool_data->info;
entry->info_count = tool_data->info_count;
entry->features = tool_data->features;
entry->feature_count = tool_data->feature_count;
entry->data = *callback_data;
entry->file_handle = tool_data->file_handle;
@@ -287,10 +291,12 @@ CONSTRUCTOR_API void constructor() {
parameters_dict["HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_TOKEN_MASK2"] = HSA_VEN_AMD_AQLPROFILE_PARAMETER_NAME_TOKEN_MASK2;
// Set output file
result_file_name = getenv("ROCP_OUTPUT");
result_prefix = getenv("ROCP_OUTPUT_DIR");
FILE* file_handle = NULL;
if (result_file_name != NULL) {
file_handle = fopen(result_file_name, "w");
if (result_prefix != NULL) {
std::ostringstream oss;
oss << result_prefix << "/results.txt";
file_handle = fopen(oss.str().c_str(), "w");
if (file_handle == NULL) {
perror("result file fopen");
exit(1);
@@ -324,17 +330,17 @@ CONSTRUCTOR_API void constructor() {
// Getting traces
auto traces_list = xml->GetNodes("top.trace");
const unsigned info_count = metrics_vec.size() + traces_list.size();
rocprofiler_info_t* info= new rocprofiler_info_t[info_count];
memset(info, 0, info_count * sizeof(rocprofiler_info_t));
const unsigned feature_count = metrics_vec.size() + traces_list.size();
rocprofiler_feature_t* features= new rocprofiler_feature_t[feature_count];
memset(features, 0, feature_count * sizeof(rocprofiler_feature_t));
printf(" %d metrics\n", (int) metrics_vec.size());
for (unsigned i = 0; i < metrics_vec.size(); ++i) {
const std::string& name = metrics_vec[i];
printf("%s%s", (i == 0) ? " " : ", ", name.c_str());
info[i] = {};
info[i].type = ROCPROFILER_TYPE_METRIC;
info[i].name = strdup(name.c_str());
features[i] = {};
features[i].kind = ROCPROFILER_FEATURE_KIND_METRIC;
features[i].name = strdup(name.c_str());
}
if (metrics_vec.size()) printf("\n");
@@ -349,10 +355,10 @@ CONSTRUCTOR_API void constructor() {
const std::string& name = entry->opts["name"];
const bool to_copy_data = (entry->opts["copy"] == "true");
printf(" %s (\n", name.c_str());
info[index] = {};
info[index].type = ROCPROFILER_TYPE_TRACE;
info[index].name = strdup(name.c_str());
info[index].data.result_bytes.copy = to_copy_data;
features[index] = {};
features[index].kind = ROCPROFILER_FEATURE_KIND_TRACE;
features[index].name = strdup(name.c_str());
features[index].data.result_bytes.copy = to_copy_data;
for (auto* params : params_list) {
const unsigned parameter_count = params->opts.size();
@@ -372,31 +378,31 @@ CONSTRUCTOR_API void constructor() {
++p_index;
}
info[index].parameters = parameters;
info[index].parameter_count = parameter_count;
features[index].parameters = parameters;
features[index].parameter_count = parameter_count;
}
printf(" )\n");
++index;
}
// Adding dispatch observer
if (info_count) {
if (feature_count) {
dispatch_data_t* dispatch_data = new dispatch_data_t{};
dispatch_data->info = info;
dispatch_data->info_count = info_count;
dispatch_data->features = features;
dispatch_data->feature_count = feature_count;
dispatch_data->group_index = 0;
dispatch_data->file_handle = file_handle;
rocprofiler_set_dispatch_observer(dispatch_callback, dispatch_data);
rocprofiler_set_dispatch_callback(dispatch_callback, dispatch_data);
}
}
// Tool destructor
DESTRUCTOR_API void destructor() {
printf("\nROCPRofiler: %u contexts collected", context_array_count);
if (result_file_name == NULL) {
if (result_prefix == NULL) {
printf("\n");
} else {
printf(", dumping to %s\n", result_file_name);
printf(", dumping to %s\n", result_prefix);
}
// Dump profiling output data which hasn't yet dumped by completi onhandler
dump_context_array();