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 <algorithm>
12 : #include <unordered_set>
13 : #include "mc2_compont.h"
14 : #include "ccu_assist.h"
15 : #include "mc2_context.h"
16 : #include "ccu_task_arg_mc2.h"
17 : #include "coll_service_device_mode.h"
18 : #include "mc2_global_mirror_tasks.h"
19 : #include "op_params_checker.h"
20 :
21 : namespace Hccl {
22 :
23 256 : Mc2Compont::~Mc2Compont()
24 : {
25 256 : auto deviceLogicId = comm->GetDeviceLogicId();
26 263 : for (const auto& server : ccuServerMap) {
27 7 : auto ret = InsExeQue::DeregisterExtendInstruction(deviceLogicId, server.first);
28 21 : HCCL_INFO("[Mc2Compont:%s]Destroy ccuServer execId[%u]", __func__, server.first);
29 7 : if (ret != HcclResult::HCCL_SUCCESS) {
30 15 : HCCL_ERROR("DeregisterExtendInstruction execId[%u] failed, ret[%d]", server.first, ret);
31 : }
32 : }
33 256 : ccuServerMap.clear();
34 256 : }
35 :
36 2 : void Mc2Compont::AllocCommResource(void* mc2Tiling, void** commContext)
37 : {
38 2 : auto tilingVersion = *static_cast<uint32_t*>(mc2Tiling);
39 6 : HCCL_INFO("[Mc2Compont:%s] Tiling version [%u]", __func__, tilingVersion);
40 2 : if (tilingVersion != UNKNOWN_TILING_V1 && tilingVersion != UNKNOWN_TILING_V2) {
41 0 : THROW<NotSupportException>(StringFormat("Tiling version not support, version[%u]", tilingVersion));
42 : }
43 :
44 2 : if (comm->GetRankSize() == 1) {
45 3 : HCCL_WARNING("Comm[%s] rank size is 1, Mc2 not support", comm->GetId().c_str());
46 1 : return;
47 : }
48 :
49 1 : std::unordered_set<uint64_t> algoTemplateRequire;
50 1 : if (tilingVersion == UNKNOWN_TILING_V1) {
51 : // 申请deviceMem、通信域信息获取、commContext赋值
52 0 : Alloc();
53 : // 生成本次需要的算子模板
54 0 : GenerateAlgoTemplates(reinterpret_cast<Mc2Tiling*>(mc2Tiling), algoTemplateRequire);
55 : } else {
56 : // 申请deviceMem、通信域信息获取、commContext赋值
57 1 : AllocV2();
58 : // 生成本次需要的算子模板
59 1 : GenerateAlgoTemplatesV2(reinterpret_cast<Mc2InitTilingInner*>(mc2Tiling), algoTemplateRequire);
60 : }
61 :
62 3 : HCCL_RUN_INFO(
63 : "hcclCombinOpParam info: workSpace = [%llu], rankId = [%u], rankDim = [%u], xnAddr = [%llu], "
64 : "ckeAddr = [%llu], winSize = [%llu], windowsOut[0] = [%llu]",
65 : combinOpParam.workSpace, combinOpParam.rankId, combinOpParam.rankDim, combinOpParam.xnAddr,
66 : combinOpParam.ckeAddr, combinOpParam.winSize, combinOpParam.windowsOut[0]);
67 3 : HCCL_RUN_INFO(
68 : "opType[0] = [%u], opType[1] = [%u], opType[2] = [%u], opType[3] = [%u], opType[4] = [%u], "
69 : "opType[5] = [%u], opType[6] = [%u], opType[7] = [%u], ",
70 : combinOpParam.opType[0], combinOpParam.opType[1], combinOpParam.opType[2], combinOpParam.opType[3],
71 : combinOpParam.opType[4], combinOpParam.opType[5], combinOpParam.opType[6], combinOpParam.opType[7]);
72 3 : HCCL_RUN_INFO(
73 : "algorithmType[0] = [%u], algorithmType[1] = [%u], algorithmType[2] = [%u], algorithmType[3] = [%u], "
74 : "algorithmType[4] = [%u], algorithmType[5] = [%u], algorithmType[6] = [%u], algorithmType[7] = [%u]",
75 : combinOpParam.algorithmType[0], combinOpParam.algorithmType[1], combinOpParam.algorithmType[2],
76 : combinOpParam.algorithmType[3], combinOpParam.algorithmType[4], combinOpParam.algorithmType[5],
77 : combinOpParam.algorithmType[6], combinOpParam.algorithmType[7]);
78 1 : auto paramSize = sizeof(HcclCombinOpParam);
79 1 : if (combinOpParamBuffer == nullptr) {
80 1 : combinOpParamBuffer = std::make_shared<DevBuffer>(paramSize);
81 : }
82 2 : HrtMemcpy(
83 1 : reinterpret_cast<void*>(combinOpParamBuffer->GetAddr()), paramSize, static_cast<void*>(&combinOpParam),
84 : paramSize, RT_MEMCPY_HOST_TO_DEVICE);
85 1 : *commContext = reinterpret_cast<void*>(combinOpParamBuffer->GetAddr());
86 : // 生成ccuServer指令,将注册得到的execId保存在curExecId,GetCcuTaskInfo时通过curExecId获取TaskParam
87 1 : GenerateCcuServer(algoTemplateRequire);
88 1 : }
89 :
90 2 : static bool GetArgSizeFlag(std::vector<std::vector<CcuTaskParam>>& taskParams)
91 : {
92 : /*
93 : * 在MC2场景下,暂定只支持三种场景:1)单die且一个mission,2)双die且每die一个mission,3)单die且多个mission
94 : * 一次调用HCCL接口只能支持一种场景,其中2)包括所有双die算法,3)包括带尾块处理的算法与HalfAlltoAllV算子,1)包括其余算法
95 : * 只有场景3)时需要使argSize=1,1)和2)argSize均不变
96 : */
97 2 : std::unordered_set<uint8_t> dieIdSet;
98 2 : std::unordered_set<uint8_t> missionIdSet;
99 4 : for (auto& task : taskParams) {
100 2 : dieIdSet.emplace(task[0].dieId);
101 2 : missionIdSet.emplace(task[0].missionId);
102 6 : HCCL_INFO("TaskParam: dieId = [%u], missionId = [%u]", task[0].dieId, task[0].missionId);
103 : }
104 2 : bool oneDieOneMission = (dieIdSet.size() == 1) && (missionIdSet.size() == 1);
105 2 : bool twoDieOneMission = (dieIdSet.size() == 2) && (missionIdSet.size() == 1);
106 2 : bool oneDieMultiMission = (dieIdSet.size() == 1) && (missionIdSet.size() > 1);
107 2 : if (!oneDieOneMission && !twoDieOneMission && !oneDieMultiMission) {
108 0 : THROW<NotSupportException>(
109 0 : StringFormat("MC2 Scene cannot support: not OneDieOneMission, TwoDieOneMission or OneDieMultiMission !"));
110 : }
111 2 : return oneDieMultiMission;
112 2 : }
113 :
114 2 : std::vector<CcuTaskParam> Mc2Compont::GetCcuTaskInfo(void* tilingData)
115 : {
116 6 : HCCL_INFO("%s start.", __func__);
117 6 : HCCL_INFO("tilingData=%llu", tilingData);
118 2 : std::vector<std::vector<CcuTaskParam>> taskParams;
119 2 : std::vector<CcuTaskParam> ccuTaskParam;
120 2 : if (tilingData == nullptr) {
121 0 : return ccuTaskParam;
122 : }
123 2 : auto mc2Tiling = reinterpret_cast<Mc2Tiling*>(tilingData);
124 6 : HCCL_INFO("mc2Tiling=%s", mc2Tiling->ToString().c_str());
125 2 : auto version = mc2Tiling->version;
126 :
127 2 : if (version != UNKNOWN_TILING_V1 && version != UNKNOWN_TILING_V2) {
128 0 : THROW<NotSupportException>(StringFormat("Tiling version not support, version[%u]", version));
129 : }
130 :
131 : // 校验curExecId是否有效
132 2 : if (ccuServerMap.find(curExecId) == ccuServerMap.end()) {
133 0 : THROW<Hccl::InternalException>(
134 0 : StringFormat("CcuServer not find, curExecId[%llu], ccuServerSize[%d]", curExecId, ccuServerMap.size()));
135 : }
136 :
137 2 : CcuTaskArgMc2 ccuTaskArg(tokenInfo);
138 2 : HcclResult ret = CcuCtxMgr::GetTaskParam(comm->GetDeviceLogicId(), ccuTaskArg, curExecId, taskParams);
139 2 : if (ret != HcclResult::HCCL_SUCCESS) {
140 0 : THROW<CcuApiException>(StringFormat("GetTaskParam failed, ret[%u]", ret));
141 : }
142 2 : bool argSizeFlag = GetArgSizeFlag(taskParams);
143 3 : for (auto& task : taskParams) {
144 2 : if (task.size() != 1) {
145 1 : THROW<Hccl::InternalException>(
146 3 : StringFormat("Task Num In TaskParams Should Be 1, While It Is %d", task.size()));
147 : }
148 1 : if (argSizeFlag) {
149 0 : task[0].argSize = 1;
150 : }
151 1 : u32 notifyTimeout = comm->GetNotifyTimeoutCfg().GetNotifyTimeout();
152 1 : task[0].timeout
153 1 : = (notifyTimeout > UINT16_MAX) ? static_cast<uint16_t>(UINT16_MAX) : static_cast<uint16_t>(notifyTimeout);
154 1 : ccuTaskParam.push_back(task[0]);
155 1 : SaveMc2DfxTaskInfo(task[0], curExecId);
156 : }
157 1 : std::sort(ccuTaskParam.begin(), ccuTaskParam.end(), [](const CcuTaskParam& a, const CcuTaskParam& b) {
158 0 : return a.missionId < b.missionId;
159 : });
160 3 : HCCL_INFO("GetCcuTaskInfo success");
161 1 : return ccuTaskParam;
162 4 : }
163 :
164 1 : void Mc2Compont::Alloc()
165 : {
166 : // inputMem给算法编排使用,只需要申请一次,按照最大数据类型申请
167 1 : inputMem = std::make_shared<DevBuffer>(dataCount * DataTypeSizeGet(DataType::INT64) * comm->GetRankSize());
168 3 : HCCL_INFO("[Mc2Compont][Alloc]inputMem addr[%p] size = [%llu]", inputMem->GetAddr(), inputMem->GetSize());
169 9 : for (uint32_t i = 0; i < MAX_OP_NUM; i++) {
170 8 : combinOpParam.opType[i] = 0;
171 8 : combinOpParam.algorithmType[i] = 0;
172 : }
173 1 : if (ccuResourceAlloced) {
174 0 : return;
175 : }
176 :
177 1 : constexpr uint32_t comSyncNum = 2; // 每轮同步使用2个同步信号
178 1 : uint32_t comParamBufSize = CCU_TASK_NUM_MAX * CCU_PARAM_NUM_MAX * CCU_ONE_PARAM_SIZE;
179 1 : uint32_t comSyncBufSize = CCU_TASK_NUM_MAX * comSyncNum * CCU_ONE_PARAM_SIZE;
180 1 : workspaceBuffer = std::make_shared<DevBuffer>(MC2_WORKSPACE_SIZE);
181 1 : comParamBuffer = std::make_shared<DevBuffer>(comParamBufSize);
182 1 : comSyncBuffer = std::make_shared<DevBuffer>(comSyncBufSize);
183 :
184 1 : combinOpParam.workSpace = static_cast<uint64_t>(workspaceBuffer->GetAddr());
185 1 : combinOpParam.workSpaceSize = MC2_WORKSPACE_SIZE;
186 1 : combinOpParam.rankId = comm->GetMyRank();
187 1 : combinOpParam.rankDim = comm->GetRankSize();
188 1 : combinOpParam.xnAddr = static_cast<uint64_t>(comParamBuffer->GetAddr());
189 1 : combinOpParam.ckeAddr = static_cast<uint64_t>(comSyncBuffer->GetAddr());
190 : // add cclbuffer info
191 1 : if (comm->GetCclBuffer() == nullptr) {
192 0 : THROW<Hccl::InternalException>(StringFormat("Cannot get CCL Buffer to fill window!"));
193 : }
194 1 : combinOpParam.winSize = static_cast<uint64_t>(comm->GetCclBuffer()->GetSize());
195 1 : combinOpParam.windowsOut[0] = static_cast<uint64_t>(comm->GetCclBuffer()->GetAddr());
196 1 : ccuResourceAlloced = true;
197 :
198 1 : tokenInfo = CcuRep::GetTokenInfo(
199 1 : static_cast<uint64_t>(workspaceBuffer->GetAddr()), static_cast<uint64_t>(workspaceBuffer->GetSize()));
200 : }
201 :
202 1 : void Mc2Compont::AllocV2()
203 : {
204 1 : inputMem = std::make_shared<DevBuffer>(dataCount * DataTypeSizeGet(DataType::INT64) * comm->GetRankSize());
205 3 : HCCL_INFO("[Mc2Compont][AllocV2]inputMem addr[%p] size = [%llu]", inputMem->GetAddr(), inputMem->GetSize());
206 9 : for (uint32_t i = 0; i < MAX_OP_NUM; i++) {
207 8 : combinOpParam.opType[i] = 0;
208 8 : combinOpParam.algorithmType[i] = 0;
209 : }
210 1 : if (ccuResourceAlloced) {
211 0 : return;
212 : }
213 :
214 1 : constexpr uint32_t comSyncNum = 2; // 每轮同步使用2个同步信号
215 1 : uint32_t comParamBufSize = CCU_TASK_NUM_MAX * CCU_PARAM_NUM_MAX * CCU_ONE_PARAM_SIZE;
216 1 : uint32_t comSyncBufSize = CCU_TASK_NUM_MAX * comSyncNum * CCU_ONE_PARAM_SIZE;
217 1 : workspaceBuffer = std::make_shared<DevBuffer>(MC2_WORKSPACE_SIZE);
218 1 : comParamBuffer = std::make_shared<DevBuffer>(comParamBufSize);
219 1 : comSyncBuffer = std::make_shared<DevBuffer>(comSyncBufSize);
220 1 : HrtMemset(reinterpret_cast<void*>(workspaceBuffer->GetAddr()), MC2_WORKSPACE_SIZE, MC2_WORKSPACE_SIZE);
221 1 : HrtMemset(reinterpret_cast<void*>(comParamBuffer->GetAddr()), comParamBufSize, comParamBufSize);
222 1 : HrtMemset(reinterpret_cast<void*>(comSyncBuffer->GetAddr()), comSyncBufSize, comSyncBufSize);
223 1 : combinOpParam.workSpace = static_cast<uint64_t>(workspaceBuffer->GetAddr());
224 1 : combinOpParam.workSpaceSize = MC2_WORKSPACE_SIZE;
225 1 : combinOpParam.rankId = comm->GetMyRank();
226 1 : combinOpParam.rankDim = comm->GetRankSize();
227 1 : combinOpParam.xnAddr = static_cast<uint64_t>(comParamBuffer->GetAddr());
228 1 : combinOpParam.ckeAddr = static_cast<uint64_t>(comSyncBuffer->GetAddr());
229 : // add cclbuffer info
230 1 : if (comm->GetCclBuffer() == nullptr) {
231 0 : THROW<Hccl::InternalException>(StringFormat("Cannot get CCL Buffer to fill window!"));
232 : }
233 1 : combinOpParam.winSize = static_cast<uint64_t>(comm->GetCclBuffer()->GetSize());
234 1 : combinOpParam.windowsOut[0] = static_cast<uint64_t>(comm->GetCclBuffer()->GetAddr());
235 1 : ccuResourceAlloced = true;
236 :
237 1 : tokenInfo = CcuRep::GetTokenInfo(
238 1 : static_cast<uint64_t>(workspaceBuffer->GetAddr()), static_cast<uint64_t>(workspaceBuffer->GetSize()));
239 : }
240 :
241 2 : void Mc2Compont::MC2Orchestrate(
242 : const CollAlgParams& params, std::shared_ptr<InsQueue>& insQueue, uint8_t commEngine) const
243 : {
244 2 : auto op = comm->GetCurrentCollOperator();
245 :
246 2 : CollOpParams opParams;
247 2 : opParams.commEngine = static_cast<HcclAccelerator::Value>(commEngine);
248 2 : opParams.opType = op->opType;
249 2 : opParams.dataType = op->dataType;
250 2 : opParams.count = op->dataCount;
251 2 : opParams.reduceOp = op->reduceOp;
252 2 : opParams.isMc2 = params.isMc2;
253 2 : comm->ExecAlgSelect(opParams, op->opMode);
254 2 : if (!comm->GetOpCcuFeatureFlag()) { // 算子粒度
255 : auto msg = StringFormat(
256 : "[Mc2Compont:%s]AlgSelect not ccu, accState[%s]", __func__,
257 0 : comm->GetOpExecuteConfig().accState.Describe().c_str());
258 0 : THROW<InternalException>(msg);
259 0 : }
260 :
261 2 : std::string algName = comm->GetCurAlgName();
262 : // 算子编排获取InsQueue
263 2 : auto ret = comm->GetCollAlgComponent()->Orchestrate(*op, params, algName, insQueue);
264 2 : if (ret != HcclResult::HCCL_SUCCESS) {
265 1 : THROW<InternalException>(
266 3 : StringFormat("Error occurs when call collAlgComponent.orchestrate(), error code: %d", ret));
267 : }
268 3 : }
269 :
270 1 : void Mc2Compont::MC2AllocCommRes(
271 : const CollAlgParams& params, std::shared_ptr<InsQueue>& insQueue, uint8_t commEngine) const
272 : {
273 1 : MC2Orchestrate(params, insQueue, commEngine);
274 : // 获取LinkData
275 1 : auto collService = dynamic_cast<CollServiceDeviceMode*>(comm->GetCollService());
276 1 : auto ccuLinks = collService->GetUniqueLinks(insQueue);
277 : // Socket建链
278 1 : comm->GetSocketManager().BatchCreateSockets(ccuLinks);
279 : // 对insQueue中ccuIns进行预处理(创建transport、ccuCtx、分配资源、注册等)
280 1 : collService->GetCcuInsPreprocessor()->Preprocess(insQueue, true);
281 1 : if (collService->GetCcuInsPreprocessor()->IsRollback()) { // mc2暂不能回退到aicpu
282 1 : THROW<InternalException>("[Mc2Compont][%s]ResAlloc unsuccessful.", __func__);
283 : }
284 1 : }
285 :
286 0 : void Mc2Compont::SaveAlgoInfo(uint32_t index, uint64_t templateSign, uint32_t opType, uint8_t algorithmType)
287 : {
288 0 : combinOpParam.opType[index] = opType;
289 0 : combinOpParam.algorithmType[index] = algorithmType;
290 0 : HcclAlgoInfo hcclAlgoInfo{};
291 0 : hcclAlgoInfo.opType = opType;
292 0 : hcclAlgoInfo.algorithmType = algorithmType;
293 0 : algoInfoMap_[templateSign] = hcclAlgoInfo;
294 0 : return;
295 : }
296 :
297 0 : void Mc2Compont::GenerateAlgoTemplates(Mc2Tiling* mc2TilingPtr, std::unordered_set<uint64_t>& algoTemplateRequire)
298 : {
299 0 : HCCL_INFO("GenerateAlgoTemplates start v1");
300 :
301 0 : auto tmpMemSize = comm->GetBufferSize();
302 0 : CollAlgParams params;
303 0 : params.opMode = OpMode::OPBASE;
304 0 : params.maxTmpMemSize = tmpMemSize;
305 0 : params.isMc2 = true;
306 : // 从mc2Tiling中获取需要的算法信息
307 0 : Mc2CommConfig* commConfigPtr = reinterpret_cast<Mc2CommConfig*>(
308 : reinterpret_cast<uint8_t*>(mc2TilingPtr) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(Mc2ServerCfg));
309 0 : for (uint32_t index = 0; index < mc2TilingPtr->commConfigNum; index++) {
310 0 : const auto& commConfig = *(commConfigPtr + index);
311 0 : OpParamsChecker::CheckOpDataTypeMC2(commConfig);
312 0 : uint64_t templateSign = GetTemplateSignature(commConfig);
313 0 : algoTemplateRequire.insert(templateSign);
314 : // 已经生成过的算法模板不再生成
315 0 : if (algoTemplateMap.find(templateSign) != algoTemplateMap.end()) {
316 0 : HCCL_INFO(
317 : "A algoTemplate that meets the requirement already exists, index = [%u], templateSign = [%llu]", index,
318 : templateSign);
319 0 : if (algoInfoMap_.find(templateSign) != algoInfoMap_.end()) {
320 0 : combinOpParam.opType[index] = algoInfoMap_[templateSign].opType;
321 0 : combinOpParam.algorithmType[index] = algoInfoMap_[templateSign].algorithmType;
322 0 : continue;
323 : } else {
324 0 : THROW<Hccl::InternalException>(
325 0 : StringFormat("algoInfoMap_ do not has templateSign = [%llu]", templateSign));
326 : }
327 : }
328 :
329 0 : FillCollOperator(commConfig);
330 :
331 0 : auto insQueue = make_shared<InsQueue>();
332 0 : MC2AllocCommRes(params, insQueue, commConfig.communicationEngine);
333 :
334 0 : std::string algName = comm->GetCurAlgName();
335 0 : HCCL_INFO(
336 : "Orchestrate: index = [%u], algName = [%s], templateSign = [%llu]", index, algName.c_str(), templateSign);
337 0 : if (insQueue->Iter()->GetType() != InstructionType::CCU_INS) {
338 0 : THROW<Hccl::InternalException>(
339 0 : StringFormat("InstructionType is not ccu ins, algName = [%s]", algName.c_str()));
340 : }
341 :
342 : // 获取taskParam
343 0 : const CcuInstruction& ccuInstruction = static_cast<const CcuInstruction&>(*insQueue->Iter());
344 0 : std::vector<std::vector<CcuTaskParam>> taskParams;
345 0 : ccuInstruction.Translate(taskParams);
346 0 : if (taskParams.empty()) {
347 0 : THROW<Hccl::InternalException>(
348 0 : StringFormat("CcuInstruction translate faild, index = [%u], algName = [%s]", index, algName.c_str()));
349 : }
350 0 : algoTemplateMap[templateSign] = taskParams;
351 0 : SaveAlgoInfo(index, templateSign, commConfig.opType, comm->GetAlgorithmType());
352 0 : for (const auto& task : taskParams) {
353 0 : HCCL_INFO("taskParam: dieId = [%u], instStartId = [%u]", task[0].dieId, task[0].instStartId);
354 0 : SaveMc2DfxTaskInfo(task[0], ccuInstruction.GetExecId());
355 : }
356 0 : }
357 0 : HCCL_INFO("GenerateAlgoTemplates success");
358 0 : }
359 :
360 1 : void Mc2Compont::GenerateAlgoTemplatesV2(
361 : const Mc2InitTilingInner* mc2TilingPtr, std::unordered_set<uint64_t>& algoTemplateRequire)
362 : {
363 3 : HCCL_INFO("GenerateAlgoTemplates start v2");
364 :
365 1 : auto tmpMemSize = comm->GetBufferSize();
366 1 : CollAlgParams params;
367 1 : params.opMode = OpMode::OPBASE;
368 1 : params.maxTmpMemSize = tmpMemSize;
369 1 : params.isMc2 = true;
370 1 : if (mc2TilingPtr->mc2HcommCnt > MAX_OP_NUM) {
371 0 : THROW<Hccl::InternalException>(
372 0 : StringFormat("mc2HcommCnt is lager than MAX_OP_NUM, mc2HcommCnt = [%u]", mc2TilingPtr->mc2HcommCnt));
373 : }
374 :
375 2 : for (uint32_t index = 0; index < mc2TilingPtr->mc2HcommCnt; index++) {
376 1 : const auto offset = mc2TilingPtr->offset[index];
377 1 : const auto& commConfig
378 1 : = *(reinterpret_cast<const Mc2CcTilingInner*>(reinterpret_cast<const uint8_t*>(mc2TilingPtr) + offset));
379 1 : OpParamsChecker::CheckOpDataTypeMC2V2(commConfig);
380 1 : uint64_t templateSign = GetTemplateSignatureV2(commConfig);
381 1 : algoTemplateRequire.insert(templateSign);
382 : // 已经生成过的算法模板不再生成
383 1 : if (algoTemplateMap.find(templateSign) != algoTemplateMap.end()) {
384 3 : HCCL_INFO(
385 : "A algoTemplate that meets the requirement already exists, index = [%u], templateSign = [%llu]", index,
386 : templateSign);
387 1 : if (algoInfoMap_.find(templateSign) != algoInfoMap_.end()) {
388 1 : combinOpParam.opType[index] = algoInfoMap_[templateSign].opType;
389 1 : combinOpParam.algorithmType[index] = algoInfoMap_[templateSign].algorithmType;
390 1 : continue;
391 : } else {
392 0 : THROW<Hccl::InternalException>(
393 0 : StringFormat("algoInfoMap_ do not has templateSign = [%llu]", templateSign));
394 : }
395 : }
396 :
397 0 : FillCollOperatorV2(commConfig);
398 :
399 0 : auto insQueue = make_shared<InsQueue>();
400 0 : MC2AllocCommRes(params, insQueue, commConfig.communicationEngine);
401 :
402 0 : std::string algName = comm->GetCurAlgName();
403 0 : HCCL_INFO(
404 : "Orchestrate: index = [%u], algName = [%s], templateSign = [%llu]", index, algName.c_str(), templateSign);
405 0 : if (insQueue->Iter()->GetType() != InstructionType::CCU_INS) {
406 0 : THROW<Hccl::InternalException>(
407 0 : StringFormat("InstructionType is not ccu ins, algName = [%s]", algName.c_str()));
408 : }
409 :
410 : // 获取taskParam
411 0 : const CcuInstruction& ccuInstruction = static_cast<const CcuInstruction&>(*insQueue->Iter());
412 0 : std::vector<std::vector<CcuTaskParam>> taskParams;
413 0 : ccuInstruction.Translate(taskParams);
414 0 : if (taskParams.empty()) {
415 0 : THROW<Hccl::InternalException>(
416 0 : StringFormat("CcuInstruction translate faild, index = [%u], algName = [%s]", index, algName.c_str()));
417 : }
418 0 : algoTemplateMap[templateSign] = taskParams;
419 0 : SaveAlgoInfo(index, templateSign, commConfig.opType, comm->GetAlgorithmType());
420 0 : for (const auto& task : taskParams) {
421 0 : HCCL_INFO("taskParam: dieId = [%u], instStartId = [%u]", task[0].dieId, task[0].instStartId);
422 0 : SaveMc2DfxTaskInfo(task[0], ccuInstruction.GetExecId());
423 : }
424 0 : }
425 3 : HCCL_INFO("GenerateAlgoTemplates success");
426 1 : }
427 :
428 3 : static std::map<uint8_t, std::map<uint32_t, uint32_t>> TransToMap(const std::vector<std::vector<CcuTaskParam>>& params)
429 : {
430 3 : std::map<uint8_t, std::map<uint32_t, uint32_t>> dieIdToInstrIdMap;
431 :
432 12 : for (const auto& param : params) {
433 9 : uint8_t dieId = param[0].dieId;
434 9 : uint32_t instrId = param[0].instStartId;
435 :
436 : // 检查 dieId 是否已经存在于 map 中
437 9 : if (dieIdToInstrIdMap.find(dieId) == dieIdToInstrIdMap.end()) {
438 : // 如果不存在,创建一个新的 map
439 5 : std::map<uint32_t, uint32_t> indexIdToInstrIdMap;
440 5 : indexIdToInstrIdMap[0] = instrId;
441 5 : dieIdToInstrIdMap[dieId] = indexIdToInstrIdMap;
442 5 : } else {
443 : // 如果存在,获取对应的 map
444 4 : std::map<uint32_t, uint32_t>& indexIdToInstrIdMap = dieIdToInstrIdMap[dieId];
445 : // 插入新的 IndexId 和 InstrId
446 4 : int indexId = indexIdToInstrIdMap.size();
447 4 : indexIdToInstrIdMap[indexId] = instrId;
448 : }
449 : }
450 3 : return dieIdToInstrIdMap;
451 0 : }
452 :
453 : static std::map<uint8_t, std::vector<uint32_t>>
454 2 : TransToDieIdMissionIdMap(const std::vector<std::vector<CcuTaskParam>>& params)
455 : {
456 2 : std::map<uint8_t, std::vector<uint32_t>> dieIdMissionIdMap;
457 :
458 7 : for (const auto& param : params) {
459 5 : uint8_t dieId = param[0].dieId;
460 5 : uint32_t missionId = param[0].missionId;
461 :
462 5 : if (dieIdMissionIdMap.find(dieId) == dieIdMissionIdMap.end()) {
463 3 : dieIdMissionIdMap[dieId] = std::vector<uint32_t>();
464 : }
465 5 : dieIdMissionIdMap[dieId].push_back(missionId);
466 : }
467 2 : return dieIdMissionIdMap;
468 0 : }
469 :
470 4 : bool Mc2Compont::CompareMissionMap(
471 : const std::map<uint8_t, std::map<uint32_t, uint32_t>>& mapA,
472 : const std::map<uint8_t, std::map<uint32_t, uint32_t>>& mapB) const
473 : {
474 4 : if (mapA.size() != mapB.size()) {
475 1 : return false;
476 : }
477 5 : for (auto& entry : mapA) {
478 4 : uint8_t curDieId = entry.first;
479 4 : if (mapB.find(curDieId) == mapB.end()) {
480 2 : return false;
481 : }
482 4 : const std::map<uint32_t, uint32_t>& curSubMapA = entry.second;
483 4 : const std::map<uint32_t, uint32_t>& curSubMapB = mapB.at(curDieId);
484 4 : if (curSubMapA.size() != curSubMapB.size()) {
485 2 : return false;
486 : }
487 6 : for (auto& elem : curSubMapA) {
488 4 : if (curSubMapB.find(elem.first) == curSubMapB.end()) {
489 0 : return false;
490 : }
491 : }
492 : }
493 1 : return true;
494 : }
495 :
496 5 : u32 Mc2Compont::GetCcuMc2ServerNum() { return ccuServerMap.size(); }
497 :
498 3 : void Mc2Compont::GenerateCcuServer(const std::unordered_set<uint64_t>& algoTemplateRequire)
499 : {
500 9 : HCCL_INFO("GenerateCcuServer start");
501 3 : if (algoTemplateRequire.empty()) {
502 0 : THROW<InvalidParamsException>(StringFormat("AlgoTemplate require num is zero!"));
503 : }
504 :
505 : InsExeQue::ExtInsExeEntityId execId;
506 : // 查找当前是否存在符合条件的ccuServer
507 3 : if (FindCcuServer(algoTemplateRequire, execId)) {
508 1 : curExecId = execId;
509 3 : HCCL_INFO("A CcuServer that meets the requirement already exists, execId = [%llu]", execId);
510 1 : return;
511 : }
512 :
513 : // 没有符合条件的ccuServer, 生成一个新的ccuServer
514 2 : std::map<uint64_t, std::map<uint8_t, std::map<uint32_t, uint32_t>>> signatureMap;
515 2 : std::map<uint8_t, std::map<uint32_t, uint32_t>> compareMap;
516 2 : std::map<uint8_t, std::vector<uint32_t>> dieIdMissionIdMap;
517 2 : bool initFlag = false;
518 5 : for (uint64_t templateSignature : algoTemplateRequire) {
519 3 : auto tmpMap = TransToMap(algoTemplateMap[templateSignature]);
520 3 : if (!initFlag) {
521 2 : compareMap = tmpMap;
522 2 : dieIdMissionIdMap = TransToDieIdMissionIdMap(algoTemplateMap[templateSignature]);
523 2 : initFlag = true;
524 : } else {
525 1 : if (!CompareMissionMap(compareMap, tmpMap)) {
526 0 : THROW<InvalidParamsException>(StringFormat("AlgoTemplate require is not the same!"));
527 : }
528 : }
529 : // algoTemplateRequire为unordered_set,可以保证键值唯一
530 3 : signatureMap[templateSignature] = tmpMap;
531 3 : }
532 :
533 2 : std::map<uint8_t, std::map<uint32_t, std::map<uint64_t, uint32_t>>> algoTemplate;
534 5 : for (const auto& signature : signatureMap) {
535 8 : for (const auto& dieId : signature.second) {
536 14 : for (const auto& indexId : dieId.second) {
537 9 : algoTemplate[dieId.first][indexId.first][signature.first] = indexId.second;
538 : }
539 : }
540 : }
541 :
542 : // 实例化Mc2Context
543 2 : CcuCtxGroup ctxGroup;
544 2 : uint32_t dieNum = algoTemplate.size();
545 5 : for (const auto& item : algoTemplate) {
546 3 : uint8_t dieId = item.first;
547 8 : for (const auto& mission : item.second) {
548 5 : std::unique_ptr<Mc2ContextBase> mc2Context;
549 5 : if (mission.first == 0) {
550 3 : mc2Context = std::make_unique<Mc2Context>();
551 3 : mc2Context->SetDieId(dieId);
552 3 : static_cast<Mc2Context*>(mc2Context.get())->SetDieNum(dieNum);
553 3 : static_cast<Mc2Context*>(mc2Context.get())
554 3 : ->SetCommAddr(
555 3 : static_cast<uint64_t>(comSyncBuffer->GetAddr()),
556 3 : static_cast<uint64_t>(comParamBuffer->GetAddr()));
557 : } else {
558 2 : mc2Context = std::make_unique<Mc2SlaveContext>();
559 2 : mc2Context->SetDieId(dieId);
560 : }
561 5 : mc2Context->SetMissionNumAndId(item.second.size(), mission.first);
562 5 : mc2Context->SetAlgoTemplateInfo(mission.second);
563 5 : ctxGroup.ctxs.push_back(std::move(mc2Context));
564 5 : }
565 : }
566 :
567 : // 申请资源
568 2 : HcclResult ret = CcuCtxMgr::AllocRes(comm->GetDeviceLogicId(), ctxGroup, ccuResPack);
569 2 : if (ret != HcclResult::HCCL_SUCCESS) {
570 0 : THROW<CcuApiException>("GenerateCcuServer AllocRes failed, ret[%d]", ret);
571 : }
572 :
573 : // needtodo 检查各个templateSignature对应的missionId相同
574 2 : std::map<uint8_t, uint32_t> dieIndex;
575 7 : for (auto& ctx : ctxGroup.ctxs) {
576 5 : if (dieIndex.find(ctx->GetDieId()) == dieIndex.end()) {
577 3 : dieIndex[ctx->GetDieId()] = 0;
578 : }
579 5 : ctx->SetMissionId(dieIdMissionIdMap[ctx->GetDieId()][dieIndex[ctx->GetDieId()]++]);
580 : }
581 :
582 : // 指令注册
583 2 : InsExeQue::ExtInsExeEntity entity;
584 2 : entity.ctxGroup = std::move(ctxGroup);
585 2 : ret = InsExeQue::RegisterExtendInstruction(comm->GetDeviceLogicId(), entity, execId);
586 2 : if (ret != HcclResult::HCCL_SUCCESS) {
587 0 : THROW<CcuApiException>("GenerateCcuServer RegisterExtendInstruction failed, ret[%d]", ret);
588 : }
589 2 : ccuServerMap[execId] = algoTemplateRequire;
590 2 : curExecId = execId;
591 6 : HCCL_INFO("GenerateCcuServer success, execId[%llu]", execId);
592 2 : }
593 :
594 3 : bool Mc2Compont::FindCcuServer(
595 : const std::unordered_set<uint64_t>& algoTemplateRequire, InsExeQue::ExtInsExeEntityId& execId) const
596 : {
597 : // 查找是否有符合的ccuServer存在,本次算子需求是已有sever中包含算子的子集既符合要求
598 3 : for (const auto& server : ccuServerMap) {
599 1 : bool isMatch = true;
600 2 : for (auto& templateSign : algoTemplateRequire) {
601 1 : if (server.second.find(templateSign) == server.second.end()) {
602 0 : isMatch = false;
603 0 : break;
604 : }
605 : }
606 1 : if (isMatch) {
607 1 : execId = server.first;
608 1 : return true;
609 : }
610 : }
611 2 : return false;
612 : }
613 :
614 0 : uint64_t Mc2Compont::GetTemplateSignature(const Mc2CommConfig& config) const
615 : {
616 : // 根据Mc2CommConfig生成算子模板签名
617 0 : if (config.opType > UINT8_MAX || config.reduceType > UINT8_MAX || config.dataType > UINT8_MAX
618 0 : || config.outputDataType > UINT8_MAX) {
619 0 : THROW<InvalidParamsException>(
620 0 : StringFormat("MC2 High Level API GetTemplateSignature Failed, Mc2CommConfig value is bigger than 256!"));
621 : }
622 0 : constexpr uint16_t algoTypeShift = 32;
623 0 : constexpr uint16_t outputDataTypeShift = 24;
624 0 : constexpr uint16_t reduceTypeShift = 16;
625 0 : constexpr uint16_t dataTypeShift = 8;
626 0 : constexpr uint16_t opTypeShift = 0;
627 0 : uint64_t opType = config.opType;
628 0 : uint64_t dataType = config.dataType;
629 0 : uint64_t reduceType = config.reduceType;
630 0 : uint64_t outputDataType = config.outputDataType;
631 0 : uint64_t algoType = 0; // 用于算法选择,当前暂不支持,固定为0
632 :
633 0 : uint64_t templateSignature = ((opType & 0xff) << opTypeShift) | ((dataType & 0xff) << dataTypeShift)
634 0 : | ((reduceType & 0xff) << reduceTypeShift)
635 0 : | ((outputDataType & 0xff) << outputDataTypeShift)
636 0 : | ((algoType & 0xff) << algoTypeShift);
637 0 : HCCL_INFO(
638 : "[GetTemplateSignature]: opType[%s] dataType[%s] reduceType[%s] outputDataType[%s] algoType[%u] "
639 : "templateSignature[%llu]",
640 : MC2OpType(static_cast<AicpuComType>(config.opType)).Describe().c_str(),
641 : MC2DataType(static_cast<HcclDataType>(config.dataType)).Describe().c_str(),
642 : MC2ReduceType(static_cast<HcclReduceOp>(config.reduceType)).Describe().c_str(),
643 : MC2DataType(static_cast<HcclDataType>(config.outputDataType)).Describe().c_str(), algoType, templateSignature);
644 0 : return templateSignature;
645 : }
646 :
647 2 : uint64_t Mc2Compont::GetTemplateSignatureV2(const Mc2CcTilingInner& config) const
648 : {
649 : // 根据Mc2CommConfig生成算子模板签名
650 2 : if (config.opType > UINT8_MAX || config.reduceType > UINT8_MAX) {
651 0 : THROW<InvalidParamsException>(
652 0 : StringFormat("MC2 High Level API GetTemplateSignature Failed, Mc2CommConfig value is bigger than 256!"));
653 : }
654 2 : constexpr uint16_t algoTypeShift = 32;
655 2 : constexpr uint16_t outputDataTypeShift = 24;
656 2 : constexpr uint16_t reduceTypeShift = 16;
657 2 : constexpr uint16_t dataTypeShift = 8;
658 2 : constexpr uint16_t opTypeShift = 0;
659 2 : uint64_t opType = config.opType;
660 2 : uint64_t dataType = config.srcDataType;
661 2 : uint64_t reduceType = config.reduceType;
662 2 : uint64_t outputDataType = config.dstDataType;
663 2 : uint64_t algoType = 0; // 用于算法选择,当前暂不支持,固定为0
664 :
665 2 : uint64_t templateSignature = ((opType & 0xff) << opTypeShift) | ((dataType & 0xff) << dataTypeShift)
666 2 : | ((reduceType & 0xff) << reduceTypeShift)
667 2 : | ((outputDataType & 0xff) << outputDataTypeShift)
668 2 : | ((algoType & 0xff) << algoTypeShift);
669 6 : HCCL_INFO(
670 : "[GetTemplateSignature]: opType[%s] dataType[%s] reduceType[%s] outputDataType[%s] algoType[%u] "
671 : "templateSignature[%llu]",
672 : MC2OpType(static_cast<AicpuComType>(config.opType)).Describe().c_str(),
673 : MC2DataType(static_cast<HcclDataType>(config.srcDataType)).Describe().c_str(),
674 : MC2ReduceType(static_cast<HcclReduceOp>(config.reduceType)).Describe().c_str(),
675 : MC2DataType(static_cast<HcclDataType>(config.dstDataType)).Describe().c_str(), algoType, templateSignature);
676 2 : return templateSignature;
677 : }
678 :
679 1 : void Mc2Compont::FillCollOperatorV2(const Mc2CcTilingInner& config)
680 : {
681 1 : CollOpParams opParams;
682 1 : opParams.opType = MC2OpType(static_cast<AicpuComType>(config.opType));
683 1 : opParams.reduceOp = MC2ReduceType(static_cast<HcclReduceOp>(config.reduceType));
684 1 : opParams.dataType = MC2DataType(static_cast<HcclDataType>(config.srcDataType));
685 1 : opParams.outputDataType = MC2DataType(static_cast<HcclDataType>(config.dstDataType));
686 1 : opParams.count = dataCount;
687 1 : opParams.sendBuf = reinterpret_cast<void*>(inputMem->GetAddr());
688 1 : opParams.recvBuf = reinterpret_cast<void*>(inputMem->GetAddr());
689 1 : if (opParams.opType == OpType::ALLTOALL) {
690 0 : opParams.all2AllDataDes.sendType = opParams.dataType;
691 0 : opParams.all2AllDataDes.recvType = opParams.outputDataType;
692 0 : opParams.all2AllDataDes.sendCount = dataCount;
693 0 : opParams.all2AllDataDes.recvCount = dataCount;
694 : }
695 1 : std::string opTag = comm->GetId();
696 :
697 1 : if (opParams.opType == OpType::ALLTOALLV) {
698 1 : opParams.all2AllVDataDes.sendType = opParams.dataType;
699 1 : opParams.all2AllVDataDes.recvType = opParams.outputDataType;
700 1 : dataCounts.resize(comm->GetRankSize());
701 1 : displs.resize(comm->GetRankSize());
702 1 : u64 countSum = 0;
703 2 : for (u32 i = 0; i < comm->GetRankSize(); i++) {
704 1 : dataCounts.at(i) = 1;
705 1 : displs.at(i) = countSum++;
706 : }
707 1 : opParams.all2AllVDataDes.sendCounts = reinterpret_cast<void*>(&dataCounts[0]);
708 1 : opParams.all2AllVDataDes.recvCounts = reinterpret_cast<void*>(&dataCounts[0]);
709 1 : opParams.all2AllVDataDes.sdispls = reinterpret_cast<void*>(&displs[0]);
710 1 : opParams.all2AllVDataDes.rdispls = reinterpret_cast<void*>(&displs[0]);
711 : }
712 :
713 1 : comm->CovertToCurrentCollOperator(opTag, opParams, OpMode::OPBASE);
714 1 : }
715 :
716 1 : void Mc2Compont::FillCollOperator(const Mc2CommConfig& config)
717 : {
718 1 : CollOpParams opParams;
719 1 : opParams.opType = MC2OpType(static_cast<AicpuComType>(config.opType));
720 1 : opParams.reduceOp = MC2ReduceType(static_cast<HcclReduceOp>(config.reduceType));
721 1 : opParams.dataType = MC2DataType(static_cast<HcclDataType>(config.dataType));
722 1 : opParams.outputDataType = MC2DataType(static_cast<HcclDataType>(config.outputDataType));
723 1 : opParams.count = dataCount;
724 1 : opParams.sendBuf = reinterpret_cast<void*>(inputMem->GetAddr());
725 1 : opParams.recvBuf = reinterpret_cast<void*>(inputMem->GetAddr());
726 1 : if (opParams.opType == OpType::ALLTOALL) {
727 0 : opParams.all2AllDataDes.sendType = opParams.dataType;
728 0 : opParams.all2AllDataDes.recvType = opParams.outputDataType;
729 0 : opParams.all2AllDataDes.sendCount = dataCount;
730 0 : opParams.all2AllDataDes.recvCount = dataCount;
731 : }
732 1 : std::string opTag = comm->GetId();
733 :
734 1 : if (opParams.opType == OpType::ALLTOALLV) {
735 1 : opParams.all2AllVDataDes.sendType = opParams.dataType;
736 1 : opParams.all2AllVDataDes.recvType = opParams.outputDataType;
737 1 : dataCounts.resize(comm->GetRankSize());
738 1 : displs.resize(comm->GetRankSize());
739 1 : u64 countSum = 0;
740 2 : for (u32 i = 0; i < comm->GetRankSize(); i++) {
741 1 : dataCounts.at(i) = 1;
742 1 : displs.at(i) = countSum++;
743 : }
744 1 : opParams.all2AllVDataDes.sendCounts = reinterpret_cast<void*>(&dataCounts[0]);
745 1 : opParams.all2AllVDataDes.recvCounts = reinterpret_cast<void*>(&dataCounts[0]);
746 1 : opParams.all2AllVDataDes.sdispls = reinterpret_cast<void*>(&displs[0]);
747 1 : opParams.all2AllVDataDes.rdispls = reinterpret_cast<void*>(&displs[0]);
748 : }
749 :
750 1 : comm->CovertToCurrentCollOperator(opTag, opParams, OpMode::OPBASE);
751 1 : }
752 :
753 2 : void Mc2Compont::SaveMc2DfxTaskInfo(const CcuTaskParam& ccuTaskParam, uint64_t execId) const
754 : {
755 2 : shared_ptr<DfxOpInfo> dfxOpInfo = std::make_shared<DfxOpInfo>();
756 2 : dfxOpInfo->comm_ = comm;
757 :
758 2 : TaskParam taskParam{};
759 2 : taskParam.taskType = TaskParamType::TASK_CCU;
760 2 : taskParam.taskPara.Ccu.dieId = ccuTaskParam.dieId;
761 2 : taskParam.taskPara.Ccu.missionId = ccuTaskParam.missionId;
762 2 : taskParam.taskPara.Ccu.instrId = ccuTaskParam.instStartId;
763 2 : taskParam.taskPara.Ccu.executeId = execId;
764 :
765 2 : shared_ptr<TaskInfo> taskInfo = std::make_shared<TaskInfo>(0, 0, 0, taskParam, dfxOpInfo);
766 :
767 2 : MC2GlobalMirrorTasks::GetInstance().AddTaskInfo(comm->GetDeviceLogicId(), taskInfo);
768 2 : }
769 :
770 4 : std::vector<CcuTaskParam> Mc2Compont::GetAlgoCcuTaskInfo(InsExeQue::ExtInsExeEntityId execId) const
771 : {
772 4 : std::vector<CcuTaskParam> ccuTaskParam{};
773 4 : auto serverItor = ccuServerMap.find(execId);
774 4 : if (serverItor == ccuServerMap.end()) {
775 6 : HCCL_INFO("[Mc2Compont]Failed to find ccuServer by executeId[%llu]", execId);
776 2 : return ccuTaskParam;
777 : }
778 5 : for (uint64_t algoSign : serverItor->second) {
779 3 : auto algoTemplateItor = algoTemplateMap.find(algoSign);
780 3 : if (algoTemplateItor == algoTemplateMap.end()) {
781 3 : HCCL_INFO("[Mc2Compont]Failed to find ccuTaskParam by algoSign[%llu]", algoSign);
782 1 : continue;
783 1 : }
784 6 : for (const auto& taskParam : algoTemplateItor->second) {
785 4 : ccuTaskParam.push_back(taskParam[0]);
786 : }
787 : }
788 2 : return ccuTaskParam;
789 0 : }
790 : } // namespace Hccl
|