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 3008 : 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 3008 : uint64_t hbmTokenInfo)
93 30080 : : refManager(refManager)
94 : {
95 3008 : transDep.logicalId = deviceLogicId;
96 3008 : transDep.dieId = dieId;
97 6016 : s32 result = memcpy_s(
98 3008 : transDep.reserveChannalId, sizeof(transDep.reserveChannalId), reserverChannalId.data(),
99 : sizeof(reserverChannalId));
100 3008 : if (result != 0) {
101 0 : Hccl::THROW<Hccl::InternalException>(Hccl::StringFormat(
102 : "[NsRecovery] CcuRepTranslator::CcuRepTranslator: memcpy_s failed, ret = %d", result));
103 : }
104 :
105 3008 : HcclResult ret = CcuDevMgrImp::GetCcuVersion(transDep.logicalId, ccuVersion);
106 3008 : 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 3008 : ret = CcuDevMgrImp::GetXnBaseAddr(deviceLogicId, dieId, transDep.xnBaseAddr[dieId]);
112 3008 : 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 3008 : uint8_t anotherDieId = dieId == 0 ? 1 : 0;
119 3008 : bool anotherDieEnable = false;
120 3008 : if (static_cast<HcclResult>(CcuGetDieEnableInfo(deviceLogicId, anotherDieId, anotherDieEnable))
121 3008 : != HcclResult::HCCL_SUCCESS) {
122 0 : Hccl::THROW<Hccl::CcuApiException>(
123 : "Failed to get CcuGetDieEnableInfo. deviceLogicId = %d, dieId = %u", deviceLogicId, dieId);
124 : }
125 3008 : if (ccuVersion == CcuVersion::CCU_V2 && anotherDieEnable == true) {
126 544 : ret = CcuDevMgrImp::GetXnBaseAddr(deviceLogicId, anotherDieId, transDep.xnBaseAddr[anotherDieId]);
127 544 : 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 3008 : transDep.ccuResSpaceTokenInfo = CcuRep::GetToken(ccuTokenInfo.first, ccuTokenInfo.second, 1);
136 : // 获取hbm token信息
137 3008 : transDep.memTokenInfo = hbmTokenInfo;
138 3008 : }
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 157 : uint32_t CcuRepTranslator::GetInstrNum(const int32_t devLogicId)
151 : {
152 157 : CcuVersion tempCcuVersion = CcuVersion::CCU_INVALID;
153 157 : HcclResult ret = CcuDevMgrImp::GetCcuVersion(devLogicId, tempCcuVersion);
154 157 : if (ret != HcclResult::HCCL_SUCCESS || tempCcuVersion == CcuVersion::CCU_INVALID) {
155 0 : Hccl::THROW<Hccl::CcuApiException>("[CcuRepTranslator] GetInstrNum: Invalid CCU Type!");
156 : }
157 :
158 157 : return tempCcuVersion == CcuVersion::CCU_V1 ?
159 : 4 // 4:翻译器翻译过程中额外需要的指令空间大小(插入3条通用操作指令+1条终止指令)
160 : :
161 157 : 13; // 13:翻译器翻译过程中额外需要的指令空间大小(插入3条通用操作指令+1条终止指令+9条repJump)
162 : }
163 :
164 3008 : CcuResReq CcuRepTranslator::GetResReq(const int32_t devLogicId, uint8_t dieId)
165 : {
166 : // 申请离散 xn 资源
167 : // 需要申请若干xn、gsa、cke设置为固定值用于通用操作
168 3008 : CcuVersion tempCcuVersion = CcuVersion::CCU_INVALID;
169 3008 : HcclResult ret = CcuDevMgrImp::GetCcuVersion(devLogicId, tempCcuVersion);
170 3008 : if (ret != HcclResult::HCCL_SUCCESS || tempCcuVersion == CcuVersion::CCU_INVALID) {
171 0 : Hccl::THROW<Hccl::CcuApiException>("[CcuRepTranslator] GetResReq: Invalid CCU Type!");
172 : }
173 :
174 3008 : CcuResReq resReq;
175 3008 : int varNum = XN_NUM;
176 3008 : int gsaNum = tempCcuVersion == CcuVersion::CCU_V1 ? GSA_NUM : 0;
177 3008 : resReq.xnReq[dieId] = varNum;
178 3008 : resReq.gsaReq[dieId] = gsaNum;
179 3008 : resReq.ckeReq[dieId] = CKE_NUM;
180 6016 : return resReq;
181 : }
182 :
183 3008 : void CcuRepTranslator::GetRes(CcuRepResource& res)
184 : {
185 3008 : int varNum = XN_NUM;
186 3008 : int gsaNum = ccuVersion == CcuVersion::CCU_V1 ? GSA_NUM : 0;
187 15040 : for (int i = 0; i < varNum; i++) {
188 12032 : res.variable[transDep.dieId].push_back(var[i]);
189 : }
190 10400 : for (int i = 0; i < gsaNum; i++) {
191 7392 : res.address[transDep.dieId].push_back(addr[i]);
192 : }
193 9024 : for (int i = 0; i < CKE_NUM; i++) {
194 6016 : res.completedEvent[transDep.dieId].push_back(signal[i]);
195 : }
196 3008 : }
197 :
198 1206 : void CcuRepTranslator::PreProcess(std::shared_ptr<CcuRepBase> rep)
199 : {
200 1206 : auto repType = rep->Type();
201 1206 : 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 1206 : } else if (repType == CcuRepType::LOOP_BLOCK) {
206 42 : auto loopBlock = std::static_pointer_cast<CcuRepLoopBlock>(rep);
207 42 : refManager->SetRefBlock(loopBlock->GetLabel(), loopBlock);
208 1202 : } 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 1160 : } else if (repType == CcuRepType::LOOP_CALL) {
213 0 : BuildReference<CcuRepLoopCall, CcuRepLoopBlock>(rep);
214 1155 : } else if (repType == CcuRepType::LOOP) {
215 0 : BuildReference<CcuRepLoop, CcuRepLoopBlock>(rep);
216 : }
217 1206 : }
218 :
219 188 : 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 188 : constexpr uint32_t maxTryCount = 10; // 最大尝试次数10
224 188 : uint32_t tryCount = 0;
225 188 : uint32_t restCount = 0;
226 :
227 188 : auto funcInVar = refManager.get()->GetFuncIn();
228 188 : int funcArgIndex = 0;
229 :
230 : do {
231 208 : restCount = 0;
232 4311 : for (uint32_t index = 0; index < repVec.size(); index++) {
233 4104 : if (!filter(repVec[index])) {
234 2134 : continue;
235 : }
236 :
237 1970 : if (repVec[index]->Translated()) {
238 764 : continue;
239 : }
240 :
241 1206 : if (repVec[index]->Type() == CcuRepType::LOAD_ARG && transDep.isFuncBlock) {
242 0 : transDep.loadXnId = funcInVar[funcArgIndex++].Id();
243 : }
244 :
245 1206 : PreProcess(repVec[index]);
246 1206 : bool flag = repVec[index]->Translate(ccuKernel, instr, instrId, transDep);
247 1205 : if (!flag) {
248 126 : restCount++;
249 : }
250 : }
251 207 : tryCount++;
252 207 : HCCL_INFO("tryCount = %u, remaining representation = %u", tryCount, restCount);
253 207 : } while (restCount > 0 && tryCount < maxTryCount);
254 :
255 187 : 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 188 : }
266 :
267 : namespace {
268 :
269 : // 收集 LOAD_ARG rep 并按全局 argId 升序排序, 确保 LoadSqeArgs 指令在 mission 切分时
270 : // 落入与其 slot id 匹配的 mission (避免用户乱序 LoadArg 导致取参错位).
271 : std::vector<std::shared_ptr<CcuRepBase>>
272 46 : CollectSortedLoadArgReps(const std::vector<std::shared_ptr<CcuRepBase>>& repVec)
273 : {
274 46 : std::vector<std::shared_ptr<CcuRepBase>> sortedLoadArgReps;
275 46 : sortedLoadArgReps.reserve(repVec.size());
276 1136 : for (const auto& rep : repVec) {
277 1090 : if (rep->Type() == CcuRepType::LOAD_ARG) {
278 47 : sortedLoadArgReps.push_back(rep);
279 : }
280 : }
281 46 : 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 46 : return sortedLoadArgReps;
288 0 : }
289 :
290 : // 调用 V2 后端优化器 (极简 CkeOnly 档: 只按 CKE 写后读补 NOP, 不重排 / 不重命名寄存器).
291 : CcuInstrInfo
292 17 : RunV2BackendOptimizer(const CcuInstrInfo& instrInfo, CcuKernel* ccuKernel, const TransDep& transDep)
293 : {
294 : (void)ccuKernel; // CkeOnly 不使用 pinned Xn / pinned 组.
295 17 : HCCL_INFO("[CcuMicrocodeOpt] running backend optimizer (V2)");
296 : CcuInstrInfo optimized
297 17 : = CcuOpt::MicrocodeOptimizer::Run(instrInfo, transDep.reserveXnId, transDep.reserveCkeId);
298 17 : HCCL_INFO(
299 : "[CcuMicrocodeOpt] before instrCount=%u, after instrCount=%u", instrInfo.instrCount,
300 : optimized.instrCount);
301 17 : return optimized;
302 0 : }
303 :
304 : } // namespace
305 :
306 46 : CcuInstrInfo CcuRepTranslator::Translate(
307 : CcuKernel* ccuKernel, const std::vector<std::shared_ptr<CcuRepBase>>& repVec, uint16_t startInstrId,
308 : bool isFuncBlock)
309 : {
310 46 : constexpr uint32_t defaultInstrCapacity = 32 * 1024; // 默认最大容量32 * 1024条
311 46 : CcuInstrInfo instrInfo;
312 46 : instrInfo.instrVec.resize(defaultInstrCapacity);
313 46 : CcuInstr* instr = instrInfo.instrVec.data();
314 46 : uint16_t curInstrId = startInstrId;
315 :
316 46 : BindResource(isFuncBlock);
317 :
318 : // 翻译LoopBlock
319 46 : Translate(ccuKernel, repVec, instr, curInstrId, [](std::shared_ptr<CcuRepBase> rep) -> bool {
320 1090 : return rep->Type() == CcuRepType::LOOP_BLOCK;
321 : });
322 :
323 : // 翻译funcBlock
324 46 : Translate(ccuKernel, repVec, instr, curInstrId, [](std::shared_ptr<CcuRepBase> rep) -> bool {
325 1090 : return rep->Type() == CcuRepType::FUNC_BLOCK;
326 : });
327 :
328 46 : uint16_t missionStartInstrId = curInstrId;
329 :
330 : // 翻译Load (按全局 argId 升序).
331 46 : std::vector<std::shared_ptr<CcuRepBase>> sortedLoadArgReps = CollectSortedLoadArgReps(repVec);
332 46 : Translate(ccuKernel, sortedLoadArgReps, instr, curInstrId, [](std::shared_ptr<CcuRepBase> rep) -> bool {
333 47 : return rep->Type() == CcuRepType::LOAD_ARG;
334 : });
335 :
336 : // 插入通用操作
337 46 : CommonProcess(ccuKernel, instr, curInstrId);
338 :
339 : // 翻译主体
340 47 : Translate(ccuKernel, repVec, instr, curInstrId, []([[maybe_unused]] std::shared_ptr<CcuRepBase> rep) -> bool {
341 1872 : return true;
342 : });
343 :
344 45 : FinishMainBlock(instr, curInstrId);
345 :
346 45 : instrInfo.startInstrId = startInstrId;
347 45 : instrInfo.instrCount = curInstrId - startInstrId;
348 45 : instrInfo.missionStartInstrId = missionStartInstrId;
349 45 : instrInfo.missionInstrCount = curInstrId - missionStartInstrId;
350 45 : instrInfo.instrVec.resize(instrInfo.instrCount);
351 :
352 45 : DumpRep(repVec, instrInfo);
353 45 : DumpInstruction(instrInfo);
354 :
355 45 : if (ccuVersion == CcuVersion::CCU_V2) {
356 17 : CcuInstrInfo optimizedInstrInfo = RunV2BackendOptimizer(instrInfo, ccuKernel, transDep);
357 17 : HCCL_INFO("[CcuMicrocodeOpt] dump instruction after backend optimizer:");
358 17 : DumpInstruction(optimizedInstrInfo);
359 17 : return optimizedInstrInfo;
360 0 : }
361 :
362 28 : return instrInfo;
363 47 : }
364 :
365 46 : void CcuRepTranslator::CommonProcess(CcuKernel* ccuKernel, CcuInstr*& instr, uint16_t& instrId)
366 : {
367 46 : if (ccuVersion == CcuVersion::CCU_INVALID) {
368 0 : Hccl::THROW<Hccl::InternalException>("[CcuRepTranslator] Unexpected ccuVersion[Invalid]");
369 : }
370 46 : if (ccuVersion == CcuVersion::CCU_V1) {
371 29 : LoadImdToXnInstr(instr++, var[0].Id(), 0);
372 29 : LoadImdToGSAInstr(instr++, addr[0].Id(), 0);
373 29 : SetCKEInstr(instr++, signal[0].Id(), 0xffff, 0, 0, 1);
374 : } else {
375 17 : CcuV2::AssignI(instr++, var[0].Id(), 0);
376 17 : CcuV2::AssignI(instr++, var[XN_NUM - 1].Id(), 0);
377 17 : SetCKEInstr(instr++, signal[0].Id(), 0xffff, 0, 0, 1);
378 : }
379 :
380 : // 遍历需要赋值的常量,A5场景下暂为空表
381 46 : std::unordered_map<uint64_t, CcuRep::Variable>& constValue2VarMap = ccuKernel->GetConstValue2VarMap();
382 46 : u32 constValueNum = constValue2VarMap.size();
383 49 : for (auto elem : constValue2VarMap) {
384 3 : uint64_t constValue = elem.first;
385 3 : CcuRep::Variable curVariable = elem.second;
386 3 : if (ccuVersion == CcuVersion::CCU_V1) {
387 0 : LoadImdToXnInstr(instr++, curVariable.Id(), constValue);
388 : } else {
389 3 : CcuV2::AssignI(instr++, curVariable.Id(), constValue);
390 : }
391 3 : }
392 :
393 46 : u32 instrNum = 3 + constValueNum;
394 46 : if (instrId > UINT16_MAX - instrNum) {
395 0 : Hccl::THROW<Hccl::InternalException>("integer overflow occurs");
396 : }
397 46 : instrId += instrNum; // 插入3条指令
398 46 : }
399 :
400 45 : void CcuRepTranslator::FinishMainBlock(CcuInstr*& instr, uint16_t& instrId)
401 : {
402 45 : if (ccuVersion == CcuVersion::CCU_V1) {
403 28 : if (transDep.isFuncBlock) {
404 0 : JumpInstr(instr++, refManager.get()->GetFuncRet(FUNC_NEST_MAX).Id(), transDep.reserveXnId, 1);
405 : } else {
406 28 : LoadImdToXnInstr(instr++, var[0].Id(), 0);
407 : }
408 28 : instrId++;
409 : } else {
410 17 : if (transDep.isFuncBlock) {
411 0 : CcuV2::RelJmp(
412 0 : instr, refManager.get()->GetFuncRet(FUNC_NEST_MAX).Id(), instrId + V2_RELJMP_INSTR_NUM,
413 0 : transDep.commXn[0], transDep.commXn[1]);
414 0 : instr += V2_RELJMP_INSTR_NUM;
415 0 : CcuV2::Jump(
416 0 : instr++, refManager.get()->GetFuncRet(FUNC_NEST_MAX).Id(), transDep.reserveXnId,
417 0 : transDep.reserveXnId, 0);
418 : } else {
419 187 : for (int i = 0; i < V2_FINISH_BLOCK_INSTR_NUM; i++) {
420 170 : HCCL_INFO("FinishMainBlock Add Nop: index[%d], instrId[%d]", i, instrId);
421 170 : CcuV2::Nop(instr++);
422 : }
423 : }
424 17 : instrId += V2_FINISH_BLOCK_INSTR_NUM;
425 : }
426 :
427 45 : if (instrId > UINT16_MAX - 1) {
428 0 : Hccl::THROW<Hccl::InternalException>("integer overflow occurs");
429 : }
430 45 : }
431 :
432 62 : void CcuRepTranslator::DumpInstruction(const CcuInstrInfo& instrInfo) const
433 : {
434 62 : HCCL_INFO(
435 : "CcuInstrInfo: startInstrId = %u, instrCount = %u, missionStartInstrId = %u, missionInstrCount = %u",
436 : instrInfo.startInstrId, instrInfo.instrCount, instrInfo.missionStartInstrId, instrInfo.missionInstrCount);
437 2871 : for (uint16_t index = 0; index < instrInfo.instrVec.size(); index++) {
438 2809 : if (ccuVersion == CcuVersion::CCU_V1) {
439 1241 : HCCL_INFO(
440 : "%d: %s", instrInfo.startInstrId + index, ParseInstr(instrInfo.instrVec.data() + index).c_str());
441 : } else {
442 1568 : HCCL_INFO(
443 : "%d: %s", instrInfo.startInstrId + index,
444 : CcuV2::ParseInstrV2(instrInfo.instrVec.data() + index).c_str());
445 : }
446 : }
447 62 : }
448 :
449 45 : void CcuRepTranslator::DumpRep(
450 : const std::vector<std::shared_ptr<CcuRepBase>>& repVec, const CcuInstrInfo& instrInfo) const
451 : {
452 45 : PLF_CONFIG_INFO(PLF_TASK, "Translated Ccu Rep:");
453 1117 : for (uint32_t index = 0; index < repVec.size(); index++) {
454 1072 : uint16_t startInstrId = repVec[index]->StartInstrId();
455 1072 : uint32_t sum = static_cast<uint32_t>(startInstrId) + repVec[index]->InstrCount();
456 1072 : if (sum > UINT16_MAX) {
457 0 : HCCL_ERROR(
458 : "instrId overflow: startInstrId[%u] + InstrCount[%u] = %u exceeds UINT16_MAX", startInstrId,
459 : repVec[index]->InstrCount(), sum);
460 0 : continue;
461 : }
462 1072 : uint16_t endInstrId = static_cast<uint16_t>(sum);
463 1072 : PLF_CONFIG_INFO(
464 : PLF_TASK, "rep[%u]: %s Instr[%u--%u]", index, repVec[index]->Describe().c_str(), startInstrId,
465 : endInstrId);
466 2737 : for (uint16_t instrId = startInstrId; instrId < endInstrId; instrId++) {
467 1665 : if (instrId < instrInfo.startInstrId) {
468 0 : HCCL_ERROR("instrId[%u] less than startInstrId[%u]", instrId, instrInfo.startInstrId);
469 0 : continue;
470 : }
471 1665 : if (ccuVersion == CcuVersion::CCU_V1) {
472 1135 : PLF_CONFIG_INFO(
473 : PLF_TASK, "microcode[%u]: %s", instrId,
474 : ParseInstr(instrInfo.instrVec.data() + (instrId - instrInfo.startInstrId)).c_str());
475 : } else {
476 530 : PLF_CONFIG_INFO(
477 : PLF_TASK, "microcode[%u]: %s", instrId,
478 : CcuV2::ParseInstrV2(instrInfo.instrVec.data() + (instrId - instrInfo.startInstrId)).c_str());
479 : }
480 : }
481 : }
482 45 : }
483 :
484 46 : void CcuRepTranslator::BindResource(bool isFuncBlock)
485 : {
486 : // 在V2场景下不会为addr数组申请资源,故reserveGsaId和commGsa中实际填的都是默认值0
487 46 : transDep.reserveXnId = var[0].Id();
488 46 : transDep.reserveGsaId = addr[0].Id();
489 46 : transDep.reserveCkeId = signal[0].Id();
490 184 : for (int i = 0; i < XN_NUM - 1; i++) {
491 138 : transDep.commXn[i] = var[i + 1].Id();
492 : }
493 138 : for (int i = 0; i < GSA_NUM - 1; i++) {
494 92 : transDep.commGsa[i] = addr[i + 1].Id();
495 : }
496 46 : transDep.commSignal = signal[1].Id();
497 46 : transDep.isFuncBlock = isFuncBlock;
498 46 : HCCL_INFO(
499 : "TransDep info: logicalId = %d, dieId = %u, reserveXnId = %u, reserveGsaId = %u, reserveCkeId = %u, "
500 : "innerDieChannelId = %u, interDieChannelId = %u",
501 : transDep.logicalId, transDep.dieId, transDep.reserveXnId, transDep.reserveGsaId, transDep.reserveCkeId,
502 : transDep.reserveChannalId[0], transDep.reserveChannalId[1]);
503 46 : }
504 : }; // namespace CcuRep
505 : }; // namespace hcomm
|