* -------------------------------------------------------------------------
* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* 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 FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*/
#include "CounterEventHelper.h"
#include "StringUtil.h"
#include "TableDefs.h"
namespace Dic::Module::Timeline {
using namespace Dic::Protocol;
const std::map<std::string, std::string> CounterEventHelper::displayNameToValueName = {{"AI Core Freq", "freq"},
{"Read", "read"}, {"Write", "write"}, {"L2 Buffer Bw Level", "l2BufferBwLevel"}, {"Mata Bw Level", "mataBwLevel"},
{"DDR", "ddr"}, {"HBM", "hbm"}, {"Bandwidth", "bandwidth"}, {"Hit Rate", "hitRate"}, {"Throughput", "throughput"},
{"Freq", "freq"}, {"Usage", "usage"}, {"Total Cycle", "totalCycle"}};
void CounterEventHelper::RegisterHostMap() {
hostCounterEventMap.insert({PROCESS_TYPE::CPU_USAGE,
{"CPU Usage", PROCESS_TYPE_ES.at(PROCESS_TYPE::CPU_USAGE), "usage", "CPU {cpuId}", "Usage(%)"}});
hostCounterEventMap.insert({PROCESS_TYPE::HOST_DISK_USAGE,
{"Disk Usage", PROCESS_TYPE_ES.at(PROCESS_TYPE::HOST_DISK_USAGE), "usage", "Disk Usage", "Usage(%)"}});
hostCounterEventMap.insert({PROCESS_TYPE::HOST_NETWORK_USAGE,
{"Network Usage", PROCESS_TYPE_ES.at(PROCESS_TYPE::HOST_NETWORK_USAGE), "usage", "Network Usage", "Usage(%)"}});
hostCounterEventMap.insert({PROCESS_TYPE::HOST_MEM_USAGE,
{"Memory Usage", PROCESS_TYPE_ES.at(PROCESS_TYPE::HOST_MEM_USAGE), "usage", "Memory Usage", "Usage(%)"}});
}
void CounterEventHelper::RegisterDeviceMap() {
RegisterDeviceAICoreFreqMap();
RegisterDeviceAccPMUMap();
RegisterDeviceDDRMap();
RegisterDeviceStarsSocMap();
RegisterDeviceNPUMEMMap();
RegisterDeviceHBMMap();
RegisterDeviceLLCMap();
RegisterDeviceSamplePMUMap();
RegisterDeviceNICMap();
RegisterDevicePCIeMap();
RegisterDeviceHCCSMap();
RegisterDeviceQOSMap();
}
void CounterEventHelper::RegisterDeviceAICoreFreqMap() {
deviceCounterEventMap.insert(
{PROCESS_TYPE::AI_CORE, {"AI Core Freq", "AICORE_FREQ", "freq", "AI Core Freq", "Mhz"}});
}
void CounterEventHelper::RegisterDeviceAccPMUMap() {
deviceCounterEventMap.insert(
{PROCESS_TYPE::ACC_PMU, {"ACC PMU", "ACC_PMU", "readBwLevel", "Accelerator {accId}/readBwLevel", "Level"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::ACC_PMU, {"ACC PMU", "ACC_PMU", "writeBwLevel", "Accelerator {accId}/writeBwLevel", "Level"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::ACC_PMU, {"ACC PMU", "ACC_PMU", "readOstLevel", "Accelerator {accId}/readOstLevel", "Level"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::ACC_PMU, {"ACC PMU", "ACC_PMU", "writeOstLevel", "Accelerator {accId}/writeOstLevel", "Level"}});
}
void CounterEventHelper::RegisterDeviceDDRMap() {
deviceCounterEventMap.insert({PROCESS_TYPE::DDR, {"DDR", "DDR", "read", "Read", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::DDR, {"DDR", "DDR", "write", "Write", "Bandwidth(B/s)"}});
}
void CounterEventHelper::RegisterDeviceStarsSocMap() {
deviceCounterEventMap.insert({PROCESS_TYPE::STARS_SOC,
{"Stars Soc", "SOC_BANDWIDTH_LEVEL", "l2BufferBwLevel", "L2 Buffer Bw Level", "Level"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::STARS_SOC, {"Stars Soc", "SOC_BANDWIDTH_LEVEL", "mataBwLevel", "Mata Bw Level", "Level"}});
}
void CounterEventHelper::RegisterDeviceNPUMEMMap() {
deviceCounterEventMap.insert({PROCESS_TYPE::NPU_MEM, {"NPU MEM", "NPU_MEM", "ddr", "{type:s}/DDR", "B"}});
deviceCounterEventMap.insert({PROCESS_TYPE::NPU_MEM, {"NPU MEM", "NPU_MEM", "hbm", "{type:s}/HBM", "B"}});
}
void CounterEventHelper::RegisterDeviceHBMMap() {
deviceCounterEventMap.insert(
{PROCESS_TYPE::HBM, {"HBM", "HBM", "bandwidth", "HBM {hbmId} {type:s}/Bandwidth", "Bandwidth(B/s)"}});
}
void CounterEventHelper::RegisterDeviceLLCMap() {
deviceCounterEventMap.insert(
{PROCESS_TYPE::LLC, {"LLC", "LLC", "hitRate", "LLC {llcId} {mode:s}/Hit Rate", "Hit Rate(%)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::LLC, {"LLC", "LLC", "throughput", "LLC {llcId} {mode:s}/Throughput", "Throughput(B/s)"}});
}
void CounterEventHelper::RegisterDeviceSamplePMUMap() {
deviceCounterEventMap.insert({PROCESS_TYPE::SAMPLE_PMU,
{"SAMPLE PMU TIMELINE", "SAMPLE_PMU_TIMELINE", "freq", "{coreType:s} Core {coreId}/Freq", "Mhz"}});
deviceCounterEventMap.insert({PROCESS_TYPE::SAMPLE_PMU,
{"SAMPLE PMU TIMELINE", "SAMPLE_PMU_TIMELINE", "usage", "{coreType:s} Core {coreId}/Usage", "Usage(%)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::SAMPLE_PMU,
{"SAMPLE PMU TIMELINE", "SAMPLE_PMU_TIMELINE", "totalCycle", "{coreType:s} Core {coreId}/Total Cycle",
"Cycle"}});
}
void CounterEventHelper::RegisterDeviceNICMap() {
deviceCounterEventMap.insert({PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "roceTxPkt", "NIC/roceTxPkt", "Pkt"}});
deviceCounterEventMap.insert({PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "roceRxPkt", "NIC/roceRxPkt", "Pkt"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "roceTxErrPkt", "NIC/roceTxErrPkt", "Pkt"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "roceRxErrPkt", "NIC/roceRxErrPkt", "Pkt"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "roceTxCnpPkt", "NIC/roceTxCnpPkt", "Pkt"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "roceRxCnpPkt", "NIC/roceRxCnpPkt", "Pkt"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "roceNewPktRty", "NIC/roceNewPktRty", "Rty"}});
deviceCounterEventMap.insert({PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "nicTxByte", "NIC/nicTxByte", "Byte"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "nicTxBandwidth", "NIC/nicTxBandwidth", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "nicRxByte", "NIC/nicRxByte", "Byte"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "nicRxBandwidth", "NIC/nicRxBandwidth", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "macTxPfcPkt", "NIC/macTxPfcPkt", "Pkt"}});
deviceCounterEventMap.insert({PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "macRxPfcPkt", "NIC/macRxPfcPkt", "Pkt"}});
deviceCounterEventMap.insert({PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "macTxByte", "NIC/macTxByte", "Byte"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "macTxBandwidth", "NIC/macTxBandwidth", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "macRxByte", "NIC/macRxByte", "Byte"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "macRxBandwidth", "NIC/macRxBandwidth", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "macTxBadByte", "NIC/macTxBadByte", "Byte"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::NIC, {"NIC", "NETDEV_STATS", "macRxBadByte", "NIC/macRxBadByte", "Byte"}});
}
void CounterEventHelper::RegisterDevicePCIeMap() {
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txPostMin", "PCIE/txPostMin", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txPostMax", "PCIE/txPostMax", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txPostAvg", "PCIE/txPostAvg", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "rxPostMin", "PCIE/rxPostMin", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "rxPostMax", "PCIE/rxPostMax", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "rxPostAvg", "PCIE/rxPostAvg", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txNonpostMin", "PCIE/txNonpostMin", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txNonpostMax", "PCIE/txNonpostMax", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txNonpostAvg", "PCIE/txNonpostAvg", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "rxNonpostMin", "PCIE/rxNonpostMin", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "rxNonpostMax", "PCIE/rxNonpostMax", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "rxNonpostAvg", "PCIE/rxNonpostAvg", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txCplMin", "PCIE/txCplMin", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txCplMax", "PCIE/txCplMax", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txCplAvg", "PCIE/txCplAvg", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "rxCplMin", "PCIE/rxCplMin", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "rxCplMax", "PCIE/rxCplMax", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert({PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "rxCplAvg", "PCIE/rxCplAvg", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txNonpostLatencyMin", "PCIE/txNonpostLatencyMin", "Time(ns)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txNonpostLatencyMax", "PCIE/txNonpostLatencyMax", "Time(ns)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::PCIE, {"PCIE", "PCIE", "txNonpostLatencyAvg", "PCIE/txNonpostLatencyAvg", "Time(ns)"}});
}
void CounterEventHelper::RegisterDeviceHCCSMap() {
deviceCounterEventMap.insert(
{PROCESS_TYPE::HCCS, {"HCCS", "HCCS", "txThroughput", "HCCS/txThroughput", "Bandwidth(B/s)"}});
deviceCounterEventMap.insert(
{PROCESS_TYPE::HCCS, {"HCCS", "HCCS", "rxThroughput", "HCCS/rxThroughput", "Bandwidth(B/s)"}});
}
void CounterEventHelper::RegisterDeviceQOSMap() {
deviceCounterEventMap.insert(
{PROCESS_TYPE::QOS, {"QOS", "QOS", "bandwidth", "{eventName:s}/Bandwidth", "Bandwidth(B/s)"}});
}
std::string CounterEventHelper::GenerateHostMetadataSQL(const PROCESS_TYPE type) {
CounterEventConfig config = hostCounterEventMap.at(type);
std::string sql = "SELECT DISTINCT ";
std::vector<std::string> valueNamesToJoin;
std::string substitutedFormat = SubstituteThreadNameFormat(config.threadNameFormat, valueNamesToJoin);
sql += substitutedFormat;
sql += " AS name, '" + config.type + "' AS types FROM " + config.tableName;
for (size_t i = 0; i < valueNamesToJoin.size(); ++i) {
sql += " INNER JOIN " + TABLE_STRING_IDS + " AS id" + std::to_string(i) + " ON " + config.tableName + "." +
valueNamesToJoin[i] + " = id" + std::to_string(i) + ".id";
}
sql += ";";
return sql;
}
std::string CounterEventHelper::GenerateHostCounterSQL(const Dic::Module::Timeline::PROCESS_TYPE type) {
CounterEventConfig config = hostCounterEventMap.at(type);
std::string sql = "SELECT timestampNs - ? AS startTime, '{\"" + config.type + "\":' || " + config.valueName +
" || '}' AS args FROM " + config.tableName;
std::vector<std::string> valueNamesToJoin;
std::string substitutedFormat = SubstituteThreadNameFormat(config.threadNameFormat, valueNamesToJoin);
for (size_t i = 0; i < valueNamesToJoin.size(); ++i) {
sql += " INNER JOIN " + TABLE_STRING_IDS + " AS id" + std::to_string(i) + " ON " + config.tableName + "." +
valueNamesToJoin[i] + " = id" + std::to_string(i) + ".id";
}
sql += " WHERE " + substitutedFormat;
sql += " = ? AND startTime >= ? AND startTime <= ? ORDER BY startTime ASC;";
return sql;
}
std::string CounterEventHelper::GetDeviceProcessName(const Dic::Module::Timeline::PROCESS_TYPE type) {
auto it = deviceCounterEventMap.find(type);
if (it == deviceCounterEventMap.end()) {
return "";
}
return it->second.processName;
}
std::string CounterEventHelper::GetDeviceTableName(const Dic::Module::Timeline::PROCESS_TYPE type) {
auto it = deviceCounterEventMap.find(type);
if (it == deviceCounterEventMap.end()) {
return "";
}
return it->second.tableName;
}
std::string CounterEventHelper::GenerateDeviceMetadataSQL(const Dic::Module::Timeline::PROCESS_TYPE type) {
std::string sql;
for (auto [beg, end] = deviceCounterEventMap.equal_range(type); beg != end; ++beg) {
CounterEventConfig config = beg->second;
if (beg != deviceCounterEventMap.lower_bound(type)) {
sql += " UNION ALL ";
}
sql += "SELECT DISTINCT ";
std::vector<std::string> valueNamesToJoin;
std::string substitutedFormat = SubstituteThreadNameFormat(config.threadNameFormat, valueNamesToJoin);
sql += substitutedFormat;
sql += " AS name, '" + config.type + "' AS types FROM " + config.tableName;
for (size_t i = 0; i < valueNamesToJoin.size(); ++i) {
sql += " INNER JOIN " + TABLE_STRING_IDS + " AS id" + std::to_string(i) + " ON " + config.tableName + "." +
valueNamesToJoin[i] + " = id" + std::to_string(i) + ".id";
}
sql += " WHERE deviceId = ?";
}
sql += ";";
return sql;
}
std::string CounterEventHelper::GenerateDeviceCounterSQL(
const Dic::Module::Timeline::PROCESS_TYPE type, const std::string &threadId) {
std::string expectedDisplayName;
size_t index = threadId.find_last_of('/');
if (index == std::string::npos) {
expectedDisplayName = threadId;
} else {
expectedDisplayName = threadId.substr(index + 1);
}
std::string expectedValueName;
if (displayNameToValueName.find(expectedDisplayName) == displayNameToValueName.end()) {
expectedValueName = expectedDisplayName;
} else {
expectedValueName = displayNameToValueName.at(expectedDisplayName);
}
auto beg = deviceCounterEventMap.lower_bound(type);
auto end = deviceCounterEventMap.upper_bound(type);
for (; beg != end; ++beg) {
if (beg->second.valueName == expectedValueName) {
break;
}
}
if (beg == end) {
return "";
}
CounterEventConfig config = beg->second;
std::string sql = "SELECT timestampNs - ? AS startTime, '{\"" + config.type + "\":' || " + config.valueName +
" || '}' AS args FROM " + config.tableName;
std::vector<std::string> valueNamesToJoin;
std::string substitutedFormat = SubstituteThreadNameFormat(config.threadNameFormat, valueNamesToJoin);
for (size_t i = 0; i < valueNamesToJoin.size(); ++i) {
sql += " INNER JOIN " + TABLE_STRING_IDS + " AS id" + std::to_string(i) + " ON " + config.tableName + "." +
valueNamesToJoin[i] + " = id" + std::to_string(i) + ".id";
}
sql += " WHERE " + substitutedFormat;
sql += " = ? AND startTime >= ? AND startTime <= ? AND deviceId = ? ORDER BY startTime ASC;";
return sql;
}
std::string CounterEventHelper::SubstituteThreadNameFormat(
const std::string &format, std::vector<std::string> &valueNamesToJoin) {
std::string substitutedFormat = "'";
size_t index = 0;
while (format.find("{", index) != std::string::npos) {
size_t nextIndex = format.find("{", index);
substitutedFormat += format.substr(index, nextIndex - index) + "' || ";
size_t nextBackBraceIndex = format.find("}", index);
std::string contentInBrace = format.substr(nextIndex + 1, nextBackBraceIndex - nextIndex - 1);
if (StringUtil::EndWith(contentInBrace, ":s")) {
substitutedFormat += "id" + std::to_string(valueNamesToJoin.size()) + ".value";
valueNamesToJoin.emplace_back(contentInBrace.substr(0, contentInBrace.size() - 2));
} else {
substitutedFormat += contentInBrace;
}
substitutedFormat += " || '";
index = nextBackBraceIndex + 1;
}
substitutedFormat += format.substr(index, format.size() - index) + "'";
return substitutedFormat;
}
}