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