* 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.
*/
#include <string.h>
#include "data_manager.h"
#include "data_struct.h"
#include "msprof_stub.h"
#include "securec.h"
#include "prof_api.h"
#ifdef MSPROF_C_CPP
#include "msprof_dlog.h"
#endif
using namespace std;
namespace Cann {
namespace Dvvp {
namespace Test {
DataManager &DataManager::GetInstance()
{
static DataManager manager;
return manager;
}
std::string DataManager::GetCaseName(const char* testcase)
{
size_t len = strlen(testcase);
std::string casename;
for (size_t i = 0; i < len; i++) {
if(std::isupper(testcase[i])) {
if (i != 0) {
casename += "_";
}
casename += std::tolower(testcase[i]);
} else {
casename += testcase[i];
}
}
return casename;
}
void DataManager::Init(std::string socType, const char* testcase)
{
std::string casename = GetCaseName(testcase);
socType_ = socType;
dataDir_ = std::string(LLT_DATA_DIR) + "/" + socType_ + "/" + casename;
MSPROF_LOGD("Init data manager by testcase : %s", dataDir_.c_str());
}
void DataManager::SetDataDir(const char* dirName)
{
dataDir_ = std::string(LLT_DATA_DIR) + "/" + socType_ + "/" + dirName;
MSPROF_LOGD("Set data dir : %s", dataDir_.c_str());
}
void DataManager::UnInit()
{
dataDir_ = "";
MSPROF_LOGD("UnInit data manager");
}
void DataManager::SetModelId(uint32_t modelId)
{
modelId_ = modelId;
}
void DataManager::SetStreamId(uint32_t streamId)
{
streamId_ = streamId;
}
uint32_t DataManager::GetModelId()
{
return modelId_;
}
uint32_t DataManager::GetStreamId()
{
return streamId_;
}
int32_t DataManager::ReadFile(std::string filename, ReportDataCallback callback, bool needExist, bool once)
{
if (dataDir_.empty()) {
MSPROF_LOGE("Data manager has not been init, %s", dataDir_.c_str());
return -1;
}
MSPROF_LOGI("ReadFile dataDir_: %s, filename: %s", dataDir_.c_str(), filename.c_str());
std::string dataFile(dataDir_ + "/" + filename);
ifstream ifs;
ifs.open(dataFile, std::ios::in);
if (!ifs.is_open()) {
if (needExist) {
MSPROF_LOGE("File %s not exist.", dataFile.c_str());
return -1;
}
return 0;
}
while(!ifs.eof()) {
if (callback(ifs) != 0) {
return -1;
}
if (once) {
break;
}
}
return 0;
}
int32_t DataManager::ReportTsTimelineData(std::queue<struct Buff> &channelData)
{
return ReadFile("device_ts_timeline_data.txt", [&channelData](ifstream &ifs){
struct Buff buffer;
buffer.len = sizeof(TsProfileTimeline);
buffer.data = malloc(buffer.len);
auto tsData = (TsProfileTimeline *)buffer.data;
ifs >> tsData->taskState;
ifs >> tsData->thread;
ifs >> tsData->deviceId;
ifs >> tsData->streamId;
ifs >> tsData->taskId;
ifs >> tsData->timestamp;
tsData->head.rptType = TS_TIMELINE_RPT_TYPE;
tsData->head.mode = 1;
tsData->taskType = 1;
tsData->head.bufSize = buffer.len;
channelData.push(buffer);
return 0;
});
}
int32_t DataManager::ReportTsKeypointData(std::queue<struct Buff> &channelData)
{
return ReadFile("device_ts_keypoint_data.txt", [&channelData](ifstream &ifs){
struct Buff buffer;
buffer.len = sizeof(TsProfileKeypoint);
buffer.data = malloc(buffer.len);
auto tsData = (TsProfileKeypoint *)buffer.data;
ifs >> tsData->tagId;
ifs >> tsData->indexId;
ifs >> tsData->modelId;
ifs >> tsData->streamId;
ifs >> tsData->taskId;
ifs >> tsData->timestamp;
tsData->head.rptType = TS_KEYPOINT_RPT_TYPE;
tsData->head.mode = 1;
tsData->head.bufSize = buffer.len;
channelData.push(buffer);
return 0;
});
}
int32_t DataManager::ReportHwtsData(std::queue<struct Buff> &channelData)
{
return ReadFile("device_hwts_data.txt", [&channelData](ifstream &ifs){
struct Buff buffer;
buffer.len = sizeof(HwtsProfileType01);
buffer.data = malloc(buffer.len);
HwtsProfileType01* hwtsData = (HwtsProfileType01 *)buffer.data;
uint8_t cnt = 1;
uint8_t rType;
ifs >> rType;
ifs >> hwtsData->reserved;
ifs >> hwtsData->taskId;
ifs >> hwtsData->streamId;
ifs >> hwtsData->syscnt;
hwtsData->cntRes0Type = rType + (cnt << 4);
hwtsData->hex6bd3 = 0x6bd3;
channelData.push(buffer);
return 0;
});
}
int32_t DataManager::ReportFftsAcsqData(std::queue<struct Buff> &channelData)
{
return ReadFile("device_ffts_acsq_data.txt", [&channelData](ifstream &ifs){
struct Buff buffer;
buffer.len = sizeof(StarsAcsqLog);
buffer.data = malloc(buffer.len);
StarsAcsqLog* acsqData = (StarsAcsqLog *)buffer.data;
uint16_t logType;
ifs >> logType;
acsqData->head.logType = logType;
ifs >> acsqData->taskId;
ifs >> acsqData->streamId;
ifs >> acsqData->sysCountHigh;
ifs >> acsqData->sysCountLow;
channelData.push(buffer);
return 0;
}, false, false);
}
int32_t DataManager::ReportFftsCtxData(std::queue<struct Buff> &channelData)
{
return ReadFile("device_ffts_ctx_data.txt", [&channelData](ifstream &ifs){
struct Buff buffer;
buffer.len = sizeof(StarsCxtLog);
buffer.data = malloc(buffer.len);
StarsCxtLog* ctxData = (StarsCxtLog *)buffer.data;
uint16_t logType;
ifs >> logType;
ctxData->head.logType = logType;
ifs >> ctxData->taskId;
ifs >> ctxData->streamId;
ifs >> ctxData->sysCountHigh;
ifs >> ctxData->sysCountLow;
channelData.push(buffer);
return 0;
});
}
int32_t DataManager::ReportOpStarsAcsqData(std::queue<struct Buff> &channelData)
{
return ReadFile("device_stars_acsq_data.txt", [&channelData](ifstream &ifs){
struct Buff buffer;
buffer.len = sizeof(StarsAcsqLog);
buffer.data = malloc(buffer.len);
StarsAcsqLog* acsqData = (StarsAcsqLog *)buffer.data;
uint16_t logType;
ifs >> logType;
acsqData->head.logType = logType;
ifs >> acsqData->taskId;
ifs >> acsqData->streamId;
ifs >> acsqData->sysCountHigh;
ifs >> acsqData->sysCountLow;
channelData.push(buffer);
return 0;
}, false, false);
}
int32_t DataManager::ReportOpFftsPmuData(std::queue<struct Buff> &channelData)
{
return ReadFile("device_ffts_pmu_data.txt", [&channelData](ifstream &ifs){
struct Buff buffer;
buffer.len = sizeof(Analysis::Dvvp::Analyze::FftsSubProfile);
buffer.data = malloc(buffer.len);
Analysis::Dvvp::Analyze::FftsSubProfile* subData = (Analysis::Dvvp::Analyze::FftsSubProfile *)buffer.data;
uint16_t funcType;
ifs >> funcType;
subData->head.funcType = funcType;
MSPROF_LOGE("ReportOpFftsPmuData funcType = %u", subData->head.funcType);
ifs >> subData->taskId;
ifs >> subData->streamId;
ifs >> subData->contextId;
uint16_t fftsType;
ifs >> fftsType;
subData->fftsType = fftsType;
subData->contextType = 0;
ifs >> subData->totalCycle;
ifs >> subData->pmu[0];
ifs >> subData->pmu[1];
ifs >> subData->pmu[2];
ifs >> subData->pmu[3];
ifs >> subData->pmu[4];
ifs >> subData->pmu[5];
ifs >> subData->pmu[6];
ifs >> subData->pmu[7];
channelData.push(buffer);
return 0;
}, false, true);
}
int32_t DataManager::ReportOpDavidPmuData(std::queue<struct Buff> &channelData)
{
return ReadFile("device_david_pmu_data.txt", [&channelData](ifstream &ifs){
struct Buff buffer;
buffer.len = sizeof(Analysis::Dvvp::Analyze::DavidProfile);
buffer.data = malloc(buffer.len);
Analysis::Dvvp::Analyze::DavidProfile* subData = (Analysis::Dvvp::Analyze::DavidProfile *)buffer.data;
uint16_t funcType;
ifs >> funcType;
subData->head.funcType = funcType;
ifs >> subData->taskId;
ifs >> subData->streamId;
ifs >> subData->contextId;
ifs >> subData->startCnt;
ifs >> subData->endCnt;
subData->contextType = 0;
ifs >> subData->totalCycle;
ifs >> subData->pmu[0];
ifs >> subData->pmu[1];
ifs >> subData->pmu[2];
ifs >> subData->pmu[3];
ifs >> subData->pmu[4];
ifs >> subData->pmu[5];
ifs >> subData->pmu[6];
ifs >> subData->pmu[7];
ifs >> subData->pmu[8];
ifs >> subData->pmu[9];
channelData.push(buffer);
return 0;
}, false, true);
}
int32_t DataManager::ReportBiuPerfData(std::queue<struct Buff> &channelData)
{
const std::vector<std::vector<uint16_t>> biuData = {{0b1110, 0b000000010111, 0b0000000000001110},
{0b1110, 0b000000010110, 0b0000000000001000}, {0b1110, 0b000000010110, 0b0000000000001000},
{0b1110, 0b000000010110, 0b0000000000001000}, {0b0011, 0b000000010101, 0b1000000100001111},
{0b1111, 0b000001111111, 0b1000000000111111}, {0b1111, 0b000000000000, 0b1000000000111111}};
for (auto row : biuData) {
struct Buff buffer;
buffer.len = sizeof(Analysis::Dvvp::Analyze::BiuPerfProfile);
buffer.data = malloc(buffer.len);
Analysis::Dvvp::Analyze::BiuPerfProfile* biuperf = (Analysis::Dvvp::Analyze::BiuPerfProfile *)buffer.data;
biuperf->ctrlType = row[0];
biuperf->events = row[1];
biuperf->timeData = row[2];
channelData.push(buffer);
}
return 0;
}
int32_t DataManager::ReportStarsNanoData(std::queue<struct Buff> & )
{
return 0;
}
int32_t DataManager::ReportDefaultData(std::queue<struct Buff> &channelData)
{
struct Buff buffer;
buffer.len = 1024;
buffer.data = malloc(buffer.len);
memset_s(buffer.data, 1024, 0, 1024);
channelData.push(buffer);
return 0;
}
int32_t DataManager::CheckSubscribeResult(std::set<RunnerOpInfo> &modelOpInfo, std::string resultFile)
{
auto ret = ReadFile(resultFile, [&](ifstream &ifs){
RunnerOpInfo opInfo;
ifs >> opInfo.flag;
ifs >> opInfo.threadId;
ifs >> opInfo.opName;
ifs >> opInfo.opType;
ifs >> opInfo.opCostTime;
ifs >> opInfo.start;
ifs >> opInfo.end;
ifs >> opInfo.aicoreCostTime;
MSPROF_LOGD("[Expect] opName : %s, opType : %s, opCostTime : %llu, start : %llu, end :%llu, aicoreCostTime: %llu",
opInfo.opName.c_str(), opInfo.opType.c_str(), opInfo.opCostTime, opInfo.start, opInfo.end, opInfo.aicoreCostTime);
if (modelOpInfo.find(opInfo) == modelOpInfo.end()) {
MSPROF_LOGE("Cannot find expcet op info");
for (auto &iter : modelOpInfo) {
MSPROF_LOGD("[Unmatched] opName : %s, opType : %s, opCostTime : %llu, start : %llu, end :%llu, aicoreCostTime: %llu",
iter.opName.c_str(), iter.opType.c_str(), iter.opCostTime, iter.start, iter.end, iter.aicoreCostTime);
}
return -1;
}
modelOpInfo.erase(opInfo);
return 0;
}, true);
if (ret != 0) {
return ret;
}
return 0;
}
}
}
}