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