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 : #include <unordered_set>
12 : #include <mutex>
13 : #include "log.h"
14 : #include "adapter_rts.h"
15 : #include "adapter_hccp.h"
16 : #include "dtype_common.h"
17 : #include "externalinput.h"
18 : #include "network_manager_pub.h"
19 : #include "adapter_hal.h"
20 : #include "dlhal_function.h"
21 : #include "device_capacity.h"
22 :
23 :
24 : constexpr u32 INLINEREDUCE_ALIGN_BYTES_910A = 128;
25 : constexpr u32 INLINEREDUCE_ALIGN_BYTES_310P = 2;
26 : constexpr u32 INLINEREDUCE_ALIGN_BYTES_910_93 = 1; // A2和A3场景的inline reduce不受地址对齐限制
27 : constexpr float BANDWIDTH_HCCS_910A = 10.0f;
28 : constexpr float BANDWIDTH_HCCS_910B = 18.3f;
29 : constexpr float BANDWIDTH_RDMA_910A = 12.5f * 0.8;
30 : constexpr float BANDWIDTH_RDMA_910B = 25.0f * 0.8;
31 : constexpr float BANDWIDTH_HBM_910_93 = 650.0f * 0.9;
32 : constexpr float BANDWIDTH_SIO_910_93 = 240.0f * 0.85;
33 :
34 : // 常用带宽值 GB/s
35 : constexpr float BANDWIDTH_PCIE_GEN3 = 16.0f * 0.85;
36 : constexpr float BANDWIDTH_PCIE_GEN4 = 32.0f * 0.85;
37 : constexpr float BANDWIDTH_PCIE_GEN5 = 64.0f * 0.85;
38 :
39 : // 非超节点模式的server id配置, 通过hrtGetDeviceInfo接口查询到的server id统一为0x3FF
40 : constexpr s64 INVALID_SUPERPOD_SERVERID = 0x3FF;
41 :
42 : namespace hccl {
43 : #ifdef ASCEND_310P_DEVICE
44 : bool g_is310PDevice = true;
45 : #else
46 : bool g_is310PDevice = false;
47 : #endif
48 :
49 1 : bool IsSupportAIVCopy(HcclDataType dataType)
50 : {
51 1 : return (dataType == HCCL_DATA_TYPE_FP16 || dataType == HCCL_DATA_TYPE_INT16 || dataType == HCCL_DATA_TYPE_UINT16 ||
52 0 : dataType == HCCL_DATA_TYPE_FP32 || dataType == HCCL_DATA_TYPE_INT32 || dataType == HCCL_DATA_TYPE_UINT32 ||
53 0 : dataType == HCCL_DATA_TYPE_INT8 || dataType == HCCL_DATA_TYPE_UINT8 || dataType == HCCL_DATA_TYPE_BFP16 ||
54 2 : dataType == HCCL_DATA_TYPE_INT64 || dataType == HCCL_DATA_TYPE_UINT64 || dataType == HCCL_DATA_TYPE_FP64);
55 : }
56 :
57 0 : bool IsSupportAIVReduce(HcclDataType dataType, HcclReduceOp op)
58 : {
59 0 : bool checkDataType =
60 0 : (dataType == HCCL_DATA_TYPE_FP32 || dataType == HCCL_DATA_TYPE_FP16 || dataType == HCCL_DATA_TYPE_INT8 ||
61 0 : dataType == HCCL_DATA_TYPE_INT16 || dataType == HCCL_DATA_TYPE_INT32 || dataType == HCCL_DATA_TYPE_BFP16);
62 0 : bool checkReduceType = (op == HCCL_REDUCE_SUM || op == HCCL_REDUCE_MAX || op == HCCL_REDUCE_MIN);
63 :
64 0 : return checkDataType && checkReduceType;
65 : }
66 :
67 333 : bool IsAddressAlign(const void *inputPtr, const void *outputPtr, DevType devType)
68 : {
69 333 : switch (devType) {
70 189 : case DevType::DEV_TYPE_910:
71 189 : return (reinterpret_cast<intptr_t>(inputPtr) % INLINEREDUCE_ALIGN_BYTES_910A) ==
72 189 : (reinterpret_cast<intptr_t>(outputPtr) % INLINEREDUCE_ALIGN_BYTES_910A);
73 144 : case DevType::DEV_TYPE_910B:
74 : case DevType::DEV_TYPE_910_93:
75 : return (reinterpret_cast<intptr_t>(inputPtr) % INLINEREDUCE_ALIGN_BYTES_910_93) ==
76 144 : (reinterpret_cast<intptr_t>(outputPtr) % INLINEREDUCE_ALIGN_BYTES_910_93);
77 0 : case DevType::DEV_TYPE_310P3:
78 : case DevType::DEV_TYPE_310P1:
79 0 : return (reinterpret_cast<intptr_t>(inputPtr) % INLINEREDUCE_ALIGN_BYTES_310P) ==
80 0 : (reinterpret_cast<intptr_t>(outputPtr) % INLINEREDUCE_ALIGN_BYTES_310P);
81 0 : default:
82 0 : HCCL_WARNING("device type[%d] is out of range", static_cast<s32>(devType));
83 0 : return false;
84 : }
85 : }
86 :
87 322 : bool IsDataTypeSupport(HcclDataType dataType, DevType devType)
88 : {
89 322 : switch (devType) {
90 144 : case DevType::DEV_TYPE_910B:
91 : case DevType::DEV_TYPE_910_93:
92 50 : return (dataType == HCCL_DATA_TYPE_FP32 || dataType == HCCL_DATA_TYPE_FP16 ||
93 0 : dataType == HCCL_DATA_TYPE_INT8 || dataType == HCCL_DATA_TYPE_INT16 ||
94 194 : dataType == HCCL_DATA_TYPE_INT32 || dataType == HCCL_DATA_TYPE_BFP16);
95 178 : case DevType::DEV_TYPE_910:
96 : case DevType::DEV_TYPE_310P1:
97 178 : return dataType == HCCL_DATA_TYPE_FP32;
98 0 : case DevType::DEV_TYPE_310P3:
99 0 : return (dataType == HCCL_DATA_TYPE_FP32 || dataType == HCCL_DATA_TYPE_INT16 ||
100 0 : dataType == HCCL_DATA_TYPE_FP16);
101 0 : default:
102 0 : HCCL_WARNING("device type[%d] is out of range", static_cast<s32>(devType));
103 0 : return false;
104 : }
105 : }
106 :
107 303 : bool IsRedOpSupport(HcclReduceOp op, DevType devType)
108 : {
109 303 : switch (devType) {
110 143 : case DevType::DEV_TYPE_910B:
111 : case DevType::DEV_TYPE_910_93:
112 143 : return (op == HCCL_REDUCE_SUM || op == HCCL_REDUCE_MAX || op == HCCL_REDUCE_MIN);
113 160 : case DevType::DEV_TYPE_910:
114 : case DevType::DEV_TYPE_310P3:
115 : case DevType::DEV_TYPE_310P1:
116 160 : return op == HCCL_REDUCE_SUM;
117 0 : default:
118 0 : HCCL_WARNING("device type[%d] is out of range", static_cast<s32>(devType));
119 0 : return false;
120 : }
121 : }
122 :
123 334 : bool IsSupportSDMAReduce(const void *inputPtr, const void *outputPtr, HcclDataType dataType, HcclReduceOp op)
124 : {
125 : DevType devType;
126 334 : CHK_RET(hrtGetDeviceType(devType));
127 636 : return IsAddressAlign(inputPtr, outputPtr, devType) && IsDataTypeSupport(dataType, devType) &&
128 635 : IsRedOpSupport(op, devType);
129 : }
130 :
131 179 : bool IsSupportRDMAReduce(HcclDataType dataType, HcclReduceOp op)
132 : {
133 179 : bool checkDataType =
134 19 : (dataType == HCCL_DATA_TYPE_FP32 || dataType == HCCL_DATA_TYPE_FP16 || dataType == HCCL_DATA_TYPE_INT8 ||
135 198 : dataType == HCCL_DATA_TYPE_INT16 || dataType == HCCL_DATA_TYPE_INT32 || dataType == HCCL_DATA_TYPE_BFP16);
136 179 : bool checkReduceType = (op == HCCL_REDUCE_SUM || op == HCCL_REDUCE_MAX || op == HCCL_REDUCE_MIN);
137 179 : bool isInfNanMode = IsOverFlowInfNanMode();
138 179 : return checkDataType && checkReduceType && isInfNanMode;
139 : }
140 :
141 0 : HcclResult GetBandWidthPerNPU(u32 level, u32 userRankSize, u32 deviceNumPerAggregation, float &bandWidth)
142 : {
143 : DevType devType;
144 0 : CHK_RET(hrtGetDeviceType(devType));
145 : // 处理 level=1、910B 的特殊条件
146 0 : if (level == 1 && (devType == DevType::DEV_TYPE_910B || devType == DevType::DEV_TYPE_910_93) &&
147 0 : userRankSize == deviceNumPerAggregation * 2) // 2: 910B 16p形态 单server场景
148 : {
149 0 : bandWidth = BANDWIDTH_PCIE_GEN5;
150 0 : return HCCL_SUCCESS;
151 : }
152 : // 其余情况查表
153 : static const std::map<std::pair<u32, DevType>, float> bwTable = {
154 : // level 0
155 : {{0, DevType::DEV_TYPE_310P3}, BANDWIDTH_PCIE_GEN3},
156 : {{0, DevType::DEV_TYPE_910}, BANDWIDTH_HCCS_910A},
157 : {{0, DevType::DEV_TYPE_910B}, BANDWIDTH_HCCS_910B},
158 : {{0, DevType::DEV_TYPE_910_93},BANDWIDTH_HCCS_910B},
159 : // level 1
160 : {{1, DevType::DEV_TYPE_910}, BANDWIDTH_RDMA_910A},
161 : {{1, DevType::DEV_TYPE_910B}, BANDWIDTH_RDMA_910B},
162 : {{1, DevType::DEV_TYPE_910_93},BANDWIDTH_RDMA_910B},
163 : // level 2
164 : {{2, DevType::DEV_TYPE_910_93},BANDWIDTH_HBM_910_93},
165 : // level 3
166 : {{3, DevType::DEV_TYPE_910_93},BANDWIDTH_SIO_910_93},
167 0 : };
168 0 : auto key = std::make_pair(level, devType);
169 0 : auto it = bwTable.find(key);
170 0 : if (it != bwTable.end()) {
171 0 : bandWidth = it->second;
172 0 : return HCCL_SUCCESS;
173 : }
174 0 : HCCL_ERROR("[Get][BandWidthPerNPU] Failed, deviceType[%d] Bandwidth Level[%u]", devType, level);
175 0 : return HCCL_E_NOT_SUPPORT;
176 : }
177 :
178 520 : HcclResult CheckDeviceType(const DevType deviceType)
179 : {
180 520 : if ((deviceType >= DevType::DEV_TYPE_COUNT) || (deviceType < DevType::DEV_TYPE_910)) {
181 0 : HCCL_ERROR("[Check][DeviceType]errNo[0x%016llx] device Type[%d] out of range[%d, %d]",
182 : HCCL_ERROR_CODE(HCCL_E_PARA), deviceType, DevType::DEV_TYPE_910, DevType::DEV_TYPE_NOSOC);
183 0 : return HCCL_E_PARA;
184 : }
185 :
186 520 : return HCCL_SUCCESS;
187 : }
188 :
189 179 : bool IsOverFlowInfNanMode()
190 : {
191 179 : aclrtFloatOverflowMode floatOverflowMode = ACL_RT_OVERFLOW_MODE_UNDEF;
192 179 : HcclResult ret = hrtGetDeviceSatMode(&floatOverflowMode);
193 179 : if (ret != HCCL_SUCCESS) {
194 0 : HCCL_WARNING("[impl][IsOverFlowInfNanMode] GetDeviceSatMode failed");
195 : }
196 358 : return (!GetExternalInputHcclDumpDebug()) && (floatOverflowMode == ACL_RT_OVERFLOW_MODE_INFNAN);
197 : }
198 :
199 84710 : bool Is310PDevice()
200 : {
201 84710 : return g_is310PDevice;
202 : }
203 :
204 0 : bool IsUseSdidForDeviceId(const u32 superDeviceId)
205 : {
206 : DevType devType;
207 0 : CHK_RET(hrtGetDeviceType(devType));
208 0 : if (devType == DevType::DEV_TYPE_910_93 && superDeviceId != INVALID_UINT) {
209 0 : return true;
210 : }
211 0 : return false;
212 : }
213 :
214 3 : HcclResult IsSuperPodMode(bool &useSuperPodMode)
215 : {
216 3 : useSuperPodMode = false;
217 : DevType devType;
218 3 : CHK_RET(hrtGetDeviceType(devType));
219 3 : s64 serverId = INVALID_SUPERPOD_SERVERID;
220 3 : if (devType == DevType::DEV_TYPE_910_93) {
221 : s32 deviceLogicId;
222 2 : HcclResult ret = hrtGetDevice(&deviceLogicId);
223 2 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[IsSuperPodMode]Get device id fail"), ret);
224 2 : CHK_RET(hrtGetDeviceInfo(deviceLogicId, HcclRtDeviceModuleType::HCCL_RT_MODULE_TYPE_SYSTEM,
225 : HcclRtDeviceInfoType::HCCL_INFO_TYPE_SERVER_ID, serverId));
226 2 : useSuperPodMode = (serverId != INVALID_SUPERPOD_SERVERID);
227 2 : if (!useSuperPodMode) {
228 0 : HCCL_WARNING("If server Id is not configured, the network port may need to be " \
229 : "kept up to ensure normal service running, server id[%016llx]", serverId);
230 : }
231 : }
232 3 : HCCL_INFO("[IsSuperPodMode]ret[%d], devType[%d], serverId[%016llx]", useSuperPodMode, devType, serverId);
233 3 : return HCCL_SUCCESS;
234 : }
235 :
236 3325 : HcclResult GetMaxDevNum(u32& MaxDevNum)
237 : {
238 : // 静态缓存最大设备数
239 : static u32 cachedMaxDevNum;
240 : static std::once_flag initFlag; // 用于确保初始化只执行一次
241 : static std::mutex initMutex; // 用于保护call_once调用
242 :
243 : // 使用mutex保护call_once调用
244 3325 : std::lock_guard<std::mutex> lock(initMutex);
245 :
246 : // 使用call_once确保初始化逻辑只执行一次
247 3328 : std::call_once(initFlag, [&]() {
248 : DevType devType;
249 12 : HcclResult result = hrtGetDeviceType(devType);
250 12 : if (result != HCCL_SUCCESS) {
251 0 : HCCL_ERROR("[GetMaxDevNum] [hrtGetDeviceType] get device type failed");
252 : }
253 12 : switch (devType) {
254 0 : case DevType::DEV_TYPE_310P3:
255 0 : cachedMaxDevNum = MAX_DEVICE_NUM_THIRTY_TWO;
256 0 : break;
257 0 : case DevType::DEV_TYPE_950:
258 : case DevType::DEV_TYPE_960:
259 0 : cachedMaxDevNum = MAX_DEVICE_NUM_SIXTY_FIVE;
260 0 : break;
261 12 : default:
262 12 : cachedMaxDevNum = MAX_DEVICE_NUM_SIXTEEN;
263 12 : break;
264 : }
265 12 : });
266 :
267 : // 直接读取缓存值
268 3328 : MaxDevNum = cachedMaxDevNum;
269 3328 : HCCL_DEBUG("[GetMaxDevNum] MaxDevNum[%u]", MaxDevNum);
270 3328 : return HCCL_SUCCESS;
271 3328 : }
272 :
273 : #ifndef OPEN_HCCL_TEST
274 0 : HcclResult IsSupportAicpuNormalQP(const u32& devicePhyId, bool &isSupportNormalQP)
275 : {
276 0 : u32 aiQpCreateVersion = 0;
277 0 : HcclResult ret = hrtRaGetInterfaceVersion(devicePhyId, AI_QP_CREATE, &aiQpCreateVersion);
278 0 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[IsSupportAicpuNormalQP] ret[%d]"
279 : "devicePhyId[%u] not support" , ret, devicePhyId), HCCL_E_NETWORK);
280 0 : if (aiQpCreateVersion >= AI_NORMAL_QP_CREATE_VERSION) {
281 0 : isSupportNormalQP = true;
282 : } else {
283 0 : isSupportNormalQP = false;
284 : }
285 0 : HCCL_DEBUG("IsSupportAicpuNormalQP devicePhyId[%u], isSupportNormalQP[%d].", devicePhyId, isSupportNormalQP);
286 0 : return HCCL_SUCCESS;
287 : }
288 : #endif
289 :
290 : #ifndef OPEN_HCCL_TEST
291 5 : HcclResult IsSupportAIVNormalQP(const u32& devicePhyId, bool &isSupport)
292 : {
293 5 : u32 version = 0;
294 5 : HcclResult ret = hrtRaGetInterfaceVersion(devicePhyId, AI_QP_CREATE_WITH_ATTRS, &version);
295 5 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[hrtRaGetInterfaceVersion] ret[%d]"
296 : "devicePhyId[%u] not support" , ret, devicePhyId), HCCL_E_NETWORK);
297 :
298 5 : if (version >= AI_QP_CREATE_WITH_ATTRS_VERSION) {
299 5 : isSupport = true;
300 : } else {
301 0 : isSupport = false;
302 : }
303 5 : HCCL_INFO("IsSupportAIVNormalQP devicePhyId[%u], isSupport[%d].", devicePhyId, isSupport);
304 5 : return HCCL_SUCCESS;
305 : }
306 : #endif
307 :
308 : #ifndef OPEN_HCCL_TEST
309 153 : bool IsSupportRDMALite(const s32 deviceLogicId)
310 : {
311 153 : return NetworkManager::GetInstance(deviceLogicId).GetRdmaLiteStatus();
312 : }
313 154 : HcclResult IsSupportHccsAndSio(bool &flag)
314 : {
315 154 : flag = false;
316 154 : size_t outputLen = 0;
317 154 : supportFeaturePara inputPara = { 0 };
318 154 : supportFeaturePara outputPara = { 0 };
319 154 : s32 deviceId = 0;
320 154 : CHK_RET(hrtGetDevice(&deviceId));
321 154 : inputPara.support_feature = CTRL_SUPPORT_SHMEM_MAP_EXBUS_MASK;
322 154 : inputPara.devid = static_cast<unsigned int>(deviceId);
323 154 : CHK_RET(hrtHalMemCtl(CTRL_TYPE_SUPPORT_FEATURE, &inputPara, sizeof(supportFeaturePara), &outputPara, &outputLen));
324 :
325 152 : if ((outputPara.support_feature & CTRL_SUPPORT_SHMEM_MAP_EXBUS_MASK) != 0) {
326 0 : flag = true;
327 : }
328 152 : HCCL_INFO("[IsSupportHccsAndSio] isSupportHccsAndSio %d", flag);
329 154 : return HCCL_SUCCESS;
330 : }
331 : #endif
332 :
333 : #ifndef OPEN_HCCL_TEST
334 0 : HcclResult GetMemBlockNum(const u32 devicePhyId, u32& memBlockNum)
335 : {
336 : #ifndef CCL_KERNEL_AICPU
337 0 : u32 info = 0;
338 0 : CHK_RET(DlHalFunction::GetInstance().DlHalFunctionInit());
339 0 : CHK_RET(hrtDrvGetPlatformInfo(&info));
340 0 : if (info == 0) { // 在device侧
341 0 : std::string chipName;
342 0 : if (hrtHalGetChipInfo(devicePhyId, chipName) == HCCL_SUCCESS) {
343 0 : if (chipName.find(SOC_NAME_910B) != std::string::npos) {
344 : // 共享内存池目前不支持动态扩容;910B场景需要的内存池较大,但是申请太大,会导致310P上内存不足,通过硬件区分。
345 0 : memBlockNum = MEM_BLOCK_NUM_BIGER;
346 : }
347 : }
348 0 : }
349 : #endif
350 0 : return HCCL_SUCCESS;
351 : }
352 : #endif
353 : // 获取算子最大超时时间
354 0 : u32 GetNotifyMaxWaitTime()
355 : {
356 : static bool init = false;
357 : static uint32_t notifyMaxWaitTime = NOTIFY_MAX_WAIT_TIME;
358 0 : if (UNLIKELY(!init)) {
359 : DevType deviceType;
360 0 : if (hrtGetDeviceType(deviceType) == HCCL_SUCCESS) {
361 0 : notifyMaxWaitTime = (deviceType == DevType::DEV_TYPE_910_93 || deviceType == DevType::DEV_TYPE_910B) ?\
362 : NOTIFY_MAX_WAIT_TIME_910_93 : NOTIFY_MAX_WAIT_TIME;
363 0 : init = true;
364 : }
365 : }
366 :
367 0 : HCCL_INFO("[GetNotifyMaxWaitTime] notifyMaxWaitTime is %us", notifyMaxWaitTime);
368 0 : return notifyMaxWaitTime;
369 : }
370 :
371 2 : HcclResult IsSupportAtomicWrite(DevType deviceType, u32 devicePhyId, bool& isSupportAtomicWrite)
372 : {
373 2 : if (deviceType == DevType::DEV_TYPE_910_93 || deviceType == DevType::DEV_TYPE_910B) {
374 0 : u32 version = 0;
375 0 : HcclResult ret = hrtRaGetInterfaceVersion(devicePhyId, RA_RS_GET_ROCE_API, &version);
376 0 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("%s call hrtRaGetInterfaceVersion ret[%d] devicePhyId[%u]",
377 : __func__, ret, devicePhyId), HCCL_E_NETWORK);
378 0 : isSupportAtomicWrite = (version >= RA_RS_ATOMIC_WRITE_VERSION);
379 0 : HCCL_INFO("%s deviceType[%d] devicePhyId[%u], version[%u], isSupportAtomicWrite[%d]",
380 : __func__, deviceType, devicePhyId, version, isSupportAtomicWrite);
381 0 : } else {
382 2 : isSupportAtomicWrite = false;
383 2 : HCCL_INFO("%s deviceType[%d] not support", __func__, deviceType);
384 : }
385 2 : return HCCL_SUCCESS;
386 : }
387 : }
|