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 "net_instance.h"
12 : #include "rank_gph.h"
13 : #include "topo_match_base.h"
14 :
15 : namespace Hccl {
16 2 : TopoMatchBase::TopoMatchBase(const RankId vRank, const u32 rankSize, const RankGraph* rankGraph, const DevType devType)
17 2 : : myRank_(vRank),
18 2 : rankSize_(rankSize),
19 2 : rankGraph_(rankGraph),
20 2 : devType_(devType)
21 2 : {}
22 :
23 2 : TopoMatchBase::~TopoMatchBase() {}
24 :
25 0 : HcclResult TopoMatchBase::MatchTopo(
26 : std::vector<std::vector<RankId>>& vTopo, std::vector<RankId>& virtRanks, std::map<RankId, u32>& virtRankMap)
27 : {
28 : (void)vTopo;
29 : (void)virtRanks;
30 : (void)virtRankMap;
31 0 : HCCL_ERROR("[CollAlgFactory] Rank [%d], use proper multi-level interface to match topo.", myRank_);
32 0 : return HcclResult::HCCL_E_INTERNAL;
33 : }
34 :
35 0 : HcclResult TopoMatchBase::MatchTopo(
36 : std::vector<std::vector<std::vector<RankId>>>& vTopo, std::vector<std::vector<RankId>>& virtRanks,
37 : std::vector<std::map<RankId, u32>>& virtRankMap)
38 : {
39 : (void)vTopo;
40 : (void)virtRanks;
41 : (void)virtRankMap;
42 0 : HCCL_ERROR("[CollAlgFactory] Rank [%d], use proper 1-level interface to match topo.", myRank_);
43 0 : return HcclResult::HCCL_E_INTERNAL;
44 : }
45 :
46 0 : HcclResult TopoMatchBase::SetTargetRanks(std::set<u32>& targetRanks)
47 : {
48 : (void)targetRanks;
49 0 : return HcclResult::HCCL_SUCCESS;
50 : }
51 :
52 2 : HcclResult TopoMatchBase::GenVirtRankMapping(std::vector<RankId>& virtRanks, std::map<RankId, u32>& virtRankMap) const
53 : {
54 2 : std::sort(virtRanks.begin(), virtRanks.end());
55 10 : for (u64 idx = 0; idx < virtRanks.size(); idx++) {
56 8 : virtRankMap.insert(std::make_pair(virtRanks[idx], idx));
57 : }
58 :
59 2 : return HcclResult::HCCL_SUCCESS;
60 : }
61 :
62 0 : HcclResult TopoMatchBase::GenVirtRankMappingMultiLevel(
63 : std::vector<std::vector<RankId>>& virtRanks, std::vector<std::map<RankId, u32>>& virtRankMap) const
64 : {
65 0 : for (auto vRankIter = virtRanks.begin(); vRankIter != virtRanks.end(); vRankIter++) {
66 0 : std::map<RankId, u32> tmpVirtRankMap;
67 0 : CHK_PRT_RET(
68 : GenVirtRankMapping((*vRankIter), tmpVirtRankMap) != HcclResult::HCCL_SUCCESS,
69 : HCCL_ERROR("[CollAlgFactory] [TopoMatchMeshRing] Rank [%d], Fail to generate virtRankMapping.", myRank_),
70 : HcclResult::HCCL_E_INTERNAL);
71 0 : virtRankMap.push_back(tmpVirtRankMap);
72 0 : }
73 :
74 0 : return HcclResult::HCCL_SUCCESS;
75 : }
76 :
77 2 : HcclResult TopoMatchBase::CalcRankOnSamePlaneOfR0(
78 : std::vector<std::vector<RankId>>& rankOnSameBoardVector, std::vector<std::vector<RankId>>& rankOnSameSlotVector,
79 : std::vector<u32>& numRanksPerBoard) const
80 : {
81 2 : rankOnSameBoardVector.resize(RANK_SIZE_EIGHT, {});
82 2 : rankOnSameSlotVector.resize(RANK_SIZE_EIGHT, {});
83 2 : const NetInstance* netInstance = rankGraph_->GetNetInstanceByRankId(0, myRank_);
84 2 : if (netInstance == nullptr) {
85 0 : HCCL_ERROR("TopoMatchBase::CalcRankOnSamePlaneOfR0 netInstance is nullptr");
86 0 : return HcclResult::HCCL_E_PTR;
87 : }
88 2 : std::set<RankId> rankSet = netInstance->GetRankIds();
89 2 : CHK_PRT_RET(
90 : (rankSet.size() == 0), HCCL_ERROR("[CollAlgFactory] Rank [%d], Invalid virtual topo.", myRank_),
91 : HcclResult::HCCL_E_PARA);
92 :
93 10 : for (RankId rankId : rankSet) {
94 8 : u32 localId = rankGraph_->GetReplacedLocalId(rankId);
95 8 : CHK_PRT_RET(
96 : localId >= RANK_SIZE_EIGHT * RANK_SIZE_EIGHT,
97 : HCCL_ERROR("localId[%u] is bigger than 63 (RANK_SIZE_EIGHT * RANK_SIZE_EIGHT - 1).", localId),
98 : HcclResult::HCCL_E_PARA);
99 8 : rankOnSameBoardVector[localId / RANK_SIZE_EIGHT].push_back(rankId);
100 8 : rankOnSameSlotVector[localId % RANK_SIZE_EIGHT].push_back(rankId);
101 : }
102 18 : for (u32 i = 0; i < RANK_SIZE_EIGHT; i++) {
103 16 : if (rankOnSameBoardVector[i].size() != 0) {
104 4 : numRanksPerBoard.push_back(rankOnSameBoardVector[i].size());
105 : }
106 : }
107 2 : return HcclResult::HCCL_SUCCESS;
108 2 : }
109 :
110 0 : bool TopoMatchBase::IsAllRanksFullMeshConnected(std::set<RankId> rankSet) const
111 : {
112 0 : std::set<u32> levelSet = rankGraph_->GetLevels(myRank_);
113 0 : u32 pathNum = 0;
114 0 : for (auto it1 = rankSet.begin(); it1 != rankSet.end(); it1++) {
115 0 : for (auto it2 = std::next(it1, 1); it2 != rankSet.end(); it2++) {
116 0 : pathNum = 0;
117 0 : for (u32 levelIdx : levelSet) {
118 0 : std::vector<NetInstance::Path> paths = rankGraph_->GetPaths(levelIdx, *it1, *it2);
119 0 : pathNum += paths.size();
120 0 : }
121 0 : if (pathNum == 0) {
122 0 : return false;
123 : }
124 : }
125 : }
126 0 : return true;
127 0 : }
128 :
129 0 : u32 TopoMatchBase::GetPathNum(RankId srcRankId, RankId dstRankId) const
130 : {
131 0 : std::set<u32> levelSet = rankGraph_->GetLevels(myRank_);
132 0 : u32 pathNum = 0;
133 0 : for (u32 levelIdx : levelSet) {
134 0 : std::vector<NetInstance::Path> paths = rankGraph_->GetPaths(levelIdx, srcRankId, dstRankId);
135 0 : pathNum += paths.size();
136 0 : }
137 0 : return pathNum;
138 0 : }
139 :
140 0 : u32 TopoMatchBase::GcdTwo(u32 a, u32 b) const
141 : {
142 0 : while (0 != b) {
143 0 : a %= b;
144 0 : std::swap(a, b);
145 : }
146 0 : return a;
147 : }
148 :
149 0 : u32 TopoMatchBase::GcdMultiple(const std::vector<u32>& numbers) const
150 : {
151 0 : if (numbers.empty()) {
152 0 : THROW<InvalidParamsException>(StringFormat("Input vector cannot be empty."));
153 : }
154 0 : uint32_t result = numbers[0];
155 0 : for (const auto num : numbers) {
156 0 : result = GcdTwo(result, num);
157 0 : if (result == 1) {
158 0 : return 1;
159 : }
160 : }
161 0 : return result;
162 : }
163 :
164 0 : HcclResult TopoMatchBase::GenerateLevel1(
165 : const std::set<RankId>& rankSetLevel1, u32 gcdInstSize, RankId rankId,
166 : std::vector<std::vector<std::vector<RankId>>>& vTopo, std::vector<std::vector<RankId>>& virtRanks) const
167 : {
168 0 : CHK_PRT_RET(
169 : (gcdInstSize == 0), HCCL_ERROR("[CollAlgFactory] [TopoMatchBase] Rank [%d], gcdInstSize = 0", myRank_),
170 : HcclResult::HCCL_E_PARA);
171 :
172 0 : auto rankIter = rankSetLevel1.find(rankId);
173 0 : CHK_PRT_RET(
174 : (rankIter == rankSetLevel1.end()),
175 : HCCL_ERROR(
176 : "[CollAlgFactory] [TopoMatchBase] Rank [%d], "
177 : "failed to find this rank in rankSetLevel1[%s].",
178 : myRank_, PrintSet<RankId>(rankSetLevel1).c_str()),
179 : HcclResult::HCCL_E_PARA);
180 0 : u64 globalIdx = static_cast<u64>(std::distance(rankSetLevel1.begin(), rankIter));
181 0 : u64 relativeIdx = globalIdx % gcdInstSize;
182 :
183 0 : std::vector<RankId> rankOnSamePlaneVector;
184 0 : for (u64 step = relativeIdx; step < rankSetLevel1.size(); step += gcdInstSize) {
185 0 : auto targetIt = rankSetLevel1.begin();
186 : std::advance(targetIt, step);
187 0 : rankOnSamePlaneVector.push_back(*targetIt);
188 : }
189 :
190 0 : vTopo.push_back({rankOnSamePlaneVector});
191 0 : virtRanks.push_back(rankOnSamePlaneVector);
192 0 : return HCCL_SUCCESS;
193 0 : }
194 : } // namespace Hccl
|