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