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