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 : #ifndef HCCL_MC2_TYPE_H
11 : #define HCCL_MC2_TYPE_H
12 :
13 : #include <string>
14 : #include <unordered_map>
15 : #include <vector>
16 : #include "exception_util.h"
17 : #include "ccu_api_exception.h"
18 : #include "op_type.h"
19 : #include "data_type.h"
20 : #include "reduce_op.h"
21 :
22 : namespace Hccl {
23 :
24 : constexpr uint32_t MC2_RES_CTX_MAX = 3;
25 : constexpr uint32_t CCU_PARAM_NUM_PER_DIE = 32;
26 : constexpr uint32_t CCU_PARAM_NUM_MAX = CCU_PARAM_NUM_PER_DIE * 2;
27 : constexpr uint32_t CCU_ONE_PARAM_SIZE = 8;
28 : constexpr uint32_t CCU_TASK_NUM_MAX = 64;
29 : constexpr uint32_t MAX_RANK_NUM = 64; // 最大卡数
30 : constexpr uint32_t MAX_OP_NUM = 8; // MC2最大通信算子数
31 :
32 : constexpr uint32_t UNKNOWN_TILING_V1 = 3; // 旧版本 MC2 Tiling version = 3
33 : constexpr uint32_t UNKNOWN_TILING_V2 = 100; // 新版本 MC2 Tiling version = 100
34 : constexpr uint64_t MC2_WORKSPACE_SIZE = 16 * 1024 * 1024; // aic与ccu的交互空间workspace大小为16*1024*1024B
35 :
36 : struct HcclCommParamDesc {
37 : uint64_t version : 4; // 版本号,当前是1
38 : uint64_t groupNum : 4; // groupMatmul的输入数量,每个group对应一个输入和一个输出地址
39 : uint64_t hasFfts : 1; // 910下是否是ffts融合算子(多一个ffts_addr参数
40 : uint64_t
41 : tilingDataPtrOff : 7; // tilingdata指针所在的参数索引, 此处修改为tilingDataPtr的Offset,需要二次索引到tilingData
42 : uint64_t
43 : isDyn : 48; // 输入参数是否是动态输入,从IR输入开始计算,不包含前面的参数,is_dyn是一个bitmap,每个bit对应一个IR输入,如果是动态输入则为1,否则是0
44 : };
45 :
46 : struct KFCTilingData {
47 : uint32_t preparePosition; // 新增结构体,用来区分是否是高阶api
48 : uint32_t sendOff; // 发送数据地址偏移,count * dataTypeSize
49 : uint32_t recvOff; // 接收数据地址偏移, count * dataTypeSize
50 : uint32_t tailSendOff; // 尾块发送数据地址偏移,count * dataTypeSize
51 : uint32_t tailRecvOff; // 尾块发送数据地址偏移,count * dataTypeSize
52 : uint64_t sendCnt; // 整块发送数据个数
53 : uint32_t recvCnt; // 整块接收数据个数
54 : uint32_t tailSendCnt; // 尾块发送数据个数
55 : uint32_t tailRecvCnt; // 尾块接收数据个数
56 : uint32_t totalCnt; // 总数据个数
57 : uint32_t turnNum; // 总轮次
58 : uint32_t tailNum; // 尾块的轮次
59 : uint32_t stride; // 跳写间隔
60 : uint32_t workspaceOff; // 使用workspace作为recvbuf时的workspace偏移
61 : uint32_t notifyOff; // device notify write/read value偏移
62 : uint16_t notifyBeginCnt; // notify write value的使用个数
63 : uint16_t notifyEndCnt; // notify read value的使用个数
64 : uint8_t useBufferType; // 是否使用workspace作为recvbuf
65 : uint8_t funID; // function ID
66 : uint8_t dataType; // hccl 数据类型
67 : uint8_t groupNum; // groupNum
68 : uint8_t reuseMode; // tiling调试,填msgCnt,内存优化选择复用的内存块个数
69 : uint8_t commType; // 通信类型
70 : uint8_t reduceOp; // reduce op type
71 : uint8_t commOrder; // 通信顺序,0表示通信在前,1表示通信在后
72 : uint8_t waitPolicy; // 等待任务启动的阻塞策略
73 : // 2、首轮等待,1、每轮等待。KFC根据此标记在主流任务前面加wait,AIC需要按策略发对应record才能触发执行
74 : uint8_t rspPolicy; // 任务执行结束时的响应策略, 2、最后通知一次,
75 : // 1、每轮通知一次。KFC根据此标记在主流任务后面加record
76 : uint8_t exitPolicy; // 退出策略,0,一次通信任务下发完成直接退出;1. 通信任务执行完成退出;2.
77 : // 等待AIC通知退出(可以多次执行任务)。
78 : uint8_t commAlg; // 用于指定具体通信算法。
79 : uint8_t taskType; // 用于识别不同任务。参考KfcTaskType定义
80 : uint8_t debugMode; // 调测模式
81 : // 1:单独执行CUBE
82 : // 2:单独执行Vector
83 : // 4:单独执行AICPU KFC算子
84 : // 8:KFC等待通信结束
85 : // 16:KFC统计各阶段耗时
86 : // 32:调试多ccu任务模式,通过ccuNum告诉ccu是几个ccu任务
87 : uint8_t stepSize; // 用于指定通算频率步长
88 : uint8_t sendArgIndex; // 发送数据参数索引,对应算子原型的参数顺序
89 : uint8_t recvArgIndex; // 接收数据参数索引,对应算子原型的参数顺序
90 : uint8_t commOutArgIndex; // 通信输出参数索引,对应算子原型的参数顺序
91 : uint8_t hasCommOut; // 是否有通信输出
92 :
93 : uint8_t reduceOutputDataType; // 输入datatype类型为hif8、fp8、int8 才生效, 输出只有fp16/fp32/bf16类型
94 : uint32_t workspaceSendOffset;
95 : uint32_t workspaceRecvOffset;
96 : uint32_t ccuNum;
97 : uint32_t ccuParamNum[CCU_TASK_NUM_MAX];
98 : uint64_t paramAddr[CCU_PARAM_NUM_MAX * CCU_TASK_NUM_MAX];
99 : uint64_t paramValue[CCU_PARAM_NUM_MAX * CCU_TASK_NUM_MAX];
100 :
101 : std::string ToString() const
102 : {
103 : return StringFormat(
104 : "sendArgIndex = %u\nrecvArgIndex = %u\nsendOff = %u\nrecvOff = %u\ntailSendOff = %u\ntailRecvOff = "
105 : "%u\nsendCnt = %u\nrecvCnt = %u\ntailSendCnt = %u\ntailRecvCnt = %u\ntotalCnt = %u\nturnNum = %u\ntailNum "
106 : "= %u\ndataType = %u\ncommType = %u\ncommOutArgIndex = %u\nnotifyBeginCnt = %u\nnotifyEndCnt = "
107 : "%u\nuseBufferType = %u\nreduceOp = %u\nreduceOutputDataType = %u\nworkspaceSendOffset = "
108 : "%lu\nworkspaceRecvOffset = %lu",
109 : sendArgIndex, recvArgIndex, sendOff, recvOff, tailSendOff, tailRecvOff, sendCnt, recvCnt, tailSendCnt,
110 : tailRecvCnt, totalCnt, turnNum, tailNum, dataType, commType, commOutArgIndex, notifyBeginCnt, notifyEndCnt,
111 : useBufferType, reduceOp, reduceOutputDataType, workspaceSendOffset, workspaceRecvOffset);
112 : }
113 : };
114 :
115 : enum HcclBufferType {
116 : HCCL_BUFFER_TYPE_DEFAULT = 0,
117 : HCCL_BUFFER_TYPE_OUTPUT,
118 : HCCL_BUFFER_TYPE_WINDOW_IN,
119 : HCCL_BUFFER_TYPE_WINDOW_OUT,
120 : HCCL_BUFFER_TYPE_WORKSPACE,
121 : HCCL_BUFFER_TYPE_INPUT,
122 : HCCL_BUFFER_TYPE_COMMOUT,
123 : HCCL_BUFFER_TYPE_SEND_WORKSPACE,
124 : HCCL_BUFFER_TYPE_RECV_WORKSPACE,
125 : HCCL_BUFFER_TYPE_SEND_RECV_WORKSPACE,
126 : HCCL_BUFFER_TYPE_END,
127 : };
128 :
129 : enum AicpuComType {
130 : HCCL_CMD_INVALID = 0,
131 : HCCL_CMD_BROADCAST = 1,
132 : HCCL_CMD_ALLREDUCE,
133 : HCCL_CMD_REDUCE,
134 : HCCL_CMD_SEND,
135 : HCCL_CMD_RECEIVE,
136 : HCCL_CMD_ALLGATHER,
137 : HCCL_CMD_REDUCE_SCATTER,
138 : HCCL_CMD_ALLTOALLV,
139 : HCCL_CMD_ALLTOALLVC,
140 : HCCL_CMD_ALLTOALL,
141 : HCCL_CMD_GATHER,
142 : HCCL_CMD_SCATTER,
143 : HCCL_CMD_BATCH_SEND_RECV,
144 : HCCL_CMD_BATCH_PUT,
145 : HCCL_CMD_BATCH_GET,
146 : HCCL_CMD_ALLGATHER_V,
147 : HCCL_CMD_REDUCE_SCATTER_V,
148 : HCCL_CMD_BATCH_WRITE,
149 : HCCL_CMD_HALF_ALLTOALLV = 20,
150 : HCCL_CMD_ALL,
151 : HCCL_CMD_RESERVED
152 : };
153 :
154 : constexpr OpType MC2_OP_TYPE[]
155 : = {OpType::INVALID, OpType::BROADCAST, OpType::ALLREDUCE, OpType::REDUCE, OpType::SEND,
156 : OpType::RECV, OpType::ALLGATHER, OpType::REDUCESCATTER, OpType::ALLTOALLV, OpType::ALLTOALLVC,
157 : OpType::ALLTOALL, OpType::GATHER, OpType::INVALID, OpType::INVALID, OpType::INVALID,
158 : OpType::INVALID, OpType::INVALID, OpType::INVALID, OpType::INVALID, OpType::INVALID,
159 : OpType::HALFALLTOALLV, OpType::INVALID};
160 :
161 125 : inline OpType MC2OpType(AicpuComType comType)
162 : {
163 125 : if (comType >= HCCL_CMD_RESERVED || comType <= HCCL_CMD_INVALID) {
164 0 : THROW<Hccl::CcuApiException>(StringFormat("Invalid OpType [%u].", comType));
165 : }
166 125 : return MC2_OP_TYPE[comType];
167 : }
168 :
169 : constexpr ReduceOp MC2_REDUCE_TYPE[] = {ReduceOp::SUM, ReduceOp::PROD, ReduceOp::MAX, ReduceOp::MIN, ReduceOp::INVALID};
170 :
171 6 : inline ReduceOp MC2ReduceType(HcclReduceOp reduceOp)
172 : {
173 6 : if (reduceOp >= (sizeof(MC2_REDUCE_TYPE) / sizeof(MC2_REDUCE_TYPE[0])) || reduceOp < HCCL_REDUCE_SUM) {
174 0 : THROW<Hccl::CcuApiException>(StringFormat("Invalid ReduceOp [%u].", reduceOp));
175 : }
176 6 : return MC2_REDUCE_TYPE[reduceOp];
177 : }
178 :
179 : constexpr DataType MC2_DATA_TYPE[]
180 : = {DataType::INT8, DataType::INT16, DataType::INT32, DataType::FP16, DataType::FP32,
181 : DataType::INT64, DataType::UINT64, DataType::UINT8, DataType::UINT16, DataType::UINT32,
182 : DataType::FP64, DataType::BFP16, DataType::INT128, DataType::BF16_SAT, DataType::HIF8,
183 : DataType::FP8E4M3, DataType::FP8E5M2, DataType::FP8E8M0, DataType::INVALID};
184 :
185 250 : inline DataType MC2DataType(HcclDataType dataType)
186 : {
187 250 : if (dataType >= (sizeof(MC2_DATA_TYPE) / sizeof(MC2_DATA_TYPE[0])) || dataType < HCCL_DATA_TYPE_INT8) {
188 0 : THROW<Hccl::CcuApiException>(StringFormat("Invalid DataType [%u].", dataType));
189 : }
190 250 : return MC2_DATA_TYPE[dataType];
191 : }
192 :
193 : struct AivAicpuOpParam {
194 : AicpuComType commType; // 32b
195 : HcclReduceOp opType; // 32b
196 : uint64_t sendBuffer;
197 : uint64_t recvBuffer;
198 : uint64_t count;
199 : uint64_t strideLen;
200 :
201 : // offset 32B
202 : HcclDataType hcclDataType;
203 : uint32_t valid; // 检查消息有效性
204 :
205 : // 存地址
206 : uint64_t sendCnt; // send CKE地址
207 : uint64_t rcvCnt; // rcv CKE地址
208 :
209 : uint8_t isLast; // 是否最后一个下
210 : uint8_t funID; // 功能ID,1地址消息; 2开始工作
211 : uint8_t everyTurnRsp; // 每轮都需要等待执行结束发送响应,再执行下一轮
212 : uint8_t everyTurnWait; // 每轮都需要等待work消息再执行
213 : uint8_t totalTurnCnt; // 总轮次
214 : uint8_t res[59]; // 整体消息128字节
215 : };
216 :
217 : struct KFCTaskV2 {
218 : uint64_t inputA; // A矩阵地址,通信在前时为sendbuffer
219 : uint64_t outputC; // 输出C矩阵地址
220 : uint64_t commOut; // 双输出时,通信输出地址
221 : uint64_t ctxNum;
222 : uint64_t context[MC2_RES_CTX_MAX]; // HCCL通信context
223 : uint64_t workSpace; // 通信结果不直接输出时,放到workspace中
224 : uint64_t tilingData; // 通信
225 : };
226 :
227 : struct HcclAiRMAWQ {
228 : u32 jettyId;
229 : u64 sqVA;
230 : u32 wqeSize;
231 : u32 sqDepth;
232 : u64 headAddr; // AIV无依赖
233 : u64 tailAddr; // AIV无依赖
234 : u64 dbAddr;
235 : u32 tp_id;
236 : uint8_t rmtEid[16];
237 : uint32_t rmtObjId; // rmtTokenID
238 : uint32_t rmtTokenValue;
239 : uint32_t localTokenId;
240 : };
241 :
242 : struct HcclAiRMACQ {
243 : u32 jfcId;
244 : u64 cqVA;
245 : u32 cqeSize;
246 : u32 cqDepth;
247 : u64 headAddr;
248 : u64 tailAddr;
249 : u64 dbAddr;
250 : };
251 :
252 : struct HcclCombinOpParam {
253 : uint64_t workSpace; // client和server之间通信的地址
254 : uint64_t workSpaceSize; // client和server之间通信的空间大小
255 : uint32_t rankId; // 当前卡rankId
256 : uint32_t rankDim; // 总卡数
257 : uint64_t winSize; // ccu不使用
258 : uint64_t windowsIn[MAX_RANK_NUM]; // ccu不使用
259 : uint64_t windowsOut[MAX_RANK_NUM]; // ccu不使用
260 :
261 : // for ccu
262 : uint64_t xnAddr; // Xn寄存器其实地址
263 : uint64_t ckeAddr; // CKE寄存器其实地址
264 : uint64_t msAddr; // MS地址,预留
265 : uint64_t msSize; // 可写的MS个数,预留
266 :
267 : uint32_t opType[MAX_OP_NUM];
268 : uint8_t algorithmType[MAX_OP_NUM];
269 :
270 : HcclAiRMAWQ wq[MAX_RANK_NUM];
271 : HcclAiRMACQ cq[MAX_RANK_NUM];
272 : };
273 :
274 : struct Mc2ServerCfg {
275 : uint32_t version;
276 : uint8_t debugMode;
277 : uint8_t sendArgIndex;
278 : uint8_t recvArgIndex;
279 : uint8_t commOutArgIndex;
280 : uint8_t reserved[8];
281 :
282 2 : std::string ToString() const
283 : {
284 : return StringFormat(
285 2 : "debugMode = %u\nsendArgIndex = %u\nrecvArgIndex = %u\ncommOutArgIndex = %u\n", debugMode, sendArgIndex,
286 2 : recvArgIndex, commOutArgIndex);
287 : }
288 : };
289 :
290 : struct Mc2CommConfig {
291 : uint8_t skipLocalRankCopy;
292 : uint8_t skipBufferWindowCopy;
293 : uint8_t stepSize;
294 : uint8_t communicationEngine; // 用于标记使用AIV、CCU、AICPU做通信加速器,定义同通信域加速器配置
295 : char reserved[12];
296 : char groupName[128]; // 指定通信域
297 : char algConfig[128]; // 指定算法
298 : uint32_t opType; // 算子类型
299 : uint32_t reduceType; // reduce类型,sum,max等
300 : uint32_t dataType; // 输入数据类型
301 : uint32_t outputDataType; // 输出数据类型
302 :
303 2 : std::string ToString() const
304 : {
305 : return StringFormat(
306 2 : "opType = %u\nreduceType = %u\ndataType = %u\noutputDataType = %u\n", opType, reduceType, dataType,
307 2 : outputDataType);
308 : }
309 : };
310 : struct Mc2Tiling {
311 : uint32_t version; // 版本
312 : uint32_t commConfigNum; // commComfig的个数,每个通信切片一个hcclConfig
313 : struct Mc2ServerCfg serverCfg; // 计算部分tiling
314 : struct Mc2CommConfig commConfig; // 通信部分tiling,共有Mc2CommConfig个,每个通信切片一个hcclConfig
315 :
316 2 : std::string ToString()
317 : {
318 2 : auto selfDesc = StringFormat("version = %u\ncommConfigNum = %u\n", version, commConfigNum);
319 4 : return selfDesc + serverCfg.ToString() + commConfig.ToString();
320 2 : }
321 : };
322 :
323 : struct Mc2InitTilingInner { // 这个必须放到mc2tiling的最前面
324 : uint32_t version; // tiling结构体版本号,外部不可配置, 100开始
325 : uint32_t mc2HcommCnt; // 通信的次数
326 : uint32_t offset[MAX_OP_NUM]; // 每个通信的偏移
327 : uint8_t debugMode; // 调测模式, 0表示关闭,1表示开启,外部可配置
328 : uint8_t preparePosition; // prepare消息发送的位置,0表示device,1表示host,外部可配置
329 : char reserved[22];
330 : };
331 :
332 : struct Mc2CcTilingInner {
333 : uint8_t skipLocalRankCopy; // 跳过本卡拷贝,在通信结果只需要给MC2内部计算使用或者本卡拷贝由aicore完成时,
334 : uint8_t skipBufferWindowCopy; // 跳过hbm到window间搬运 0不跳过,1跳过snd-window, 2跳过window-rcv
335 : uint8_t stepSize; // 通信步长,粗粒度融合时填0,
336 : uint8_t version; // 版本号
337 : char reserved[8]; // 保留字段
338 : uint8_t protocol; // 协议类型 0:ubmemory 1:urma
339 : uint8_t
340 : communicationEngine; // 用于标记使用AIV、CCU、AICPU做通信加速器,定义同通信域加速器配置 0:默认ccu 1:ccu 2:aiv
341 : uint8_t srcDataType; // 输入数据类型
342 : uint8_t dstDataType; // 输出数据类型
343 : char groupName[128]; // groupName
344 : char algConfig[128]; // 算法配置
345 : uint32_t opType; // tiling结构体版本号
346 : uint32_t reduceType; // reduce类型
347 : };
348 :
349 : constexpr uint32_t ALG_CONFIG_SIZE = 128;
350 : constexpr uint32_t MAX_OP_NAME_SIZE = 256;
351 : constexpr uint32_t MAX_MEM_TAG_SIZE = 256;
352 : struct HcclOpArgs {
353 : DataType srcDataType;
354 : DataType dstDataType;
355 : ReduceOp reduceType;
356 : uint64_t count{0};
357 : char algConfig[ALG_CONFIG_SIZE];
358 : HcclAccelerator commEngine;
359 : uint64_t reverse;
360 :
361 3 : void Init()
362 : { // if not set value, give a default
363 3 : srcDataType = DataType::FP16;
364 3 : dstDataType = DataType::FP16;
365 3 : reduceType = ReduceOp::SUM;
366 3 : count = 0;
367 3 : }
368 : };
369 :
370 : } // namespace Hccl
371 :
372 : #endif // HCCL_MC2_TYPE_H
|