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