* Copyright (c) 2026 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 "machine/utils/dynamic/dev_cell_match_dump.h"
#include "machine/utils/dynamic/dev_cell_match_mem_layout.h"
#include "tilefwk/aikernel_data.h"
#include <sstream>
namespace npu::tile_fwk::dynamic {
std::string DumpCellMatchPartialUpdateTable(
const uint64_t* cellMatchTableData, uint32_t dataSize, const DevCellMatchTableDesc& desc)
{
std::ostringstream oss;
if (desc.cellUint64Size == 0 || dataSize == 0 || cellMatchTableData == nullptr) {
return oss.str();
}
static const char* opNames[] = {"NW", "AW", "RD"};
auto opTypeName = [&](uint32_t t) -> const char* {
return (t == CELL_MATCH_OP_TYPE_NONE) ? "NONE" : (t <= CELL_MATCH_OP_TYPE_READ) ? opNames[t] : "?";
};
for (uint32_t ci = 0; ci < desc.GetStride(0); ci++) {
uint64_t cellBase = ci * desc.cellUint64Size;
uint64_t meta = cellMatchTableData[cellBase];
uint32_t curType = CellMatchGetCurrentOpType(meta);
uint32_t curCnt = CellMatchGetCurrentOpCount(meta);
uint32_t prevType = CellMatchGetPrevMutexOpType(meta);
uint32_t prevCnt = CellMatchGetPrevMutexOpCount(meta);
uint64_t tagId = CellMatchGetTagId(meta);
oss << "cell[" << ci << "]: meta=0x" << std::hex << meta << std::dec;
oss << " curType=" << opTypeName(curType) << " curCnt=" << curCnt << " prevType=" << opTypeName(prevType);
if (prevCnt != CELL_MATCH_INVALID_OP_COUNT) {
oss << " prevCnt=" << prevCnt;
} else {
oss << " prevCnt=INVALID";
}
oss << " tagId=0x" << std::hex << tagId << std::dec;
auto dumpOps = [&](uint32_t opType, uint32_t count, const char* label) {
if (count == 0 || opType > CELL_MATCH_OP_TYPE_READ)
return;
oss << " " << label << "=[";
uint32_t printed = 0;
for (uint32_t i = 0; i < count; i++) {
uint64_t opId = CellMatchGetOpId(const_cast<uint64_t*>(cellMatchTableData), cellBase, opType, i, desc);
if (opId != AICORE_TASK_INIT) {
oss << (printed > 0 ? "," : "") << FuncID(static_cast<uint32_t>(opId)) << "!"
<< TaskID(static_cast<uint32_t>(opId));
printed++;
}
}
oss << "]";
};
if (prevType <= CELL_MATCH_OP_TYPE_READ && prevCnt > 0 && prevCnt != CELL_MATCH_INVALID_OP_COUNT) {
dumpOps(prevType, prevCnt, "prev");
}
if (curType <= CELL_MATCH_OP_TYPE_READ && curCnt > 0) {
dumpOps(curType, curCnt, "cur");
}
oss << "\n";
}
return oss.str();
}
}