Files
rocm-systems/source/lib/rocprofiler-sdk/counters/parser/raw_ast.hpp
T
Giovanni Lenzi Baraldi a78753d392 Accumulation metrics support and update counter collection API to aqlprofile_v2 (#915)
* 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>
2024-07-01 21:56:41 -03:00

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