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 :
13 : #include "alg_data_trans_wrapper.h"
14 : #include "ins_temp_all_gather_mesh_opt.h"
15 :
16 : namespace Hccl {
17 0 : InsTempAllGatherMesh1DOpt::InsTempAllGatherMesh1DOpt(
18 : const RankId virtualRank, const u32 tempRankSize, const std::vector<std::vector<RankId>>& tempVTopo,
19 0 : const std::map<RankId, u32>& tempVirtRankMap)
20 0 : : InsAlgTemplateBase(virtualRank, tempRankSize, tempVTopo, tempVirtRankMap)
21 0 : {}
22 :
23 0 : InsTempAllGatherMesh1DOpt::~InsTempAllGatherMesh1DOpt() {}
24 :
25 0 : HcclResult InsTempAllGatherMesh1DOpt::CalcRes(AlgTempResReq& tempResReq)
26 : {
27 0 : HCCL_DEBUG("[InsTempAllGatherMesh1DOpt] Enter CalcRes");
28 0 : tempResReq.queNum = tempVTopo_[0].size();
29 0 : HCCL_INFO("LGC tempVTopo_.size() is [%zu], AllGather queNum is [%llu]", tempVTopo_.size(), tempResReq.queNum);
30 0 : tempResReq.streamNum = tempResReq.queNum;
31 0 : tempResReq.queNotifys = CreateMasterSlaveQueNotifiesRequest(tempResReq.queNum);
32 0 : HCCL_DEBUG("[InsTempAllGatherMesh1DOpt] CalcRes queNotifys size[%zu]", tempResReq.queNotifys.size());
33 :
34 0 : QId centerQ = 0;
35 0 : tempResReq.localWaitGroupCntNotify.emplace_back(centerQ, 0);
36 0 : tempResReq.localBcastPostCntNotify.emplace_back(centerQ, 0);
37 :
38 0 : CHK_RET(CalcResLinksMesh(myRank_, tempRankSize_, tempVTopo_, linkNumBtwPeers_, tempResReq));
39 0 : HCCL_DEBUG("[InsTempAllGatherMesh1DOpt] CalcRes done");
40 0 : return HcclResult::HCCL_SUCCESS;
41 : }
42 :
43 : HcclResult
44 0 : InsTempAllGatherMesh1DOpt::CalcSliceInfo(const AllignInfo& allignInfo, const u64 dataSize, RankSliceInfo& sliceInfoVec)
45 : {
46 0 : std::vector<SliceInfo> tmp(1);
47 0 : sliceInfoVec.resize(tempRankSize_, tmp);
48 :
49 0 : CHK_RET(CalcRsAgSliceInfoMesh(myRank_, tempRankSize_, allignInfo, dataSize, sliceInfoVec));
50 :
51 0 : return HcclResult::HCCL_SUCCESS;
52 0 : }
53 :
54 0 : HcclResult InsTempAllGatherMesh1DOpt::GenExtIns(
55 : const TempFuncs& tempFuncs, const TemplateDataParams& tempAlgParams, const ResLinks& tempLinks,
56 : std::vector<InsQuePtr>& tempInsQues)
57 : {
58 0 : HCCL_INFO("[InsTempAllGatherMesh1DOpt] RunAllGather start");
59 :
60 0 : opMode_ = tempFuncs.opMode;
61 0 : tempAlgParams_ = tempAlgParams;
62 0 : tempLinks_ = tempLinks;
63 :
64 0 : CHK_PRT_RET(
65 : tempInsQues.size() != tempVTopo_[0].size(),
66 : HCCL_ERROR(
67 : "[InsTempAllGatherMesh1DOpt] RunAllGather Rank [%d], requiredQueNum [%u] not equals to "
68 : "templateQueNum [%u].",
69 : myRank_, tempVTopo_[0].size(), tempInsQues.size()),
70 : HcclResult::HCCL_E_INTERNAL);
71 :
72 0 : CHK_RET(LocalCopyToScratch(tempInsQues[0]));
73 :
74 : // semaphore sync
75 0 : CHK_RET(PreSyncInterQueues(tempInsQues));
76 :
77 : // Local Copy from Input to Output
78 0 : CHK_RET(LocalCopyToUsrOut(tempInsQues[0]));
79 :
80 : // locate myRank in tempVTopo -> algRank
81 : u32 myAlgRank;
82 0 : CHK_RET(GetAlgRank(myRank_, tempVTopo_[0], myAlgRank));
83 :
84 : // run Mesh 使用第1至rankSize条queue
85 0 : CHK_PRT_RET(
86 : RunMesh(myAlgRank, tempVTopo_[0], tempInsQues) != HcclResult::HCCL_SUCCESS,
87 : HCCL_ERROR("[InsTempAllGatherMesh1DOpt] Rank [%d], unable to run mesh algorithm.", myRank_),
88 : HcclResult::HCCL_E_INTERNAL);
89 :
90 : // semaphore sync
91 0 : CHK_RET(PostSyncInterQueues(tempInsQues));
92 :
93 0 : return HcclResult::HCCL_SUCCESS;
94 : }
95 :
96 0 : HcclResult InsTempAllGatherMesh1DOpt::LocalCopyToUsrOut(InsQuePtr tempInsQue)
97 : {
98 0 : if (tempAlgParams_.buffInfo.inBuffType == tempAlgParams_.buffInfo.outBuffType) {
99 0 : return HcclResult::HCCL_SUCCESS;
100 : }
101 :
102 : u32 myAlgRank;
103 0 : CHK_RET(GetAlgRank(myRank_, tempVTopo_[0], myAlgRank));
104 0 : u64 sliceSize = ((myAlgRank == tempRankSize_ - 1) && (tempAlgParams_.tailSize != 0)) ? tempAlgParams_.tailSize :
105 : tempAlgParams_.sliceSize;
106 0 : for (u32 rpt = 0; rpt < tempAlgParams_.repeatNum; ++rpt) {
107 0 : const u64 inBaseOff = tempAlgParams_.buffInfo.inBuffBaseOff + rpt * tempAlgParams_.inputRepeatStride;
108 0 : const u64 outBaseOff = tempAlgParams_.buffInfo.outBuffBaseOff + rpt * tempAlgParams_.outputRepeatStride;
109 :
110 0 : const u64 inOff = tempAlgParams_.inputSliceStride * myAlgRank + inBaseOff;
111 0 : const u64 outOff = tempAlgParams_.outputSliceStride * myAlgRank + outBaseOff;
112 :
113 0 : DataSlice src(tempAlgParams_.buffInfo.inBuffType, inOff, sliceSize);
114 0 : DataSlice dst(tempAlgParams_.buffInfo.outBuffType, outOff, sliceSize);
115 0 : HCCL_INFO("[InsTempAllGatherMesh1DOpt] in:%s -> out:%s", src.Describe().c_str(), dst.Describe().c_str());
116 0 : auto ins = std::make_unique<InsLocalCopy>(src, dst);
117 0 : tempInsQue->Append(std::move(ins));
118 0 : }
119 0 : return HcclResult::HCCL_SUCCESS;
120 : }
121 :
122 0 : HcclResult InsTempAllGatherMesh1DOpt::LocalCopyToScratch(InsQuePtr tempInsQue)
123 : {
124 : u32 myAlgRank;
125 0 : CHK_RET(GetAlgRank(myRank_, tempVTopo_[0], myAlgRank));
126 0 : u64 sliceSize = ((myAlgRank == tempRankSize_ - 1) && (tempAlgParams_.tailSize != 0)) ? tempAlgParams_.tailSize :
127 : tempAlgParams_.sliceSize;
128 :
129 0 : if (opMode_ == OpMode::OPBASE) {
130 0 : for (u32 rpt = 0; rpt < tempAlgParams_.repeatNum; ++rpt) {
131 0 : const u64 scratchRepeatStride = tempAlgParams_.sliceSize * tempRankSize_;
132 0 : const u64 inBaseOff = tempAlgParams_.buffInfo.inBuffBaseOff + rpt * tempAlgParams_.inputRepeatStride;
133 0 : const u64 outBaseOff = tempAlgParams_.buffInfo.scratchBuffBaseOff + rpt * scratchRepeatStride;
134 0 : const u64 inOff = tempAlgParams_.inputSliceStride * myAlgRank + inBaseOff;
135 0 : const u64 outOff = tempAlgParams_.sliceSize * myAlgRank + outBaseOff;
136 :
137 0 : DataSlice src(tempAlgParams_.buffInfo.inBuffType, inOff, sliceSize);
138 0 : DataSlice dst(tempAlgParams_.buffInfo.scratBuffType, outOff, sliceSize);
139 0 : HCCL_INFO(
140 : "[InsTempAllGatherMesh1DOpt] in:%s -> scratch:%s", src.Describe().c_str(), dst.Describe().c_str());
141 :
142 0 : auto ins = std::make_unique<InsLocalCopy>(src, dst);
143 0 : tempInsQue->Append(std::move(ins));
144 0 : }
145 : }
146 0 : return HcclResult::HCCL_SUCCESS;
147 : }
148 :
149 0 : HcclResult InsTempAllGatherMesh1DOpt::RunMesh(
150 : const u32 myAlgRank, const std::vector<RankId>& vTopo, std::vector<InsQuePtr>& tempInsQues)
151 : {
152 0 : for (u32 rpt = 0; rpt < tempAlgParams_.repeatNum; ++rpt) {
153 0 : const u64 inBaseOff = tempAlgParams_.buffInfo.inBuffBaseOff + rpt * tempAlgParams_.inputRepeatStride;
154 0 : const u64 outBaseOff = tempAlgParams_.buffInfo.outBuffBaseOff + rpt * tempAlgParams_.outputRepeatStride;
155 0 : const u64 scratchRepeatStride = tempAlgParams_.sliceSize * tempRankSize_;
156 0 : const u64 scratchBase = tempAlgParams_.buffInfo.scratchBuffBaseOff + rpt * scratchRepeatStride;
157 :
158 0 : for (u32 queIdx = 0; queIdx < vTopo.size() - 1; queIdx++) {
159 0 : RankId connectedRank = vTopo[(myAlgRank + 1 + queIdx) % vTopo.size()];
160 :
161 0 : u32 connectedAlgRank = 0;
162 0 : CHK_RET(GetAlgRank(connectedRank, tempVTopo_[0], connectedAlgRank));
163 0 : auto it = tempLinks_.find(connectedRank);
164 0 : if (it == tempLinks_.end()) {
165 0 : HCCL_ERROR("[InsTempAllGatherMesh1DOpt] connectedRank does not exist");
166 0 : return HcclResult::HCCL_E_PARA;
167 : }
168 :
169 0 : u64 sendSliceSize = ((myAlgRank == tempRankSize_ - 1) && (tempAlgParams_.tailSize != 0)) ?
170 : tempAlgParams_.tailSize :
171 : tempAlgParams_.sliceSize;
172 0 : u64 recvSliceSize = ((connectedAlgRank == tempRankSize_ - 1) && (tempAlgParams_.tailSize != 0)) ?
173 : tempAlgParams_.tailSize :
174 : tempAlgParams_.sliceSize;
175 :
176 0 : CHK_PRT_RET(
177 : queIdx + 1 >= tempInsQues.size() || tempLinks_.at(connectedRank).empty(),
178 : HCCL_ERROR(
179 : "[InsTempAllGatherMesh1DOpt] queIdx=%u, tempInsQues.size=%u, connectedRank=%d, tempLinks_.size=%u",
180 : queIdx, tempInsQues.size(), connectedRank, tempLinks_.size()),
181 : HcclResult::HCCL_E_INTERNAL);
182 :
183 0 : InsQuePtr currQue = tempInsQues[queIdx + 1];
184 0 : LinkData& neighborLinkData = tempLinks_.at(connectedRank)[0];
185 :
186 0 : BufferType writeType = (opMode_ == OpMode::OPBASE) ? tempAlgParams_.buffInfo.scratBuffType :
187 0 : tempAlgParams_.buffInfo.inBuffType;
188 0 : HCCL_INFO("[InsTempAllGatherMesh1DOpt] offset cal");
189 0 : u64 txInOffset = tempAlgParams_.inputSliceStride * myAlgRank + inBaseOff;
190 0 : u64 txOutOffset = tempAlgParams_.outputSliceStride * myAlgRank + outBaseOff;
191 0 : u64 txScratchOffset = scratchBase + tempAlgParams_.sliceSize * myAlgRank;
192 0 : u64 txDstOffset = (opMode_ == OpMode::OPBASE) ? txScratchOffset : txOutOffset;
193 :
194 0 : u64 rxInOffset = tempAlgParams_.inputSliceStride * connectedAlgRank + inBaseOff;
195 0 : u64 rxOutOffset = tempAlgParams_.outputSliceStride * connectedAlgRank + outBaseOff;
196 0 : u64 rxScratchOffset = scratchBase + tempAlgParams_.sliceSize * connectedAlgRank;
197 0 : u64 rxSrcOffset = (opMode_ == OpMode::OPBASE) ? rxScratchOffset : rxInOffset;
198 :
199 0 : vector<DataSlice> txSrcSlices{DataSlice(tempAlgParams_.buffInfo.inBuffType, txInOffset, sendSliceSize)};
200 0 : vector<DataSlice> txDstSlices{DataSlice(writeType, txDstOffset, sendSliceSize)};
201 0 : vector<DataSlice> rxSrcSlices{DataSlice(writeType, rxSrcOffset, recvSliceSize)};
202 0 : vector<DataSlice> rxDstSlices{DataSlice(tempAlgParams_.buffInfo.outBuffType, rxOutOffset, recvSliceSize)};
203 :
204 0 : TxRxSlicesList sendRecvSlicesList({txSrcSlices, txDstSlices}, {rxSrcSlices, rxDstSlices});
205 0 : TxRxLinks sendRecvLinks(neighborLinkData, neighborLinkData);
206 0 : SendRecvInfo sendRecvInfo(sendRecvLinks, sendRecvSlicesList);
207 :
208 0 : CHK_PRT_RET(
209 : SendRecv(sendRecvInfo, currQue, 0, true, DmaMode::GET),
210 : HCCL_ERROR(
211 : "[InsTempAllGatherMesh1DOpt] sendrecv failed (nbr=%d, queIdx=%u, rpt=%u)", connectedRank, queIdx,
212 : rpt),
213 : HcclResult::HCCL_E_INTERNAL);
214 0 : }
215 : }
216 0 : return HcclResult::HCCL_SUCCESS;
217 : }
218 :
219 : } // namespace Hccl
|