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 "base_selector.h"
12 :
13 : #include <numeric>
14 :
15 : namespace Hccl {
16 0 : BaseSelector& BaseSelector::SetVirtualTopo(RankGraph* rankGraph)
17 : {
18 0 : rankGraph_ = rankGraph;
19 0 : return *this;
20 : }
21 :
22 0 : BaseSelector& BaseSelector::SetDevType(DevType devType)
23 : {
24 0 : devType_ = devType;
25 0 : return *this;
26 : }
27 :
28 0 : BaseSelector& BaseSelector::SetMyRank(RankId myRank)
29 : {
30 0 : myRank_ = myRank;
31 0 : return *this;
32 : }
33 :
34 0 : BaseSelector& BaseSelector::SetRankSize(u32 rankSize)
35 : {
36 0 : rankSize_ = rankSize;
37 0 : return *this;
38 : }
39 :
40 0 : BaseSelector& BaseSelector::SetSeverId(std::string severId)
41 : {
42 0 : severId_ = severId;
43 0 : return *this;
44 : }
45 :
46 0 : BaseSelector& BaseSelector::SetDeviceNumPerSever(u32 deviceNumPerSever)
47 : {
48 0 : deviceNumPerSever_ = deviceNumPerSever;
49 0 : return *this;
50 : }
51 :
52 0 : BaseSelector& BaseSelector::SetServerNum(u32 serverNum)
53 : {
54 0 : serverNum_ = serverNum;
55 0 : return *this;
56 : }
57 :
58 0 : BaseSelector& BaseSelector::SetIsMc2(bool isMc2)
59 : {
60 0 : isMc2_ = isMc2;
61 0 : return *this;
62 : }
63 :
64 0 : BaseSelector& BaseSelector::SetOpConfig(OpExecuteConfig opConfig)
65 : {
66 0 : opConfig_ = opConfig;
67 0 : return *this;
68 : }
69 :
70 0 : RankGraph* BaseSelector::GetVirtualTopo() { return rankGraph_; }
71 :
72 0 : DevType BaseSelector::GetDevType() { return devType_; }
73 :
74 0 : RankId BaseSelector::GetMyRank() const { return myRank_; }
75 :
76 0 : u32 BaseSelector::GetRankSize() const { return rankSize_; }
77 :
78 0 : std::string BaseSelector::GetSeverId() { return severId_; }
79 :
80 0 : u32 BaseSelector::GetDeviceNumPerSever() const { return deviceNumPerSever_; }
81 :
82 0 : u32 BaseSelector::GetServerNum() const { return serverNum_; }
83 :
84 0 : u32 BaseSelector::Gcd(u32 a, u32 b) const
85 : {
86 0 : while (b != 0) {
87 0 : a %= b;
88 0 : std::swap(a, b);
89 : }
90 0 : return a;
91 : }
92 :
93 0 : u32 BaseSelector::GcdOfArray(const std::vector<u32>& numbers) const
94 : {
95 0 : if (numbers.empty()) {
96 0 : return 0;
97 : }
98 0 : u32 result = numbers[0];
99 0 : for (size_t i = 1; i < numbers.size(); ++i) {
100 0 : result = Gcd(result, numbers[i]); // C++17 及以上推荐使用 std::gcd
101 : }
102 0 : return result;
103 : }
104 :
105 0 : u32 BaseSelector::GetLevel0Gcd() const
106 : {
107 0 : std::vector<u32> instSizeList = {};
108 0 : u32 listSize = 0;
109 0 : rankGraph_->GetNetInstanceList(0, instSizeList, listSize);
110 0 : return GcdOfArray(instSizeList);
111 0 : }
112 :
113 0 : bool BaseSelector::IsAsymmetricTopoShapeLevel1Nhr(
114 : const std::vector<std::vector<u32>>& localIdPerBoard, u32 gcdRankSizeLevel0) const
115 : {
116 : // Level0的gcd为1分支
117 0 : if (gcdRankSizeLevel0 == 1) {
118 0 : return true;
119 : }
120 : // Pod形状不规则分支
121 0 : if (localIdPerBoard.size() > 1) {
122 0 : if (!IsTopoShapeLevel0Regular(localIdPerBoard)) {
123 0 : return true;
124 : }
125 : }
126 0 : return false;
127 : }
128 :
129 0 : bool BaseSelector::IsTopoShapeLevel0Regular(const std::vector<std::vector<u32>>& localIdPerBoard) const
130 : {
131 0 : u32 rankSizeOfFirstBoard = localIdPerBoard[0].size();
132 0 : u32 rankSize = 8;
133 0 : for (u32 boardIdx = 1; boardIdx < localIdPerBoard.size(); ++boardIdx) {
134 : // 条件1:与第一行rank数是否一致
135 0 : if (localIdPerBoard[boardIdx].size() != rankSizeOfFirstBoard) {
136 0 : return false;
137 : }
138 : // 条件2:同一slot内rank数差异是否能被8整除
139 0 : for (u32 slotIdx = 0; slotIdx < rankSizeOfFirstBoard; ++slotIdx) {
140 0 : if ((localIdPerBoard[boardIdx][slotIdx] - localIdPerBoard[0][slotIdx]) % rankSize != 0) {
141 0 : return false;
142 : }
143 : }
144 : }
145 0 : return true;
146 : }
147 :
148 0 : HcclResult BaseSelector::ExtractNetLayerDetails(TopoInfo& topoInfo) const
149 : {
150 0 : CHK_PRT_RET(
151 : rankGraph_ == nullptr, HCCL_ERROR("[BaseSelector][ExtractNetLayerDetails] rankGraph_ is null"), HCCL_E_PTR);
152 :
153 0 : auto& topoLevelNum = topoInfo.levelNum;
154 0 : auto& netLayerNum = topoInfo.netLayerDetails.netLayerNum;
155 0 : auto& netLayers = topoInfo.netLayerDetails.netLayers;
156 0 : auto& netInstNumOfLayer = topoInfo.netLayerDetails.netInstNumOfLayer;
157 0 : auto& instSizeListOfLayer = topoInfo.netLayerDetails.instSizeListOfLayer;
158 0 : auto& localNetInsSizeOfLayer = topoInfo.netLayerDetails.localNetInsSizeOfLayer;
159 :
160 0 : netLayers = rankGraph_->GetLevels(myRank_); // 有那几层网络 如:[0,1]
161 0 : netLayerNum = rankGraph_->GetLevelNum();
162 0 : netInstNumOfLayer.resize(netLayerNum); // 每层网络中有几个网络实例
163 0 : instSizeListOfLayer.resize(netLayerNum); // 每层网络中的各个网络实例的大小
164 0 : localNetInsSizeOfLayer.resize(netLayerNum);
165 :
166 : HcclResult ret;
167 : // 获取并校验每一层的网路实例大小
168 0 : for (auto layerIdx : netLayers) {
169 0 : std::vector<u32>& currLayerInstSizeList = instSizeListOfLayer[layerIdx];
170 0 : u32& currLayerNetInstNum = netInstNumOfLayer[layerIdx];
171 0 : ret = rankGraph_->GetNetInstanceList(layerIdx, currLayerInstSizeList, currLayerNetInstNum);
172 0 : CHK_PRT_RET(
173 : ret != HCCL_SUCCESS,
174 : HCCL_ERROR("[BaseSelector][ExtractNetLayerDetails] GetNetInstanceList failed, netLayer[%u]", layerIdx),
175 : ret);
176 0 : for (u32 i = 0; i < currLayerInstSizeList.size(); i++) {
177 0 : HCCL_DEBUG(
178 : "[BaseSelector][ExtractNetLayerDetails] netInstanceSize[%u] is [%u]", i, currLayerInstSizeList[i]);
179 : }
180 0 : u32 currLayerRankSize = std::accumulate(currLayerInstSizeList.begin(), currLayerInstSizeList.end(), 0);
181 0 : HCCL_INFO("[BaseSelector][ExtractNetLayerDetails] Net layer[%u] instNum[%u]", layerIdx, currLayerNetInstNum);
182 0 : CHK_PRT_RET(
183 : currLayerRankSize != rankSize_,
184 : HCCL_ERROR(
185 : "[BaseSelector][ExtractNetLayerDetails] NetLayer[%u], totalRankSize[%u] is not equal to comm "
186 : "rankSize[%u]",
187 : layerIdx, currLayerRankSize, rankSize_),
188 : HCCL_E_PARA);
189 0 : localNetInsSizeOfLayer[layerIdx] = rankGraph_->GetLocalInstSize(layerIdx);
190 : }
191 :
192 0 : topoLevelNum = 0;
193 : // 获取最小的能覆盖所有卡的 layer
194 0 : for (auto layerIdx : netLayers) {
195 0 : if (netInstNumOfLayer[layerIdx] == 1) {
196 : // 当本层只有一个网络实例时, 认为这个就是当前的 topoLevelNum
197 0 : topoLevelNum = layerIdx + 1;
198 0 : break;
199 : }
200 : }
201 :
202 0 : HCCL_INFO(
203 : "[BaseSelector][ExtractNetLayerDetails] topoLevelNum[%u], netLayerNum[%u], netLayers.size[%u]", topoLevelNum,
204 : netLayerNum, netLayers.size());
205 :
206 0 : CHK_PRT_RET(
207 : topoLevelNum == 0,
208 : HCCL_ERROR(
209 : "[BaseSelector][ExtractNetLayerDetails] topoLevelNum[%u] is invalid, netLayerNum[%u]", topoLevelNum,
210 : netLayerNum),
211 : HCCL_E_INTERNAL);
212 0 : return HCCL_SUCCESS;
213 : }
214 :
215 0 : HcclResult BaseSelector::ExtractTopoDetails(TopoInfo& topoInfo) const
216 : {
217 : HcclResult ret;
218 0 : CHK_PRT_RET(rankGraph_ == nullptr, HCCL_ERROR("[BaseSelector][ExtractTopoDetails] rankGraph_ is null"), HCCL_E_PTR);
219 0 : u32 netLayerNum = topoInfo.netLayerDetails.netLayerNum;
220 :
221 : // 初始化每一层的 TopoInstDetails
222 0 : topoInfo.topoInstDetailsOfLayer.resize(netLayerNum);
223 0 : for (u32 netLayerIdx = 0; netLayerIdx < netLayerNum; netLayerIdx++) {
224 0 : auto& currentNetLayerTopoTopoDetail = topoInfo.topoInstDetailsOfLayer[netLayerIdx];
225 0 : auto& currentLayerTopoSize = currentNetLayerTopoTopoDetail.sizeOfTopo;
226 0 : auto& currentLayerTopoType = currentNetLayerTopoTopoDetail.typeOfTopo;
227 0 : auto& currentLayerTopoRanks = currentNetLayerTopoTopoDetail.ranksInTopo;
228 0 : auto& currentLayerTopo2SizeMap = currentNetLayerTopoTopoDetail.rankNumForTopoType;
229 0 : auto& topoInstNum = currentNetLayerTopoTopoDetail.topoInstNum;
230 :
231 0 : std::vector<u32> topoInsts;
232 0 : rankGraph_->GetTopoInstsByLayer(netLayerIdx, topoInsts, topoInstNum);
233 0 : HCCL_INFO("[BaseSelector][ExtractTopoDetails] netLayerIdx[%u], topoInstNum[%u]", netLayerIdx, topoInstNum);
234 : // 初始化当前层的拓扑信息
235 0 : currentLayerTopoSize.resize(topoInstNum);
236 0 : currentLayerTopoType.resize(topoInstNum);
237 0 : currentLayerTopoRanks.resize(topoInstNum);
238 0 : currentLayerTopo2SizeMap.clear();
239 :
240 : // 填充当前层的拓扑信息
241 0 : for (u32 topoInstIdx = 0; topoInstIdx < topoInstNum; topoInstIdx++) {
242 0 : u32& topoInstId = topoInsts[topoInstIdx];
243 0 : u32& topoSize = currentLayerTopoSize[topoInstIdx];
244 0 : TopoType& topoType = currentLayerTopoType[topoInstIdx];
245 0 : std::vector<u32>& ranks = currentLayerTopoRanks[topoInstIdx];
246 :
247 : // 获取拓扑实例的类型
248 0 : ret = rankGraph_->GetTopoType(netLayerIdx, topoInstId, topoType);
249 0 : CHK_PRT_RET(
250 : ret != HCCL_SUCCESS,
251 : HCCL_ERROR(
252 : "[BaseSelector][ExtractTopoDetails] GetTopoType failed, netLayerIdx[%u], topoInstId[%u]",
253 : netLayerIdx, topoInstId),
254 : ret);
255 :
256 : // 获取拓扑实例中包含的rank
257 0 : ret = rankGraph_->GetRanksByTopoInst(netLayerIdx, topoInstId, ranks, topoSize);
258 0 : CHK_PRT_RET(
259 : ret != HCCL_SUCCESS,
260 : HCCL_ERROR(
261 : "[BaseSelector][ExtractTopoDetails] GetRanksByTopoInst failed, netLayerIdx[%u], topoInstId[%u]",
262 : netLayerIdx, topoInstId),
263 : ret);
264 :
265 : // 将topoInstId按照topoType进行归类
266 0 : currentLayerTopo2SizeMap[topoType].push_back(topoSize);
267 :
268 0 : HCCL_INFO(
269 : "[BaseSelector][ExtractTopoDetails] netLayerIdx[%u], topoInstIdx[%u] type is[%s], topoInstId is[%u], "
270 : "topoSize is[%u]",
271 : netLayerIdx, topoInstIdx, topoType.Describe().c_str(), topoInstId, topoSize);
272 : }
273 0 : }
274 0 : return HCCL_SUCCESS;
275 : }
276 :
277 0 : HcclResult BaseSelector::CalcLevel0TopoShape(TopoInfo& topoInfo) const
278 : {
279 0 : u32 netLayer = 0;
280 0 : u32 topoInstNum2 = 2;
281 0 : u32 topoInstNum3 = 3;
282 0 : CHK_PRT_RET(
283 : topoInfo.topoInstDetailsOfLayer.size() <= netLayer,
284 : HCCL_ERROR(
285 : "[BaseSelector][CalcLevel0TopoShape] topoInstNumOfLayer size[%zu] <= netLayer[%u]",
286 : topoInfo.topoInstDetailsOfLayer.size(), netLayer),
287 : HCCL_E_INTERNAL);
288 0 : TopoInstDetails& level0TopoInstDetails = topoInfo.topoInstDetailsOfLayer[netLayer];
289 0 : CHK_PRT_RET(
290 : topoInfo.netLayerDetails.localNetInsSizeOfLayer.size() <= netLayer,
291 : HCCL_ERROR(
292 : "[BaseSelector][CalcLevel0TopoShape] localNetInsSizeOfLayer size[%zu] <= netLayer[%u]",
293 : topoInfo.netLayerDetails.localNetInsSizeOfLayer.size(), netLayer),
294 : HCCL_E_INTERNAL);
295 0 : u32 level0LocalRankSize = topoInfo.netLayerDetails.localNetInsSizeOfLayer[netLayer];
296 :
297 0 : auto& topoInstNum = level0TopoInstDetails.topoInstNum;
298 0 : auto& rankNumForTopoType = level0TopoInstDetails.rankNumForTopoType;
299 0 : HCCL_INFO("[%s]topoInstNum[%u]", __func__, topoInstNum);
300 0 : for (const auto& iter : rankNumForTopoType) {
301 0 : HCCL_INFO("[%s]topoType[%d] size[%lu]", __func__, iter.first, iter.second.size());
302 : }
303 :
304 0 : if (topoInstNum == 1 && rankNumForTopoType[TopoType::MESH_1D].size() == 1) {
305 : // MESH_1D 拓扑校验
306 0 : CHK_PRT_RET(
307 : rankNumForTopoType[TopoType::MESH_1D][0] != level0LocalRankSize,
308 : HCCL_ERROR(
309 : "[BaseSelector][CalcLevel0TopoShape] MESH_1D rankSize[%u] is not equal to level0LocalRankSize[%u]",
310 : rankNumForTopoType[TopoType::MESH_1D][0], level0LocalRankSize),
311 : HCCL_E_INTERNAL);
312 0 : topoInfo.level0Shape = Level0Shape::MESH_1D;
313 0 : return HCCL_SUCCESS;
314 0 : } else if (topoInstNum == 1 && rankNumForTopoType[TopoType::CLOS].size() == 1) {
315 : // CLOS 拓扑校验
316 0 : CHK_PRT_RET(
317 : rankNumForTopoType[TopoType::CLOS][0] != level0LocalRankSize,
318 : HCCL_ERROR(
319 : "[BaseSelector][CalcLevel0TopoShape] CLOS rankSize[%u] is not equal to level0LocalRankSize[%u]",
320 : rankNumForTopoType[TopoType::CLOS][0], level0LocalRankSize),
321 : HCCL_E_INTERNAL);
322 0 : topoInfo.level0Shape = Level0Shape::CLOS;
323 0 : if (IsLevel0PcieMix()) {
324 0 : topoInfo.level0PcieMix = true;
325 : }
326 0 : return HCCL_SUCCESS;
327 0 : } else if (
328 0 : topoInstNum == topoInstNum2 && rankNumForTopoType[TopoType::CLOS].size() == 1
329 0 : && rankNumForTopoType[TopoType::MESH_1D].size() == 1) {
330 : // MESH_1D_CLOS 拓扑校验
331 0 : CHK_PRT_RET(
332 : rankNumForTopoType[TopoType::CLOS][0] != level0LocalRankSize,
333 : HCCL_ERROR(
334 : "[BaseSelector][CalcLevel0TopoShape] CLOS rankSize[%u] is not equal to level0LocalRankSize[%u]",
335 : rankNumForTopoType[TopoType::CLOS][0], level0LocalRankSize),
336 : HCCL_E_INTERNAL);
337 0 : topoInfo.level0Shape = Level0Shape::MESH_1D_CLOS;
338 :
339 0 : if (IsLevel0PcieMix()) {
340 0 : topoInfo.level0PcieMix = true;
341 : }
342 0 : if (rankNumForTopoType[TopoType::CLOS].at(0) > BIG_CLOS_RANGE) {
343 0 : topoInfo.level0BigClosRange = true;
344 : }
345 0 : return HCCL_SUCCESS;
346 0 : } else if (
347 0 : topoInstNum == topoInstNum3 && rankNumForTopoType[TopoType::MESH_1D].size() == topoInstNum2
348 0 : && rankNumForTopoType[TopoType::CLOS].size() == 1) {
349 : // MESH_2D 拓扑校验
350 0 : CHK_PRT_RET(
351 : rankNumForTopoType[TopoType::MESH_1D][0] * rankNumForTopoType[TopoType::MESH_1D][1] != level0LocalRankSize,
352 : HCCL_ERROR(
353 : "[BaseSelector][CalcLevel0TopoShape] mesh rankSize[%u] * [%u] is not equal to level0LocalRankSize[%u]",
354 : rankNumForTopoType[TopoType::MESH_1D][0], rankNumForTopoType[TopoType::MESH_1D][1],
355 : level0LocalRankSize),
356 : HCCL_E_INTERNAL);
357 0 : topoInfo.level0Shape = Level0Shape::MESH_2D;
358 0 : return HCCL_SUCCESS;
359 : }
360 0 : HCCL_ERROR("Unknown topo for level 0, topoInstNum[%u]", topoInstNum);
361 0 : return HCCL_E_INTERNAL;
362 : }
363 :
364 0 : void BaseSelector::CalcTopoShape(TopoInfo& topoInfo) const
365 : {
366 0 : CHK_PRT_THROW(
367 : ExtractNetLayerDetails(topoInfo) != HCCL_SUCCESS,
368 : HCCL_ERROR("[BaseSelector][CalcTopoShape] ExtractNetLayerDetails Failed"), InvalidParamsException,
369 : "ExtractNetLayerDetails Failed");
370 0 : HCCL_INFO("[BaseSelector][CalcTopoShape] topoInfo.levelNum is [%u]", topoInfo.levelNum);
371 :
372 0 : CHK_PRT_THROW(
373 : ExtractTopoDetails(topoInfo) != HCCL_SUCCESS,
374 : HCCL_ERROR("[BaseSelector][CalcTopoShape] ExtractTopoDetails Failed"), InvalidParamsException,
375 : "ExtractTopoDetails Failed");
376 0 : HCCL_INFO("[BaseSelector][ExtractTopoDetails] topoInstDetails size[%zu]", topoInfo.topoInstDetailsOfLayer.size());
377 :
378 0 : CHK_PRT_THROW(
379 : CalcLevel0TopoShape(topoInfo), HCCL_ERROR("[BaseSelector][CalcTopoShape] CalcLevel0TopoShape Failed"),
380 : InvalidParamsException, "CalcLevel0TopoShape Failed");
381 0 : HCCL_INFO(
382 : "[BaseSelector][CalcTopoShape] topoInfo.level0Shape is [%d], level0PcieMix is [%d], level0BigClosRange is [%d]",
383 : topoInfo.level0Shape, topoInfo.level0PcieMix, topoInfo.level0BigClosRange);
384 0 : }
385 :
386 0 : bool BaseSelector::IsLayerAllConnetedWithTopo(
387 : const TopoInfo& topoInfo, const u32 netLayer, const TopoType topoType) const
388 : {
389 0 : CHK_PRT_THROW(
390 : rankGraph_ == nullptr, HCCL_ERROR("[BaseSelector][IsLayerAllConnetedWithTopo] rankGraph is nullptr"),
391 : NullPtrException, "[IsLayerAllConnetedWithTopo] rankGraph is nullptr");
392 :
393 0 : CHK_PRT_RET(
394 : topoInfo.netLayerDetails.localNetInsSizeOfLayer.size() <= netLayer,
395 : HCCL_WARNING(
396 : "[BaseSelector][IsLayerAllConnetedWithTopo] localNetInsSizeOfLayer size[%zu] <= netLayer[%u]",
397 : topoInfo.netLayerDetails.localNetInsSizeOfLayer.size(), netLayer),
398 : false);
399 0 : u32 localRankSize = topoInfo.netLayerDetails.localNetInsSizeOfLayer[netLayer];
400 :
401 0 : CHK_PRT_RET(
402 : topoInfo.topoInstDetailsOfLayer.size() <= netLayer,
403 : HCCL_WARNING(
404 : "[BaseSelector][IsLayerAllConnetedWithTopo] topoInstDetailsOfLayer size[%zu] <= netLayer[%u]",
405 : topoInfo.topoInstDetailsOfLayer.size(), netLayer),
406 : false);
407 :
408 0 : auto rankNumForTopoTypeItr = topoInfo.topoInstDetailsOfLayer[netLayer].rankNumForTopoType.find(topoType);
409 0 : if (rankNumForTopoTypeItr == topoInfo.topoInstDetailsOfLayer[netLayer].rankNumForTopoType.end()) {
410 0 : return false;
411 : }
412 :
413 0 : for (auto topoRankNum : rankNumForTopoTypeItr->second) {
414 0 : if (topoRankNum == localRankSize) {
415 0 : return true;
416 : }
417 : }
418 0 : return false;
419 : }
420 :
421 0 : bool BaseSelector::IsInputOutputOverlap(
422 : const std::shared_ptr<Buffer>& inputMem, const std::shared_ptr<Buffer>& outputMem) const
423 : {
424 0 : CHK_PRT_RET(
425 : inputMem == nullptr || outputMem == nullptr,
426 : HCCL_INFO("[Algo][BaseSelector][IsInputOutputOverlap] The input or output buffer is null. Not overlap."),
427 : false);
428 :
429 0 : u64 inputStart = inputMem->GetAddr();
430 0 : u64 outputStart = outputMem->GetAddr();
431 :
432 0 : CHK_PRT_RET(
433 : inputStart == 0 || outputStart == 0,
434 : HCCL_INFO("[Algo][BaseSelector][IsInputOutputOverlap] The input or output buffer addr is null. Not overlap."),
435 : false);
436 :
437 0 : u64 inputDataSize = inputMem->GetSize();
438 0 : u64 outputDataSize = outputMem->GetSize();
439 :
440 0 : CHK_PRT_RET(
441 : inputDataSize == 0 || outputDataSize == 0,
442 : // 不存在overlap情况
443 : HCCL_INFO("[Algo][BaseSelector][IsInputOutputOverlap] The input or output buffer size is 0. Not overlap."),
444 : false);
445 :
446 0 : u64 inputEnd = inputStart + inputDataSize - 1;
447 0 : u64 outputEnd = outputStart + outputDataSize - 1;
448 :
449 0 : HCCL_DEBUG(
450 : "[Algo][BaseSelector][IsInputOutputOverlap] inputStart[%llu], inputEnd[%llu], outputStart[%llu], "
451 : "outputEnd[%llu].",
452 : inputStart, inputEnd, outputStart, outputEnd);
453 :
454 0 : CHK_PRT_RET(
455 : inputStart <= outputEnd && outputStart <= inputEnd,
456 : HCCL_INFO(
457 : "[Algo][BaseSelector][IsInputOutputOverlap] inputStart[%llu], inputEnd[%llu], outputStart[%llu], "
458 : "outputEnd[%llu]. Overlap detected.",
459 : inputStart, inputEnd, outputStart, outputEnd),
460 : true);
461 :
462 0 : HCCL_DEBUG("[Algo][BaseSelector][IsInputOutputOverlap]No overlap between input and output memory.");
463 0 : return false;
464 : }
465 :
466 0 : bool BaseSelector::Is2DieFullMesh() const
467 : {
468 0 : u32 netLayer = 0; // 0 级拓扑
469 0 : const NetInstance* netInstance = rankGraph_->GetNetInstanceByRankId(netLayer, myRank_);
470 0 : std::set<RankId> rankSet = netInstance->GetRankIds();
471 0 : if (rankSet.size() <= 2) { // 小于2张卡的话,肯定不是2die全互连
472 0 : return false;
473 : }
474 : // 遍历所有对端,校验是否和所有卡有全连链路,并判断链路中本端端口所所对应的 CCU die 是否一致;
475 0 : u32 dieNum = 2; // 一共2个die
476 0 : std::vector<u32> dieLinkCounter(dieNum, 0);
477 0 : for (RankId rankId : rankSet) {
478 0 : if (rankId == myRank_) {
479 0 : continue;
480 : }
481 0 : std::vector<NetInstance::Path> paths = rankGraph_->GetPaths(netLayer, myRank_, rankId);
482 0 : CHK_PRT_RET(
483 : paths.size() == 0 || paths[0].links.size() == 0,
484 : HCCL_INFO(
485 : "[BaseSelector][Is2DieFullMesh], Can not find path from Local[%d] to Rmt[%d], in netLayer %u. "
486 : "Topo is not mesh",
487 : myRank_, rankId, netLayer),
488 : false);
489 0 : NetInstance::Link& link = paths[0].links[0]; // 只取第一条路径的第一条link
490 0 : std::shared_ptr<NetInstance::ConnInterface> connInterface = link.GetSourceIface();
491 0 : u32 dieID = connInterface->GetLocalDieId();
492 0 : CHK_PRT_RET(
493 : dieID >= dieNum,
494 : HCCL_WARNING(
495 : "[BaseSelector][Is2DieFullMesh], Link from Local[%d] to Rmt[%d] die id[%u] is out of range[%u].",
496 : myRank_, rankId, dieID, dieNum),
497 : false);
498 0 : dieLinkCounter[dieID]++;
499 0 : HCCL_INFO(
500 : "[BaseSelector][Is2DieFullMesh], Link from Local[%d] to Rmt[%d] use die[%u], current counter[%u]", myRank_,
501 : rankId, dieID, dieLinkCounter[dieID]);
502 0 : }
503 0 : for (u32 i = 0; i < dieNum; i++) {
504 0 : if (dieLinkCounter[i] == 0) {
505 0 : return false;
506 : }
507 : }
508 0 : return true;
509 0 : }
510 :
511 0 : bool BaseSelector::IsLevel0PcieMix() const
512 : {
513 0 : u32 netLayer = 0; // 0 级拓扑
514 0 : const NetInstance* netInstance = rankGraph_->GetNetInstanceByRankId(netLayer, myRank_);
515 0 : std::set<RankId> rankSet = netInstance->GetRankIds();
516 0 : for (RankId rankId : rankSet) {
517 0 : if (rankId == myRank_) {
518 0 : continue;
519 : }
520 0 : std::vector<NetInstance::Path> paths = rankGraph_->GetPaths(netLayer, myRank_, rankId);
521 0 : CHK_PRT_RET(
522 : paths.size() == 0 || paths[0].links.size() == 0,
523 : HCCL_INFO(
524 : "[BaseSelector][IsLevel0PcieMix], Can not find path from Local[%d] to Rmt[%d], in netLayer %u. "
525 : "Topo is not mesh",
526 : myRank_, rankId, netLayer),
527 : false);
528 0 : NetInstance::Link& link = paths[0].links[0]; // 只取第一条路径的第一条link
529 0 : std::shared_ptr<NetInstance::ConnInterface> connInterface = link.GetSourceIface();
530 0 : std::set<LinkProtocol> linkProtocolsSet = connInterface->GetLinkProtocols();
531 : // 判断协议类型包含PCIE
532 0 : if (linkProtocolsSet.find(LinkProtocol::PCIE) != linkProtocolsSet.end()) {
533 0 : HCCL_INFO("IsLevel0PcieMix[true]");
534 0 : return true;
535 : }
536 0 : }
537 0 : HCCL_INFO("IsLevel0PcieMix[false]");
538 0 : return false;
539 0 : }
540 : } // namespace Hccl
|