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 "ins_temp_reduce_mesh_1D_two_shot.h"
12 :
13 : #include "log.h"
14 : #include "alg_data_trans_wrapper.h"
15 :
16 : namespace Hccl {
17 :
18 0 : InsTempReduceMesh1DTwoShot::InsTempReduceMesh1DTwoShot(const RankId virtualRank, const u32 tempRankSize,
19 0 : const std::vector<std::vector<RankId>> &tempVTopo, const std::map<RankId, u32> &tempVirtRankMap)
20 0 : : InsAlgTemplateBase(virtualRank, tempRankSize, tempVTopo, tempVirtRankMap)
21 : {
22 0 : idxToRankMap_.assign(this->tempRankSize_, -1);
23 0 : for (const auto &pair : tempVirtRankMap_) {
24 0 : if (pair.second < this->tempRankSize_) {
25 0 : idxToRankMap_[pair.second] = pair.first;
26 : }
27 : }
28 0 : HCCL_INFO("[InsTempReduceMesh1DTwoShot] Init.");
29 0 : }
30 :
31 0 : InsTempReduceMesh1DTwoShot::~InsTempReduceMesh1DTwoShot()
32 : {
33 0 : HCCL_INFO("[InsTempReduceMesh1DTwoShot] exit.");
34 0 : }
35 :
36 0 : HcclResult InsTempReduceMesh1DTwoShot::CalcRes(AlgTempResReq &tempResReq)
37 : {
38 0 : tempResReq.queNum = tempRankSize_;
39 0 : tempResReq.streamNum = tempResReq.queNum;
40 0 : tempResReq.queNotifys = CreateMasterSlaveQueNotifiesRequest(tempResReq.queNum);
41 :
42 0 : QId centerQ = 0;
43 0 : tempResReq.localWaitGroupCntNotify.emplace_back(centerQ, 0);
44 0 : tempResReq.localBcastPostCntNotify.emplace_back(centerQ, 0);
45 :
46 0 : CHK_PRT_RET(CalcResLinksMesh(myRank_, tempRankSize_, tempVTopo_, linkNumBtwPeers_, tempResReq) != HcclResult::HCCL_SUCCESS,
47 : HCCL_ERROR("[InsTempReduceMesh1DTwoShot] Rank [%d], resLinks calculation error!", myRank_),
48 : HcclResult::HCCL_E_INTERNAL);
49 :
50 0 : return HcclResult::HCCL_SUCCESS;
51 : }
52 :
53 0 : u32 InsTempReduceMesh1DTwoShot::CalcScratchMultiple(BufferType inBuffType, BufferType outBuffType) const
54 : {
55 : (void)inBuffType;
56 : (void)outBuffType;
57 0 : return tempRankSize_;
58 : }
59 :
60 0 : HcclResult InsTempReduceMesh1DTwoShot::CalcSlice(const u64 dataSize, RankSliceInfo &sliceInfoVec)
61 : {
62 0 : std::vector<SliceInfo> tmp(tempVTopo_.size());
63 0 : sliceInfoVec.resize(tempRankSize_, tmp);
64 :
65 0 : u32 unitAlignSize = DataTypeSizeGet(dataType_);
66 0 : if (unitAlignSize == 0) {
67 0 : return HcclResult::HCCL_E_INTERNAL;
68 : }
69 :
70 0 : u64 totalElements = dataSize / unitAlignSize;
71 0 : u64 baseElements = totalElements / tempRankSize_;
72 0 : u64 remainder = totalElements % tempRankSize_;
73 :
74 0 : u64 accumOff = 0;
75 0 : for (u32 rankIdx = 0; rankIdx < tempRankSize_; rankIdx++) {
76 0 : u64 currSize = 0;
77 :
78 0 : if (rankIdx < remainder) {
79 0 : currSize = (baseElements + 1) * unitAlignSize;
80 : } else {
81 0 : currSize = baseElements * unitAlignSize;
82 : }
83 :
84 0 : sliceInfoVec[rankIdx][0] = {accumOff, currSize};
85 0 : accumOff += currSize;
86 : }
87 :
88 0 : return HcclResult::HCCL_SUCCESS;
89 0 : }
90 :
91 0 : HcclResult InsTempReduceMesh1DTwoShot::GenExtIns(const TempFuncs &tempFuncs, const TemplateDataParams &tempAlgParams,
92 : const ResLinks &tempLinks, std::vector<InsQuePtr> &tempInsQues)
93 : {
94 0 : if (tempAlgParams.sliceSize == 0) {
95 0 : return HcclResult::HCCL_SUCCESS;
96 : }
97 :
98 0 : opMode_ = tempFuncs.opMode;
99 0 : enableCounterNotify_ = tempFuncs.enableCounterNotify;
100 :
101 0 : auto it = tempVirtRankMap_.find(myRank_);
102 0 : if (it == tempVirtRankMap_.end()) {
103 0 : HCCL_ERROR("[InsTempReduceMesh1DTwoShot] myRank [%d] not found in tempVirtRankMap.", myRank_);
104 0 : return HcclResult::HCCL_E_INTERNAL;
105 : }
106 0 : myIdx_ = it->second;
107 :
108 0 : RankSliceInfo sliceInfoVec;
109 0 : CHK_RET(CalcSlice(tempAlgParams.sliceSize, sliceInfoVec));
110 :
111 0 : CHK_RET(RunReduceScatter(sliceInfoVec, tempLinks, tempInsQues, tempAlgParams));
112 :
113 0 : CHK_RET(RunGatherToRoot(sliceInfoVec, tempLinks, tempInsQues, tempAlgParams));
114 :
115 0 : return HcclResult::HCCL_SUCCESS;
116 0 : }
117 :
118 0 : HcclResult InsTempReduceMesh1DTwoShot::RunReduceScatter(const RankSliceInfo &sliceInfoVec, const ResLinks &tempLinks,
119 : std::vector<InsQuePtr> &tempInsQues, const TemplateDataParams &tempAlgParams)
120 : {
121 0 : u64 inOff = tempAlgParams.buffInfo.inBuffBaseOff;
122 0 : u64 scOff = tempAlgParams.buffInfo.scratchBuffBaseOff;
123 :
124 0 : PreSyncInterQueues(tempInsQues);
125 :
126 0 : const u64 mySliceSize = sliceInfoVec[myIdx_][0].size;
127 0 : const u64 mySliceOffset = sliceInfoVec[myIdx_][0].offset;
128 :
129 0 : for (u32 rankId = 0; rankId < tempRankSize_; rankId++) {
130 0 : u64 sliceSize = sliceInfoVec[rankId][0].size;
131 0 : u64 sliceOffset = sliceInfoVec[rankId][0].offset;
132 :
133 0 : DataSlice sendSrcSlice(tempAlgParams.buffInfo.inBuffType, sliceOffset + inOff, sliceSize);
134 0 : DataSlice sendDstSlice(tempAlgParams.buffInfo.scratBuffType, static_cast<u64>(myIdx_) * sliceSize + scOff, sliceSize);
135 :
136 0 : if (rankId == myIdx_) {
137 0 : if (sliceSize != 0) {
138 0 : CHK_RET(LocalCopy(tempInsQues[rankId], sendSrcSlice, sendDstSlice));
139 : }
140 : } else {
141 0 : DataSlice recvSrcSlice(tempAlgParams.buffInfo.inBuffType, mySliceOffset + inOff, mySliceSize);
142 0 : DataSlice recvDstSlice(tempAlgParams.buffInfo.scratBuffType, static_cast<u64>(rankId) * mySliceSize + scOff, mySliceSize);
143 :
144 0 : RankId targetRank = GetRankFromMap(rankId);
145 0 : if (targetRank == -1 || tempLinks.find(targetRank) == tempLinks.end()) {
146 0 : HCCL_ERROR("[InsTempReduceMesh1DTwoShot] Invalid rank [%u] mapped to [%d] or link not found.", rankId, targetRank);
147 0 : return HcclResult::HCCL_E_INTERNAL;
148 : }
149 :
150 0 : const auto &link = tempLinks.at(targetRank)[0];
151 0 : TxRxLinks links(link, link);
152 :
153 0 : SlicesList sendSList({sendSrcSlice}, {sendDstSlice});
154 0 : SlicesList recvSList({recvSrcSlice}, {recvDstSlice});
155 0 : TxRxSlicesList txRxSList(sendSList, recvSList);
156 :
157 0 : CHK_RET(SendRecv(SendRecvInfo(links, txRxSList), tempInsQues[rankId], 0, true, DmaMode::PUT));
158 0 : }
159 : }
160 :
161 0 : PostSyncInterQueues(tempInsQues);
162 :
163 0 : if (mySliceSize != 0) {
164 0 : u64 destOffset = static_cast<u64>(myIdx_) * mySliceSize + scOff;
165 0 : DataSlice finalDest(tempAlgParams.buffInfo.scratBuffType, destOffset, mySliceSize);
166 :
167 0 : for (u32 i = 0; i < tempRankSize_; i++) {
168 0 : if (i == myIdx_) {
169 0 : continue;
170 : }
171 0 : DataSlice currentSrc(tempAlgParams.buffInfo.scratBuffType, static_cast<u64>(i) * mySliceSize + scOff, mySliceSize);
172 0 : CHK_RET(LocalReduce(tempInsQues[0], currentSrc, finalDest, dataType_, redOp_));
173 : }
174 : }
175 :
176 0 : return HcclResult::HCCL_SUCCESS;
177 : }
178 :
179 0 : HcclResult InsTempReduceMesh1DTwoShot::RunGatherToRoot(const RankSliceInfo &sliceInfoVec, const ResLinks &tempLinks,
180 : std::vector<InsQuePtr> &tempInsQues, const TemplateDataParams &tempAlgParams)
181 : {
182 0 : u64 scOff = tempAlgParams.buffInfo.scratchBuffBaseOff;
183 0 : u64 outOff = tempAlgParams.buffInfo.outBuffBaseOff;
184 :
185 0 : PreSyncInterQueues(tempInsQues);
186 :
187 0 : if (static_cast<u32>(myRank_) == root_) {
188 0 : for (u32 rankIdx = 0; rankIdx < tempRankSize_; rankIdx++) {
189 0 : u64 curSize = sliceInfoVec[rankIdx][0].size;
190 0 : if (curSize == 0) continue;
191 :
192 0 : if (rankIdx == myIdx_) {
193 0 : u64 srcOffset = static_cast<u64>(myIdx_) * curSize + scOff;
194 0 : DataSlice src(tempAlgParams.buffInfo.scratBuffType, srcOffset, curSize);
195 0 : DataSlice dst(tempAlgParams.buffInfo.outBuffType, sliceInfoVec[rankIdx][0].offset + outOff, curSize);
196 0 : CHK_RET(LocalCopy(tempInsQues[rankIdx], src, dst));
197 : } else {
198 0 : u64 remoteSrcOffset = static_cast<u64>(rankIdx) * curSize + scOff;
199 0 : DataSlice rsrc(tempAlgParams.buffInfo.scratBuffType, remoteSrcOffset, curSize);
200 0 : DataSlice rdest(tempAlgParams.buffInfo.outBuffType, sliceInfoVec[rankIdx][0].offset + outOff, curSize);
201 :
202 0 : RankId targetRank = GetRankFromMap(rankIdx);
203 0 : if (targetRank == -1 || tempLinks.find(targetRank) == tempLinks.end()) {
204 0 : HCCL_ERROR("[InsTempReduceMesh1DTwoShot] Gather root: Invalid rank [%u] mapped to [%d] or link not found.", rankIdx, targetRank);
205 0 : return HcclResult::HCCL_E_INTERNAL;
206 : }
207 :
208 0 : const auto &link = tempLinks.at(targetRank)[0];
209 0 : SlicesList sliceList({rsrc}, {rdest});
210 :
211 0 : CHK_RET(Recv(DataInfo(link, sliceList), tempInsQues[rankIdx], 1, true, DmaMode::GET));
212 0 : }
213 : }
214 : } else {
215 0 : u32 rankIdx = myIdx_;
216 0 : u64 curSize = sliceInfoVec[rankIdx][0].size;
217 :
218 0 : if (curSize != 0) {
219 0 : DataSlice ssrc(tempAlgParams.buffInfo.scratBuffType, static_cast<u64>(rankIdx) * curSize + scOff, curSize);
220 0 : DataSlice sdest(tempAlgParams.buffInfo.outBuffType, sliceInfoVec[rankIdx][0].offset + outOff, curSize);
221 :
222 0 : if (tempLinks.find(root_) == tempLinks.end()) {
223 0 : HCCL_ERROR("[InsTempReduceMesh1DTwoShot] Gather non-root: Root rank [%u] link not found.", root_);
224 0 : return HcclResult::HCCL_E_INTERNAL;
225 : }
226 :
227 0 : const auto &link = tempLinks.at(root_)[0];
228 0 : SlicesList sliceList({ssrc}, {sdest});
229 :
230 0 : auto rootIt = tempVirtRankMap_.find(root_);
231 0 : if (rootIt == tempVirtRankMap_.end()) {
232 0 : HCCL_ERROR("[InsTempReduceMesh1DTwoShot] root_ [%u] not found in tempVirtRankMap.", root_);
233 0 : return HcclResult::HCCL_E_INTERNAL;
234 : }
235 :
236 0 : CHK_RET(Send(DataInfo(link, sliceList), tempInsQues[rootIt->second], 1, true, DmaMode::GET));
237 0 : }
238 : }
239 :
240 0 : PostSyncInterQueues(tempInsQues);
241 0 : return HcclResult::HCCL_SUCCESS;
242 : }
243 :
244 0 : RankId InsTempReduceMesh1DTwoShot::GetRankFromMap(const u32 rankIdx)
245 : {
246 0 : if (static_cast<size_t>(rankIdx) >= idxToRankMap_.size()) {
247 0 : return -1;
248 : }
249 0 : return idxToRankMap_[rankIdx];
250 : }
251 : } // namespace Hccl
|