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 interfacce 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 interfacce 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, HCCL_ERROR("localId is bigger than 63."),
97 : HcclResult::HCCL_E_PARA);
98 8 : rankOnSameBoardVector[localId / RANK_SIZE_EIGHT].push_back(rankId);
99 8 : rankOnSameSlotVector[localId % RANK_SIZE_EIGHT].push_back(rankId);
100 : }
101 18 : for (u32 i = 0; i < RANK_SIZE_EIGHT; i++) {
102 16 : if (rankOnSameBoardVector[i].size() != 0) {
103 4 : numRanksPerBoard.push_back(rankOnSameBoardVector[i].size());
104 : }
105 : }
106 2 : return HcclResult::HCCL_SUCCESS;
107 2 : }
108 :
109 0 : bool TopoMatchBase::IsAllRanksFullMeshConnected(std::set<RankId> rankSet) const
110 : {
111 0 : std::set<u32> levelSet = rankGraph_->GetLevels(myRank_);
112 0 : u32 pathNum = 0;
113 0 : for (auto it1 = rankSet.begin(); it1 != rankSet.end(); it1++) {
114 0 : for (auto it2 = std::next(it1, 1); it2 != rankSet.end(); it2++) {
115 0 : pathNum = 0;
116 0 : for (u32 levelIdx : levelSet) {
117 0 : std::vector<NetInstance::Path> paths = rankGraph_->GetPaths(levelIdx, *it1, *it2);
118 0 : pathNum += paths.size();
119 0 : }
120 0 : if (pathNum == 0) {
121 0 : return false;
122 : }
123 : }
124 : }
125 0 : return true;
126 0 : }
127 :
128 0 : u32 TopoMatchBase::GetPathNum(RankId srcRankId, RankId dstRankId) const
129 : {
130 0 : std::set<u32> levelSet = rankGraph_->GetLevels(myRank_);
131 0 : u32 pathNum = 0;
132 0 : for (u32 levelIdx : levelSet) {
133 0 : std::vector<NetInstance::Path> paths = rankGraph_->GetPaths(levelIdx, srcRankId, dstRankId);
134 0 : pathNum += paths.size();
135 0 : }
136 0 : return pathNum;
137 0 : }
138 :
139 0 : u32 TopoMatchBase::GcdTwo(u32 a, u32 b) const
140 : {
141 0 : while (0 != b) {
142 0 : a %= b;
143 0 : std::swap(a, b);
144 : }
145 0 : return a;
146 : }
147 :
148 0 : u32 TopoMatchBase::GcdMultiple(const std::vector<u32>& numbers) const
149 : {
150 0 : if (numbers.empty()) {
151 0 : THROW<InvalidParamsException>(StringFormat("Input vector cannot be empty."));
152 : }
153 0 : uint32_t result = numbers[0];
154 0 : for (const auto num : numbers) {
155 0 : result = GcdTwo(result, num);
156 0 : if (result == 1) {
157 0 : return 1;
158 : }
159 : }
160 0 : return result;
161 : }
162 :
163 0 : HcclResult TopoMatchBase::GenerateLevel1(
164 : const std::set<RankId>& rankSetLevel1, u32 gcdInstSize, RankId rankId,
165 : std::vector<std::vector<std::vector<RankId>>>& vTopo, std::vector<std::vector<RankId>>& virtRanks) const
166 : {
167 0 : CHK_PRT_RET(
168 : (gcdInstSize == 0), HCCL_ERROR("[CollAlgFactory] [TopoMatchBase] Rank [%d], gcdInstSize = 0", myRank_),
169 : HcclResult::HCCL_E_PARA);
170 :
171 0 : auto rankIter = rankSetLevel1.find(rankId);
172 0 : CHK_PRT_RET(
173 : (rankIter == rankSetLevel1.end()),
174 : HCCL_ERROR(
175 : "[CollAlgFactory] [TopoMatchBase] Rank [%d], "
176 : "failed to find this rank in rankSetLevel1[%s].",
177 : myRank_, PrintSet<RankId>(rankSetLevel1).c_str()),
178 : HcclResult::HCCL_E_PARA);
179 0 : u64 globalIdx = static_cast<u64>(std::distance(rankSetLevel1.begin(), rankIter));
180 0 : u64 relativeIdx = globalIdx % gcdInstSize;
181 :
182 0 : std::vector<RankId> rankOnSamePlaneVector;
183 0 : for (u64 step = relativeIdx; step < rankSetLevel1.size(); step += gcdInstSize) {
184 0 : auto targetIt = rankSetLevel1.begin();
185 : std::advance(targetIt, step);
186 0 : rankOnSamePlaneVector.push_back(*targetIt);
187 : }
188 :
189 0 : vTopo.push_back({rankOnSamePlaneVector});
190 0 : virtRanks.push_back(rankOnSamePlaneVector);
191 0 : return HCCL_SUCCESS;
192 0 : }
193 : } // namespace Hccl
|