Line data Source code
1 : /**
2 : * Copyright (c) 2025 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_kernel.h"
12 : #include "ccu_rep_v1.h"
13 : #include "ccu_kernel_resource.h"
14 : #include "ccu_microcode_v1.h"
15 :
16 : #include "ccu_types.h"
17 : #include "exception_util.h"
18 : #include "ccu_api_exception.h"
19 : #include "ccu_dev_mgr_imp.h"
20 : #include "env_config.h"
21 : #include "ccu_rep_type_v1.h"
22 :
23 : #include "hcomm_c_adpt.h"
24 :
25 : #include "ccu_rep_context_v1.h"
26 : #include "ccu_rep_funccall_v1.h"
27 : #include "../../endpoint_pairs/channels/ccu/ccu_urma_channel.h"
28 :
29 : #include "ccu_log.h"
30 :
31 : #include "hcom_common.h"
32 :
33 : // todo: 引入头文件需要检查
34 : #include "ccu_assist_v1.h"
35 : #include "hccl_comm_pub.h"
36 : #include "hcclCommDfx.h"
37 : #include "task_info.h"
38 : #include "task_param.h"
39 :
40 : #include "ccu_ins_generater_base.h"
41 : #include "ccu_ins_generater_v1.h"
42 : #include "unified_platform/pub_inc/config_plf_log.h"
43 :
44 : namespace hcomm {
45 :
46 : using Hccl::PLF_DATA_OP;
47 :
48 : constexpr uint32_t TOKEN_VALUE_INDEX = 2;
49 : constexpr uint16_t INVALID_U16 = 65535;
50 :
51 : using CcuRep::CcuInsGeneraterBase;
52 : using CcuRep::CcuInsGeneraterV1;
53 :
54 : template <typename T>
55 551 : T CcuKernel::CreateResAssist(
56 : std::array<std::vector<T>, CCU_MAX_IODIE_NUM> &resRecord)
57 : {
58 : // kernel确认die之前默认为0,需要刷新资源
59 : // 确认die之后按实际使用die分配资源
60 551 : const uint32_t dieId = GetDieId();
61 551 : resRecord[dieId].emplace_back(this);
62 551 : auto& item = resRecord[dieId].back();
63 551 : item.Reset(resRecord[dieId].size(), dieId);
64 551 : return item;
65 : }
66 :
67 : template <typename T>
68 19 : std::vector<T> CcuKernel::CreateBlockResAssist(
69 : const uint32_t count,
70 : std::array<std::vector<T>, CCU_MAX_IODIE_NUM> &resRecord)
71 : {
72 19 : constexpr uint16_t CCU_BLOCK_RES_ID_BASE = 0x1000; // block 批量分配资源 id 基址,与单资源 id 区间隔离便于 DFX 定位
73 19 : std::vector<T> block;
74 19 : block.reserve(count);
75 19 : const uint32_t dieId = GetDieId();
76 258 : for (size_t i = 0; i < count; i++) {
77 239 : block.emplace_back(this);
78 239 : block.back().Reset(static_cast<uint16_t>(CCU_BLOCK_RES_ID_BASE + resRecord[dieId].size() + i), dieId);
79 : }
80 19 : resRecord[dieId].insert(resRecord[dieId].end(), block.begin(), block.end());
81 19 : return block;
82 0 : }
83 :
84 63 : CcuKernel::~CcuKernel()
85 : {
86 63 : }
87 :
88 10 : static HcclResult GetDieIdByChannel(const ChannelHandle channel, uint32_t &dieId)
89 : {
90 10 : void *channelPtr{nullptr};
91 10 : CHK_RET(static_cast<HcclResult>(HcommChannelGet(channel, &channelPtr)));
92 10 : auto *channelImpl = dynamic_cast<CcuUrmaChannel *>(static_cast<Channel *>(channelPtr));
93 10 : if (channelImpl == nullptr) {
94 0 : HCCL_ERROR("[%s] failed to cast channel[0x%llx] to CcuUrmaChannel", __func__, channel);
95 0 : return HcclResult::HCCL_E_PTR;
96 : }
97 10 : dieId = channelImpl->GetDieId();
98 10 : HCCL_INFO("[%s], channelHandle[0x%llx], dieId[%u]", __func__, channel, dieId);
99 10 : return HcclResult::HCCL_SUCCESS;
100 : }
101 :
102 19 : static HcclResult GetDieIdByChannels(const std::unordered_set<ChannelHandle> &channels, uint32_t &dieId)
103 : {
104 19 : if (channels.empty()) {
105 14 : int32_t devLogicId = HcclGetThreadDeviceId();
106 14 : for (uint32_t die = 0; die < CCU_MAX_IODIE_NUM; die++) {
107 14 : bool enableFlag = false;
108 28 : CHK_RET(static_cast<HcclResult>(CcuGetDieEnableInfo(devLogicId, die, enableFlag)));
109 14 : if (enableFlag) {
110 14 : dieId = die;
111 14 : return HcclResult::HCCL_SUCCESS;
112 : }
113 : }
114 :
115 0 : HCCL_ERROR("[CcuKernel][%s] failed, all dies are disable, devLogicId[%d].",
116 : __func__, devLogicId);
117 0 : return HcclResult::HCCL_E_INTERNAL;
118 : }
119 :
120 5 : uint32_t firstDieId = 0;
121 5 : CHK_RET(GetDieIdByChannel(*channels.begin(), firstDieId));
122 10 : for (const auto channel : channels) {
123 5 : uint32_t nextDieId = 0;
124 5 : CHK_RET(GetDieIdByChannel(channel, nextDieId));
125 5 : if (firstDieId != nextDieId) {
126 0 : HCCL_ERROR("[%s] failed, the dies of channels are not same.", __func__);
127 0 : return HcclResult::HCCL_E_PARA;
128 : }
129 : }
130 :
131 5 : dieId = firstDieId;
132 5 : return HcclResult::HCCL_SUCCESS;
133 : }
134 :
135 19 : static void MoveResourcesToDie(CcuRepResource &res, uint32_t targetDieId)
136 : {
137 19 : if (targetDieId == 0) return; // 初始资源位于die0,不用设置
138 :
139 0 : auto moveAndSet = [&](auto &arr) {
140 0 : arr[targetDieId] = std::move(arr[0]);
141 0 : for (auto &item : arr[targetDieId]) item.SetDieId(targetDieId);
142 0 : };
143 :
144 0 : moveAndSet(res.ccubufs);
145 0 : moveAndSet(res.blockCcubufs);
146 0 : moveAndSet(res.executor);
147 0 : moveAndSet(res.blockExecutor);
148 0 : moveAndSet(res.completedEvent);
149 0 : moveAndSet(res.blockCompletedEvent);
150 0 : moveAndSet(res.address);
151 0 : moveAndSet(res.continuousVariable);
152 0 : moveAndSet(res.variable);
153 0 : moveAndSet(res.localNotify);
154 : }
155 :
156 26 : HcclResult CcuKernel::SetupProfilingInfo(const char *kernelFuncName)
157 : {
158 26 : if (kernelFuncName == nullptr || strlen(kernelFuncName) == 0) {
159 0 : name_ = std::string("CCU_KERNEL"); // 默认名称
160 0 : AddSqeProfiling(name_);
161 0 : return HcclResult::HCCL_SUCCESS;
162 : }
163 :
164 26 : constexpr size_t MAX_KERNEL_FUNC_NAME_LEN = 128;
165 26 : const auto nameLen = strlen(kernelFuncName);
166 26 : if (nameLen > MAX_KERNEL_FUNC_NAME_LEN) {
167 0 : name_ = std::string(kernelFuncName, MAX_KERNEL_FUNC_NAME_LEN);
168 0 : HCCL_WARNING("[CcuKernel][%s] kernelFuncName is too long, reset to %s.",
169 : __func__, name_.c_str());
170 : }
171 :
172 : // 生成SQE粒度profiling信息,此时未选择die,默认die 0
173 26 : AddSqeProfiling(name_);
174 26 : return HcclResult::HCCL_SUCCESS;
175 : }
176 :
177 19 : static HcclResult UpdateProfilingInfo(
178 : std::vector<CcuProfilingInfo> &profilingInfos, uint32_t dieId,
179 : const std::string &kernelName)
180 : {
181 19 : if (dieId == 0) {
182 : // 与默认dieId相同,不需要修改
183 19 : return HcclResult::HCCL_SUCCESS;
184 : }
185 :
186 : // 正常情况仅首个info包含die信息,仅应为CCU_TASK_PROFILING类型
187 0 : if (UNLIKELY(profilingInfos.empty())) {
188 : // profiling不属于主流程,不打断算子业务
189 0 : HCCL_INFO("[%s] passed, profiling infos are empty, ccu kernel func[%s].",
190 : __func__, kernelName.c_str());
191 0 : return HcclResult::HCCL_SUCCESS;
192 : }
193 :
194 : // 根据选择的die跟新profiling信息
195 0 : for (auto &info : profilingInfos) {
196 0 : info.dieId = dieId;
197 : }
198 :
199 0 : HCCL_INFO("[%s] reset profiling info dieId to [%u], ccu kernel func[%s].",
200 : __func__, dieId, kernelName.c_str());
201 0 : return HcclResult::HCCL_SUCCESS;
202 : }
203 :
204 19 : HcclResult CcuKernel::SelectDie()
205 : {
206 19 : uint32_t dieId{0};
207 19 : CHK_RET(GetDieIdByChannels(channels_, dieId));
208 19 : CHK_PRT_RET(dieId >= CCU_MAX_IODIE_NUM,
209 : HCCL_ERROR("[CcuKernel][%s] failed, dieId[%u] should be less than [%u].",
210 : __func__, dieId, CCU_MAX_IODIE_NUM),
211 : HcclResult::HCCL_E_PARA);
212 19 : SetDieId(dieId);
213 19 : MoveResourcesToDie(res_, dieId);
214 19 : (void)UpdateProfilingInfo(profilingInfo, dieId, name_);
215 :
216 19 : return HcclResult::HCCL_SUCCESS;
217 : }
218 :
219 26 : void CcuKernel::SetInsGenerater(CcuInsGeneraterBase* insGeneraterBase)
220 : {
221 26 : insGenerator = insGeneraterBase;
222 26 : }
223 :
224 3 : CcuResult CcuKernel::ValidateTaskArgs(const uint64_t *taskArgs, uint32_t argsNum) const
225 : {
226 3 : if (loadArgUsedSet_.size() != argsNum) {
227 0 : HCCL_ERROR("[CcuKernel][%s] failed, args number does not match the Load instruction, "
228 : "argsNum = %u, loaded = %zu", __func__, argsNum, loadArgUsedSet_.size());
229 0 : return CcuResult::CCU_E_INTERNAL;
230 : }
231 33 : for (uint32_t i = 0; i < argsNum; ++i) {
232 30 : if (loadArgUsedSet_.count(i) == 0) {
233 0 : HCCL_ERROR("[CcuKernel][%s] failed, argId %u not loaded (argsNum=%u)",
234 : __func__, i, argsNum);
235 0 : return CcuResult::CCU_E_INTERNAL;
236 : }
237 : }
238 3 : if (argsNum != 0) {
239 2 : CCU_CHK_PTR_NULL(taskArgs);
240 : }
241 3 : if (instrInfo_.missionInstrCount == 0 || instrInfo_.instrVec.empty()) {
242 0 : HCCL_ERROR("[CcuKernel][%s] failed, mission instructions are empty, "
243 : "the kernel is not been translated yet.", __func__);
244 0 : return CcuResult::CCU_E_INTERNAL;
245 : }
246 3 : return CcuResult::CCU_SUCCESS;
247 : }
248 :
249 5 : void CcuKernel::FillTaskParam(CcuTaskParam ¶m, uint32_t index, uint32_t seqNum,
250 : const uint64_t *taskArgs, uint32_t argsNum) const
251 : {
252 5 : param.dieId = GetDieId();
253 5 : param.missionId = GetMissionId();
254 5 : param.instStartId = instrInfo_.missionStartInstrId + index * CCU_SQE_ARGS_LEN;
255 5 : param.key = GetMissionKey();
256 5 : param.argSize = CCU_SQE_ARGS_LEN;
257 :
258 5 : const uint32_t preMissionInsCnt = index * CCU_SQE_ARGS_LEN;
259 5 : const bool isLast = (index == seqNum - 1);
260 5 : param.instCnt = isLast ? (instrInfo_.missionInstrCount - preMissionInsCnt) : CCU_SQE_ARGS_LEN;
261 :
262 5 : if (argsNum > preMissionInsCnt) {
263 : const uint32_t argsToCopy = isLast
264 4 : ? std::min(argsNum - preMissionInsCnt, CCU_SQE_ARGS_LEN)
265 4 : : CCU_SQE_ARGS_LEN;
266 4 : std::copy(taskArgs + preMissionInsCnt, taskArgs + preMissionInsCnt + argsToCopy,
267 4 : std::begin(param.args));
268 : }
269 :
270 5 : HCCL_INFO("[GeneTaskParam]task Param, dieId[%u] missionId[%u] instStartId[%u] instCnt[%u], argSize[%u]",
271 : param.dieId, param.missionId, param.instStartId, param.instCnt, param.argSize);
272 5 : }
273 :
274 3 : CcuResult CcuKernel::GeneTaskParams(const uint64_t *taskArgs, uint32_t argsNum,
275 : std::vector<CcuTaskParam> &taskParams)
276 : {
277 3 : CCU_CHK_RET(ValidateTaskArgs(taskArgs, argsNum));
278 :
279 : // 如果agrs数量超过sqe arg的最大数量,则返回多个TaskParam,前面几个只从sqe中加载args;
280 : // args数量大于等于0、小于等于最大值时,返回1个TaskParam
281 3 : const uint32_t seqNum
282 3 : = (argsNum / CCU_SQE_ARGS_LEN) + ((argsNum % CCU_SQE_ARGS_LEN) == 0 ? 0 : 1) + (argsNum == 0 ? 1 : 0);
283 :
284 3 : const uint32_t preMissonSqeInsCnt = (seqNum - 1) * CCU_SQE_ARGS_LEN;
285 3 : if (instrInfo_.missionInstrCount < preMissonSqeInsCnt) {
286 0 : HCCL_ERROR("[CcuKernel][%s] failed, missionInstrCount[%u] should be greater "
287 : "than preMissonSqeInsCnt[%u].", __func__, instrInfo_.missionInstrCount,
288 : preMissonSqeInsCnt);
289 0 : return CcuResult::CCU_E_INTERNAL;
290 : }
291 :
292 3 : taskParams.resize(seqNum);
293 8 : for (uint32_t index = 0; index < seqNum; index++) {
294 5 : FillTaskParam(taskParams[index], index, seqNum, taskArgs, argsNum);
295 : }
296 :
297 3 : return CcuResult::CCU_SUCCESS;
298 : }
299 :
300 6 : HcclResult CcuKernel::CreateVariable(const ChannelHandle channel, uint32_t varIndex, CcuRep::Variable *var)
301 : {
302 6 : channels_.insert(channel);
303 :
304 6 : void *channelPtr{nullptr};
305 6 : CHK_RET(static_cast<HcclResult>(HcommChannelGet(channel, &channelPtr)));
306 6 : auto *channelImpl = dynamic_cast<CcuUrmaChannel *>(static_cast<Channel *>(channelPtr));
307 6 : if (channelImpl == nullptr) {
308 0 : HCCL_ERROR("[%s] failed to cast channel[0x%llx] to CcuUrmaChannel", __func__, channel);
309 0 : return HcclResult::HCCL_E_PTR;
310 : }
311 6 : uint32_t locXnId{0};
312 6 : CHK_RET(channelImpl->GetLocXnByIndex(varIndex, locXnId));
313 6 : var->Reset(locXnId, channelImpl->GetDieId());
314 6 : return HcclResult::HCCL_SUCCESS;
315 : }
316 :
317 19 : CcuRepResource &CcuKernel::GetResource()
318 : {
319 19 : return res_;
320 : }
321 :
322 38 : CcuResReq CcuKernel::GetResourceRequest()
323 : {
324 38 : CcuResReq req;
325 38 : uint32_t dieId = GetDieId();
326 38 : req.msReq[dieId] = res_.ccubufs[dieId].size();
327 38 : req.blockMsReq[dieId] = res_.blockCcubufs[dieId].size();
328 38 : req.ckeReq[dieId] = res_.completedEvent[dieId].size()
329 38 : + res_.localNotify[dieId].size();
330 38 : req.blockCkeReq[dieId] = res_.blockCompletedEvent[dieId].size();
331 38 : req.loopEngineReq[dieId] = res_.executor[dieId].size();
332 38 : req.blockLoopEngineReq[dieId] = res_.blockExecutor[dieId].size();
333 38 : req.gsaReq[dieId] = res_.address[dieId].size();
334 38 : req.xnReq[dieId] = res_.variable[dieId].size();
335 38 : req.continuousXnReq[dieId] = res_.continuousVariable[dieId].size();
336 :
337 38 : req.missionReq.reqType = MissionReqType::FUSION_MULTIPLE_DIE;
338 38 : req.missionReq.req[dieId] = 1;
339 :
340 : auto info
341 : = Hccl::StringFormat("resource request: dieId[%u], ms[%u], blockMs[%u], cke[%u], blockCke[%u], "
342 : "loopEngine[%u], blockLoopEngine[%u], gsa[%u], xn[%u], continuous xn[%u], missionId[%u]",
343 152 : dieId, req.msReq[dieId], req.blockMsReq[dieId], req.ckeReq[dieId], req.blockCkeReq[dieId],
344 152 : req.loopEngineReq[dieId], req.blockLoopEngineReq[dieId], req.gsaReq[dieId], req.xnReq[dieId],
345 38 : req.continuousXnReq[dieId], req.missionReq.req[dieId]);
346 :
347 38 : HCCL_INFO("%s", info.c_str());
348 :
349 76 : return req;
350 38 : }
351 :
352 : template<typename HandleType, typename ResourceType>
353 706 : static CcuResult GetResourceByHandle(
354 : std::unordered_map<HandleType, ResourceType> &resourceMap,
355 : HandleType handle, ResourceType **resource, const char *resourceType)
356 : {
357 706 : auto iter = resourceMap.find(handle);
358 706 : if (iter == resourceMap.end()) {
359 0 : HCCL_ERROR("[%s] failed to find %s by handle: 0x%llx", __func__, resourceType, handle);
360 0 : return CcuResult::CCU_E_NOT_FOUND;
361 : }
362 :
363 : // ccu资源本身可能重载=,对象赋值会被转换成指令,导致流程失败
364 706 : *resource = &(iter->second);
365 706 : return CcuResult::CCU_SUCCESS;
366 : }
367 :
368 531 : CcuResult CcuKernel::GetVariableByHandle(CcuVariableHandle varHandle, CcuRep::Variable **variable)
369 : {
370 531 : return GetResourceByHandle(ccuVarMap_, varHandle, variable, "variable");
371 : }
372 : //Alloc 相关接口
373 246 : CcuResult CcuKernel::VariableAlloc(CcuVariableHandle *varHandle)
374 : {
375 246 : PLF_CONFIG_INFO(PLF_DATA_OP, "[VariableAlloc]");
376 246 : const auto &var = CreateResAssist(res_.continuousVariable);
377 246 : CcuVariableHandle handle = ccuVarMap_.size();
378 246 : ccuVarMap_.emplace(handle, var);
379 :
380 246 : *varHandle = handle;
381 246 : return CcuResult::CCU_SUCCESS;
382 246 : }
383 3 : CcuResult CcuKernel::AddressAlloc(CcuAddressHandle *addrHandle)
384 : {
385 3 : PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAlloc]");
386 3 : const auto addr = CreateAddress();
387 3 : CcuAddressHandle handle = ccuAddrMap_.size();
388 3 : ccuAddrMap_.emplace(handle, addr);
389 3 : *addrHandle = handle;
390 3 : return CcuResult::CCU_SUCCESS;
391 3 : }
392 6 : CcuResult CcuKernel::EventAlloc(CcuEventHandle *eventHandle)
393 : {
394 6 : PLF_CONFIG_INFO(PLF_DATA_OP, "[EventAlloc]");
395 6 : const auto &event = CreateResAssist(res_.completedEvent);
396 6 : CcuEventHandle handle = ccuEventMap_.size();
397 6 : ccuEventMap_.emplace(handle, event);
398 6 : *eventHandle = handle;
399 6 : return CcuResult::CCU_SUCCESS;
400 6 : }
401 0 : CcuResult CcuKernel::BufferAlloc(CcuBufferHandle *bufHandle)
402 : {
403 0 : PLF_CONFIG_INFO(PLF_DATA_OP, "[BufferAlloc]");
404 0 : const auto &buf = CreateResAssist(res_.ccubufs);
405 0 : CcuBufferHandle handle = ccuBufferMap_.size();
406 0 : ccuBufferMap_.emplace(handle, buf);
407 0 : *bufHandle = handle;
408 0 : return CcuResult::CCU_SUCCESS;
409 0 : }
410 81 : CcuResult CcuKernel::LocalAddrAlloc(CcuLocalAddrHandle *localAddrHandle, CcuAddressHandle *addrHandle, CcuVariableHandle *tokenHandle)
411 : {
412 81 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalAddrAlloc]");
413 81 : auto localAddr = CreateLocalAddr();
414 :
415 81 : CcuAddressHandle aHandle = ccuAddrMap_.size();
416 81 : ccuAddrMap_.emplace(aHandle, localAddr.addr);
417 :
418 81 : CcuVariableHandle tHandle = ccuVarMap_.size();
419 81 : ccuVarMap_.emplace(tHandle, localAddr.token);
420 :
421 81 : CcuLocalAddrHandle laHandle = ccuLocalAddrMap_.size();
422 81 : ccuLocalAddrMap_.emplace(laHandle, localAddr);
423 :
424 81 : *localAddrHandle = laHandle;
425 81 : *addrHandle = aHandle;
426 81 : *tokenHandle = tHandle;
427 81 : return CcuResult::CCU_SUCCESS;
428 :
429 81 : }
430 20 : CcuResult CcuKernel::RemoteAddrAlloc(CcuRemoteAddrHandle *remoteAddrHandle, CcuAddressHandle *addrHandle, CcuVariableHandle *tokenHandle)
431 : {
432 20 : PLF_CONFIG_INFO(PLF_DATA_OP, "[RemoteAddrAlloc]");
433 20 : auto remoteAddr = CreateRemoteAddr();
434 :
435 20 : CcuAddressHandle aHandle = ccuAddrMap_.size();
436 20 : ccuAddrMap_.emplace(aHandle, remoteAddr.addr);
437 :
438 20 : CcuVariableHandle tHandle = ccuVarMap_.size();
439 20 : ccuVarMap_.emplace(tHandle, remoteAddr.token);
440 :
441 20 : CcuRemoteAddrHandle raHandle = ccuRemoteAddrMap_.size();
442 20 : ccuRemoteAddrMap_.emplace(raHandle, remoteAddr);
443 :
444 20 : *remoteAddrHandle = raHandle;
445 20 : *addrHandle = aHandle;
446 20 : *tokenHandle = tHandle;
447 20 : return CcuResult::CCU_SUCCESS;
448 20 : }
449 :
450 2 : CcuResult CcuKernel::BlockVariableAlloc(CcuVariableHandle *varHandles, uint32_t count)
451 : {
452 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[BlockVariableAlloc] count=%u", count);
453 2 : const auto& var = CreateBlockResAssist(count, res_.continuousVariable);
454 6 : for (uint32_t i = 0; i < count; i++) {
455 4 : CcuVariableHandle handle = ccuVarMap_.size();
456 4 : ccuVarMap_.emplace(handle, var[i]);
457 4 : varHandles[i] = handle;
458 : }
459 2 : return CcuResult::CCU_SUCCESS;
460 2 : }
461 :
462 3 : CcuResult CcuKernel::BlockEventAlloc(CcuEventHandle *eventHandles, uint32_t count)
463 : {
464 3 : PLF_CONFIG_INFO(PLF_DATA_OP, "[BlockEventAlloc] count=%u", count);
465 3 : const auto& event = CreateBlockResAssist(count, res_.blockCompletedEvent);
466 29 : for (uint32_t i = 0; i < count; i++) {
467 26 : CcuEventHandle handle = ccuEventMap_.size();
468 26 : ccuEventMap_.emplace(handle, event[i]);
469 26 : eventHandles[i] = handle;
470 : }
471 3 : return CcuResult::CCU_SUCCESS;
472 3 : }
473 :
474 4 : CcuResult CcuKernel::BlockBufferAlloc(CcuBufferHandle *bufHandles, uint32_t count)
475 : {
476 4 : PLF_CONFIG_INFO(PLF_DATA_OP, "[BlockBufferAlloc] count=%u", count);
477 4 : const auto& buffer = CreateBlockResAssist(count, res_.blockCcubufs);
478 198 : for (uint32_t i = 0; i < count; i++) {
479 194 : CcuBufferHandle handle = ccuBufferMap_.size();
480 194 : ccuBufferMap_.emplace(handle, buffer[i]);
481 194 : bufHandles[i] = handle;
482 : }
483 4 : return CcuResult::CCU_SUCCESS;
484 4 : }
485 :
486 6 : CcuResult CcuKernel::VariableCreateByChannel(ChannelHandle channel, uint32_t varIndex, CcuVariableHandle *varHandle)
487 : {
488 6 : PLF_CONFIG_INFO(PLF_DATA_OP, "[VariableCreateByChannel] channel=%llu, varIndex=%u", channel, varIndex);
489 6 : channels_.insert(channel);
490 6 : CcuRep::Variable var(this);
491 6 : CCU_CHK_RET(CreateVariable(channel, varIndex, &var));
492 6 : CcuVariableHandle handle = ccuVarMap_.size();
493 6 : ccuVarMap_.emplace(handle, var);
494 6 : *varHandle = handle;
495 6 : return CcuResult::CCU_SUCCESS;
496 6 : }
497 :
498 99 : CcuResult CcuKernel::VariableAssignImm(CcuVariableHandle varHandle, uint64_t immediate)
499 : {
500 99 : PLF_CONFIG_INFO(PLF_DATA_OP, "[VariableAssignImm] varHandle=%llu, immediate=%llu", varHandle, immediate);
501 99 : CcuRep::Variable *variable{nullptr};
502 99 : CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
503 : // 通过符号重载实现,内部记录rep;异常由入口 HcommCcuKernelRegister 的
504 : // CCU_EXCEPTION_HANDLE_BEGIN/END 统一接住,无需在此局部 try/catch。
505 99 : (*variable) = immediate;
506 99 : return CcuResult::CCU_SUCCESS;
507 : }
508 :
509 47 : CcuResult CcuKernel::VariableAssignVar(CcuVariableHandle varHandle, CcuVariableHandle varA)
510 : {
511 47 : PLF_CONFIG_INFO(PLF_DATA_OP, "[VariableAssignVar] varHandle=%llu, varA=%llu", varHandle, varA);
512 47 : CcuRep::Variable *variable{nullptr};
513 47 : CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
514 47 : CcuRep::Variable *variableA{nullptr};
515 47 : CCU_CHK_RET(GetVariableByHandle(varA, &variableA));
516 : // 通过符号重载实现,内部记录rep;异常由入口统一 catch。
517 47 : (*variable) = (*variableA);
518 47 : return CcuResult::CCU_SUCCESS;
519 : }
520 :
521 52 : CcuResult CcuKernel::VariableAddVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
522 : {
523 52 : PLF_CONFIG_INFO(PLF_DATA_OP, "[VariableAddVarToVar] varHandle=%llu, varAHandle=%llu, varBHandle=%llu",
524 : varHandle, varAHandle, varBHandle);
525 52 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
526 52 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
527 52 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
528 52 : CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
529 :
530 : // 通过符号重载实现,内部记录rep;异常由入口统一 catch。
531 52 : *resVar = *leftVar + *rightVar;
532 52 : return CcuResult::CCU_SUCCESS;
533 : }
534 :
535 0 : CcuResult CcuKernel::VariableSubVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
536 : {
537 0 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
538 0 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
539 0 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
540 0 : CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
541 :
542 0 : *resVar = *leftVar - *rightVar;
543 0 : return CcuResult::CCU_SUCCESS;
544 : }
545 :
546 0 : CcuResult CcuKernel::VariableMulVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
547 : {
548 0 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
549 0 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
550 0 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
551 0 : CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
552 :
553 0 : *resVar = *leftVar * *rightVar;
554 0 : return CcuResult::CCU_SUCCESS;
555 : }
556 :
557 0 : CcuResult CcuKernel::VariableAddImmToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, uint16_t immediate)
558 : {
559 0 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr};
560 0 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
561 0 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
562 :
563 0 : *resVar = *leftVar + immediate;
564 0 : return CcuResult::CCU_SUCCESS;
565 : }
566 :
567 0 : CcuResult CcuKernel::VariableSubImmToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, uint16_t immediate)
568 : {
569 0 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr};
570 0 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
571 0 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
572 :
573 0 : *resVar = *leftVar - immediate;
574 0 : return CcuResult::CCU_SUCCESS;
575 : }
576 :
577 0 : CcuResult CcuKernel::VariableMulImmToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, uint16_t immediate)
578 : {
579 0 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr};
580 0 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
581 0 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
582 :
583 0 : *resVar = *leftVar * immediate;
584 0 : return CcuResult::CCU_SUCCESS;
585 : }
586 :
587 0 : CcuResult CcuKernel::VariableAndVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
588 : {
589 0 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
590 0 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
591 0 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
592 0 : CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
593 :
594 0 : *resVar = *leftVar & *rightVar;
595 0 : return CcuResult::CCU_SUCCESS;
596 : }
597 :
598 0 : CcuResult CcuKernel::VariableOrVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
599 : {
600 0 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
601 0 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
602 0 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
603 0 : CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
604 :
605 0 : *resVar = *leftVar | *rightVar;
606 0 : return CcuResult::CCU_SUCCESS;
607 : }
608 :
609 0 : CcuResult CcuKernel::VariableXorVarToVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle, CcuVariableHandle varBHandle)
610 : {
611 0 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr}, *rightVar{nullptr};
612 0 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
613 0 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
614 0 : CCU_CHK_RET(GetVariableByHandle(varBHandle, &rightVar));
615 :
616 0 : *resVar = *leftVar ^ *rightVar;
617 0 : return CcuResult::CCU_SUCCESS;
618 : }
619 :
620 0 : CcuResult CcuKernel::VariableNotVar(CcuVariableHandle varHandle, CcuVariableHandle varAHandle)
621 : {
622 0 : CcuRep::Variable *resVar{nullptr}, *leftVar{nullptr};
623 0 : CCU_CHK_RET(GetVariableByHandle(varHandle, &resVar));
624 0 : CCU_CHK_RET(GetVariableByHandle(varAHandle, &leftVar));
625 :
626 0 : *resVar = ~(*leftVar);
627 0 : return CcuResult::CCU_SUCCESS;
628 : }
629 :
630 : /*========== Event信号同步类 相关接口 ==========*/
631 6 : CcuResult CcuKernel::EventRecord(CcuEventHandle eventHandle, uint32_t mask)
632 : {
633 6 : PLF_CONFIG_INFO(PLF_DATA_OP, "[EventRecord] eventHandle=%llu, mask=%u", eventHandle, mask);
634 6 : CcuRep::CompletedEvent *event{nullptr};
635 6 : CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
636 : // 复用已有的 RecordEvent 实现(内部 Append CcuRepLocRecordEvent)
637 6 : CCU_CHK_RET(RecordEvent(*event, mask));
638 5 : return CcuResult::CCU_SUCCESS;
639 : }
640 :
641 21 : CcuResult CcuKernel::EventWait(CcuEventHandle eventHandle, uint32_t mask)
642 : {
643 21 : PLF_CONFIG_INFO(PLF_DATA_OP, "[EventWait] eventHandle=%llu, mask=%u", eventHandle, mask);
644 21 : CcuRep::CompletedEvent *event{nullptr};
645 21 : CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
646 : // 复用已有的 WaitEvent 实现(内部 Append CcuRepLocWaitEvent)
647 21 : CCU_CHK_RET(WaitEvent(*event, mask));
648 21 : return CcuResult::CCU_SUCCESS;
649 : }
650 :
651 1 : CcuResult CcuKernel::LocalNotifyRecord(const char *notifyTag, const uint32_t mask)
652 : {
653 1 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalNotifyRecord] tag=%s, mask=%u", (notifyTag ? notifyTag : "null"), mask);
654 1 : if (notifyTag == nullptr) {
655 0 : HCCL_ERROR("[CcuKernel][%s] notifyTag is nullptr, please check.", __func__);
656 0 : return CcuResult::CCU_E_PTR;
657 : }
658 1 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
659 1 : HCCL_ERROR("[CcuKernel][%s] is not supported in loop block, please check.", __func__);
660 1 : return LatchBodyError(CcuResult::CCU_E_NOT_SUPPORT);
661 : }
662 :
663 0 : const std::string tagKey(notifyTag);
664 :
665 0 : auto &sharedNotifies = importedRes_.sharedNotifies;
666 0 : if (sharedNotifies.find(tagKey) == sharedNotifies.end()) {
667 0 : CcuRep::LocalNotify localNotify;
668 0 : sharedNotifies.insert({tagKey, localNotify});
669 0 : }
670 :
671 0 : Append(std::make_shared<CcuRep::CcuRepRecordSharedNotify>(insGenerator, sharedNotifies.at(tagKey), mask));
672 :
673 0 : return CcuResult::CCU_SUCCESS;
674 0 : }
675 :
676 0 : CcuResult CcuKernel::LocalNotifyWait(const char *notifyTag, const uint32_t mask)
677 : {
678 0 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalNotifyWait] tag=%s, mask=%u", (notifyTag ? notifyTag : "null"), mask);
679 0 : if (notifyTag == nullptr) {
680 0 : HCCL_ERROR("[CcuKernel][%s] notifyTag is nullptr, please check.", __func__);
681 0 : return CcuResult::CCU_E_PTR;
682 : }
683 :
684 0 : const std::string tagKey(notifyTag);
685 :
686 0 : auto &sharedNotifies = exportedRes_.sharedNotifies;
687 0 : if (sharedNotifies.find(tagKey) == sharedNotifies.end()) {
688 0 : CcuRep::LocalNotify notify = CreateLocalNotify();
689 0 : exportedRes_.sharedNotifies.insert({tagKey, notify});
690 0 : }
691 :
692 0 : bool isProfiling = CurrentBlock()->Type() != CcuRep::CcuRepType::LOOP_BLOCK;
693 0 : Append(std::make_shared<CcuRep::CcuRepLocWaitNotify>(
694 0 : insGenerator, exportedRes_.sharedNotifies.at(tagKey), mask, isProfiling));
695 0 : return CcuResult::CCU_SUCCESS;
696 0 : }
697 :
698 3 : CcuResult CcuKernel::NotifyRecord(const ChannelHandle channel,
699 : uint32_t remoteNotifyIdx, uint32_t mask)
700 : {
701 3 : PLF_CONFIG_INFO(PLF_DATA_OP, "[NotifyRecord] channel=%llu, remoteNotifyIdx=%u, mask=%u",
702 : channel, remoteNotifyIdx, mask);
703 3 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
704 1 : HCCL_ERROR("[%s] NotifyRecord is not allowed inside a ccu::Loop body", __func__);
705 1 : return LatchBodyError(CcuResult::CCU_E_NOT_SUPPORT);
706 : }
707 2 : channels_.insert(channel);
708 2 : Append(std::make_shared<CcuRep::CcuRepRemPostSem>(insGenerator, channel, remoteNotifyIdx, mask));
709 2 : return CCU_SUCCESS;
710 : }
711 :
712 4 : CcuResult CcuKernel::NotifyWait(const ChannelHandle channel, uint32_t localNotifyIdx, uint32_t mask)
713 : {
714 4 : PLF_CONFIG_INFO(PLF_DATA_OP, "[NotifyWait] channel=%llu, localNotifyIdx=%u, mask=%u",
715 : channel, localNotifyIdx, mask);
716 4 : channels_.insert(channel);
717 4 : bool isProfiling = CurrentBlock()->Type() != CcuRep::CcuRepType::LOOP_BLOCK;
718 4 : if (isProfiling) {
719 12 : CCU_CHK_RET(static_cast<HcclResult>(AddProfiling(channel, "NotifyWait", localNotifyIdx, mask)));
720 : }
721 4 : Append(std::make_shared<CcuRep::CcuRepRemWaitSem>(insGenerator, channel, localNotifyIdx, mask, isProfiling));
722 4 : return CcuResult::CCU_SUCCESS;
723 : }
724 :
725 6 : CcuResult CcuKernel::WriteVariableWithNotify(const ChannelHandle channel, CcuVariableHandle varHandle,
726 : uint32_t remoteVarIdx, uint32_t remoteNotifyIdx, uint32_t mask)
727 : {
728 6 : PLF_CONFIG_INFO(PLF_DATA_OP, "[WriteVariableWithNotify] channel=%llu, varHandle=%llu, remoteVarIdx=%u,"
729 : " remoteNotifyIdx=%u, mask=%u", channel, varHandle, remoteVarIdx, remoteNotifyIdx, mask);
730 6 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
731 1 : HCCL_ERROR("[%s] WriteVariableWithNotify is not allowed inside a ccu::Loop body", __func__);
732 1 : return LatchBodyError(CcuResult::CCU_E_NOT_SUPPORT);
733 : }
734 5 : channels_.insert(channel);
735 5 : CcuRep::Variable *var{nullptr};
736 5 : CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
737 5 : Append(std::make_shared<CcuRep::CcuRepRemPostVar>(insGenerator, *var, channel, remoteVarIdx, remoteNotifyIdx, mask));
738 5 : return CcuResult::CCU_SUCCESS;
739 : }
740 :
741 :
742 : //加载类 相关接口
743 32 : CcuResult CcuKernel::LoadArg(CcuVariableHandle varHandle, uint32_t argId)
744 : {
745 32 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LoadArg] varHandle=%llu, argId=%u", varHandle, argId);
746 32 : loadArgUsedSet_.insert(argId);
747 32 : CcuRep::Variable *var{nullptr};
748 32 : CCU_CHK_RET(GetVariableByHandle(varHandle,&var));
749 : auto loadArgRep = std::make_shared<CcuRep::CcuRepLoadArg>(
750 32 : insGenerator, *var, argId % CCU_SQE_ARGS_LEN, static_cast<uint16_t>(argId));
751 32 : Append(loadArgRep);
752 32 : return CcuResult::CCU_SUCCESS;
753 32 : }
754 :
755 8 : CcuResult CcuKernel::CheckContinuousVariables(CcuVariableHandle varHandle, uint32_t num,
756 : const CcuRep::Variable &baseVar, const char *tag)
757 : {
758 8 : if (num <= 1) {
759 4 : return CcuResult::CCU_SUCCESS;
760 : }
761 8 : for (uint32_t i = 1; i < num; i++) {
762 4 : CcuRep::Variable *nextVar{nullptr};
763 4 : CCU_CHK_RET(GetVariableByHandle(varHandle + i, &nextVar));
764 4 : if (nextVar->Id() != baseVar.Id() + i) {
765 0 : HCCL_ERROR("[CcuKernel][%s] variables not continuous at index %u, "
766 : "expected Id %u but got %u", tag, i, baseVar.Id() + i, nextVar->Id());
767 0 : return HCCL_TO_CCU_RET(HCCL_E_PARA);
768 : }
769 : }
770 4 : return CcuResult::CCU_SUCCESS;
771 : }
772 :
773 2 : CcuResult CcuKernel::LoadVar(uint64_t addr, CcuVariableHandle varHandle, uint32_t num)
774 : {
775 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LoadVar] addr=0x%llx, varHandle=%llu, num=%u", addr, varHandle, num);
776 2 : CcuRep::Variable *var{nullptr};
777 2 : CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
778 2 : CCU_CHK_RET(CheckContinuousVariables(varHandle, num, *var, "LoadVariable"));
779 2 : Append(std::make_shared<CcuRep::CcuRepLoad>(insGenerator, addr, *var, num));
780 2 : return CcuResult::CCU_SUCCESS;
781 : }
782 :
783 2 : CcuResult CcuKernel::CcuLoadVarFromVarAddr(CcuVariableHandle addrHandle, CcuVariableHandle varHandle, uint32_t num)
784 : {
785 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[CcuLoadVarFromVarAddr] addrHandle=%llu, varHandle=%llu,"
786 : " num=%u", addrHandle, varHandle, num);
787 2 : CcuRep::Variable *addrVar{nullptr};
788 2 : CCU_CHK_RET(GetVariableByHandle(addrHandle, &addrVar));
789 2 : CcuRep::Variable *var{nullptr};
790 2 : CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
791 2 : CCU_CHK_RET(CheckContinuousVariables(varHandle, num, *var, "LoadVar dst"));
792 2 : Append(std::make_shared<CcuRep::CcuRepLoadVar>(insGenerator, *addrVar, *var, num));
793 2 : return CcuResult::CCU_SUCCESS;
794 : }
795 :
796 2 : CcuResult CcuKernel::StoreVar(uint64_t addr, CcuVariableHandle varHandle, uint32_t num)
797 : {
798 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[StoreVar] addr=0x%llx, varHandle=%llu, num=%u", addr, varHandle, num);
799 2 : CcuRep::Variable *var{nullptr};
800 2 : CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
801 2 : CCU_CHK_RET(CheckContinuousVariables(varHandle, num, *var, "StoreVariable"));
802 2 : Append(std::make_shared<CcuRep::CcuRepStore>(insGenerator, *var, addr, num));
803 2 : return CcuResult::CCU_SUCCESS;
804 : }
805 :
806 2 : CcuResult CcuKernel::CcuStoreVarToVarAddr(CcuVariableHandle addrHandle, CcuVariableHandle varHandle, uint32_t num)
807 : {
808 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[CcuStoreVarToVarAddr] addrHandle=%llu, varHandle=%llu,"
809 : " num=%u", addrHandle, varHandle, num);
810 2 : CcuRep::Variable *addrVar{nullptr};
811 2 : CCU_CHK_RET(GetVariableByHandle(addrHandle, &addrVar));
812 2 : CcuRep::Variable *var{nullptr};
813 2 : CCU_CHK_RET(GetVariableByHandle(varHandle, &var));
814 2 : CCU_CHK_RET(CheckContinuousVariables(varHandle, num, *var, "StoreVar src"));
815 2 : Append(std::make_shared<CcuRep::CcuRepStoreVar>(insGenerator, *var, *addrVar, num));
816 2 : return CcuResult::CCU_SUCCESS;
817 : }
818 :
819 : //本地数据拷贝 相关实现
820 6 : CcuResult CcuKernel::LocalCopyMemToBuffer(CcuBufferHandle dstHandle, CcuLocalAddrHandle srcHandle,
821 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
822 : {
823 6 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalCopyMemToBuffer] dstHandle=%llu, srcHandle=%llu, lenHandle=%llu,"
824 : " eventHandle=%llu, mask=%u", dstHandle, srcHandle, lenHandle, eventHandle, mask);
825 6 : CcuRep::CcuBuf *dst{nullptr};
826 6 : CCU_CHK_RET(GetBufferByHandle(dstHandle, &dst));
827 6 : CcuRep::LocalAddr *src{nullptr};
828 6 : CCU_CHK_RET(GetLocalAddrByHandle(srcHandle, &src));
829 6 : CcuRep::Variable *len{nullptr};
830 6 : CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
831 6 : CcuRep::CompletedEvent *event{nullptr};
832 6 : CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
833 6 : auto ret = LocalCopyNb(*dst, *src, *len, *event, mask); // 复用 protected
834 6 : return HCCL_TO_CCU_RET(ret);
835 : }
836 :
837 4 : CcuResult CcuKernel::LocalCopyBufferToMem(CcuLocalAddrHandle dstHandle, CcuBufferHandle srcHandle,
838 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
839 : {
840 4 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalCopyBufferToMem] dstHandle=%llu, srcHandle=%llu, lenHandle=%llu,"
841 : " eventHandle=%llu, mask=%u", dstHandle, srcHandle, lenHandle, eventHandle, mask);
842 4 : CcuRep::LocalAddr *dst{nullptr};
843 4 : CCU_CHK_RET(GetLocalAddrByHandle(dstHandle, &dst));
844 4 : CcuRep::CcuBuf *src{nullptr};
845 4 : CCU_CHK_RET(GetBufferByHandle(srcHandle, &src));
846 4 : CcuRep::Variable *len{nullptr};
847 4 : CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
848 4 : CcuRep::CompletedEvent *event{nullptr};
849 4 : CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
850 4 : auto ret = LocalCopyNb(*dst, *src, *len, *event, mask);
851 4 : return HCCL_TO_CCU_RET(ret);
852 : }
853 :
854 0 : CcuResult CcuKernel::LocalCopyMemToMem(CcuLocalAddrHandle dstHandle, CcuLocalAddrHandle srcHandle,
855 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
856 : {
857 0 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalCopyMemToMem] dstHandle=%llu, srcHandle=%llu, lenHandle=%llu,"
858 : " eventHandle=%llu, mask=%u", dstHandle, srcHandle, lenHandle, eventHandle, mask);
859 0 : CcuRep::LocalAddr *dst{nullptr};
860 0 : CCU_CHK_RET(GetLocalAddrByHandle(dstHandle, &dst));
861 0 : CcuRep::LocalAddr *src{nullptr};
862 0 : CCU_CHK_RET(GetLocalAddrByHandle(srcHandle, &src));
863 0 : CcuRep::Variable *len{nullptr};
864 0 : CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
865 0 : CcuRep::CompletedEvent *event{nullptr};
866 0 : CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
867 0 : auto ret = LocalCopyNb(*dst, *src, *len, *event, mask);
868 0 : return HCCL_TO_CCU_RET(ret);
869 : }
870 :
871 : //本地reduce 相关实现
872 0 : CcuResult CcuKernel::LocalMemReduce(CcuLocalAddrHandle dstHandle, CcuLocalAddrHandle srcHandle,
873 : CcuVariableHandle lenHandle, HcclDataType dataType,
874 : HcclReduceOp opType, CcuEventHandle eventHandle, uint32_t mask)
875 : {
876 0 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalMemReduce] dstHandle=%llu, srcHandle=%llu, lenHandle=%llu, dataType=%d,"
877 : " op=%d, eventHandle=%llu, mask=%u",
878 : dstHandle, srcHandle, lenHandle, dataType, opType, eventHandle, mask);
879 0 : CcuRep::LocalAddr *dst{nullptr};
880 0 : CCU_CHK_RET(GetLocalAddrByHandle(dstHandle, &dst));
881 0 : CcuRep::LocalAddr *src{nullptr};
882 0 : CCU_CHK_RET(GetLocalAddrByHandle(srcHandle, &src));
883 0 : CcuRep::Variable *len{nullptr};
884 0 : CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
885 0 : CcuRep::CompletedEvent *event{nullptr};
886 0 : CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
887 0 : auto ret = LocalReduceNb(*dst, *src, *len, dataType, opType, *event, mask);
888 0 : return HCCL_TO_CCU_RET(ret);
889 : }
890 :
891 2 : CcuResult CcuKernel::LocalBufferReduce(CcuBufferHandle* bufHandles, uint32_t count,
892 : HcclDataType dataType, HcclDataType outputDataType,
893 : HcclReduceOp opType, CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
894 : {
895 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LocalBufferReduce] count=%u, dataType=%d, outDataType=%d,"
896 : " op=%d, lenHandle=%llu, eventHandle=%llu, mask=%u",
897 : count, dataType, outputDataType, opType, lenHandle, eventHandle, mask);
898 2 : CcuRep::Variable *len{nullptr};
899 2 : CCU_CHK_RET(GetVariableByHandle(lenHandle, &len));
900 2 : CcuRep::CompletedEvent *event{nullptr};
901 2 : CCU_CHK_RET(GetEventByHandle(eventHandle, &event));
902 2 : std::vector<CcuRep::CcuBuf> bufs(count);
903 6 : for (uint32_t i = 0; i < count; i++) {
904 4 : CcuRep::CcuBuf *buf{nullptr};
905 4 : CCU_CHK_RET(GetBufferByHandle(bufHandles[i], &buf));
906 4 : bufs[i] = *buf;
907 : }
908 2 : auto ret = LocalReduceNb(bufs.data(), count, dataType, outputDataType, opType, *len, *event, mask);
909 2 : return HCCL_TO_CCU_RET(ret);
910 2 : }
911 :
912 : /*========== 远端数据传输操作 ==========*/
913 :
914 2 : CcuResult CcuKernel::ResolveBufRemoteLenEvent(CcuBufferHandle bufHandle, CcuRemoteAddrHandle remoteHandle,
915 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle,
916 : CcuRep::CcuBuf **buf, CcuRep::RemoteAddr **remote,
917 : CcuRep::Variable **len, CcuRep::CompletedEvent **event)
918 : {
919 2 : CCU_CHK_RET(GetBufferByHandle(bufHandle, buf));
920 2 : CCU_CHK_RET(GetRemoteAddrByHandle(remoteHandle, remote));
921 2 : CCU_CHK_RET(GetVariableByHandle(lenHandle, len));
922 2 : CCU_CHK_RET(GetEventByHandle(eventHandle, event));
923 2 : return CcuResult::CCU_SUCCESS;
924 : }
925 :
926 3 : CcuResult CcuKernel::ResolveLocalRemoteLenEvent(CcuLocalAddrHandle localHandle, CcuRemoteAddrHandle remoteHandle,
927 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle,
928 : CcuRep::LocalAddr **local, CcuRep::RemoteAddr **remote,
929 : CcuRep::Variable **len, CcuRep::CompletedEvent **event)
930 : {
931 3 : CCU_CHK_RET(GetLocalAddrByHandle(localHandle, local));
932 3 : CCU_CHK_RET(GetRemoteAddrByHandle(remoteHandle, remote));
933 3 : CCU_CHK_RET(GetVariableByHandle(lenHandle, len));
934 3 : CCU_CHK_RET(GetEventByHandle(eventHandle, event));
935 3 : return CcuResult::CCU_SUCCESS;
936 : }
937 :
938 3 : CcuResult CcuKernel::ResolveRemoteLocalLenEvent(CcuRemoteAddrHandle remoteHandle, CcuLocalAddrHandle localHandle,
939 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle,
940 : CcuRep::RemoteAddr **remote, CcuRep::LocalAddr **local,
941 : CcuRep::Variable **len, CcuRep::CompletedEvent **event)
942 : {
943 3 : CCU_CHK_RET(GetRemoteAddrByHandle(remoteHandle, remote));
944 3 : CCU_CHK_RET(GetLocalAddrByHandle(localHandle, local));
945 3 : CCU_CHK_RET(GetVariableByHandle(lenHandle, len));
946 3 : CCU_CHK_RET(GetEventByHandle(eventHandle, event));
947 3 : return CcuResult::CCU_SUCCESS;
948 : }
949 :
950 2 : CcuResult CcuKernel::ReadMemToMem(ChannelHandle channel, CcuLocalAddrHandle localHandle, CcuRemoteAddrHandle remoteHandle,
951 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
952 : {
953 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[ReadMemToMem] channel=%llu, localHandle=%llu, remoteHandle=%llu,"
954 : " lenHandle=%llu, eventHandle=%llu, mask=%u",
955 : channel, localHandle, remoteHandle, lenHandle, eventHandle, mask);
956 2 : channels_.insert(channel);
957 2 : CcuRep::LocalAddr *local{nullptr};
958 2 : CcuRep::RemoteAddr *remote{nullptr};
959 2 : CcuRep::Variable *len{nullptr};
960 2 : CcuRep::CompletedEvent *event{nullptr};
961 2 : CCU_CHK_RET(ResolveLocalRemoteLenEvent(localHandle, remoteHandle, lenHandle, eventHandle,
962 : &local, &remote, &len, &event));
963 2 : auto ret = ReadNb(channel, *local, *remote, *len, *event, mask);
964 2 : return HCCL_TO_CCU_RET(ret);
965 : }
966 :
967 1 : CcuResult CcuKernel::ReadMemToBuffer(ChannelHandle channel, CcuBufferHandle localHandle, CcuRemoteAddrHandle remoteHandle,
968 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
969 : {
970 1 : PLF_CONFIG_INFO(PLF_DATA_OP, "[ReadMemToBuffer] channel=%llu, bufHandle=%llu, remoteHandle=%llu,"
971 : " lenHandle=%llu, eventHandle=%llu, mask=%u",
972 : channel, localHandle, remoteHandle, lenHandle, eventHandle, mask);
973 1 : channels_.insert(channel);
974 1 : CcuRep::CcuBuf *local{nullptr};
975 1 : CcuRep::RemoteAddr *remote{nullptr};
976 1 : CcuRep::Variable *len{nullptr};
977 1 : CcuRep::CompletedEvent *event{nullptr};
978 1 : CCU_CHK_RET(ResolveBufRemoteLenEvent(localHandle, remoteHandle, lenHandle, eventHandle,
979 : &local, &remote, &len, &event));
980 1 : auto ret = ReadNb(channel, *local, *remote, *len, *event, mask);
981 1 : return HCCL_TO_CCU_RET(ret);
982 : }
983 :
984 1 : CcuResult CcuKernel::ReadMemToMemReduce(ChannelHandle channel, CcuLocalAddrHandle localHandle, CcuRemoteAddrHandle remoteHandle,
985 : CcuVariableHandle lenHandle, HcclDataType dataType,
986 : HcclReduceOp opType, CcuEventHandle eventHandle, uint32_t mask)
987 : {
988 1 : PLF_CONFIG_INFO(PLF_DATA_OP, "[ReadMemToMemReduce] channel=%llu, lenHandle=%llu, dataType=%d, op=%d,"
989 : " eventHandle=%llu, mask=%u", channel, lenHandle, dataType, opType, eventHandle, mask);
990 1 : channels_.insert(channel);
991 1 : CcuRep::LocalAddr *local{nullptr};
992 1 : CcuRep::RemoteAddr *remote{nullptr};
993 1 : CcuRep::Variable *len{nullptr};
994 1 : CcuRep::CompletedEvent *event{nullptr};
995 1 : CCU_CHK_RET(ResolveLocalRemoteLenEvent(localHandle, remoteHandle, lenHandle, eventHandle,
996 : &local, &remote, &len, &event));
997 1 : auto ret = ReadReduceNb(channel, *local, *remote, *len, dataType, opType, *event, mask);
998 1 : return HCCL_TO_CCU_RET(ret);
999 : }
1000 :
1001 2 : CcuResult CcuKernel::WriteMemToMem(ChannelHandle channel, CcuRemoteAddrHandle remoteHandle, CcuLocalAddrHandle localHandle,
1002 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
1003 : {
1004 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[WriteMemToMem] channel=%llu, remoteHandle=%llu, localHandle=%llu,"
1005 : " lenHandle=%llu, eventHandle=%llu, mask=%u",
1006 : channel, remoteHandle, localHandle, lenHandle, eventHandle, mask);
1007 2 : channels_.insert(channel);
1008 2 : CcuRep::RemoteAddr *remote{nullptr};
1009 2 : CcuRep::LocalAddr *local{nullptr};
1010 2 : CcuRep::Variable *len{nullptr};
1011 2 : CcuRep::CompletedEvent *event{nullptr};
1012 2 : CCU_CHK_RET(ResolveRemoteLocalLenEvent(remoteHandle, localHandle, lenHandle, eventHandle,
1013 : &remote, &local, &len, &event));
1014 2 : auto ret = WriteNb(channel, *remote, *local, *len, *event, mask);
1015 2 : return HCCL_TO_CCU_RET(ret);
1016 : }
1017 :
1018 1 : CcuResult CcuKernel::WriteBufferToMem(ChannelHandle channel, CcuRemoteAddrHandle remoteHandle, CcuBufferHandle localHandle,
1019 : CcuVariableHandle lenHandle, CcuEventHandle eventHandle, uint32_t mask)
1020 : {
1021 1 : PLF_CONFIG_INFO(PLF_DATA_OP, "[WriteBufferToMem] channel=%llu, remoteHandle=%llu, bufHandle=%llu,"
1022 : " lenHandle=%llu, eventHandle=%llu, mask=%u",
1023 : channel, remoteHandle, localHandle, lenHandle, eventHandle, mask);
1024 1 : channels_.insert(channel);
1025 1 : CcuRep::CcuBuf *local{nullptr};
1026 1 : CcuRep::RemoteAddr *remote{nullptr};
1027 1 : CcuRep::Variable *len{nullptr};
1028 1 : CcuRep::CompletedEvent *event{nullptr};
1029 1 : CCU_CHK_RET(ResolveBufRemoteLenEvent(localHandle, remoteHandle, lenHandle, eventHandle,
1030 : &local, &remote, &len, &event));
1031 1 : auto ret = WriteNb(channel, *remote, *local, *len, *event, mask);
1032 1 : return HCCL_TO_CCU_RET(ret);
1033 : }
1034 :
1035 1 : CcuResult CcuKernel::WriteMemToMemReduce(ChannelHandle channel, CcuRemoteAddrHandle remoteHandle, CcuLocalAddrHandle localHandle,
1036 : CcuVariableHandle lenHandle, HcclDataType dataType,
1037 : HcclReduceOp opType, CcuEventHandle eventHandle, uint32_t mask)
1038 : {
1039 1 : PLF_CONFIG_INFO(PLF_DATA_OP, "[WriteMemToMemReduce] channel=%llu, lenHandle=%llu, dataType=%d, op=%d,"
1040 : " eventHandle=%llu, mask=%u", channel, lenHandle, dataType, opType, eventHandle, mask);
1041 1 : channels_.insert(channel);
1042 1 : CcuRep::RemoteAddr *remote{nullptr};
1043 1 : CcuRep::LocalAddr *local{nullptr};
1044 1 : CcuRep::Variable *len{nullptr};
1045 1 : CcuRep::CompletedEvent *event{nullptr};
1046 1 : CCU_CHK_RET(ResolveRemoteLocalLenEvent(remoteHandle, localHandle, lenHandle, eventHandle,
1047 : &remote, &local, &len, &event));
1048 1 : auto ret = WriteReduceNb(channel, *remote, *local, *len, dataType, opType, *event, mask);
1049 1 : return HCCL_TO_CCU_RET(ret);
1050 : }
1051 :
1052 521 : void CcuKernel::FlushClosablePendingIfs()
1053 : {
1054 521 : if (isFlushing_) {
1055 14 : return;
1056 : }
1057 507 : isFlushing_ = true;
1058 1028 : while (IfLabelStackTopIsClosable()) {
1059 14 : const char *lbl = IfLabelStackPop();
1060 14 : if (lbl != nullptr) {
1061 14 : IfEnd(lbl);
1062 : }
1063 : }
1064 507 : isFlushing_ = false;
1065 : }
1066 :
1067 470 : void CcuKernel::Append(std::shared_ptr<CcuRep::CcuRepBase> rep)
1068 : {
1069 470 : FlushClosablePendingIfs();
1070 470 : CcuRep::CcuRepContext::Append(rep);
1071 470 : }
1072 :
1073 : namespace {
1074 18 : std::shared_ptr<CcuRep::CcuRepJumpBase> MakeInvertedCondJumpImm(
1075 : CcuInsGeneraterBase *insGenerator, const std::string &destLabelStr,
1076 : const CcuRep::Variable &targetVar, const CcuRep::Variable &expectVar,
1077 : const CcuRep::Variable &variable, uint64_t immediate,
1078 : CcuConditionType condType, const char *funcName)
1079 : {
1080 18 : switch (condType) {
1081 9 : case CCU_CONDITION_EQ:
1082 18 : return std::make_shared<CcuRep::CcuRepJumpNE>(
1083 9 : insGenerator, destLabelStr, targetVar, expectVar, variable, immediate);
1084 9 : case CCU_CONDITION_NE:
1085 18 : return std::make_shared<CcuRep::CcuRepJumpEQ>(
1086 9 : insGenerator, destLabelStr, targetVar, expectVar, variable, immediate);
1087 0 : default:
1088 0 : HCCL_ERROR("[%s] unsupported condition type: %d", funcName, condType);
1089 0 : return nullptr;
1090 : }
1091 : }
1092 :
1093 : // 双变量版本:当 (lhsVar OP rhsVar) 为假时跳转到 destLabelStr。
1094 0 : std::shared_ptr<CcuRep::CcuRepJumpBase> MakeInvertedCondJumpVar(
1095 : CcuInsGeneraterBase *insGenerator, const std::string &destLabelStr,
1096 : const CcuRep::Variable &targetVar,
1097 : const CcuRep::Variable &lhsVar, const CcuRep::Variable &rhsVar,
1098 : CcuConditionType condType, const char *funcName)
1099 : {
1100 0 : switch (condType) {
1101 0 : case CCU_CONDITION_EQ:
1102 0 : return std::make_shared<CcuRep::CcuRepJumpNE>(
1103 0 : insGenerator, destLabelStr, targetVar, lhsVar, rhsVar);
1104 0 : case CCU_CONDITION_NE:
1105 0 : return std::make_shared<CcuRep::CcuRepJumpEQ>(
1106 0 : insGenerator, destLabelStr, targetVar, lhsVar, rhsVar);
1107 0 : default:
1108 0 : HCCL_ERROR("[%s] unsupported condition type: %d", funcName, condType);
1109 0 : return nullptr;
1110 : }
1111 : }
1112 : } // namespace
1113 :
1114 17 : CcuResult CcuKernel::IfBegin(CcuVariableHandle varHandle, uint64_t immediate,
1115 : CcuConditionType condType, const char *label)
1116 : {
1117 17 : PLF_CONFIG_INFO(PLF_DATA_OP, "[IfBegin] varHandle=%llu, immediate=%llu, condType=%d, label=%s",
1118 : varHandle, immediate, condType, (label ? label : "null"));
1119 17 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
1120 1 : HCCL_ERROR("[%s] CCU_IF is not allowed inside a ccu::Loop body (label='%s')",
1121 : __func__, label != nullptr ? label : "(null)");
1122 1 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
1123 : }
1124 16 : CcuRep::Variable *variable{nullptr};
1125 16 : CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
1126 :
1127 16 : FlushClosablePendingIfs();
1128 :
1129 16 : std::string labelStr(label);
1130 16 : if (pendingIfCtx_.find(labelStr) != pendingIfCtx_.end()) {
1131 0 : HCCL_ERROR("[%s] label '%s' already has a pending IfBegin without IfEnd", __func__, label);
1132 0 : return CcuResult::CCU_E_PARA;
1133 : }
1134 :
1135 16 : std::string elseLabelStr = labelStr + "_else";
1136 16 : std::string endLabelStr = labelStr + "_end";
1137 16 : auto elseLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, elseLabelStr);
1138 16 : auto endLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, endLabelStr);
1139 16 : auto targetVar = CcuRep::CreateVariable(this);
1140 16 : auto expectVar = CcuRep::CreateVariable(this);
1141 :
1142 : // 反转条件:"if <cond>, 执行块" 等价于 "!<cond> 时跳过块"。
1143 : auto jump = MakeInvertedCondJumpImm(insGenerator, elseLabelStr,
1144 16 : targetVar, expectVar, *variable, immediate, condType, __func__);
1145 16 : if (jump == nullptr) {
1146 0 : return CcuResult::CCU_E_PARA;
1147 : }
1148 16 : jump->Reference(elseLabel);
1149 16 : Append(jump);
1150 :
1151 16 : PendingIfContext ctx;
1152 16 : ctx.elseLabel = elseLabel;
1153 16 : ctx.endLabel = endLabel;
1154 16 : ctx.hasElse = false;
1155 16 : pendingIfCtx_.emplace(labelStr, std::move(ctx));
1156 :
1157 16 : return CcuResult::CCU_SUCCESS;
1158 16 : }
1159 :
1160 0 : CcuResult CcuKernel::IfBeginVar(CcuVariableHandle lhsHandle, CcuVariableHandle rhsHandle,
1161 : CcuConditionType condType, const char *label)
1162 : {
1163 0 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
1164 0 : HCCL_ERROR("[%s] CCU_IF is not allowed inside a ccu::Loop body (label='%s')",
1165 : __func__, label != nullptr ? label : "(null)");
1166 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
1167 : }
1168 0 : CcuRep::Variable *lhsVar{nullptr};
1169 0 : CcuRep::Variable *rhsVar{nullptr};
1170 0 : CCU_CHK_RET(GetVariableByHandle(lhsHandle, &lhsVar));
1171 0 : CCU_CHK_RET(GetVariableByHandle(rhsHandle, &rhsVar));
1172 :
1173 0 : FlushClosablePendingIfs();
1174 :
1175 0 : std::string labelStr(label);
1176 0 : if (pendingIfCtx_.find(labelStr) != pendingIfCtx_.end()) {
1177 0 : HCCL_ERROR("[%s] label '%s' already has a pending IfBegin without IfEnd", __func__, label);
1178 0 : return CcuResult::CCU_E_PARA;
1179 : }
1180 :
1181 0 : std::string endLabelStr = labelStr + "_end";
1182 0 : std::string elseLabelStr = labelStr + "_else";
1183 0 : auto endLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, endLabelStr);
1184 0 : auto elseLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, elseLabelStr);
1185 0 : auto targetVar = CcuRep::CreateVariable(this);
1186 :
1187 : auto jump = MakeInvertedCondJumpVar(insGenerator, elseLabelStr,
1188 0 : targetVar, *lhsVar, *rhsVar, condType, __func__);
1189 0 : if (jump == nullptr) {
1190 0 : return CcuResult::CCU_E_PARA;
1191 : }
1192 0 : jump->Reference(elseLabel);
1193 0 : Append(jump);
1194 :
1195 0 : PendingIfContext ctx;
1196 0 : ctx.hasElse = false;
1197 0 : ctx.endLabel = endLabel;
1198 0 : ctx.elseLabel = elseLabel;
1199 0 : pendingIfCtx_.emplace(labelStr, std::move(ctx));
1200 :
1201 0 : return CcuResult::CCU_SUCCESS;
1202 0 : }
1203 :
1204 2 : CcuResult CcuKernel::IfElse(const char *label)
1205 : {
1206 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[IfElse] label=%s", (label ? label : "null"));
1207 2 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
1208 0 : HCCL_ERROR("[%s] CCU_ELSE is not allowed inside a ccu::Loop body (label='%s')",
1209 : __func__, label != nullptr ? label : "(null)");
1210 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
1211 : }
1212 :
1213 2 : std::string labelStr(label);
1214 2 : auto iter = pendingIfCtx_.find(labelStr);
1215 2 : if (iter == pendingIfCtx_.end()) {
1216 0 : HCCL_ERROR("[%s] no matching IfBegin for label '%s'", __func__, label);
1217 0 : return CcuResult::CCU_E_NOT_FOUND;
1218 : }
1219 :
1220 2 : if (iter->second.hasElse) {
1221 0 : HCCL_ERROR("[%s] label '%s' already has an IfElse", __func__, label);
1222 0 : return CcuResult::CCU_E_PARA;
1223 : }
1224 :
1225 : // At end of then-block: unconditional jump past else-block to endLabel
1226 2 : std::string endLabelStr = labelStr + "_end";
1227 2 : auto skipElseVar = CcuRep::CreateVariable(this);
1228 : auto skipElseJump = std::make_shared<CcuRep::CcuRepJump>(
1229 2 : insGenerator, endLabelStr, skipElseVar);
1230 2 : skipElseJump->Reference(iter->second.endLabel);
1231 2 : Append(skipElseJump);
1232 :
1233 : // Place the else label (entry point of else-block)
1234 2 : Append(iter->second.elseLabel);
1235 :
1236 2 : iter->second.hasElse = true;
1237 :
1238 2 : return CcuResult::CCU_SUCCESS;
1239 2 : }
1240 :
1241 16 : CcuResult CcuKernel::IfEnd(const char *label)
1242 : {
1243 16 : PLF_CONFIG_INFO(PLF_DATA_OP, "[IfEnd] label=%s", (label ? label : "null"));
1244 16 : std::string labelStr(label);
1245 16 : auto iter = pendingIfCtx_.find(labelStr);
1246 16 : if (iter == pendingIfCtx_.end()) {
1247 0 : HCCL_ERROR("[%s] no matching IfBegin for label '%s'", __func__, label);
1248 0 : return CcuResult::CCU_E_NOT_FOUND;
1249 : }
1250 :
1251 16 : if (iter->second.hasElse) {
1252 : // Had else-block: place endLabel after else-block
1253 2 : Append(iter->second.endLabel);
1254 : } else {
1255 : // No else-block: place elseLabel as the skip target
1256 14 : Append(iter->second.elseLabel);
1257 : }
1258 :
1259 16 : pendingIfCtx_.erase(iter);
1260 :
1261 16 : return CcuResult::CCU_SUCCESS;
1262 16 : }
1263 :
1264 2 : CcuResult CcuKernel::WhileBegin(CcuVariableHandle varHandle, uint64_t immediate,
1265 : CcuConditionType condType, const char *label)
1266 : {
1267 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[WhileBegin] varHandle=%llu, immediate=%llu, condType=%d, label=%s",
1268 : varHandle, immediate, condType, (label ? label : "null"));
1269 2 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
1270 0 : HCCL_ERROR("[%s] CCU_WHILE is not allowed inside a ccu::Loop body (label='%s')",
1271 : __func__, label != nullptr ? label : "(null)");
1272 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
1273 : }
1274 :
1275 2 : CcuRep::Variable *variable{nullptr};
1276 2 : CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
1277 :
1278 2 : std::string labelStr(label);
1279 2 : if (pendingWhileCtx_.find(labelStr) != pendingWhileCtx_.end()) {
1280 0 : HCCL_ERROR("[%s] label '%s' already has a pending WhileBegin without WhileEnd", __func__, label);
1281 0 : return CcuResult::CCU_E_PARA;
1282 : }
1283 :
1284 2 : std::string beginLabelStr = labelStr + "_begin";
1285 2 : std::string endLabelStr = labelStr + "_end";
1286 2 : auto beginLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, beginLabelStr);
1287 2 : auto endLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, endLabelStr);
1288 :
1289 2 : Append(beginLabel);
1290 :
1291 2 : auto targetVar = CcuRep::CreateVariable(this);
1292 2 : auto expectVar = CcuRep::CreateVariable(this);
1293 : auto jump = MakeInvertedCondJumpImm(insGenerator, endLabelStr,
1294 2 : targetVar, expectVar, *variable, immediate, condType, __func__);
1295 2 : if (jump == nullptr) {
1296 0 : return CcuResult::CCU_E_PARA;
1297 : }
1298 2 : jump->Reference(endLabel);
1299 2 : Append(jump);
1300 :
1301 2 : PendingWhileContext ctx;
1302 2 : ctx.beginLabel = beginLabel;
1303 2 : ctx.endLabel = endLabel;
1304 2 : ctx.varHandle = varHandle;
1305 2 : ctx.immediate = immediate;
1306 2 : ctx.condType = condType;
1307 2 : pendingWhileCtx_.emplace(labelStr, std::move(ctx));
1308 :
1309 2 : return CcuResult::CCU_SUCCESS;
1310 2 : }
1311 :
1312 0 : CcuResult CcuKernel::WhileBeginVar(CcuVariableHandle lhsHandle, CcuVariableHandle rhsHandle,
1313 : CcuConditionType condType, const char *label)
1314 : {
1315 0 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
1316 0 : HCCL_ERROR("[%s] CCU_WHILE is not allowed inside a ccu::Loop body (label='%s')",
1317 : __func__, label != nullptr ? label : "(null)");
1318 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
1319 : }
1320 :
1321 0 : CcuRep::Variable *lhsVar{nullptr};
1322 0 : CcuRep::Variable *rhsVar{nullptr};
1323 0 : CCU_CHK_RET(GetVariableByHandle(lhsHandle, &lhsVar));
1324 0 : CCU_CHK_RET(GetVariableByHandle(rhsHandle, &rhsVar));
1325 :
1326 0 : std::string labelStr(label);
1327 0 : if (pendingWhileCtx_.find(labelStr) != pendingWhileCtx_.end()) {
1328 0 : HCCL_ERROR("[%s] label '%s' already has a pending WhileBegin without WhileEnd", __func__, label);
1329 0 : return CcuResult::CCU_E_PARA;
1330 : }
1331 :
1332 0 : std::string endLabelStr = labelStr + "_end";
1333 0 : std::string beginLabelStr = labelStr + "_begin";
1334 0 : auto endLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, endLabelStr);
1335 0 : auto beginLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, beginLabelStr);
1336 :
1337 0 : Append(beginLabel);
1338 :
1339 0 : auto targetVar = CcuRep::CreateVariable(this);
1340 : auto jump = MakeInvertedCondJumpVar(insGenerator, endLabelStr,
1341 0 : targetVar, *lhsVar, *rhsVar, condType, __func__);
1342 0 : if (jump == nullptr) {
1343 0 : return CcuResult::CCU_E_PARA;
1344 : }
1345 0 : jump->Reference(endLabel);
1346 0 : Append(jump);
1347 :
1348 0 : PendingWhileContext ctx;
1349 0 : ctx.beginLabel = beginLabel;
1350 0 : ctx.endLabel = endLabel;
1351 0 : ctx.varHandle = lhsHandle;
1352 0 : ctx.immediate = 0;
1353 0 : ctx.condType = condType;
1354 0 : pendingWhileCtx_.emplace(labelStr, std::move(ctx));
1355 :
1356 0 : return CcuResult::CCU_SUCCESS;
1357 0 : }
1358 :
1359 2 : CcuResult CcuKernel::WhileEnd(const char *label)
1360 : {
1361 2 : PLF_CONFIG_INFO(PLF_DATA_OP, "[WhileEnd] label=%s", (label ? label : "null"));
1362 2 : std::string labelStr(label);
1363 2 : auto iter = pendingWhileCtx_.find(labelStr);
1364 2 : if (iter == pendingWhileCtx_.end()) {
1365 0 : HCCL_ERROR("[%s] no matching WhileBegin for label '%s'", __func__, label);
1366 0 : return CcuResult::CCU_E_NOT_FOUND;
1367 : }
1368 :
1369 2 : std::string beginLabelStr = labelStr + "_begin";
1370 2 : auto loopBackVar = CcuRep::CreateVariable(this);
1371 : auto loopBackJump = std::make_shared<CcuRep::CcuRepJump>(
1372 2 : insGenerator, beginLabelStr, loopBackVar);
1373 2 : loopBackJump->Reference(iter->second.beginLabel);
1374 2 : Append(loopBackJump);
1375 :
1376 2 : Append(iter->second.endLabel);
1377 :
1378 2 : pendingWhileCtx_.erase(iter);
1379 :
1380 2 : return CcuResult::CCU_SUCCESS;
1381 2 : }
1382 :
1383 6 : CcuResult CcuKernel::DoWhileBegin(const char *label)
1384 : {
1385 6 : PLF_CONFIG_INFO(PLF_DATA_OP, "[DoWhileBegin] label=%s", (label ? label : "null"));
1386 6 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
1387 0 : HCCL_ERROR("[%s] CCU_DO is not allowed inside a ccu::Loop body (label='%s')",
1388 : __func__, label != nullptr ? label : "(null)");
1389 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
1390 : }
1391 :
1392 6 : std::string labelStr(label);
1393 6 : if (pendingDoWhileCtx_.find(labelStr) != pendingDoWhileCtx_.end()) {
1394 0 : HCCL_ERROR("[%s] label '%s' already has a pending DoWhileBegin without DoWhileEnd", __func__, label);
1395 0 : return CcuResult::CCU_E_PARA;
1396 : }
1397 :
1398 6 : std::string beginLabelStr = labelStr + "_begin";
1399 6 : auto beginLabel = std::make_shared<CcuRep::CcuRepJumpLabel>(insGenerator, beginLabelStr);
1400 6 : Append(beginLabel);
1401 :
1402 6 : PendingDoWhileContext ctx;
1403 6 : ctx.beginLabel = beginLabel;
1404 6 : pendingDoWhileCtx_.emplace(labelStr, std::move(ctx));
1405 :
1406 6 : return CcuResult::CCU_SUCCESS;
1407 6 : }
1408 :
1409 3 : CcuResult CcuKernel::DoWhileEnd(CcuVariableHandle varHandle, uint64_t immediate,
1410 : CcuConditionType condType, const char *label)
1411 : {
1412 3 : PLF_CONFIG_INFO(PLF_DATA_OP, "[DoWhileEnd] varHandle=%llu, immediate=%llu, condType=%d, label=%s",
1413 : varHandle, immediate, condType, (label ? label : "null"));
1414 3 : CcuRep::Variable *variable{nullptr};
1415 3 : CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
1416 :
1417 3 : std::string labelStr(label);
1418 3 : auto iter = pendingDoWhileCtx_.find(labelStr);
1419 3 : if (iter == pendingDoWhileCtx_.end()) {
1420 0 : HCCL_ERROR("[%s] no matching DoWhileBegin for label '%s'", __func__, label);
1421 0 : return CcuResult::CCU_E_NOT_FOUND;
1422 : }
1423 :
1424 3 : std::string beginLabelStr = labelStr + "_begin";
1425 3 : auto targetVar = CcuRep::CreateVariable(this);
1426 3 : auto expectVar = CcuRep::CreateVariable(this);
1427 3 : std::shared_ptr<CcuRep::CcuRepJumpBase> jump{nullptr};
1428 :
1429 : // "condition true => continue looping" means jump back to begin when condition holds
1430 3 : if (condType == CCU_CONDITION_EQ) {
1431 0 : jump = std::make_shared<CcuRep::CcuRepJumpEQ>(
1432 0 : insGenerator, beginLabelStr, targetVar, expectVar, *variable, immediate);
1433 3 : } else if (condType == CCU_CONDITION_NE) {
1434 3 : jump = std::make_shared<CcuRep::CcuRepJumpNE>(
1435 3 : insGenerator, beginLabelStr, targetVar, expectVar, *variable, immediate);
1436 : } else {
1437 0 : HCCL_ERROR("[%s] unsupported condition type: %d", __func__, condType);
1438 0 : return CcuResult::CCU_E_PARA;
1439 : }
1440 :
1441 3 : jump->Reference(iter->second.beginLabel);
1442 3 : Append(jump);
1443 :
1444 3 : pendingDoWhileCtx_.erase(iter);
1445 :
1446 3 : return CcuResult::CCU_SUCCESS;
1447 3 : }
1448 :
1449 0 : CcuResult CcuKernel::DoWhileEndVar(CcuVariableHandle lhsHandle, CcuVariableHandle rhsHandle,
1450 : CcuConditionType condType, const char *label)
1451 : {
1452 0 : CcuRep::Variable *lhsVar{nullptr};
1453 0 : CcuRep::Variable *rhsVar{nullptr};
1454 0 : CCU_CHK_RET(GetVariableByHandle(lhsHandle, &lhsVar));
1455 0 : CCU_CHK_RET(GetVariableByHandle(rhsHandle, &rhsVar));
1456 :
1457 0 : std::string labelStr(label);
1458 0 : auto iter = pendingDoWhileCtx_.find(labelStr);
1459 0 : if (iter == pendingDoWhileCtx_.end()) {
1460 0 : HCCL_ERROR("[%s] no matching DoWhileBegin for label '%s'", __func__, label);
1461 0 : return CcuResult::CCU_E_NOT_FOUND;
1462 : }
1463 :
1464 0 : std::string beginLabelStr = labelStr + "_begin";
1465 0 : auto targetVar = CcuRep::CreateVariable(this);
1466 0 : std::shared_ptr<CcuRep::CcuRepJumpBase> jump{nullptr};
1467 :
1468 0 : if (condType == CCU_CONDITION_EQ) {
1469 0 : jump = std::make_shared<CcuRep::CcuRepJumpEQ>(
1470 0 : insGenerator, beginLabelStr, targetVar, *lhsVar, *rhsVar);
1471 0 : } else if (condType == CCU_CONDITION_NE) {
1472 0 : jump = std::make_shared<CcuRep::CcuRepJumpNE>(
1473 0 : insGenerator, beginLabelStr, targetVar, *lhsVar, *rhsVar);
1474 : } else {
1475 0 : HCCL_ERROR("[%s] unsupported condition type: %d", __func__, condType);
1476 0 : return CcuResult::CCU_E_PARA;
1477 : }
1478 :
1479 0 : jump->Reference(iter->second.beginLabel);
1480 0 : Append(jump);
1481 :
1482 0 : pendingDoWhileCtx_.erase(iter);
1483 :
1484 0 : return CcuResult::CCU_SUCCESS;
1485 0 : }
1486 :
1487 : // 控制流标签栈实体
1488 16 : void CcuKernel::IfLabelStackPush(const char *label)
1489 : {
1490 16 : iflabelStack_.push_back({label, false});
1491 16 : }
1492 16 : void CcuKernel::IfLabelStackMarkBodyDone()
1493 : {
1494 16 : if (iflabelStack_.empty()) {
1495 0 : HCCL_ERROR("[CcuKernel::IfLabelStack][MarkBodyDone] stack is empty");
1496 0 : return;
1497 : }
1498 16 : iflabelStack_.back().bodyDone = true;
1499 : }
1500 2 : const char *CcuKernel::IfLabelStackPopForElse()
1501 : {
1502 2 : if (iflabelStack_.empty()) {
1503 0 : HCCL_ERROR("[CcuKernel::IfLabelStack][PopForElse] orphan CCU_ELSE: "
1504 : "no matching CCU_IF on the stack");
1505 0 : return nullptr;
1506 : }
1507 2 : if (!iflabelStack_.back().bodyDone) {
1508 0 : HCCL_ERROR("[CcuKernel::IfLabelStack][PopForElse] CCU_ELSE called while "
1509 : "top if-body is still InBody (label='%s')",
1510 : iflabelStack_.back().label != nullptr
1511 : ? iflabelStack_.back().label : "(null)");
1512 0 : return nullptr;
1513 : }
1514 2 : const char *label = iflabelStack_.back().label;
1515 2 : iflabelStack_.pop_back();
1516 2 : return label;
1517 : }
1518 521 : bool CcuKernel::IfLabelStackTopIsClosable()
1519 : {
1520 521 : return !iflabelStack_.empty() && iflabelStack_.back().bodyDone;
1521 : }
1522 :
1523 14 : const char *CcuKernel::IfLabelStackPop()
1524 : {
1525 14 : if (iflabelStack_.empty()) {
1526 0 : return nullptr;
1527 : }
1528 14 : const char *label = iflabelStack_.back().label;
1529 14 : iflabelStack_.pop_back();
1530 14 : return label;
1531 : }
1532 :
1533 6 : void CcuKernel::DoWhileLabelStackPush(const char *label)
1534 : {
1535 6 : DoWhileLabelEntry entry;
1536 6 : entry.label = label;
1537 6 : entry.snapshotBlock = CurrentBlock();
1538 6 : entry.snapshotRepCount = (entry.snapshotBlock != nullptr)
1539 6 : ? entry.snapshotBlock->GetReps().size()
1540 : : 0;
1541 6 : doWhileLabelStack_.push_back(std::move(entry));
1542 6 : }
1543 :
1544 8 : const char *CcuKernel::DoWhileLabelStackPopForWhile()
1545 : {
1546 8 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
1547 1 : return nullptr;
1548 : }
1549 7 : if (doWhileLabelStack_.empty()) {
1550 2 : return nullptr;
1551 : }
1552 5 : DoWhileLabelEntry entry = doWhileLabelStack_.back();
1553 5 : doWhileLabelStack_.pop_back();
1554 :
1555 5 : auto currentBlock = CurrentBlock();
1556 5 : size_t currentRepCount = (currentBlock != nullptr) ? currentBlock->GetReps().size() : 0;
1557 5 : if (currentBlock != entry.snapshotBlock || currentRepCount != entry.snapshotRepCount) {
1558 1 : HCCL_ERROR("[CcuKernel::DoWhileLabelStackPopForWhile] dangling CCU calls between CCU_DO end "
1559 : "and CCU_WHILE (label='%s', snapRep=%zu, curRep=%zu, blockChanged=%d); they must "
1560 : "be syntactically adjacent, otherwise the code in between is pulled into the body.",
1561 : entry.label != nullptr ? entry.label : "(null)", entry.snapshotRepCount,
1562 : currentRepCount, currentBlock != entry.snapshotBlock ? 1 : 0);
1563 1 : return nullptr;
1564 : }
1565 4 : return entry.label;
1566 5 : }
1567 :
1568 88 : CcuResult CcuKernel::GetAddressByHandle(CcuAddressHandle addrHandle, CcuRep::Address **address)
1569 : {
1570 88 : return GetResourceByHandle(ccuAddrMap_, addrHandle, address, "address");
1571 : }
1572 :
1573 : // addr = 立即数 → CcuRepAssign(Address, uint64_t)
1574 6 : CcuResult CcuKernel::AddressAssignImm(CcuAddressHandle addrHandle, uint64_t immediate)
1575 : {
1576 6 : PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAssignImm] addrHandle=%llu, immediate=%llu", addrHandle, immediate);
1577 6 : CcuRep::Address *address{nullptr};
1578 6 : CCU_CHK_RET(GetAddressByHandle(addrHandle, &address));
1579 6 : (*address) = immediate;
1580 6 : return CcuResult::CCU_SUCCESS;
1581 : }
1582 :
1583 : // addr = variable → CcuRepAssign(Address, Variable)
1584 9 : CcuResult CcuKernel::AddressAssignVar(CcuAddressHandle addrHandle, CcuVariableHandle varHandle)
1585 : {
1586 9 : PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAssignVar] addrHandle=%llu, varHandle=%llu", addrHandle, varHandle);
1587 9 : CcuRep::Address *address{nullptr};
1588 9 : CCU_CHK_RET(GetAddressByHandle(addrHandle, &address));
1589 :
1590 9 : CcuRep::Variable *variable{nullptr};
1591 9 : CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
1592 :
1593 9 : (*address) = (*variable);
1594 9 : return CcuResult::CCU_SUCCESS;
1595 : }
1596 : // addr = addr → CcuRepAssign(Address, Address)
1597 22 : CcuResult CcuKernel::AddressAssignAddr(CcuAddressHandle dstAddrHandle, CcuAddressHandle srcAddrHandle)
1598 : {
1599 22 : PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAssignAddr] dstAddrHandle=%llu, srcAddrHandle=%llu",
1600 : dstAddrHandle, srcAddrHandle);
1601 22 : CcuRep::Address *dstAddress{nullptr};
1602 22 : CCU_CHK_RET(GetAddressByHandle(dstAddrHandle, &dstAddress));
1603 :
1604 22 : CcuRep::Address *srcAddress{nullptr};
1605 22 : CCU_CHK_RET(GetAddressByHandle(srcAddrHandle, &srcAddress));
1606 :
1607 22 : (*dstAddress) = (*srcAddress);
1608 22 : return CcuResult::CCU_SUCCESS;
1609 : }
1610 :
1611 : // resAddr = lhsAddr + rhsVar → CcuRepAdd(Address, Address, Variable)
1612 0 : CcuResult CcuKernel::AddressAddVarToAddr(
1613 : CcuAddressHandle resAddrHandle, CcuAddressHandle lhsAddrHandle, CcuVariableHandle rhsVarHandle)
1614 : {
1615 0 : PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAddVarToAddr] resAddrHandle=%llu, lhsAddrHandle=%llu, rhsVarHandle=%llu",
1616 : resAddrHandle, lhsAddrHandle, rhsVarHandle);
1617 0 : CcuRep::Address *resAddr{nullptr}, *lhsAddr{nullptr};
1618 0 : CCU_CHK_RET(GetAddressByHandle(resAddrHandle, &resAddr));
1619 0 : CCU_CHK_RET(GetAddressByHandle(lhsAddrHandle, &lhsAddr));
1620 :
1621 0 : CcuRep::Variable *rhsVar{nullptr};
1622 0 : CCU_CHK_RET(GetVariableByHandle(rhsVarHandle, &rhsVar));
1623 :
1624 0 : *resAddr = *lhsAddr + *rhsVar;
1625 0 : return CcuResult::CCU_SUCCESS;
1626 : }
1627 :
1628 : // resAddr = addrA + addrB → CcuRepAdd(Address, Address, Address)
1629 1 : CcuResult CcuKernel::AddressAddAddrToAddr(
1630 : CcuAddressHandle resAddrHandle, CcuAddressHandle addrAHandle, CcuAddressHandle addrBHandle)
1631 : {
1632 1 : PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAddAddrToAddr] resAddrHandle=%llu, addrAHandle=%llu, addrBHandle=%llu",
1633 : resAddrHandle, addrAHandle, addrBHandle);
1634 1 : CcuRep::Address *resAddr{nullptr}, *addrA{nullptr}, *addrB{nullptr};
1635 1 : CCU_CHK_RET(GetAddressByHandle(resAddrHandle, &resAddr));
1636 1 : CCU_CHK_RET(GetAddressByHandle(addrAHandle, &addrA));
1637 1 : CCU_CHK_RET(GetAddressByHandle(addrBHandle, &addrB));
1638 :
1639 1 : *resAddr = *addrA + *addrB;
1640 1 : return CcuResult::CCU_SUCCESS;
1641 : }
1642 :
1643 : // addr += variable → CcuRepAdd(Address, Variable) 就地加
1644 26 : CcuResult CcuKernel::AddressAddAssignVar(CcuAddressHandle addrHandle, CcuVariableHandle varHandle)
1645 : {
1646 26 : PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAddAssignVar] addrHandle=%llu, varHandle=%llu", addrHandle, varHandle);
1647 26 : CcuRep::Address *address{nullptr};
1648 26 : CCU_CHK_RET(GetAddressByHandle(addrHandle, &address));
1649 :
1650 26 : CcuRep::Variable *variable{nullptr};
1651 26 : CCU_CHK_RET(GetVariableByHandle(varHandle, &variable));
1652 :
1653 26 : (*address) += (*variable);
1654 26 : return CcuResult::CCU_SUCCESS;
1655 : }
1656 :
1657 : // addr += addr → 等价于 addr = addr + otherAddr
1658 0 : CcuResult CcuKernel::AddressAddAssignAddr(CcuAddressHandle addrHandle, CcuAddressHandle otherHandle)
1659 : {
1660 0 : PLF_CONFIG_INFO(PLF_DATA_OP, "[AddressAddAssignAddr] addrHandle=%llu, otherHandle=%llu", addrHandle, otherHandle);
1661 0 : CcuRep::Address *address{nullptr};
1662 0 : CCU_CHK_RET(GetAddressByHandle(addrHandle, &address));
1663 :
1664 0 : CcuRep::Address *other{nullptr};
1665 0 : CCU_CHK_RET(GetAddressByHandle(otherHandle, &other));
1666 :
1667 0 : (*address) = (*address) + (*other);
1668 0 : return CcuResult::CCU_SUCCESS;
1669 : }
1670 :
1671 0 : CcuResult CcuKernel::AddressAddImmToAddr(CcuAddressHandle resAddrHandle, CcuAddressHandle addrAHandle, uint16_t imm)
1672 : {
1673 0 : CcuRep::Address *resAddr{nullptr}, *addrA{nullptr};
1674 0 : CCU_CHK_RET(GetAddressByHandle(resAddrHandle, &resAddr));
1675 0 : CCU_CHK_RET(GetAddressByHandle(addrAHandle, &addrA));
1676 :
1677 0 : *resAddr = *addrA + imm;
1678 0 : return CcuResult::CCU_SUCCESS;
1679 : }
1680 :
1681 0 : void CcuKernel::Load(const CcuRep::Variable &var)
1682 : {
1683 : auto loadArgRep = std::make_shared<CcuRep::CcuRepLoadArg>(
1684 0 : insGenerator, var, loadArgIndex_ % CCU_SQE_ARGS_LEN, static_cast<uint16_t>(loadArgIndex_));
1685 0 : GetLGProfilingInfo().loadRep2ArgIdxMap[loadArgRep] = loadArgIndex_;
1686 0 : Append(loadArgRep);
1687 0 : loadArgIndex_++;
1688 0 : }
1689 :
1690 0 : void CcuKernel::StoreVariable(const CcuRep::Variable &var, uint64_t addr)
1691 : {
1692 0 : Append(std::make_shared<CcuRep::CcuRepStore>(insGenerator, var, addr));
1693 0 : }
1694 :
1695 0 : void CcuKernel::LoadVariable(const CcuRep::Variable &src, const CcuRep::Variable &var)
1696 : {
1697 0 : Append(std::make_shared<CcuRep::CcuRepLoadVar>(insGenerator, src, var));
1698 0 : }
1699 :
1700 6 : HcclResult CcuKernel::RecordEvent(CcuRep::CompletedEvent event, uint32_t mask)
1701 : {
1702 6 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
1703 1 : HCCL_ERROR("[CcuKernel][%s] is not supported in loop block, please check.", __func__);
1704 1 : LatchBodyError(HCCL_TO_CCU_RET(HcclResult::HCCL_E_NOT_SUPPORT));
1705 1 : return HcclResult::HCCL_E_NOT_SUPPORT;
1706 : }
1707 :
1708 5 : auto rep = std::make_shared<CcuRep::CcuRepLocRecordEvent>(insGenerator, event, mask);
1709 5 : Append(rep);
1710 5 : SetDependencyInfo(event.Id(), mask, rep);
1711 5 : return HCCL_SUCCESS;
1712 5 : }
1713 :
1714 21 : HcclResult CcuKernel::WaitEvent(CcuRep::CompletedEvent event, uint32_t mask)
1715 : {
1716 21 : bool isProfiling = CurrentBlock()->Type() != CcuRep::CcuRepType::LOOP_BLOCK;
1717 21 : auto rep = std::make_shared<CcuRep::CcuRepLocWaitEvent>(insGenerator, event, mask, isProfiling);
1718 21 : if (isProfiling) {
1719 33 : CHK_RET(static_cast<HcclResult>(AddProfiling("WaitEvent", rep->GetMask())));
1720 : }
1721 21 : rep->SetDependencyInfo(GetDependencyInfo(event.Id()));
1722 21 : EraseDependencyInfo(event.Id());
1723 21 : Append(rep);
1724 21 : return HCCL_SUCCESS;
1725 21 : }
1726 :
1727 47 : CcuResult CcuKernel::GetEventByHandle(CcuEventHandle eventHandle, CcuRep::CompletedEvent **event)
1728 : {
1729 47 : return GetResourceByHandle(ccuEventMap_, eventHandle, event, "completedEvent");
1730 : }
1731 :
1732 : /*
1733 : LocalAddr / RemoteAddr 相关接口
1734 : */
1735 16 : CcuResult CcuKernel::GetLocalAddrByHandle(CcuLocalAddrHandle handle, CcuRep::LocalAddr **localAddr)
1736 : {
1737 16 : return GetResourceByHandle(ccuLocalAddrMap_, handle, localAddr, "localAddr");
1738 : }
1739 :
1740 8 : CcuResult CcuKernel::GetRemoteAddrByHandle(CcuRemoteAddrHandle handle, CcuRep::RemoteAddr **remoteAddr)
1741 : {
1742 8 : return GetResourceByHandle(ccuRemoteAddrMap_, handle, remoteAddr, "remoteAddr");
1743 : }
1744 :
1745 :
1746 : /*Read新接口*/
1747 1 : HcclResult CcuKernel::ReadNb(const ChannelHandle channel, const CcuRep::CcuBuf &loc, const CcuRep::RemoteAddr &rem,
1748 : const CcuRep::Variable &len, CcuRep::CompletedEvent event, uint32_t mask)
1749 : {
1750 1 : channels_.insert(channel);
1751 1 : auto rep = std::make_shared<CcuRep::CcuRepBufRead>(insGenerator, channel, rem, loc, len, event, mask);
1752 1 : Append(rep);
1753 1 : SetDependencyInfo(event.Id(), mask, rep);
1754 1 : return HCCL_SUCCESS;
1755 1 : }
1756 :
1757 : /*Write新接口*/
1758 1 : HcclResult CcuKernel::WriteNb(const ChannelHandle channel, const CcuRep::RemoteAddr &rem, const CcuRep::CcuBuf &loc,
1759 : const CcuRep::Variable &len, CcuRep::CompletedEvent event, uint32_t mask)
1760 : {
1761 1 : channels_.insert(channel);
1762 1 : auto rep = std::make_shared<CcuRep::CcuRepBufWrite>(insGenerator, channel, loc, rem, len, event, mask);
1763 1 : Append(rep);
1764 1 : SetDependencyInfo(event.Id(), mask, rep);
1765 1 : return HCCL_SUCCESS;
1766 1 : }
1767 :
1768 4 : static bool isLowPrecisionIn(Hccl::DataType dataType)
1769 : {
1770 8 : return dataType == Hccl::DataType::INT8 || dataType == Hccl::DataType::HIF8 || dataType == Hccl::DataType::FP8E4M3
1771 8 : || dataType == Hccl::DataType::FP8E5M2;
1772 : }
1773 :
1774 0 : static bool isLowPrecisionOut(Hccl::DataType dataType)
1775 : {
1776 0 : return dataType == Hccl::DataType::FP16 || dataType == Hccl::DataType::BFP16 || dataType == Hccl::DataType::FP32;
1777 : }
1778 :
1779 : constexpr uint32_t MAX_DATA_TYPE = 17;
1780 :
1781 : const Hccl::DataType orionDataTypes[] = {
1782 : Hccl::DataType::INT8,
1783 : Hccl::DataType::INT16,
1784 : Hccl::DataType::INT32,
1785 : Hccl::DataType::FP16,
1786 : Hccl::DataType::FP32,
1787 : Hccl::DataType::INT64,
1788 : Hccl::DataType::UINT64,
1789 : Hccl::DataType::UINT8,
1790 : Hccl::DataType::UINT16,
1791 : Hccl::DataType::UINT32,
1792 : Hccl::DataType::FP64,
1793 : Hccl::DataType::BFP16,
1794 : Hccl::DataType::INT128,
1795 : #if !defined (OPEN_BUILD_PROJECT) || defined (ORION_MODE)
1796 : Hccl::DataType::HIF8,
1797 : Hccl::DataType::FP8E4M3,
1798 : Hccl::DataType::FP8E5M2,
1799 : Hccl::DataType::FP8E8M0
1800 : #endif
1801 : };
1802 :
1803 6 : static Hccl::DataType HcommDataTypeToHcclDataType(const HcclDataType dataType)
1804 : {
1805 6 : const auto dataTypeNum = static_cast<uint32_t>(dataType);
1806 6 : if (dataTypeNum > MAX_DATA_TYPE) {
1807 0 : return Hccl::DataType::INVALID;
1808 : }
1809 :
1810 6 : return orionDataTypes[dataTypeNum];
1811 : }
1812 :
1813 : constexpr uint32_t MAX_REDUCE_TYPE = 4;
1814 : const Hccl::ReduceOp orionReduceOps[] = {
1815 : Hccl::ReduceOp::SUM,
1816 : Hccl::ReduceOp::PROD,
1817 : Hccl::ReduceOp::MAX,
1818 : Hccl::ReduceOp::MIN,
1819 : };
1820 :
1821 4 : static Hccl::ReduceOp HcommReduceOpToHcclReduceOp(const HcclReduceOp reduceOp)
1822 : {
1823 4 : const auto reduceOpNum = static_cast<uint32_t>(reduceOp);
1824 4 : if (reduceOpNum > MAX_REDUCE_TYPE) {
1825 0 : return Hccl::ReduceOp::INVALID;
1826 : }
1827 :
1828 4 : return orionReduceOps[reduceOpNum];
1829 : }
1830 :
1831 2 : HcclResult CcuKernel::LocalReduceNb(const CcuRep::CcuBuf *bufs, uint32_t count, HcclDataType dataType,
1832 : HcclDataType outputDataType, HcclReduceOp opType,
1833 : const CcuRep::Variable &len, CcuRep::CompletedEvent event, uint32_t mask)
1834 : {
1835 2 : auto opType_ = HcommReduceOpToHcclReduceOp(opType);
1836 2 : auto dataType_ = HcommDataTypeToHcclDataType(dataType);
1837 2 : auto outputDataType_ = HcommDataTypeToHcclDataType(outputDataType);
1838 :
1839 4 : if ((opType_ == Hccl::ReduceOp::SUM && isLowPrecisionIn(dataType_) && !isLowPrecisionOut(outputDataType_))
1840 2 : || (opType_ == Hccl::ReduceOp::SUM && !isLowPrecisionIn(dataType_) && dataType_ != outputDataType_)
1841 4 : || (opType_ != Hccl::ReduceOp::SUM && dataType_ != outputDataType_)) {
1842 0 : return HCCL_E_NOT_SUPPORT;
1843 : }
1844 :
1845 2 : std::vector<CcuRep::CcuBuf> ccuBufs(count);
1846 6 : for (uint32_t i = 0; i < count; i++) {
1847 4 : ccuBufs[i] = bufs[i];
1848 : }
1849 :
1850 0 : auto rep = std::make_shared<CcuRep::CcuRepBufReduce>(insGenerator, ccuBufs, count, CcuRep::GetCcuDataType(dataType_, opType_),
1851 2 : CcuRep::GetCcuDataType(outputDataType_, opType_), CcuRep::GetCcuReduceType(opType_), event, len, mask);
1852 2 : Append(rep);
1853 2 : SetDependencyInfo(event.Id(), mask, rep);
1854 2 : return HCCL_SUCCESS;
1855 2 : }
1856 :
1857 : /*Read新接口*/
1858 2 : HcclResult CcuKernel::ReadNb(const ChannelHandle channel, const CcuRep::LocalAddr &loc, const CcuRep::RemoteAddr &rem,
1859 : const CcuRep::Variable &len, CcuRep::CompletedEvent event, uint32_t mask)
1860 : {
1861 2 : channels_.insert(channel);
1862 2 : auto rep = std::make_shared<CcuRep::CcuRepRead>(insGenerator, channel, loc, rem, len, event, mask);
1863 2 : Append(rep);
1864 2 : SetDependencyInfo(event.Id(), mask, rep);
1865 2 : return HCCL_SUCCESS;
1866 2 : }
1867 :
1868 : /*ReadReduce新接口*/
1869 1 : HcclResult CcuKernel::ReadReduceNb(const ChannelHandle channel, const CcuRep::LocalAddr &loc, const CcuRep::RemoteAddr &rem,
1870 : const CcuRep::Variable &len, HcclDataType dataType, HcclReduceOp opType,
1871 : CcuRep::CompletedEvent event, uint32_t mask)
1872 : {
1873 1 : channels_.insert(channel);
1874 1 : auto opType_ = HcommReduceOpToHcclReduceOp(opType);
1875 1 : auto dataType_ = HcommDataTypeToHcclDataType(dataType);
1876 :
1877 0 : auto rep = std::make_shared<CcuRep::CcuRepRead>(insGenerator, channel, loc, rem, len, CcuRep::GetUBDataType(dataType_),
1878 1 : CcuRep::GetUBReduceType(opType_), event, mask);
1879 1 : Append(rep);
1880 1 : SetDependencyInfo(event.Id(), mask, rep);
1881 1 : return HCCL_SUCCESS;
1882 1 : }
1883 :
1884 : /*Write新接口*/
1885 2 : HcclResult CcuKernel::WriteNb(const ChannelHandle channel, const CcuRep::RemoteAddr &rem, const CcuRep::LocalAddr &loc,
1886 : const CcuRep::Variable &len, CcuRep::CompletedEvent event, uint32_t mask)
1887 : {
1888 2 : channels_.insert(channel);
1889 2 : auto rep = std::make_shared<CcuRep::CcuRepWrite>(insGenerator, channel, rem, loc, len, event, mask);
1890 2 : Append(rep);
1891 2 : SetDependencyInfo(event.Id(), mask, rep);
1892 2 : return HCCL_SUCCESS;
1893 2 : }
1894 :
1895 1 : HcclResult CcuKernel::WriteReduceNb(const ChannelHandle channel, const CcuRep::RemoteAddr &rem, const CcuRep::LocalAddr &loc,
1896 : const CcuRep::Variable &len, HcclDataType dataType, HcclReduceOp opType,
1897 : CcuRep::CompletedEvent event, uint32_t mask)
1898 : {
1899 1 : channels_.insert(channel);
1900 1 : auto opType_ = HcommReduceOpToHcclReduceOp(opType);
1901 1 : auto dataType_ = HcommDataTypeToHcclDataType(dataType);
1902 :
1903 1 : auto rep = std::make_shared<CcuRep::CcuRepWrite>(insGenerator,
1904 1 : channel, rem, loc, len, CcuRep::GetUBDataType(dataType_), CcuRep::GetUBReduceType(opType_), event, mask);
1905 1 : Append(rep);
1906 1 : SetDependencyInfo(event.Id(), mask, rep);
1907 1 : return HCCL_SUCCESS;
1908 1 : }
1909 :
1910 16 : CcuResult CcuKernel::GetBufferByHandle(CcuBufferHandle bufferHandle, CcuRep::CcuBuf **buffer)
1911 : {
1912 16 : return GetResourceByHandle(ccuBufferMap_, bufferHandle, buffer, "buffer");
1913 : }
1914 :
1915 0 : HcclResult CcuKernel::LocalCopyNb(const CcuRep::LocalAddr &dst, const CcuRep::LocalAddr &src, const CcuRep::Variable &len,
1916 : CcuRep::CompletedEvent event, uint32_t mask)
1917 : {
1918 0 : auto rep = std::make_shared<CcuRep::CcuRepLocCpy>(insGenerator, dst, src, len, event, mask);
1919 0 : Append(rep);
1920 0 : SetDependencyInfo(event.Id(), mask, rep);
1921 0 : return HCCL_SUCCESS;
1922 0 : }
1923 :
1924 6 : HcclResult CcuKernel::LocalCopyNb(const CcuRep::CcuBuf &dst, const CcuRep::LocalAddr &src, const CcuRep::Variable &len,
1925 : CcuRep::CompletedEvent event, uint32_t mask)
1926 : {
1927 6 : auto rep = std::make_shared<CcuRep::CcuRepBufLocRead>(insGenerator, src, dst, len, event, mask);
1928 6 : Append(rep);
1929 6 : SetDependencyInfo(event.Id(), mask, rep);
1930 6 : return HCCL_SUCCESS;
1931 6 : }
1932 :
1933 4 : HcclResult CcuKernel::LocalCopyNb(const CcuRep::LocalAddr &dst, const CcuRep::CcuBuf &src, const CcuRep::Variable &len,
1934 : CcuRep::CompletedEvent event, uint32_t mask)
1935 : {
1936 4 : auto rep = std::make_shared<CcuRep::CcuRepBufLocWrite>(insGenerator, src, dst, len, event, mask);
1937 4 : Append(rep);
1938 4 : SetDependencyInfo(event.Id(), mask, rep);
1939 4 : return HCCL_SUCCESS;
1940 4 : }
1941 :
1942 0 : HcclResult CcuKernel::LocalReduceNb(const CcuRep::LocalAddr &dst, const CcuRep::LocalAddr &src, const CcuRep::Variable &len,
1943 : HcclDataType dataType, HcclReduceOp opType, CcuRep::CompletedEvent event, uint32_t mask)
1944 : {
1945 0 : auto opType_ = HcommReduceOpToHcclReduceOp(opType);
1946 0 : auto dataType_ = HcommDataTypeToHcclDataType(dataType);
1947 :
1948 0 : auto rep = std::make_shared<CcuRep::CcuRepLocCpy>(insGenerator, dst, src, len, CcuRep::GetUBDataType(dataType_),
1949 0 : CcuRep::GetUBReduceType(opType_), event, mask);
1950 0 : Append(rep);
1951 0 : SetDependencyInfo(event.Id(), mask, rep);
1952 0 : return HCCL_SUCCESS;
1953 0 : }
1954 :
1955 0 : CcuRep::FuncCall CcuKernel::Func(const std::string &label)
1956 : {
1957 0 : return CcuRep::FuncCall(this, label);
1958 : }
1959 :
1960 0 : CcuRep::FuncCall CcuKernel::Func(const CcuRep::Variable &funcAddr)
1961 : {
1962 0 : return CcuRep::FuncCall(this, funcAddr);
1963 : }
1964 :
1965 0 : CcuRep::LoopCall CcuKernel::Loop(const std::string &label)
1966 : {
1967 0 : return CcuRep::LoopCall(this, label);
1968 : }
1969 :
1970 31 : CcuResult CcuKernel::LoopCreate(CcuLoop *loop)
1971 : {
1972 31 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopCreate]");
1973 31 : if (loop == nullptr) {
1974 0 : HCCL_ERROR("[CcuKernel::LoopCreate] null pointer");
1975 0 : return CcuResult::CCU_E_PTR;
1976 : }
1977 31 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
1978 0 : HCCL_ERROR("[CcuKernel::LoopCreate] cannot create loop inside a loop body");
1979 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
1980 : }
1981 31 : if (inFuncBody_) {
1982 0 : HCCL_ERROR("[CcuKernel::LoopCreate] cannot create loop inside a func body");
1983 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
1984 : }
1985 :
1986 31 : CcuLoop handle = ++loopHandleCounter_;
1987 31 : std::string label = "loop_" + std::to_string(handle);
1988 :
1989 31 : LoopDescriptor desc;
1990 31 : desc.label = label;
1991 31 : desc.repLoopBlock = std::make_shared<CcuRep::CcuRepLoopBlock>(insGenerator, label);
1992 :
1993 31 : loopMap_[handle] = std::move(desc);
1994 31 : *loop = handle;
1995 31 : return CcuResult::CCU_SUCCESS;
1996 31 : }
1997 :
1998 7 : CcuResult CcuKernel::LatchBodyError(CcuResult err)
1999 : {
2000 15 : if ((CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK || inFuncBody_)
2001 15 : && bodyError_ == CcuResult::CCU_SUCCESS) {
2002 7 : bodyError_ = err;
2003 : }
2004 7 : return err;
2005 : }
2006 :
2007 31 : CcuResult CcuKernel::LoopBodyEnter(CcuLoop loop)
2008 : {
2009 31 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopBodyEnter] loop=%llu", loop);
2010 31 : auto it = loopMap_.find(loop);
2011 31 : if (it == loopMap_.end()) {
2012 0 : HCCL_ERROR("[CcuKernel::LoopBodyEnter] invalid loop handle %lu", loop);
2013 0 : return CcuResult::CCU_E_PARA;
2014 : }
2015 31 : auto &desc = it->second;
2016 31 : if (desc.bodyDefined) {
2017 0 : HCCL_ERROR("[CcuKernel::LoopBodyEnter] loop %lu body already defined", loop);
2018 0 : return CcuResult::CCU_E_INTERNAL;
2019 : }
2020 :
2021 31 : Append(desc.repLoopBlock);
2022 31 : desc.prevActiveBlock = CurrentBlock();
2023 31 : SetCurrentBlock(desc.repLoopBlock);
2024 31 : ++loopBodyDepth_;
2025 31 : bodyError_ = CcuResult::CCU_SUCCESS;
2026 :
2027 31 : return CcuResult::CCU_SUCCESS;
2028 : }
2029 :
2030 31 : CcuResult CcuKernel::LoopBodyExit(CcuLoop loop)
2031 : {
2032 31 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopBodyExit] loop=%llu", loop);
2033 31 : auto it = loopMap_.find(loop);
2034 31 : if (it == loopMap_.end()) {
2035 0 : HCCL_ERROR("[CcuKernel::LoopBodyExit] invalid loop handle %lu", loop);
2036 0 : return CcuResult::CCU_E_PARA;
2037 : }
2038 31 : auto &desc = it->second;
2039 :
2040 31 : SetCurrentBlock(desc.prevActiveBlock);
2041 31 : desc.bodyDefined = true;
2042 31 : --loopBodyDepth_;
2043 :
2044 31 : if (bodyError_ != CcuResult::CCU_SUCCESS) {
2045 6 : const CcuResult err = bodyError_;
2046 6 : HCCL_ERROR("[CcuKernel::LoopBodyExit] illegal operation inside loop body, err=%d", err);
2047 6 : bodyError_ = CcuResult::CCU_SUCCESS;
2048 6 : return err;
2049 : }
2050 :
2051 25 : return CcuResult::CCU_SUCCESS;
2052 : }
2053 :
2054 8 : CcuResult CcuKernel::FuncBlockLookup(const void *funcPtr, uint64_t *outHandle)
2055 : {
2056 8 : PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncBlockLookup] funcPtr=%p", funcPtr);
2057 8 : if (funcPtr == nullptr || outHandle == nullptr) {
2058 0 : HCCL_ERROR("[CcuKernel::FuncBlockLookup] null pointer");
2059 0 : return CcuResult::CCU_E_PTR;
2060 : }
2061 8 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK || inFuncBody_) {
2062 2 : HCCL_ERROR("[CcuKernel::FuncBlockLookup] ccu::CallFunc only allowed at top level");
2063 2 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
2064 : }
2065 :
2066 6 : auto it = funcInstanceMap_.find(funcPtr);
2067 6 : *outHandle = (it == funcInstanceMap_.end()) ? 0 : it->second;
2068 6 : return CcuResult::CCU_SUCCESS;
2069 : }
2070 :
2071 5 : CcuResult CcuKernel::FuncBlockBegin(const void *funcPtr, uint64_t *outHandle)
2072 : {
2073 5 : PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncBlockBegin] funcPtr=%p", funcPtr);
2074 5 : if (funcPtr == nullptr || outHandle == nullptr) {
2075 0 : HCCL_ERROR("[CcuKernel::FuncBlockBegin] null pointer");
2076 0 : return CcuResult::CCU_E_PTR;
2077 : }
2078 5 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK || inFuncBody_) {
2079 0 : HCCL_ERROR("[CcuKernel::FuncBlockBegin] ccu::CallFunc only allowed at top level");
2080 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
2081 : }
2082 :
2083 5 : auto exist = funcInstanceMap_.find(funcPtr);
2084 5 : if (exist != funcInstanceMap_.end()) {
2085 0 : *outHandle = exist->second;
2086 0 : return CcuResult::CCU_SUCCESS;
2087 : }
2088 :
2089 5 : const uint64_t handle = ++funcHandleCounter_;
2090 5 : std::string label = "func_" + std::to_string(handle);
2091 :
2092 5 : FuncDescriptor desc;
2093 5 : desc.funcPtr = funcPtr;
2094 5 : desc.label = label;
2095 5 : desc.repFuncBlock = std::make_shared<CcuRep::CcuRepFuncBlock>(insGenerator, label);
2096 5 : desc.prevActiveBlock = CurrentBlock();
2097 :
2098 5 : funcMap_[handle] = desc;
2099 5 : SetCurrentBlock(desc.repFuncBlock);
2100 5 : inFuncBody_ = true;
2101 5 : bodyError_ = CcuResult::CCU_SUCCESS;
2102 5 : *outHandle = handle;
2103 5 : return CcuResult::CCU_SUCCESS;
2104 5 : }
2105 :
2106 4 : CcuResult CcuKernel::FuncBlockEnd(uint64_t handle)
2107 : {
2108 4 : PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncBlockEnd] handle=%llu", handle);
2109 4 : auto it = funcMap_.find(handle);
2110 4 : if (it == funcMap_.end()) {
2111 0 : HCCL_ERROR("[CcuKernel::FuncBlockEnd] invalid func handle %lu", handle);
2112 0 : return CcuResult::CCU_E_PARA;
2113 : }
2114 4 : auto &desc = it->second;
2115 :
2116 4 : SetCurrentBlock(desc.prevActiveBlock);
2117 4 : inFuncBody_ = false;
2118 :
2119 4 : if (bodyError_ != CcuResult::CCU_SUCCESS) {
2120 0 : const CcuResult err = bodyError_;
2121 0 : HCCL_ERROR("[CcuKernel::FuncBlockEnd] illegal operation inside func body, err=%d", err);
2122 0 : bodyError_ = CcuResult::CCU_SUCCESS;
2123 0 : funcMap_.erase(it);
2124 0 : return err;
2125 : }
2126 :
2127 4 : Append(desc.repFuncBlock);
2128 4 : desc.bodyDefined = true;
2129 4 : funcInstanceMap_[desc.funcPtr] = handle;
2130 4 : return CcuResult::CCU_SUCCESS;
2131 : }
2132 :
2133 7 : CcuResult CcuKernel::FuncDefineInArg(uint64_t handle, CcuVariableHandle formal)
2134 : {
2135 7 : PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncDefineInArg] handle=%llu, formal=%llu", handle, formal);
2136 7 : auto it = funcMap_.find(handle);
2137 7 : if (it == funcMap_.end()) {
2138 0 : HCCL_ERROR("[CcuKernel::FuncDefineInArg] invalid func handle %lu", handle);
2139 0 : return CcuResult::CCU_E_PARA;
2140 : }
2141 :
2142 7 : CcuRep::Variable *formalVar = nullptr;
2143 7 : CCU_CHK_RET(GetVariableByHandle(formal, &formalVar));
2144 7 : it->second.repFuncBlock->DefineInArg(*formalVar);
2145 7 : return CcuResult::CCU_SUCCESS;
2146 : }
2147 :
2148 5 : CcuResult CcuKernel::FuncCall(uint64_t handle, const CcuVariableHandle *inArgs, uint32_t numIn)
2149 : {
2150 5 : PLF_CONFIG_INFO(PLF_DATA_OP, "[FuncCall] handle=%llu, numIn=%u", handle, numIn);
2151 5 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK || inFuncBody_) {
2152 0 : HCCL_ERROR("[CcuKernel::FuncCall] ccu::CallFunc only allowed at top level");
2153 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
2154 : }
2155 5 : if (numIn > 0 && inArgs == nullptr) {
2156 0 : HCCL_ERROR("[CcuKernel::FuncCall] null input args");
2157 0 : return CcuResult::CCU_E_PTR;
2158 : }
2159 :
2160 5 : auto it = funcMap_.find(handle);
2161 5 : if (it == funcMap_.end() || !it->second.bodyDefined) {
2162 0 : HCCL_ERROR("[CcuKernel::FuncCall] invalid func handle %lu", handle);
2163 0 : return CcuResult::CCU_E_PARA;
2164 : }
2165 :
2166 5 : auto repFuncCall = std::make_shared<CcuRep::CcuRepFuncCall>(insGenerator, it->second.label);
2167 12 : for (uint32_t i = 0; i < numIn; i++) {
2168 7 : CcuRep::Variable *actual = nullptr;
2169 7 : CCU_CHK_RET(GetVariableByHandle(inArgs[i], &actual));
2170 7 : repFuncCall->SetInArg(*actual);
2171 : }
2172 5 : Append(repFuncCall);
2173 5 : return CcuResult::CCU_SUCCESS;
2174 5 : }
2175 :
2176 : // 按 maxLoopNum 把 res_.blockExecutor[0] 扩容到至少 maxLoopNum 个 LoopEngine。
2177 : // 与 CreateBlockResAssist 对齐:所有 LoopEngine 资源先落在 die0 池,待
2178 : // SelectDie 完成后再由 MoveResourcesToDie 迁移到目标 die。
2179 : // 不同 LoopGroup 通过 local loopIdx 复用同一池低位 executorId,所以这里只
2180 : // "补足"而不是"累加"。
2181 18 : CcuResult CcuKernel::EnsureLoopEnginePool(uint32_t maxLoopNum)
2182 : {
2183 18 : if (maxLoopNum == 0) {
2184 0 : HCCL_ERROR("[CcuKernel::EnsureLoopEnginePool] maxLoopNum must be > 0");
2185 0 : return CcuResult::CCU_E_PARA;
2186 : }
2187 18 : constexpr uint32_t poolDieId = 0;
2188 18 : auto &loopEnginePool = res_.blockExecutor[poolDieId];
2189 18 : if (maxLoopNum <= loopEnginePool.size()) {
2190 8 : return CcuResult::CCU_SUCCESS;
2191 : }
2192 10 : const uint32_t deficit = maxLoopNum - static_cast<uint32_t>(loopEnginePool.size());
2193 10 : std::vector<CcuRep::Executor> tmp(deficit, CcuRep::Executor(this));
2194 10 : (void)CreateBlockExecutor(deficit, tmp.data());
2195 10 : return CcuResult::CCU_SUCCESS;
2196 10 : }
2197 :
2198 8 : CcuResult CcuKernel::LoopGroupCreate(CcuLoopGroup *group, uint32_t maxLoopNum,
2199 : const CcuLoopGroupConfig *config)
2200 : {
2201 8 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopGroupCreate] maxLoopNum=%u", maxLoopNum);
2202 8 : if (group == nullptr || config == nullptr) {
2203 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreate] null pointer");
2204 0 : return CcuResult::CCU_E_PTR;
2205 : }
2206 8 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
2207 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreate] cannot create loop group inside a loop body");
2208 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
2209 : }
2210 8 : if (inFuncBody_) {
2211 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreate] cannot create loop group inside a func body");
2212 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
2213 : }
2214 :
2215 : // 按需扩 LoopEngine 池;池足够则复用低位 executorId,跨组共享。
2216 8 : CCU_CHK_RET(EnsureLoopEnginePool(maxLoopNum));
2217 :
2218 8 : CcuLoopGroup handle = ++loopGroupHandleCounter_;
2219 :
2220 8 : LoopGroupDescriptor desc;
2221 8 : desc.config = *config;
2222 8 : desc.parallelVar = CreateVariable();
2223 8 : desc.offsetVar = CreateVariable();
2224 8 : desc.isVarBased = false;
2225 :
2226 : auto bundle = std::make_shared<CcuRep::CcuRepLoopGroupBundle>(
2227 8 : insGenerator, *config, desc.parallelVar, desc.offsetVar);
2228 8 : if (ccuVersion_ == CcuVersion::CCU_V2) {
2229 1 : bundle->SetXnOffsetVar(CreateVariable());
2230 : }
2231 8 : desc.bundleRep = bundle;
2232 8 : Append(bundle);
2233 :
2234 8 : loopGroupMap_[handle] = std::move(desc);
2235 8 : *group = handle;
2236 8 : return CcuResult::CCU_SUCCESS;
2237 8 : }
2238 :
2239 10 : CcuResult CcuKernel::LoopGroupCreateFromVar(CcuLoopGroup *group, uint32_t maxLoopNum,
2240 : CcuVariableHandle parallelVarHandle, CcuVariableHandle offsetVarHandle)
2241 : {
2242 10 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopGroupCreateFromVar] maxLoopNum=%u, parallelVarHandle=%llu, offsetVarHandle=%llu",
2243 : maxLoopNum, parallelVarHandle, offsetVarHandle);
2244 10 : if (group == nullptr) {
2245 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVar] null pointer for group");
2246 0 : return CcuResult::CCU_E_PTR;
2247 : }
2248 10 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
2249 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVar] cannot create loop group inside a loop body");
2250 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
2251 : }
2252 10 : if (inFuncBody_) {
2253 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVar] cannot create loop group inside a func body");
2254 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
2255 : }
2256 :
2257 10 : CCU_CHK_RET(EnsureLoopEnginePool(maxLoopNum));
2258 :
2259 10 : CcuRep::Variable *parallelVarPtr = nullptr;
2260 10 : CcuRep::Variable *offsetVarPtr = nullptr;
2261 10 : CCU_CHK_RET(GetVariableByHandle(parallelVarHandle, ¶llelVarPtr));
2262 10 : CCU_CHK_RET(GetVariableByHandle(offsetVarHandle, &offsetVarPtr));
2263 :
2264 10 : CcuLoopGroup handle = ++loopGroupHandleCounter_;
2265 :
2266 10 : LoopGroupDescriptor desc;
2267 10 : desc.parallelVar = CcuRep::Variable(*parallelVarPtr);
2268 10 : desc.offsetVar = CcuRep::Variable(*offsetVarPtr);
2269 10 : desc.isVarBased = true;
2270 :
2271 : auto bundle = std::make_shared<CcuRep::CcuRepLoopGroupBundle>(
2272 10 : insGenerator, desc.parallelVar, desc.offsetVar);
2273 10 : if (ccuVersion_ == CcuVersion::CCU_V2) {
2274 1 : bundle->SetCompatRemapVars(CreateVariable(), CreateVariable());
2275 : }
2276 10 : desc.bundleRep = bundle;
2277 10 : Append(bundle);
2278 :
2279 10 : loopGroupMap_[handle] = std::move(desc);
2280 10 : *group = handle;
2281 10 : return CcuResult::CCU_SUCCESS;
2282 10 : }
2283 :
2284 0 : CcuResult CcuKernel::LoopGroupCreateFromVarV2(CcuLoopGroup *group, uint32_t maxLoopNum,
2285 : CcuVariableHandle parallelVarV2Handle, CcuVariableHandle offsetVarV2Handle, CcuVariableHandle varOffsetVarHandle)
2286 : {
2287 0 : if (ccuVersion_ != CcuVersion::CCU_V2) {
2288 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVarV2] only supported on V2");
2289 0 : return CcuResult::CCU_E_NOT_SUPPORT;
2290 : }
2291 0 : if (group == nullptr) {
2292 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVarV2] null pointer for group");
2293 0 : return CcuResult::CCU_E_PTR;
2294 : }
2295 0 : if (CurrentBlock()->Type() == CcuRep::CcuRepType::LOOP_BLOCK) {
2296 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVarV2] cannot create loop group inside a loop body");
2297 0 : return CcuResult::CCU_E_INTERNAL;
2298 : }
2299 0 : if (inFuncBody_) {
2300 0 : HCCL_ERROR("[CcuKernel::LoopGroupCreateFromVar] cannot create loop group inside a func body");
2301 0 : return LatchBodyError(CcuResult::CCU_E_INTERNAL);
2302 : }
2303 :
2304 0 : CCU_CHK_RET(EnsureLoopEnginePool(maxLoopNum));
2305 :
2306 0 : CcuRep::Variable *parallelVarPtr = nullptr;
2307 0 : CcuRep::Variable *offsetVarPtr = nullptr;
2308 0 : CcuRep::Variable *xnOffsetVarPtr = nullptr;
2309 0 : CCU_CHK_RET(GetVariableByHandle(parallelVarV2Handle, ¶llelVarPtr));
2310 0 : CCU_CHK_RET(GetVariableByHandle(offsetVarV2Handle, &offsetVarPtr));
2311 0 : CCU_CHK_RET(GetVariableByHandle(varOffsetVarHandle, &xnOffsetVarPtr));
2312 :
2313 0 : CcuLoopGroup handle = ++loopGroupHandleCounter_;
2314 :
2315 0 : LoopGroupDescriptor desc;
2316 0 : desc.parallelVar = CcuRep::Variable(*parallelVarPtr);
2317 0 : desc.offsetVar = CcuRep::Variable(*offsetVarPtr);
2318 0 : desc.xnOffsetVar = CcuRep::Variable(*xnOffsetVarPtr);
2319 0 : desc.isVarBased = true;
2320 0 : desc.isVersionV2 = true;
2321 :
2322 : auto bundle = std::make_shared<CcuRep::CcuRepLoopGroupBundle>(
2323 0 : insGenerator, desc.parallelVar, desc.offsetVar);
2324 0 : bundle->SetLayout(CcuRep::CcuRepLoopGroupBundle::Layout::VersionV2);
2325 0 : bundle->SetXnOffsetVar(desc.xnOffsetVar);
2326 0 : desc.bundleRep = bundle;
2327 0 : Append(bundle);
2328 :
2329 0 : loopGroupMap_[handle] = std::move(desc);
2330 0 : *group = handle;
2331 0 : return CcuResult::CCU_SUCCESS;
2332 0 : }
2333 :
2334 36 : CcuResult CcuKernel::LookupLoopGroupAndLoop(CcuLoopGroup group, CcuLoop loop,
2335 : const char *fnName, const char *createFnName,
2336 : LoopGroupDescriptor *&grpDesc, LoopDescriptor *&loopDesc,
2337 : uint32_t &loopIdx)
2338 : {
2339 36 : auto grpIt = loopGroupMap_.find(group);
2340 36 : if (grpIt == loopGroupMap_.end()) {
2341 0 : HCCL_ERROR("[CcuKernel::%s] invalid group handle %lu", fnName, group);
2342 0 : return CcuResult::CCU_E_PARA;
2343 : }
2344 36 : grpDesc = &grpIt->second;
2345 :
2346 36 : auto loopIt = loopMap_.find(loop);
2347 36 : if (loopIt == loopMap_.end()) {
2348 0 : HCCL_ERROR("[CcuKernel::%s] invalid loop handle %lu", fnName, loop);
2349 0 : return CcuResult::CCU_E_PARA;
2350 : }
2351 36 : loopDesc = &loopIt->second;
2352 :
2353 36 : if (!loopDesc->bodyDefined) {
2354 0 : HCCL_ERROR("[CcuKernel::%s] loop %lu body not defined", fnName, loop);
2355 0 : return CcuResult::CCU_E_INTERNAL; // CCU_E_LOOP_BODY_UNDEFINED
2356 : }
2357 :
2358 36 : auto &loopEnginePool = res_.blockExecutor[0];
2359 36 : loopIdx = grpDesc->loopCount;
2360 36 : if (loopIdx >= loopEnginePool.size()) {
2361 0 : HCCL_ERROR("[CcuKernel::%s] loopEngine pool exhausted (pool size %zu, loopIdx %u). "
2362 : "Pass a larger maxLoopNum to %s so the pool can be extended at create time.",
2363 : fnName, loopEnginePool.size(), loopIdx, createFnName);
2364 0 : return CcuResult::CCU_E_PARA;
2365 : }
2366 36 : return CcuResult::CCU_SUCCESS;
2367 : }
2368 :
2369 17 : CcuResult CcuKernel::LoopGroupAddLoop(CcuLoopGroup group,
2370 : CcuLoop loop, const CcuLoopConfig *config)
2371 : {
2372 17 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopGroupAddLoop] group=%llu, loop=%llu", group, loop);
2373 17 : if (config == nullptr) {
2374 0 : HCCL_ERROR("[CcuKernel::LoopGroupAddLoop] null pointer for config");
2375 0 : return CcuResult::CCU_E_PTR;
2376 : }
2377 :
2378 17 : LoopGroupDescriptor *grpDesc = nullptr;
2379 17 : LoopDescriptor *loopDesc = nullptr;
2380 17 : uint32_t loopIdx = 0;
2381 17 : CCU_CHK_RET(LookupLoopGroupAndLoop(group, loop, "LoopGroupAddLoop", "CcuLoopGroupCreate",
2382 : grpDesc, loopDesc, loopIdx));
2383 17 : auto &loopEnginePool = res_.blockExecutor[0];
2384 :
2385 17 : grpDesc->loopCount++;
2386 17 : grpDesc->totalLoopNum = grpDesc->loopCount;
2387 :
2388 17 : CcuRep::CcuRepLoopGroupBundle::LoopEntry entry;
2389 17 : entry.config = *config;
2390 17 : entry.executor = loopEnginePool[loopIdx];
2391 17 : entry.repLoopBlock = loopDesc->repLoopBlock;
2392 17 : entry.loopParamVar = CreateVariable();
2393 17 : entry.layout = CcuRep::CcuRepLoopGroupBundle::Layout::Config;
2394 17 : if (ccuVersion_ == CcuVersion::CCU_V2) {
2395 2 : entry.iterNumVar = CreateVariable();
2396 2 : entry.addrOffsetVar = CreateVariable();
2397 2 : entry.ctxIdVar = CreateVariable();
2398 : }
2399 :
2400 17 : auto bundle = std::static_pointer_cast<CcuRep::CcuRepLoopGroupBundle>(grpDesc->bundleRep);
2401 17 : bundle->AddLoop(entry);
2402 :
2403 17 : if (!grpDesc->isVarBased) {
2404 13 : bundle->SetRepeatLoopIdx(grpDesc->config.cloneLoopOffset);
2405 13 : bundle->SetTotalLoopNum(grpDesc->totalLoopNum);
2406 : }
2407 :
2408 17 : return CcuResult::CCU_SUCCESS;
2409 17 : }
2410 :
2411 19 : CcuResult CcuKernel::LoopGroupAddLoopFromVar(CcuLoopGroup group,
2412 : CcuLoop loop, CcuVariableHandle loopParamVarHandle)
2413 : {
2414 19 : PLF_CONFIG_INFO(PLF_DATA_OP, "[LoopGroupAddLoopFromVar] group=%llu, loop=%llu, loopParamVarHandle=%llu",
2415 : group, loop, loopParamVarHandle);
2416 19 : LoopGroupDescriptor *grpDesc = nullptr;
2417 19 : LoopDescriptor *loopDesc = nullptr;
2418 19 : uint32_t loopIdx = 0;
2419 19 : CCU_CHK_RET(LookupLoopGroupAndLoop(group, loop, "LoopGroupAddLoopFromVar", "CcuLoopGroupCreateFromVar",
2420 : grpDesc, loopDesc, loopIdx));
2421 19 : auto &loopEnginePool = res_.blockExecutor[0];
2422 :
2423 19 : CcuRep::Variable *loopParamVarPtr = nullptr;
2424 19 : CCU_CHK_RET(GetVariableByHandle(loopParamVarHandle, &loopParamVarPtr));
2425 :
2426 19 : CcuRep::CcuRepLoopGroupBundle::LoopEntry entry;
2427 19 : entry.executor = loopEnginePool[loopIdx];
2428 19 : entry.repLoopBlock = loopDesc->repLoopBlock;
2429 19 : entry.loopParamVar = CcuRep::Variable(*loopParamVarPtr);
2430 19 : entry.layout = CcuRep::CcuRepLoopGroupBundle::Layout::PackedVar;
2431 19 : if (ccuVersion_ == CcuVersion::CCU_V2) {
2432 2 : entry.iterNumVar = CreateVariable();
2433 2 : entry.addrOffsetVar = CreateVariable();
2434 2 : entry.ctxIdVar = CreateVariable();
2435 : }
2436 :
2437 19 : auto bundle = std::static_pointer_cast<CcuRep::CcuRepLoopGroupBundle>(grpDesc->bundleRep);
2438 19 : bundle->AddLoop(entry);
2439 :
2440 : // 计数放在入 bundle 之后统一更新:totalLoopNum 仅供 config 组同步编码使用,与 AddLoop 无先后依赖。
2441 19 : grpDesc->loopCount++;
2442 19 : grpDesc->totalLoopNum = grpDesc->loopCount;
2443 19 : if (!grpDesc->isVarBased) {
2444 4 : bundle->SetRepeatLoopIdx(grpDesc->config.cloneLoopOffset);
2445 4 : bundle->SetTotalLoopNum(grpDesc->totalLoopNum);
2446 : }
2447 :
2448 19 : return CcuResult::CCU_SUCCESS;
2449 19 : }
2450 :
2451 0 : CcuResult CcuKernel::LoopGroupAddLoopFromVarV2(CcuLoopGroup group,
2452 : CcuLoop loop, CcuVariableHandle iterNumVarHandle, CcuVariableHandle addrOffsetVarHandle,
2453 : CcuVariableHandle ctxIdVarHandle)
2454 : {
2455 0 : if (ccuVersion_ != CcuVersion::CCU_V2) {
2456 0 : HCCL_ERROR("[CcuKernel::LoopGroupAddLoopFromVarV2] only supported on V2");
2457 0 : return CcuResult::CCU_E_NOT_SUPPORT;
2458 : }
2459 :
2460 0 : LoopGroupDescriptor *grpDesc = nullptr;
2461 0 : LoopDescriptor *loopDesc = nullptr;
2462 0 : uint32_t loopIdx = 0;
2463 0 : CCU_CHK_RET(LookupLoopGroupAndLoop(group, loop, "LoopGroupAddLoopFromVarV2", "CcuLoopGroupCreateFromVarV2",
2464 : grpDesc, loopDesc, loopIdx));
2465 0 : auto &loopEnginePool = res_.blockExecutor[0];
2466 :
2467 0 : CcuRep::Variable *iterNumVarPtr = nullptr;
2468 0 : CcuRep::Variable *addrOffsetVarPtr = nullptr;
2469 0 : CcuRep::Variable *ctxIdVarPtr = nullptr;
2470 0 : CCU_CHK_RET(GetVariableByHandle(iterNumVarHandle, &iterNumVarPtr));
2471 0 : CCU_CHK_RET(GetVariableByHandle(addrOffsetVarHandle, &addrOffsetVarPtr));
2472 0 : CCU_CHK_RET(GetVariableByHandle(ctxIdVarHandle, &ctxIdVarPtr));
2473 :
2474 0 : grpDesc->loopCount++;
2475 0 : grpDesc->totalLoopNum = grpDesc->loopCount;
2476 :
2477 0 : VersionV2LoopRecord record;
2478 0 : record.iterNumVar = CcuRep::Variable(*iterNumVarPtr);
2479 0 : record.addrOffsetVar = CcuRep::Variable(*addrOffsetVarPtr);
2480 0 : record.ctxIdVar = CcuRep::Variable(*ctxIdVarPtr);
2481 0 : grpDesc->versionV2Loops.push_back(record);
2482 :
2483 0 : CcuRep::CcuRepLoopGroupBundle::LoopEntry entry;
2484 0 : entry.executor = loopEnginePool[loopIdx];
2485 0 : entry.repLoopBlock = loopDesc->repLoopBlock;
2486 0 : entry.iterNumVar = CcuRep::Variable(*iterNumVarPtr);
2487 0 : entry.addrOffsetVar = CcuRep::Variable(*addrOffsetVarPtr);
2488 0 : entry.ctxIdVar = CcuRep::Variable(*ctxIdVarPtr);
2489 0 : entry.layout = CcuRep::CcuRepLoopGroupBundle::Layout::VersionV2;
2490 :
2491 0 : auto bundle = std::static_pointer_cast<CcuRep::CcuRepLoopGroupBundle>(grpDesc->bundleRep);
2492 0 : bundle->AddLoop(entry);
2493 :
2494 0 : if (!grpDesc->isVarBased) {
2495 0 : bundle->SetRepeatLoopIdx(grpDesc->config.cloneLoopOffset);
2496 0 : bundle->SetTotalLoopNum(grpDesc->totalLoopNum);
2497 : }
2498 :
2499 0 : return CcuResult::CCU_SUCCESS;
2500 0 : }
2501 :
2502 19 : void CcuKernel::SetInstrId(uint32_t instrId)
2503 : {
2504 19 : instrInfo_.startInstrId = instrId;
2505 19 : }
2506 :
2507 41 : uint32_t CcuKernel::GetInstrId() const
2508 : {
2509 41 : return instrInfo_.startInstrId;
2510 : }
2511 :
2512 38 : uint32_t CcuKernel::GetInstrCount()
2513 : {
2514 38 : uint32_t instrCount = 0;
2515 856 : for (const auto &rep : GetRepSequence()) {
2516 818 : instrCount += rep->InstrCount();
2517 : }
2518 38 : instrInfo_.instrCount = instrCount;
2519 38 : HCCL_INFO("Kernel inst %u", instrCount);
2520 38 : return instrCount;
2521 : }
2522 :
2523 19 : void CcuKernel::SetCcuInstrInfo(const CcuRep::CcuInstrInfo &instrInfo)
2524 : {
2525 19 : this->instrInfo_ = instrInfo;
2526 19 : }
2527 :
2528 195 : CcuRep::Variable CcuKernel::CreateVariable()
2529 : {
2530 195 : return CreateResAssist(res_.continuousVariable);
2531 : }
2532 :
2533 104 : CcuRep::Address CcuKernel::CreateAddress()
2534 : {
2535 104 : CcuInsGeneraterV1* tmpPtrV1 = dynamic_cast<CcuInsGeneraterV1*>(insGenerator);
2536 104 : if (tmpPtrV1) {
2537 104 : return CreateResAssist(res_.address);
2538 : } else {
2539 : // A6创建Address时,需要添加到Variable的列表中,但是仍以Address返回
2540 0 : return CcuRep::Address(CreateResAssist(res_.continuousVariable));
2541 : }
2542 : }
2543 :
2544 0 : CcuRep::LocalNotify CcuKernel::CreateLocalNotify()
2545 : {
2546 0 : return CreateResAssist(res_.localNotify);
2547 : }
2548 :
2549 0 : CcuRep::CompletedEvent CcuKernel::CreateCompletedEvent()
2550 : {
2551 0 : return CreateResAssist(res_.completedEvent);
2552 : }
2553 :
2554 0 : CcuRep::CcuBuf CcuKernel::CreateCcuBuf()
2555 : {
2556 0 : return CreateResAssist(res_.ccubufs);
2557 : }
2558 :
2559 0 : CcuRep::Executor CcuKernel::CreateExecutor()
2560 : {
2561 0 : return CreateResAssist(res_.executor);
2562 : }
2563 :
2564 81 : CcuRep::LocalAddr CcuKernel::CreateLocalAddr()
2565 : {
2566 81 : return CcuRep::LocalAddr(CreateAddress(), CreateVariable());
2567 : }
2568 :
2569 20 : CcuRep::RemoteAddr CcuKernel::CreateRemoteAddr()
2570 : {
2571 20 : return CcuRep::RemoteAddr(CreateAddress(), CreateVariable());
2572 : }
2573 :
2574 0 : CcuRep::RemoteAddr CcuKernel::GetRemoteAddr(const ChannelHandle channel, uint32_t index)
2575 : {
2576 : (void)index;
2577 0 : channels_.insert(channel);
2578 0 : auto mem = CcuRep::RemoteAddr(CreateAddress(), CreateVariable());
2579 0 : Append(std::make_shared<CcuRep::CcuRepRemMem>(insGenerator, channel, mem));
2580 0 : return mem;
2581 0 : }
2582 :
2583 0 : CcuRep::LocalAddr CcuKernel::CreateLocalAddr(const CcuRep::Variable &token)
2584 : {
2585 0 : return CcuRep::LocalAddr(CreateAddress(), token);
2586 : }
2587 :
2588 0 : HcclResult CcuKernel::CreateBlockCcuBuf(const uint32_t count, CcuRep::CcuBuf *ccuBufs)
2589 : {
2590 0 : CHK_PTR_NULL(ccuBufs);
2591 0 : auto resources = CreateBlockResAssist(count, res_.blockCcubufs);
2592 :
2593 0 : for (uint32_t i = 0; i < count; i++) {
2594 0 : ccuBufs[i] = resources[i]; // 拷贝虚拟资源,通过shared_ptr链接到物理资源
2595 : }
2596 :
2597 0 : return HcclResult::HCCL_SUCCESS;
2598 0 : }
2599 :
2600 10 : HcclResult CcuKernel::CreateBlockExecutor(const uint32_t count, CcuRep::Executor *ccuExes)
2601 : {
2602 10 : CHK_PTR_NULL(ccuExes);
2603 10 : auto resources = CreateBlockResAssist(count, res_.blockExecutor);
2604 :
2605 25 : for (uint32_t i = 0; i < count; i++) {
2606 15 : ccuExes[i] = resources[i]; // 拷贝虚拟资源,通过shared_ptr链接到物理资源
2607 : }
2608 :
2609 10 : return HcclResult::HCCL_SUCCESS;
2610 10 : }
2611 :
2612 0 : HcclResult CcuKernel::CreateBlockCompletedEvent(const uint32_t count, CcuRep::CompletedEvent *ccuEvents)
2613 : {
2614 0 : CHK_PTR_NULL(ccuEvents);
2615 0 : auto resources = CreateBlockResAssist(count, res_.blockCompletedEvent);
2616 :
2617 0 : for (uint32_t i = 0; i < count; i++) {
2618 0 : ccuEvents[i] = resources[i]; // 拷贝虚拟资源,通过shared_ptr链接到物理资源
2619 : }
2620 :
2621 0 : return HcclResult::HCCL_SUCCESS;
2622 0 : }
2623 :
2624 19 : void CcuKernel::SetResRepository(const CcuResRepository &resRepo)
2625 : {
2626 19 : resRepo_ = resRepo;
2627 19 : }
2628 :
2629 19 : CcuResRepository &CcuKernel::GetResRepository()
2630 : {
2631 19 : return resRepo_;
2632 : }
2633 :
2634 19 : CcuSharedResource &CcuKernel::GetExportedRes()
2635 : {
2636 19 : return exportedRes_;
2637 : }
2638 :
2639 19 : CcuSharedResource &CcuKernel::GetImportedRes()
2640 : {
2641 19 : return importedRes_;
2642 : }
2643 :
2644 0 : static HcclResult GetArgIndex(const std::unordered_map<uint16_t, uint16_t> &varId2VarIdMap,
2645 : const std::unordered_map<uint16_t, uint32_t> &varId2ArgIndexMap,
2646 : const uint64_t *taskArgs, uint32_t argSize,
2647 : uint16_t varId, uint64_t& argIndex)
2648 : {
2649 0 : HCCL_INFO("[GetArgIndex] Enter varId(%u)", varId);
2650 0 : auto item = varId2ArgIndexMap.find(varId);
2651 0 : if (item == varId2ArgIndexMap.end()) {
2652 0 : uint16_t oriVarId = varId;
2653 0 : auto iter = varId2VarIdMap.find(varId);
2654 0 : while (iter != varId2VarIdMap.end()) { // 循环查找中间assign Rep,找到起始varId
2655 0 : oriVarId = iter->second;
2656 0 : iter = varId2VarIdMap.find(oriVarId);
2657 : }
2658 0 : if (oriVarId != varId) { // 起始varId预期通过LoadArg赋值
2659 0 : item = varId2ArgIndexMap.find(oriVarId);
2660 0 : if (item == varId2ArgIndexMap.end()) {
2661 0 : HCCL_ERROR("[%s]fail, Invalid goSize variable id(%u), oriVarId = %u", __func__, varId, oriVarId);
2662 0 : return HCCL_E_PARA;
2663 : }
2664 : } else {
2665 0 : HCCL_ERROR("[%s]fail, Invalid goSize variable id(%u)", __func__, varId);
2666 0 : return HCCL_E_PARA;
2667 : }
2668 : }
2669 0 : HCCL_INFO("[GetArgIndex] find end");
2670 0 : if (item->second >= argSize) {
2671 0 : HCCL_ERROR("Invalid goSize variable index(%u).", item->second);
2672 0 : return HCCL_E_PARA;
2673 : }
2674 0 : HCCL_INFO(
2675 : "GetArgIndex success: varId(%u) varId2VarIdMapSize(%u) varId2ArgIndexMapSize(%u) taskArgsSize(%u)",
2676 : varId, varId2VarIdMap.size(), varId2ArgIndexMap.size(), argSize);
2677 0 : argIndex = taskArgs[item->second];
2678 0 : return HCCL_SUCCESS;
2679 : }
2680 :
2681 3 : void DumpCcuProfilingInfo(const std::vector<CcuProfilingInfo> &ccuProfilingInfo)
2682 : {
2683 6 : auto dumpLinkInfo = [] (const CcuProfilingInfo &info) -> void {
2684 102 : for (int i = 0; i < CCU_MAX_CHANNEL_NUM; i++) {
2685 96 : if (info.channelId[i] == INVALID_VALUE_CHANNELID) {
2686 92 : continue;
2687 : }
2688 4 : HCCL_INFO("channelId(%u), remoteRankId(%u).", info.channelId[i], info.remoteRankId[i]);
2689 : }
2690 6 : };
2691 :
2692 12 : for (const auto &profInfo : ccuProfilingInfo) {
2693 9 : if (profInfo.type == static_cast<uint8_t>(CcuProfilinType::CCU_TASK_PROFILING)) {
2694 3 : HCCL_INFO("Dump CCU Profiling Info:SQE Profiling Info: ctxSignautre(%s), "
2695 : "dieId(%d), missionId(%d), instrId(%d).",
2696 : profInfo.name.c_str(), static_cast<int>(profInfo.dieId), static_cast<int>(profInfo.missionId),
2697 : static_cast<int>(profInfo.instrId));
2698 6 : } else if (profInfo.type == static_cast<uint8_t>(CcuProfilinType::CCU_WAITCKE_PROFILING)) {
2699 6 : HCCL_INFO("Microcode WaitCKE Profiling Info: name(%s), "
2700 : "dieId(%d), missionId(%d), instrId(%d), ckeId(%u), mask(%u).",
2701 : profInfo.name.c_str(), static_cast<int>(profInfo.dieId), static_cast<int>(profInfo.missionId),
2702 : static_cast<int>(profInfo.instrId), profInfo.ckeId, profInfo.mask);
2703 6 : dumpLinkInfo(profInfo);
2704 0 : } else if (profInfo.type == static_cast<uint8_t>(CcuProfilinType::CCU_LOOPGROUP_PROFILING)) {
2705 0 : HCCL_INFO("Microcode LoopGroup Profiling Info: name(%s), "
2706 : "dieId(%d), missionId(%d), instrId(%d), reduceOpType(%d), inputDataType(%d), "
2707 : "outputDataType(%d), dataSize(%llu).",
2708 : profInfo.name.c_str(), static_cast<int>(profInfo.dieId), static_cast<int>(profInfo.missionId),
2709 : static_cast<int>(profInfo.instrId), static_cast<int>(profInfo.reduceOpType),
2710 : static_cast<int>(profInfo.inputDataType), static_cast<int>(profInfo.outputDataType),
2711 : profInfo.dataSize);
2712 0 : dumpLinkInfo(profInfo);
2713 : }
2714 : }
2715 3 : }
2716 :
2717 0 : constexpr uint64_t SetBits(uint16_t end)
2718 : {
2719 0 : return ((uint64_t(1) << (end + 1)) - uint64_t(1));
2720 : }
2721 :
2722 0 : static uint16_t ParseRepeatNumFromParallelParam(uint64_t parallelParam)
2723 : {
2724 0 : constexpr uint16_t repeatBitNum = 7; // 7: repeat num 占 7 bits
2725 0 : constexpr uint16_t repeatNumShiftBit = 55; // 55: repeat num占[61:55]位置
2726 0 : return ( parallelParam >> repeatNumShiftBit) & SetBits(repeatBitNum);
2727 : }
2728 :
2729 3 : HcclResult CcuKernel::CollectSqeAndWaitCkeProfilingInfo()
2730 : {
2731 3 : auto &ccuProfilingCache = GetProfilingInfo();
2732 3 : uint32_t count {0};
2733 3 : HCCL_INFO("[GetCcuProfilingInfo] Process sqe&waitcke profiling info start.");
2734 12 : for (auto &profInfo : ccuProfilingCache) {
2735 9 : profInfo.missionId = GetMissionId();
2736 9 : if (profInfo.type == static_cast<uint8_t>(hcomm::CcuProfilinType::CCU_TASK_PROFILING)) {
2737 3 : profInfo.instrId = GetInstrId();
2738 3 : allCcuProfilingInfos_.push_back(profInfo);
2739 3 : continue;
2740 : }
2741 6 : if (count >= GetWaiteCkeProfilingReps().size()) {
2742 0 : HCCL_ERROR("count[%u] out of range[0, %u], cache size(%u).", count,
2743 : GetWaiteCkeProfilingReps().size(), ccuProfilingCache.size());
2744 0 : return HCCL_E_INTERNAL;
2745 : }
2746 6 : auto waitCkeRep = GetWaiteCkeProfilingReps()[count];
2747 6 : profInfo.instrId = waitCkeRep->StartInstrId();
2748 6 : if (profInfo.ckeId == INVALID_CKE_ID) { // localWait Rep
2749 2 : if (waitCkeRep.get() == nullptr) {
2750 0 : HCCL_ERROR("[GetCcuProfilingInfo] localWaitRep is nullptr.");
2751 0 : return HCCL_E_PTR;
2752 : }
2753 2 : profInfo.ckeId = waitCkeRep->GetId();
2754 2 : HCCL_INFO("[CcuKernel][GetCcuProfilingInfo] waitcke[%u]", profInfo.ckeId);
2755 : }
2756 6 : allCcuProfilingInfos_.push_back(profInfo);
2757 6 : count++;
2758 6 : }
2759 3 : return HCCL_SUCCESS;
2760 : }
2761 :
2762 3 : HcclResult CcuKernel::BuildLoopGroupVarIdMaps(std::unordered_map<uint16_t, uint32_t> &varId2ArgIndexMap,
2763 : std::unordered_map<uint16_t, uint16_t> &varId2VarIdMap)
2764 : {
2765 3 : auto &lgProfInfo = GetLGProfilingInfo();
2766 3 : HCCL_INFO("[GetCcuProfilingInfo] create varId2ArgIndexMap start. size=%lu",
2767 : lgProfInfo.loadRep2ArgIdxMap.size());
2768 3 : for (auto &iter : lgProfInfo.loadRep2ArgIdxMap) {
2769 0 : if (iter.first.get() == nullptr) {
2770 0 : HCCL_ERROR("[GetCcuProfilingInfo] loadRep is nullptr.");
2771 0 : return HCCL_E_PTR;
2772 : }
2773 0 : auto loadRep = dynamic_cast<CcuRep::CcuRepLoadArg*>(iter.first.get());
2774 0 : varId2ArgIndexMap[loadRep->GetVarId()] = iter.second;
2775 : }
2776 :
2777 3 : HCCL_INFO("[GetCcuProfilingInfo] create varId2VarIdMap start. size=%lu",
2778 : lgProfInfo.assignProfilingReps.size());
2779 49 : for (auto &iter : lgProfInfo.assignProfilingReps) {
2780 46 : if (iter.get() == nullptr) {
2781 0 : HCCL_ERROR("[GetCcuProfilingInfo] assignRep is nullptr.");
2782 0 : return HCCL_E_PTR;
2783 : }
2784 46 : auto assignRep = dynamic_cast<CcuRep::CcuRepAssign*>(iter.get());
2785 46 : varId2VarIdMap[assignRep->GetVarB().Id()] = assignRep->GetVarA().Id();
2786 : }
2787 3 : return HCCL_SUCCESS;
2788 : }
2789 :
2790 3 : HcclResult CcuKernel::CollectLoopGroupProfilingInfo(const uint64_t *taskArgs, uint32_t argSize,
2791 : const std::unordered_map<uint16_t, uint32_t> &varId2ArgIndexMap,
2792 : const std::unordered_map<uint16_t, uint16_t> &varId2VarIdMap)
2793 : {
2794 3 : auto &lgProfInfo = GetLGProfilingInfo();
2795 3 : HCCL_INFO("[GetCcuProfilingInfo] process loop group profiling start: "
2796 : "lgsize(%lu), goSize(%lu)", lgProfInfo.lgProfilingReps.size(), groupOpSizeInfo_.size());
2797 3 : for (uint32_t i = 0; i < lgProfInfo.lgProfilingReps.size(); i += 2) { // 2: 一个goSize对应一个CcuProfilingInfo,对应1个loopGroup Rep
2798 0 : if (argSize == 0 || varId2ArgIndexMap.empty()) {
2799 0 : continue;
2800 : }
2801 0 : uint64_t loopParam {0};
2802 0 : CHK_RET(GetArgIndex(varId2VarIdMap, varId2ArgIndexMap, taskArgs, argSize,
2803 : groupOpSizeInfo_[i].loopParamId, loopParam));
2804 0 : uint64_t parallelParam {0};
2805 0 : CHK_RET(GetArgIndex(varId2VarIdMap, varId2ArgIndexMap, taskArgs, argSize,
2806 : groupOpSizeInfo_[i].parallelParamId, parallelParam));
2807 0 : HCCL_INFO("Collect loopgroup profiling info: repSize[%u], index[%u],"
2808 : "loopParam[%llu], parallelParam[%llu].",
2809 : lgProfInfo.lgProfilingReps.size(), i, loopParam, parallelParam);
2810 :
2811 0 : if (loopParam != 0) {
2812 0 : lgProfInfo.ccuProfilingInfos[i].dataSize = loopParam * moConfig_.loopCount * moConfig_.memSlice;
2813 0 : lgProfInfo.ccuProfilingInfos[i].instrId = dynamic_cast<CcuRep::CcuRepLoopGroupBundle*>(lgProfInfo.lgProfilingReps[i].get())->StartInstrId();
2814 0 : allCcuProfilingInfos_.push_back(lgProfInfo.ccuProfilingInfos[i]);
2815 : }
2816 :
2817 0 : if (parallelParam != 0) {
2818 0 : HCCL_INFO("[GetCcuProfilingInfo] collect lg, residual start i=%lu", i);
2819 0 : uint64_t residual {0};
2820 0 : CHK_RET(GetArgIndex(varId2VarIdMap, varId2ArgIndexMap, taskArgs, argSize,
2821 : groupOpSizeInfo_[i].residualId, residual));
2822 0 : uint64_t repeatNum = ParseRepeatNumFromParallelParam(parallelParam);
2823 0 : lgProfInfo.ccuProfilingInfos[i].dataSize = repeatNum * moConfig_.memSlice + residual;
2824 0 : lgProfInfo.ccuProfilingInfos[i].instrId = dynamic_cast<CcuRep::CcuRepLoopGroupBundle*>(lgProfInfo.lgProfilingReps[i + 1].get())->StartInstrId();
2825 0 : allCcuProfilingInfos_.push_back(lgProfInfo.ccuProfilingInfos[i]);
2826 : }
2827 : }
2828 3 : return HCCL_SUCCESS;
2829 : }
2830 :
2831 : /*
2832 : * variable/maskSignal等资源变量Id,一定要在获取ccu profiling时才获取;
2833 : * 原因:在创建context Rep时,其资源Id属于虚拟资源;翻译时,才会绑定固定的物理资源。
2834 : */
2835 3 : HcclResult CcuKernel::GetCcuProfilingInfo(const uint64_t *taskArgs, uint32_t argSize,
2836 : std::vector<CcuProfilingInfo> &allCcuProfilingInfo)
2837 : {
2838 3 : HCCL_INFO("[GetCcuProfilingInfo] Enter.");
2839 3 : allCcuProfilingInfos_.clear();
2840 :
2841 3 : CHK_RET(CollectSqeAndWaitCkeProfilingInfo());
2842 :
2843 3 : std::unordered_map<uint16_t, uint32_t> varId2ArgIndexMap;
2844 3 : std::unordered_map<uint16_t, uint16_t> varId2VarIdMap;
2845 3 : CHK_RET(BuildLoopGroupVarIdMaps(varId2ArgIndexMap, varId2VarIdMap));
2846 :
2847 3 : CHK_RET(CollectLoopGroupProfilingInfo(taskArgs, argSize, varId2ArgIndexMap, varId2VarIdMap));
2848 :
2849 3 : DumpCcuProfilingInfo(allCcuProfilingInfos_);
2850 3 : allCcuProfilingInfo = allCcuProfilingInfos_;
2851 3 : return HCCL_SUCCESS;
2852 3 : }
2853 :
2854 0 : HcclResult CcuKernel::AddProfilingInfo(const ChannelHandle *channels, uint32_t channelNum, HcclDataType dataType,
2855 : HcclDataType outputDataType, HcclReduceOp opType, const std::string& opName)
2856 : {
2857 0 : CHK_PTR_NULL(channels);
2858 0 : ccuProfilingInfoCache.type = (uint8_t)CcuProfilinType::CCU_LOOPGROUP_PROFILING;
2859 0 : ccuProfilingInfoCache.name = opName;
2860 0 : ccuProfilingInfoCache.reduceOpType = opType;
2861 0 : ccuProfilingInfoCache.inputDataType = dataType;
2862 0 : ccuProfilingInfoCache.outputDataType = outputDataType;
2863 0 : ccuProfilingInfoCache.missionId = GetMissionId();
2864 :
2865 0 : CHK_SAFETY_FUNC_RET(memset_s(ccuProfilingInfoCache.channelId, sizeof(ccuProfilingInfoCache.channelId),
2866 : INVALID_VALUE_CHANNELID, sizeof(ccuProfilingInfoCache.channelId)));
2867 0 : for (uint32_t i = 0; i < channelNum; i++) {
2868 0 : void *channelPtr{nullptr};
2869 0 : CHK_RET(static_cast<HcclResult>(HcommChannelGet(channels[i], &channelPtr)));
2870 0 : auto *channelImpl = dynamic_cast<CcuUrmaChannel *>(static_cast<Channel *>(channelPtr));
2871 0 : CHK_PTR_NULL(channelImpl);
2872 0 : ccuProfilingInfoCache.channelId[i] = channelImpl->GetChannelId();
2873 0 : ccuProfilingInfoCache.channelHandle[i] = channels[i];
2874 0 : HCCL_INFO("[%s]type[%d], name[%s], opType[%d], dataType[%d], outputDataType[%d], missionId[%u], "
2875 : "channelHandle[0x%llx], channelId[%u]", __func__, ccuProfilingInfoCache.type,
2876 : ccuProfilingInfoCache.name.c_str(), opType, dataType, outputDataType, ccuProfilingInfoCache.missionId,
2877 : ccuProfilingInfoCache.channelHandle[i], ccuProfilingInfoCache.channelId[i]);
2878 : }
2879 0 : lgProfilingInfo.ccuProfilingInfos.push_back(ccuProfilingInfoCache);
2880 0 : lgProfilingInfo.lgProfilingReps.push_back(allLgProfilingReps.back());
2881 0 : return HCCL_SUCCESS;
2882 : }
2883 :
2884 0 : HcclResult CcuKernel::AddCcuProfiling(GroupInfo groupInfo, const std::vector<ChannelHandle> channelHandle, HcclDataType dataType,
2885 : HcclDataType outputDataType, HcclReduceOp opType, const std::string& opName)
2886 : {
2887 0 : CHK_RET(AddCcuProfiling(channelHandle.data(), channelHandle.size(), dataType, outputDataType, opType, opName));
2888 0 : groupOpSizeInfo_.push_back(groupInfo);
2889 0 : return HCCL_SUCCESS;
2890 : }
2891 :
2892 0 : HcclResult CcuKernel::AddCcuProfiling(const ChannelHandle *channels, uint32_t channelNum, HcclDataType dataType,
2893 : HcclDataType outputDataType, HcclReduceOp opType, const std::string& opName)
2894 : {
2895 0 : CHK_PTR_NULL(channels);
2896 0 : CHK_RET(AddProfilingInfo(channels, channelNum, dataType, outputDataType, opType, opName));
2897 0 : return HCCL_SUCCESS;
2898 : }
2899 :
2900 0 : HcclResult CcuKernel::Add2ConstValue2VarMap(std::vector<uint64_t> &values)
2901 : {
2902 : // 记录当前context所需的常量,仅A6场景适用
2903 0 : for (uint64_t value : values) {
2904 0 : if (constValue2VarMap.find(value) == constValue2VarMap.end()) {
2905 0 : constValue2VarMap[value] = CreateVariable();
2906 : }
2907 : }
2908 0 : return HCCL_SUCCESS;
2909 : }
2910 :
2911 : }; // namespace hcomm
|