* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
*/
#ifndef PROFILER_SERVER_TEXTADVICESQLCONSTANT_H
#define PROFILER_SERVER_TEXTADVICESQLCONSTANT_H
#include <string>
#include <utility>
#include "algorithm"
#include "StringUtil.h"
#include "ServerLog.h"
#include "TimelineProtocolRequest.h"
#include "TableDefs.h"
#include "TraceDatabaseDef.h"
namespace Dic::Module::Timeline {
class TextAdviceSqlConstant {
public:
static std::string GenerateFusibleOpFilterTextSql(
const Protocol::KernelDetailsParams ¶ms, const std::vector<Timeline::FuseableOpRule> &rule) {
size_t maxLen = 0;
for (const auto &r : rule) {
maxLen = std::max(maxLen, r.opList.size());
}
std::string timeCondSql;
if (params.startTime != params.endTime) {
timeCondSql += " AND (kd.start_time + kd.duration * 1000) >= ? AND kd.start_time <= ? ";
}
std::string sql = "WITH data AS ( "
"SELECT kd.deviceId, kd.name AS name, kd.op_type, kd.accelerator_core, "
"kd.start_time - ? AS startTime, "
"s.duration AS duration, t.pid AS pid, t.tid AS tid, "
"s.id AS id, s.track_id AS track_id, "
"ROW_NUMBER() OVER (ORDER BY s.track_id ASC, s.timestamp ASC) AS row_num, "
"op_type AS op";
for (size_t k = 1; k < maxLen; ++k) {
sql += ", LEAD(op_type, " + std::to_string(k) +
") OVER (ORDER BY s.track_id ASC, s.timestamp ASC) AS next" + std::to_string(k);
}
sql += " FROM " + KERNEL_DETAIL +
" kd "
"JOIN " +
SLICE_TABLE +
" s ON kd.name = s.name AND kd.start_time = s.timestamp "
"JOIN " +
THREAD_TABLE +
" t ON s.track_id = t.track_id "
"WHERE kd.deviceId = ? "
"AND kd.accelerator_core NOT IN ('HCCL', 'COMMUNICATION') " +
timeCondSql + ") ";
sql = GenerateTextFusedOpRuleSql(sql, rule);
sql += " ORDER BY " + params.orderBy + " " + params.order + " ) LIMIT ? OFFSET ? ";
return sql;
}
private:
static std::string GenerateTextFusedOpRuleSql(std::string sql, const std::vector<Timeline::FuseableOpRule> &rule) {
auto buildRuleCond = [](const Timeline::FuseableOpRule &rule) {
std::string cond = "( op = '" + rule.opList[0] + "' ";
for (size_t i = 1; i < rule.opList.size(); ++i) {
cond += " AND next" + std::to_string(i) + " = '" + rule.opList[i] + "' ";
}
cond += ")";
return cond;
};
sql += "SELECT * FROM ( SELECT data.*, COUNT(*) OVER () AS total_count, CASE ";
for (const auto &ruleItem : rule) {
sql += "WHEN " + buildRuleCond(ruleItem) + " THEN '" + StringUtil::join(ruleItem.opList, ", ") + "' ";
}
sql += "END AS originOpList, CASE ";
for (const auto &ruleItem : rule) {
sql += "WHEN " + buildRuleCond(ruleItem) + " THEN '" + ruleItem.fusedOp + "' ";
}
sql += "END AS fusedOp FROM data WHERE ";
bool firstRule = true;
for (const auto &ruleItem : rule) {
if (!firstRule) {
sql += " OR ";
}
firstRule = false;
sql += buildRuleCond(ruleItem);
}
return sql;
}
};
}
#endif