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 : #include "ccu_ins_generator_v2.h"
11 : #include "hcomm_c_adpt.h"
12 : #include "ccu_rep_base_v1.h"
13 : #include "../../../../endpoint_pairs/channels/ccu/ccu_urma_channel.h"
14 : #include "ccu_api_exception.h"
15 : #include "ccu_assist_v1.h"
16 : #include "hcom_common.h"
17 :
18 : #include <iostream>
19 :
20 : namespace hcomm {
21 :
22 : namespace CcuRep {
23 : #define UNUSED(x) static_cast<void>(x)
24 :
25 : namespace {
26 : constexpr uint8_t URMA_DMA_OP_READ = 0x6; // UB URMA WQEBB opcode: read
27 : constexpr uint8_t URMA_DMA_OP_WRITE = 0x3; // UB URMA WQEBB opcode: write
28 : constexpr uint32_t REL_JMP_INSTR_NUM = 9; // RelJmp生成的指令数
29 : constexpr uint32_t FUNC_CALL_JMP_OFFSET = 11; // RelJmp+Jump+Nop
30 : constexpr uint32_t FUNC_CALL_RET_OFFSET = 12; // FUNC_CALL_JMP_OFFSET + 1
31 : // loopParamVar 布局:iterNum[12:0] gsaOffset[44:13] ctxId[52:45]
32 : constexpr uint64_t LOOP_ITER_NUM_MASK = 0x1FFFULL;
33 : constexpr uint32_t LOOP_GSA_OFFSET_SHIFT = 13;
34 : constexpr uint64_t LOOP_GSA_OFFSET_MASK = 0xFFFFFFFFULL;
35 : constexpr uint64_t LOOP_FIELD_MASK = 0x7FULL;
36 :
37 : template <typename T>
38 0 : void LoadAddrArg(CcuInstr*& instr, const T& dst, const T& src)
39 : {
40 0 : CcuV2::Assign(instr++, dst.addr.Id(), src.addr.Id());
41 0 : CcuV2::Assign(instr++, dst.token.Id(), src.token.Id());
42 0 : }
43 :
44 : template <typename T>
45 0 : HcclResult LoadAddrListArg(CcuInstr*& instr, const std::vector<T>& dst, const std::vector<T>& src)
46 : {
47 0 : if (src.size() != dst.size()) {
48 0 : HCCL_ERROR("Mismatched Arg Size: srcSize[%u], dstSize[%u]", src.size(), dst.size());
49 0 : return HCCL_E_PARA;
50 : }
51 0 : for (uint32_t j = 0; j < src.size(); j++) {
52 0 : LoadAddrArg(instr, dst[j], src[j]);
53 : }
54 0 : return HcclResult::HCCL_SUCCESS;
55 : }
56 12 : HcclResult GetUrmaChannel(ChannelHandle channelHandle, CcuUrmaChannel*& channelImpl)
57 : {
58 12 : void *channelPtr{nullptr};
59 12 : CHK_RET(static_cast<HcclResult>(HcommChannelGet(channelHandle, &channelPtr)));
60 12 : channelImpl = dynamic_cast<CcuUrmaChannel*>(static_cast<Channel*>(channelPtr));
61 12 : CHK_PTR_NULL(channelImpl);
62 12 : return HcclResult::HCCL_SUCCESS;
63 : }
64 :
65 8 : HcclResult GetRmtToken(CcuUrmaChannel* channelImpl, uint64_t& rmtToken)
66 : {
67 8 : uint32_t rmtTokenId{0};
68 8 : uint32_t rmtTokenValue{0};
69 8 : CHK_PTR_NULL(channelImpl);
70 8 : CHK_RET(channelImpl->GetRmtCcuBufferTokenInfo(rmtTokenId, rmtTokenValue));
71 8 : rmtToken = CcuRep::GetToken(rmtTokenId, rmtTokenValue, 1);
72 8 : return HcclResult::HCCL_SUCCESS;
73 : }
74 : } // namespace
75 :
76 421 : uint32_t CcuInsGeneratorV2::GetInstrCount(CcuRepType repType)
77 : {
78 421 : if (repTypeInstrCount.find(repType) == repTypeInstrCount.end()) {
79 0 : Hccl::THROW<Hccl::CcuApiException>("[%s] Unsupported repType[%d]", __func__, repType);
80 : }
81 421 : return repTypeInstrCount[repType];
82 : }
83 :
84 4 : HcclResult CcuInsGeneratorV2::CcuRepBufLocReadTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepBufLocRead* repBufLocRead, const TransDep &dep)
85 : {
86 4 : CHK_PTR_NULL(repBufLocRead);
87 4 : CcuV2::CacheConfig config = {0};
88 :
89 4 : TransLocMemToLocMS(instr++, repBufLocRead->GetDst().Id(), repBufLocRead->GetSrc().addr.Id(), repBufLocRead->GetSrc().token.Id(), repBufLocRead->GetLen().Id(), dep.reserveXnId,
90 8 : repBufLocRead->GetSem().Id(), repBufLocRead->GetMask(), config);
91 :
92 4 : return HcclResult::HCCL_SUCCESS;
93 : }
94 :
95 2 : HcclResult CcuInsGeneratorV2::CcuRepBufLocWriteTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepBufLocWrite* repBufLocWrite, const TransDep &dep)
96 : {
97 2 : CHK_PTR_NULL(repBufLocWrite);
98 2 : CcuV2::CacheConfig config = {0};
99 :
100 2 : TransLocMSToLocMem(instr++, repBufLocWrite->GetDst().addr.Id(), repBufLocWrite->GetDst().token.Id(), repBufLocWrite->GetSrc().Id(), repBufLocWrite->GetLen().Id(), dep.reserveXnId,
101 4 : repBufLocWrite->GetSem().Id(), repBufLocWrite->GetMask(), config);
102 :
103 2 : return HcclResult::HCCL_SUCCESS;
104 : }
105 :
106 0 : HcclResult CcuInsGeneratorV2::CcuRepBufReadTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepBufRead* repBufRead, const TransDep &dep)
107 : {
108 0 : CHK_PTR_NULL(repBufRead);
109 0 : CHK_PTR_NULL(ccuKernel);
110 0 : CcuUrmaChannel *channelImpl{nullptr};
111 0 : CHK_RET(GetUrmaChannel(repBufRead->GetChannel(), channelImpl));
112 :
113 0 : CcuV2::TransMemNotifyInfo notify = {};
114 0 : CcuV2::TransMemReduceInfo reduce = {};
115 0 : CcuV2::TransMemConfig config = {};
116 0 : config.dmaOpCode = URMA_DMA_OP_READ; // UB URMA WQEBB opcode: read
117 0 : config.src_mode = 1;
118 0 : config.dst_mode = 0;
119 0 : config.msIdMode = 1;
120 0 : uint32_t channelId = channelImpl->GetChannelId();
121 0 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
122 0 : TransMem(instr++, repBufRead->GetDst().Id(), constValue2VarMap.at(dep.ccuResSpaceTokenInfo).Id(),
123 0 : repBufRead->GetSrc().addr.Id(), repBufRead->GetSrc().token.Id(),
124 0 : repBufRead->GetLen().Id(), constValue2VarMap.at(channelId).Id(), notify, reduce, config,
125 0 : repBufRead->GetSem().Id(), repBufRead->GetMask());
126 :
127 0 : return HcclResult::HCCL_SUCCESS;
128 : }
129 :
130 0 : HcclResult CcuInsGeneratorV2::CcuRepWriteTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepWrite* repWrite)
131 : {
132 0 : CHK_PTR_NULL(repWrite);
133 0 : CHK_PTR_NULL(ccuKernel);
134 0 : CcuUrmaChannel *channelImpl{nullptr};
135 0 : CHK_RET(GetUrmaChannel(repWrite->GetChannel(), channelImpl));
136 0 : CcuV2::TransMemNotifyInfo notify = {};
137 0 : CcuV2::TransMemReduceInfo reduce = {};
138 0 : CcuV2::TransMemConfig config = {};
139 0 : config.dmaOpCode = URMA_DMA_OP_WRITE; // UB URMA WQEBB opcode: write
140 0 : config.src_mode = 0;
141 0 : config.dst_mode = 1;
142 :
143 0 : if (repWrite->GetReduceFlag() == 1) {
144 0 : config.udfEnable = 1;
145 0 : reduce.udfType = 0;
146 0 : reduce.reduceDataType = repWrite->GetDataType();
147 0 : reduce.reduceOpCode = repWrite->GetOpType();
148 : }
149 0 : uint32_t channelId = channelImpl->GetChannelId();
150 0 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
151 :
152 0 : uint64_t rmtCcuResToken{};
153 0 : CHK_RET(GetRmtToken(channelImpl, rmtCcuResToken));
154 0 : notify.xntId = constValue2VarMap.at(rmtCcuResToken).Id();
155 0 : TransMem(instr++, repWrite->GetRem().addr.Id(), repWrite->GetRem().token.Id(), repWrite->GetLoc().addr.Id(), repWrite->GetLoc().token.Id(), repWrite->GetLen().Id(),
156 0 : constValue2VarMap.at(channelId).Id(), notify, reduce, config, repWrite->GetSem().Id(), repWrite->GetMask());
157 :
158 0 : return HcclResult::HCCL_SUCCESS;
159 : }
160 :
161 :
162 1 : HcclResult CcuInsGeneratorV2::CcuRepReadTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepRead* repRead)
163 : {
164 1 : CHK_PTR_NULL(repRead);
165 1 : CHK_PTR_NULL(ccuKernel);
166 1 : CcuUrmaChannel *channelImpl{nullptr};
167 1 : CHK_RET(GetUrmaChannel(repRead->GetChannel(), channelImpl));
168 :
169 1 : CcuV2::TransMemNotifyInfo notify = {};
170 1 : CcuV2::TransMemReduceInfo reduce = {};
171 1 : CcuV2::TransMemConfig config = {};
172 1 : config.dmaOpCode = URMA_DMA_OP_READ; // UB URMA WQEBB opcode: read
173 :
174 1 : if (repRead->GetReduceFlag() == 1) {
175 0 : config.udfEnable = 1;
176 0 : reduce.udfType = 0;
177 0 : reduce.reduceDataType = repRead->GetDataType();
178 0 : reduce.reduceOpCode = repRead->GetOpType();
179 : }
180 1 : uint32_t channelId = channelImpl->GetChannelId();
181 1 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
182 1 : TransMem(instr++, repRead->GetLoc().addr.Id(), repRead->GetLoc().token.Id(), repRead->GetRem().addr.Id(), repRead->GetRem().token.Id(), repRead->GetLen().Id(),
183 2 : constValue2VarMap.at(channelId).Id(), notify, reduce, config, repRead->GetSem().Id(), repRead->GetMask());
184 :
185 1 : return HcclResult::HCCL_SUCCESS;
186 : }
187 :
188 0 : HcclResult CcuInsGeneratorV2::CcuRepRemMemTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepRemMem* repRemMem)
189 : {
190 0 : CHK_PTR_NULL(repRemMem);
191 0 : CcuUrmaChannel *channelImpl{nullptr};
192 0 : CHK_RET(GetUrmaChannel(repRemMem->GetChannel(), channelImpl));
193 :
194 0 : uint64_t addr{0};
195 0 : uint32_t size{0}, tokenId{0}, tokenValue{0};
196 0 : CHK_PRT_RET(channelImpl->GetRmtBuffer(addr, size, tokenId, tokenValue) != HcclResult::HCCL_SUCCESS,
197 : HCCL_ERROR("[CcuRepRemMem][%s] failed to get remote buffer, channelHandle[0x%llx].",
198 : __func__, repRemMem->GetChannel()), HCCL_E_INTERNAL);// 当前认为channel只持有一个buffer
199 :
200 0 : auto tokenInfo = GetToken(tokenId, tokenValue, 1);
201 :
202 0 : CcuV2::LoadImdToXn(instr++, repRemMem->GetRem().addr.Id(), addr);
203 0 : CcuV2::LoadImdToXn(instr++, repRemMem->GetRem().token.Id(), tokenInfo);
204 :
205 0 : return HcclResult::HCCL_SUCCESS;
206 : }
207 :
208 0 : HcclResult CcuInsGeneratorV2::CcuRepLocCpyTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepLocCpy* repLocCpy, const TransDep &dep)
209 : {
210 0 : CHK_PTR_NULL(repLocCpy);
211 0 : if (repLocCpy->GetReduceFlag() == 0 && repLocCpy->GetUseCcuBuffer() == true) {
212 0 : CcuV2::CacheConfig cacheConfig{0x0, 0x0};
213 0 : CcuV2::TransLocMemToLocMem(instr++, repLocCpy->GetDstAddrId(), repLocCpy->GetDstTokenId(),
214 0 : repLocCpy->GetSrcAddrId(), repLocCpy->GetSrcTokenId(), repLocCpy->GetLenId(),
215 0 : repLocCpy->GetFirstBufId(), repLocCpy->GetUsedBufNum(),
216 0 : repLocCpy->GetSemId(), repLocCpy->GetMask(), cacheConfig, cacheConfig);
217 : } else {
218 : // 使用旧接口或带规约场景,都走环回
219 0 : CcuV2::TransMemNotifyInfo notify = {};
220 0 : CcuV2::TransMemReduceInfo reduce = {};
221 0 : CcuV2::TransMemConfig config = {};
222 0 : config.dmaOpCode = URMA_DMA_OP_WRITE; // UB URMA WQEBB opcode: write
223 0 : if (repLocCpy->GetReduceFlag() == 1) {
224 0 : config.udfEnable = 1;
225 0 : reduce.udfType = 0;
226 0 : reduce.reduceDataType = repLocCpy->GetDataType();
227 0 : reduce.reduceOpCode = repLocCpy->GetOpType();
228 : }
229 0 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
230 0 : CcuV2::TransMem(instr++, repLocCpy->GetDstAddrId(), repLocCpy->GetDstTokenId(),
231 0 : repLocCpy->GetSrcAddrId(), repLocCpy->GetSrcTokenId(), repLocCpy->GetLenId(),
232 0 : constValue2VarMap.at(dep.reserveChannalId[0]).Id(), notify, reduce, config, repLocCpy->GetSemId(), repLocCpy->GetMask());
233 : }
234 :
235 0 : return HcclResult::HCCL_SUCCESS;
236 : }
237 :
238 0 : HcclResult CcuInsGeneratorV2::CcuRepBufWriteTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepBufWrite* ccuRepBufWrite, const TransDep &dep)
239 : {
240 0 : CHK_PTR_NULL(ccuRepBufWrite);
241 0 : CHK_PTR_NULL(ccuKernel);
242 0 : CcuV2::TransMemNotifyInfo notify = {};
243 0 : CcuV2::TransMemReduceInfo reduce = {};
244 0 : CcuV2::TransMemConfig config = {};
245 0 : config.dmaOpCode = URMA_DMA_OP_WRITE; // UB URMA WQEBB opcode: write
246 0 : config.src_mode = 0; // 不偏移
247 0 : config.dst_mode = 1; // 偏移 256K
248 0 : config.msIdMode = 1; // 使用msId模式
249 0 : CcuUrmaChannel *channelImpl{nullptr};
250 0 : CHK_RET(GetUrmaChannel(ccuRepBufWrite->GetChannel(), channelImpl));
251 :
252 0 : uint32_t channelId = channelImpl->GetChannelId();
253 0 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
254 :
255 0 : uint64_t rmtCcuResToken{};
256 0 : CHK_RET(GetRmtToken(channelImpl, rmtCcuResToken));
257 0 : notify.xntId = constValue2VarMap.at(rmtCcuResToken).Id();
258 0 : HCCL_INFO("DstTokenXnId[%u], NotifyTokenXnId[%u]", constValue2VarMap.at(dep.ccuResSpaceTokenInfo).Id(), notify.xntId);
259 0 : TransMem(instr++, ccuRepBufWrite->GetDst().addr.Id(), ccuRepBufWrite->GetDst().token.Id(),
260 0 : ccuRepBufWrite->GetSrc().Id(), constValue2VarMap.at(dep.ccuResSpaceTokenInfo).Id(),
261 0 : ccuRepBufWrite->GetLen().Id(), constValue2VarMap.at(channelId).Id(), notify, reduce, config,
262 0 : ccuRepBufWrite->GetSem().Id(), ccuRepBufWrite->GetMask());
263 :
264 0 : return HcclResult::HCCL_SUCCESS;
265 : }
266 :
267 2 : HcclResult CcuInsGeneratorV2::CcuRepBufReduceTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepBufReduce* ccuRepBufReduce)
268 : {
269 : UNUSED(ccuKernel);
270 2 : CHK_PTR_NULL(ccuRepBufReduce);
271 2 : if (ccuRepBufReduce->GetCount() > CCU_REDUCE_MAX_MS || ccuRepBufReduce->GetMem().size() > CCU_REDUCE_MAX_MS) {
272 0 : HCCL_ERROR("count and mem size must less than %u", CCU_REDUCE_MAX_MS);
273 0 : return HCCL_E_PARA;
274 : }
275 2 : if (ccuRepBufReduce->GetCount() < CCU_REDUCE_MIN_MS) {
276 0 : HCCL_ERROR("count must be at least %u", CCU_REDUCE_MIN_MS);
277 0 : return HCCL_E_PARA;
278 : }
279 :
280 2 : uint16_t msId[CCU_REDUCE_MAX_MS] = {0};
281 2 : const auto& mem = ccuRepBufReduce->GetMem();
282 6 : for (uint16_t i = 0; i < mem.size(); i++) {
283 4 : msId[i] = mem[i].Id();
284 : }
285 :
286 2 : if (ccuRepBufReduce->GetOpType() == CCU_REDUCE_SUM) {
287 2 : if (ccuRepBufReduce->GetOutputDataType() == 1) { // 1是fp16
288 2 : CcuV2::ReduceAdd(instr++, msId, ccuRepBufReduce->GetCount(), ccuRepBufReduce->GetOutputDataType(),
289 4 : ccuRepBufReduce->GetDataType(), ccuRepBufReduce->GetSem().Id(), ccuRepBufReduce->GetMask(),
290 4 : ccuRepBufReduce->GetXnIdLength().Id());
291 0 : } else if (ccuRepBufReduce->GetOutputDataType() == 2) { // 2是bf16
292 0 : CcuV2::ReduceAdd(instr++, msId, ccuRepBufReduce->GetCount(), ccuRepBufReduce->GetOutputDataType(),
293 0 : ccuRepBufReduce->GetDataType(), ccuRepBufReduce->GetSem().Id(), ccuRepBufReduce->GetMask(),
294 0 : ccuRepBufReduce->GetXnIdLength().Id());
295 : } else {
296 0 : CcuV2::ReduceAdd(instr++, msId, ccuRepBufReduce->GetCount(), 0, ccuRepBufReduce->GetDataType(),
297 0 : ccuRepBufReduce->GetSem().Id(), ccuRepBufReduce->GetMask(), ccuRepBufReduce->GetXnIdLength().Id());
298 : }
299 0 : } else if (ccuRepBufReduce->GetOpType() == CCU_REDUCE_MAX) {
300 0 : CcuV2::ReduceMax(instr++, msId, ccuRepBufReduce->GetCount(), ccuRepBufReduce->GetDataType(),
301 0 : ccuRepBufReduce->GetSem().Id(), ccuRepBufReduce->GetMask(), ccuRepBufReduce->GetXnIdLength().Id());
302 0 : } else if (ccuRepBufReduce->GetOpType() == CCU_REDUCE_MIN) {
303 0 : CcuV2::ReduceMin(instr++, msId, ccuRepBufReduce->GetCount(), ccuRepBufReduce->GetDataType(),
304 0 : ccuRepBufReduce->GetSem().Id(), ccuRepBufReduce->GetMask(), ccuRepBufReduce->GetXnIdLength().Id());
305 : } else {
306 0 : HCCL_ERROR("[CcuRepBufReduceTranslate] Unsupported opType[%d]", ccuRepBufReduce->GetOpType());
307 0 : return HCCL_E_PARA;
308 : }
309 :
310 2 : return HcclResult::HCCL_SUCCESS;
311 : }
312 :
313 1 : HcclResult CcuInsGeneratorV2::CcuRepLocRecordEventTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepLocRecordEvent* ccuRepLocRecordEvent)
314 : {
315 1 : CHK_PTR_NULL(ccuRepLocRecordEvent);
316 1 : CcuV2::SetCKE(instr++, ccuRepLocRecordEvent->GetEvent().Id(), ccuRepLocRecordEvent->GetMask(), 0, 0, 1);
317 :
318 1 : return HcclResult::HCCL_SUCCESS;
319 : }
320 :
321 7 : HcclResult CcuInsGeneratorV2::CcuRepLocWaitEventTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepLocWaitEvent* ccuRepLocWaitEvent)
322 : {
323 7 : CHK_PTR_NULL(ccuRepLocWaitEvent);
324 : // 需要profiling的使用SetCKEInstr, 否则使用ClearCKEInstr
325 7 : if (ccuRepLocWaitEvent->GetIsProfiling()) {
326 1 : CcuV2::SetCKE(instr++, 0, 0, ccuRepLocWaitEvent->GetEvent().Id(), ccuRepLocWaitEvent->GetMask(), 1);
327 : } else {
328 6 : CcuV2::ClearCKE(instr++, 0, 0, ccuRepLocWaitEvent->GetEvent().Id(), ccuRepLocWaitEvent->GetMask(), 1);
329 : }
330 :
331 7 : return HcclResult::HCCL_SUCCESS;
332 : }
333 :
334 0 : HcclResult CcuInsGeneratorV2::CcuRepLocWaitNotifyTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepLocWaitNotify* ccuRepLocWaitNotify)
335 : {
336 0 : CHK_PTR_NULL(ccuRepLocWaitNotify);
337 0 : if (ccuRepLocWaitNotify->GetIsProfiling()) {
338 0 : CcuV2::SetCKE(instr++, 0, 0, ccuRepLocWaitNotify->GetNotify().Id(), ccuRepLocWaitNotify->GetMask(), 1);
339 : } else {
340 0 : CcuV2::ClearCKE(instr++, 0, 0, ccuRepLocWaitNotify->GetNotify().Id(), ccuRepLocWaitNotify->GetMask(), 1);
341 : }
342 :
343 0 : return HcclResult::HCCL_SUCCESS;
344 : }
345 :
346 2 : HcclResult CcuInsGeneratorV2::CcuRepRemWaitSemTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepRemWaitSem* ccuRepRemWaitSem)
347 : {
348 2 : CHK_PTR_NULL(ccuRepRemWaitSem);
349 2 : CcuUrmaChannel *channelImpl{nullptr};
350 2 : CHK_RET(GetUrmaChannel(ccuRepRemWaitSem->GetChannel(), channelImpl));
351 :
352 2 : uint32_t locCkeId{0};
353 2 : CHK_PRT_RET(channelImpl->GetLocCkeByIndex(ccuRepRemWaitSem->GetSemIndex(), locCkeId) != HcclResult::HCCL_SUCCESS,
354 : HCCL_ERROR("[CcuRepRemWaitSem][%s] failed to get to loc cke id.", __func__), HCCL_E_INTERNAL);
355 :
356 : // 需要profiling的使用SetCKEInstr, 否则使用ClearCKEInstr
357 2 : if (ccuRepRemWaitSem->GetIsProfiling()) {
358 2 : CcuV2::SetCKE(instr++, 0, 0, locCkeId, ccuRepRemWaitSem->GetMask(), 1);
359 : } else {
360 0 : CcuV2::ClearCKE(instr++, 0, 0, locCkeId, ccuRepRemWaitSem->GetMask(), 1);
361 : }
362 :
363 2 : return HcclResult::HCCL_SUCCESS;
364 : }
365 :
366 3 : HcclResult CcuInsGeneratorV2::CcuRepRemPostVarTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepRemPostVar* ccuRepRemPostVar)
367 : {
368 3 : CHK_PTR_NULL(ccuRepRemPostVar);
369 3 : CHK_PTR_NULL(ccuKernel);
370 3 : CcuUrmaChannel *channelImpl{nullptr};
371 3 : CHK_RET(GetUrmaChannel(ccuRepRemPostVar->GetChannel(), channelImpl));
372 :
373 3 : uint32_t channelId = channelImpl->GetChannelId();
374 3 : uint64_t rmtSignalAddr{0};
375 3 : uint64_t rmtVarAddr{0};
376 3 : CHK_PRT_RET(channelImpl->GetRmtSignalAddrByIndex(ccuRepRemPostVar->GetSemIndex(), rmtSignalAddr) != HcclResult::HCCL_SUCCESS,
377 : HCCL_ERROR("[CcuInsGeneratorV2][%s] failed to get remote signal addr, channelHandle[0x%llx].",
378 : __func__, ccuRepRemPostVar->GetChannel()), HCCL_E_INTERNAL);
379 3 : CHK_PRT_RET(channelImpl->GetRmtVarAddrByIndex(ccuRepRemPostVar->GetParamIndex(), rmtVarAddr) != HcclResult::HCCL_SUCCESS,
380 : HCCL_ERROR("[CcuInsGeneratorV2][%s] failed to get remote var addr, channelHandle[0x%llx].",
381 : __func__, ccuRepRemPostVar->GetChannel()), HCCL_E_INTERNAL);
382 3 : uint64_t rmtToken{};
383 3 : CHK_RET(GetRmtToken(channelImpl, rmtToken));
384 :
385 3 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
386 3 : CcuV2::TransMemNotifyInfo notify = {0};
387 3 : notify.xnId = constValue2VarMap.at(rmtSignalAddr).Id();
388 3 : notify.xntId = constValue2VarMap.at(rmtToken).Id();
389 3 : notify.value = ccuRepRemPostVar->GetMask();
390 :
391 3 : SyncWtX(instr++, constValue2VarMap.at(rmtVarAddr).Id(), constValue2VarMap.at(rmtToken).Id(),
392 6 : ccuRepRemPostVar->GetParam().Id(), constValue2VarMap.at(channelId).Id(), notify, 0, 0);
393 :
394 3 : return HcclResult::HCCL_SUCCESS;
395 : }
396 :
397 1 : HcclResult CcuInsGeneratorV2::CcuRepRemPostSemTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepRemPostSem* ccuRepRemPostSem, const TransDep &dep)
398 : {
399 1 : CHK_PTR_NULL(ccuRepRemPostSem);
400 1 : CHK_PTR_NULL(ccuKernel);
401 1 : CcuUrmaChannel *channelImpl{nullptr};
402 1 : CHK_RET(GetUrmaChannel(ccuRepRemPostSem->GetChannel(), channelImpl));
403 :
404 1 : uint64_t rmtSignalAddr{0};
405 1 : uint32_t channelId = channelImpl->GetChannelId();
406 1 : CHK_PRT_RET(channelImpl->GetRmtSignalAddrByIndex(ccuRepRemPostSem->GetSemIndex(), rmtSignalAddr) != HcclResult::HCCL_SUCCESS,
407 : HCCL_ERROR("[CcuInsGeneratorV2][%s] failed to get remote signal addr, channelHandle[0x%llx].",
408 : __func__, ccuRepRemPostSem->GetChannel()), HCCL_E_INTERNAL);
409 1 : uint64_t rmtToken{};
410 1 : CHK_RET(GetRmtToken(channelImpl, rmtToken));
411 :
412 1 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
413 1 : CcuV2::TransMemNotifyInfo notify = {0};
414 1 : notify.xnId = constValue2VarMap.at(rmtSignalAddr).Id();
415 1 : notify.xntId = constValue2VarMap.at(rmtToken).Id();
416 1 : notify.value = ccuRepRemPostSem->GetMask();
417 :
418 1 : CcuV2::SyncWtX(instr++, notify, constValue2VarMap.at(channelId).Id(), 0, 0);
419 :
420 1 : return HcclResult::HCCL_SUCCESS;
421 : }
422 :
423 : constexpr uint16_t CCU_RESOURCE_CKE_MASK_LENGTH = 2;
424 0 : HcclResult CcuInsGeneratorV2::CcuRepRecordSharedNotifyTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepRecordSharedNotify* ccuRepRecordSharedNotify, const TransDep &dep)
425 : {
426 0 : CHK_PTR_NULL(ccuRepRecordSharedNotify);
427 0 : CHK_PTR_NULL(ccuKernel);
428 0 : if (ccuRepRecordSharedNotify->GetNotify().DieId() != dep.dieId) {
429 : // 计算对端cke地址,对端Xn基地址 + 256K + (ccuRepRecordSharedNotify->GetNotify().Id() * 8)
430 0 : uint64_t ckeAddr = dep.xnBaseAddr[ccuRepRecordSharedNotify->GetNotify().DieId()] +
431 0 : CCU_RESOURCE_XN_V2_RESERVE_SIZE + (ccuRepRecordSharedNotify->GetNotify().Id() * CCU_RESOURCE_CKE_PER_SIZE);
432 0 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
433 0 : CcuV2::CacheConfig cacheConfig{0x0, 0x0};
434 0 : CcuV2::StoreXToMem(instr++,
435 0 : constValue2VarMap.at(ckeAddr).Id(), // 对端cke xn
436 0 : constValue2VarMap.at(dep.memTokenInfo).Id(), // 对端cke xn token
437 0 : constValue2VarMap.at(ccuRepRecordSharedNotify->GetMask()).Id(), // cke mask
438 0 : constValue2VarMap.at(CCU_RESOURCE_CKE_MASK_LENGTH).Id(), // cke mask,2字节
439 : cacheConfig,
440 0 : dep.commSignal, // store完成后同步的cke
441 : 1); // store完成后同步的cke mask
442 0 : CcuV2::SetCKE(instr++, 0, 0, dep.commSignal, 1, 1);
443 : } else {
444 0 : CcuV2::SetCKE(instr++, ccuRepRecordSharedNotify->GetNotify().Id(),
445 0 : ccuRepRecordSharedNotify->GetMask(), 0, 0, 1);
446 : }
447 :
448 0 : return HcclResult::HCCL_SUCCESS;
449 : }
450 :
451 62 : HcclResult CcuInsGeneratorV2::CcuRepAddTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepAdd* ccuRepAdd, const TransDep &dep)
452 : {
453 62 : HCCL_INFO("Use table-driven translate for add");
454 : UNUSED(dep);
455 62 : CHK_PTR_NULL(ccuRepAdd);
456 :
457 : // {isImmed, isSelf, dstVar, srcAVar, srcBAddr} — 按 AddSubType 枚举顺序
458 : static constexpr struct { bool isImmed; bool isSelf; bool dstVar; bool srcAVar; bool srcBAddr; } table[] = {
459 : {false, false, false, false, false}, // INVALID
460 : {false, false, false, false, false}, // ADDR_PLUS_VAR_TO_ADDR
461 : {false, false, false, false, true}, // ADDR_PLUS_ADDR_TO_ADDR
462 : {false, false, true, true, false}, // VAR_PLUS_VAR_TO_VAR
463 : {false, true, false, false, false}, // SELF_ADD_ADDRESS
464 : {false, true, true, true, false}, // SELF_ADD_VARIABLE
465 : {true, false, true, true, false}, // VAR_PLUS_IMMED_TO_VAR
466 : {true, false, false, false, false}, // ADDR_PLUS_IMMED_TO_ADDR
467 : {false, false, false, true, false}, // VAR_PLUS_VAR_TO_ADDR
468 : {true, true, false, false, false}, // SELF_ADD_IMMED_ADDRESS
469 : {true, true, true, true, false}, // SELF_ADD_IMMED_VARIABLE
470 : {true, false, false, true, false}, // VAR_PLUS_IMMED_TO_ADDR
471 : {true, false, true, false, false}, // ADDR_PLUS_IMMED_TO_VAR
472 : {false, false, true, false, true}, // ADDR_PLUS_ADDR_TO_VAR
473 : };
474 :
475 62 : auto idx = static_cast<size_t>(ccuRepAdd->GetSubType());
476 62 : if (idx == 0 || idx >= sizeof(table) / sizeof(table[0])) {
477 0 : HCCL_ERROR("Invalid AddSubType[%d]", idx);
478 0 : return HCCL_E_PARA;
479 : }
480 62 : const auto& info = table[idx];
481 :
482 62 : uint16_t srcAId = info.srcAVar ? ccuRepAdd->GetVarA().Id() : ccuRepAdd->GetAddrA().Id();
483 109 : uint16_t dstId = info.isSelf ? srcAId
484 109 : : (info.dstVar ? ccuRepAdd->GetVarC().Id() : ccuRepAdd->GetAddrC().Id());
485 :
486 62 : if (info.isImmed) {
487 5 : CcuV2::AddI(instr++, dstId, srcAId, ccuRepAdd->GetImmedB(), 0, 0);
488 : } else {
489 57 : uint16_t srcBId = info.srcBAddr ? ccuRepAdd->GetAddrB().Id() : ccuRepAdd->GetVarB().Id();
490 57 : CcuV2::Add(instr++, dstId, srcAId, srcBId, 0, 0);
491 : }
492 :
493 62 : return HcclResult::HCCL_SUCCESS;
494 : }
495 :
496 141 : HcclResult CcuInsGeneratorV2::CcuRepAssignTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepAssign* ccuRepAssign, const TransDep &dep)
497 : {
498 : UNUSED(dep);
499 141 : CHK_PTR_NULL(ccuRepAssign);
500 141 : switch (ccuRepAssign->GetSubType()) {
501 89 : case AssignSubType::IMD_TO_VARIABLE: {
502 89 : CcuV2::AssignI(instr++, ccuRepAssign->GetVarA().Id(), ccuRepAssign->GetImmed());
503 89 : break;
504 : }
505 2 : case AssignSubType::IMD_TO_ADDR: {
506 2 : CcuV2::AssignI(instr++, ccuRepAssign->GetAddrA().Id(), ccuRepAssign->GetImmed());
507 2 : break;
508 : }
509 5 : case AssignSubType::VAR_TO_ADDR: {
510 5 : CcuV2::Assign(instr++, ccuRepAssign->GetAddrA().Id(), ccuRepAssign->GetVarA().Id());
511 5 : break;
512 : }
513 16 : case AssignSubType::ADDR_TO_ADDR: {
514 16 : CcuV2::Assign(instr++, ccuRepAssign->GetAddrB().Id(), ccuRepAssign->GetAddrA().Id());
515 16 : break;
516 : }
517 29 : case AssignSubType::VAR_TO_VAR: {
518 29 : CcuV2::Assign(instr++, ccuRepAssign->GetVarB().Id(), ccuRepAssign->GetVarA().Id());
519 29 : break;
520 : }
521 0 : default: {
522 0 : HCCL_ERROR("Invalid Assign");
523 0 : return HCCL_E_PARA;
524 : }
525 : }
526 :
527 141 : return HcclResult::HCCL_SUCCESS;
528 : }
529 :
530 8 : HcclResult CcuInsGeneratorV2::CcuRepMulTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepMul* ccuRepMul)
531 : {
532 8 : CHK_PTR_NULL(ccuRepMul);
533 :
534 : // {isImmed, isSelf, dstVar, srcAVar, srcBAddr} — 按 MulSubType 枚举顺序
535 : static constexpr struct { bool isImmed; bool isSelf; bool dstVar; bool srcAVar; bool srcBAddr; } table[] = {
536 : {false, false, false, false, false}, // INVALID
537 : {false, false, true, true, false}, // VAR_MUL_VAR_TO_VAR
538 : {true, false, true, true, false}, // VAR_MUL_IMMED_TO_VAR
539 : {false, true, true, true, false}, // SELF_MUL_VAR_VARIABLE
540 : {true, true, true, true, false}, // SELF_MUL_IMMED_VARIABLE
541 : {false, false, false, true, false}, // VAR_MUL_VAR_TO_ADDR
542 : {false, false, false, true, true}, // VAR_MUL_ADDR_TO_ADDR
543 : {true, false, false, true, false}, // VAR_MUL_IMMED_TO_ADDR
544 : {true, false, false, false, false}, // ADDR_MUL_IMMED_TO_ADDR
545 : {false, true, false, false, false}, // SELF_MUL_VAR_ADDRESS
546 : {true, true, false, false, false}, // SELF_MUL_IMMED_ADDRESS
547 : {true, false, true, false, false}, // ADDR_MUL_IMMED_TO_VAR
548 : };
549 :
550 8 : auto idx = static_cast<size_t>(ccuRepMul->GetSubType());
551 8 : if (idx == 0 || idx >= sizeof(table) / sizeof(table[0])) {
552 0 : HCCL_ERROR("Invalid Mul");
553 0 : return HCCL_E_PARA;
554 : }
555 8 : const auto& info = table[idx];
556 :
557 8 : uint16_t srcAId = info.srcAVar ? ccuRepMul->GetVarA().Id() : ccuRepMul->GetAddrA().Id();
558 15 : uint16_t dstId = info.isSelf ? srcAId
559 15 : : (info.dstVar ? ccuRepMul->GetVarC().Id() : ccuRepMul->GetAddrC().Id());
560 :
561 8 : if (info.isImmed) {
562 3 : CcuV2::MulI(instr++, dstId, srcAId, ccuRepMul->GetImmedB(), 0, 0);
563 : } else {
564 5 : uint16_t srcBId = info.srcBAddr ? ccuRepMul->GetAddrB().Id() : ccuRepMul->GetVarB().Id();
565 5 : CcuV2::Mul(instr++, dstId, srcAId, srcBId, 0, 0);
566 : }
567 :
568 8 : return HcclResult::HCCL_SUCCESS;
569 : }
570 :
571 8 : HcclResult CcuInsGeneratorV2::CcuRepSubTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepSub* ccuRepSub)
572 : {
573 8 : CHK_PTR_NULL(ccuRepSub);
574 :
575 : // {isImmed, isSelf, dstVar, srcAVar, srcBAddr} — 按 MinusSubType 枚举顺序
576 : static constexpr struct { bool isImmed; bool isSelf; bool dstVar; bool srcAVar; bool srcBAddr; } table[] = {
577 : {false, false, false, false, false}, // INVALID
578 : {false, false, true, true, false}, // VAR_MINUS_VAR_TO_VAR
579 : {true, false, true, true, false}, // VAR_MINUS_IMMED_TO_VAR
580 : {false, true, true, true, false}, // SELF_SUB_VAR_VARIABLE
581 : {true, true, true, true, false}, // SELF_SUB_IMMED_VARIABLE
582 : {false, false, false, false, false}, // ADDR_MINUS_VAR_TO_ADDR
583 : {true, false, false, false, false}, // ADDR_MINUS_IMMED_TO_ADDR
584 : {false, true, false, false, false}, // SELF_SUB_VAR_ADDRESS
585 : {true, true, false, false, false}, // SELF_SUB_IMMED_ADDRESS
586 : {true, false, false, true, false}, // VAR_MINUS_IMMED_TO_ADDR
587 : {true, false, true, false, false}, // ADDR_MINUS_IMMED_TO_VAR
588 : };
589 :
590 8 : auto idx = static_cast<size_t>(ccuRepSub->GetSubType());
591 8 : if (idx == 0 || idx >= sizeof(table) / sizeof(table[0])) {
592 0 : HCCL_ERROR("Invalid Sub");
593 0 : return HCCL_E_PARA;
594 : }
595 8 : const auto& info = table[idx];
596 :
597 8 : uint16_t srcAId = info.srcAVar ? ccuRepSub->GetVarA().Id() : ccuRepSub->GetAddrA().Id();
598 15 : uint16_t dstId = info.isSelf ? srcAId
599 15 : : (info.dstVar ? ccuRepSub->GetVarC().Id() : ccuRepSub->GetAddrC().Id());
600 :
601 8 : if (info.isImmed) {
602 3 : CcuV2::SubI(instr++, dstId, srcAId, ccuRepSub->GetImmedB(), 0, 0);
603 : } else {
604 5 : uint16_t srcBId = info.srcBAddr ? ccuRepSub->GetAddrB().Id() : ccuRepSub->GetVarB().Id();
605 5 : CcuV2::Sub(instr++, dstId, srcAId, srcBId, 0, 0);
606 : }
607 :
608 8 : return HcclResult::HCCL_SUCCESS;
609 : }
610 :
611 2 : HcclResult CcuInsGeneratorV2::CcuRepAndTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepAnd* ccuRepAnd, const TransDep &dep)
612 : {
613 2 : CHK_PTR_NULL(ccuRepAnd);
614 2 : switch (ccuRepAnd->GetSubType()) {
615 2 : case AndSubType::VAR_AND_VAR_TO_VAR: {
616 2 : CcuV2::And(instr++, ccuRepAnd->GetVarC().Id(), ccuRepAnd->GetVarA().Id(), ccuRepAnd->GetVarB().Id(), 0, 0);
617 2 : break;
618 : }
619 0 : case AndSubType::SELF_AND_VAR_VARIABLE: {
620 0 : CcuV2::And(instr++, ccuRepAnd->GetVarC().Id(), ccuRepAnd->GetVarC().Id(), ccuRepAnd->GetVarB().Id(), 0, 0);
621 0 : break;
622 : }
623 0 : default: {
624 0 : HCCL_ERROR("Invalid And");
625 0 : return HCCL_E_PARA;
626 : }
627 : }
628 2 : return HcclResult::HCCL_SUCCESS;
629 : }
630 :
631 1 : HcclResult CcuInsGeneratorV2::CcuRepNotTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepNot* ccuRepNot, const TransDep &dep)
632 : {
633 1 : CHK_PTR_NULL(ccuRepNot);
634 1 : switch (ccuRepNot->GetSubType()) {
635 1 : case NotSubType::VAR_EQUALS_NOT_VAR: {
636 1 : CcuV2::Not(instr++, ccuRepNot->GetVarC().Id(), ccuRepNot->GetVarB().Id(), 0, 0);
637 1 : break;
638 : }
639 0 : default: {
640 0 : HCCL_ERROR("Invalid Not");
641 0 : return HCCL_E_PARA;
642 : }
643 : }
644 1 : return HcclResult::HCCL_SUCCESS;
645 : }
646 :
647 2 : HcclResult CcuInsGeneratorV2::CcuRepOrTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepOr* ccuRepOr, const TransDep &dep)
648 : {
649 2 : CHK_PTR_NULL(ccuRepOr);
650 2 : switch (ccuRepOr->GetSubType()) {
651 2 : case OrSubType::VAR_OR_VAR_TO_VAR: {
652 2 : CcuV2::Or(instr++, ccuRepOr->GetVarC().Id(), ccuRepOr->GetVarA().Id(), ccuRepOr->GetVarB().Id(), 0, 0);
653 2 : break;
654 : }
655 0 : case OrSubType::SELF_OR_VAR_VARIABLE: {
656 0 : CcuV2::Or(instr++, ccuRepOr->GetVarC().Id(), ccuRepOr->GetVarC().Id(), ccuRepOr->GetVarB().Id(), 0, 0);
657 0 : break;
658 : }
659 0 : default: {
660 0 : HCCL_ERROR("Invalid Or");
661 0 : return HCCL_E_PARA;
662 : }
663 : }
664 2 : return HcclResult::HCCL_SUCCESS;
665 : }
666 :
667 2 : HcclResult CcuInsGeneratorV2::CcuRepXorTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepXor* ccuRepXor, const TransDep &dep)
668 : {
669 2 : CHK_PTR_NULL(ccuRepXor);
670 2 : switch (ccuRepXor->GetSubType()) {
671 2 : case XorSubType::VAR_XOR_VAR_TO_VAR: {
672 2 : CcuV2::Xor(instr++, ccuRepXor->GetVarC().Id(), ccuRepXor->GetVarA().Id(), ccuRepXor->GetVarB().Id(), 0, 0);
673 2 : break;
674 : }
675 0 : case XorSubType::SELF_XOR_VAR_VARIABLE: {
676 0 : CcuV2::Xor(instr++, ccuRepXor->GetVarC().Id(), ccuRepXor->GetVarC().Id(), ccuRepXor->GetVarB().Id(), 0, 0);
677 0 : break;
678 : }
679 0 : default: {
680 0 : HCCL_ERROR("Invalid Xor");
681 0 : return HCCL_E_PARA;
682 : }
683 : }
684 2 : return HcclResult::HCCL_SUCCESS;
685 : }
686 :
687 4 : HcclResult CcuInsGeneratorV2::CcuRepShLTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepShL* ccuRepShL, const TransDep &dep)
688 : {
689 4 : CHK_PTR_NULL(ccuRepShL);
690 4 : if (ccuRepShL->GetShiftType() == ShiftType::LOGICAL_SHIFT) {
691 4 : switch (ccuRepShL->GetShiftSubType()) {
692 1 : case ShiftSubType::VAR_EQUALS_VAR_SHIFT_VAR: {
693 1 : CcuV2::SLL(instr++, ccuRepShL->GetVarD().Id(), ccuRepShL->GetVarN().Id(), ccuRepShL->GetVarM().Id(), 0, 0);
694 1 : break;
695 : }
696 1 : case ShiftSubType::VAR_SHIFT_ASSIGN_VAR: {
697 1 : CcuV2::SLL(instr++, ccuRepShL->GetVarD().Id(), ccuRepShL->GetVarD().Id(), ccuRepShL->GetVarM().Id(), 0, 0);
698 1 : break;
699 : }
700 1 : case ShiftSubType::ADDR_EQUALS_VAR_SHIFT_VAR: {
701 1 : CcuV2::SLL(instr++, ccuRepShL->GetAddressD().Id(), ccuRepShL->GetVarN().Id(), ccuRepShL->GetVarM().Id(), 0, 0);
702 1 : break;
703 : }
704 1 : case ShiftSubType::ADDR_SHIFT_ASSIGN_VAR: {
705 1 : CcuV2::SLL(instr++, ccuRepShL->GetAddressD().Id(), ccuRepShL->GetAddressD().Id(), ccuRepShL->GetVarM().Id(), 0, 0);
706 1 : break;
707 : }
708 0 : default: {
709 0 : HCCL_ERROR("Invalid Shift left");
710 0 : return HCCL_E_PARA;
711 : }
712 : }
713 : } else {
714 0 : HCCL_ERROR("Invalid Shift");
715 0 : return HCCL_E_PARA;
716 : }
717 4 : return HcclResult::HCCL_SUCCESS;
718 : }
719 :
720 4 : HcclResult CcuInsGeneratorV2::CcuRepShRTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, CcuRepShR* ccuRepShR, const TransDep &dep)
721 : {
722 4 : CHK_PTR_NULL(ccuRepShR);
723 4 : if (ccuRepShR->GetShiftType() == ShiftType::LOGICAL_SHIFT) {
724 4 : switch (ccuRepShR->GetShiftSubType()) {
725 1 : case ShiftSubType::VAR_EQUALS_VAR_SHIFT_VAR: {
726 1 : CcuV2::SRL(instr++, ccuRepShR->GetVarD().Id(), ccuRepShR->GetVarN().Id(), ccuRepShR->GetVarM().Id(), 0, 0);
727 1 : break;
728 : }
729 1 : case ShiftSubType::VAR_SHIFT_ASSIGN_VAR: {
730 1 : CcuV2::SRL(instr++, ccuRepShR->GetVarD().Id(), ccuRepShR->GetVarD().Id(), ccuRepShR->GetVarM().Id(), 0, 0);
731 1 : break;
732 : }
733 1 : case ShiftSubType::ADDR_EQUALS_VAR_SHIFT_VAR: {
734 1 : CcuV2::SRL(instr++, ccuRepShR->GetAddressD().Id(), ccuRepShR->GetVarN().Id(), ccuRepShR->GetVarM().Id(), 0, 0);
735 1 : break;
736 : }
737 1 : case ShiftSubType::ADDR_SHIFT_ASSIGN_VAR: {
738 1 : CcuV2::SRL(instr++, ccuRepShR->GetAddressD().Id(), ccuRepShR->GetAddressD().Id(), ccuRepShR->GetVarM().Id(), 0, 0);
739 1 : break;
740 : }
741 0 : default: {
742 0 : HCCL_ERROR("Invalid Shift right");
743 0 : return HCCL_E_PARA;
744 : }
745 : }
746 : } else {
747 0 : HCCL_ERROR("Invalid Shift");
748 0 : return HCCL_E_PARA;
749 : }
750 4 : return HcclResult::HCCL_SUCCESS;
751 : }
752 :
753 0 : HcclResult CcuInsGeneratorV2::CcuRepFuncBlockTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId,
754 : CcuRepFuncBlock* funcBlockPtr, const TransDep &dep, uint32_t step)
755 : {
756 0 : CHK_PTR_NULL(funcBlockPtr);
757 0 : std::vector<CcuRepArg>& inArgs = funcBlockPtr->GetInArgs();
758 : (void)inArgs;
759 0 : std::vector<CcuRepArg>& outArgs = funcBlockPtr->GetOutArgs();
760 0 : CcuRepReferenceManager* funcManager = funcBlockPtr->GetFuncManager();
761 0 : CHK_PTR_NULL(funcManager);
762 0 : uint16_t callLayer = funcBlockPtr->GetCallLayer();
763 0 : if (step == 0) {
764 : // 函数入口为nop
765 0 : CcuV2::Nop(instr++);
766 0 : curInstrId++;
767 0 : } else if (step == 1) {
768 : // 处理输出的参数
769 0 : uint32_t iOutArg = 0;
770 0 : const auto& funcOut = funcManager->GetFuncOut();
771 0 : if (iOutArg >= funcOut.size()) {
772 0 : HCCL_ERROR("[FuncBlock] out arg index %u >= funcOut size %zu", iOutArg, funcOut.size());
773 0 : return HCCL_E_PARA;
774 : }
775 0 : for (uint32_t i = 0; i < outArgs.size(); i++) {
776 0 : if (outArgs[i].type == CcuArgType::VARIABLE) {
777 0 : CcuV2::Add(instr++, funcOut[iOutArg++].Id(), outArgs[i].var.Id(), dep.reserveXnId);
778 0 : curInstrId++;
779 0 : } else if (outArgs[i].type == CcuArgType::VARIABLE_LIST) {
780 0 : for (uint32_t j = 0; j < outArgs[i].varList.size(); j++) {
781 0 : CcuV2::Add(instr++, funcOut[iOutArg++].Id(), outArgs[i].varList[j].Id(), dep.reserveXnId);
782 0 : curInstrId++;
783 : }
784 : }
785 : }
786 :
787 : // 返回调用处
788 0 : uint32_t relJmpInstrNum = REL_JMP_INSTR_NUM; // relJmp需要9条指令
789 0 : CcuV2::RelJmp(instr, funcManager->GetFuncRet(callLayer).Id(), curInstrId + relJmpInstrNum, dep.commXn[0], dep.commXn[1]);
790 0 : instr += relJmpInstrNum;
791 0 : curInstrId += relJmpInstrNum;
792 0 : CcuV2::Jump(instr++, funcManager->GetFuncRet(callLayer).Id(), dep.reserveXnId, dep.reserveXnId, 0);
793 0 : curInstrId++;
794 : } else {
795 0 : HCCL_ERROR("Unsupported step[%d] for CcuRepFuncBlockTranslate", step);
796 0 : return HCCL_E_PARA;
797 : }
798 0 : return HcclResult::HCCL_SUCCESS;
799 : }
800 :
801 0 : void CcuInsGeneratorV2::LoadFuncCallInArgs(CcuInstr* instr, std::vector<CcuRepArg>& inArgs,
802 : std::vector<Variable>& formalIns, uint16_t reserveXnId)
803 : {
804 0 : uint32_t idx = 0;
805 0 : for (uint32_t i = 0; i < inArgs.size(); i++) {
806 0 : if (inArgs[i].type == CcuArgType::VARIABLE) {
807 0 : CcuV2::Add(instr + idx, formalIns[idx].Id(), inArgs[i].var.Id(), reserveXnId);
808 0 : idx++;
809 0 : } else if (inArgs[i].type == CcuArgType::VARIABLE_LIST) {
810 0 : for (uint32_t j = 0; j < inArgs[i].varList.size(); j++) {
811 0 : CcuV2::Add(instr + idx, formalIns[idx].Id(), inArgs[i].varList[j].Id(), reserveXnId);
812 0 : idx++;
813 : }
814 : }
815 : }
816 0 : }
817 :
818 0 : void CcuInsGeneratorV2::LoadFuncCallOutArgs(CcuInstr* instr, uint32_t offset, std::vector<CcuRepArg>& outArgs,
819 : CcuRepReferenceManager* funcManager, uint16_t reserveXnId)
820 : {
821 0 : uint32_t idx = 0;
822 0 : for (uint32_t i = 0; i < outArgs.size(); i++) {
823 0 : if (outArgs[i].type == CcuArgType::VARIABLE) {
824 0 : CcuV2::Add(instr + offset + idx, outArgs[i].var.Id(), funcManager->GetFuncOut()[idx].Id(), reserveXnId);
825 0 : idx++;
826 0 : } else if (outArgs[i].type == CcuArgType::VARIABLE_LIST) {
827 0 : for (uint32_t j = 0; j < outArgs[i].varList.size(); j++) {
828 0 : CcuV2::Add(instr + offset + idx, outArgs[i].varList[j].Id(), funcManager->GetFuncOut()[idx].Id(),
829 : reserveXnId);
830 0 : idx++;
831 : }
832 : }
833 : }
834 0 : }
835 :
836 0 : HcclResult CcuInsGeneratorV2::CcuRepFuncCallTranslate(CcuKernel* ccuKernel, CcuInstr *&curInstr, uint16_t &curInstrId,
837 : CcuRepFuncCall* funcCallPtr, const TransDep &dep)
838 : {
839 : (void)curInstr;
840 : (void)curInstrId;
841 :
842 0 : FuncCallContext ctx;
843 0 : CHK_RET(PrepareFuncCallContext(funcCallPtr, ctx));
844 :
845 0 : std::vector<CcuRepArg>& inArgs = funcCallPtr->GetInArgs();
846 0 : std::vector<CcuRepArg>& outArgs = funcCallPtr->GetOutArgs();
847 0 : uint32_t inArgCount = ctx.inArgCount;
848 0 : CcuRepReferenceManager* funcManager = ctx.funcManager;
849 0 : std::shared_ptr<CcuRepFuncBlock>& funcBlock = ctx.funcBlock;
850 0 : CcuInstr* instr = ctx.instr;
851 0 : std::vector<Variable>& formalIns = ctx.formalIns;
852 0 : Variable funcAddrVar = funcCallPtr->GetFuncAddrVar();
853 0 : int32_t callLayer = funcCallPtr->GetCallLayer();
854 0 : uint16_t instrId = funcCallPtr->StartInstrId();
855 0 : LoadFuncCallInArgs(instr, inArgs, formalIns, dep.reserveXnId);
856 :
857 0 : uint32_t locId = 0;
858 0 : if (funcBlock != nullptr) {
859 0 : CcuV2::LoadImdToXn(instr + inArgCount + locId++, funcManager->GetFuncCall().Id(), funcBlock->StartInstrId());
860 : } else {
861 0 : CcuV2::Add(instr + inArgCount + locId++, funcManager->GetFuncCall().Id(), funcAddrVar.Id(), dep.reserveXnId);
862 : }
863 0 : CcuV2::LoadImdToXn(instr + inArgCount + locId++, funcManager->GetFuncRet(callLayer).Id(),
864 0 : instrId + inArgCount + FUNC_CALL_RET_OFFSET); // 需要指向函数返回位置
865 0 : CcuV2::RelJmp(instr + inArgCount + locId, funcManager->GetFuncCall().Id(),
866 0 : instrId + inArgCount + FUNC_CALL_JMP_OFFSET, // Jmp的目标指令为其后11条指令
867 0 : dep.commXn[0], dep.commXn[1]);
868 0 : locId += REL_JMP_INSTR_NUM; // relJmp需要9条指令
869 0 : CcuV2::Jump(instr + inArgCount + locId++, funcManager->GetFuncCall().Id(), dep.reserveXnId, dep.reserveXnId, 0);
870 0 : CcuV2::Nop(instr + inArgCount + locId++);
871 :
872 0 : uint32_t extraInstrNum = GetInstrCount(funcCallPtr->Type());
873 0 : LoadFuncCallOutArgs(instr, inArgCount + extraInstrNum, outArgs, funcManager, dep.reserveXnId);
874 0 : return HcclResult::HCCL_SUCCESS;
875 0 : }
876 :
877 39 : uint32_t GetRelativeInstrId(uint32_t currentInstrId, uint32_t targetInstrId)
878 : {
879 : static constexpr uint32_t CCU_INSTR_ID_SPACE_SIZE = 0x10000;
880 39 : if (targetInstrId > currentInstrId) {
881 29 : return targetInstrId - currentInstrId;
882 : } else {
883 10 : uint32_t diff = currentInstrId - targetInstrId;
884 10 : if (diff >= CCU_INSTR_ID_SPACE_SIZE) {
885 0 : HCCL_ERROR("Jump distance %u exceeds instr id space %u", diff, CCU_INSTR_ID_SPACE_SIZE);
886 0 : return 0;
887 : }
888 10 : return CCU_INSTR_ID_SPACE_SIZE - diff;
889 : }
890 : }
891 :
892 4 : HcclResult CcuInsGeneratorV2::CcuRepJumpTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepJump* jumpPtr, const TransDep &dep)
893 : {
894 : (void)instr;
895 : (void)curInstrId;
896 : (void)dep;
897 : // 翻译直接跳转指令
898 4 : CHK_PTR_NULL(jumpPtr);
899 4 : std::shared_ptr<CcuRepJumpLabel> jumpLabel = jumpPtr->GetJumpLabel();
900 4 : CHK_PTR_NULL(jumpLabel);
901 4 : uint16_t instrIdOffset = GetRelativeInstrId(jumpPtr->StartInstrId() + 1, jumpLabel->StartInstrId());
902 4 : CcuV2::LoadImdToXn(jumpPtr->GetInstr() + 0, jumpPtr->GetTargetInstrId().Id(), instrIdOffset, 0, 0);
903 : // 无条件跳转
904 4 : CcuV2::Jump(jumpPtr->GetInstr() + 1, jumpPtr->GetTargetInstrId().Id(), 0, 0, static_cast<int>(ConditionType::DEFAULT));
905 :
906 4 : return HcclResult::HCCL_SUCCESS;
907 4 : }
908 :
909 17 : HcclResult CcuInsGeneratorV2::CcuRepJumpTranslateV2Base(CcuInstr *&curInstr, uint16_t &curInstrId, CcuRepJumpBase* jumpBasePtr,
910 : uint64_t expected, const Variable &condition, const Variable &expectedVar,
911 : ConditionType condType)
912 : {
913 : (void)curInstr;
914 : (void)curInstrId;
915 17 : CHK_PTR_NULL(jumpBasePtr);
916 17 : CcuInstr* instr = jumpBasePtr->GetInstr();
917 17 : uint16_t instrId = jumpBasePtr->StartInstrId();
918 17 : Variable& targetInstrId = jumpBasePtr->GetTargetInstrId();
919 17 : std::shared_ptr<CcuRepJumpLabel> jumpLabel = jumpBasePtr->GetJumpLabel();
920 17 : CHK_PTR_NULL(jumpLabel);
921 :
922 17 : if (jumpBasePtr->IsComparedWithImmd()) {
923 12 : CcuV2::LoadImdToXn(instr + 0, expectedVar.Id(), expected, 0, 0);
924 12 : uint16_t instrIdOffset = GetRelativeInstrId(instrId + 2, jumpLabel->StartInstrId()); // 2: jump指令偏移
925 12 : CcuV2::LoadImdToXn(instr + 1, targetInstrId.Id(), instrIdOffset, 0, 0);
926 12 : CcuV2::Jump(instr + 2, targetInstrId.Id(), condition.Id(), expectedVar.Id(), // 2: jump指令偏移
927 : static_cast<int>(condType));
928 : } else {
929 5 : uint16_t instrIdOffset = GetRelativeInstrId(instrId + 1, jumpLabel->StartInstrId());
930 5 : CcuV2::LoadImdToXn(instr + 0, targetInstrId.Id(), instrIdOffset, 0, 0);
931 5 : CcuV2::Jump(instr + 1, targetInstrId.Id(), condition.Id(), expectedVar.Id(), static_cast<int>(condType));
932 : }
933 :
934 17 : return HcclResult::HCCL_SUCCESS;
935 17 : }
936 :
937 4 : HcclResult CcuInsGeneratorV2::CcuRepJumpNETranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepJumpNE* jumpNEPtr, const TransDep &dep)
938 : {
939 : (void)dep;
940 4 : CHK_PTR_NULL(jumpNEPtr);
941 4 : return CcuRepJumpTranslateV2Base(instr, curInstrId, jumpNEPtr, jumpNEPtr->GetExpectedNum(), jumpNEPtr->GetCondition(),
942 8 : jumpNEPtr->GetExpectedVar(), ConditionType::NOT_EQUAL);
943 : }
944 :
945 3 : HcclResult CcuInsGeneratorV2::CcuRepJumpEQTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepJumpEQ* jumpEQPtr, const TransDep &dep)
946 : {
947 : (void)dep;
948 3 : CHK_PTR_NULL(jumpEQPtr);
949 3 : return CcuRepJumpTranslateV2Base(instr, curInstrId, jumpEQPtr, jumpEQPtr->GetExpectedNum(), jumpEQPtr->GetCondition(),
950 6 : jumpEQPtr->GetExpectedVar(), ConditionType::EQUAL);
951 : }
952 :
953 2 : HcclResult CcuInsGeneratorV2::CcuRepJumpLETranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepJumpLE* jumpLEPtr, const TransDep &dep)
954 : {
955 : (void)dep;
956 2 : CHK_PTR_NULL(jumpLEPtr);
957 2 : return CcuRepJumpTranslateV2Base(instr, curInstrId, jumpLEPtr, jumpLEPtr->GetExpectedNum(), jumpLEPtr->GetCondition(),
958 4 : jumpLEPtr->GetExpectedVar(), ConditionType::LESS_EQUAL);
959 : }
960 :
961 4 : HcclResult CcuInsGeneratorV2::CcuRepJumpGETranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepJumpGE* jumpGEPtr, const TransDep &dep)
962 : {
963 : (void)dep;
964 4 : CHK_PTR_NULL(jumpGEPtr);
965 4 : return CcuRepJumpTranslateV2Base(instr, curInstrId, jumpGEPtr, jumpGEPtr->GetExpectedNum(), jumpGEPtr->GetCondition(),
966 8 : jumpGEPtr->GetExpectedVar(), ConditionType::GREATER_EQUAL);
967 : }
968 :
969 1 : HcclResult CcuInsGeneratorV2::CcuRepJumpGTTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepJumpGT* jumpGTPtr, const TransDep &dep)
970 : {
971 : (void)dep;
972 1 : CHK_PTR_NULL(jumpGTPtr);
973 1 : return CcuRepJumpTranslateV2Base(instr, curInstrId, jumpGTPtr, jumpGTPtr->GetExpectedNum(), jumpGTPtr->GetCondition(),
974 2 : jumpGTPtr->GetExpectedVar(), ConditionType::GREATER_THAN);
975 : }
976 :
977 3 : HcclResult CcuInsGeneratorV2::CcuRepJumpLTTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepJumpLT* jumpLTPtr, const TransDep &dep)
978 : {
979 : (void)dep;
980 3 : CHK_PTR_NULL(jumpLTPtr);
981 3 : return CcuRepJumpTranslateV2Base(instr, curInstrId, jumpLTPtr, jumpLTPtr->GetExpectedNum(), jumpLTPtr->GetCondition(),
982 6 : jumpLTPtr->GetExpectedVar(), ConditionType::LESS_THAN);
983 : }
984 :
985 :
986 0 : HcclResult CcuInsGeneratorV2::CcuRepLoopTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepLoop* loopPtr)
987 : {
988 : (void)curInstrId;
989 0 : CHK_PTR_NULL(loopPtr);
990 0 : auto loopBlock = loopPtr->GetLoopBlock();
991 0 : CHK_PTR_NULL(loopBlock);
992 0 : CcuV2::Loop(instr++, loopBlock->StartInstrId(), loopBlock->StartInstrId() + loopBlock->InstrCount() - 1,
993 0 : loopPtr->GetLoopIterNum().Id(), loopPtr->GetLoopGsaOffset().Id(), loopPtr->GetLoopParam()->Id());
994 0 : return HcclResult::HCCL_SUCCESS;
995 : }
996 :
997 0 : HcclResult CcuInsGeneratorV2::LoadLoopCallArg(CcuInstr*& instr, const CcuRepArg& inArg, const CcuRepArg& blkArg)
998 : {
999 0 : switch (inArg.type) {
1000 0 : case CcuArgType::VARIABLE:
1001 0 : CcuV2::Assign(instr++, blkArg.var.Id(), inArg.var.Id());
1002 0 : break;
1003 0 : case CcuArgType::VARIABLE_LIST:
1004 0 : if (inArg.varList.size() != blkArg.varList.size()) {
1005 0 : HCCL_ERROR("Mismatched Arg Size");
1006 0 : return HCCL_E_PARA;
1007 : }
1008 0 : for (uint32_t j = 0; j < inArg.varList.size(); j++) {
1009 0 : CcuV2::Assign(instr++, blkArg.varList[j].Id(), inArg.varList[j].Id());
1010 : }
1011 0 : break;
1012 0 : case CcuArgType::MEMORY:
1013 0 : LoadAddrArg(instr, blkArg.mem, inArg.mem);
1014 0 : break;
1015 0 : case CcuArgType::LOCAL_ADDR:
1016 0 : LoadAddrArg(instr, blkArg.localAddr, inArg.localAddr);
1017 0 : break;
1018 0 : case CcuArgType::REMOTE_ADDR:
1019 0 : LoadAddrArg(instr, blkArg.remoteAddr, inArg.remoteAddr);
1020 0 : break;
1021 0 : case CcuArgType::MEMORY_LIST:
1022 0 : CHK_RET(LoadAddrListArg(instr, blkArg.memList, inArg.memList));
1023 0 : break;
1024 0 : case CcuArgType::LOCAL_ADDR_LIST:
1025 0 : CHK_RET(LoadAddrListArg(instr, blkArg.localAddrList, inArg.localAddrList));
1026 0 : break;
1027 0 : case CcuArgType::REMOTE_ADDR_LIST:
1028 0 : CHK_RET(LoadAddrListArg(instr, blkArg.remoteAddrList, inArg.remoteAddrList));
1029 0 : break;
1030 0 : default:
1031 0 : HCCL_ERROR("Mismatched Arg Type");
1032 0 : return HCCL_E_PARA;
1033 : }
1034 0 : return HcclResult::HCCL_SUCCESS;
1035 : }
1036 :
1037 0 : HcclResult CcuInsGeneratorV2::CcuRepLoopCallTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepLoopCall* loopCallPtr, const TransDep &dep)
1038 : {
1039 : (void)curInstrId;
1040 : (void)dep;
1041 0 : CHK_PTR_NULL(loopCallPtr);
1042 0 : std::vector<CcuRepArg> &inArgs = loopCallPtr->GetInArgs();
1043 0 : auto loopBlock = loopCallPtr->GetLoopBlock();
1044 0 : CHK_PTR_NULL(loopBlock);
1045 :
1046 0 : for (uint32_t i = 0; i < inArgs.size(); i++) {
1047 0 : const CcuRepArg& inArg = inArgs[i];
1048 0 : const CcuRepArg& blkArg = loopBlock->GetArg(i);
1049 0 : if (inArg.type != blkArg.type) {
1050 0 : HCCL_ERROR("Mismatched Arg Type");
1051 0 : return HCCL_E_PARA;
1052 : }
1053 0 : CHK_RET(LoadLoopCallArg(instr, inArg, blkArg));
1054 : }
1055 :
1056 0 : return HcclResult::HCCL_SUCCESS;
1057 0 : }
1058 :
1059 0 : HcclResult CcuInsGeneratorV2::CcuRepSetLoopTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepSetLoop* setLoopPtr)
1060 : {
1061 : (void)curInstrId;
1062 0 : CHK_PTR_NULL(setLoopPtr);
1063 : // CCU V121 将executorId赋值给loop指令的Xp,上层计算的loopContextId实际上没有用
1064 0 : CcuV2::LoadImdToXn(instr++, setLoopPtr->loopParam.Id(), setLoopPtr->executor.Id());
1065 0 : return HcclResult::HCCL_SUCCESS;
1066 : }
1067 :
1068 :
1069 0 : HcclResult CcuInsGeneratorV2::CcuRepLoadTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepLoad* loadPtr, const TransDep &dep)
1070 : {
1071 : (void)curInstrId;
1072 0 : CHK_PTR_NULL(loadPtr);
1073 0 : CHK_PTR_NULL(ccuKernel);
1074 0 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
1075 0 : CcuV2::CacheConfig cacheConfig{0x0, 0x0};
1076 :
1077 : // var寄存器的真实id在常量准备阶段(Register)无法获取,故不记录在常量表中,单独赋值处理
1078 0 : CcuV2::LoadImdToXn(instr++, dep.commXn[0], loadPtr->GetVar().Id()); // dst xn id
1079 0 : CcuV2::LoadXFromMem(instr++,
1080 0 : dep.commXn[0],
1081 0 : constValue2VarMap.at(loadPtr->GetAddr()).Id(),
1082 0 : constValue2VarMap.at(dep.memTokenInfo).Id(),
1083 0 : constValue2VarMap.at(CCU_RESOURCE_XN_PER_SIZE * loadPtr->GetNum()).Id(),
1084 0 : cacheConfig, dep.commSignal, loadPtr->GetMask());
1085 0 : CcuV2::SetCKE(instr++, 0, 0, dep.commSignal, loadPtr->GetMask(), 1);
1086 :
1087 0 : return HcclResult::HCCL_SUCCESS;
1088 : }
1089 :
1090 0 : HcclResult CcuInsGeneratorV2::CcuRepLoadVarTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepLoadVar* loadVarPtr, const TransDep &dep)
1091 : {
1092 : (void)curInstrId;
1093 0 : CHK_PTR_NULL(loadVarPtr);
1094 0 : CHK_PTR_NULL(ccuKernel);
1095 0 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
1096 0 : CcuV2::CacheConfig cacheConfig{0x0, 0x0};
1097 :
1098 : // var寄存器的真实id在常量准备阶段(Register)无法获取,故不记录在常量表中,单独赋值处理
1099 0 : CcuV2::LoadImdToXn(instr++, dep.commXn[0], loadVarPtr->GetVar().Id()); // dst xn id
1100 0 : CcuV2::LoadXFromMem(instr++,
1101 0 : dep.commXn[0],
1102 0 : loadVarPtr->GetSrc().Id(),
1103 0 : constValue2VarMap.at(dep.memTokenInfo).Id(),
1104 0 : constValue2VarMap.at(CCU_RESOURCE_XN_PER_SIZE * loadVarPtr->GetNum()).Id(),
1105 0 : cacheConfig, dep.commSignal, loadVarPtr->GetMask());
1106 0 : CcuV2::SetCKE(instr++, 0, 0, dep.commSignal, loadVarPtr->GetMask(), 1);
1107 0 : return HcclResult::HCCL_SUCCESS;
1108 : }
1109 :
1110 15 : HcclResult CcuInsGeneratorV2::CcuRepLoadArgTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepLoadArg* loadArgPtr, const TransDep &dep)
1111 : {
1112 : (void)curInstrId;
1113 15 : CHK_PTR_NULL(loadArgPtr);
1114 15 : if (dep.isFuncBlock) {
1115 : // Xn(var) = Xn(loadXnId) + 0
1116 0 : CcuV2::Add(instr++, loadArgPtr->GetVar().Id(), dep.loadXnId, dep.reserveXnId);
1117 : } else {
1118 15 : CcuV2::LoadSqeArgsToX(instr++, loadArgPtr->GetVar().Id(), loadArgPtr->GetArgId());
1119 : }
1120 :
1121 15 : return HcclResult::HCCL_SUCCESS;
1122 : }
1123 :
1124 21 : HcclResult CcuInsGeneratorV2::CcuRepNopTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepNop* nopPtr, const TransDep &dep)
1125 : {
1126 : (void)curInstrId;
1127 : (void)nopPtr;
1128 : (void)dep;
1129 21 : CcuV2::Nop(instr++);
1130 :
1131 21 : return HcclResult::HCCL_SUCCESS;
1132 : }
1133 :
1134 0 : HcclResult CcuInsGeneratorV2::CcuRepStoreTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepStore* storePtr, const TransDep &dep)
1135 : {
1136 : (void)curInstrId;
1137 0 : CHK_PTR_NULL(storePtr);
1138 0 : CHK_PTR_NULL(ccuKernel);
1139 0 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
1140 0 : CcuV2::CacheConfig cacheConfig{0x0, 0x0};
1141 :
1142 : // var寄存器的真实id在常量准备阶段(Register)无法获取,故不记录在常量表中,单独赋值处理
1143 0 : CcuV2::LoadImdToXn(instr++, dep.commXn[0], storePtr->GetVar().Id()); // src xn id
1144 0 : CcuV2::StoreXToMem(instr++,
1145 0 : constValue2VarMap.at(storePtr->GetAddr()).Id(),
1146 0 : constValue2VarMap.at(dep.memTokenInfo).Id(),
1147 0 : dep.commXn[0],
1148 0 : constValue2VarMap.at(CCU_RESOURCE_XN_PER_SIZE * storePtr->GetNum()).Id(),
1149 0 : cacheConfig, dep.commSignal, storePtr->GetMask());
1150 0 : CcuV2::SetCKE(instr++, 0, 0, dep.commSignal, storePtr->GetMask(), 1);
1151 :
1152 0 : return HcclResult::HCCL_SUCCESS;
1153 : }
1154 :
1155 0 : HcclResult CcuInsGeneratorV2::CcuRepStoreVarTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId, CcuRepStoreVar* storeVarPtr, const TransDep &dep)
1156 : {
1157 0 : CHK_PTR_NULL(storeVarPtr);
1158 0 : CHK_PTR_NULL(ccuKernel);
1159 : (void)curInstrId;
1160 0 : CcuV2::CacheConfig cacheConfig{0x0, 0x0};
1161 :
1162 : // var寄存器的真实id在常量准备阶段(Register)无法获取,故不记录在常量表中,单独赋值处理
1163 0 : CcuV2::LoadImdToXn(instr++, dep.commXn[0], storeVarPtr->GetVar().Id());
1164 0 : const auto &constValue2VarMap = ccuKernel->GetConstValue2VarMap();
1165 0 : if (storeVarPtr->GetHscbFlag()) {
1166 0 : CcuV2::HSCBStoreXToMem(instr++,
1167 0 : storeVarPtr->GetDst().Id(),
1168 0 : dep.commXn[0],
1169 0 : constValue2VarMap.at(CCU_RESOURCE_XN_PER_SIZE * storeVarPtr->GetNum()).Id(),
1170 0 : cacheConfig, dep.commSignal, storeVarPtr->GetMask());
1171 : } else {
1172 0 : CcuV2::StoreXToMem(instr++,
1173 0 : storeVarPtr->GetDst().Id(),
1174 0 : constValue2VarMap.at(dep.memTokenInfo).Id(),
1175 0 : dep.commXn[0],
1176 0 : constValue2VarMap.at(CCU_RESOURCE_XN_PER_SIZE * storeVarPtr->GetNum()).Id(),
1177 0 : cacheConfig, dep.commSignal, storeVarPtr->GetMask());
1178 : }
1179 0 : CcuV2::SetCKE(instr++, 0, 0, dep.commSignal, storeVarPtr->GetMask(), 1);
1180 :
1181 0 : return HcclResult::HCCL_SUCCESS;
1182 : }
1183 :
1184 320 : HcclResult CcuInsGeneratorV2::PrepareConstValue(CcuRepBase* repPtr, const TransDep &dep, CcuKernel *ccuKernel)
1185 : {
1186 320 : CHK_PTR_NULL(repPtr);
1187 320 : CHK_PTR_NULL(ccuKernel);
1188 320 : HCCL_INFO("CcuInsGeneratorV2::PrepareConstValue Current RepType[%d]", repPtr->Type());
1189 320 : switch (repPtr->Type()) {
1190 0 : case CcuRepType::LOAD: return PrepareLoadConstValue(repPtr, dep, ccuKernel);
1191 0 : case CcuRepType::LOAD_VAR: return PrepareLoadVarConstValue(repPtr, dep, ccuKernel);
1192 0 : case CcuRepType::STORE: return PrepareStoreConstValue(repPtr, dep, ccuKernel);
1193 0 : case CcuRepType::STORE_VAR: return PrepareStoreVarConstValue(repPtr, dep, ccuKernel);
1194 1 : case CcuRepType::REM_POST_SEM: return PrepareRemPostSemConstValue(repPtr, dep, ccuKernel);
1195 3 : case CcuRepType::REM_POST_VAR: return PrepareRemPostVarConstValue(repPtr, dep, ccuKernel);
1196 0 : case CcuRepType::WRITE: return PrepareWriteConstValue(repPtr, dep, ccuKernel);
1197 1 : case CcuRepType::READ: return PrepareReadConstValue(repPtr, dep, ccuKernel);
1198 0 : case CcuRepType::BUF_WRITE: return PrepareBufWriteConstValue(repPtr, dep, ccuKernel);
1199 0 : case CcuRepType::BUF_READ: return PrepareBufReadConstValue(repPtr, dep, ccuKernel);
1200 0 : case CcuRepType::LOCAL_CPY: return PrepareLocCpyConstValue(repPtr, dep, ccuKernel);
1201 0 : case CcuRepType::RECORD_SHARED_NOTIFY: return PrepareRecordSharedNotifyConstValue(repPtr, dep, ccuKernel);
1202 315 : default: break;
1203 : }
1204 315 : return HcclResult::HCCL_SUCCESS;
1205 : }
1206 :
1207 0 : HcclResult CcuInsGeneratorV2::PrepareLoadConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1208 : {
1209 0 : CcuRepLoad* loadPtr = dynamic_cast<CcuRepLoad*>(repPtr);
1210 0 : CHK_PTR_NULL(loadPtr);
1211 0 : std::vector<uint64_t> values = {loadPtr->GetAddr(), dep.memTokenInfo,
1212 0 : CCU_RESOURCE_XN_PER_SIZE * loadPtr->GetNum()};
1213 0 : return ccuKernel->Add2ConstValue2VarMap(values);
1214 0 : }
1215 :
1216 0 : HcclResult CcuInsGeneratorV2::PrepareLoadVarConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1217 : {
1218 0 : CcuRepLoadVar* loadVarPtr = dynamic_cast<CcuRepLoadVar*>(repPtr);
1219 0 : CHK_PTR_NULL(loadVarPtr);
1220 0 : std::vector<uint64_t> values = {dep.memTokenInfo, CCU_RESOURCE_XN_PER_SIZE * loadVarPtr->GetNum()};
1221 0 : return ccuKernel->Add2ConstValue2VarMap(values);
1222 0 : }
1223 :
1224 0 : HcclResult CcuInsGeneratorV2::PrepareStoreConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1225 : {
1226 0 : CcuRepStore* storePtr = dynamic_cast<CcuRepStore*>(repPtr);
1227 0 : CHK_PTR_NULL(storePtr);
1228 0 : std::vector<uint64_t> values = {storePtr->GetAddr(), dep.memTokenInfo,
1229 0 : CCU_RESOURCE_XN_PER_SIZE * storePtr->GetNum()};
1230 0 : return ccuKernel->Add2ConstValue2VarMap(values);
1231 0 : }
1232 :
1233 0 : HcclResult CcuInsGeneratorV2::PrepareStoreVarConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1234 : {
1235 0 : CcuRepStoreVar* storeVarPtr = dynamic_cast<CcuRepStoreVar*>(repPtr);
1236 0 : CHK_PTR_NULL(storeVarPtr);
1237 0 : std::vector<uint64_t> values = {CCU_RESOURCE_XN_PER_SIZE * storeVarPtr->GetNum()};
1238 0 : if (!storeVarPtr->GetHscbFlag()) { values.push_back(dep.memTokenInfo); }
1239 0 : return ccuKernel->Add2ConstValue2VarMap(values);
1240 0 : }
1241 :
1242 1 : HcclResult CcuInsGeneratorV2::PrepareRemPostSemConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1243 : {
1244 1 : CcuRepRemPostSem* repRemPostSemPtr = dynamic_cast<CcuRepRemPostSem*>(repPtr);
1245 1 : CHK_PTR_NULL(repRemPostSemPtr);
1246 1 : CcuUrmaChannel* channelImpl{};
1247 1 : CHK_RET(GetUrmaChannel(repRemPostSemPtr->GetChannel(), channelImpl));
1248 1 : uint64_t rmtSignalAddr{0};
1249 1 : CHK_PRT_RET(channelImpl->GetRmtSignalAddrByIndex(repRemPostSemPtr->GetSemIndex(), rmtSignalAddr) != HcclResult::HCCL_SUCCESS,
1250 : HCCL_ERROR("[CcuInsGeneratorV2][%s] failed to get remote signal addr, channelHandle[0x%llx].",
1251 : __func__, repRemPostSemPtr->GetChannel()), HCCL_E_INTERNAL);
1252 1 : uint64_t rmtToken{};
1253 1 : CHK_RET(GetRmtToken(channelImpl, rmtToken));
1254 2 : std::vector<uint64_t> values = {channelImpl->GetChannelId(), rmtSignalAddr, rmtToken};
1255 1 : return ccuKernel->Add2ConstValue2VarMap(values);
1256 1 : }
1257 :
1258 3 : HcclResult CcuInsGeneratorV2::PrepareRemPostVarConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1259 : {
1260 3 : CcuRepRemPostVar* repRemPostVarPtr = dynamic_cast<CcuRepRemPostVar*>(repPtr);
1261 3 : CHK_PTR_NULL(repRemPostVarPtr);
1262 3 : CcuUrmaChannel* channelImpl{};
1263 3 : CHK_RET(GetUrmaChannel(repRemPostVarPtr->GetChannel(), channelImpl));
1264 3 : uint64_t rmtSignalAddr{0};
1265 3 : uint64_t rmtVarAddr{0};
1266 3 : CHK_PRT_RET(channelImpl->GetRmtSignalAddrByIndex(repRemPostVarPtr->GetSemIndex(), rmtSignalAddr) != HcclResult::HCCL_SUCCESS,
1267 : HCCL_ERROR("[CcuInsGeneratorV2][%s] failed to get remote signal addr, channelHandle[0x%llx].",
1268 : __func__, repRemPostVarPtr->GetChannel()), HCCL_E_INTERNAL);
1269 3 : CHK_PRT_RET(channelImpl->GetRmtVarAddrByIndex(repRemPostVarPtr->GetParamIndex(), rmtVarAddr) != HcclResult::HCCL_SUCCESS,
1270 : HCCL_ERROR("[CcuInsGeneratorV2][%s] failed to get remote var addr, channelHandle[0x%llx].",
1271 : __func__, repRemPostVarPtr->GetChannel()), HCCL_E_INTERNAL);
1272 3 : uint64_t rmtToken{};
1273 3 : CHK_RET(GetRmtToken(channelImpl, rmtToken));
1274 6 : std::vector<uint64_t> values = {channelImpl->GetChannelId(), rmtSignalAddr, rmtToken, rmtVarAddr};
1275 3 : return ccuKernel->Add2ConstValue2VarMap(values);
1276 3 : }
1277 :
1278 0 : HcclResult CcuInsGeneratorV2::PrepareWriteConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1279 : {
1280 0 : CcuRepWrite* repWritePtr = dynamic_cast<CcuRepWrite*>(repPtr);
1281 0 : CHK_PTR_NULL(repWritePtr);
1282 0 : CcuUrmaChannel* channelImpl{};
1283 0 : CHK_RET(GetUrmaChannel(repWritePtr->GetChannel(), channelImpl));
1284 0 : uint64_t rmtToken{};
1285 0 : CHK_RET(GetRmtToken(channelImpl, rmtToken));
1286 0 : std::vector<uint64_t> values = {channelImpl->GetChannelId(), rmtToken};
1287 0 : return ccuKernel->Add2ConstValue2VarMap(values);
1288 0 : }
1289 :
1290 1 : HcclResult CcuInsGeneratorV2::PrepareReadConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1291 : {
1292 1 : CcuRepRead* repReadPtr = dynamic_cast<CcuRepRead*>(repPtr);
1293 1 : CHK_PTR_NULL(repReadPtr);
1294 1 : CcuUrmaChannel* channelImpl{};
1295 1 : CHK_RET(GetUrmaChannel(repReadPtr->GetChannel(), channelImpl));
1296 2 : std::vector<uint64_t> values = {channelImpl->GetChannelId()};
1297 1 : return ccuKernel->Add2ConstValue2VarMap(values);
1298 1 : }
1299 :
1300 0 : HcclResult CcuInsGeneratorV2::PrepareBufWriteConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1301 : {
1302 0 : CcuRepBufWrite* repBufWritePtr = dynamic_cast<CcuRepBufWrite*>(repPtr);
1303 0 : CHK_PTR_NULL(repBufWritePtr);
1304 0 : CcuUrmaChannel* channelImpl{};
1305 0 : CHK_RET(GetUrmaChannel(repBufWritePtr->GetChannel(), channelImpl));
1306 0 : uint64_t rmtToken{};
1307 0 : CHK_RET(GetRmtToken(channelImpl, rmtToken));
1308 0 : std::vector<uint64_t> values = {channelImpl->GetChannelId(), rmtToken, dep.ccuResSpaceTokenInfo};
1309 0 : return ccuKernel->Add2ConstValue2VarMap(values);
1310 0 : }
1311 :
1312 0 : HcclResult CcuInsGeneratorV2::PrepareBufReadConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1313 : {
1314 0 : CcuRepBufRead* repBufReadPtr = dynamic_cast<CcuRepBufRead*>(repPtr);
1315 0 : CHK_PTR_NULL(repBufReadPtr);
1316 0 : CcuUrmaChannel* channelImpl{};
1317 0 : CHK_RET(GetUrmaChannel(repBufReadPtr->GetChannel(), channelImpl));
1318 0 : std::vector<uint64_t> values = {channelImpl->GetChannelId(), dep.ccuResSpaceTokenInfo};
1319 0 : return ccuKernel->Add2ConstValue2VarMap(values);
1320 0 : }
1321 :
1322 0 : HcclResult CcuInsGeneratorV2::PrepareLocCpyConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1323 : {
1324 0 : CcuRepLocCpy* repLocCpyPtr = dynamic_cast<CcuRepLocCpy*>(repPtr);
1325 0 : CHK_PTR_NULL(repLocCpyPtr);
1326 0 : std::vector<uint64_t> values = {dep.reserveChannalId[0]};
1327 0 : return ccuKernel->Add2ConstValue2VarMap(values);
1328 0 : }
1329 :
1330 0 : HcclResult CcuInsGeneratorV2::PrepareRecordSharedNotifyConstValue(CcuRepBase* repPtr, const TransDep& dep, CcuKernel* ccuKernel)
1331 : {
1332 : CcuRepRecordSharedNotify* sharedNotifyPtr =
1333 0 : dynamic_cast<CcuRepRecordSharedNotify*>(repPtr);
1334 0 : CHK_PTR_NULL(sharedNotifyPtr);
1335 0 : uint64_t ckeAddr = dep.xnBaseAddr[sharedNotifyPtr->GetNotify().DieId()] +
1336 0 : CCU_RESOURCE_XN_V2_RESERVE_SIZE + (sharedNotifyPtr->GetNotify().Id() * CCU_RESOURCE_CKE_PER_SIZE);
1337 0 : std::vector<uint64_t> values = {ckeAddr, dep.memTokenInfo, CCU_RESOURCE_CKE_MASK_LENGTH, sharedNotifyPtr->GetMask()};
1338 0 : return ccuKernel->Add2ConstValue2VarMap(values);
1339 0 : }
1340 :
1341 9 : HcclResult CcuInsGeneratorV2::LoopConfigTranslate(CcuInstr*& instr, uint16_t& curInstrId,
1342 : CcuRepLoopGroupBundle* bundlePtr, const TransDep& dep)
1343 : {
1344 28 : for (const auto &loop : bundlePtr->GetLoops()) {
1345 19 : CcuV2::LoadImdToXn(instr++, loop.ctxIdVar.Id(), loop.executor.Id());
1346 19 : curInstrId++;
1347 19 : if (loop.layout == CcuRepLoopGroupBundle::Layout::Config) {
1348 7 : CcuV2::LoadImdToXn(instr++, loop.iterNumVar.Id(), loop.config.iterNum);
1349 7 : curInstrId++;
1350 7 : CcuV2::LoadImdToXn(instr++, loop.addrOffsetVar.Id(), loop.config.addrOffset);
1351 7 : curInstrId++;
1352 12 : } else if (loop.layout == CcuRepLoopGroupBundle::Layout::PackedVar) {
1353 : // loopParamVar 布局:iterNum[12:0] gsaOffset[44:13] ctxId[52:45]
1354 4 : CcuV2::LoadImdToXn(instr++, dep.reserveXnId, LOOP_ITER_NUM_MASK);
1355 4 : curInstrId++;
1356 4 : CcuV2::And(instr++, loop.iterNumVar.Id(), loop.loopParamVar.Id(), dep.reserveXnId);
1357 4 : curInstrId++;
1358 4 : CcuV2::LoadImdToXn(instr++, dep.reserveXnId, LOOP_GSA_OFFSET_SHIFT);
1359 4 : curInstrId++;
1360 4 : CcuV2::SRL(instr++, loop.addrOffsetVar.Id(), loop.loopParamVar.Id(), dep.reserveXnId);
1361 4 : curInstrId++;
1362 4 : CcuV2::LoadImdToXn(instr++, dep.reserveXnId, LOOP_GSA_OFFSET_MASK);
1363 4 : curInstrId++;
1364 4 : CcuV2::And(instr++, loop.addrOffsetVar.Id(), loop.addrOffsetVar.Id(), dep.reserveXnId);
1365 4 : curInstrId++;
1366 : }
1367 : }
1368 9 : return HcclResult::HCCL_SUCCESS;
1369 : }
1370 :
1371 9 : HcclResult CcuInsGeneratorV2::LoopGroupConfigTranslate(CcuInstr*& instr, uint16_t& curInstrId,
1372 : CcuRepLoopGroupBundle* bundlePtr, const TransDep& dep,
1373 : bool isConfig, bool isCompat, uint16_t& loopGroupConfigId)
1374 : {
1375 9 : loopGroupConfigId = bundlePtr->GetParallelVar().Id();
1376 9 : if (isConfig) {
1377 4 : const auto &cfg = bundlePtr->GetConfig();
1378 4 : uint64_t parallelImm = GetParallelParamV2(cfg.cloneNum, bundlePtr->GetRepeatLoopIdx(),
1379 : bundlePtr->GetTotalLoopNum());
1380 4 : CcuV2::LoadImdToXn(instr++, bundlePtr->GetParallelVar().Id(), parallelImm);
1381 4 : curInstrId++;
1382 4 : uint64_t offsetImm = GetOffsetParam(cfg.addrOffset, cfg.ccuBufferOffset, cfg.eventOffset);
1383 4 : CcuV2::LoadImdToXn(instr++, bundlePtr->GetOffsetParam().Id(), offsetImm);
1384 4 : curInstrId++;
1385 4 : CcuV2::LoadImdToXn(instr++, bundlePtr->GetXnOffsetVar().Id(), cfg.varOffset);
1386 4 : curInstrId++;
1387 5 : } else if (isCompat) {
1388 1 : const uint16_t newXm = bundlePtr->GetNewParallelVar().Id();
1389 1 : const uint16_t scratch = bundlePtr->GetScratchVar().Id();
1390 1 : const uint16_t src = bundlePtr->GetParallelVar().Id();
1391 : struct FieldMap { uint16_t srcShift; uint16_t dstShift; };
1392 1 : const FieldMap fields[] = {{41, 0}, {48, 10}, {55, 19}};
1393 4 : for (size_t i = 0; i < sizeof(fields) / sizeof(fields[0]); i++) {
1394 3 : const uint16_t dst = (i == 0) ? newXm : scratch;
1395 3 : CcuV2::LoadImdToXn(instr++, dep.reserveXnId, fields[i].srcShift);
1396 3 : curInstrId++;
1397 3 : CcuV2::SRL(instr++, dst, src, dep.reserveXnId);
1398 3 : curInstrId++;
1399 3 : CcuV2::LoadImdToXn(instr++, dep.reserveXnId, LOOP_FIELD_MASK);
1400 3 : curInstrId++;
1401 3 : CcuV2::And(instr++, dst, dst, dep.reserveXnId);
1402 3 : curInstrId++;
1403 3 : if (fields[i].dstShift != 0) {
1404 2 : CcuV2::LoadImdToXn(instr++, dep.reserveXnId, fields[i].dstShift);
1405 2 : curInstrId++;
1406 2 : CcuV2::SLL(instr++, dst, dst, dep.reserveXnId);
1407 2 : curInstrId++;
1408 2 : CcuV2::Or(instr++, newXm, newXm, scratch);
1409 2 : curInstrId++;
1410 : }
1411 : }
1412 1 : CcuV2::LoadImdToXn(instr++, dep.reserveXnId, 0);
1413 1 : curInstrId++;
1414 1 : loopGroupConfigId = newXm;
1415 : }
1416 9 : return HcclResult::HCCL_SUCCESS;
1417 : }
1418 :
1419 9 : HcclResult CcuInsGeneratorV2::CcuRepLoopGroupBundleTranslate(CcuKernel* ccuKernel, CcuInstr *&instr, uint16_t &curInstrId,
1420 : CcuRepLoopGroupBundle* bundlePtr, const TransDep &dep)
1421 : {
1422 : UNUSED(ccuKernel);
1423 9 : CHK_PTR_NULL(bundlePtr);
1424 9 : const auto &loops = bundlePtr->GetLoops();
1425 9 : const auto layout = bundlePtr->GetLayout();
1426 : // 兼容路径:V2 下需插入位重排指令
1427 9 : const bool isCompat = (layout == CcuRepLoopGroupBundle::Layout::PackedVar);
1428 9 : const bool isConfig = (layout == CcuRepLoopGroupBundle::Layout::Config);
1429 :
1430 : // 每 loop 寄存器:按各 loop 自身构造方式载入,与 group 的构造方式相互独立
1431 9 : CHK_RET(LoopConfigTranslate(instr, curInstrId, bundlePtr, dep));
1432 :
1433 : // loopGroupConfig:config 按 960 位分布打包立即数;兼容路径把旧 parallelVar 重排到新分布
1434 : // 新分布:LoopNum[9:0] RepeatLoopIndex[18:10] ExtendNum[27:19]
1435 : // 旧分布:totalLoopNum<<41 repeatLoopIndex<<48 repeatNum<<55
1436 9 : uint16_t loopGroupConfigId{};
1437 9 : CHK_RET(LoopGroupConfigTranslate(instr, curInstrId, bundlePtr, dep, isConfig, isCompat, loopGroupConfigId));
1438 :
1439 : // LoopGroup:loops 定义在其后第 3 条起(跳过 2 条无条件跳转)
1440 : // xnOffset(Xp):config/version960 有来源,兼容路径无来源填 0
1441 9 : const uint16_t xnOffsetId = isCompat ? dep.reserveXnId : bundlePtr->GetXnOffsetVar().Id();
1442 9 : CcuV2::LoopGroup(instr++, curInstrId + 3, loopGroupConfigId, bundlePtr->GetOffsetParam().Id(), xnOffsetId); // 向后3条为loop入口
1443 9 : curInstrId++;
1444 :
1445 : // 无条件跳转,跳过后续 loop 定义
1446 9 : const uint16_t loopCount = static_cast<uint16_t>(loops.size());
1447 9 : const uint16_t jumpInstrId = curInstrId + 1;
1448 9 : const uint16_t targetInstrId = curInstrId + 2 + loopCount; // 跳转目的为loop指令后额外2条
1449 9 : CcuV2::LoadImdToXn(instr++, dep.reserveXnId, GetRelativeInstrId(jumpInstrId, targetInstrId));
1450 9 : curInstrId++;
1451 9 : CcuV2::Jump(instr++, dep.reserveXnId, 0, 0, static_cast<int>(ConditionType::DEFAULT));
1452 9 : curInstrId++;
1453 :
1454 28 : for (const auto &loop : loops) {
1455 19 : const auto &block = loop.repLoopBlock;
1456 19 : CHK_PTR_NULL(block);
1457 19 : CcuV2::Loop(instr++, block->StartInstrId(), block->StartInstrId() + block->InstrCount() - 1,
1458 19 : loop.iterNumVar.Id(), loop.addrOffsetVar.Id(), loop.ctxIdVar.Id());
1459 19 : curInstrId++;
1460 : }
1461 :
1462 9 : CcuV2::LoadImdToXn(instr++, dep.reserveXnId, 0);
1463 9 : curInstrId++;
1464 :
1465 9 : return HcclResult::HCCL_SUCCESS;
1466 : }
1467 :
1468 27 : uint16_t CcuInsGeneratorV2::CcuRepLoopGroupBundleInstrCount(CcuRepLoopGroupBundle* bundlePtr)
1469 : {
1470 27 : if (bundlePtr == nullptr) {
1471 0 : Hccl::THROW<Hccl::CcuApiException>("[%s] bundlePtr is nullptr", __func__);
1472 : }
1473 27 : uint16_t total = 0;
1474 : // 每 loop 按自身构造方式计条数
1475 84 : for (const auto &loop : bundlePtr->GetLoops()) {
1476 57 : switch (loop.layout) {
1477 21 : case CcuRepLoopGroupBundle::Layout::Config:
1478 21 : total += 4; // 3 条载入(ctxId/iterNum/gsaOffset) + 1 条 Loop
1479 21 : break;
1480 24 : case CcuRepLoopGroupBundle::Layout::VersionV2:
1481 24 : total += 2; // 1 条 ctxId 载入 + 1 条 Loop
1482 24 : break;
1483 12 : case CcuRepLoopGroupBundle::Layout::PackedVar:
1484 : default:
1485 12 : total += 8; // 7 条(ctxId1 + 位重排6) + 1 条 Loop
1486 12 : break;
1487 : }
1488 : }
1489 : // group 头按 group 自身构造方式计条数
1490 27 : switch (bundlePtr->GetLayout()) {
1491 12 : case CcuRepLoopGroupBundle::Layout::Config:
1492 12 : total += 7; // 打包3(parallel/offset/xnOffset) + loopgroup1 + 跳过2 + 收尾1
1493 12 : break;
1494 12 : case CcuRepLoopGroupBundle::Layout::VersionV2:
1495 12 : total += 4; // loopgroup1 + 跳过2 + 收尾1
1496 12 : break;
1497 3 : case CcuRepLoopGroupBundle::Layout::PackedVar:
1498 : default:
1499 3 : total += 23; // 位重排19 + loopgroup1 + 跳过2 + 收尾1
1500 3 : break;
1501 : }
1502 27 : return total;
1503 : }
1504 :
1505 : }
1506 : } // namespace hcomm
|