* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This file is part of the MindStudio project.
*
* 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 "analysis/csrc/application/timeline/timeline_manager.h"
#include <atomic>
#include "analysis/csrc/application/timeline/timeline_factory.h"
#include "analysis/csrc/infrastructure/utils/thread_pool.h"
#include "analysis/csrc/domain/entities/viewer_data/ai_task/include/step_trace_data.h"
#include "analysis/csrc/domain/entities/viewer_data/ai_task/include/msprof_tx_host_data.h"
namespace Analysis {
namespace Application {
namespace {
const std::string PREFIX_CONTEXT = "[";
const std::string SUFFIX_CONTEXT = "]";
const int JSON_FILE_OFFSET = -1;
const size_t MIN_NUM_FOR_IOC = std::set<std::string>{PROCESSOR_NAME_HASH}.size();
const std::unordered_map<JsonProcess, std::string> JSON_TO_ASSEMBLER_TABLE{
{JsonProcess::ASCEND, PROCESS_TASK},
{JsonProcess::ACC_PMU, PROCESS_ACC_PMU},
{JsonProcess::CANN, PROCESS_API},
{JsonProcess::DDR, PROCESS_DDR},
{JsonProcess::STARS_CHIP_TRANS, PROCESS_STARS_CHIP_TRANS},
{JsonProcess::HBM, PROCESS_HBM},
{JsonProcess::COMMUNICATION, PROCESS_HCCL},
{JsonProcess::CCU, PROCESS_CCU},
{JsonProcess::HCCS, PROCESS_HCCS},
{JsonProcess::OS_RUNTIME_API, PROCESSOR_NAME_OSRT_API},
{JsonProcess::NETWORK_USAGE, PROCESS_NETWORK_USAGE},
{JsonProcess::DISK_USAGE, PROCESS_DISK_USAGE},
{JsonProcess::MEMORY_USAGE, PROCESS_MEMORY_USAGE},
{JsonProcess::CPU_USAGE, PROCESS_CPU_USAGE},
{JsonProcess::MSPROFTX, PROCESS_MSPROFTX},
{JsonProcess::NPU_MEM, PROCESS_NPU_MEM},
{JsonProcess::OVERLAP_ANALYSE, PROCESS_OVERLAP_ANALYSE},
{JsonProcess::PCIE, PROCESS_PCIE},
{JsonProcess::SIO, PROCESS_SIO},
{JsonProcess::STARS_SOC, PROCESS_STARS_SOC},
{JsonProcess::STEP_TRACE, PROCESS_STEP_TRACE},
{JsonProcess::FREQ, PROCESS_AI_CORE_FREQ},
{JsonProcess::LLC, PROCESS_LLC},
{JsonProcess::NIC, PROCESS_NIC},
{JsonProcess::ROCE, PROCESS_ROCE},
{JsonProcess::QOS, PROCESS_QOS},
{JsonProcess::DEVICE_TX, PROCESS_DEVICE_TX},
{JsonProcess::LOW_POWER, PROCESS_LOW_POWER},
{JsonProcess::BIU_PERF, PROCESS_BIU_PERF},
{JsonProcess::UB, PROCESS_UB},
{JsonProcess::BLOCK_DETAIL, PROCESS_BLOCK_DETAIL},
};
std::set<std::string> TIMELINE_DATA_PROCESS_LIST{
PROCESSOR_NAME_API,
PROCESSOR_NAME_COMMUNICATION,
PROCESSOR_NAME_CCU_MISSION,
PROCESSOR_NAME_COMPUTE_TASK_INFO,
PROCESSOR_NAME_KFC_TASK,
PROCESSOR_NAME_KFC_COMM,
PROCESSOR_NAME_DEVICE_TX,
PROCESSOR_NAME_MSTX,
PROCESSOR_NAME_STEP_TRACE,
PROCESSOR_NAME_TASK,
PROCESSOR_NAME_ACC_PMU,
PROCESSOR_NAME_AICORE_FREQ,
PROCESSOR_NAME_CHIP_TRAINS,
PROCESSOR_NAME_DDR,
PROCESSOR_NAME_HBM,
PROCESSOR_NAME_HCCS,
PROCESSOR_NAME_CPU_USAGE,
PROCESSOR_NAME_MEM_USAGE,
PROCESSOR_NAME_DISK_USAGE,
PROCESSOR_NAME_NETWORK_USAGE,
PROCESSOR_NAME_OSRT_API,
PROCESSOR_NAME_LLC,
PROCESSOR_NAME_NPU_MEM,
PROCESSOR_NAME_PCIE,
PROCESSOR_NAME_SIO,
PROCESSOR_NAME_SOC,
PROCESSOR_NAME_NIC,
PROCESSOR_NAME_ROCE,
PROCESSOR_NAME_QOS,
PROCESSOR_MC2_COMM_INFO,
PROCESSOR_NAME_MEMCPY_INFO,
PROCESSOR_NAME_NPU_OP_MEM,
PROCESSOR_NAME_NPU_MODULE_MEM,
PROCESSOR_NAME_NIC_TIMELINE,
PROCESSOR_NAME_ROCE_TIMELINE,
PROCESSOR_NAME_LOW_POWER,
PROCESSOR_NAME_BIU_PERF,
PROCESSOR_NAME_UB,
PROCESSOR_NAME_BLOCK_DETAIL,
};
}
bool TimelineManager::ProcessTimeLine(DataInventory& dataInventory, const std::vector<JsonProcess>& jsonProcess)
{
const uint16_t tableProcessors = 10;
Analysis::Utils::ThreadPool pool(tableProcessors);
pool.Start();
std::atomic<bool> retFlag(true);
std::vector<std::string> assemblerList = GetAssemblerList(jsonProcess);
for (const auto& name : assemblerList) {
pool.AddTask([this, &name, &retFlag, &dataInventory]() {
auto assembler = TimelineFactory::GetAssemblerByName(name);
if (assembler == nullptr) {
ERROR("% is not defined", name);
retFlag = false;
return;
}
retFlag = assembler->Run(dataInventory, profPath_) && retFlag;
});
}
pool.WaitAllTasks();
pool.Stop();
if (!retFlag) {
ERROR("The % for json assemble failed to be executed.", profPath_);
PRINT_ERROR("The % for json assemble failed to be executed. "
"Please check msprof_analysis_log in outputPath for more info.", profPath_);
return false;
}
return true;
}
void TimelineManager::WriteFile(const std::string &filePrefix, FileCategory category)
{
auto tempFile = filePrefix;
tempFile.append("_").append(GetTimeStampStr()).append(JSON_SUFFIX);
auto filePath = File::PathJoin({outputPath_, tempFile});
DumpTool::WriteToFile(filePath, PREFIX_CONTEXT.c_str(), PREFIX_CONTEXT.size(), category);
fileType_.emplace(category, filePath);
}
bool TimelineManager::PreDumpJson(DataInventory &dataInventory)
{
if (dataInventory.Size() <= MIN_NUM_FOR_IOC) {
return false;
}
WriteFile(MSPROF_JSON_FILE, FileCategory::MSPROF);
if (dataInventory.GetPtr<std::vector<TrainTraceData>>()) {
WriteFile(STEP_TRACE_FILE, FileCategory::STEP);
}
if (dataInventory.GetPtr<std::vector<MsprofTxHostData>>()) {
WriteFile(MSPROF_TX_FILE, FileCategory::MSPROF_TX);
}
return true;
}
void TimelineManager::PostDumpJson()
{
for (const auto &it : fileType_) {
FileWriter writer(it.second, std::ios::in | std::ios::out | std::ios::ate);
writer.WriteTextBack(SUFFIX_CONTEXT, JSON_FILE_OFFSET);
}
}
bool TimelineManager::Run(DataInventory &dataInventory, const std::vector<JsonProcess>& jsonProcess)
{
INFO("Start exporting timeline!");
PRINT_INFO("Start exporting the timeline!");
if (!PreDumpJson(dataInventory)) {
WARN("Can't Get data from dataInventory after data process");
PRINT_WARN("Can't export timeline, msprof_analysis_log in outputPath for more info");
return true;
}
bool runFlag = ProcessTimeLine(dataInventory, jsonProcess);
PostDumpJson();
if (!runFlag) {
ERROR("The unified timeline process failed to be executed.");
PRINT_ERROR("The unified timeline process failed to be executed. "
"Please check msprof_analysis_log in outputPath for more info.");
return false;
}
PRINT_INFO("End exporting timeline output_file. The file is stored in the PROF file.");
return true;
}
std::vector<std::string> TimelineManager::GetAssemblerList(const std::vector<JsonProcess>& jsonProcess)
{
std::vector<std::string> assemblerList;
for (const auto& jsonEnum : jsonProcess) {
assemblerList.push_back(JSON_TO_ASSEMBLER_TABLE.at(jsonEnum));
}
return assemblerList;
}
const std::set<std::string>& TimelineManager::GetProcessList()
{
return TIMELINE_DATA_PROCESS_LIST;
}
}
}