a78753d392
* Updating to v3 API * General fixes * Extending dimension bits to 54 * Disabling agent profiling tests * Fixed unit test * Adding accumulate metric support for parsing counters (#609) * Adding accumulate metric support for parsing counters * Adding metric flag * Updating tests * source formatting (clang-format v11) (#610) Co-authored-by: Manjunath-Jakaraddi <21177428+Manjunath-Jakaraddi@users.noreply.github.com> * source formatting (clang-format v11) (#614) Co-authored-by: jrmadsen <6001865+jrmadsen@users.noreply.github.com> * Adding evaluate ast test * source formatting (clang-format v11) (#633) Co-authored-by: Manjunath-Jakaraddi <21177428+Manjunath-Jakaraddi@users.noreply.github.com> * Update scanner generated file * Adding flags to events for aqlprofile * Fix Mi200 failing test --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Manjunath-Jakaraddi <21177428+Manjunath-Jakaraddi@users.noreply.github.com> Co-authored-by: jrmadsen <6001865+jrmadsen@users.noreply.github.com> * Revert "Extending dimension bits to 54" This reverts commit 3cd6628452484044a93e129f27974f996a0e4c08. * Removing CU dimension * Fixing merge conflicts * Revert "Disabling agent profiling tests" This reverts commit 7e01518ed8c51fbb0c3b2575e1e0b8f9ddfa8237. * Fixing merge conflicts * Fix parser tests * Adding accumulate metric documentation * Update counter_collection_services.md * Update index.md * fix nested expression use * Update source/lib/rocprofiler-sdk/counters/evaluate_ast.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Doc update --------- Co-authored-by: Benjamin Welton <ben@amd.com> Co-authored-by: Manjunath P Jakaraddi <manjunath180397@gmail.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Manjunath-Jakaraddi <21177428+Manjunath-Jakaraddi@users.noreply.github.com> Co-authored-by: jrmadsen <6001865+jrmadsen@users.noreply.github.com> Co-authored-by: Manjunath-Jakaraddi <manjunath.jakaraddi@amd.com>
320 lines
10 KiB
C++
320 lines
10 KiB
C++
// MIT License
|
|
//
|
|
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
|
|
//
|
|
// 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.
|
|
|
|
#pragma once
|
|
|
|
#include "lib/common/utility.hpp"
|
|
#include "lib/rocprofiler-sdk/counters/id_decode.hpp"
|
|
|
|
#include <fmt/core.h>
|
|
#include <fmt/ranges.h>
|
|
|
|
#include <map>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
#include <utility>
|
|
#include <variant>
|
|
#include <vector>
|
|
|
|
namespace rocprofiler
|
|
{
|
|
namespace counters
|
|
{
|
|
enum NodeType
|
|
{
|
|
NONE = 0,
|
|
ADDITION_NODE,
|
|
DIVIDE_NODE,
|
|
MULTIPLY_NODE,
|
|
NUMBER_NODE,
|
|
RANGE_NODE,
|
|
REDUCE_NODE,
|
|
REFERENCE_NODE,
|
|
SELECT_NODE,
|
|
SUBTRACTION_NODE,
|
|
CONSTANT_NODE,
|
|
ACCUMULATE_NODE
|
|
};
|
|
|
|
enum class ACCUMULATE_OP_TYPE
|
|
{
|
|
NONE = 0,
|
|
LOW_RESOLUTION,
|
|
HIGH_RESOLUTION
|
|
};
|
|
|
|
struct LinkedList
|
|
{
|
|
std::string name;
|
|
int data{-1};
|
|
LinkedList* next{nullptr};
|
|
LinkedList(const char* v, LinkedList* next_node)
|
|
: name(std::string{CHECK_NOTNULL(v)})
|
|
, next(next_node)
|
|
{}
|
|
LinkedList(const char* v, int d, LinkedList* next_node)
|
|
: name(std::string{CHECK_NOTNULL(v)})
|
|
, data(d)
|
|
, next(next_node)
|
|
{}
|
|
};
|
|
|
|
struct RawAST
|
|
{
|
|
// Node type
|
|
NodeType type{NONE}; // Operation to perform on the counter set
|
|
std::string reduce_op{};
|
|
ACCUMULATE_OP_TYPE accumulate_op{ACCUMULATE_OP_TYPE::NONE};
|
|
|
|
// Stores either the name or digit dependening on whether this
|
|
// is a name or number
|
|
std::variant<std::monostate, std::string, int64_t> value{std::monostate{}};
|
|
|
|
// Counter set of ASTs needed to compute this counter.
|
|
// Operation is applied to all counters in this set.
|
|
std::vector<RawAST*> counter_set;
|
|
|
|
// Dimension set to remove dimensions (such as shader engine)
|
|
// from the result.
|
|
std::unordered_set<rocprofiler_profile_counter_instance_types> reduce_dimension_set;
|
|
|
|
// Dimension set to select certain dimensions from the result
|
|
std::unordered_map<rocprofiler_profile_counter_instance_types, int> select_dimension_set;
|
|
|
|
// Range restriction on this node
|
|
RawAST* range{nullptr};
|
|
|
|
~RawAST()
|
|
{
|
|
auto deleteVec = [](auto& vec) {
|
|
for(auto val : vec)
|
|
{
|
|
delete val;
|
|
}
|
|
};
|
|
|
|
deleteVec(counter_set);
|
|
delete range;
|
|
}
|
|
|
|
// Constructors for raw value types
|
|
RawAST(NodeType t, const char* v)
|
|
: type(t)
|
|
, value(std::string{CHECK_NOTNULL(v)})
|
|
{}
|
|
|
|
RawAST(NodeType t, int64_t v)
|
|
: type(t)
|
|
, value(v)
|
|
{}
|
|
|
|
static const auto& get_dim_map()
|
|
{
|
|
static const auto dim_map = []() {
|
|
std::map<std::string, rocprofiler_profile_counter_instance_types> out;
|
|
const auto& dims = dimension_map();
|
|
for(const auto& [id, name] : dims)
|
|
{
|
|
out.emplace(name, id);
|
|
}
|
|
return out;
|
|
}();
|
|
return dim_map;
|
|
}
|
|
|
|
// Reduce operation constructor. Counter is the counter AST
|
|
// to use for the reduce op, op is how to reduce (i.e. SUM,AVG,etc),
|
|
// dimensions contains the set of dimensions which we want to keep
|
|
// in the result. Dimensions not specified are all reduced according to op
|
|
RawAST(NodeType t, RawAST* counter, const char* op, LinkedList* dimensions)
|
|
: type(t)
|
|
, reduce_op(CHECK_NOTNULL(op))
|
|
, counter_set({counter})
|
|
{
|
|
CHECK_EQ(t, REDUCE_NODE);
|
|
if(dimensions)
|
|
{
|
|
while(dimensions)
|
|
{
|
|
const rocprofiler_profile_counter_instance_types* dim =
|
|
rocprofiler::common::get_val(get_dim_map(), std::string{dimensions->name});
|
|
if(!dim)
|
|
{
|
|
throw std::runtime_error(
|
|
fmt::format("Unknown Dimension - {}", dimensions->name));
|
|
}
|
|
|
|
reduce_dimension_set.insert(*dim);
|
|
LinkedList* current = dimensions;
|
|
dimensions = dimensions->next;
|
|
delete current;
|
|
}
|
|
}
|
|
}
|
|
|
|
RawAST(NodeType t, const char* v, const char* op)
|
|
: type(t)
|
|
, value(std::string{CHECK_NOTNULL(v)})
|
|
{
|
|
CHECK_NOTNULL(op);
|
|
static std::unordered_map<std::string_view, ACCUMULATE_OP_TYPE> map = {
|
|
{"NONE", ACCUMULATE_OP_TYPE::NONE},
|
|
{"LOW_RES", ACCUMULATE_OP_TYPE::LOW_RESOLUTION},
|
|
{"HIGH_RES", ACCUMULATE_OP_TYPE::HIGH_RESOLUTION},
|
|
};
|
|
accumulate_op = map.at(static_cast<std::string_view>(op));
|
|
CHECK_EQ(t, ACCUMULATE_NODE);
|
|
}
|
|
|
|
// Select operation constructor. Counter is the counter AST
|
|
// to use for the reduce op, refs is the reference set AST.
|
|
// dimensions contains the mapping for selecting dimensions
|
|
// (XCC=1,SE=2,...)
|
|
RawAST(NodeType t, RawAST* counter, LinkedList* dimensions)
|
|
: type(t)
|
|
, counter_set({counter})
|
|
{
|
|
if(dimensions)
|
|
{
|
|
LinkedList* ptr = dimensions;
|
|
while(ptr)
|
|
{
|
|
const rocprofiler_profile_counter_instance_types* dim =
|
|
rocprofiler::common::get_val(get_dim_map(), dimensions->name);
|
|
if(!dim)
|
|
{
|
|
throw std::runtime_error(
|
|
fmt::format("Unknown Dimension - {}", dimensions->name));
|
|
}
|
|
|
|
select_dimension_set.insert({*dim, ptr->data});
|
|
LinkedList* current = ptr;
|
|
ptr = ptr->next;
|
|
delete current;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ROCP_ERROR << "select_dimension_set creation failed.";
|
|
}
|
|
}
|
|
|
|
RawAST(NodeType t, std::vector<RawAST*> c)
|
|
: type(t)
|
|
, counter_set(std::move(c))
|
|
{}
|
|
};
|
|
} // namespace counters
|
|
} // namespace rocprofiler
|
|
|
|
namespace fmt
|
|
{
|
|
// fmt::format support for RawAST
|
|
template <>
|
|
struct formatter<rocprofiler::counters::RawAST>
|
|
{
|
|
template <typename ParseContext>
|
|
constexpr auto parse(ParseContext& ctx)
|
|
{
|
|
return ctx.begin();
|
|
}
|
|
|
|
template <typename Ctx>
|
|
auto format(rocprofiler::counters::RawAST const& ast, Ctx& ctx) const
|
|
{
|
|
static const std::map<rocprofiler::counters::NodeType, std::string> NodeTypeToString = {
|
|
{rocprofiler::counters::NONE, "NONE"},
|
|
{rocprofiler::counters::ADDITION_NODE, "ADDITION_NODE"},
|
|
{rocprofiler::counters::DIVIDE_NODE, "DIVIDE_NODE"},
|
|
{rocprofiler::counters::MULTIPLY_NODE, "MULTIPLY_NODE"},
|
|
{rocprofiler::counters::NUMBER_NODE, "NUMBER_NODE"},
|
|
{rocprofiler::counters::RANGE_NODE, "RANGE_NODE"},
|
|
{rocprofiler::counters::ACCUMULATE_NODE, "ACCUMULATE_NODE"},
|
|
{rocprofiler::counters::REDUCE_NODE, "REDUCE_NODE"},
|
|
{rocprofiler::counters::REFERENCE_NODE, "REFERENCE_NODE"},
|
|
{rocprofiler::counters::SELECT_NODE, "SELECT_NODE"},
|
|
{rocprofiler::counters::SUBTRACTION_NODE, "SUBTRACTION_NODE"},
|
|
};
|
|
|
|
static std::unordered_map<rocprofiler::counters::ACCUMULATE_OP_TYPE, std::string_view>
|
|
AccumulateTypeToString = {
|
|
{rocprofiler::counters::ACCUMULATE_OP_TYPE::NONE, "NONE"},
|
|
{rocprofiler::counters::ACCUMULATE_OP_TYPE::HIGH_RESOLUTION, "HIGH_RES"},
|
|
{rocprofiler::counters::ACCUMULATE_OP_TYPE::LOW_RESOLUTION, "LOW_RES"},
|
|
};
|
|
|
|
auto out =
|
|
fmt::format_to(ctx.out(),
|
|
"{{\"Type\":\"{}\", \"REDUCE_OP\":\"{}\", \"ACCUMULATE_OP\":\"{}\",",
|
|
NodeTypeToString.at(ast.type),
|
|
ast.reduce_op,
|
|
AccumulateTypeToString.at(ast.accumulate_op));
|
|
|
|
if(const auto* string_val = std::get_if<std::string>(&ast.value))
|
|
{
|
|
out = fmt::format_to(out, " \"Value\":\"{}\",", *string_val);
|
|
}
|
|
else if(const auto* int_val = std::get_if<int64_t>(&ast.value))
|
|
{
|
|
out = fmt::format_to(out, " \"Value\":{},", *int_val);
|
|
}
|
|
|
|
if(ast.range)
|
|
{
|
|
out = fmt::format_to(out, " \"Range\":{},", *ast.range);
|
|
}
|
|
|
|
out = fmt::format_to(out, " \"Counter_Set\":[");
|
|
for(const auto& ref : ast.counter_set)
|
|
{
|
|
out = fmt::format_to(
|
|
out, "{}{}", *CHECK_NOTNULL(ref), ref == ast.counter_set.back() ? "" : ",");
|
|
}
|
|
|
|
out = fmt::format_to(out, "], \"Reduce_Dimension_Set\":[");
|
|
size_t ReduceSetIndex = 0;
|
|
for(const auto& ref : ast.reduce_dimension_set)
|
|
{
|
|
out = fmt::format_to(out,
|
|
"\"{}\"{}",
|
|
static_cast<int>(ref),
|
|
++ReduceSetIndex == ast.reduce_dimension_set.size() ? "" : ",");
|
|
}
|
|
|
|
out = fmt::format_to(out, "], \"Select_Dimension_Set\":[");
|
|
size_t SelectSetIndex = 0;
|
|
for(const auto& [type, val] : ast.select_dimension_set)
|
|
{
|
|
out = fmt::format_to(out,
|
|
"\"{},{}\"{}",
|
|
static_cast<int>(type),
|
|
val,
|
|
++SelectSetIndex == ast.select_dimension_set.size() ? "" : ",");
|
|
}
|
|
|
|
return fmt::format_to(out, "]}}");
|
|
}
|
|
};
|
|
} // namespace fmt
|