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