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