* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#ifndef CATLASS_TUNER_METRIC_H
#define CATLASS_TUNER_METRIC_H
#include <map>
#include <unordered_map>
#include <vector>
#include <sstream>
#include <iomanip>
#include "catlass/library/operation.h"
namespace Catlass {
enum class ClassicMetric : uint32_t {
CASE_ID = 0,
TASK_DURATION,
DEVICE_ID,
OPERATION,
DESCRIPTION,
L0,
L1,
SWIZZLE,
M,
N,
K,
A,
B,
C,
END
};
struct ClassicMetricStr {
static constexpr std::string_view CASE_ID = "case_id";
static constexpr std::string_view TASK_DURATION = "task_duration(us)";
static constexpr std::string_view DEVICE_ID = "device_id";
static constexpr std::string_view OPERATION = "operation";
static constexpr std::string_view DESCRIPTION = "description";
static constexpr std::string_view L0 = "l0_tile_shape";
static constexpr std::string_view L1 = "l1_tile_shape";
static constexpr std::string_view SWIZZLE = "swizzle";
static constexpr std::string_view M = "m";
static constexpr std::string_view N = "n";
static constexpr std::string_view K = "k";
static constexpr std::string_view A = "A";
static constexpr std::string_view B = "B";
static constexpr std::string_view C = "C";
};
class Metric {
public:
explicit Metric();
[[nodiscard]] std::string ToString() const;
[[nodiscard]] std::string ToTerminalString() const;
void SaveOperator(Library::Operation *op);
void SetField(const std::string &key, const std::string &value);
template<ClassicMetric key, typename T>
void SetField(const T &value)
{
if constexpr (IsString<T>::value) {
classic_[static_cast<uint32_t>(key)] = value;
if constexpr (key == ClassicMetric::DESCRIPTION) {
std::string_view sv = classic_[static_cast<uint32_t>(key)];
auto r = sv.rfind('_');
if (r == std::string::npos || r == 0) {
return;
}
classic_[static_cast<uint32_t>(ClassicMetric::SWIZZLE)] = sv.substr(r + 1);
auto l = sv.rfind('_', r - 1);
if (l == std::string::npos || l == 0) {
return;
}
classic_[static_cast<uint32_t>(ClassicMetric::L0)] = sv.substr(l + 1, r - l - 1);
r = l - 1;
l = sv.rfind('_', r);
if (l == std::string::npos) {
return;
}
classic_[static_cast<uint32_t>(ClassicMetric::L1)] = sv.substr(l + 1, r - l);
}
} else {
if constexpr (key == ClassicMetric::TASK_DURATION) {
taskDuration_ = value;
std::stringstream ss;
constexpr size_t PREC = 3;
ss << std::fixed << std::setprecision(PREC) << value;
classic_[static_cast<uint32_t>(key)] = ss.str();
} else {
classic_[static_cast<uint32_t>(key)] = std::to_string(value);
}
}
}
inline const std::string& Field(ClassicMetric key) const
{
return classic_[static_cast<uint32_t>(key)];
}
inline const std::string& Field(const std::string &key) const
{
static std::string empty{};
if (auto it = CLASSIC_STR_TO_E.find(key); it != CLASSIC_STR_TO_E.end()) {
return Field(it->second);
} else if (auto itf = fields_.find(key); itf != fields_.end()) {
return itf->second;
}
return empty;
}
inline const auto& Fields() const { return fields_; }
inline double GetTaskDuration() const { return taskDuration_; }
const static std::unordered_map<std::string, ClassicMetric> CLASSIC_STR_TO_E;
private:
template <typename T>
struct IsString : std::false_type {};
double taskDuration_{0};
std::map<std::string, std::string> fields_;
std::vector<std::string> classic_ = std::vector<std::string>(static_cast<uint32_t>(ClassicMetric::END));
};
template <>
struct Metric::IsString<std::string> : std::true_type {};
template <>
struct Metric::IsString<std::string_view> : std::true_type {};
template <typename T>
struct Metric::IsString<T*> : std::is_same<std::remove_const_t<T>, char> {};
template <typename T>
struct Metric::IsString<T* const> : std::is_same<std::remove_const_t<T>, char> {};
template <size_t N>
struct Metric::IsString<char[N]> : std::true_type {};
template <size_t N>
struct Metric::IsString<const char[N]> : std::true_type {};
}
#endif