Line data Source code
1 : /**
2 : * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "ccu_rep_translator_v1.h"
12 :
13 : #include <algorithm>
14 :
15 : #include "exception_util.h"
16 : #include "ccu_api_exception.h"
17 : #include "ccu_rep_loopcall_v1.h"
18 : #include "ccu_rep_funccall_v1.h"
19 : #include "ccu_rep_type_v1.h"
20 : #include "ccu_rep_loop_v1.h"
21 : #include "ccu_rep_loadarg_v1.h"
22 : #include "ccu_assist_v1.h"
23 :
24 : #include "ccu_dev_mgr_imp.h"
25 : #include "dtype_common.h"
26 :
27 : #include "ccu_ins_generator_base.h"
28 : #include "ccu_ins_generator_v1.h"
29 : #include "ccu_ins_generator_v2.h"
30 : #include "../../../ccu_device/ccu_res_specs.h"
31 :
32 : #include "unified_platform/pub_inc/config_plf_log.h"
33 :
34 : #include "microcode_optimizer.h"
35 :
36 : namespace hcomm {
37 : namespace CcuRep {
38 :
39 : using Hccl::PLF_TASK;
40 :
41 : template <typename T>
42 : bool CheckType(const std::shared_ptr<CcuRepBlock>& refer)
43 : {
44 : if (refer == nullptr) {
45 : HCCL_ERROR("[%s] input refer is nullptr", __func__);
46 : return false;
47 : }
48 : HCCL_INFO("[CheckType] refer->Type() = %d", refer->Type());
49 : return false;
50 : }
51 :
52 : template <>
53 5 : bool CheckType<CcuRepFuncBlock>(const std::shared_ptr<CcuRepBlock>& refer)
54 : {
55 5 : if (refer == nullptr) {
56 0 : HCCL_ERROR("[%s] input refer is nullptr", __func__);
57 0 : return false;
58 : }
59 5 : return refer->Type() == CcuRepType::FUNC_BLOCK ? true : false;
60 : }
61 :
62 : template <>
63 0 : bool CheckType<CcuRepLoopBlock>(const std::shared_ptr<CcuRepBlock>& refer)
64 : {
65 0 : if (refer == nullptr) {
66 0 : HCCL_ERROR("[%s] input refer is nullptr", __func__);
67 0 : return false;
68 : }
69 0 : return refer->Type() == CcuRepType::LOOP_BLOCK ? true : false;
70 : }
71 :
72 : template <typename T1, typename T2>
73 5 : void CcuRepTranslator::BuildReference(const std::shared_ptr<CcuRepBase>& rep)
74 : {
75 5 : auto caller = std::static_pointer_cast<T1>(rep);
76 5 : auto label = caller->GetLabel();
77 : // 特例:针对函数地址调用,不需要依靠函数名索引
78 5 : if (label == "") {
79 0 : return;
80 : }
81 5 : auto refer = refManager->GetRefBlock(label);
82 5 : if (CheckType<T2>(refer)) {
83 5 : caller->Reference(std::static_pointer_cast<T2>(refer));
84 : } else {
85 0 : Hccl::THROW<Hccl::CcuApiException>("Invalid Reference: %s", label.c_str());
86 : }
87 5 : }
88 :
89 3168 : CcuRepTranslator::CcuRepTranslator(
90 : int32_t deviceLogicId, uint8_t dieId, std::shared_ptr<CcuRepReferenceManager> refManager,
91 : std::array<uint16_t, CCU_MAX_IODIE_NUM>& reserverChannalId, std::pair<uint64_t, uint64_t>& ccuTokenInfo,
92 3168 : uint64_t hbmTokenInfo)
93 31680 : : refManager(refManager)
94 : {
95 3168 : transDep.logicalId = deviceLogicId;
96 3168 : transDep.dieId = dieId;
97 6336 : s32 result = memcpy_s(
98 3168 : transDep.reserveChannalId, sizeof(transDep.reserveChannalId), reserverChannalId.data(),
99 : sizeof(reserverChannalId));
100 3168 : if (result != 0) {
101 0 : Hccl::THROW<Hccl::InternalException>(Hccl::StringFormat(
102 : "[NsRecovery] CcuRepTranslator::CcuRepTranslator: memcpy_s failed, ret = %d", result));
103 : }
104 :
105 3168 : HcclResult ret = CcuDevMgrImp::GetCcuVersion(transDep.logicalId, ccuVersion);
106 3168 : if (ret != HcclResult::HCCL_SUCCESS || ccuVersion == CcuVersion::CCU_INVALID) {
107 0 : Hccl::THROW<Hccl::CcuApiException>("[CcuRepTranslator] Constructor: Invalid CCU Type!");
108 : }
109 :
110 : // 获取本die的xn起始地址
111 3168 : ret = CcuDevMgrImp::GetXnBaseAddr(deviceLogicId, dieId, transDep.xnBaseAddr[dieId]);
112 3168 : if (ret != HcclResult::HCCL_SUCCESS) {
113 0 : Hccl::THROW<Hccl::CcuApiException>(
114 : "Failed to get xn base address. deviceLogicId = %d, dieId = %u, ret = %d", deviceLogicId, dieId, ret);
115 : }
116 :
117 : // 若另一die使能,在A6场景下获得其xn起始地址
118 3168 : uint8_t anotherDieId = dieId == 0 ? 1 : 0;
119 3168 : bool anotherDieEnable = false;
120 3168 : if (static_cast<HcclResult>(CcuGetDieEnableInfo(deviceLogicId, anotherDieId, anotherDieEnable))
121 3168 : != HcclResult::HCCL_SUCCESS) {
122 0 : Hccl::THROW<Hccl::CcuApiException>(
123 : "Failed to get CcuGetDieEnableInfo. deviceLogicId = %d, dieId = %u", deviceLogicId, dieId);
124 : }
125 3168 : if (ccuVersion == CcuVersion::CCU_V2 && anotherDieEnable == true) {
126 608 : ret = CcuDevMgrImp::GetXnBaseAddr(deviceLogicId, anotherDieId, transDep.xnBaseAddr[anotherDieId]);
127 608 : if (ret != HcclResult::HCCL_SUCCESS) {
128 0 : Hccl::THROW<Hccl::CcuApiException>(
129 : "Failed to get xn base address. deviceLogicId = %d, dieId = %u, "
130 : "ret = %d",
131 : deviceLogicId, anotherDieId, ret);
132 : }
133 : }
134 :
135 3168 : transDep.ccuResSpaceTokenInfo = CcuRep::GetToken(ccuTokenInfo.first, ccuTokenInfo.second, 1);
136 : // 获取hbm token信息
137 3168 : transDep.memTokenInfo = hbmTokenInfo;
138 3168 : }
139 :
140 4 : CcuRepTranslator::CcuRepTranslator(std::shared_ptr<CcuRepReferenceManager> refManager, const TransDep& transDep)
141 4 : : refManager(refManager),
142 40 : transDep(transDep)
143 : {
144 4 : HcclResult ret = CcuDevMgrImp::GetCcuVersion(transDep.logicalId, ccuVersion);
145 4 : if (ret != HcclResult::HCCL_SUCCESS || ccuVersion == CcuVersion::CCU_INVALID) {
146 0 : Hccl::THROW<Hccl::CcuApiException>("[CcuRepTranslator] Constructor: Invalid CCU Type!");
147 : }
148 4 : }
149 :
150 160 : uint32_t CcuRepTranslator::GetInstrNum(const int32_t devLogicId)
151 : {
152 160 : CcuVersion tempCcuVersion = CcuVersion::CCU_INVALID;
153 160 : HcclResult ret = CcuDevMgrImp::GetCcuVersion(devLogicId, tempCcuVersion);
154 160 : if (ret != HcclResult::HCCL_SUCCESS || tempCcuVersion == CcuVersion::CCU_INVALID) {
155 0 : Hccl::THROW<Hccl::CcuApiException>("[CcuRepTranslator] GetInstrNum: Invalid CCU Type!");
156 : }
157 :
158 160 : return tempCcuVersion == CcuVersion::CCU_V1 ?
159 : 4 // 4:翻译器翻译过程中额外需要的指令空间大小(插入3条通用操作指令+1条终止指令)
160 : :
161 160 : 13; // 13:翻译器翻译过程中额外需要的指令空间大小(插入3条通用操作指令+1条终止指令+9条repJump)
162 : }
163 :
164 3168 : CcuResReq CcuRepTranslator::GetResReq(const int32_t devLogicId, uint8_t dieId)
165 : {
166 : // 申请离散 xn 资源
167 : // 需要申请若干xn、gsa、cke设置为固定值用于通用操作
168 3168 : CcuVersion tempCcuVersion = CcuVersion::CCU_INVALID;
169 3168 : HcclResult ret = CcuDevMgrImp::GetCcuVersion(devLogicId, tempCcuVersion);
170 3168 : if (ret != HcclResult::HCCL_SUCCESS || tempCcuVersion == CcuVersion::CCU_INVALID) {
171 0 : Hccl::THROW<Hccl::CcuApiException>("[CcuRepTranslator] GetResReq: Invalid CCU Type!");
172 : }
173 :
174 3168 : CcuResReq resReq;
175 3168 : int varNum = XN_NUM;
176 3168 : int gsaNum = tempCcuVersion == CcuVersion::CCU_V1 ? GSA_NUM : 0;
177 3168 : resReq.xnReq[dieId] = varNum;
178 3168 : resReq.gsaReq[dieId] = gsaNum;
179 3168 : resReq.ckeReq[dieId] = CKE_NUM;
180 6336 : return resReq;
181 : }
182 :
183 3168 : void CcuRepTranslator::GetRes(CcuRepResource& res)
184 : {
185 3168 : int varNum = XN_NUM;
186 3168 : int gsaNum = ccuVersion == CcuVersion::CCU_V1 ? GSA_NUM : 0;
187 15840 : for (int i = 0; i < varNum; i++) {
188 12672 : res.variable[transDep.dieId].push_back(var[i]);
189 : }
190 10848 : for (int i = 0; i < gsaNum; i++) {
191 7680 : res.address[transDep.dieId].push_back(addr[i]);
192 : }
193 9504 : for (int i = 0; i < CKE_NUM; i++) {
194 6336 : res.completedEvent[transDep.dieId].push_back(signal[i]);
195 : }
196 3168 : }
197 :
198 1208 : void CcuRepTranslator::PreProcess(std::shared_ptr<CcuRepBase> rep)
199 : {
200 1208 : auto repType = rep->Type();
201 1208 : if (repType == CcuRepType::FUNC_BLOCK) {
202 4 : auto funcBlock = std::static_pointer_cast<CcuRepFuncBlock>(rep);
203 4 : refManager->SetRefBlock(funcBlock->GetLabel(), funcBlock);
204 4 : funcBlock->SetFuncManager(refManager.get());
205 1208 : } else if (repType == CcuRepType::LOOP_BLOCK) {
206 43 : auto loopBlock = std::static_pointer_cast<CcuRepLoopBlock>(rep);
207 43 : refManager->SetRefBlock(loopBlock->GetLabel(), loopBlock);
208 1204 : } else if (repType == CcuRepType::FUNC_CALL) {
209 5 : BuildReference<CcuRepFuncCall, CcuRepFuncBlock>(rep);
210 5 : auto funcCall = std::static_pointer_cast<CcuRepFuncCall>(rep);
211 5 : funcCall->SetFuncManager(refManager.get());
212 1161 : } else if (repType == CcuRepType::LOOP_CALL) {
213 0 : BuildReference<CcuRepLoopCall, CcuRepLoopBlock>(rep);
214 1156 : } else if (repType == CcuRepType::LOOP) {
215 0 : BuildReference<CcuRepLoop, CcuRepLoopBlock>(rep);
216 : }
217 1208 : }
218 :
219 192 : void CcuRepTranslator::Translate(
220 : CcuKernel* ccuKernel, const std::vector<std::shared_ptr<CcuRepBase>>& repVec, CcuInstr*& instr,
221 : uint16_t& instrId, std::function<bool(std::shared_ptr<CcuRepBase>)> filter)
222 : {
223 192 : constexpr uint32_t maxTryCount = 10; // 最大尝试次数10
224 192 : uint32_t tryCount = 0;
225 192 : uint32_t restCount = 0;
226 :
227 192 : auto funcInVar = refManager.get()->GetFuncIn();
228 192 : int funcArgIndex = 0;
229 :
230 : do {
231 212 : restCount = 0;
232 4321 : for (uint32_t index = 0; index < repVec.size(); index++) {
233 4110 : if (!filter(repVec[index])) {
234 2137 : continue;
235 : }
236 :
237 1973 : if (repVec[index]->Translated()) {
238 765 : continue;
239 : }
240 :
241 1208 : if (repVec[index]->Type() == CcuRepType::LOAD_ARG && transDep.isFuncBlock) {
242 0 : transDep.loadXnId = funcInVar[funcArgIndex++].Id();
243 : }
244 :
245 1208 : PreProcess(repVec[index]);
246 1208 : bool flag = repVec[index]->Translate(ccuKernel, instr, instrId, transDep);
247 1207 : if (!flag) {
248 126 : restCount++;
249 : }
250 : }
251 211 : tryCount++;
252 211 : HCCL_INFO("tryCount = %u, remaining representation = %u", tryCount, restCount);
253 211 : } while (restCount > 0 && tryCount < maxTryCount);
254 :
255 191 : if (tryCount == maxTryCount && restCount > 0) {
256 0 : HCCL_ERROR(
257 : "After translation, remaining representation: tryCount = %u, restCount = %u ", tryCount, restCount);
258 0 : for (uint32_t index = 0; index < repVec.size(); index++) {
259 0 : if (!repVec[index]->Translated()) {
260 0 : HCCL_ERROR("index[%u], %s", index, repVec[index]->Describe().c_str());
261 : }
262 : }
263 0 : Hccl::THROW<Hccl::CcuApiException>("Translation Failed");
264 : }
265 192 : }
266 :
267 : namespace {
268 :
269 : // 收集 LOAD_ARG rep 并按全局 argId 升序排序, 确保 LoadSqeArgs 指令在 mission 切分时
270 : // 落入与其 slot id 匹配的 mission (避免用户乱序 LoadArg 导致取参错位).
271 : std::vector<std::shared_ptr<CcuRepBase>>
272 47 : CollectSortedLoadArgReps(const std::vector<std::shared_ptr<CcuRepBase>>& repVec)
273 : {
274 47 : std::vector<std::shared_ptr<CcuRepBase>> sortedLoadArgReps;
275 47 : sortedLoadArgReps.reserve(repVec.size());
276 1139 : for (const auto& rep : repVec) {
277 1092 : if (rep->Type() == CcuRepType::LOAD_ARG) {
278 47 : sortedLoadArgReps.push_back(rep);
279 : }
280 : }
281 47 : std::stable_sort(
282 : sortedLoadArgReps.begin(), sortedLoadArgReps.end(),
283 115 : [](const std::shared_ptr<CcuRepBase>& a, const std::shared_ptr<CcuRepBase>& b) {
284 230 : return std::static_pointer_cast<CcuRepLoadArg>(a)->GetFullArgId()
285 115 : < std::static_pointer_cast<CcuRepLoadArg>(b)->GetFullArgId();
286 : });
287 47 : return sortedLoadArgReps;
288 0 : }
289 :
290 : // 调用 V2 后端优化器 (极简 CkeOnly 档: 只按 CKE 写后读补 NOP, 不重排 / 不重命名寄存器).
291 : // 默认关闭 (未定义 CCU_MICROCODE_OPT_ENABLE) 时此函数不被引用, 标注避免未使用告警.
292 : [[maybe_unused]] CcuInstrInfo
293 17 : RunV2BackendOptimizer(const CcuInstrInfo& instrInfo, CcuKernel* ccuKernel, const TransDep& transDep)
294 : {
295 : (void)ccuKernel; // CkeOnly 不使用 pinned Xn / pinned 组.
296 17 : HCCL_INFO("[CcuMicrocodeOpt] running backend optimizer (V2)");
297 : CcuInstrInfo optimized
298 17 : = CcuOpt::MicrocodeOptimizer::Run(instrInfo, transDep.reserveXnId, transDep.reserveCkeId);
299 17 : HCCL_INFO(
300 : "[CcuMicrocodeOpt] before instrCount=%u, after instrCount=%u", instrInfo.instrCount,
301 : optimized.instrCount);
302 17 : return optimized;
303 0 : }
304 :
305 : } // namespace
306 :
307 47 : CcuInstrInfo CcuRepTranslator::Translate(
308 : CcuKernel* ccuKernel, const std::vector<std::shared_ptr<CcuRepBase>>& repVec, uint16_t startInstrId,
309 : bool isFuncBlock)
310 : {
311 47 : constexpr uint32_t defaultInstrCapacity = 32 * 1024; // 默认最大容量32 * 1024条
312 47 : CcuInstrInfo instrInfo;
313 47 : instrInfo.instrVec.resize(defaultInstrCapacity);
314 47 : CcuInstr* instr = instrInfo.instrVec.data();
315 47 : uint16_t curInstrId = startInstrId;
316 :
317 47 : BindResource(isFuncBlock);
318 :
319 : // 翻译LoopBlock
320 47 : Translate(ccuKernel, repVec, instr, curInstrId, [](std::shared_ptr<CcuRepBase> rep) -> bool {
321 1092 : return rep->Type() == CcuRepType::LOOP_BLOCK;
322 : });
323 :
324 : // 翻译funcBlock
325 47 : Translate(ccuKernel, repVec, instr, curInstrId, [](std::shared_ptr<CcuRepBase> rep) -> bool {
326 1092 : return rep->Type() == CcuRepType::FUNC_BLOCK;
327 : });
328 :
329 47 : uint16_t missionStartInstrId = curInstrId;
330 :
331 : // 翻译Load (按全局 argId 升序).
332 47 : std::vector<std::shared_ptr<CcuRepBase>> sortedLoadArgReps = CollectSortedLoadArgReps(repVec);
333 47 : Translate(ccuKernel, sortedLoadArgReps, instr, curInstrId, [](std::shared_ptr<CcuRepBase> rep) -> bool {
334 47 : return rep->Type() == CcuRepType::LOAD_ARG;
335 : });
336 :
337 : // 插入通用操作
338 47 : CommonProcess(ccuKernel, instr, curInstrId);
339 :
340 : // 翻译主体
341 48 : Translate(ccuKernel, repVec, instr, curInstrId, []([[maybe_unused]] std::shared_ptr<CcuRepBase> rep) -> bool {
342 1874 : return true;
343 : });
344 :
345 46 : FinishMainBlock(instr, curInstrId);
346 :
347 46 : instrInfo.startInstrId = startInstrId;
348 46 : instrInfo.instrCount = curInstrId - startInstrId;
349 46 : instrInfo.missionStartInstrId = missionStartInstrId;
350 46 : instrInfo.missionInstrCount = curInstrId - missionStartInstrId;
351 46 : instrInfo.instrVec.resize(instrInfo.instrCount);
352 :
353 46 : DumpRep(repVec, instrInfo);
354 46 : DumpInstruction(instrInfo);
355 :
356 46 : if (ccuVersion == CcuVersion::CCU_V2) {
357 : #if !defined(CCU_MICROCODE_OPT_DISABLE)
358 : // 编译期开启后端优化 (-DCCU_MICROCODE_OPT_ENABLE=ON): 按 CKE 写后读补 NOP.
359 17 : CcuInstrInfo optimizedInstrInfo = RunV2BackendOptimizer(instrInfo, ccuKernel, transDep);
360 17 : HCCL_INFO("[CcuMicrocodeOpt] dump instruction after backend optimizer:");
361 17 : DumpInstruction(optimizedInstrInfo);
362 17 : return optimizedInstrInfo;
363 : #else
364 : // 默认关闭后端优化: 直接返回未优化指令序列, 不做 CKE 补 NOP.
365 : HCCL_INFO("[CcuMicrocodeOpt] backend optimizer disabled by default; return raw instrInfo");
366 : #endif
367 0 : }
368 :
369 29 : return instrInfo;
370 48 : }
371 :
372 47 : void CcuRepTranslator::CommonProcess(CcuKernel* ccuKernel, CcuInstr*& instr, uint16_t& instrId)
373 : {
374 47 : if (ccuVersion == CcuVersion::CCU_INVALID) {
375 0 : Hccl::THROW<Hccl::InternalException>("[CcuRepTranslator] Unexpected ccuVersion[Invalid]");
376 : }
377 47 : if (ccuVersion == CcuVersion::CCU_V1) {
378 30 : LoadImdToXnInstr(instr++, var[0].Id(), 0);
379 30 : LoadImdToGSAInstr(instr++, addr[0].Id(), 0);
380 30 : SetCKEInstr(instr++, signal[0].Id(), 0xffff, 0, 0, 1);
381 : } else {
382 17 : CcuV2::AssignI(instr++, var[0].Id(), 0);
383 17 : CcuV2::AssignI(instr++, var[XN_NUM - 1].Id(), 0);
384 17 : SetCKEInstr(instr++, signal[0].Id(), 0xffff, 0, 0, 1);
385 : }
386 :
387 : // 遍历需要赋值的常量,A5场景下暂为空表
388 47 : std::unordered_map<uint64_t, CcuRep::Variable>& constValue2VarMap = ccuKernel->GetConstValue2VarMap();
389 47 : u32 constValueNum = constValue2VarMap.size();
390 50 : for (auto elem : constValue2VarMap) {
391 3 : uint64_t constValue = elem.first;
392 3 : CcuRep::Variable curVariable = elem.second;
393 3 : if (ccuVersion == CcuVersion::CCU_V1) {
394 0 : LoadImdToXnInstr(instr++, curVariable.Id(), constValue);
395 : } else {
396 3 : CcuV2::AssignI(instr++, curVariable.Id(), constValue);
397 : }
398 3 : }
399 :
400 47 : u32 instrNum = 3 + constValueNum;
401 47 : if (instrId > UINT16_MAX - instrNum) {
402 0 : Hccl::THROW<Hccl::InternalException>("integer overflow occurs");
403 : }
404 47 : instrId += instrNum; // 插入3条指令
405 47 : }
406 :
407 46 : void CcuRepTranslator::FinishMainBlock(CcuInstr*& instr, uint16_t& instrId)
408 : {
409 46 : if (ccuVersion == CcuVersion::CCU_V1) {
410 29 : if (transDep.isFuncBlock) {
411 0 : JumpInstr(instr++, refManager.get()->GetFuncRet(FUNC_NEST_MAX).Id(), transDep.reserveXnId, 1);
412 : } else {
413 29 : LoadImdToXnInstr(instr++, var[0].Id(), 0);
414 : }
415 29 : instrId++;
416 : } else {
417 17 : if (transDep.isFuncBlock) {
418 0 : CcuV2::RelJmp(
419 0 : instr, refManager.get()->GetFuncRet(FUNC_NEST_MAX).Id(), instrId + V2_RELJMP_INSTR_NUM,
420 0 : transDep.commXn[0], transDep.commXn[1]);
421 0 : instr += V2_RELJMP_INSTR_NUM;
422 0 : CcuV2::Jump(
423 0 : instr++, refManager.get()->GetFuncRet(FUNC_NEST_MAX).Id(), transDep.reserveXnId,
424 0 : transDep.reserveXnId, 0);
425 : } else {
426 187 : for (int i = 0; i < V2_FINISH_BLOCK_INSTR_NUM; i++) {
427 170 : HCCL_INFO("FinishMainBlock Add Nop: index[%d], instrId[%d]", i, instrId);
428 170 : CcuV2::Nop(instr++);
429 : }
430 : }
431 17 : instrId += V2_FINISH_BLOCK_INSTR_NUM;
432 : }
433 :
434 46 : if (instrId > UINT16_MAX - 1) {
435 0 : Hccl::THROW<Hccl::InternalException>("integer overflow occurs");
436 : }
437 46 : }
438 :
439 63 : void CcuRepTranslator::DumpInstruction(const CcuInstrInfo& instrInfo) const
440 : {
441 63 : HCCL_INFO(
442 : "CcuInstrInfo: startInstrId = %u, instrCount = %u, missionStartInstrId = %u, missionInstrCount = %u",
443 : instrInfo.startInstrId, instrInfo.instrCount, instrInfo.missionStartInstrId, instrInfo.missionInstrCount);
444 2884 : for (uint16_t index = 0; index < instrInfo.instrVec.size(); index++) {
445 2821 : if (ccuVersion == CcuVersion::CCU_V1) {
446 1253 : HCCL_INFO(
447 : "%d: %s", instrInfo.startInstrId + index, ParseInstr(instrInfo.instrVec.data() + index).c_str());
448 : } else {
449 1568 : HCCL_INFO(
450 : "%d: %s", instrInfo.startInstrId + index,
451 : CcuV2::ParseInstrV2(instrInfo.instrVec.data() + index).c_str());
452 : }
453 : }
454 63 : }
455 :
456 46 : void CcuRepTranslator::DumpRep(
457 : const std::vector<std::shared_ptr<CcuRepBase>>& repVec, const CcuInstrInfo& instrInfo) const
458 : {
459 46 : PLF_CONFIG_INFO(PLF_TASK, "Translated Ccu Rep:");
460 1120 : for (uint32_t index = 0; index < repVec.size(); index++) {
461 1074 : uint16_t startInstrId = repVec[index]->StartInstrId();
462 1074 : uint32_t sum = static_cast<uint32_t>(startInstrId) + repVec[index]->InstrCount();
463 1074 : if (sum > UINT16_MAX) {
464 0 : HCCL_ERROR(
465 : "instrId overflow: startInstrId[%u] + InstrCount[%u] = %u exceeds UINT16_MAX", startInstrId,
466 : repVec[index]->InstrCount(), sum);
467 0 : continue;
468 : }
469 1074 : uint16_t endInstrId = static_cast<uint16_t>(sum);
470 1074 : PLF_CONFIG_INFO(
471 : PLF_TASK, "rep[%u]: %s Instr[%u--%u]", index, repVec[index]->Describe().c_str(), startInstrId,
472 : endInstrId);
473 2747 : for (uint16_t instrId = startInstrId; instrId < endInstrId; instrId++) {
474 1673 : if (instrId < instrInfo.startInstrId) {
475 0 : HCCL_ERROR("instrId[%u] less than startInstrId[%u]", instrId, instrInfo.startInstrId);
476 0 : continue;
477 : }
478 1673 : if (ccuVersion == CcuVersion::CCU_V1) {
479 1143 : PLF_CONFIG_INFO(
480 : PLF_TASK, "microcode[%u]: %s", instrId,
481 : ParseInstr(instrInfo.instrVec.data() + (instrId - instrInfo.startInstrId)).c_str());
482 : } else {
483 530 : PLF_CONFIG_INFO(
484 : PLF_TASK, "microcode[%u]: %s", instrId,
485 : CcuV2::ParseInstrV2(instrInfo.instrVec.data() + (instrId - instrInfo.startInstrId)).c_str());
486 : }
487 : }
488 : }
489 46 : }
490 :
491 47 : void CcuRepTranslator::BindResource(bool isFuncBlock)
492 : {
493 : // 在V2场景下不会为addr数组申请资源,故reserveGsaId和commGsa中实际填的都是默认值0
494 47 : transDep.reserveXnId = var[0].Id();
495 47 : transDep.reserveGsaId = addr[0].Id();
496 47 : transDep.reserveCkeId = signal[0].Id();
497 188 : for (int i = 0; i < XN_NUM - 1; i++) {
498 141 : transDep.commXn[i] = var[i + 1].Id();
499 : }
500 141 : for (int i = 0; i < GSA_NUM - 1; i++) {
501 94 : transDep.commGsa[i] = addr[i + 1].Id();
502 : }
503 47 : transDep.commSignal = signal[1].Id();
504 47 : transDep.isFuncBlock = isFuncBlock;
505 47 : HCCL_INFO(
506 : "TransDep info: logicalId = %d, dieId = %u, reserveXnId = %u, reserveGsaId = %u, reserveCkeId = %u, "
507 : "innerDieChannelId = %u, interDieChannelId = %u",
508 : transDep.logicalId, transDep.dieId, transDep.reserveXnId, transDep.reserveGsaId, transDep.reserveCkeId,
509 : transDep.reserveChannalId[0], transDep.reserveChannalId[1]);
510 47 : }
511 : }; // namespace CcuRep
512 : }; // namespace hcomm
|