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 : #ifndef HCCL_TEAM_MGR_H
12 : #define HCCL_TEAM_MGR_H
13 :
14 : #include <shared_mutex>
15 : #include <string>
16 : #include <unordered_map>
17 : #include <vector>
18 :
19 : #include "coll_comm.h"
20 : #include "hccl/hccl_res.h"
21 : #include "hcomm_team.h"
22 : #include "hcomm_team_defs.h"
23 :
24 : namespace hccl {
25 : /**
26 : * @note 职责:进程级 team 管理器,统一维护:
27 : * 1) WorldTeam 与 SubTeam 的父子关系(world→sub 列表 / sub→world);
28 : * 2) Team 粒度的 syncMem 本地内存(HcommTeamCreate 返回大小后 hrtMalloc,待 channel 交换);
29 : * 3) WorldTeam 与 Window 的 1:N 关系(worldTeam 存 window 列表),Team 与 Window 的 N:N 关系
30 : * (ChannelsCreate 通过 FindWorldTeam 解析 worldTeam 的所有 window)。
31 : */
32 : // 单个 window 的信息(归 worldTeam 所有,1:N)
33 : struct WindowInfo {
34 : HcommWindowHandle handle{nullptr}; // 业务 window 句柄
35 : CommMem registeredLocalMem{}; // 注册时的 localMem,判重基准(子集复用)
36 : HcclMemHandle localMemHandle{nullptr}; // localMem 注册得到的句柄
37 : std::string localMemTag; // localMem 的 memTag(ChannelsCreate 远端 tag 匹配用)
38 : bool exchanged{false}; // 是否已参与建链交换,避免重复交换
39 : };
40 :
41 : struct TeamEntry {
42 : CollComm* collComm{nullptr}; // 反查通信域
43 : HcommTeamHandle worldTeam{nullptr}; // 父 world team;world team 自身为 nullptr
44 : void* syncMemPtr{nullptr}; // 本地 syncMem 内存指针(hrtMalloc 申请)
45 : uint64_t syncMemSize{0}; // syncMem 内存大小
46 : // team 粒度 syncMem 内存句柄(首次 WindowRegister 时注册一次)
47 : HcclMemHandle syncMemHandle{nullptr};
48 : std::string syncMemTag;
49 : bool syncMemExchanged{false}; // syncMemHandle 是否已参与建链交换,避免重复交换
50 : // worldTeam 下注册的所有 window(1:N,仅 world team 条目填充)
51 : std::vector<WindowInfo> windows;
52 : // memberId→rankId 映射,下标=memberId,值=rankId。L2 维护,rankId 不下沉 L3。
53 : std::vector<uint32_t> rankIds;
54 : };
55 :
56 : class HcclTeamMgr {
57 : public:
58 : static HcclTeamMgr& GetInstance();
59 :
60 : // —— 创建/销毁 team 时调用 ——
61 : // 注册 world team:存 collComm + syncMem + rankIds(memberId→rankId 映射)。
62 : HcclResult RegisterWorldTeam(
63 : HcommTeamHandle worldTeam, CollComm* collComm, void* syncMemPtr, uint64_t syncMemSize, const uint32_t* rankIds,
64 : uint32_t rankNum);
65 : // 注册 sub team:校验 worldTeam 存在,建父子关系,存 syncMem + rankIds(collComm 取自 worldTeam 条目)。
66 : HcclResult RegisterSubTeam(
67 : HcommTeamHandle worldTeam, HcommTeamHandle subTeam, void* syncMemPtr, uint64_t syncMemSize,
68 : const uint32_t* rankIds, uint32_t rankNum);
69 : // 销毁 team:hrtFree syncMem + erase 自身。memHandles 不注销。
70 : void UnregisterTeam(HcommTeamHandle team);
71 :
72 : // —— 查询 ——
73 : CollComm* FindCollComm(HcommTeamHandle team);
74 : // sub→world;world team 自身返回自身,未找到返回 nullptr。
75 : HcommTeamHandle FindWorldTeam(HcommTeamHandle team);
76 : // 取 team 的 rankIds(memberId→rankId 映射)拷贝,未找到返回空。
77 : std::vector<uint32_t> GetRankIds(HcommTeamHandle team);
78 :
79 : // —— syncMem ——
80 : void* GetSyncMemPtr(HcommTeamHandle team);
81 : uint64_t GetSyncMemSize(HcommTeamHandle team);
82 :
83 : // —— team 粒度 syncMem 内存句柄(ChannelsCreate 首次注册并取用)——
84 : void SetTeamSyncMemHandle(HcommTeamHandle team, HcclMemHandle handle, const std::string& tag);
85 : HcclMemHandle GetTeamSyncMemHandle(HcommTeamHandle team);
86 : std::string GetTeamSyncMemTag(HcommTeamHandle team);
87 :
88 : // —— window 复用与判重(worldTeam 范围,HcclTeamWindowRegister 用)——
89 : // 遍历 worldTeam 的所有 window,找 registeredLocalMem 是入参 localMem 超集的 window。
90 : // 命中返回 true 并填充 window;否则 false。
91 : bool FindReusableWindow(HcommTeamHandle worldTeam, const CommMem& localMem, HcommWindowHandle& window);
92 : // 往 worldTeam 的 window 列表追加一条记录(HcclTeamWindowRegister 新建 window 后调用)。
93 : void AddWorldTeamWindow(
94 : HcommTeamHandle worldTeam, HcommWindowHandle window, const CommMem& localMem, HcclMemHandle localMemHandle,
95 : const std::string& localMemTag);
96 : // 取 worldTeam 的所有 window(拷贝),供 ChannelsCreate 遍历绑定。
97 : std::vector<WindowInfo> GetWorldTeamWindows(HcommTeamHandle worldTeam);
98 : // 收集未交换的 memHandles(syncMemHandle + window localMemHandle),标记已交换,避免重复建链交换。
99 : std::vector<HcclMemHandle> CollectPendingMemHandles(HcommTeamHandle worldTeam, HcommTeamHandle team);
100 : // 从 worldTeam 的 window 列表移除指定 window 的记录(HcclTeamWindowDeregister 用)。
101 : void RemoveWorldTeamWindow(HcommTeamHandle worldTeam, HcommWindowHandle window);
102 :
103 : // 取 worldTeam 下所有 subTeam 的 handle(worldTeam 销毁时连带销毁用)。锁内收集,调用方锁外销毁。
104 : std::vector<HcommTeamHandle> GetSubTeams(HcommTeamHandle worldTeam);
105 :
106 : // —— CollComm 析构兜底:清理属于该 comm 的所有 team 条目(hrtFree syncMem + erase)——
107 : void ClearByCollComm(CollComm* collComm);
108 :
109 : private:
110 6 : HcclTeamMgr() = default;
111 : ~HcclTeamMgr() = default;
112 : HcclTeamMgr(const HcclTeamMgr&) = delete;
113 : HcclTeamMgr& operator=(const HcclTeamMgr&) = delete;
114 :
115 : // ClearByCollComm 的单 team 销毁信息(锁内收集,锁外销毁)
116 : struct TeamCleanupInfo {
117 : HcommTeamHandle handle{nullptr};
118 : std::vector<HcommWindowHandle> windows; // 仅 worldTeam 非空
119 : void* syncMemPtr{nullptr};
120 : };
121 : // 锁内收集该通信域下所有 team 的销毁信息并 erase teamMap 条目
122 : std::vector<TeamCleanupInfo> CollectTeamCleanupInfo(CollComm* collComm);
123 : // 锁外依次销毁:window(L3)→ team(L3)→ syncMem(L2 本地内存)
124 : void ExecuteTeamCleanup(const std::vector<TeamCleanupInfo>& cleanupInfos);
125 :
126 : std::unordered_map<HcommTeamHandle, TeamEntry> teamMap_;
127 : std::shared_mutex mutex_; // 读写锁:查询类接口多读,注册/销毁类接口独占写
128 : };
129 : } // namespace hccl
130 :
131 : #endif // HCCL_TEAM_MGR_H
|