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