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 "coll_reduce_scatter_comm_executor.h"
12 : #include "alg_template_register.h"
13 :
14 : namespace hccl {
15 :
16 6 : CollReduceScatterCommExecutor::CollReduceScatterCommExecutor(
17 6 : const HcclDispatcher dispatcher, std::unique_ptr<TopoMatcher>& topoMatcher)
18 6 : : CollReduceScatterExecutor(dispatcher, topoMatcher)
19 : {
20 6 : desc_.deterministic = 1;
21 6 : DMAReduceFlag_ = false;
22 6 : }
23 :
24 12 : void CollReduceScatterCommExecutor::ParseParam(const OpParam& param)
25 : {
26 12 : tag_ = param.tag;
27 :
28 12 : if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
29 0 : scratchMemFlag_ = false;
30 : } else {
31 12 : scratchMemFlag_ = true;
32 : }
33 :
34 : // 记录图模式总数据量
35 12 : totalSize_ = topoAttr_.userRankSize * param.DataDes.count * SIZE_TABLE[param.DataDes.dataType];
36 12 : aicpuUnfoldMode_ = param.aicpuUnfoldMode;
37 12 : }
38 :
39 6 : HcclResult CollReduceScatterCommExecutor::CalcScratchMemSize(u64& scratchMemSize)
40 : {
41 6 : if (scratchMemFlag_) {
42 6 : if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
43 0 : scratchMemSize = inCCLbufferSize_;
44 : } else {
45 6 : scratchMemSize = totalSize_;
46 : }
47 : } else {
48 0 : scratchMemSize = 0U;
49 : }
50 :
51 6 : HCCL_INFO(
52 : "[CollReduceScatterCommExecutor][CalcScratchMemSize] tag[%s] scratchMemSize[%llu]", tag_.c_str(),
53 : scratchMemSize);
54 6 : return HCCL_SUCCESS;
55 : }
56 :
57 0 : bool CollReduceScatterCommExecutor::IsSmallData(const u64 totalSize, const u64 curSize)
58 : {
59 0 : return topoAttr_.deviceType == DevType::DEV_TYPE_910_93;
60 : }
61 :
62 6 : HcclResult CollReduceScatterCommExecutor::CalcCommInfo(std::vector<LevelNSubCommTransport>& opTransport)
63 : {
64 6 : TransportMemType inputType = TransportMemType::RESERVED;
65 6 : TransportMemType outputType = TransportMemType::RESERVED;
66 6 : CHK_RET(CalcTransportMemType(inputType, outputType));
67 6 : CHK_RET(CalcCombinedCommInfo(inputType, outputType, opTransport));
68 6 : return HCCL_SUCCESS;
69 : }
70 :
71 : HcclResult
72 6 : CollReduceScatterCommExecutor::CalcTransportMemType(TransportMemType& inputType, TransportMemType& outputType)
73 : {
74 6 : if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
75 0 : inputType = TransportMemType::CCL_INPUT;
76 0 : if (scratchMemFlag_) {
77 0 : outputType = TransportMemType::SCRATCH;
78 : } else {
79 0 : outputType = TransportMemType::CCL_OUTPUT;
80 : }
81 : } else {
82 6 : inputType = TransportMemType::PARAM_INPUT;
83 6 : if (scratchMemFlag_) {
84 6 : outputType = TransportMemType::SCRATCH;
85 : } else {
86 0 : outputType = TransportMemType::PARAM_OUTPUT;
87 : }
88 : }
89 6 : HCCL_INFO(
90 : "[CollReduceScatterCommExecutor][CalcTransportMemType] tag[%s] inputType[%d], outputType[%d]", tag_.c_str(),
91 : inputType, outputType);
92 6 : return HCCL_SUCCESS;
93 : }
94 :
95 6 : HcclResult CollReduceScatterCommExecutor::CalcCombinedCommInfo(
96 : TransportMemType inputType, TransportMemType outputType, std::vector<LevelNSubCommTransport>& opTransport)
97 : {
98 6 : CommPlane commPlane = COMM_COMBINE_ORDER;
99 :
100 6 : CommParaInfo commParaInfo(commPlane, CommType::COMM_TAG_MAX);
101 :
102 6 : if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR) {
103 0 : commParaInfo.commType = CommType::COMM_TAG_NONUNIFORM_HIERARCHICAL_RING;
104 6 : } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR_V1) {
105 0 : commParaInfo.commType = CommType::COMM_TAG_NONUNIFORM_HIERARCHICAL_RING_V1;
106 6 : } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB) {
107 0 : commParaInfo.commType = CommType::COMM_TAG_NONUNIFORM_BRUCK;
108 6 : } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_HD) {
109 0 : commParaInfo.commType = CommType::COMM_TAG_HALVING_DOUBLING;
110 : } else {
111 6 : commParaInfo.commType = CommType::COMM_TAG_RING_INNER;
112 : }
113 6 : CHK_RET(CalcCommPlaneInfo(tag_, commParaInfo, opTransport[commPlane], inputType, outputType));
114 :
115 6 : return HCCL_SUCCESS;
116 6 : }
117 :
118 0 : u64 CollReduceScatterCommExecutor::CalcLoopMaxCount(const u32 unitSize)
119 : {
120 : // 中转内存单次最多能够接受的output count
121 0 : u64 maxCountPerLoop
122 0 : = inCCLbufferSize_ / topoAttr_.userRankSize / HCCL_MIN_SLICE_ALIGN * HCCL_MIN_SLICE_ALIGN / unitSize;
123 0 : return maxCountPerLoop;
124 : }
125 :
126 0 : bool CollReduceScatterCommExecutor::IsHugeData(const u64 curSize, OpParam* param)
127 : {
128 0 : bool hugeData = (curSize * topoAttr_.userRankSize / HCCL_INTERNODE_MAX_DATA_RATE > RDMA_SEND_MAX_SIZE)
129 0 : || (curSize > SDMA_SEND_MAX_SIZE);
130 0 : return hugeData;
131 : }
132 :
133 6 : HcclResult CollReduceScatterCommExecutor::KernelRun(const OpParam& param, ExecMem& execMem)
134 : {
135 6 : HCCL_CONFIG_INFO(HCCL_ALG, "[%s] userRank[%u] starts.", __func__, topoAttr_.userRank);
136 6 : CommPlane commPlane = COMM_COMBINE_ORDER;
137 :
138 6 : CHK_RET(CheckCommSize(commPlane, COMM_INDEX_0 + 1));
139 6 : SubCommInfo combinedCommInfo = GetSubCommInfo(commPlane, COMM_INDEX_0);
140 :
141 6 : u64 reduceAttr = GetReduceAttr(execMem.inputMem, execMem.outputMem, param.DataDes.dataType, param.reduceType);
142 :
143 : // 构造ring algorithm对应的reduce-scatter实例
144 6 : std::unique_ptr<AlgTemplateBase> tempAlg;
145 6 : if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR) {
146 0 : tempAlg = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_NHR, dispatcher_);
147 0 : HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_NHR in COMM_COMBINE_ORDER", __func__);
148 0 : CHK_SMART_PTR_NULL(tempAlg);
149 0 : CHK_RET(tempAlg->Prepare(reduceAttr, false));
150 0 : CHK_RET(tempAlg->Prepare(
151 : execMem.inputMem, execMem.outputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType,
152 : param.stream, param.reduceType));
153 0 : if (topoAttr_.deviceType != DevType::DEV_TYPE_910_93 || algoAttr_.isSupportAtomicWrite) {
154 0 : tempAlg->CloseBarrier();
155 : }
156 0 : CHK_RET(RunTemplate(tempAlg, combinedCommInfo));
157 6 : } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR_V1) {
158 : tempAlg
159 0 : = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_NHR_V1, dispatcher_);
160 0 : HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_NHR_V1 in COMM_COMBINE_ORDER", __func__);
161 0 : CHK_SMART_PTR_NULL(tempAlg);
162 0 : CHK_RET(tempAlg->Prepare(reduceAttr));
163 0 : CHK_RET(tempAlg->Prepare(
164 : execMem.inputMem, execMem.outputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType,
165 : param.stream, param.reduceType));
166 0 : CHK_RET(RunTemplate(tempAlg, combinedCommInfo));
167 6 : } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB) {
168 0 : tempAlg = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_NB, dispatcher_);
169 0 : HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_NB in COMM_COMBINE_ORDER", __func__);
170 0 : CHK_SMART_PTR_NULL(tempAlg);
171 0 : CHK_RET(tempAlg->Prepare(reduceAttr));
172 0 : CHK_RET(tempAlg->Prepare(
173 : execMem.inputMem, execMem.outputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType,
174 : param.stream, param.reduceType));
175 0 : CHK_RET(RunTemplate(tempAlg, combinedCommInfo));
176 6 : } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_HD) {
177 0 : tempAlg = AlgTemplateRegistry::Instance().GetAlgTemplate(
178 0 : TemplateType::TEMPLATE_REDUCESCATTER_RECURSIVE_HD, dispatcher_);
179 0 : HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_RECURSIVE_HD in COMM_COMBINE_ORDER", __func__);
180 0 : CHK_SMART_PTR_NULL(tempAlg);
181 0 : CHK_RET(tempAlg->Prepare(reduceAttr));
182 0 : DeviceMem scratchMem = execMem.scratchMem.range(0, execMem.inputMem.size());
183 0 : u64 inputDataCount = execMem.inputMem.size() / SIZE_TABLE[param.DataDes.dataType];
184 0 : CHK_RET(tempAlg->Prepare(
185 : execMem.inputMem, execMem.inputMem, scratchMem, inputDataCount, param.DataDes.dataType, param.stream,
186 : param.reduceType, LEVEL0_BRIDGE_RANK_ID, std::vector<Slice>(0)));
187 0 : CHK_RET(RunTemplate(tempAlg, combinedCommInfo));
188 0 : u64 dataSize = execMem.count * SIZE_TABLE[param.DataDes.dataType];
189 0 : DeviceMem srcMem = execMem.inputMem.range(dataSize * topoAttr_.userRank, dataSize);
190 0 : DeviceMem dstMem = execMem.outputMem.range(0, dataSize);
191 0 : CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstMem, srcMem, const_cast<Stream&>(param.stream)));
192 0 : } else {
193 : tempAlg
194 6 : = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_RING, dispatcher_);
195 6 : HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_RING in COMM_COMBINE_ORDER", __func__);
196 6 : CHK_SMART_PTR_NULL(tempAlg);
197 6 : CHK_RET(tempAlg->Prepare(reduceAttr));
198 30 : CHK_RET(tempAlg->Prepare(
199 : execMem.inputMem, execMem.inputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType, param.stream,
200 : param.reduceType));
201 6 : CHK_RET(RunTemplate(tempAlg, combinedCommInfo));
202 : // 将cclInBuffer中与userRank_对应的部分拷贝至cclOutBuffer
203 6 : u64 dataSize = execMem.count * SIZE_TABLE[param.DataDes.dataType];
204 6 : DeviceMem srcMem = execMem.inputMem.range(dataSize * topoAttr_.userRank, dataSize);
205 6 : DeviceMem dstMem = execMem.outputMem.range(0, dataSize);
206 6 : CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstMem, srcMem, const_cast<Stream&>(param.stream)));
207 6 : }
208 6 : return HCCL_SUCCESS;
209 6 : }
210 :
211 : REGISTER_EXEC("ReduceScatterComm", ReduceScatterComm, CollReduceScatterCommExecutor);
212 : } // namespace hccl
|