Line data Source code
1 : /**
2 : * Copyright (c) 2026 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 "root_info_detect_bridge.h"
12 :
13 : #include <memory>
14 :
15 : #include "acl/acl_rt.h"
16 : #include "hccl_common_v2.h"
17 : #include "log.h"
18 : #include "orion_adapter_rts.h"
19 : #include "rank_info_detect.h"
20 : #include "securec.h"
21 :
22 : namespace Hccl {
23 : namespace {
24 :
25 0 : HcclResult GetCurrentDeviceIds(s32& userDevId, s32& devPhyId)
26 : {
27 0 : userDevId = HrtGetDevice();
28 0 : aclError aclRet = aclrtGetPhyDevIdByUserDevId(userDevId, &devPhyId);
29 0 : CHK_PRT_RET(
30 : aclRet != ACL_SUCCESS,
31 : HCCL_ERROR("[%s] aclrtGetPhyDevIdByUserDevId failed, userDevId[%d], ret[%d]", __func__, userDevId, aclRet),
32 : HCCL_E_INTERNAL);
33 0 : return HCCL_SUCCESS;
34 : }
35 :
36 : // Provider 编译进 hcomm;hccl_v2 中保留的兼容入口只通过 RootInfoDetectBridge 转发到这里。
37 0 : HcclResult GetRootInfoImpl(HcclRootInfo* rootInfo)
38 : {
39 0 : HCCL_RUN_INFO("Entry-HcclGetRootInfo V950");
40 0 : CHK_PTR_NULL(rootInfo);
41 0 : HcclUs startut = TIME_NOW();
42 :
43 0 : HcclRootHandleV2 rootHandle{};
44 0 : std::shared_ptr<RankInfoDetect> rankInfoDetectServer;
45 0 : EXCEPTION_CATCH((rankInfoDetectServer = std::make_shared<RankInfoDetect>()), return HCCL_E_MEMORY);
46 0 : TRY_CATCH_RETURN(rankInfoDetectServer->SetupServer(rootHandle));
47 :
48 0 : u32 rootHandleLen = sizeof(HcclRootHandleV2);
49 0 : CHK_PRT_RET(
50 : rootHandleLen > HCCL_ROOT_INFO_BYTES,
51 : HCCL_ERROR(
52 : "[%s] hccl root info overflow. max length: %u, actual:%zu, identifier[%s]", __func__,
53 : HCCL_ROOT_INFO_BYTES, rootHandleLen, rootHandle.identifier),
54 : HCCL_E_INTERNAL);
55 :
56 : // 对外 HcclRootInfo 仍使用固定大小的不透明缓冲区,避免迁移实现后改变既有接口布局。
57 0 : s32 sRet = memcpy_s(rootInfo->internal, HCCL_ROOT_INFO_BYTES, &rootHandle, rootHandleLen);
58 0 : CHK_PRT_RET(
59 : sRet != EOK,
60 : HCCL_ERROR(
61 : "[%s] memcpy root info fail. errorno[%d] params:destMaxSize[%u], count[%u]", __func__, sRet,
62 : HCCL_ROOT_INFO_BYTES, rootHandleLen),
63 : HCCL_E_MEMORY);
64 :
65 0 : s32 userDevId = 0;
66 0 : s32 devPhyId = 0;
67 0 : CHK_RET(GetCurrentDeviceIds(userDevId, devPhyId));
68 0 : HCCL_RUN_INFO(
69 : "HcclGetRootInfoV2 success, take time [%lld]us, rootinfo: host ip[%s] port[%u] "
70 : "netMode[%s] identifier[%s], userDevId[%d], devPhyId[%d]",
71 : DURATION_US(TIME_NOW() - startut), rootHandle.ip, rootHandle.listenPort,
72 : rootHandle.netMode.Describe().c_str(), rootHandle.identifier, userDevId, devPhyId);
73 0 : return HCCL_SUCCESS;
74 0 : }
75 :
76 0 : HcclResult DetectRankTableImpl(
77 : u32 nRanks, u32 rank, const HcclRootHandleV2& rootHandle, RankTableInfo& rankTable,
78 : RootInfoDetectBridge::DetectContext& detectContext)
79 : {
80 0 : s32 userDevId = 0;
81 0 : s32 devPhyId = 0;
82 0 : CHK_RET(GetCurrentDeviceIds(userDevId, devPhyId));
83 0 : HCCL_RUN_INFO(
84 : "[%s] nRanks[%u], rank[%u] entry flat topo detect, rootinfo: host ip[%s] port[%u] "
85 : "netMode[%s] identifier[%s], userDevId[%d], devPhyId[%d]",
86 : __func__, nRanks, rank, rootHandle.ip, rootHandle.listenPort, rootHandle.netMode.Describe().c_str(),
87 : rootHandle.identifier, userDevId, devPhyId);
88 :
89 0 : std::shared_ptr<RankInfoDetect> rankInfoDetectAgent;
90 0 : EXCEPTION_CATCH((rankInfoDetectAgent = std::make_shared<RankInfoDetect>()), return HCCL_E_MEMORY);
91 :
92 0 : bool hasException = false;
93 0 : EXCEPTION_CATCH(rankInfoDetectAgent->SetupAgent(nRanks, rank, rootHandle), hasException = true);
94 0 : EXCEPTION_CATCH(
95 : rankInfoDetectAgent->WaitComplete(rootHandle.listenPort, RANKINFO_DETECT_SERVER_STATUS_IDLE),
96 : hasException = true);
97 0 : CHK_PRT_RET(
98 : hasException,
99 : HCCL_ERROR("[%s] RankInfoDetect SetupAgent fail, identifier[%s].", __func__, rootHandle.identifier),
100 : HCCL_E_INTERNAL);
101 :
102 0 : rankInfoDetectAgent->GetRankTable(rankTable);
103 : // bridge 不暴露 RankInfoDetect 类型;调用方持有类型擦除后的 shared_ptr,
104 : // 使 agent 及其探测资源在后续通信域初始化完成前保持有效。
105 0 : detectContext = rankInfoDetectAgent;
106 0 : HCCL_RUN_INFO("[%s] end.", __func__);
107 0 : return HCCL_SUCCESS;
108 0 : }
109 :
110 : const RootInfoDetectBridge ROOT_INFO_DETECT_BRIDGE = {GetRootInfoImpl, DetectRankTableImpl};
111 :
112 : // hcomm 链接 hccl_v2,并在自身装载阶段将 provider 回调注册到 hccl_v2 的槽位。
113 : // 这样兼容入口保持原符号不变,同时不再直接依赖 RankInfoDetect 实现类。
114 : struct RootInfoDetectBridgeRegistrar {
115 47 : RootInfoDetectBridgeRegistrar()
116 : {
117 : // 静态构造函数无法向加载方返回错误;重复注册由 bridge 侧日志记录。
118 47 : (void)RegisterRootInfoDetectBridge(ROOT_INFO_DETECT_BRIDGE);
119 47 : }
120 : };
121 :
122 : RootInfoDetectBridgeRegistrar g_rootInfoDetectBridgeRegistrar;
123 :
124 : } // namespace
125 : } // namespace Hccl
|