Line data Source code
1 : /**
2 : * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "ccu_rep_v1.h"
12 : #include "ccu_rep_reference_manager_v1.h"
13 : #include "ccu_rep_translator_v1.h"
14 :
15 : #include "string_util.h"
16 : #include "exception_util.h"
17 : #include "ccu_api_exception.h"
18 :
19 : #include "ccu_ins_generator_base.h"
20 : #include "ccu_kernel.h"
21 :
22 : namespace hcomm {
23 : namespace CcuRep {
24 :
25 : using namespace Hccl;
26 :
27 16 : CcuRepFuncBlock::CcuRepFuncBlock(CcuInsGeneratorBase* insGenPtr, const std::string& label)
28 16 : : CcuRepBlock(insGenPtr, label)
29 : {
30 16 : type = CcuRepType::FUNC_BLOCK;
31 16 : instrCount = 0;
32 16 : }
33 :
34 5 : std::string CcuRepFuncBlock::Describe() { return Hccl::StringFormat("FuncBlock[%s]", GetLabel().c_str()); }
35 :
36 6 : void CcuRepFuncBlock::SetFuncManager(CcuRepReferenceManager* funcManager) { this->funcManager = funcManager; }
37 :
38 1 : void CcuRepFuncBlock::SetCallLayer(uint16_t callLayer)
39 : {
40 1 : if (callLayer != FUNC_CALL_LAYER_INVALID) {
41 1 : this->callLayer = callLayer;
42 1 : return;
43 : }
44 :
45 0 : uint16_t innerCallLayer = 0;
46 0 : for (const auto& rep : GetReps()) {
47 0 : if (rep->Type() == CcuRepType::FUNC_CALL) {
48 0 : innerCallLayer = std::static_pointer_cast<CcuRepFuncCall>(rep)->GetCallLayer() + 1;
49 0 : this->callLayer = this->callLayer > innerCallLayer ? this->callLayer : innerCallLayer;
50 : }
51 : }
52 0 : if (this->callLayer > FUNC_NEST_MAX - 1) {
53 0 : Hccl::THROW<Hccl::CcuApiException>("Max Func Call Nest Num is %u", FUNC_NEST_MAX);
54 : }
55 : }
56 :
57 0 : uint16_t CcuRepFuncBlock::GetCallLayer() const { return callLayer; }
58 :
59 9 : void CcuRepFuncBlock::DefineInArg(const Variable& var)
60 : {
61 9 : inArgCount++;
62 9 : inArgs.push_back(CcuRepArg(var));
63 9 : HCCL_INFO("Define Input Arg: Index[%u], Type[Variable] Id[%u]", inArgs.size(), var.Id());
64 9 : }
65 :
66 2 : void CcuRepFuncBlock::DefineOutArg(const Variable& var)
67 : {
68 2 : outArgCount++;
69 2 : if (outArgCount > FUNC_ARG_MAX) {
70 0 : Hccl::THROW<Hccl::CcuApiException>("CcuFunc Max ArgCount = %u", FUNC_ARG_MAX);
71 : }
72 2 : outArgs.push_back(CcuRepArg(var));
73 2 : HCCL_INFO("Define Output Arg: Index[%u], Type[Variable] Id[%u]", outArgs.size(), var.Id());
74 2 : }
75 :
76 1 : void CcuRepFuncBlock::DefineInArg(const std::vector<Variable>& varList)
77 : {
78 1 : inArgCount += varList.size();
79 1 : inArgs.push_back(CcuRepArg(varList));
80 1 : HCCL_INFO("Define Input Arg: Index[%u], Type[Variable List]: ", inArgs.size());
81 2 : for (uint32_t index = 0; index < varList.size(); index++) {
82 1 : HCCL_INFO(" Index[%u].Id[%u]", index, varList[index].Id());
83 : }
84 1 : }
85 :
86 1 : void CcuRepFuncBlock::DefineOutArg(const std::vector<Variable>& varList)
87 : {
88 1 : outArgCount += varList.size();
89 1 : if (outArgCount > FUNC_ARG_MAX) {
90 0 : Hccl::THROW<Hccl::CcuApiException>("CcuFunc Max ArgCount = %u", FUNC_ARG_MAX);
91 : }
92 1 : outArgs.push_back(CcuRepArg(varList));
93 1 : HCCL_INFO("Define Output Arg: Index[%u], Type[Variable List]: ", outArgs.size());
94 2 : for (uint32_t index = 0; index < varList.size(); index++) {
95 1 : HCCL_INFO(" Index[%u].Id[%u]", index, varList[index].Id());
96 : }
97 1 : }
98 :
99 5 : std::vector<Variable> CcuRepFuncBlock::GetInArgVars() const
100 : {
101 5 : std::vector<Variable> vars;
102 12 : for (const auto& arg : inArgs) {
103 7 : if (arg.type == CcuArgType::VARIABLE) {
104 7 : vars.push_back(arg.var);
105 0 : } else if (arg.type == CcuArgType::VARIABLE_LIST) {
106 0 : vars.insert(vars.end(), arg.varList.begin(), arg.varList.end());
107 : }
108 : }
109 5 : return vars;
110 0 : }
111 13 : uint16_t CcuRepFuncBlock::InstrCount()
112 : {
113 13 : instrCount = CcuRepBlock::InstrCount() + inArgCount + outArgCount
114 13 : + insGeneratorPtr_->GetInstrCount(type); // FuncBlock需要额外指令
115 13 : return instrCount;
116 : }
117 :
118 4 : bool CcuRepFuncBlock::Translate(CcuKernel* ccuKernel, CcuInstr*& instr, uint16_t& instrId, const TransDep& dep)
119 : {
120 4 : if (funcManager == nullptr) {
121 0 : Hccl::THROW<Hccl::CcuApiException>("funcManager is nullptr");
122 : }
123 :
124 4 : this->instrId = instrId;
125 4 : translated = true;
126 :
127 4 : CHK_PRT_THROW(
128 : insGeneratorPtr_->CcuRepFuncBlockTranslate(ccuKernel, instr, instrId, this, dep, 0)
129 : != HcclResult::HCCL_SUCCESS,
130 : HCCL_ERROR("[CcuRepFuncBlock][Translate] failed to translate inArgs processing for instrId[%u]", instrId),
131 : Hccl::CcuApiException, "CcuRepFuncBlock translate failed");
132 : // 使用空实现的自定义删除器,避免智能指针析构时释放对象
133 : auto translator = CcuRepTranslator(
134 8 : std::shared_ptr<CcuRepReferenceManager>(funcManager, []([[maybe_unused]] CcuRepReferenceManager* ptr) {}),
135 4 : dep);
136 8 : translator.Translate(
137 4 : ccuKernel, GetReps(), instr, instrId, []([[maybe_unused]] std::shared_ptr<CcuRepBase> rep) -> bool {
138 5 : return true;
139 : });
140 :
141 4 : CHK_PRT_THROW(
142 : insGeneratorPtr_->CcuRepFuncBlockTranslate(ccuKernel, instr, instrId, this, dep, 1)
143 : != HcclResult::HCCL_SUCCESS,
144 : HCCL_ERROR("[CcuRepFuncBlock][Translate] failed to translate outArgs processing for instrId[%u]", instrId),
145 : Hccl::CcuApiException, "CcuRepFuncBlock translate failed");
146 :
147 4 : return translated;
148 4 : }
149 :
150 : }; // namespace CcuRep
151 : }; // namespace hcomm
|