* 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.
*/
* \file codegen_scalar.cpp
* \brief
*/
#include "interface/tensor/logical_tensor.h"
#include "codegen_op_npu.h"
#include "securec.h"
#include "codegen/utils/codegen_utils.h"
#include "codegen/symbol_mgr/codegen_symbol.h"
namespace npu::tile_fwk {
std::string CodeGenOpNPU::GenBarrier() const
{
auto pipeId1 = GetPipeId(syncQueue.pipeId_);
std::ostringstream oss;
oss << "pipe_barrier(" << pipeId1 << ")" << STMT_END;
return oss.str();
}
std::string CodeGenOpNPU::PrintSyncInSingleKernel(bool isWait) const
{
std::string syncOp = isWait ? "wait_flag" : "set_flag";
auto pipeId1 = GetPipeId(syncQueue.pipeId_);
auto pipeId2 = GetPipeId(syncQueue.trigPipeId_);
std::ostringstream oss;
std::vector<std::string> tileOpParams = {pipeId1, pipeId2, "EVENT_ID" + std::to_string(syncQueue.eventId_)};
oss << syncOp << WrapParamByParentheses(tileOpParams) << STMT_END;
return oss.str();
}
std::string CodeGenOpNPU::GenSyncSetOp() const { return PrintSyncInSingleKernel(); }
std::string CodeGenOpNPU::GenSyncWaitOp() const { return PrintSyncInSingleKernel(true); }
void InsertSetSysCnt(std::ostringstream& oss)
{
oss << "#ifdef OPEN_MIX_PERF\n";
oss << "{\n";
oss << " __gm__ uint64_t* setEventBase = reinterpret_cast<__gm__ uint64_t*>(taskStat->perfDataBaseAddr + "
"taskStat->setEventAddr);\n";
oss << " setEventBase[taskStat->setEventNum++] = get_sys_cnt();\n";
oss << "}\n";
oss << "#endif\n";
}
std::string CodeGenOpNPU::GenCVSyncSetOp() const
{
auto pipeId = GetPipeId(syncQueue.pipeId_);
std::ostringstream oss;
InsertSetSysCnt(oss);
oss << "set_intra_block(" << pipeId << ", " << std::to_string(syncQueue.eventId_) << ");\n";
return oss.str();
}
void InsertWaitSysCnt(std::ostringstream& oss)
{
oss << "#ifdef OPEN_MIX_PERF\n";
oss << "{\n";
oss << " __gm__ uint64_t* waitEventBase = reinterpret_cast<__gm__ uint64_t*>(taskStat->perfDataBaseAddr + "
"taskStat->waitEventAddr);\n";
oss << " waitEventBase[taskStat->waitEventNum++] = get_sys_cnt();\n";
oss << "}\n";
oss << "#endif\n";
}
std::string CodeGenOpNPU::GenCVSyncWaitOp() const
{
auto pipeId = GetPipeId(syncQueue.trigPipeId_);
std::ostringstream oss;
InsertWaitSysCnt(oss);
oss << "wait_intra_block(" << pipeId << ", " << std::to_string(syncQueue.eventId_) << ");\n";
return oss.str();
}
static const std::unordered_map<int, std::string> aicpuCallNumDict = {
{AICPU_CALL_NUM_COPYOUT_RESOLVE, "AICPU_CALL_NUM_COPYOUT_RESOLVE"},
};
std::string CodeGenOpNPU::GenAicpuCallOp() const
{
ASSERT(OperErr::ATTRIBUTE_INVALID, opAttrs.count(OpAttributeKey::aicpuCall))
<< "OpAttributeKey::aicpuCall not found";
uint32_t call = static_cast<uint32_t>(AnyCast<int64_t>(opAttrs.find(OpAttributeKey::aicpuCall)->second));
uint16_t callNum = call >> AICPU_CALL_ARG_BIT;
uint16_t callArg = call & ((1 << AICPU_CALL_ARG_BIT) - 1);
std::ostringstream oss;
std::string callNumName = std::to_string(callNum);
if (aicpuCallNumDict.count(callNum)) {
callNumName = aicpuCallNumDict.find(callNum)->second;
}
oss << tileOpName << "<" << callNumName << "," << callArg << ">(GET_CURRENT_TASKID());\n";
return oss.str();
}
}