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 : #ifndef COLL_ALG_COMM_H
12 : #define COLL_ALG_COMM_H
13 :
14 : #include <string>
15 : #include <vector>
16 : #include <map>
17 : #include <set>
18 : #include <unordered_set>
19 :
20 : #include "hccl_common.h"
21 : #include "hccl_types.h"
22 : #include "transport_pub.h"
23 : #include "stream_pub.h"
24 : #include "local_notify.h"
25 : #include "hccl_trace_info.h"
26 : #include "common.h"
27 : #include "threadManage.h"
28 : #include "template_v1_utils.h"
29 :
30 : namespace hccl {
31 : using RankId = u32;
32 :
33 : enum class OpMode {
34 : OFFLOAD = 0,
35 : OPBASE = 1
36 : };
37 :
38 : enum class DeviceMode {
39 : HOST = 0,
40 : AICPU = 1
41 : };
42 :
43 : enum class AlgExpansionMode {
44 : SUPERK_HOST = 0,
45 : SUPERK_AICPU = 1,
46 : SUPERK_AIV = 2,
47 : // SUPERK_CCU = 3,
48 : SUPERK_RECURSIVE = 4
49 : };
50 :
51 : enum class TransportStatus {
52 : INIT,
53 : READY,
54 : STOP
55 : };
56 :
57 : enum TransportMemType {
58 : CCL_INPUT = 0,
59 : CCL_OUTPUT,
60 : SCRATCH,
61 : PARAM_INPUT,
62 : PARAM_OUTPUT,
63 : AIV_INPUT,
64 : AIV_OUTPUT,
65 : USER_MEM,
66 : RESERVED
67 : };
68 :
69 : enum class TransportLinkType : int {
70 : RESERVED = -1,
71 : HCCS = 0,
72 : SIO = 1,
73 : RDMA = 2,
74 : MAX_NUM
75 : };
76 :
77 : struct TransportRequest {
78 : bool isValid = false;
79 : RankId localUserRank = 0;
80 : RankId remoteUserRank = 0;
81 : TransportMemType inputMemType = TransportMemType::RESERVED;
82 : TransportMemType outputMemType = TransportMemType::RESERVED;
83 : bool isUsedRdma = false;
84 : u32 notifyNum = 0;
85 : TransportLinkType linkType = TransportLinkType::RESERVED;
86 : };
87 :
88 : struct SingleSubCommTransport {
89 : std::vector<TransportRequest> transportRequests;
90 : std::vector<LINK> links;
91 : std::vector<TransportStatus> status; // 代表该transport是否ready, stop后为stop, 建链后为ready
92 : u64 taskNum = 0;
93 : std::map<u32, u32> userRank2subCommRank;
94 : std::map<u32, u32> subCommRank2UserRank;
95 : bool supportDataReceivedAck = false;
96 : LinkMode linkMode = LinkMode::LINK_DUPLEX_MODE;
97 : bool enableUseOneDoorbell = false;
98 : bool needVirtualLink = false; // for alltoall 多线程性能提升使用
99 : std::vector<LINK> virtualLinks; // for alltoall 多线程性能提升使用
100 : bool isZeroCopy = false;
101 : };
102 : using LevelNSubCommTransport = std::vector<SingleSubCommTransport>;
103 : using OpCommTransport = std::vector<LevelNSubCommTransport>;
104 :
105 : struct AlgResourceRequest {
106 : u64 scratchMemSize = 0;
107 : u32 streamNum = 0;
108 : u32 notifyNum = 0;
109 : u64 aivBufferRequest = 0;
110 : DeviceMode mode = DeviceMode::HOST; // 用于区分是host模式,还是aicpu模式
111 : OpCommTransport opTransport;
112 : bool isInGraphCaptureZeroCopy = false;
113 : void Describe()
114 : {
115 : HCCL_DEBUG("[AlgResourceRequest], scratchMemSize[%u], streamNum[%u], notifyNum[%u], aivBufferRequest[%llu], "
116 : "DeviceMode[%d].", scratchMemSize, streamNum, notifyNum, aivBufferRequest, mode);
117 : };
118 : };
119 :
120 : struct AlgResourceResponse {
121 : DeviceMem cclInputMem;
122 : DeviceMem cclOutputMem;
123 : DeviceMem paramInputMem;
124 : DeviceMem paramOutputMem;
125 : DeviceMem scratchMem;
126 : DeviceMem aivInputMem;
127 : DeviceMem aivOutputMem;
128 : DeviceMem aivCommInfoMem;
129 : std::vector<Stream> slaveStreams;
130 : std::vector<Stream> slaveDevStreams;
131 : std::vector<std::shared_ptr<LocalNotify> > notifiesMain; // Main Signals, 与Aux成对使用,大小等同于slaveStreams
132 : std::vector<std::shared_ptr<LocalNotify> > notifiesAux; // Auxiliary Signals, 与Main成对使用, 大小等同于slaveStreams
133 : std::vector<std::shared_ptr<LocalNotify> > notifiesDevMain; // 大小等同于slaveStreams
134 : std::vector<std::shared_ptr<LocalNotify> > notifiesDevAux; // 大小等同于slaveStreams
135 : OpCommTransport opTransportResponse; // 默认的Transport资源
136 : OpCommTransport opTransportResponseBackUp; // Transport备资源 (借轨场景使用)
137 : std::vector<std::shared_ptr<ThreadManage>> threadManage;
138 : };
139 :
140 : enum class BatchSendRecvCurMode {
141 : SEND = 0,
142 : RECV = 1,
143 : SEND_RECV = 2,
144 : SEND_RECV_RESERVED
145 : };
146 :
147 : struct OpParam {
148 : std::string tag = "";
149 : Stream stream;
150 : void* inputPtr = nullptr;
151 : u64 inputSize = 0;
152 : void* outputPtr = nullptr;
153 : u64 outputSize = 0;
154 : HcclReduceOp reduceType = HcclReduceOp::HCCL_REDUCE_RESERVED;
155 : SyncMode syncMode = SyncMode::DEFAULT_TIMEWAITSYNCMODE;
156 : RankId root = INVALID_VALUE_RANKID;
157 : RankId dstRank = 0;
158 : RankId srcRank = 0;
159 : bool aicpuUnfoldMode = false;
160 : uint8_t aicpuCacheEnable = 0;
161 : bool isCapture = false;
162 : HcclTraceInfo* opBaseAtraceInfo = nullptr;
163 : union {
164 : struct {
165 : u64 count;
166 : HcclDataType dataType;
167 : u64 strideCount;
168 : } DataDes = {0, HCCL_DATA_TYPE_RESERVED, 0};
169 : struct {
170 : void* counts;
171 : void* displs;
172 : HcclDataType dataType;
173 : } VDataDes;
174 : struct {
175 : HcclDataType sendType;
176 : HcclDataType recvType;
177 : u64 sendCount;
178 : u64 recvCount;
179 : void* sendCounts;
180 : void* recvCounts;
181 : void* sdispls;
182 : void* rdispls;
183 : void* sendCountMatrix;
184 : } All2AllDataDes;
185 : struct {
186 : HcclSendRecvItem* sendRecvItemsPtr;
187 : u32 itemNum;
188 : u32 curIterNum;
189 : BatchSendRecvCurMode curMode;
190 : u8* isDirectRemoteRank;
191 : } BatchSendRecvDataDes;
192 : struct {
193 : u32 itemNum;
194 : u32 queueNum;
195 : u32 queueIdx;
196 : } BatchWriteDataDes;
197 : };
198 : HcclCMDType opType = HcclCMDType::HCCL_CMD_INVALID;
199 : bool supportZeroCopy = false;
200 : bool isZeroCopy = false;
201 : u8 aclGraphZeroCopyEnable = 0; // 记录和传递外部配置参数aclGraphZeroCopyEnable
202 : bool supportRoceDirect = false; // AIV场景支持Roce直驱
203 : bool isNpuDirectRoce = false; // AIV场景使用Roce直驱标记位
204 : s32 aivTag = 0; // AIV场景使用的软同步标记位
205 : u32 index = 0;
206 : bool isInplaceError = false;
207 : u32 rankSize = 0;
208 : u32 aivCoreLimit = 0;
209 : u8 deterministic = 0;
210 : u32 srTag = 0;
211 : u32 localGroupRank = 0;
212 : bool isGroupMode = false;
213 : bool supportSymmetricMemory = false;
214 : void* inputSymWindow = nullptr;
215 : u64 inputOffset = 0;
216 : void* outputSymWindow = nullptr;
217 : u64 outputOffset = 0;
218 : bool needIncreLink = false;
219 :
220 102 : inline HcclDataType GetDataType() const
221 : {
222 102 : if (opType == HcclCMDType::HCCL_CMD_ALLGATHER_V || opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER_V) {
223 0 : return VDataDes.dataType;
224 : }
225 102 : return DataDes.dataType;
226 : }
227 61 : inline u64 GetDataCount(RankId rankId) const
228 : {
229 61 : if (opType == HcclCMDType::HCCL_CMD_ALLGATHER_V || opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER_V) {
230 0 : return static_cast<const u64 *>(VDataDes.counts)[rankId];
231 : }
232 61 : return DataDes.count;
233 : }
234 17 : inline u64 GetStrideCount() const
235 : {
236 17 : if (opType == HcclCMDType::HCCL_CMD_ALLGATHER_V || opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER_V) {
237 0 : return 0;
238 : }
239 17 : return DataDes.strideCount;
240 : }
241 : //重载<符号,用于map
242 0 : bool operator<(const OpParam &other) const noexcept {
243 0 : switch (opType) {
244 : //比较数据类型、数据量、通信域、可用核数、确定性、capture场景
245 0 : case HcclCMDType::HCCL_CMD_ALLGATHER:
246 0 : return std::tie(opType, DataDes.count, DataDes.dataType, tag, aivCoreLimit, deterministic, isCapture) <
247 0 : std::tie(other.opType, other.DataDes.count, other.DataDes.dataType, other.tag, other.aivCoreLimit, other.deterministic, other.isCapture);
248 0 : case HcclCMDType::HCCL_CMD_ALLTOALL:
249 0 : return std::tie(opType, All2AllDataDes.sendCount, All2AllDataDes.sendType,
250 0 : All2AllDataDes.recvCount, All2AllDataDes.recvType, tag, aivCoreLimit, deterministic, isCapture) <
251 0 : std::tie(other.opType, other.All2AllDataDes.sendCount, other.All2AllDataDes.sendType,
252 0 : other.All2AllDataDes.recvCount, other.All2AllDataDes.recvType, other.tag, other.aivCoreLimit, other.deterministic, other.isCapture);
253 0 : case HcclCMDType::HCCL_CMD_BROADCAST:
254 0 : return std::tie(opType, DataDes.count, DataDes.dataType, root, tag, aivCoreLimit, deterministic, isCapture) <
255 0 : std::tie(other.opType, other.DataDes.count, other.DataDes.dataType, other.root, other.tag, other.aivCoreLimit, other.deterministic, other.isCapture);
256 0 : case HcclCMDType::HCCL_CMD_ALLREDUCE:
257 : case HcclCMDType::HCCL_CMD_REDUCE_SCATTER:
258 0 : return std::tie(opType, DataDes.count, DataDes.dataType, reduceType, tag, aivCoreLimit, deterministic, isCapture) <
259 0 : std::tie(other.opType, other.DataDes.count, other.DataDes.dataType, other.reduceType, other.tag, other.aivCoreLimit, other.deterministic, other.isCapture);
260 0 : default:
261 0 : break;
262 : }
263 0 : return true;
264 : }
265 : };
266 :
267 : struct AlgDesc {
268 : bool isZeroCopy = false;
269 : bool isAivMode = false;
270 : bool isAivCrossNode = false;
271 : bool isLastSelect = false;
272 : s32 deterministic = -1; // -1:invalid,0:disable,1:enable,2:strict
273 : s32 aivTagNum = 1;
274 : AlgType algType;
275 : // executor所支持的各级算法,当vector为空时表示不校验,若外部传入的algType不支持,重定向为vector第一个元素
276 : // 由于默认算法要从列表里的第一个取,因此使用顺序确定的vector而非set
277 : std::vector<AlgTypeLevel0> level0SupportedAlgos;
278 : std::vector<AlgTypeLevel1> level1SupportedAlgos;
279 : std::vector<AlgTypeLevel2> level2SupportedAlgos;
280 : };
281 :
282 : struct ResourceLimit {
283 : bool ifLimit = false;
284 : bool ifCompileForAiv = false; // 图编译时选择AIV算法,不运行
285 : u32 aivCoreLimit = 0;
286 : };
287 :
288 : } // namespace hccl
289 : #endif
|