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
|
||||
python $BIN_DIR/tblextr.py $csv_output $OUTPUT_LIST
|
||||
if [ "$?" = 1 ] ; then
|
||||
error "CSV generation error, profiling results '$RES_DIR'"
|
||||
if [ "$?" -eq 0 ] ; then
|
||||
echo "RPL: '$csv_output' is generated"
|
||||
fi
|
||||
echo "RPL: '$csv_output' is generated"
|
||||
fi
|
||||
|
||||
if [ "$DATA_PATH" = "$TMP_DIR" ] ; then
|
||||
|
||||
+4
-2
@@ -83,6 +83,7 @@ def parse_res(infile):
|
||||
# print results table method
|
||||
def print_tbl(outfile):
|
||||
global var_list
|
||||
if len(var_table) == 0: return 1
|
||||
|
||||
out = open(outfile, 'w')
|
||||
|
||||
@@ -107,6 +108,7 @@ def print_tbl(outfile):
|
||||
out.write("\n")
|
||||
|
||||
out.close()
|
||||
return 0
|
||||
#############################################################
|
||||
|
||||
# main
|
||||
@@ -116,6 +118,6 @@ outfile = sys.argv[1]
|
||||
infiles = sys.argv[2:]
|
||||
for f in infiles :
|
||||
parse_res(f)
|
||||
print_tbl(outfile)
|
||||
sys.exit(0)
|
||||
ret = print_tbl(outfile)
|
||||
sys.exit(ret)
|
||||
#############################################################
|
||||
|
||||
+15
-4
@@ -33,6 +33,7 @@ SOFTWARE.
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "core/group_set.h"
|
||||
#include "core/metrics.h"
|
||||
#include "core/profile.h"
|
||||
#include "core/queue.h"
|
||||
@@ -48,7 +49,7 @@ class Context;
|
||||
inline unsigned align_size(unsigned size, unsigned alignment) {
|
||||
return ((size + alignment - 1) & ~(alignment - 1));
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Block descriptor
|
||||
struct block_des_t {
|
||||
uint32_t id;
|
||||
@@ -68,7 +69,7 @@ struct block_status_t {
|
||||
uint32_t counter_index;
|
||||
uint32_t group_index;
|
||||
};
|
||||
|
||||
#endif
|
||||
// Metrics arguments
|
||||
template <class Map> class MetricArgs : public xml::args_cache_t {
|
||||
public:
|
||||
@@ -181,7 +182,12 @@ class Context {
|
||||
{
|
||||
metrics_ = MetricsDict::Create(agent_info);
|
||||
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();
|
||||
|
||||
if (handler != NULL) {
|
||||
@@ -209,7 +215,7 @@ class 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
|
||||
for (unsigned i = 0; i < info_count; ++i) {
|
||||
rocprofiler_feature_t* info = &info_array[i];
|
||||
@@ -272,9 +278,12 @@ class Context {
|
||||
block_status.max_counters = block_counters;
|
||||
}
|
||||
if (block_status.counter_index >= block_status.max_counters) {
|
||||
return false;
|
||||
|
||||
block_status.counter_index = 0;
|
||||
block_status.group_index += 1;
|
||||
}
|
||||
block_status.counter_index += 1;
|
||||
if (block_status.group_index >= set_.size()) {
|
||||
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 << ")");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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_
|
||||
Reference in New Issue
Block a user