metrics list auto groups on the limit exceed error
Change-Id: I851d8fb6779fd39098ccbfb0a95ec1fd183ab89f
This commit is contained in:
+2
-3
@@ -327,10 +327,9 @@ done
|
|||||||
|
|
||||||
if [ -n "$csv_output" ] ; then
|
if [ -n "$csv_output" ] ; then
|
||||||
python $BIN_DIR/tblextr.py $csv_output $OUTPUT_LIST
|
python $BIN_DIR/tblextr.py $csv_output $OUTPUT_LIST
|
||||||
if [ "$?" = 1 ] ; then
|
if [ "$?" -eq 0 ] ; then
|
||||||
error "CSV generation error, profiling results '$RES_DIR'"
|
echo "RPL: '$csv_output' is generated"
|
||||||
fi
|
fi
|
||||||
echo "RPL: '$csv_output' is generated"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$DATA_PATH" = "$TMP_DIR" ] ; then
|
if [ "$DATA_PATH" = "$TMP_DIR" ] ; then
|
||||||
|
|||||||
+4
-2
@@ -83,6 +83,7 @@ def parse_res(infile):
|
|||||||
# print results table method
|
# print results table method
|
||||||
def print_tbl(outfile):
|
def print_tbl(outfile):
|
||||||
global var_list
|
global var_list
|
||||||
|
if len(var_table) == 0: return 1
|
||||||
|
|
||||||
out = open(outfile, 'w')
|
out = open(outfile, 'w')
|
||||||
|
|
||||||
@@ -107,6 +108,7 @@ def print_tbl(outfile):
|
|||||||
out.write("\n")
|
out.write("\n")
|
||||||
|
|
||||||
out.close()
|
out.close()
|
||||||
|
return 0
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
# main
|
# main
|
||||||
@@ -116,6 +118,6 @@ outfile = sys.argv[1]
|
|||||||
infiles = sys.argv[2:]
|
infiles = sys.argv[2:]
|
||||||
for f in infiles :
|
for f in infiles :
|
||||||
parse_res(f)
|
parse_res(f)
|
||||||
print_tbl(outfile)
|
ret = print_tbl(outfile)
|
||||||
sys.exit(0)
|
sys.exit(ret)
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|||||||
+15
-4
@@ -33,6 +33,7 @@ SOFTWARE.
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "core/group_set.h"
|
||||||
#include "core/metrics.h"
|
#include "core/metrics.h"
|
||||||
#include "core/profile.h"
|
#include "core/profile.h"
|
||||||
#include "core/queue.h"
|
#include "core/queue.h"
|
||||||
@@ -48,7 +49,7 @@ class Context;
|
|||||||
inline unsigned align_size(unsigned size, unsigned alignment) {
|
inline unsigned align_size(unsigned size, unsigned alignment) {
|
||||||
return ((size + alignment - 1) & ~(alignment - 1));
|
return ((size + alignment - 1) & ~(alignment - 1));
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
// Block descriptor
|
// Block descriptor
|
||||||
struct block_des_t {
|
struct block_des_t {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
@@ -68,7 +69,7 @@ struct block_status_t {
|
|||||||
uint32_t counter_index;
|
uint32_t counter_index;
|
||||||
uint32_t group_index;
|
uint32_t group_index;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
// Metrics arguments
|
// Metrics arguments
|
||||||
template <class Map> class MetricArgs : public xml::args_cache_t {
|
template <class Map> class MetricArgs : public xml::args_cache_t {
|
||||||
public:
|
public:
|
||||||
@@ -181,7 +182,12 @@ class Context {
|
|||||||
{
|
{
|
||||||
metrics_ = MetricsDict::Create(agent_info);
|
metrics_ = MetricsDict::Create(agent_info);
|
||||||
if (metrics_ == NULL) EXC_RAISING(HSA_STATUS_ERROR, "MetricsDict create failed");
|
if (metrics_ == NULL) EXC_RAISING(HSA_STATUS_ERROR, "MetricsDict create failed");
|
||||||
Initialize(info, info_count);
|
if (Initialize(info, info_count) == false) {
|
||||||
|
fprintf(stdout, "\nInput metrics out of HW limit. Proposed metrics group set:\n"); fflush(stdout);
|
||||||
|
MetricsGroupSet(agent_info, info, info_count).Print(stdout);
|
||||||
|
fprintf(stdout, "\n"); fflush(stdout);
|
||||||
|
EXC_RAISING(HSA_STATUS_ERROR, "Metrics list exceeds HW limits");
|
||||||
|
}
|
||||||
Finalize();
|
Finalize();
|
||||||
|
|
||||||
if (handler != NULL) {
|
if (handler != NULL) {
|
||||||
@@ -209,7 +215,7 @@ class Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize rocprofiler context
|
// Initialize rocprofiler context
|
||||||
void Initialize(rocprofiler_feature_t* info_array, const uint32_t info_count) {
|
bool Initialize(rocprofiler_feature_t* info_array, const uint32_t info_count) {
|
||||||
// Register input features to not duplicate by features referencing
|
// Register input features to not duplicate by features referencing
|
||||||
for (unsigned i = 0; i < info_count; ++i) {
|
for (unsigned i = 0; i < info_count; ++i) {
|
||||||
rocprofiler_feature_t* info = &info_array[i];
|
rocprofiler_feature_t* info = &info_array[i];
|
||||||
@@ -272,9 +278,12 @@ class Context {
|
|||||||
block_status.max_counters = block_counters;
|
block_status.max_counters = block_counters;
|
||||||
}
|
}
|
||||||
if (block_status.counter_index >= block_status.max_counters) {
|
if (block_status.counter_index >= block_status.max_counters) {
|
||||||
|
return false;
|
||||||
|
|
||||||
block_status.counter_index = 0;
|
block_status.counter_index = 0;
|
||||||
block_status.group_index += 1;
|
block_status.group_index += 1;
|
||||||
}
|
}
|
||||||
|
block_status.counter_index += 1;
|
||||||
if (block_status.group_index >= set_.size()) {
|
if (block_status.group_index >= set_.size()) {
|
||||||
set_.push_back(Group(agent_info_, this, block_status.group_index));
|
set_.push_back(Group(agent_info_, this, block_status.group_index));
|
||||||
}
|
}
|
||||||
@@ -287,6 +296,8 @@ class Context {
|
|||||||
EXC_RAISING(HSA_STATUS_ERROR, "bad rocprofiler feature kind (" << kind << ")");
|
EXC_RAISING(HSA_STATUS_ERROR, "bad rocprofiler feature kind (" << kind << ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Finalize() {
|
void Finalize() {
|
||||||
|
|||||||
@@ -0,0 +1,246 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 ROCm Core Technology
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SRC_CORE_GROUP_SET_H_
|
||||||
|
#define SRC_CORE_GROUP_SET_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "core/metrics.h"
|
||||||
|
#include "util/exception.h"
|
||||||
|
#include "util/hsa_rsrc_factory.h"
|
||||||
|
|
||||||
|
namespace rocprofiler {
|
||||||
|
|
||||||
|
// Block descriptor
|
||||||
|
struct block_des_t {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t index;
|
||||||
|
};
|
||||||
|
|
||||||
|
// block_des_t less-then functor
|
||||||
|
struct lt_block_des {
|
||||||
|
bool operator()(const block_des_t& a1, const block_des_t& a2) const {
|
||||||
|
return (a1.id < a2.id) || ((a1.id == a2.id) && (a1.index < a2.index));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Block status
|
||||||
|
struct block_status_t {
|
||||||
|
uint32_t max_counters;
|
||||||
|
uint32_t counter_index;
|
||||||
|
uint32_t group_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Metrics set class
|
||||||
|
class MetricsGroup {
|
||||||
|
public:
|
||||||
|
// Info map type
|
||||||
|
typedef std::map<std::string, const Metric*> info_map_t;
|
||||||
|
// Blocks map type
|
||||||
|
typedef std::map<block_des_t, block_status_t, lt_block_des> blocks_map_t;
|
||||||
|
|
||||||
|
MetricsGroup(const util::AgentInfo* agent_info) :
|
||||||
|
agent_info_(agent_info)
|
||||||
|
{
|
||||||
|
metrics_ = MetricsDict::Create(agent_info);
|
||||||
|
if (metrics_ == NULL) EXC_RAISING(HSA_STATUS_ERROR, "MetricsDict create failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Print(FILE* file) const {
|
||||||
|
for (const Metric* metric : metrics_vec_) {
|
||||||
|
fprintf(file, " %s", metric->GetName().c_str()); fflush(stdout);
|
||||||
|
}
|
||||||
|
fprintf(file, "\n"); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Metric* GetMetric(const MetricsDict* metrics, const std::string& name) {
|
||||||
|
// Metric object
|
||||||
|
const Metric* metric = metrics->Get(name);
|
||||||
|
if (metric == NULL)
|
||||||
|
EXC_RAISING(HSA_STATUS_ERROR, "input metric '" << name << "' is not found");
|
||||||
|
return metric;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Metric* GetMetric(const MetricsDict* metrics, const rocprofiler_feature_t* info) {
|
||||||
|
// Metrics name
|
||||||
|
const char* name = info->name;
|
||||||
|
if (name == NULL) EXC_RAISING(HSA_STATUS_ERROR, "input feature name is NULL");
|
||||||
|
const Metric* metric = GetMetric(metrics, name);
|
||||||
|
#if 0
|
||||||
|
std::cout << " " << name << (metric->GetExpr() ? " = " + metric->GetExpr()->String() : " counter") << std::endl;
|
||||||
|
#endif
|
||||||
|
return metric;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add metric
|
||||||
|
bool AddMetric(const rocprofiler_feature_t* info) {
|
||||||
|
return AddMetric(GetMetric(metrics_, info));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AddMetric(const Metric* metric) {
|
||||||
|
// Blocks utilization delta
|
||||||
|
blocks_map_t blocks_delta;
|
||||||
|
|
||||||
|
// Process metrics counters
|
||||||
|
const counters_vec_t& counters_vec = metric->GetCounters();
|
||||||
|
if (counters_vec.empty())
|
||||||
|
EXC_RAISING(HSA_STATUS_ERROR, "bad metric '" << metric->GetName() << "' is empty");
|
||||||
|
|
||||||
|
for (const counter_t* counter : counters_vec) {
|
||||||
|
const event_t* event = &(counter->event);
|
||||||
|
|
||||||
|
// For metrics expressions checking that there is no the same counter in the input metrics
|
||||||
|
// and also that the counter wasn't registered already by another input metric expression
|
||||||
|
if (info_map_.find(counter->name) != info_map_.end()) continue;
|
||||||
|
|
||||||
|
const block_des_t block_des = {event->block_name, event->block_index};
|
||||||
|
auto ret = blocks_map_.insert({block_des, {}});
|
||||||
|
block_status_t& block_status = ret.first->second;
|
||||||
|
if (ret.second == true) {
|
||||||
|
profile_t query = {};
|
||||||
|
query.agent = agent_info_->dev_id;
|
||||||
|
query.type = HSA_VEN_AMD_AQLPROFILE_EVENT_TYPE_PMC;
|
||||||
|
query.events = event;
|
||||||
|
|
||||||
|
uint32_t block_counters;
|
||||||
|
hsa_status_t status = util::HsaRsrcFactory::Instance().AqlProfileApi()->hsa_ven_amd_aqlprofile_get_info(
|
||||||
|
&query, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_COUNTERS, &block_counters);
|
||||||
|
if (status != HSA_STATUS_SUCCESS) AQL_EXC_RAISING(status, "get block_counters info");
|
||||||
|
block_status.max_counters = block_counters;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = blocks_delta.insert({block_des, block_status});
|
||||||
|
block_status_t& delta_status = ret.first->second;
|
||||||
|
delta_status.counter_index += 1;
|
||||||
|
if (delta_status.counter_index > delta_status.max_counters) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register metric
|
||||||
|
metrics_vec_.push_back(metric);
|
||||||
|
info_map_[metric->GetName()] = metric;
|
||||||
|
for (const counter_t* counter : counters_vec) {
|
||||||
|
if (info_map_.find(counter->name) == info_map_.end()) info_map_[counter->name] = NewCounterInfo(counter->name);
|
||||||
|
}
|
||||||
|
for (const auto& entry : blocks_delta) {
|
||||||
|
blocks_map_[entry.first] = entry.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Metric* NewCounterInfo(const std::string& name) const {
|
||||||
|
return GetMetric(metrics_, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Agent info
|
||||||
|
const util::AgentInfo* const agent_info_;
|
||||||
|
// Metrics dictionary
|
||||||
|
const MetricsDict* metrics_;
|
||||||
|
// Info map
|
||||||
|
info_map_t info_map_;
|
||||||
|
// Blocks map
|
||||||
|
blocks_map_t blocks_map_;
|
||||||
|
// Metrics vector
|
||||||
|
std::vector<const Metric*> metrics_vec_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Metrics groups class
|
||||||
|
class MetricsGroupSet {
|
||||||
|
public:
|
||||||
|
MetricsGroupSet(const util::AgentInfo* agent_info, const rocprofiler_feature_t* info_array, const uint32_t info_count) :
|
||||||
|
agent_info_(agent_info)
|
||||||
|
{
|
||||||
|
metrics_ = MetricsDict::Create(agent_info);
|
||||||
|
if (metrics_ == NULL) EXC_RAISING(HSA_STATUS_ERROR, "MetricsDict create failed");
|
||||||
|
Initialize(info_array, info_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
~MetricsGroupSet() {
|
||||||
|
for (auto* group : groups_) delete group;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t GetSize() const { return groups_.size(); }
|
||||||
|
|
||||||
|
void Print(FILE* file) const {
|
||||||
|
uint32_t idx = 0;
|
||||||
|
for (const auto* group : groups_) {
|
||||||
|
++idx;
|
||||||
|
fprintf(stdout, " group%u:", idx); fflush(stdout);
|
||||||
|
group->Print(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Initialize(const rocprofiler_feature_t* info_array, const uint32_t info_count) {
|
||||||
|
std::multimap<uint32_t, const Metric*> input_metrics;
|
||||||
|
for (unsigned i = 0; i < info_count; ++i) {
|
||||||
|
const rocprofiler_feature_t* info = &info_array[i];
|
||||||
|
if (info->kind != ROCPROFILER_FEATURE_KIND_METRIC) continue;
|
||||||
|
const Metric* metric = MetricsGroup::GetMetric(metrics_, info);
|
||||||
|
const uint32_t counters_num = metric->GetCounters().size();
|
||||||
|
input_metrics.insert({counters_num, metric});
|
||||||
|
|
||||||
|
if (MetricsGroup(agent_info_).AddMetric(metric) == false) {
|
||||||
|
AQL_EXC_RAISING(HSA_STATUS_ERROR, "Metric '" << metric->GetName() << "' doesn't fit in one group");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t group_num = 0;
|
||||||
|
while (input_metrics.size() != 0) {
|
||||||
|
MetricsGroup* group = NextGroup();
|
||||||
|
++group_num;
|
||||||
|
auto it = input_metrics.end();
|
||||||
|
--it;
|
||||||
|
bool to_cont = true;
|
||||||
|
do {
|
||||||
|
const Metric* metric = it->second;
|
||||||
|
const bool to_erase = (group->AddMetric(metric) == true);
|
||||||
|
to_cont = (it != input_metrics.begin());
|
||||||
|
|
||||||
|
auto curr = it;
|
||||||
|
if (to_cont) --it;
|
||||||
|
if (to_erase) input_metrics.erase(curr);
|
||||||
|
} while (to_cont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MetricsGroup* NextGroup() {
|
||||||
|
groups_.push_back(new MetricsGroup(agent_info_));
|
||||||
|
return groups_.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Agent info
|
||||||
|
const util::AgentInfo* const agent_info_;
|
||||||
|
// Metrics dictionary
|
||||||
|
const MetricsDict* metrics_;
|
||||||
|
// Metrics group vector
|
||||||
|
std::vector<MetricsGroup*> groups_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace rocprofiler
|
||||||
|
|
||||||
|
#endif // SRC_CORE_GROUP_SET_H_
|
||||||
Fai riferimento in un nuovo problema
Block a user