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 "alg_data_trans_wrapper.h"
12 : #include "ins_temp_reduce_mesh_1D.h"
13 :
14 : namespace Hccl {
15 :
16 0 : InsTempReduceMesh1D::InsTempReduceMesh1D(
17 : const RankId virtualRank, const u32 tempRankSize, const std::vector<std::vector<RankId>>& tempVTopo,
18 0 : const std::map<RankId, u32>& tempVirtRankMap)
19 0 : : InsAlgTemplateBase(virtualRank, tempRankSize, tempVTopo, tempVirtRankMap)
20 0 : {}
21 :
22 0 : InsTempReduceMesh1D::~InsTempReduceMesh1D() {}
23 :
24 0 : HcclResult InsTempReduceMesh1D::CalcRes(AlgTempResReq& tempResReq)
25 : {
26 0 : HCCL_INFO("[InsTempReduceMesh1D] rank[%d] CalcRes start", myRank_);
27 :
28 0 : CHK_PRT_RET(tempRankSize_ == 0, HCCL_ERROR("[InsTempReduceMesh1D] rankSize is 0"), HcclResult::HCCL_E_INTERNAL);
29 :
30 0 : tempResReq.queNum = tempRankSize_;
31 0 : tempResReq.streamNum = tempResReq.queNum;
32 0 : tempResReq.queNotifys = CreateMasterSlaveQueNotifiesRequest(tempResReq.queNum);
33 0 : CHK_RET(CalcResLinksMesh(myRank_, tempRankSize_, tempVTopo_, linkNumBtwPeers_, tempResReq));
34 :
35 0 : HCCL_INFO(
36 : "[InsTempReduceMesh1D] rank[%d] CalcRes finished, need queNum[%u], queNotifyNum[%u], linkNum[%u]", myRank_,
37 : tempResReq.queNum, tempResReq.queNotifys.size(), tempResReq.links.size());
38 0 : return HcclResult::HCCL_SUCCESS;
39 : }
40 :
41 0 : u32 InsTempReduceMesh1D::CalcScratchMultiple(BufferType inBuffType, BufferType outBuffType) const
42 : {
43 : (void)inBuffType;
44 : (void)outBuffType;
45 :
46 0 : CHK_PRT_RET(tempRankSize_ == 0, HCCL_ERROR("[InsTempReduceMesh1D] rankSize is 0"), HcclResult::HCCL_E_INTERNAL);
47 :
48 0 : HCCL_INFO("[InsTempReduceMesh1D] rank[%d] scratch multiple is [%u]", myRank_, tempRankSize_);
49 0 : return tempRankSize_;
50 : }
51 :
52 0 : HcclResult InsTempReduceMesh1D::GenExtIns(
53 : const TempFuncs& tempFuncs, const TemplateDataParams& dataParams, const ResLinks& tempLinks,
54 : std::vector<InsQuePtr>& tempInsQues)
55 : {
56 0 : HCCL_INFO("[InsTempReduceMesh1D] rank[%d] GenExtIns start", myRank_);
57 :
58 : // 处理数据量为0场景
59 0 : if (dataParams.sliceSize == 0) {
60 0 : HCCL_INFO("[InsTempReduceMesh1D] sliceSize is 0, no need to process");
61 0 : return HcclResult::HCCL_SUCCESS;
62 : }
63 :
64 0 : CHK_PRT_RET(tempRankSize_ == 0, HCCL_ERROR("[InsTempReduceMesh1D] rankSize is 0"), HcclResult::HCCL_E_INTERNAL);
65 0 : CHK_PRT_RET(
66 : tempVTopo_.size() != 1,
67 : HCCL_ERROR("[InsTempReduceMesh1D] level num of vtopo need to be 1, current is [%zu]", tempVTopo_.size()),
68 : HcclResult::HCCL_E_INTERNAL);
69 0 : CHK_PRT_RET(
70 : tempVTopo_.at(0).size() != tempRankSize_,
71 : HCCL_ERROR(
72 : "[InsTempReduceMesh1D] rank num of level 0 in vtopo should be equal to rankSize[%u], current is [%zu]",
73 : tempRankSize_, tempVTopo_.at(0).size()),
74 : HcclResult::HCCL_E_INTERNAL);
75 0 : CHK_PRT_RET(root_ == INVALID_U32, HCCL_ERROR("[InsTempReduceMesh1D] root is invalid"), HcclResult::HCCL_E_INTERNAL);
76 :
77 0 : opMode_ = tempFuncs.opMode;
78 0 : buffInfo_ = dataParams.buffInfo;
79 :
80 0 : queNum_ = tempRankSize_;
81 0 : CHK_PRT_RET(
82 : tempInsQues.size() != queNum_,
83 : HCCL_ERROR("[InsTempReduceMesh1D] resource queNum[%zu] is invalid, need[%u]", tempInsQues.size(), queNum_),
84 : HcclResult::HCCL_E_INTERNAL);
85 :
86 0 : CHK_PRT_RET(
87 : tempVirtRankMap_.count(myRank_) == 0,
88 : HCCL_ERROR("[InsTempReduceMesh1D] rank[%d] is not in virtRankMap", myRank_), HcclResult::HCCL_E_INTERNAL);
89 0 : myIdx_ = tempVirtRankMap_.at(myRank_);
90 0 : CHK_PRT_RET(
91 : myIdx_ >= tempRankSize_,
92 : HCCL_ERROR(
93 : "[InsTempReduceMesh1D] rank idx[%u] in virtRankMap is invalid, it should be less than rankSize[%u]", myIdx_,
94 : tempRankSize_),
95 : HcclResult::HCCL_E_INTERNAL);
96 :
97 0 : CHK_RET(RunReduce(dataParams, tempLinks, tempInsQues));
98 :
99 0 : HCCL_INFO("[InsTempReduceMesh1D] rank[%d] GenExtIns finished", myRank_);
100 0 : return HcclResult::HCCL_SUCCESS;
101 : }
102 :
103 0 : HcclResult InsTempReduceMesh1D::RunReduce(
104 : const TemplateDataParams& dataParams, const ResLinks& tempLinks, std::vector<InsQuePtr>& tempInsQues)
105 : {
106 0 : if (u32(myRank_) == root_) {
107 : // 主从队列同步
108 0 : if (tempInsQues.size() > 1) {
109 0 : CHK_RET(PreSyncInterQueues(tempInsQues));
110 : }
111 : // Gather数据
112 0 : CHK_RET(GatherData(dataParams, tempLinks, tempInsQues));
113 : // 主从队列同步
114 0 : if (tempInsQues.size() > 1) {
115 0 : CHK_RET(PostSyncInterQueues(tempInsQues));
116 : }
117 : // 规约数据
118 0 : CHK_RET(ReduceData(dataParams, tempInsQues));
119 : } else {
120 : // Gather数据
121 0 : CHK_RET(SendData(dataParams, tempLinks, tempInsQues));
122 : }
123 :
124 0 : return HcclResult::HCCL_SUCCESS;
125 : }
126 :
127 0 : HcclResult InsTempReduceMesh1D::SendData(
128 : const TemplateDataParams& dataParams, const ResLinks& tempLinks, std::vector<InsQuePtr>& tempInsQues)
129 : {
130 0 : DataSlice srcDataSlice(buffInfo_.inBuffType, buffInfo_.inBuffBaseOff, dataParams.sliceSize);
131 :
132 0 : const LinkData& SendLink = tempLinks.at(root_).at(0);
133 :
134 0 : DataSlice dstDataSlice(buffInfo_.scratBuffType, dataParams.sliceSize * myIdx_, dataParams.sliceSize);
135 0 : SlicesList sendSlicesList({srcDataSlice}, {dstDataSlice});
136 0 : DataInfo sendInfo(SendLink, sendSlicesList);
137 :
138 0 : CHK_PRT_RET(
139 : Send(sendInfo, tempInsQues.at(0), 0, true, DmaMode::PUT), HCCL_ERROR("[InsTempReduceMesh1D] Send data failed"),
140 : HcclResult::HCCL_E_INTERNAL);
141 :
142 0 : return HcclResult::HCCL_SUCCESS;
143 0 : }
144 :
145 0 : HcclResult InsTempReduceMesh1D::GatherData(
146 : const TemplateDataParams& dataParams, const ResLinks& tempLinks, std::vector<InsQuePtr>& tempInsQues)
147 : {
148 0 : DataSlice srcDataSlice(buffInfo_.inBuffType, buffInfo_.inBuffBaseOff, dataParams.sliceSize);
149 :
150 : // 主流将数据从inBuff拷贝到outBuff
151 0 : if (buffInfo_.inBuffType != buffInfo_.outBuffType) {
152 0 : DataSlice dstCopySlice(buffInfo_.outBuffType, buffInfo_.inBuffBaseOff, dataParams.sliceSize);
153 0 : CHK_PRT_RET(
154 : LocalCopy(tempInsQues.at(0), srcDataSlice, dstCopySlice),
155 : HCCL_ERROR("[InsTempReduceMesh1D] LocalCopy failed"), HcclResult::HCCL_E_INTERNAL);
156 : }
157 :
158 : // 单卡场景做完LocalCopy就直接返回
159 0 : if (tempRankSize_ == 1) {
160 0 : HCCL_INFO("[InsTempReduceMesh1D] rankSize is 1, copy data from inBuff to outBuff and return");
161 0 : return HcclResult::HCCL_SUCCESS;
162 : }
163 :
164 : // 从流接收来自其它rank的数据
165 0 : u32 queId = 1;
166 0 : for (u32 idx = 0; idx < tempVTopo_.at(0).size(); ++idx) {
167 0 : if (idx == myIdx_) {
168 0 : continue;
169 : }
170 :
171 0 : RankId rmtRank = tempVTopo_.at(0).at(idx);
172 0 : const LinkData& recvLink = tempLinks.at(rmtRank).at(0);
173 :
174 0 : DataSlice dstDataSlice(buffInfo_.scratBuffType, dataParams.sliceSize * idx, dataParams.sliceSize);
175 0 : SlicesList recvSlicesList({srcDataSlice}, {dstDataSlice});
176 0 : DataInfo recvInfo(recvLink, recvSlicesList);
177 :
178 0 : CHK_PRT_RET(
179 : Recv(recvInfo, tempInsQues.at(queId), 0, true, DmaMode::PUT),
180 : HCCL_ERROR("[InsTempReduceMesh1D] Recv data failed"), HcclResult::HCCL_E_INTERNAL);
181 :
182 0 : queId++;
183 0 : }
184 :
185 0 : return HcclResult::HCCL_SUCCESS;
186 : }
187 :
188 0 : HcclResult InsTempReduceMesh1D::ReduceData(const TemplateDataParams& dataParams, std::vector<InsQuePtr>& tempInsQues)
189 : {
190 0 : if (tempRankSize_ == 1) {
191 : // 当rankSize为1时,数据已经拷贝至output,无需规约,直接返回
192 0 : return HcclResult::HCCL_SUCCESS;
193 : }
194 :
195 0 : DataSlice dstDataSlice(buffInfo_.outBuffType, buffInfo_.outBuffBaseOff, dataParams.sliceSize);
196 :
197 0 : for (u32 idx = 0; idx < tempVTopo_.at(0).size(); ++idx) {
198 0 : if (idx == myIdx_) {
199 0 : continue;
200 : }
201 :
202 0 : DataSlice srcDataSlice(buffInfo_.scratBuffType, dataParams.sliceSize * idx, dataParams.sliceSize);
203 0 : CHK_PRT_RET(
204 : LocalReduce(tempInsQues.at(0), srcDataSlice, dstDataSlice, dataType_, redOp_),
205 : HCCL_ERROR("[InsTempReduceMesh1D] Local reduce data failed"), HcclResult::HCCL_E_INTERNAL);
206 : }
207 :
208 0 : return HcclResult::HCCL_SUCCESS;
209 : }
210 :
211 : } // namespace Hccl
|