LCOV - code coverage report
Current view: top level - coll_communicator_mgr/team/hccl - hccl_team_c_adpt.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.5 % 383 362
Test Date: 2026-08-17 10:19:35 Functions: 100.0 % 20 20

            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 "hccl_team_c_adpt.h"
      12              : 
      13              : #include <sstream>
      14              : #include <string>
      15              : #include <unordered_map>
      16              : #include <utility>
      17              : #include <vector>
      18              : 
      19              : #include "adapter_rts_common.h"
      20              : #include "hccl_comm_pub.h"
      21              : #include "hccl_team.h"
      22              : #include "hccl_team_mgr.h"
      23              : #include "hccl/hccl_rank_graph.h"
      24              : #include "hccl/hccl_res.h"
      25              : #include "hcomm_result_defs.h"
      26              : #include "hcomm_team.h"
      27              : #include "hcomm_team_c_adpt.h"
      28              : #include "hcomm_team_mgr.h"
      29              : 
      30              : using namespace hccl;
      31              : 
      32              : /**
      33              :  * @note 职责:集合通信的通信域HcclTeam管理的C接口的C到C++适配
      34              :  */
      35              : 
      36              : /* 在 rankIds 中查找 selfRankId 的下标作为 memberId。
      37              :  * 例如 rankIds=[1,3,5,7],selfRankId=3,则 selfMemberId=1。未找到返回 HCCL_E_NOT_FOUND。 */
      38           43 : static HcclResult FindSelfMemberId(const HcclTeamCreateDesc* desc, uint32_t& selfMemberId)
      39              : {
      40           88 :     for (uint32_t i = 0; i < desc->rankNum; i++) {
      41           86 :         if (desc->rankIds[i] == desc->selfRankId) {
      42           41 :             selfMemberId = i;
      43           41 :             return HCCL_SUCCESS;
      44              :         }
      45              :     }
      46            2 :     HCCL_ERROR("[FindSelfMemberId] selfRankId[%u] not found in rankIds", desc->selfRankId);
      47            2 :     return HCCL_E_NOT_FOUND;
      48              : }
      49              : 
      50              : /* 从 HcclTeamCreateDesc 填充 HcommTeamCreateDesc。
      51              :  * worldMemberIds:worldTeam 传 nullptr(L3 生成 [0,memberNum));subTeam 传 worldTeam 的 memberId 列表。 */
      52           40 : static void FillHcommTeamCreateDesc(
      53              :     const HcclTeamCreateDesc* desc, uint32_t selfMemberId, const uint32_t* worldMemberIds,
      54              :     HcommTeamCreateDesc& hcommDesc)
      55              : {
      56              :     /* 用头文件 Init 初始化 ABI 头部(magicWord/version/size)与默认字段,再覆盖业务字段。 */
      57           40 :     (void)HcommTeamCreateDescInit(&hcommDesc);
      58           40 :     hcommDesc.memberNum = desc->rankNum;
      59           40 :     hcommDesc.selfMemberId = selfMemberId;
      60           40 :     hcommDesc.worldMemberIds = worldMemberIds;
      61           40 :     hcommDesc.requirement.signalCount = 0;  // 不支持配置,强制为0
      62           40 :     hcommDesc.requirement.counterCount = 0; // 不支持配置,强制为0
      63           40 :     hcommDesc.requirement.barrierCount = desc->requirement.barrierCount;
      64           40 :     hcommDesc.netLayer = desc->netLayer;
      65           40 :     hcommDesc.protocol = desc->protocol;
      66           40 : }
      67              : 
      68              : /* 反查 subTeam.rankIds 在 worldTeam.rankIds 中的下标作为 worldMemberIds(worldTeam 的 memberId)。
      69              :  * 用 unordered_map 预建 rankId→worldMemberId 反查表,O(N+M) 避免双重循环。 */
      70            7 : static HcclResult BuildSubTeamWorldMemberIds(
      71              :     HcommTeamHandle worldTeam, const uint32_t* subRankIds, uint32_t subRankNum, std::vector<uint32_t>& worldMemberIds)
      72              : {
      73            7 :     std::vector<uint32_t> worldRankIds = HcclTeamMgr::GetInstance().GetRankIds(worldTeam);
      74            7 :     CHK_PRT_RET(
      75              :         worldRankIds.empty(), HCCL_ERROR("[%s] GetRankIds failed, worldTeam[%p] not registered", __func__, worldTeam),
      76              :         HCCL_E_PARA);
      77            6 :     std::unordered_map<uint32_t, uint32_t> rankToMember;
      78            6 :     rankToMember.reserve(worldRankIds.size());
      79           18 :     for (uint32_t m = 0; m < worldRankIds.size(); m++) {
      80           12 :         rankToMember[worldRankIds[m]] = m;
      81              :     }
      82            6 :     worldMemberIds.resize(subRankNum);
      83           18 :     for (uint32_t i = 0; i < subRankNum; i++) {
      84           12 :         auto it = rankToMember.find(subRankIds[i]);
      85           12 :         CHK_PRT_RET(
      86              :             it == rankToMember.end(),
      87              :             HCCL_ERROR("[%s] subTeam rankId[%u] not in worldTeam rankIds", __func__, subRankIds[i]), HCCL_E_PARA);
      88           12 :         worldMemberIds[i] = it->second;
      89              :     }
      90            6 :     return HCCL_SUCCESS;
      91            7 : }
      92              : 
      93              : /* 申请 syncMem 本地内存。失败时回滚已创建的 team(HcommTeamDestroy)。 */
      94           35 : static HcclResult AllocTeamSyncMem(HcommTeamHandle* team, uint64_t syncMemSize, void*& syncMemPtr)
      95              : {
      96           35 :     syncMemPtr = nullptr;
      97           35 :     HcclResult mallocRet = hrtMalloc(&syncMemPtr, syncMemSize);
      98           35 :     if (mallocRet != HCCL_SUCCESS || syncMemPtr == nullptr) {
      99            2 :         HCCL_ERROR("[AllocTeamSyncMem] hrtMalloc failed, ret[%d] size[%llu]", mallocRet, syncMemSize);
     100            2 :         (void)HcommTeamDestroy(*team);
     101            2 :         *team = nullptr;
     102            2 :         return HCCL_E_MEMORY;
     103              :     }
     104           33 :     return HCCL_SUCCESS;
     105              : }
     106              : 
     107           43 : HcclResult HcclWorldTeamCreate(HcclComm comm, const HcclTeamCreateDesc* desc, HcommTeamHandle* worldTeam)
     108              : {
     109           43 :     CHK_PTR_NULL(comm);
     110           41 :     CHK_PTR_NULL(desc);
     111           40 :     CHK_PTR_NULL(worldTeam);
     112           39 :     CHK_PRT_RET(
     113              :         (desc->rankNum == 0 || desc->rankNum == 1),
     114              :         HCCL_ERROR("[%s] world team can not be empty or single rank", __func__), HCCL_E_PARA);
     115           37 :     CHK_PRT_RET(desc->rankIds == nullptr, HCCL_ERROR("[%s] rankIds is null", __func__), HCCL_E_PTR);
     116           36 :     CHK_PRT_RET(
     117              :         (desc->requirement.signalCount != 0 || desc->requirement.counterCount != 0),
     118              :         HCCL_ERROR(
     119              :             "[%s] signalCount[%u] and counterCount[%u] must be 0", __func__, desc->requirement.signalCount,
     120              :             desc->requirement.counterCount),
     121              :         HCCL_E_PARA);
     122           36 :     CHK_PRT_RET(
     123              :         desc->requirement.barrierCount == 0, HCCL_ERROR("[%s] barrierCount must be >= 1", __func__), HCCL_E_PARA);
     124              : 
     125           36 :     auto* hcclComm = static_cast<hccl::hcclComm*>(comm);
     126           36 :     CollComm* collComm = hcclComm->GetCollComm();
     127           36 :     CHK_PTR_NULL(collComm);
     128           36 :     const std::string commId = collComm->GetCommId();
     129              : 
     130              :     /* 0. 校验 desc 与通信域匹配(worldTeam 可为子集)。 */
     131           36 :     uint32_t commRankSize = collComm->GetRankSize();
     132           36 :     CHK_PRT_RET(
     133              :         desc->rankNum > commRankSize,
     134              :         HCCL_ERROR(
     135              :             "[%s] rankNum[%u] > commRankSize[%u], comm[%s]", __func__, desc->rankNum, commRankSize, commId.c_str()),
     136              :         HCCL_E_PARA);
     137              : 
     138              :     /* 1. selfRankId 是本 rank 的实际 rankId,需在 rankIds 中查找其下标作为 memberId。 */
     139           35 :     uint32_t selfMemberId = 0;
     140           35 :     CHK_RET(FindSelfMemberId(desc, selfMemberId));
     141              : 
     142              :     /* 2. 填充 HcommTeamCreateDesc,world team 无父 team,worldMemberIds 传 nullptr(L3 生成 [0,memberNum))。 */
     143           34 :     HcommTeamCreateDesc hcommDesc = {};
     144           34 :     FillHcommTeamCreateDesc(desc, selfMemberId, nullptr, hcommDesc);
     145              : 
     146              :     /* 3. 调用 Hcomm 层创建 world team,outSyncMemSize 为需要本地申请的 syncMem 字节数。 */
     147           34 :     uint64_t syncMemSize = 0;
     148           34 :     HcommResult ret = HcommTeamCreate(nullptr, &hcommDesc, worldTeam, &syncMemSize);
     149           34 :     CHK_PRT_RET(
     150              :         ret != 0 || *worldTeam == nullptr,
     151              :         HCCL_ERROR(
     152              :             "[%s] HcommTeamCreate failed, comm[%s] ret[%d] rankNum[%u] selfRankId[%u]", __func__, commId.c_str(), ret,
     153              :             desc->rankNum, desc->selfRankId),
     154              :         (ret != 0) ? static_cast<HcclResult>(ret) : HCCL_E_INTERNAL);
     155           32 :     CHK_PRT_RET(syncMemSize == 0, HCCL_ERROR("[%s] syncMemSize is 0", __func__), HCCL_E_PARA);
     156              : 
     157              :     /* 4. 申请 syncMem 本地内存,后续基于 channel 交换。失败时回滚已创建的 team。 */
     158           31 :     void* syncMemPtr = nullptr;
     159           31 :     CHK_RET(AllocTeamSyncMem(worldTeam, syncMemSize, syncMemPtr));
     160              : 
     161              :     /* 5. 注册 worldTeam 到 HcclTeamMgr(存 syncMem + collComm 反查 + rankIds),供 HcclSubTeamCreate/HcclTeamDestroy
     162              :      * 反查。 */
     163           30 :     HcclResult regRet = HcclTeamMgr::GetInstance().RegisterWorldTeam(
     164           30 :         *worldTeam, collComm, syncMemPtr, syncMemSize, desc->rankIds, desc->rankNum);
     165           30 :     if (regRet != HCCL_SUCCESS) {
     166            0 :         HCCL_ERROR("[%s] RegisterWorldTeam failed, comm[%s] ret[%d]", __func__, commId.c_str(), regRet);
     167            0 :         (void)hrtFree(syncMemPtr);
     168            0 :         (void)HcommTeamDestroy(*worldTeam);
     169            0 :         *worldTeam = nullptr;
     170            0 :         return regRet;
     171              :     }
     172              : 
     173           30 :     HCCL_INFO(
     174              :         "[%s] success, team[%p] comm[%s] rankNum[%u] selfRankId[%u] selfMemberId[%u] syncMemSize[%llu]", __func__,
     175              :         *worldTeam, commId.c_str(), desc->rankNum, desc->selfRankId, selfMemberId, syncMemSize);
     176           30 :     return HCCL_SUCCESS;
     177           36 : }
     178              : 
     179           13 : HcclResult HcclSubTeamCreate(HcommTeamHandle worldTeam, const HcclTeamCreateDesc* desc, HcommTeamHandle* team)
     180              : {
     181           13 :     CHK_PTR_NULL(worldTeam);
     182           12 :     CHK_PTR_NULL(desc);
     183           11 :     CHK_PTR_NULL(team);
     184              : 
     185           10 :     CHK_PRT_RET(
     186              :         (desc->rankNum == 0 || desc->rankNum == 1),
     187              :         HCCL_ERROR("[%s] sub team can not be empty or single rank", __func__), HCCL_E_PARA);
     188            9 :     CHK_PRT_RET(desc->rankIds == nullptr, HCCL_ERROR("[%s] rankIds is null", __func__), HCCL_E_PTR);
     189            8 :     CHK_PRT_RET(
     190              :         (desc->requirement.signalCount != 0 || desc->requirement.counterCount != 0),
     191              :         HCCL_ERROR(
     192              :             "[%s] signalCount[%u] and counterCount[%u] must be 0", __func__, desc->requirement.signalCount,
     193              :             desc->requirement.counterCount),
     194              :         HCCL_E_PARA);
     195            8 :     CHK_PRT_RET(
     196              :         desc->requirement.barrierCount == 0, HCCL_ERROR("[%s] barrierCount must be >= 1", __func__), HCCL_E_PARA);
     197              : 
     198              :     /* selfRankId 是本 rank 的实际 rankId,需在 rankIds 中查找其下标作为 memberId。 */
     199            8 :     uint32_t selfMemberId = 0;
     200            8 :     CHK_RET(FindSelfMemberId(desc, selfMemberId));
     201              : 
     202              :     /* 1. 反查 subTeam 的 rankIds 在 worldTeam.rankIds 中的下标作为 worldMemberIds(worldTeam 的 memberId)。 */
     203            7 :     std::vector<uint32_t> worldMemberIds;
     204            7 :     CHK_RET(BuildSubTeamWorldMemberIds(worldTeam, desc->rankIds, desc->rankNum, worldMemberIds));
     205              : 
     206              :     /* 2. 填充 HcommTeamCreateDesc:成员为 desc 的子集,父 team 为 worldTeam,worldMemberIds 用反查结果。 */
     207            6 :     HcommTeamCreateDesc hcommDesc = {};
     208            6 :     FillHcommTeamCreateDesc(desc, selfMemberId, worldMemberIds.data(), hcommDesc);
     209              : 
     210              :     /* 3. 调用 Hcomm 层创建 sub team,outSyncMemSize 为需要本地申请的 syncMem 字节数。 */
     211            6 :     uint64_t syncMemSize = 0;
     212            6 :     HcommResult ret = HcommTeamCreate(worldTeam, &hcommDesc, team, &syncMemSize);
     213            6 :     CHK_PRT_RET(
     214              :         ret != 0 || *team == nullptr,
     215              :         HCCL_ERROR(
     216              :             "[%s] HcommTeamCreate failed, ret[%d] rankNum[%u] selfRankId[%u]", __func__, ret, desc->rankNum,
     217              :             desc->selfRankId),
     218              :         (ret != 0) ? static_cast<HcclResult>(ret) : HCCL_E_INTERNAL);
     219            5 :     CHK_PRT_RET(syncMemSize == 0, HCCL_ERROR("[%s] syncMemSize is 0", __func__), HCCL_E_PARA);
     220              : 
     221              :     /* 4. 申请 syncMem 本地内存。失败时回滚已创建的 sub team。 */
     222            4 :     void* syncMemPtr = nullptr;
     223            4 :     CHK_RET(AllocTeamSyncMem(team, syncMemSize, syncMemPtr));
     224              : 
     225              :     /* 5. 注册 sub team 到 HcclTeamMgr(建父子关系 + 存 syncMem + rankIds,collComm 取自 worldTeam 条目)。 */
     226            3 :     HcclResult regRet = HcclTeamMgr::GetInstance().RegisterSubTeam(
     227            3 :         worldTeam, *team, syncMemPtr, syncMemSize, desc->rankIds, desc->rankNum);
     228            3 :     if (regRet != HCCL_SUCCESS) {
     229            0 :         HCCL_ERROR("[%s] RegisterSubTeam failed, ret[%d]", __func__, regRet);
     230            0 :         (void)hrtFree(syncMemPtr);
     231            0 :         (void)HcommTeamDestroy(*team);
     232            0 :         *team = nullptr;
     233            0 :         return regRet;
     234              :     }
     235              : 
     236            3 :     HCCL_INFO(
     237              :         "[%s] success, team[%p] worldTeam[%p] rankNum[%u] selfRankId[%u] selfMemberId[%u] syncMemSize[%llu]", __func__,
     238              :         *team, worldTeam, desc->rankNum, desc->selfRankId, selfMemberId, syncMemSize);
     239            3 :     return HCCL_SUCCESS;
     240            7 : }
     241              : 
     242           34 : HcclResult HcclTeamDestroy(HcommTeamHandle team)
     243              : {
     244           34 :     CHK_PTR_NULL(team);
     245              : 
     246              :     /* worldTeam 销毁时连带销毁其所有 subTeam 与 window(1:N),避免泄漏。subTeam 无子 team、无 window。 */
     247           33 :     if (HcclTeamMgr::GetInstance().FindWorldTeam(team) == team) {
     248              :         // 先销毁所有 subTeam(递归调 HcclTeamDestroy,subTeam 不会重复进入此分支)
     249           29 :         std::vector<HcommTeamHandle> subTeams = HcclTeamMgr::GetInstance().GetSubTeams(team);
     250           30 :         for (HcommTeamHandle sub : subTeams) {
     251            1 :             (void)HcclTeamDestroy(sub);
     252              :         }
     253              :         // 再销毁 worldTeam 拥有的 window
     254           29 :         std::vector<WindowInfo> windows = HcclTeamMgr::GetInstance().GetWorldTeamWindows(team);
     255           48 :         for (const auto& win : windows) {
     256           19 :             if (win.handle != nullptr) {
     257           19 :                 (void)HcommTeamWindowDeregister(team, win.handle);
     258              :             }
     259              :         }
     260           29 :     }
     261              : 
     262              :     /* 释放该 team 的 syncMem(hrtFree)+ erase 条目。 */
     263           33 :     HcclTeamMgr::GetInstance().UnregisterTeam(team);
     264              : 
     265           33 :     HcommResult ret = HcommTeamDestroy(team);
     266           33 :     CHK_PRT_RET(
     267              :         ret != 0, HCCL_ERROR("[%s] HcommTeamDestroy failed, ret[%d]", __func__, ret), static_cast<HcclResult>(ret));
     268              : 
     269           32 :     HCCL_INFO("[%s] success", __func__);
     270           32 :     return HCCL_SUCCESS;
     271              : }
     272              : 
     273              : /* 注册 team 的 syncMem 内存(team 粒度,仅首次注册一次)。
     274              :  * syncMemHandle 已存在则跳过注册;syncMemHandle 出参返回当前句柄(首次或已存在),供调用方日志使用。 */
     275              : static HcclResult
     276           11 : RegisterTeamSyncMem(HcommTeamHandle team, const std::string& commId, CommMems* commMem, HcclMemHandle& syncMemHandle)
     277              : {
     278           11 :     syncMemHandle = HcclTeamMgr::GetInstance().GetTeamSyncMemHandle(team);
     279           11 :     if (syncMemHandle != nullptr) {
     280            0 :         HCCL_INFO(
     281              :             "[RegisterTeamSyncMem] syncMemHandle[%p] already registered, comm[%s] team[%p]", syncMemHandle,
     282              :             commId.c_str(), team);
     283            0 :         return HCCL_SUCCESS;
     284              :     }
     285           11 :     void* syncMemPtr = HcclTeamMgr::GetInstance().GetSyncMemPtr(team);
     286           11 :     uint64_t syncMemSize = HcclTeamMgr::GetInstance().GetSyncMemSize(team);
     287           11 :     if (syncMemPtr == nullptr || syncMemSize == 0) {
     288            0 :         HCCL_ERROR(
     289              :             "[RegisterTeamSyncMem] syncMemPtr[%p] or syncMemSize[%llu] is invalid, comm[%s] team[%p]", syncMemPtr,
     290              :             syncMemSize, commId.c_str(), team);
     291            0 :         return HCCL_E_INTERNAL;
     292              :     }
     293           11 :     CommMem syncMemVar{};
     294           11 :     syncMemVar.type = COMM_MEM_TYPE_DEVICE;
     295           11 :     syncMemVar.addr = syncMemPtr;
     296           11 :     syncMemVar.size = syncMemSize;
     297           11 :     std::ostringstream syncMemTagStream;
     298           11 :     syncMemTagStream << HCCL_TEAM_SYNCMEM_TAG_PREFIX << commId << "_team_" << team << "_addr_" << syncMemPtr << "_size_"
     299           11 :                      << syncMemSize;
     300           11 :     const std::string syncMemTagStr = syncMemTagStream.str();
     301           11 :     HcclResult ret = commMem->CommRegMem(syncMemTagStr, syncMemVar, &syncMemHandle);
     302           11 :     CHK_PRT_RET(
     303              :         ret != HCCL_SUCCESS,
     304              :         HCCL_ERROR(
     305              :             "[RegisterTeamSyncMem] register syncMem failed, comm[%s] ret[%d] size[%llu]", commId.c_str(), ret,
     306              :             syncMemSize),
     307              :         ret);
     308           11 :     HcclTeamMgr::GetInstance().SetTeamSyncMemHandle(team, syncMemHandle, syncMemTagStr);
     309           11 :     return HCCL_SUCCESS;
     310           11 : }
     311              : 
     312              : /* 重复注册检测:worldTeam 已注册过 window 且本次 localMem 是某 window 的 registeredLocalMem 的子集,则复用。
     313              :  * 命中复用时设 *window 并返回 true;否则返回 false。 */
     314           18 : static bool TryReuseWindow(
     315              :     HcommTeamHandle worldTeam, const CommMem& localMem, const std::string& commId, HcommTeamHandle team,
     316              :     HcommWindowHandle* window)
     317              : {
     318           18 :     HcommWindowHandle reusableWindow = nullptr;
     319           18 :     if (!HcclTeamMgr::GetInstance().FindReusableWindow(worldTeam, localMem, reusableWindow)) {
     320           15 :         return false;
     321              :     }
     322            3 :     *window = reusableWindow;
     323            3 :     HCCL_INFO(
     324              :         "[TryReuseWindow] reuse registered window, comm[%s] team[%p] worldTeam[%p] window[%p]", commId.c_str(), team,
     325              :         worldTeam, *window);
     326            3 :     return true;
     327              : }
     328              : 
     329              : /* 非复用路径:在 worldTeam 上创建业务 window,注册 localMem(失败回滚 window),记录到 worldTeam 的 window 列表。 */
     330           15 : static HcclResult CreateNewWindow(
     331              :     HcommTeamHandle worldTeam, const CommMem& localMem, const std::string& commId, CommMems* commMem,
     332              :     HcommWindowHandle* window)
     333              : {
     334           15 :     HcommResult hRet = HcommTeamWindowRegister(worldTeam, nullptr, window, HCOMM_TEAM_WINDOW_FLAG_SYMMETRIC);
     335           15 :     if (hRet != 0 || *window == nullptr) {
     336            1 :         HCCL_ERROR(
     337              :             "[CreateNewWindow] HcommTeamWindowRegister failed, comm[%s] worldTeam[%p] ret[%d]", commId.c_str(),
     338              :             worldTeam, hRet);
     339            1 :         *window = nullptr;
     340            1 :         return (hRet != 0) ? static_cast<HcclResult>(hRet) : HCCL_E_INTERNAL;
     341              :     }
     342           14 :     std::ostringstream userTagStream;
     343           14 :     userTagStream << HCCL_TEAM_USERMEM_TAG_PREFIX << commId << "_addr_" << localMem.addr << "_size_" << localMem.size;
     344           14 :     const std::string userTag = userTagStream.str();
     345           14 :     HcclMemHandle userHandle = nullptr;
     346           14 :     HcclResult ret = commMem->CommRegMem(userTag, localMem, &userHandle);
     347           14 :     if (ret != HCCL_SUCCESS) {
     348            0 :         HCCL_ERROR("[CreateNewWindow] register localMem failed, comm[%s] ret[%d]", commId.c_str(), ret);
     349            0 :         (void)HcommTeamWindowDeregister(worldTeam, *window);
     350            0 :         *window = nullptr;
     351            0 :         return ret;
     352              :     }
     353           14 :     HcclTeamMgr::GetInstance().AddWorldTeamWindow(worldTeam, *window, localMem, userHandle, userTag);
     354           14 :     return HCCL_SUCCESS;
     355           14 : }
     356              : 
     357           26 : HcclResult HcclTeamWindowRegister(
     358              :     HcclComm comm, HcommTeamHandle worldTeam, const CommMem* localMem, HcommWindowHandle* window, uint32_t flag)
     359              : {
     360           26 :     CHK_PTR_NULL(comm);
     361           24 :     CHK_PTR_NULL(worldTeam);
     362           23 :     CHK_PTR_NULL(localMem);
     363           23 :     CHK_PTR_NULL(window);
     364           22 :     CHK_PRT_RET(flag != 0, HCCL_ERROR("[%s] flag[%u] is not supported, only support 0", __func__, flag), HCCL_E_PARA);
     365           22 :     CHK_PRT_RET(
     366              :         (localMem->type != COMM_MEM_TYPE_DEVICE),
     367              :         HCCL_ERROR("[%s] localMem type[%d] must be device", __func__, localMem->type), HCCL_E_PARA);
     368           22 :     CHK_PRT_RET(localMem->addr == nullptr, HCCL_ERROR("[%s] localMem addr is null", __func__), HCCL_E_PTR);
     369           21 :     CHK_PRT_RET(localMem->size == 0, HCCL_ERROR("[%s] localMem size is 0", __func__), HCCL_E_PARA);
     370              : 
     371           20 :     auto* hcclComm = static_cast<hccl::hcclComm*>(comm);
     372           20 :     CollComm* collComm = hcclComm->GetCollComm();
     373           20 :     CHK_PTR_NULL(collComm);
     374           20 :     const std::string commId = collComm->GetCommId();
     375              : 
     376              :     /* 入参 worldTeam 必须是 worldTeam(syncMem 注册已移至 ChannelsCreate,window 归 worldTeam 所有)。 */
     377           20 :     CHK_PRT_RET(
     378              :         HcclTeamMgr::GetInstance().FindWorldTeam(worldTeam) != worldTeam,
     379              :         HCCL_ERROR("[%s] worldTeam[%p] is not worldTeam", __func__, worldTeam), HCCL_E_PARA);
     380           18 :     CollComm* worldCollComm = HcclTeamMgr::GetInstance().FindCollComm(worldTeam);
     381           18 :     CHK_PTR_NULL(worldCollComm);
     382           18 :     CHK_PRT_RET(
     383              :         worldCollComm->GetCommId() != commId,
     384              :         HCCL_ERROR("[%s] worldTeam[%p] is not belong to comm[%s]", __func__, worldTeam, commId.c_str()), HCCL_E_PARA);
     385              : 
     386           18 :     auto myRank = collComm->GetMyRank();
     387           18 :     CHK_PTR_NULL(myRank);
     388           18 :     CommMems* commMem = myRank->GetCommMems();
     389           18 :     CHK_PTR_NULL(commMem);
     390              : 
     391           18 :     if (TryReuseWindow(worldTeam, *localMem, commId, worldTeam, window)) {
     392            3 :         return HCCL_SUCCESS;
     393              :     }
     394              : 
     395           15 :     CHK_RET(CreateNewWindow(worldTeam, *localMem, commId, commMem, window));
     396              : 
     397           14 :     HCCL_INFO("[%s] success, comm[%s] worldTeam[%p] window[%p]", __func__, commId.c_str(), worldTeam, *window);
     398           14 :     return HCCL_SUCCESS;
     399           20 : }
     400              : 
     401            6 : HcclResult HcclTeamWindowDeregister(HcommTeamHandle team, HcommWindowHandle window)
     402              : {
     403            6 :     CHK_PTR_NULL(team);
     404            5 :     CHK_PTR_NULL(window);
     405              : 
     406              :     /* 1. 取入参 team 对应的 worldTeam。 */
     407            4 :     HcommTeamHandle worldTeam = HcclTeamMgr::GetInstance().FindWorldTeam(team);
     408            4 :     CHK_PRT_RET(
     409              :         worldTeam == nullptr,
     410              :         HCCL_WARNING("[%s] FindWorldTeam failed, team[%p] not registered, maybe already destroyed", __func__, team),
     411              :         HCCL_SUCCESS);
     412              : 
     413              :     /* 2. 从 worldTeam 的 window 列表移除该 window 的记录(WindowInfo)。
     414              :      *    注:不注销 localMem 的 MemReg(由通信域析构兜底清理);不处理 syncMem(team 粒度,team 销毁时释放)。 */
     415            3 :     HcclTeamMgr::GetInstance().RemoveWorldTeamWindow(worldTeam, window);
     416              : 
     417              :     /* 3. 销毁 Hcomm 层 window。 */
     418            3 :     HcommResult ret = HcommTeamWindowDeregister(worldTeam, window);
     419            3 :     CHK_PRT_RET(
     420              :         ret != 0, HCCL_ERROR("[%s] HcommTeamWindowDeregister failed, ret[%d]", __func__, ret),
     421              :         static_cast<HcclResult>(ret));
     422              : 
     423            2 :     HCCL_INFO("[%s] success, team[%p] worldTeam[%p] window[%p]", __func__, team, worldTeam, window);
     424            2 :     return HCCL_SUCCESS;
     425              : }
     426              : 
     427              : /* 查询本rank到peerRank的link,填充 HcclChannelDesc 的 endpoint/protocol 字段。*/
     428              : static HcclResult
     429           11 : FillChannelDescForPeer(HcclComm comm, HcommTeamHandle team, uint32_t selfRank, uint32_t peerRank, HcclChannelDesc& desc)
     430              : {
     431           11 :     uint32_t netLayer = 0;
     432           11 :     HcommResult hRet = HcommTeamGetNetLayer(team, &netLayer);
     433           11 :     CHK_PRT_RET(
     434              :         hRet != 0, HCCL_ERROR("[%s] HcommTeamGetNetLayer failed, ret[%d]", __func__, hRet),
     435              :         (hRet != 0) ? static_cast<HcclResult>(hRet) : HCCL_E_INTERNAL);
     436              : 
     437           10 :     CommLink* links = nullptr;
     438           10 :     uint32_t linkNum = 0;
     439           10 :     HcclResult ret = HcclRankGraphGetLinks(comm, netLayer, selfRank, peerRank, &links, &linkNum);
     440           10 :     if (ret != HCCL_SUCCESS || links == nullptr || linkNum == 0) {
     441            1 :         HCCL_ERROR("[%s] no link found from rank[%u] to rank[%u]", __func__, selfRank, peerRank);
     442            1 :         return HCCL_E_NOT_FOUND;
     443              :     }
     444            9 :     const CommLink& link = links[0];
     445            9 :     desc.remoteRank = peerRank;
     446            9 :     desc.channelProtocol = link.linkAttr.linkProtocol;
     447            9 :     desc.localEndpoint = link.srcEndpointDesc;
     448            9 :     desc.remoteEndpoint = link.dstEndpointDesc;
     449            9 :     return HCCL_SUCCESS;
     450              : }
     451              : 
     452              : /* 从 HcclTeamMgr 取 team 的 rankIds(memberId→rankId),推算 memberNum 与 selfMemberId。 */
     453           11 : static HcclResult GetTeamMemberInfo(HcommTeamHandle team, uint32_t selfRank, ChannelsCreateCtx& ctx)
     454              : {
     455           11 :     ctx.rankIds = HcclTeamMgr::GetInstance().GetRankIds(team);
     456           11 :     CHK_PRT_RET(
     457              :         ctx.rankIds.empty(), HCCL_ERROR("[%s] GetRankIds failed, team[%p] not registered", __func__, team),
     458              :         HCCL_E_PARA);
     459           11 :     ctx.memberNum = static_cast<uint32_t>(ctx.rankIds.size());
     460           11 :     bool selfFound = false;
     461           22 :     for (uint32_t m = 0; m < ctx.memberNum; m++) {
     462           22 :         if (ctx.rankIds[m] == selfRank) {
     463           11 :             ctx.selfMemberId = m;
     464           11 :             selfFound = true;
     465           11 :             break;
     466              :         }
     467              :     }
     468           11 :     CHK_PRT_RET(!selfFound, HCCL_ERROR("[%s] selfRank[%u] not in team rankIds", __func__, selfRank), HCCL_E_PARA);
     469           11 :     return HCCL_SUCCESS;
     470              : }
     471              : 
     472              : /* 取 worldTeam 及其所有 window、memHandles;取 worldTeam 维度信息并计算 curToWorld 映射。 */
     473           11 : static HcclResult GetWorldTeamContext(HcommTeamHandle team, uint32_t selfRank, ChannelsCreateCtx& ctx)
     474              : {
     475           11 :     ctx.worldTeam = HcclTeamMgr::GetInstance().FindWorldTeam(team);
     476           11 :     CHK_PTR_NULL(ctx.worldTeam);
     477           11 :     ctx.windows = HcclTeamMgr::GetInstance().GetWorldTeamWindows(ctx.worldTeam); // 移动赋值,避免深拷贝
     478           11 :     ctx.syncMemTag = HcclTeamMgr::GetInstance().GetTeamSyncMemTag(team);
     479              :     // 只收集未交换的 memHandles(syncMemHandle + window localMemHandle),避免重复建链交换
     480           11 :     ctx.memHandles = HcclTeamMgr::GetInstance().CollectPendingMemHandles(ctx.worldTeam, team);
     481              : 
     482           11 :     ctx.worldRankIds = HcclTeamMgr::GetInstance().GetRankIds(ctx.worldTeam);
     483           11 :     CHK_PRT_RET(
     484              :         ctx.worldRankIds.empty(),
     485              :         HCCL_ERROR("[%s] GetRankIds failed, worldTeam[%p] not registered", __func__, ctx.worldTeam), HCCL_E_PARA);
     486           11 :     ctx.worldMemberNum = static_cast<uint32_t>(ctx.worldRankIds.size());
     487           11 :     bool worldSelfFound = false;
     488           22 :     for (uint32_t w = 0; w < ctx.worldMemberNum; w++) {
     489           22 :         if (ctx.worldRankIds[w] == selfRank) {
     490           11 :             ctx.worldSelfMemberId = w;
     491           11 :             worldSelfFound = true;
     492           11 :             break;
     493              :         }
     494              :     }
     495           11 :     CHK_PRT_RET(
     496              :         !worldSelfFound, HCCL_ERROR("[%s] selfRank[%u] not in worldTeam rankIds", __func__, selfRank), HCCL_E_PARA);
     497              :     // curToWorld[m] = 当前 team memberId m 的 rankId 在 worldRankIds 中的下标(worldMemberId)
     498           11 :     ctx.curToWorld.assign(ctx.memberNum, 0);
     499           33 :     for (uint32_t m = 0; m < ctx.memberNum; m++) {
     500           22 :         uint32_t rankId = ctx.rankIds[m];
     501           33 :         for (uint32_t w = 0; w < ctx.worldMemberNum; w++) {
     502           33 :             if (ctx.worldRankIds[w] == rankId) {
     503           22 :                 ctx.curToWorld[m] = w;
     504           22 :                 break;
     505              :             }
     506              :         }
     507              :     }
     508           11 :     return HCCL_SUCCESS;
     509              : }
     510              : 
     511              : /* 对每个 peer member 创建 channelCnt 个 channel,结果存 ctx.channelsByMember(self 为空)。 */
     512           11 : static HcclResult AcquireChannels(
     513              :     HcclComm comm, HcommTeamHandle team, const HcclTeamCreateChannelsDesc* desc, uint32_t selfRank,
     514              :     ChannelsCreateCtx& ctx)
     515              : {
     516           11 :     uint32_t channelCnt = desc->channelCnt;
     517           11 :     ctx.channelsByMember.assign(ctx.memberNum, {});
     518           27 :     for (uint32_t m = 0; m < ctx.memberNum; m++) {
     519           19 :         if (m == ctx.selfMemberId) {
     520            8 :             continue; // 本 member 不建到自己的 channel
     521              :         }
     522           11 :         uint32_t peerRank = ctx.rankIds[m];
     523           11 :         std::vector<HcclChannelDesc> channelDescs(channelCnt);
     524           11 :         HcclResult ret = HcclChannelDescInit(channelDescs.data(), channelCnt);
     525           11 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[%s] HcclChannelDescInit failed, ret[%d]", __func__, ret), ret);
     526           20 :         for (uint32_t c = 0; c < channelCnt; c++) {
     527           11 :             ret = FillChannelDescForPeer(comm, team, selfRank, peerRank, channelDescs[c]);
     528           11 :             CHK_PRT_RET(
     529              :                 ret != HCCL_SUCCESS,
     530              :                 HCCL_ERROR("[%s] FillChannelDescForPeer failed, peerRank[%u] ret[%d]", __func__, peerRank, ret), ret);
     531            9 :             channelDescs[c].notifyNum = desc->notifyNum;
     532            9 :             if (!ctx.memHandles.empty()) {
     533            9 :                 channelDescs[c].memHandles = ctx.memHandles.data();
     534            9 :                 channelDescs[c].memHandleNum = static_cast<uint32_t>(ctx.memHandles.size());
     535              :             }
     536              :         }
     537            9 :         ctx.channelsByMember[m].assign(channelCnt, 0);
     538            9 :         ret = HcclChannelAcquire(comm, desc->engine, channelDescs.data(), channelCnt, ctx.channelsByMember[m].data());
     539            9 :         CHK_PRT_RET(
     540              :             ret != HCCL_SUCCESS,
     541              :             HCCL_ERROR(
     542              :                 "[%s] HcclChannelAcquire failed, peerMember[%u] peerRank[%u] ret[%d]", __func__, m, peerRank, ret),
     543              :             ret);
     544           11 :     }
     545            8 :     return HCCL_SUCCESS;
     546              : }
     547              : 
     548              : /* 构造 HcommTeamBindChannelsDesc,绑定 team 与 channel。 */
     549            8 : static HcclResult BindTeamChannels(
     550              :     HcommTeamHandle team, const HcclTeamCreateChannelsDesc* desc, const std::string& commId, ChannelsCreateCtx& ctx)
     551              : {
     552            8 :     std::vector<uint32_t> channelNumPerMember(ctx.memberNum, 0);
     553            8 :     std::vector<uint64_t*> channelsByMemberIdPtrs(ctx.memberNum, nullptr);
     554              :     // 保持各 member 的 channel 数组生命周期覆盖 BindChannels 调用
     555           24 :     for (uint32_t m = 0; m < ctx.memberNum; m++) {
     556           16 :         channelNumPerMember[m] = static_cast<uint32_t>(ctx.channelsByMember[m].size());
     557           16 :         channelsByMemberIdPtrs[m] = ctx.channelsByMember[m].data();
     558              :     }
     559            8 :     HcommTeamBindChannelsDesc bindDesc = {};
     560            8 :     (void)HcommTeamBindChannelsDescInit(&bindDesc);
     561            8 :     bindDesc.memberNum = ctx.memberNum;
     562            8 :     bindDesc.channelNumPerMember = channelNumPerMember.data();
     563            8 :     bindDesc.channelsByMemberId = channelsByMemberIdPtrs.data();
     564            8 :     HcommResult hRet = HcommTeamBindChannels(team, &bindDesc);
     565            8 :     CHK_PRT_RET(
     566              :         hRet != 0,
     567              :         HCCL_ERROR(
     568              :             "[%s] HcommTeamBindChannels failed, comm[%s] ret[%d] memberNum[%u]", __func__, commId.c_str(), hRet,
     569              :             ctx.memberNum),
     570              :         static_cast<HcclResult>(hRet));
     571            7 :     return HCCL_SUCCESS;
     572            8 : }
     573              : 
     574              : /* 收集所有 peer channel 的远端内存+tag。selfMemberId 槽填本地 syncMem,peer 槽按 memberId 填远端 syncMem;
     575              :  * 各 window 的 localMem 远端按 (windowIndex, worldMemberId) 存 remoteMemsByWindow。 */
     576            7 : static HcclResult CollectRemoteMems(HcclComm comm, HcommTeamHandle team, ChannelsCreateCtx& ctx)
     577              : {
     578            7 :     ctx.syncMemRemoteMems.assign(ctx.memberNum, CommMem{});
     579              :     // selfMemberId 槽填本地 syncMem 内存
     580            7 :     void* localSyncMemPtr = HcclTeamMgr::GetInstance().GetSyncMemPtr(team);
     581            7 :     uint64_t localSyncMemSize = HcclTeamMgr::GetInstance().GetSyncMemSize(team);
     582            7 :     if (localSyncMemPtr != nullptr && localSyncMemSize > 0) {
     583            7 :         ctx.syncMemRemoteMems[ctx.selfMemberId].type = COMM_MEM_TYPE_DEVICE;
     584            7 :         ctx.syncMemRemoteMems[ctx.selfMemberId].addr = localSyncMemPtr;
     585            7 :         ctx.syncMemRemoteMems[ctx.selfMemberId].size = localSyncMemSize;
     586              :     }
     587              :     // window.mems 维度为 worldTeam memberNum,peer 槽按 worldMemberId 索引
     588           14 :     ctx.remoteMemsByWindow.assign(ctx.windows.size(), std::vector<CommMem>(ctx.worldMemberNum));
     589           19 :     for (uint32_t m = 0; m < ctx.memberNum; m++) {
     590           13 :         if (m == ctx.selfMemberId || ctx.channelsByMember[m].empty()) {
     591            6 :             continue;
     592              :         }
     593            7 :         uint32_t peerWorldMemberId = ctx.curToWorld[m];
     594           13 :         for (ChannelHandle channel : ctx.channelsByMember[m]) {
     595            7 :             if (channel == 0) {
     596            0 :                 continue;
     597              :             }
     598            7 :             uint32_t memNum = 0;
     599            7 :             CommMem* remoteMems = nullptr;
     600            7 :             char** memTags = nullptr;
     601            7 :             HcclResult gRet = HcclChannelGetRemoteMems(comm, channel, &memNum, &remoteMems, &memTags);
     602            7 :             CHK_PRT_RET(
     603              :                 gRet != HCCL_SUCCESS,
     604              :                 HCCL_ERROR("[%s] HcclChannelGetRemoteMems failed, member[%u] ret[%d]", __func__, m, gRet), gRet);
     605            6 :             uint32_t userMemFilled = 0;
     606            9 :             for (uint32_t r = 0; r < memNum; r++) {
     607              :                 std::string tag
     608            9 :                     = (memTags != nullptr && memTags[r] != nullptr) ? std::string(memTags[r]) : std::string();
     609            3 :                 if (!ctx.syncMemTag.empty()
     610            3 :                     && tag.compare(0, strlen(HCCL_TEAM_SYNCMEM_TAG_PREFIX), HCCL_TEAM_SYNCMEM_TAG_PREFIX) == 0) {
     611            0 :                     ctx.syncMemRemoteMems[m] = remoteMems[r]; // 按下标 memberId 存
     612            0 :                     continue;
     613              :                 }
     614            3 :                 if (userMemFilled < ctx.windows.size()
     615            3 :                     && tag.compare(0, strlen(HCCL_TEAM_USERMEM_TAG_PREFIX), HCCL_TEAM_USERMEM_TAG_PREFIX) == 0) {
     616            1 :                     ctx.remoteMemsByWindow[userMemFilled][peerWorldMemberId] = remoteMems[r];
     617            1 :                     userMemFilled++;
     618              :                 }
     619            3 :             }
     620              :         }
     621              :     }
     622            6 :     return HCCL_SUCCESS;
     623              : }
     624              : 
     625              : /* per window 调 HcommTeamWindowBindRemoteMems(worldMemberId 维 mems);调 HcommTeamBindRemoteSyncMem 绑定 syncMem。 */
     626            6 : static HcclResult BindWindowsAndSyncMem(HcommTeamHandle team, const std::string& commId, ChannelsCreateCtx& ctx)
     627              : {
     628              :     // 对每个 window 调 HcommTeamWindowBindRemoteMems
     629           11 :     for (size_t w = 0; w < ctx.windows.size(); w++) {
     630            6 :         std::vector<CommMem> windowMems(ctx.worldMemberNum);
     631           18 :         for (uint32_t m = 0; m < ctx.worldMemberNum; m++) {
     632           12 :             if (m == ctx.worldSelfMemberId) {
     633            6 :                 continue;
     634              :             }
     635            6 :             windowMems[m] = ctx.remoteMemsByWindow[w][m];
     636              :         }
     637              :         // self 槽填调用者在 WindowRegister 时传入的本地内存(registeredLocalMem),与 peer 槽的远端 CommMem 对称
     638            6 :         windowMems[ctx.worldSelfMemberId] = ctx.windows[w].registeredLocalMem;
     639            6 :         HcommTeamWindowDesc winDesc = {};
     640            6 :         (void)HcommTeamWindowDescInit(&winDesc);
     641            6 :         winDesc.mems = windowMems.data();
     642            6 :         winDesc.memberNum = ctx.worldMemberNum;
     643            6 :         HcommResult bindWinRet = HcommTeamWindowBindRemoteMems(team, ctx.windows[w].handle, &winDesc);
     644            6 :         CHK_PRT_RET(
     645              :             bindWinRet != 0,
     646              :             HCCL_ERROR(
     647              :                 "[%s] HcommTeamWindowBindRemoteMems failed, comm[%s] team[%p] window[%p] ret[%d]", __func__,
     648              :                 commId.c_str(), team, ctx.windows[w].handle, bindWinRet),
     649              :             static_cast<HcclResult>(bindWinRet));
     650            6 :     }
     651              :     // 调 HcommTeamBindRemoteSyncMem
     652            5 :     HcommTeamBindSyncMemDesc syncDesc = {};
     653            5 :     (void)HcommTeamBindSyncMemDescInit(&syncDesc);
     654            5 :     syncDesc.remoteMems = ctx.syncMemRemoteMems.data();
     655            5 :     syncDesc.remoteMemNum = static_cast<uint32_t>(ctx.syncMemRemoteMems.size());
     656            5 :     HcommResult bindSyncRet = HcommTeamBindRemoteSyncMem(team, &syncDesc);
     657            5 :     CHK_PRT_RET(
     658              :         bindSyncRet != 0,
     659              :         HCCL_ERROR(
     660              :             "[%s] HcommTeamBindRemoteSyncMem failed, comm[%s] team[%p] ret[%d] remoteMemNum[%zu]", __func__,
     661              :             commId.c_str(), team, bindSyncRet, ctx.syncMemRemoteMems.size()),
     662              :         static_cast<HcclResult>(bindSyncRet));
     663            4 :     return HCCL_SUCCESS;
     664              : }
     665              : 
     666           16 : HcclResult HcclTeamChannelsCreate(HcclComm comm, HcommTeamHandle team, const HcclTeamCreateChannelsDesc* desc)
     667              : {
     668           16 :     CHK_PTR_NULL(comm);
     669           15 :     CHK_PTR_NULL(team);
     670           14 :     CHK_PTR_NULL(desc);
     671           13 :     CHK_PRT_RET(desc->channelCnt == 0, HCCL_ERROR("[%s] channelCnt is 0", __func__), HCCL_E_PARA);
     672              : 
     673           12 :     auto* hcclComm = static_cast<hccl::hcclComm*>(comm);
     674           12 :     CollComm* collComm = hcclComm->GetCollComm();
     675           12 :     CHK_PTR_NULL(collComm);
     676           12 :     const std::string commId = collComm->GetCommId();
     677           12 :     uint32_t selfRank = collComm->GetMyRankId();
     678              : 
     679           12 :     CollComm* worldCollComm = HcclTeamMgr::GetInstance().FindCollComm(team);
     680           12 :     CHK_PTR_NULL(worldCollComm);
     681           11 :     CHK_PRT_RET(
     682              :         worldCollComm->GetCommId() != commId,
     683              :         HCCL_ERROR("[%s] team[%p] is not belong to comm[%s]", __func__, team, commId.c_str()), HCCL_E_PARA);
     684              : 
     685           11 :     ChannelsCreateCtx ctx{};
     686           11 :     CHK_RET(GetTeamMemberInfo(team, selfRank, ctx));
     687              : 
     688              :     /* 注册 team 的 syncMem 内存(team 粒度,仅首次注册一次),供 channel 交换与 GetWorldTeamContext 取用。 */
     689           11 :     auto myRank = collComm->GetMyRank();
     690           11 :     CHK_PTR_NULL(myRank);
     691           11 :     CommMems* commMem = myRank->GetCommMems();
     692           11 :     CHK_PTR_NULL(commMem);
     693           11 :     HcclMemHandle syncMemHandle = nullptr;
     694           11 :     CHK_RET(RegisterTeamSyncMem(team, commId, commMem, syncMemHandle));
     695              : 
     696           11 :     CHK_RET(GetWorldTeamContext(team, selfRank, ctx));
     697           11 :     CHK_RET(AcquireChannels(comm, team, desc, selfRank, ctx));
     698            8 :     CHK_RET(BindTeamChannels(team, desc, commId, ctx));
     699            7 :     CHK_RET(CollectRemoteMems(comm, team, ctx));
     700            6 :     CHK_RET(BindWindowsAndSyncMem(team, commId, ctx));
     701              : 
     702            4 :     HCCL_INFO(
     703              :         "[%s] success, comm[%s] team[%p] memberNum[%u] channelCnt[%u] windowNum[%zu] syncMemRemoteMemNum[%zu]",
     704              :         __func__, commId.c_str(), team, ctx.memberNum, desc->channelCnt, ctx.windows.size(),
     705              :         ctx.syncMemRemoteMems.size());
     706            4 :     return HCCL_SUCCESS;
     707           12 : }
        

Generated by: LCOV version 2.0-1