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 __AICPU_KFC_DEF_H__
12 : #define __AICPU_KFC_DEF_H__
13 :
14 : #include <cstdint>
15 : #include <chrono>
16 : #include "common/aicpu_hccl_def.h"
17 : #include "hccl_common.h"
18 : #include "hccl_msg.h"
19 : #include "aicpu_operator_pub.h"
20 :
21 : constexpr int32_t AICPU_CNT = 8;
22 : constexpr int32_t CLUSTER_CNT = 2;
23 : constexpr u64 HCCL_COPY_ALIGN = 16 * 1024;
24 : constexpr u64 HCCL_MIN_SLICE_ALIGN = 128;
25 : constexpr u32 AC_DEFAULT_ONE_SHOT_SIZE = 100 * 1024; // 缺省小于100K使用oneshot算法
26 : constexpr s32 AC_ERROR_INVALID_PARAM = 0x011088;
27 : constexpr u32 AICPU_OP_NOTIFY_NUM = 2U;
28 : constexpr u32 AC_SQE_SIZE = 64U;
29 : constexpr u32 AC_DEFAULT_WINDOW_DIM = 2; // 小数据量时分2片做swap window使用,可以提前把下一次内容拷贝到window中
30 : constexpr u32 AC_DEFAULT_RANK_GROUP = 2;
31 : constexpr u32 HCCL_SMALL_COUNT_1_M = 1024 * 1024;
32 : constexpr u32 HCCL_SMALL_COUNT_256K = 256 * 1024; // 256KB: 256 * 1024
33 : constexpr uint8_t MC2_DEBUG_ONLY_CUBE = 1; // 只计算不通信
34 : constexpr uint8_t MC2_DEBUG_PRINT_MSG = 2;
35 : constexpr uint8_t MC2_DEBUG_PRINT_BUFF = 3;
36 : constexpr uint8_t MC2_DEBUG_TIME_TAKEN = 4; // KFC算子自己统计各阶段耗时
37 : constexpr uint8_t MC2_DEBUG_WAIT_COMM = 8; // KFC算子等待通信结束
38 : constexpr uint8_t MC2_DEBUG_PREPARE_TIMEOUT = 250;
39 : constexpr uint8_t MC2_DEBUG_COMMIT_TIMEOUT = 251;
40 : constexpr uint8_t MC2_DEBUG_NOTIFY_WAIT_TIMEOUT = 252;
41 : constexpr uint8_t MC2_DEBUG_AICORE_WAIT_TIMEOUT = 253;
42 : constexpr uint8_t MC2_DEBUG_FINALIZE_TIMEOUT = 254;
43 : constexpr uint8_t MC2_DEBUG_SDMA_ERROR = 255;
44 : constexpr uint64_t MC2_API_MSG_TIMEOUT = 20UL;
45 : constexpr uint32_t MC2_API_XORCHECK_PRINT_NUM = 10000;
46 : const uint16_t TAIL_TASK = 1;
47 : const uint16_t HEAD_TASK = 0;
48 : constexpr int32_t MAX_COMM_CTX_NUM = 3;
49 : constexpr int32_t LOCAL = 0;
50 : constexpr int32_t REMOTE = 1;
51 : constexpr uint16_t MAX_BATCH_WRITE_THREAD_NUM = 2;
52 :
53 : constexpr uint8_t FLAG_OFFSET = 1;
54 : constexpr uint8_t FLAG_INTERVAL = 2;
55 : constexpr uint8_t POST_SEND_FLAG_COUNT = 3;
56 : constexpr u64 MAX_RDMA_WQE_SIZE = 2ULL * 1024 * 1024 * 1024; // RDMA最大WQE限制是2GB
57 :
58 : using HcclHandle = int8_t;
59 :
60 : enum CommAlgType {
61 : COMM_ALG_DEFAULT = 0,
62 : COMM_ALG_FULL_MESH = 1,
63 : COMM_ALG_DOUBLE_RING = 2,
64 : COMM_ALG_SWITCH_WING = 3,
65 : COMM_ALG_RESERVED
66 : };
67 :
68 : enum MC2_BUFFER_TYPE {
69 : MC2_BUFFER_TYPE_DEFAULT = 0,
70 : MC2_BUFFER_TYPE_OUTPUT,
71 : MC2_BUFFER_TYPE_WINDOW_IN,
72 : MC2_BUFFER_TYPE_WINDOW_OUT,
73 : MC2_BUFFER_TYPE_WORKSPACE,
74 : MC2_BUFFER_TYPE_INPUT,
75 : MC2_BUFFER_TYPE_COMMOUT,
76 : MC2_BUFFER_TYPE_END
77 : };
78 :
79 : enum AicpuTilingVer {
80 : TILING_DATA_VER_OLD_FOR_HOST = 0,
81 : TILING_DATA_VER_OLD_FOR_KERNEL,
82 : TILING_DATA_VER_OLD_FOR_KERNEL_V2,
83 : TILING_DATA_VER_FOR_TILING_API = 100
84 : };
85 :
86 : struct KFCGroupTilingDataAuto { // for grouped_mat_mul_all_reduce op
87 : HcclKFCTilingData msg[64]; // 64: same as the tiling data size
88 : uint32_t groupNum;
89 : uint32_t groupTilingMagicNum;
90 : };
91 :
92 : struct KFCGroupTilingData { // for grouped_mat_mul_all_reduce op
93 : uint32_t groupNum;
94 : uint32_t reserve;
95 : HcclKFCTilingData msg[64]; // 64: same as the tiling data size
96 : };
97 :
98 : struct KFCTask {
99 : u64 inputA; // A矩阵地址,通信在前时为sendbuffer
100 : u64 outputC; // 输出C矩阵地址
101 : u64 commOut; // 双输出时,通信输出地址
102 : u64 context; // HCCL通信context
103 : u64 workSpace; // 通信结果不直接输出时,放到workspace中
104 : u64 tilingData; // 通信
105 : };
106 :
107 : struct KFCTaskV2 {
108 : u64 inputA; // A矩阵地址,通信在前时为sendbuffer
109 : u64 outputC; // 输出C矩阵地址
110 : u64 commOut; // 双输出时,通信输出地址
111 : u64 ctxNum;
112 : u64 context[MAX_COMM_CTX_NUM]; // HCCL通信context
113 : u64 workSpace; // 通信结果不直接输出时,放到workspace中
114 : u64 tilingData; // 通信
115 : };
116 :
117 : struct KFCResInitTask {
118 : u64 context; // A矩阵地址,通信在前时为sendbuffer
119 : bool isCustom;
120 : };
121 :
122 : struct PostSendTaskParam {
123 : // For DataCopy
124 : u32 lKey;
125 : u32 rKey;
126 : HcclQpInfoV2 qpInfo;
127 : u64 remoteAddr;
128 : u64 localAddr;
129 : u64 dataSize;
130 :
131 : u64 timeOut;
132 :
133 : // For Flag
134 : u64 localFlagAddr;
135 : u64 remoteFlagAddr;
136 : u32 lfKey;
137 : u32 rfKey;
138 : };
139 :
140 : struct CommonHcclMsg {
141 : HcclCMDType commType; // 通信原语类型,AllReduce/AllGather.../Finalize/InterHcclGroupSync
142 : HcclReduceOp opType; // reduce操作类型,sum/prod/max/min
143 : uint64_t sendBuffer; // 源数据buffer地址。
144 : uint64_t recvBuffer; // 目的数据buffer地址
145 : uint64_t dataCnt; // 参与操作的数据个数
146 : uint64_t
147 : strideCount; // 完整的数据结果一般是连续的,切分多轮后会导致需要加上stride,例如AllGather的stride是每个卡上的完整数据量
148 : HcclDataType hcclDataType; // 参与操作的数据类型
149 : uint32_t p2pSrcDestRankId; // 点对点通信send/recv对端的rankId,send中的destRank, recv中的srcRank
150 : uint32_t valid; // 检查消息有效性
151 : uint8_t repeatCnt; // 本消息需要重复的次数,默认是1
152 : uint8_t everyTurnRsp; // 每轮都需要等待执行结束发送响应,再执行下一轮
153 : uint8_t everyTurnWait; // 每轮都需要等待work消息再执行
154 : HcclHandle
155 : commDepGroupID; // 本消息执行需要等待的通信域组id,默认是-1,表示不需要等待,用于设置notify监听的通信域组id
156 : HcclHandle commDepHandleID; // 本消息执行需要等待的通信域轮次,默认是-1,表示不需要等待,用于设置notify监听的地址
157 : HcclHandle selfHandleID; // 通信消息对应的handleId值
158 : uint8_t seqNum; // 消息序号
159 : HcclApi::HcclTilingVersion version; // 消息的版本信息,version=0使用hcclMsg
160 : uint32_t xorCheck; // xor checksum
161 : uint64_t ccOpTilingData; // 消息的tiling信息
162 0 : void PrintMsg(const std::string& desc)
163 : {
164 0 : HCCL_INFO(
165 : "%s Msg[version %u, commType %u, opType %u, sendBuffer %p, recvBuffer %p, dataCnt %lu, strideLen %lu,"
166 : " hcclDataType %u, p2pSrcDestRankId %u, valid %u"
167 : " repeatCnt %u, everyTurnRsp %u, everyTurnWait %u, commDepGroupID %d,"
168 : " commDepHandleID %d, selfHandleID %d, seqNum %u, ccOpTilingData %#llx]",
169 : desc.c_str(), static_cast<uint32_t>(version), static_cast<uint32_t>(commType),
170 : static_cast<uint32_t>(opType), sendBuffer, recvBuffer, dataCnt, strideCount,
171 : static_cast<uint32_t>(hcclDataType), p2pSrcDestRankId, valid, repeatCnt, everyTurnRsp, everyTurnWait,
172 : commDepGroupID, commDepHandleID, selfHandleID, seqNum, ccOpTilingData);
173 0 : }
174 : };
175 :
176 : struct WqeSendSharedContect {
177 : volatile u32 startedThreadNum = 0;
178 : volatile u32 workedThreadNum = 0;
179 : std::atomic<bool> taskFinishFlag{false};
180 : volatile u32 curThreadIdsOnCpu[AICPU_CNT];
181 : volatile u32 sendWqeNum[MAX_BATCH_WRITE_THREAD_NUM];
182 : };
183 :
184 : struct DataBlock {
185 : uint32_t data[16];
186 : };
187 :
188 : constexpr uint32_t MAX_AICPU_NUM_BLOCKS = 6U;
189 :
190 : // HCCL 代码直调时直接传此结构:
191 6 : struct AivAicpuOpParam {
192 : HcclCMDType commType; // 32b
193 : HcclReduceOp opType; // 32b
194 : u64 sendBuffer;
195 : u64 recvBuffer;
196 : u64 count;
197 : u64 strideLen;
198 :
199 : // offset 32B
200 : HcclDataType hcclDataType;
201 :
202 : uint32_t valid; // 检查消息有效性
203 : uint8_t isLast; // 是否最后一个下
204 : uint8_t funID; // 功能ID,1地址消息; 2开始工作
205 : uint8_t sendCnt; // 发送计数
206 : uint8_t rcvCnt; // 执行结束轮次技术
207 : uint8_t everyTurnRsp; // 每轮都需要等待执行结束发送响应,再执行下一轮
208 : uint8_t everyTurnWait; // 每轮都需要等待work消息再执行
209 : uint8_t totalTurnCnt; // 总轮次
210 : uint8_t useBufferType;
211 : uint64_t winOffset; // 发送数据偏移地址
212 :
213 : HcclOpIdentifier opId;
214 : uint8_t res[2]; // 整体消息64字节
215 125 : void PrintMsg(const std::string& desc)
216 : {
217 125 : HCCL_INFO(
218 : "%s Msg[commType %u, opType %u, sendBuffer %p, recvBuffer %p, count %lu, strideLen %lu,"
219 : " hcclDataType %s, valid %u, isLast %u, funID %u, sendCnt %u, rcvCnt %u,"
220 : " everyTurnRsp %u, everyTurnWait %u, totalTurnCnt %u, winOffset %lu]",
221 : desc.c_str(), static_cast<uint32_t>(commType), static_cast<uint32_t>(opType), sendBuffer, recvBuffer, count,
222 : strideLen, GetDataTypeEnumStr(hcclDataType).c_str(), valid, isLast, funID, sendCnt, rcvCnt, everyTurnRsp,
223 : everyTurnWait, totalTurnCnt, winOffset);
224 125 : }
225 : };
226 :
227 : constexpr uint32_t MAX_DEBUG_CNT = 128U;
228 : struct AicDebugCntInfo {
229 : uint8_t cnt[MAX_DEBUG_CNT];
230 : }; // 128
231 :
232 : using AicpuAddOneNotifyWaitSqe
233 : = void (*)(uint16_t, uint16_t, u64, const uint8_t*, uint8_t*, const dfx::DfxTimeOutConfig&);
234 : using AicpuAddOneRecordSqe = void (*)(uint16_t, uint16_t, u64, const uint8_t*, uint8_t*);
235 : using AicpuAddOneWriteValueRecordSqe = void (*)(uint16_t, uint16_t, u64, const uint8_t*, uint8_t*);
236 : using AicpuAddOneMemcpySqe = void (*)(
237 : uint16_t, uint16_t, const void*, uint32_t, const aclDataType, aclrtReduceKind, const void*, uint32_t, uint32_t,
238 : uint32_t, u64, uint8_t, const uint8_t*, uint8_t*, uint32_t);
239 : using AicpuAddOneEventResetSqe = void (*)(uint16_t, int32_t, uint16_t, int64_t, int64_t, u64, const uint8_t*, uint8_t*);
240 : using AicpuAddOneEventRecordSqe = void (*)(uint16_t, int32_t, uint16_t, const uint8_t*, uint8_t*);
241 : using AicpuAddOneEventWaitSqe = void (*)(uint16_t, int32_t, uint16_t, const uint8_t*, uint8_t*);
242 : using AicpuAddOneRdmaDbSendSqe
243 : = void (*)(uint16_t, uint16_t, uint64_t, uint64_t, uint32_t, uint8_t, const uint8_t*, uint8_t*);
244 : using AicpuAddOneFlipPlaceHolderSqe = void (*)(uint16_t, uint16_t, uint16_t, const uint8_t*, uint8_t*);
245 :
246 : extern AicpuAddOneNotifyWaitSqe AicpuGetAddOneNotifyWaitSqe();
247 : extern AicpuAddOneRecordSqe AicpuGetAddOneRecordSqe();
248 : extern AicpuAddOneWriteValueRecordSqe AicpuGetAddOneWriteValueRecordSqe();
249 : extern AicpuAddOneMemcpySqe AicpuGetAddOneMemcpySqe();
250 : extern AicpuAddOneEventResetSqe AicpuGetAddOneEventResetSqe();
251 : extern AicpuAddOneEventRecordSqe AicpuGetAddOneEventRecordSqe();
252 : extern AicpuAddOneEventWaitSqe AicpuGetAddOneEventWaitSqe();
253 : extern AicpuAddOneRdmaDbSendSqe AicpuGetAddOneRdmaDbSendSqe();
254 : extern AicpuAddOneFlipPlaceHolderSqe AicpuGetAddOneFlipPlaceHolderSqe();
255 :
256 : struct RestartParam {
257 : // 重执行标记,表示是否发生异常需要重执行
258 : bool restartFlag = false;
259 : // 重执行次数
260 : uint32_t restartCnt = 0;
261 : // 是否所有通信域都重执行协商完成
262 : uint32_t consultationAllEnd = 0;
263 : // 通信域重执行协商情况
264 : bool consultationResult[MAX_COMM_CTX_NUM] = {false, false, false};
265 : // 通信域是否执行过changeLink
266 : bool linkChanged[MAX_COMM_CTX_NUM] = {false, false, false};
267 : // 通信域重执行协商初始化state
268 : HcclOpExecFSM fsmState[MAX_COMM_CTX_NUM]
269 : = {HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END, HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END,
270 : HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END};
271 : KfcError errorCode[MAX_COMM_CTX_NUM] = {KfcError::kNone, KfcError::kNone, KfcError::kNone};
272 : std::chrono::time_point<std::chrono::steady_clock> startTime[MAX_COMM_CTX_NUM];
273 : };
274 :
275 : enum class BarrierStatus : u8 { NO_BARRIER = 0U, SELF_BARRIER, INTER_BARRIER };
276 :
277 : struct BarrierInfo {
278 : BarrierStatus status;
279 : u64 lastTimeStamp;
280 : };
281 :
282 : enum class AicpuServerRole { MASTER = 0, SLAVE = 1, INVALID = 2 };
283 :
284 : #ifndef CCL_LLT
285 : #define ANONYMOUS_NAMESPACE_BEGIN namespace {
286 : #define ANONYMOUS_NAMESPACE_END }
287 : #else
288 : #define ANONYMOUS_NAMESPACE_BEGIN
289 : #define ANONYMOUS_NAMESPACE_END
290 : #endif
291 :
292 : #endif
|