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 HCCL_COMMON_H
12 : #define HCCL_COMMON_H
13 :
14 : #include <map>
15 : #include <set>
16 : #include <vector>
17 : #include <atomic>
18 : #include <climits>
19 : #include <queue>
20 : #include <string>
21 : #include <unordered_map>
22 : #include <algorithm>
23 :
24 : #include "dtype_common.h"
25 : #include "hccl_ip_address.h"
26 : #include "log.h"
27 : #include "hccl/hcom.h"
28 :
29 : #ifndef T_DESC
30 : #define T_DESC(_msg, _y) ((_y) ? true : false)
31 : #endif
32 :
33 : #ifndef HCCL_DEPRECATED
34 : #define HCCL_DEPRECATED(class) [[deprecated("Use "#class" instead")]]
35 : #endif
36 :
37 :
38 : using char_t = char;
39 :
40 : using HcclRtStream = void *;
41 : using HcclRtNotify = void *;
42 : using RdmaHandle = void *;
43 : using SocketHandle = void *;
44 : using FdHandle = void *;
45 : using QpHandle = void *;
46 : using HcclRtContext = void *;
47 : using HcclDispatcher = void *;
48 : using HcclRtEvent = void *;
49 : using HcclTraHandle = intptr_t;
50 : using MrHandle = void *;
51 :
52 : #if T_DESC("公共常量及宏", true)
53 : /* 未使用的参数声明 */
54 : #define UNUSED_PARAM(x) (void)(x)
55 : constexpr u32 INVALID_VALUE_RANKID = 0xFFFFFFFF; // rank id非法值
56 : constexpr u32 INVALID_VALUE_RANKSIZE = 0xFFFFFFFF; // rank size非法值
57 : constexpr u32 INVALID_SUBCOMM_ID = 0xFFFFFFFF; // 子通信域ID非法值
58 : constexpr u32 INVALID_UINT = 0xFFFFFFFF;
59 : constexpr u64 INVALID_U64 = 0xFFFFFFFFFFFFFFFF;
60 : constexpr s32 INVALID_INT = 0xFFFFFFFF;
61 : constexpr s64 INVALID_S64 = 0xFFFFFFFFFFFFFFFF;
62 : constexpr s32 INVALID_VALUE_STAGE = -1;
63 : constexpr u32 INVALID_QOSCFG = 0xFFFFFFFF;
64 : // 系统常用参数
65 : constexpr u64 SYS_MAX_COUNT = 0x7FFFFFFFF; // 系统当前支持的最大count数
66 : constexpr u32 HCCL_AISERVER_DEVICE_NUM = 8; // 单个Server 支持最大的设备数量
67 : constexpr u32 MAX_MODULE_DEVICE_NUM = 65; // 单server双模组时支持最大的设备数量
68 : constexpr u32 AICPU_ZERO_COPY_MAX_DEVICE_NUM_A3 = 32; // 零拷贝相关在A3场景上的最大设备数,影响外部组件使用,不能随意修改
69 : constexpr u32 HCCL_DEVICE_NIC_NUM = 3; // device网卡上最大的device ip数目,1个ipv4,ipv4自动转换的ipv6,用户配置的ipv6
70 : constexpr u32 HCCL_HOST_NIC_NUM = 1000; // host 支持最大的网卡数量
71 : constexpr int HCCL_DEVICE_MINNUM = 1;
72 : constexpr s32 HCCL_DEVICE_NOT_SET = -1; // device id 的无效值
73 : constexpr s32 HOST_DEVICE_ID = -1;
74 :
75 : constexpr int HCCL_MODULE_NUM_TWO = 2; // 910B A+X集群中 serverNum为1,moduleNum等于此数值时,要校验RDMA
76 : constexpr int HCCL_DEVICE_NUM_ONE = 1;
77 : constexpr int HCCL_DEVICE_NUM_TWO = 2; // 平均device num小于等于此数值时,无法通过HCCS链路类型接口判定当前硬件环境
78 : constexpr int HCCL_DEVICE_NUM_FOUR = 4; // 平均device num等于此数值时,需校验server内device选取合法性
79 : constexpr int HCCL_DEVICE_NUM_EIGHT = 8;
80 : constexpr u32 GROUP_NAME_MAX_LEN = 127; // 最大的group name 长度
81 : constexpr u32 RANK_TABLE_MAX_LEN = PATH_MAX - 1;
82 : constexpr u32 IDENTIFY_MAX_LEN = 127; // 最大的identify 长度
83 : constexpr s32 STRING_MAX_LENGTH = 40 * 1024 * 1024; // rankTable string length 40*1024*1024=40M.
84 : constexpr u64 DEVICE_MEMORY_MAX_ALLOC_SIZE = 16ULL * 1024 * 1024 * 1024; // device mmeory size 16GB
85 : constexpr int HCCL_BARRIER_DEFAULT_COUNT = 8;
86 : constexpr s32 NOTIFY_DEFAULT_WAIT_TIME = 27 * 68; // notifywait默认1836等待时长
87 : constexpr u32 NOTIFY_INVALID_WAIT_TIME = 0xFFFFFFFF; // notifywait时长非法值
88 : constexpr u32 HCCL_FFTS_CAPACITY = 65535; // FFTS+子图最大容量
89 : constexpr char HCCL_WORLD_GROUP[] = "hccl_world_group";
90 :
91 : // Notify时间增量数值
92 : constexpr u64 AICPU_H2D_TIMEOUT_INC = 27; // AICPU host-device同步的notify超时时间增量数值
93 : constexpr u64 AICPU_KERNEL_TIMEOUT_INC = 25; // AICPU kernel超时时间增量数值
94 : constexpr u64 AICPU_SQE_TIMEOUT_INC = 22; // AICPU 执行超时时间增量数值
95 : constexpr u64 AICPU_RTSQ_TIMEOUT_INC = 20; // AICPU 下发等待超时时间增量数值
96 :
97 : constexpr s64 HCCL_ALIGN_SIZE = 4096; // hccl 对齐方式, 按4KB来对齐
98 : constexpr s64 HCCL_WORKSPACE_MEM_32_KB = 32768; // hccl内存大小,暂定32KB
99 :
100 : constexpr u32 HCCP_SQ_TEMPLATE_CAPACITY = 12; // SQ模板深度为 12 个 wqe
101 : constexpr u64 CCL_COMM_INBUFFER_UNALIGNED_RESERVE_SIZE = (1 * 1024 * 1024); // 1 * 1024 * 1024, 即1M
102 :
103 : constexpr u32 MAX_FRAME_LEN = 2 * 1024; // 最大信息长度2*1024
104 :
105 : constexpr s32 NOTIFY_MAX_WAIT_TIME = 255 * 68; // 非910B和910_93场景notify wait最大等待时长,由硬件决定
106 : constexpr s32 NOTIFY_MAX_WAIT_TIME_910_93 = 2147483647; // 910B和910_93场景notify wait最大等待时长,由软件实现
107 :
108 : // HCCL QOS 与 SDMA QOS 映射级别
109 : constexpr uint32_t SDMA_QOS_LOW = 2;
110 : constexpr uint32_t SDMA_QOS_MIDDLE = 4;
111 : constexpr uint32_t SDMA_QOS_HIGH = 6;
112 :
113 : constexpr uint32_t SDMA_QOS_DEFAULT = 6;
114 :
115 : constexpr uint32_t HCCL_QOS_MIN = 0;
116 : constexpr uint32_t HCCL_QOS_LEVEL_1_LIMIT = 2;
117 : constexpr uint32_t HCCL_QOS_LEVEL_2_LIMIT = 4;
118 : constexpr uint32_t HCCL_QOS_LEVEL_3_LIMIT = 7;
119 :
120 : constexpr uint32_t HCCL_EXCHANGE_INFO_LEN = 2048; // HCCL一致性校验交换信息最大长度 socket底层约束2k
121 : /* error message相关 */
122 : /* EI0004 */
123 : const std::string RANKTABLE_PARSE_ERROR_REASON =
124 : "The rankTable file path does not exist, the permission is insufficient, or the JSON format is incorrect.";
125 : /* EI0006 */
126 : const std::string GET_SOCKET_TIMEOUT_REASON_CLOSE_DETECT =
127 : "Connection fault detection has been disabled. "\
128 : "1. The remote end does not initiate a connection request. some NPUs in the cluster are abnormal. "\
129 : "2. The remote end does not initiate a connection request because the collective communication operator is "\
130 : "started too late or is not started by some NPUs in the cluster. "\
131 : "3. The communication link is disconnected. (For example, the IP addresses are not on "\
132 : "the same network segment or the TLS configurations are inconsistent.)";
133 : const std::string GET_SOCKET_TIMEOUT_REASON_WITH_EVENT =
134 : "1. If the link setup timeout is reported on both ends, check the network connectivity between the two ends."\
135 : "2. If dstRank reports other exceptions, locate the cause based on the exception information of dstRank."\
136 : "3. If dstRank does not report any error, the possible cause is that the service process is suspended or exits in advance";
137 : const std::string GET_SOCKET_TIMEOUT_REASON_WITHOUT_EVENT =
138 : "1. The communication operator types or parameters called by some ranks in a communicator are inconsistent. "\
139 : "For example, some ranks call allreduce, while other ranks call broadcast."\
140 : "2. The send recv operator depends on the ring."\
141 : "You can check the peer dependency relationship of link establishment and the operator information in the plog logs "\
142 : "to locate and analyze the fault. (You need to enable log recording using HCCL_ENTRY_LOG_ENABLE.) "\
143 : "For details about the troubleshooting method, search for the keyword \"EI0006\" on "\
144 : "https://www.hiascend.com/document/.";
145 :
146 : /* 对关键报错日志提供多级检索关键字 */
147 : /* 一级检索关键字 */
148 : const std::string LOG_KEYWORDS_TASK_EXEC = "TaskExecStage"; // 算子执行阶段异常
149 : const std::string LOG_KEYWORDS_INIT_GROUP = "InitGroupStage"; // 通信域初始化阶段异常
150 : const std::string LOG_KEYWORDS_INIT_CHANNEL = "InitChannelStage";
151 : const std::string LOG_KEYWORDS_LINK_INFO = "LinkInfo";
152 :
153 : /* 二级检索关键字 */
154 : const std::string LOG_KEYWORDS_TIMEOUT = "Timeout"; // 算子执行阶段超时
155 : const std::string LOG_KEYWORDS_RUN_FAILED = "RunFailed"; // 算子执行阶段失败,如SDMA ERROR
156 : const std::string LOG_KEYWORDS_HEARTBEAT_EVETN = "HeartbeatAbnormal"; // 算子执行阶段心跳异常事件
157 : const std::string LOG_KEYWORDS_ENV_CONFIG = "EnvConfig"; // 环境变量配置异常
158 : const std::string LOG_KEYWORDS_RANKTABLE_CONFIG = "RanktableConfig"; // ranktable读取失败
159 : const std::string LOG_KEYWORDS_RANKTABLE_CHECK = "RanktableCheck"; // ranktable校验失败
160 : const std::string LOG_KEYWORDS_RANKTABLE_DETECT = "RanktableDetect"; // ranktable协商失败
161 : const std::string LOG_KEYWORDS_PARAMETER_CONFLICT = "ParameterConflict"; // 参数不一致
162 : const std::string LOG_KEYWORDS_VERSION_CONFLICT = "VersionConflict"; // HCCL版本不一致
163 : const std::string LOG_KEYWORDS_INVALID_ARGUMENT= "InvalidArgument"; // 外部入参非法
164 : const std::string LOG_KEYWORDS_RESOURCE = "Resource";
165 : const std::string LOG_KEYWORDS_NOT_SUPPORTED = "Not Supported";
166 :
167 : /* 三级检索关键字 */
168 : const std::string LOG_KEYWORDS_HOST = "HOST";
169 : const std::string LOG_KEYWORDS_HOST_TS = "HOST_TS";
170 : const std::string LOG_KEYWORDS_AIV = "AIV";
171 : const std::string LOG_KEYWORDS_AICPU = "AICPU";
172 : const std::string LOG_KEYWORDS_CQE_ERROR = "CQE ERROR";
173 :
174 : /* 通信域及本卡信息关键字 */
175 : const std::string LOG_KEYWORDS_COMMUNICATOR = "Communicator Key Info";
176 : const std::string LOG_KEYWORDS_LOCALRANK = "LocalRank Key Info";
177 :
178 : constexpr u32 HETEROG_CCL_PORT = 16666; // 通信默认端口
179 : // host网卡相关参数
180 : constexpr u32 PORT_MIN = 0; // port最小值
181 : constexpr u32 PORT_MAX = 65535; // port最大值
182 : constexpr u32 HOST_CONTROL_BASE_PORT = 60000; // 控制面起始port
183 : constexpr u32 HOST_PARA_BASE_PORT = 60008; // 数据面起始port
184 : constexpr u32 HOST_PORT_MAX = 65520;
185 : #endif
186 :
187 : // 内存相关
188 : constexpr u64 LARGE_PAGE_MEMORY_MIN_SIZE = 2*1024*1024; // 申请内存用于MR注册时需要申请大页内存(最小2*1024*1024)
189 :
190 :
191 : /* 公共模块函数返回值定义,跟业务层同步 */
192 : const std::map<HcclDataType, std::string> HCOM_DATA_TYPE_STR_MAP{
193 : {HcclDataType::HCCL_DATA_TYPE_INT8, "int8"},
194 : {HcclDataType::HCCL_DATA_TYPE_INT16, "int16"},
195 : {HcclDataType::HCCL_DATA_TYPE_INT32, "int32"},
196 : {HcclDataType::HCCL_DATA_TYPE_INT64, "int64"},
197 : {HcclDataType::HCCL_DATA_TYPE_UINT64, "uint64"},
198 : {HcclDataType::HCCL_DATA_TYPE_FP16, "float16"},
199 : {HcclDataType::HCCL_DATA_TYPE_FP32, "float32"},
200 : {HcclDataType::HCCL_DATA_TYPE_UINT8, "uint8"},
201 : {HcclDataType::HCCL_DATA_TYPE_UINT16, "uint16"},
202 : {HcclDataType::HCCL_DATA_TYPE_UINT32, "uint32"},
203 : {HcclDataType::HCCL_DATA_TYPE_FP64, "float64"},
204 : {HcclDataType::HCCL_DATA_TYPE_BFP16, "bfloat16"},
205 : {HcclDataType::HCCL_DATA_TYPE_INT128, "int128"},
206 : {HcclDataType::HCCL_DATA_TYPE_FP8E4M3, "fp8e4m3"},
207 : {HcclDataType::HCCL_DATA_TYPE_FP8E5M2, "fp8e5m2"},
208 : {HcclDataType::HCCL_DATA_TYPE_RESERVED, "reserved"}
209 : };
210 :
211 954 : inline std::string GetDataTypeEnumStr(HcclDataType dataType)
212 : {
213 954 : auto iter = HCOM_DATA_TYPE_STR_MAP.find(dataType);
214 885 : if (iter == HCOM_DATA_TYPE_STR_MAP.end()) {
215 0 : return "HcclDataType(" + std::to_string(dataType) + ")";
216 : } else {
217 889 : return iter->second;
218 : }
219 : }
220 :
221 6 : inline std::string GetDataTypeEnumStr(u32 dataType)
222 : {
223 6 : auto hcclDataType = static_cast<HcclDataType>(dataType);
224 6 : return GetDataTypeEnumStr(hcclDataType);
225 : }
226 :
227 : const std::map<HcclReduceOp, std::string> HCOM_REDUCE_OP_STR_MAP{
228 : {HcclReduceOp::HCCL_REDUCE_SUM, "sum"},
229 : {HcclReduceOp::HCCL_REDUCE_PROD, "prod"},
230 : {HcclReduceOp::HCCL_REDUCE_MAX, "max"},
231 : {HcclReduceOp::HCCL_REDUCE_MIN, "min"},
232 : {HcclReduceOp::HCCL_REDUCE_RESERVED, "reserved"}
233 : };
234 :
235 256 : inline std::string GetReduceOpEnumStr(HcclReduceOp reduceOp)
236 : {
237 256 : auto iter = HCOM_REDUCE_OP_STR_MAP.find(reduceOp);
238 235 : if (iter == HCOM_REDUCE_OP_STR_MAP.end()) {
239 0 : return "HcclReduceOp(" + std::to_string(reduceOp) + ")";
240 : } else {
241 236 : return iter->second;
242 : }
243 : }
244 :
245 : constexpr u32 HCCL_LEVEL_ALGO_WIDTH = 8;
246 :
247 : // 参数平面位置
248 : enum class NICDeployment {
249 : NIC_DEPLOYMENT_HOST = 0,
250 : NIC_DEPLOYMENT_DEVICE,
251 : NIC_DEPLOYMENT_RESERVED
252 : };
253 :
254 : // server内link类型
255 : enum class LinkTypeInServer {
256 : HCCS_TYPE = 0,
257 : PXI_TYPE = 1,
258 : SIO_TYPE = 2,
259 : HCCS_SW_TYPE = 3,
260 : RESERVED_LINK_TYPE
261 : };
262 : // notifywait超时类型
263 : enum class SyncMode {
264 : DEFAULT_TIMEWAITSYNCMODE = 0,
265 : CONFIGURABLE_TIMEWAITSYNCMODE = 1,
266 : UNLIMITED_TIMEWAITSYNCMODE
267 : };
268 :
269 : // notifywait超时时间配置类型
270 : enum class HcclExecTimeoutSet {
271 : HCCL_EXEC_TIMEOUT_NOT_SET = 0,
272 : HCCL_EXEC_TIMEOUT_SET_BY_OPTIONS,
273 : HCCL_EXEC_TIMEOUT_SET_BY_ENV
274 : };
275 :
276 : using IpSocket = struct IpSocket {
277 : SocketHandle nicSocketHandle;
278 : RdmaHandle nicRdmaHandle;
279 : std::set<u32> listenedPort;
280 :
281 75 : IpSocket() : nicSocketHandle(nullptr), nicRdmaHandle(nullptr), listenedPort()
282 : {
283 75 : }
284 : };
285 : using RaResourceInfo = struct TagRaResourceInfo {
286 : std::map<hccl::HcclIpAddress, IpSocket> vnicSocketMap;
287 : std::map<hccl::HcclIpAddress, IpSocket> nicSocketMap;
288 : std::map<hccl::HcclIpAddress, IpSocket> hostNetSocketMap;
289 :
290 1563 : TagRaResourceInfo()
291 1563 : {
292 1562 : }
293 :
294 : TagRaResourceInfo(const TagRaResourceInfo &that) : vnicSocketMap(that.vnicSocketMap),
295 : nicSocketMap(that.nicSocketMap), hostNetSocketMap(that.hostNetSocketMap)
296 : {
297 : }
298 :
299 251 : TagRaResourceInfo &operator=(const TagRaResourceInfo &that)
300 : {
301 251 : if (&that != this) {
302 251 : vnicSocketMap = that.vnicSocketMap;
303 251 : nicSocketMap = that.nicSocketMap;
304 251 : hostNetSocketMap = that.hostNetSocketMap;
305 : }
306 251 : return *this;
307 : }
308 :
309 1530 : ~TagRaResourceInfo()
310 : {
311 1530 : vnicSocketMap.clear();
312 1530 : nicSocketMap.clear();
313 1529 : hostNetSocketMap.clear();
314 1530 : }
315 : };
316 :
317 : namespace hccl {
318 :
319 : /* 抽象链路信息 */
320 : enum class TransportType {
321 : TRANS_TYPE_IBV_EXP = 0,
322 : TRANS_TYPE_P2P = 1,
323 : TRANS_TYPE_DEVICE_P2P = 2,
324 : TRANS_TYPE_DEVICE_IBVERBS = 3,
325 : TRANS_TYPE_DEVICE_DIRECT = 4,
326 : TRANS_TYPE_RESERVED = 255,
327 : };
328 :
329 : class Referenced {
330 : public:
331 : // 初始化这个类,引用计数设为1,并且将p指向传入的地址
332 14219 : Referenced(): refCount(0) {}
333 :
334 130 : Referenced(const Referenced& other): refCount(other.refCount.load()) {}
335 :
336 : // 引用计数加1
337 1555 : int Ref()
338 : {
339 1555 : return ++refCount;
340 : }
341 :
342 : // 引用计数减1
343 2309 : int Unref()
344 : {
345 2309 : return --refCount;
346 : }
347 :
348 : // 返回引用计数
349 4888 : int Count() const
350 : {
351 4888 : return refCount;
352 : }
353 :
354 20 : int Clear()
355 : {
356 20 : refCount = 0;
357 20 : return refCount;
358 : }
359 : bool IsZero() const
360 : {
361 : return refCount == 0;
362 : }
363 13958 : ~Referenced() {}
364 : private:
365 : std::atomic<int> refCount; // 引用计数,表示有多少个变量引用这块内存
366 : };
367 :
368 : using RemoteRankInfo = struct TagRemoteRankInfo {
369 : s32 remoteDeviceId;
370 : u32 remoteRank;
371 : s32 remotePid;
372 : s32 remoteSdid;
373 : TagRemoteRankInfo()
374 : : remoteDeviceId(INVALID_INT), remoteRank(INVALID_UINT), remotePid(INVALID_INT), remoteSdid(INVALID_INT) {}
375 0 : TagRemoteRankInfo(s32 remoteDeviceId, u32 remoteRank)
376 0 : : remoteDeviceId(remoteDeviceId), remoteRank(remoteRank), remotePid(INVALID_INT), remoteSdid(INVALID_INT) {}
377 1 : TagRemoteRankInfo(s32 remoteDeviceId, u32 remoteRank, s32 remotePid)
378 1 : : remoteDeviceId(remoteDeviceId), remoteRank(remoteRank), remotePid(remotePid), remoteSdid(INVALID_INT) {}
379 0 : TagRemoteRankInfo(s32 remoteDeviceId, u32 remoteRank, s32 remotePid, s32 remoteSdid)
380 0 : : remoteDeviceId(remoteDeviceId), remoteRank(remoteRank), remotePid(remotePid), remoteSdid(remoteSdid) {}
381 : };
382 :
383 : enum class NotifyLoadType {
384 : HOST_NOTIFY = 0,
385 : DEVICE_NOTIFY
386 : };
387 : } // namespace hccl
388 :
389 : struct HcclSignalInfo {
390 : u64 resId; // 在代表event时为eventid,notify时为notifyid
391 : u64 addr;
392 : u32 devId;
393 : u32 tsId;
394 : u32 rankId;
395 : u32 flag;
396 : };
397 :
398 : struct HcclAicpuDispatcherInfo {
399 : u32 devId;
400 : u32 ssid;
401 : DevType devType = DevType::DEV_TYPE_COUNT;
402 : u64 overflowAddr;
403 : s64 chipId = INVALID_S64;
404 : };
405 :
406 : struct HcclComStreamInfo {
407 : int32_t actualStreamId; // 实际streamid
408 : int32_t sqId;
409 : uint32_t sqDepth;
410 : void *sqBaseAddr;
411 : u32 logicCqId; // 记录逻辑cqId
412 : };
413 :
414 : // offload P2P建链状态
415 : constexpr u32 HETEROG_P2P_SUCCESS = 0;
416 : constexpr u32 HETEROG_P2P_WAIT = 1;
417 : constexpr u32 HETEROG_P2P_FAILED = 2;
418 :
419 : constexpr s32 MAX_SCATTER_BUF_NUM = 64;
420 :
421 : enum class QPMode {
422 : INVALID = -1,
423 : NORMAL = 0,
424 : OFFLOAD = 1
425 : };
426 :
427 : // 算子计数信息
428 : struct OpCounterInfo {
429 : u64 headCountMem = 0;
430 : u64 tailCountMem = 0;
431 : u64 addOneMem = 0;
432 : u32 memSize = 0;
433 : bool isEnableCounter = false;
434 : };
435 : #endif // HCCL_COMMON_H
|