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 "log.h"
12 : #include "alg_data_trans_wrapper.h"
13 : #include "executor_utils.h"
14 : #include "ins_temp_all_to_all_mesh_2D.h"
15 :
16 : namespace Hccl {
17 0 : InsTempAlltoAllMesh2D::InsTempAlltoAllMesh2D(const RankId virtualRank, const u32 tempRankSize,
18 : const std::vector<std::vector<RankId>> &tempVTopo,
19 0 : const std::map<RankId, u32> &tempVirtRankMap)
20 0 : : InsAlgTemplateBase(virtualRank, tempRankSize, tempVTopo, tempVirtRankMap)
21 : {
22 0 : }
23 :
24 0 : InsTempAlltoAllMesh2D::~InsTempAlltoAllMesh2D()
25 : {
26 0 : }
27 :
28 0 : HcclResult InsTempAlltoAllMesh2D::CalcRes(AlgTempResReq &tempResReq)
29 : {
30 0 : if (tempVTopo_.size() >= TEMPVTOPOSIZE) {
31 0 : rankId_ = myRank_;
32 0 : rankSize_ = tempRankSize_;
33 0 : xRankSize_ = tempVTopo_[0].size();
34 0 : yRankSize_ = tempVTopo_[1].size();
35 0 : CHK_RET(GetAlgRank(myRank_, tempVTopo_[0], xRankId_));
36 0 : CHK_RET(GetAlgRank(myRank_, tempVTopo_[1], yRankId_));
37 0 : CHK_PRT_RET((xRankSize_ == 0), HCCL_ERROR("xRankSize_ equals to zero."), HcclResult::HCCL_E_PARA);
38 0 : CHK_PRT_RET((yRankSize_ == 0), HCCL_ERROR("yRankSize_ equals to zero."), HcclResult::HCCL_E_PARA);
39 : } else {
40 0 : HCCL_ERROR("tempVTopo_.size() is [%zu]", tempVTopo_.size());
41 0 : return HcclResult::HCCL_E_INTERNAL;
42 : }
43 :
44 0 : HCCL_DEBUG("rankId_ is [%u], rankSize_ is [%u], xRankSize_ is [%u], yRankSize_ is [%u]", rankId_, rankSize_, xRankSize_, yRankSize_);
45 :
46 0 : tempResReq.queNum = tempVTopo_[0].size() + tempVTopo_[1].size();
47 0 : tempResReq.streamNum = tempResReq.queNum;
48 0 : tempResReq.queNotifys = CreateMasterSlaveQueNotifiesRequest(tempResReq.queNum);
49 :
50 0 : QId centerQ = 0;
51 0 : tempResReq.localWaitGroupCntNotify.emplace_back(centerQ, 0);
52 0 : tempResReq.localBcastPostCntNotify.emplace_back(centerQ, 0);
53 :
54 : uint32_t myAlgRank;
55 0 : for (u32 dim = 0; dim < tempVTopo_.size(); dim++) {
56 0 : CHK_RET(GetAlgRank(myRank_, tempVTopo_[dim], myAlgRank));
57 0 : for (u32 queIdx = 0; queIdx < tempVTopo_[dim].size() - 1; queIdx++) {
58 0 : u32 neighborAlgRank = (myAlgRank + 1 + queIdx) % (tempVTopo_[dim].size());
59 0 : RankId neighborRank = tempVTopo_[dim][neighborAlgRank];
60 0 : HCCL_INFO("InsTempAlltoAllMesh2D::CalcRes Rank[%d], Dim[%u], NeighborRank[%d].", myRank_,
61 : dim, neighborRank);
62 : // LinkNum
63 0 : tempResReq.links[neighborRank] = 1;
64 : }
65 : }
66 0 : HCCL_INFO("[InsTempAlltoAllMesh2D] Calculate resource, stream number is[%u], queNotifys size is[%u]",
67 : tempResReq.streamNum, tempResReq.queNotifys.size());
68 0 : return HcclResult::HCCL_SUCCESS;
69 : }
70 :
71 0 : HcclResult InsTempAlltoAllMesh2D::RunMeshX(std::vector<u64> &xDataInAddr, std::vector<u64> &xDataOutAddr, u64 xSize,
72 : BufferType srcBufferType, BufferType dstBufferType, DmaMode dmaMode, std::vector<InsQuePtr> &xInsQues,
73 : const ResLinks &tempLinks) const
74 : {
75 0 : HCCL_DEBUG("RunMeshX begin, xSize is [%u]", xSize);
76 0 : if (xSize == 0) {
77 0 : HCCL_INFO("[InsTempAlltoAllMesh2D] RunMeshX, xSize is 0");
78 0 : return HcclResult::HCCL_SUCCESS;
79 : }
80 0 : std::vector<DataSlice> txSrcSlices, txDstSlices, rxSrcSlices, rxDstSlices;
81 0 : for (u32 i = 0; i < rankSize_; i++) {
82 : // 计算send
83 0 : u64 xOffset = xRankId_;
84 0 : u64 yOffset = i / xRankSize_;
85 0 : u64 dstOffset = yOffset * xRankSize_ + xOffset;
86 :
87 0 : DataSlice txSrcSlice = DataSlice(srcBufferType, xDataInAddr[i], xSize);
88 0 : DataSlice txDstSlice = DataSlice(dstBufferType, xDataOutAddr[dstOffset] , xSize);
89 0 : txSrcSlices.push_back(txSrcSlice);
90 0 : txDstSlices.push_back(txDstSlice);
91 :
92 : // 计算recv,recv侧的 xOffset,yOffset,dstOffset的计算方式和send侧一样
93 0 : DataSlice rxSrcSlice = DataSlice(srcBufferType, xDataInAddr[dstOffset], xSize);
94 0 : DataSlice rxDstSlice = DataSlice(dstBufferType, xDataOutAddr[i], xSize);
95 0 : rxSrcSlices.push_back(rxSrcSlice);
96 0 : rxDstSlices.push_back(rxDstSlice);
97 : }
98 :
99 : // 同一列的用一个队列
100 0 : std::vector<DataSlice> txLocalSrcSlices, txLocalDstSlices;
101 0 : for (u32 i = 0; i < rankSize_; i++) {
102 0 : if ( i % xRankSize_ == xRankId_) {
103 0 : txLocalSrcSlices.push_back(txSrcSlices[i]);
104 0 : txLocalDstSlices.push_back(txDstSlices[i]);
105 : }
106 : }
107 : // 本地拷贝
108 0 : CHK_RET(LocalCopySlices(xInsQues[xRankId_], txLocalSrcSlices, txLocalDstSlices));
109 :
110 : // 拷贝到其他卡
111 0 : for (u32 queIdx = 0; queIdx < xRankSize_; queIdx++) {
112 0 : if (queIdx == xRankId_) {
113 0 : continue;
114 : }
115 :
116 0 : std::vector<DataSlice> txRmtSrcSlices, txRmtDstSlices, rxRmtSrcSlices, rxRmtDstSlices;
117 0 : for (u32 i = 0; i < rankSize_; i++) {
118 0 : if ( i % xRankSize_ == queIdx) {
119 0 : txRmtSrcSlices.push_back(txSrcSlices[i]);
120 0 : txRmtDstSlices.push_back(txDstSlices[i]);
121 0 : rxRmtSrcSlices.push_back(rxSrcSlices[i]);
122 0 : rxRmtDstSlices.push_back(rxDstSlices[i]);
123 : }
124 : }
125 0 : TxRxSlicesList sendRecvSlicesList({txRmtSrcSlices, txRmtDstSlices}, {rxRmtSrcSlices, rxRmtDstSlices});
126 :
127 0 : RankId rankSendRecv = queIdx + yRankId_ * xRankSize_;
128 0 : const std::vector<LinkData> &linkSendRecv = tempLinks.at(rankSendRecv);
129 0 : TxRxLinks sendRecvLinks(linkSendRecv[0], linkSendRecv[0]);
130 :
131 0 : SendRecvInfo sendRecvInfo(sendRecvLinks, sendRecvSlicesList);
132 0 : CHK_PRT_RET(SendRecv(sendRecvInfo, xInsQues[queIdx], 0, true, dmaMode),
133 : HCCL_ERROR("[InsTempAlltoAllMesh2D] RunMeshX SendRecv failed"), HcclResult::HCCL_E_INTERNAL);
134 0 : }
135 :
136 0 : return HcclResult::HCCL_SUCCESS;
137 0 : }
138 :
139 0 : HcclResult InsTempAlltoAllMesh2D::RunMeshY(std::vector<u64> &yDataInAddr, std::vector<u64> &yDataOutAddr, u64 ySize,
140 : BufferType srcBufferType, BufferType dstBufferType, DmaMode dmaMode, std::vector<InsQuePtr> &yInsQues,
141 : const ResLinks &tempLinks) const
142 : {
143 0 : HCCL_DEBUG("RunMeshX begin, ySize is [%u]", ySize);
144 0 : if (ySize == 0) {
145 0 : HCCL_INFO("[InsTempAlltoAllMesh2D] RunMeshY, ySize is 0");
146 0 : return HcclResult::HCCL_SUCCESS;
147 : }
148 :
149 0 : std::vector<DataSlice> txSrcSlices, txDstSlices, rxSrcSlices, rxDstSlices;
150 0 : for (u32 i = 0; i < rankSize_; i++) {
151 : // 计算send
152 0 : u64 xOffset = i % xRankSize_;
153 0 : u64 yOffset = yRankId_;
154 0 : u64 dstOffset = yOffset * xRankSize_ + xOffset;
155 :
156 0 : DataSlice txSrcSlice = DataSlice(srcBufferType, yDataInAddr[i], ySize);
157 0 : DataSlice txDstSlice = DataSlice(dstBufferType, yDataOutAddr[dstOffset], ySize);
158 0 : txSrcSlices.push_back(txSrcSlice);
159 0 : txDstSlices.push_back(txDstSlice);
160 :
161 : // 计算recv,recv侧的 xOffset,yOffset,dstOffset的计算方式和send侧一样
162 0 : DataSlice rxSrcSlice = DataSlice(srcBufferType, yDataInAddr[dstOffset], ySize);
163 0 : DataSlice rxDstSlice = DataSlice(dstBufferType, yDataOutAddr[i], ySize);
164 0 : rxSrcSlices.push_back(rxSrcSlice);
165 0 : rxDstSlices.push_back(rxDstSlice);
166 : }
167 :
168 : // 同一行的用一个队列
169 0 : std::vector<DataSlice> txLocalSrcSlices, txLocalDstSlices;
170 0 : for (u32 i = 0; i < rankSize_; i++) {
171 0 : if ( i / xRankSize_ == yRankId_) {
172 0 : txLocalSrcSlices.push_back(txSrcSlices[i]);
173 0 : txLocalDstSlices.push_back(txDstSlices[i]);
174 : }
175 : }
176 : // 本地拷贝
177 0 : CHK_RET(LocalCopySlices(yInsQues[yRankId_], txLocalSrcSlices, txLocalDstSlices));
178 :
179 : // 拷贝到其他卡
180 0 : for (u32 queIdx = 0; queIdx < yRankSize_; queIdx++) {
181 0 : if (queIdx == yRankId_) {
182 0 : continue;
183 : }
184 :
185 0 : std::vector<DataSlice> txRmtSrcSlices, txRmtDstSlices, rxRmtSrcSlices, rxRmtDstSlices;
186 0 : for (u32 i = 0; i < rankSize_; i++) {
187 0 : if ( i / xRankSize_ == queIdx) {
188 0 : txRmtSrcSlices.push_back(txSrcSlices[i]);
189 0 : txRmtDstSlices.push_back(txDstSlices[i]);
190 0 : rxRmtSrcSlices.push_back(rxSrcSlices[i]);
191 0 : rxRmtDstSlices.push_back(rxDstSlices[i]);
192 : }
193 : }
194 0 : TxRxSlicesList sendRecvSlicesList({txRmtSrcSlices, txRmtDstSlices}, {rxRmtSrcSlices, rxRmtDstSlices});
195 :
196 0 : RankId rankSendRecv = queIdx * xRankSize_ + xRankId_;
197 0 : const std::vector<LinkData> &linkSendRecv = tempLinks.at(rankSendRecv);
198 0 : TxRxLinks sendRecvLinks(linkSendRecv[0], linkSendRecv[0]);
199 :
200 0 : SendRecvInfo sendRecvInfo(sendRecvLinks, sendRecvSlicesList);
201 0 : CHK_PRT_RET(SendRecv(sendRecvInfo, yInsQues[queIdx], 0, true, dmaMode),
202 : HCCL_ERROR("[InsTempAlltoAllMesh2D] RunMeshY SendRecv failed"), HcclResult::HCCL_E_INTERNAL);
203 0 : }
204 :
205 0 : return HcclResult::HCCL_SUCCESS;
206 0 : }
207 :
208 0 : HcclResult InsTempAlltoAllMesh2D::GenExtIns(const TempFuncs &tempFuncs, const TemplateDataParams &tempAlgParams,
209 : const ResLinks &tempLinks, std::vector<InsQuePtr> &tempInsQues) const
210 : {
211 : (void)tempFuncs;
212 0 : HCCL_INFO("[InsTempAlltoAllMesh2D] Run algorithm start: rank[%d]", myRank_);
213 :
214 0 : u64 xSize = tempAlgParams.sliceSize / 2;
215 0 : u64 ySize = tempAlgParams.sliceSize - xSize;
216 :
217 : // queue arrangement
218 0 : std::vector<InsQuePtr> xInsQues, yInsQues;
219 0 : for (u32 queIdx = 0; queIdx < xRankSize_ + yRankSize_; queIdx++) {
220 0 : if (queIdx < xRankSize_) {
221 0 : xInsQues.push_back(tempInsQues[queIdx]);
222 : } else {
223 0 : yInsQues.push_back(tempInsQues[queIdx]);
224 : }
225 : }
226 :
227 : // stage1
228 0 : if (rankSize_ > 1) {
229 0 : CHK_RET(PreSyncInterQueues(tempInsQues));
230 : }
231 :
232 0 : std::vector<u64> stage1XDataInAddr, stage1YDataInAddr, stage1XDataOutAddr, stage1YDataOutAddr;
233 0 : for (u32 i = 0; i < rankSize_; i++) {
234 0 : stage1XDataInAddr.push_back(tempAlgParams.inputSliceStride * i + tempAlgParams.buffInfo.inBuffBaseOff);
235 0 : stage1YDataInAddr.push_back(tempAlgParams.inputSliceStride * i + tempAlgParams.buffInfo.inBuffBaseOff + xSize);
236 0 : stage1XDataOutAddr.push_back(tempAlgParams.buffInfo.scratchBuffBaseOff + tempAlgParams.sliceSize * i);
237 0 : stage1YDataOutAddr.push_back(tempAlgParams.buffInfo.scratchBuffBaseOff + tempAlgParams.sliceSize * i + xSize);
238 : }
239 :
240 0 : CHK_RET(RunMeshX(stage1XDataInAddr, stage1XDataOutAddr, xSize, BufferType::INPUT, BufferType::SCRATCH,
241 : DmaMode::PUT, xInsQues, tempLinks));
242 0 : CHK_RET(RunMeshY(stage1YDataInAddr, stage1YDataOutAddr, ySize, BufferType::INPUT, BufferType::SCRATCH,
243 : DmaMode::PUT, yInsQues, tempLinks));
244 :
245 0 : if (rankSize_ > 1) {
246 0 : CHK_RET(PostSyncInterQueues(tempInsQues));
247 : }
248 :
249 : // stage2
250 0 : if (rankSize_ > 1) {
251 0 : CHK_RET(PreSyncInterQueues(tempInsQues));
252 : }
253 :
254 0 : std::vector<u64> stage2XDataInAddr, stage2YDataInAddr, stage2XDataOutAddr, stage2YDataOutAddr;
255 0 : for (u32 i = 0; i < rankSize_; i++) {
256 0 : stage2XDataInAddr.push_back(tempAlgParams.buffInfo.scratchBuffBaseOff + tempAlgParams.sliceSize * i);
257 0 : stage2YDataInAddr.push_back(tempAlgParams.buffInfo.scratchBuffBaseOff + tempAlgParams.sliceSize * i + xSize);
258 0 : stage2XDataOutAddr.push_back(tempAlgParams.outputSliceStride * i + tempAlgParams.buffInfo.outBuffBaseOff);
259 0 : stage2YDataOutAddr.push_back(tempAlgParams.outputSliceStride * i + tempAlgParams.buffInfo.outBuffBaseOff + xSize);
260 : }
261 :
262 0 : BufferType outType = !tempFuncs.isBottom ? BufferType::SCRATCH : BufferType::OUTPUT;
263 0 : CHK_RET(RunMeshY(stage2XDataInAddr, stage2XDataOutAddr, xSize, BufferType::SCRATCH, outType,
264 : DmaMode::GET, yInsQues, tempLinks));
265 0 : CHK_RET(RunMeshX(stage2YDataInAddr, stage2YDataOutAddr, ySize, BufferType::SCRATCH, outType,
266 : DmaMode::GET, xInsQues, tempLinks));
267 :
268 0 : if (rankSize_ > 1) {
269 0 : CHK_RET(PostSyncInterQueues(tempInsQues));
270 : }
271 :
272 0 : HCCL_INFO("[InsTempAlltoAllMesh2D] Run algorithm end: rank[%d]", myRank_);
273 :
274 0 : return HcclResult::HCCL_SUCCESS;
275 0 : }
276 :
277 : } // namespace Hccl
|