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 : using char_t = char;
38 :
39 : using HcclRtStream = void*;
40 : using HcclRtNotify = void*;
41 : using RdmaHandle = void*;
42 : using SocketHandle = void*;
43 : using FdHandle = void*;
44 : using QpHandle = void*;
45 : using HcclRtContext = void*;
46 : using HcclDispatcher = void*;
47 : using HcclRtEvent = void*;
48 : using HcclTraHandle = intptr_t;
49 : using MrHandle = void*;
50 :
51 : #if T_DESC("公共常量及宏", true)
52 : /* 未使用的参数声明 */
53 : #define UNUSED_PARAM(x) (void)(x)
54 : constexpr u32 INVALID_VALUE_RANKID = 0xFFFFFFFF; // rank id非法值
55 : constexpr u32 INVALID_VALUE_RANKSIZE = 0xFFFFFFFF; // rank size非法值
56 : constexpr u32 INVALID_SUBCOMM_ID = 0xFFFFFFFF; // 子通信域ID非法值
57 : constexpr u32 INVALID_UINT = 0xFFFFFFFF;
58 : constexpr u64 INVALID_U64 = 0xFFFFFFFFFFFFFFFF;
59 : constexpr s32 INVALID_INT = 0xFFFFFFFF;
60 : constexpr s64 INVALID_S64 = 0xFFFFFFFFFFFFFFFF;
61 : constexpr s32 INVALID_VALUE_STAGE = -1;
62 : constexpr u32 INVALID_QOSCFG = 0xFFFFFFFF;
63 : // 系统常用参数
64 : constexpr u64 SYS_MAX_COUNT = 0x7FFFFFFFF; // 系统当前支持的最大count数
65 : constexpr u32 HCCL_AISERVER_DEVICE_NUM = 8; // 单个Server 支持最大的设备数量
66 : constexpr u32 MAX_MODULE_DEVICE_NUM = 65; // 单server双模组时支持最大的设备数量
67 : constexpr u32 AICPU_ZERO_COPY_MAX_DEVICE_NUM_A3
68 : = 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 "
137 : "in advance";
138 : const std::string GET_SOCKET_TIMEOUT_REASON_WITHOUT_EVENT
139 : = "1. The communication operator types or parameters called by some ranks in a communicator are inconsistent. "
140 : "For example, some ranks call allreduce, while other ranks call broadcast."
141 : "2. The send recv operator depends on the ring."
142 : "You can check the peer dependency relationship of link establishment and the operator information in the plog "
143 : "logs "
144 : "to locate and analyze the fault. (You need to enable log recording using HCCL_ENTRY_LOG_ENABLE.) "
145 : "For details about the troubleshooting method, search for the keyword \"EI0006\" on "
146 : "https://www.hiascend.com/document/.";
147 :
148 : /* 对关键报错日志提供多级检索关键字 */
149 : /* 一级检索关键字 */
150 : const std::string LOG_KEYWORDS_TASK_EXEC = "TaskExecStage"; // 算子执行阶段异常
151 : const std::string LOG_KEYWORDS_INIT_GROUP = "InitGroupStage"; // 通信域初始化阶段异常
152 : const std::string LOG_KEYWORDS_INIT_CHANNEL = "InitChannelStage";
153 : const std::string LOG_KEYWORDS_LINK_INFO = "LinkInfo";
154 :
155 : /* 二级检索关键字 */
156 : const std::string LOG_KEYWORDS_TIMEOUT = "Timeout"; // 算子执行阶段超时
157 : const std::string LOG_KEYWORDS_RUN_FAILED = "RunFailed"; // 算子执行阶段失败,如SDMA ERROR
158 : const std::string LOG_KEYWORDS_HEARTBEAT_EVETN = "HeartbeatAbnormal"; // 算子执行阶段心跳异常事件
159 : const std::string LOG_KEYWORDS_ENV_CONFIG = "EnvConfig"; // 环境变量配置异常
160 : const std::string LOG_KEYWORDS_RANKTABLE_CONFIG = "RanktableConfig"; // ranktable读取失败
161 : const std::string LOG_KEYWORDS_RANKTABLE_CHECK = "RanktableCheck"; // ranktable校验失败
162 : const std::string LOG_KEYWORDS_RANKTABLE_DETECT = "RanktableDetect"; // ranktable协商失败
163 : const std::string LOG_KEYWORDS_PARAMETER_CONFLICT = "ParameterConflict"; // 参数不一致
164 : const std::string LOG_KEYWORDS_VERSION_CONFLICT = "VersionConflict"; // HCCL版本不一致
165 : const std::string LOG_KEYWORDS_INVALID_ARGUMENT = "InvalidArgument"; // 外部入参非法
166 : const std::string LOG_KEYWORDS_RESOURCE = "Resource";
167 : const std::string LOG_KEYWORDS_NOT_SUPPORTED = "Not Supported";
168 :
169 : /* 三级检索关键字 */
170 : const std::string LOG_KEYWORDS_HOST = "HOST";
171 : const std::string LOG_KEYWORDS_HOST_TS = "HOST_TS";
172 : const std::string LOG_KEYWORDS_AIV = "AIV";
173 : const std::string LOG_KEYWORDS_AICPU = "AICPU";
174 : const std::string LOG_KEYWORDS_CQE_ERROR = "CQE ERROR";
175 :
176 : /* 通信域及本卡信息关键字 */
177 : const std::string LOG_KEYWORDS_COMMUNICATOR = "Communicator Key Info";
178 : const std::string LOG_KEYWORDS_LOCALRANK = "LocalRank Key Info";
179 :
180 : constexpr u32 HETEROG_CCL_PORT = 16666; // 通信默认端口
181 : // host网卡相关参数
182 : constexpr u32 PORT_MIN = 0; // port最小值
183 : constexpr u32 PORT_MAX = 65535; // port最大值
184 : constexpr u32 HOST_CONTROL_BASE_PORT = 60000; // 控制面起始port
185 : constexpr u32 HOST_PARA_BASE_PORT = 60008; // 数据面起始port
186 : constexpr u32 HOST_PORT_MAX = 65520;
187 : #endif
188 :
189 : // 内存相关
190 : constexpr u64 LARGE_PAGE_MEMORY_MIN_SIZE = 2 * 1024 * 1024; // 申请内存用于MR注册时需要申请大页内存(最小2*1024*1024)
191 :
192 : /* 公共模块函数返回值定义,跟业务层同步 */
193 : const std::map<HcclDataType, std::string> HCOM_DATA_TYPE_STR_MAP{
194 : {HcclDataType::HCCL_DATA_TYPE_INT8, "int8"}, {HcclDataType::HCCL_DATA_TYPE_INT16, "int16"},
195 : {HcclDataType::HCCL_DATA_TYPE_INT32, "int32"}, {HcclDataType::HCCL_DATA_TYPE_INT64, "int64"},
196 : {HcclDataType::HCCL_DATA_TYPE_UINT64, "uint64"}, {HcclDataType::HCCL_DATA_TYPE_FP16, "float16"},
197 : {HcclDataType::HCCL_DATA_TYPE_FP32, "float32"}, {HcclDataType::HCCL_DATA_TYPE_UINT8, "uint8"},
198 : {HcclDataType::HCCL_DATA_TYPE_UINT16, "uint16"}, {HcclDataType::HCCL_DATA_TYPE_UINT32, "uint32"},
199 : {HcclDataType::HCCL_DATA_TYPE_FP64, "float64"}, {HcclDataType::HCCL_DATA_TYPE_BFP16, "bfloat16"},
200 : {HcclDataType::HCCL_DATA_TYPE_INT128, "int128"}, {HcclDataType::HCCL_DATA_TYPE_FP8E4M3, "fp8e4m3"},
201 : {HcclDataType::HCCL_DATA_TYPE_FP8E5M2, "fp8e5m2"}, {HcclDataType::HCCL_DATA_TYPE_RESERVED, "reserved"}};
202 :
203 950 : inline std::string GetDataTypeEnumStr(HcclDataType dataType)
204 : {
205 950 : auto iter = HCOM_DATA_TYPE_STR_MAP.find(dataType);
206 887 : if (iter == HCOM_DATA_TYPE_STR_MAP.end()) {
207 0 : return "HcclDataType(" + std::to_string(dataType) + ")";
208 : } else {
209 888 : return iter->second;
210 : }
211 : }
212 :
213 6 : inline std::string GetDataTypeEnumStr(u32 dataType)
214 : {
215 6 : auto hcclDataType = static_cast<HcclDataType>(dataType);
216 6 : return GetDataTypeEnumStr(hcclDataType);
217 : }
218 :
219 : const std::map<HcclReduceOp, std::string> HCOM_REDUCE_OP_STR_MAP{
220 : {HcclReduceOp::HCCL_REDUCE_SUM, "sum"},
221 : {HcclReduceOp::HCCL_REDUCE_PROD, "prod"},
222 : {HcclReduceOp::HCCL_REDUCE_MAX, "max"},
223 : {HcclReduceOp::HCCL_REDUCE_MIN, "min"},
224 : {HcclReduceOp::HCCL_REDUCE_RESERVED, "reserved"}};
225 :
226 262 : inline std::string GetReduceOpEnumStr(HcclReduceOp reduceOp)
227 : {
228 262 : auto iter = HCOM_REDUCE_OP_STR_MAP.find(reduceOp);
229 239 : if (iter == HCOM_REDUCE_OP_STR_MAP.end()) {
230 0 : return "HcclReduceOp(" + std::to_string(reduceOp) + ")";
231 : } else {
232 240 : return iter->second;
233 : }
234 : }
235 :
236 : constexpr u32 HCCL_LEVEL_ALGO_WIDTH = 8;
237 :
238 : // 参数平面位置
239 : enum class NICDeployment { NIC_DEPLOYMENT_HOST = 0, NIC_DEPLOYMENT_DEVICE, NIC_DEPLOYMENT_RESERVED };
240 :
241 : // server内link类型
242 : enum class LinkTypeInServer { HCCS_TYPE = 0, PXI_TYPE = 1, SIO_TYPE = 2, HCCS_SW_TYPE = 3, RESERVED_LINK_TYPE };
243 : // notifywait超时类型
244 : enum class SyncMode { DEFAULT_TIMEWAITSYNCMODE = 0, CONFIGURABLE_TIMEWAITSYNCMODE = 1, UNLIMITED_TIMEWAITSYNCMODE };
245 :
246 : // notifywait超时时间配置类型
247 : enum class HcclExecTimeoutSet {
248 : HCCL_EXEC_TIMEOUT_NOT_SET = 0,
249 : HCCL_EXEC_TIMEOUT_SET_BY_OPTIONS,
250 : HCCL_EXEC_TIMEOUT_SET_BY_ENV
251 : };
252 :
253 : using IpSocket = struct IpSocket {
254 : SocketHandle nicSocketHandle;
255 : RdmaHandle nicRdmaHandle;
256 : std::set<u32> listenedPort;
257 :
258 75 : IpSocket() : nicSocketHandle(nullptr), nicRdmaHandle(nullptr), listenedPort() {}
259 : };
260 : using RaResourceInfo = struct TagRaResourceInfo {
261 : std::map<hccl::HcclIpAddress, IpSocket> vnicSocketMap;
262 : std::map<hccl::HcclIpAddress, IpSocket> nicSocketMap;
263 : std::map<hccl::HcclIpAddress, IpSocket> hostNetSocketMap;
264 :
265 1743 : TagRaResourceInfo() {}
266 :
267 : TagRaResourceInfo(const TagRaResourceInfo& that)
268 : : vnicSocketMap(that.vnicSocketMap),
269 : nicSocketMap(that.nicSocketMap),
270 : hostNetSocketMap(that.hostNetSocketMap)
271 : {}
272 :
273 239 : TagRaResourceInfo& operator=(const TagRaResourceInfo& that)
274 : {
275 239 : if (&that != this) {
276 239 : vnicSocketMap = that.vnicSocketMap;
277 239 : nicSocketMap = that.nicSocketMap;
278 238 : hostNetSocketMap = that.hostNetSocketMap;
279 : }
280 238 : return *this;
281 : }
282 :
283 1711 : ~TagRaResourceInfo()
284 : {
285 1711 : vnicSocketMap.clear();
286 1709 : nicSocketMap.clear();
287 1709 : hostNetSocketMap.clear();
288 1709 : }
289 : };
290 :
291 : namespace hccl {
292 :
293 : /* 抽象链路信息 */
294 : enum class TransportType {
295 : TRANS_TYPE_IBV_EXP = 0,
296 : TRANS_TYPE_P2P = 1,
297 : TRANS_TYPE_DEVICE_P2P = 2,
298 : TRANS_TYPE_DEVICE_IBVERBS = 3,
299 : TRANS_TYPE_DEVICE_DIRECT = 4,
300 : TRANS_TYPE_RESERVED = 255,
301 : };
302 :
303 : class Referenced {
304 : public:
305 : // 初始化这个类,引用计数设为1,并且将p指向传入的地址
306 16169 : Referenced() : refCount(0) {}
307 :
308 130 : Referenced(const Referenced& other) : refCount(other.refCount.load()) {}
309 :
310 : // 引用计数加1
311 1562 : int Ref() { return ++refCount; }
312 :
313 : // 引用计数减1
314 2379 : int Unref() { return --refCount; }
315 :
316 : // 返回引用计数
317 5403 : int Count() const { return refCount; }
318 :
319 21 : int Clear()
320 : {
321 21 : refCount = 0;
322 21 : return refCount;
323 : }
324 : bool IsZero() const { return refCount == 0; }
325 15908 : ~Referenced() {}
326 :
327 : private:
328 : std::atomic<int> refCount; // 引用计数,表示有多少个变量引用这块内存
329 : };
330 :
331 : using RemoteRankInfo = struct TagRemoteRankInfo {
332 : s32 remoteDeviceId;
333 : u32 remoteRank;
334 : s32 remotePid;
335 : s32 remoteSdid;
336 : TagRemoteRankInfo()
337 : : remoteDeviceId(INVALID_INT),
338 : remoteRank(INVALID_UINT),
339 : remotePid(INVALID_INT),
340 : remoteSdid(INVALID_INT)
341 : {}
342 0 : TagRemoteRankInfo(s32 remoteDeviceId, u32 remoteRank)
343 0 : : remoteDeviceId(remoteDeviceId),
344 0 : remoteRank(remoteRank),
345 0 : remotePid(INVALID_INT),
346 0 : remoteSdid(INVALID_INT)
347 0 : {}
348 1 : TagRemoteRankInfo(s32 remoteDeviceId, u32 remoteRank, s32 remotePid)
349 1 : : remoteDeviceId(remoteDeviceId),
350 1 : remoteRank(remoteRank),
351 1 : remotePid(remotePid),
352 1 : remoteSdid(INVALID_INT)
353 1 : {}
354 0 : TagRemoteRankInfo(s32 remoteDeviceId, u32 remoteRank, s32 remotePid, s32 remoteSdid)
355 0 : : remoteDeviceId(remoteDeviceId),
356 0 : remoteRank(remoteRank),
357 0 : remotePid(remotePid),
358 0 : remoteSdid(remoteSdid)
359 0 : {}
360 : };
361 :
362 : enum class NotifyLoadType { HOST_NOTIFY = 0, DEVICE_NOTIFY };
363 : } // namespace hccl
364 :
365 : struct HcclSignalInfo {
366 : u64 resId; // 在代表event时为eventid,notify时为notifyid
367 : u64 addr;
368 : u32 devId;
369 : u32 tsId;
370 : u32 rankId;
371 : u32 flag;
372 : };
373 :
374 : struct HcclAicpuDispatcherInfo {
375 : u32 devId;
376 : u32 ssid;
377 : DevType devType = DevType::DEV_TYPE_COUNT;
378 : u64 overflowAddr;
379 : s64 chipId = INVALID_S64;
380 : };
381 :
382 : struct HcclComStreamInfo {
383 : int32_t actualStreamId; // 实际streamid
384 : int32_t sqId;
385 : uint32_t sqDepth;
386 : void* sqBaseAddr;
387 : u32 logicCqId; // 记录逻辑cqId
388 : };
389 :
390 : // offload P2P建链状态
391 : constexpr u32 HETEROG_P2P_SUCCESS = 0;
392 : constexpr u32 HETEROG_P2P_WAIT = 1;
393 : constexpr u32 HETEROG_P2P_FAILED = 2;
394 :
395 : constexpr s32 MAX_SCATTER_BUF_NUM = 64;
396 :
397 : enum class QPMode { INVALID = -1, NORMAL = 0, OFFLOAD = 1 };
398 :
399 : // 算子计数信息
400 : struct OpCounterInfo {
401 : u64 headCountMem = 0;
402 : u64 tailCountMem = 0;
403 : u64 addOneMem = 0;
404 : u32 memSize = 0;
405 : bool isEnableCounter = false;
406 : };
407 : #endif // HCCL_COMMON_H
|