LCOV - code coverage report
Current view: top level - coll_communicator_mgr/communicator/device - coll_comm_aicpu_mgr.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.6 % 137 120
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 16 16

            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 "coll_comm_aicpu_mgr.h"
      12              : #include "ns_recovery/aicpu/ns_recovery_func_lite.h"
      13              : #include "aicpu_daemon_service.h"
      14              : #include "hcclCommTaskExceptionLite.h"
      15              : #include "coll_comm_aicpu_destroy_func.h"
      16              : #include "aicpu_indop_env.h"
      17              : #include "unified_platform/pub_inc/config_plf_log.h"
      18              : #include "dlhal_function_v2.h"
      19              : #include "profiling_command_handle_lite.h"
      20              : #include "adapter_hal_pub.h"
      21              : #include "log.h"
      22              : #include <chrono>
      23              : #include <unistd.h>
      24              : 
      25              : thread_local CollCommAicpu* CollCommAicpuMgr::currentComm_ = nullptr;
      26              : 
      27       129758 : CollCommAicpuMgr& CollCommAicpuMgr::GetInstance()
      28              : {
      29       129758 :     static CollCommAicpuMgr instance;
      30       129758 :     return instance;
      31              : }
      32              : 
      33              : // ==================== 通信域初始化 ====================
      34              : 
      35           12 : HcclResult CollCommAicpuMgr::InitComm(CommAicpuParam* commAicpuParam)
      36              : {
      37           12 :     CHK_PTR_NULL(commAicpuParam);
      38              : 
      39           11 :     std::string group = commAicpuParam->hcomId;
      40           11 :     CollCommAicpu* aicpuComm = nullptr;
      41           11 :     CHK_RET(AcquireAndCreateComm(group, &aicpuComm));
      42           11 :     if (aicpuComm == nullptr) {
      43            0 :         HCCL_ERROR("[CollCommAicpuMgr][InitComm] aicpuComm is null group[%s]", group.c_str());
      44            0 :         return HCCL_E_PTR;
      45              :     }
      46              : 
      47           11 :     HcclResult ret = aicpuComm->InitAicpuIndOp(commAicpuParam);
      48           11 :     CHK_PRT_RET(
      49              :         ret != HCCL_SUCCESS,
      50              :         HCCL_ERROR(
      51              :             "[CollCommAicpuMgr][%s]errNo[0x%016llx] Failed to init independent op comm group[%s]", __func__,
      52              :             HCCL_ERROR_CODE(ret), group.c_str()),
      53              :         ret);
      54              : 
      55              :     // 全局环境初始化 (call_once 保证只执行一次)
      56              :     static std::once_flag initBackGround;
      57           11 :     std::call_once(initBackGround, [aicpuComm, this]() {
      58            3 :         this->InitBackGroundThread(aicpuComm->GetDevId());
      59            3 :     });
      60              : 
      61              :     static std::once_flag initEnv;
      62           11 :     std::call_once(initEnv, [commAicpuParam, this]() {
      63            3 :         this->InitIndopEnv(commAicpuParam);
      64            3 :     });
      65              : 
      66           11 :     return HCCL_SUCCESS;
      67           11 : }
      68              : 
      69           24 : HcclResult CollCommAicpuMgr::AcquireAndCreateComm(const std::string& group, CollCommAicpu** outComm)
      70              : {
      71           24 :     std::unique_lock<std::shared_mutex> rwlock(commMapMutex_);
      72           24 :     auto iter = commMap_.find(group);
      73           24 :     if (iter != commMap_.end()) {
      74              :         // 已存在 — 确保 CollCommAicpu 已创建
      75            2 :         if (iter->second.comm == nullptr) {
      76            0 :             EXCEPTION_CATCH(iter->second.comm = std::make_unique<CollCommAicpu>(), return HCCL_E_PTR);
      77              :         }
      78            2 :         *outComm = iter->second.comm.get();
      79            2 :         HCCL_INFO("[%s]Reuse existing comm group [%s]", __func__, group.c_str());
      80            2 :         return HCCL_SUCCESS;
      81              :     }
      82              : 
      83              :     // 未找到则创建新实例
      84           22 :     CommEntry entry;
      85           22 :     EXCEPTION_CATCH(entry.comm = std::make_unique<CollCommAicpu>(), return HCCL_E_PTR);
      86              : 
      87           22 :     *outComm = entry.comm.get();
      88           22 :     commMap_.insert({group, std::move(entry)});
      89           22 :     HCCL_RUN_INFO("[%s]Created new comm group [%s]", __func__, group.c_str());
      90           22 :     return HCCL_SUCCESS;
      91           24 : }
      92              : 
      93              : // ==================== 通信域注册表操作 ====================
      94              : 
      95           35 : CollCommAicpu* CollCommAicpuMgr::AcquireCommForUse(const std::string& group)
      96              : {
      97           35 :     HCCL_INFO("[CollCommAicpuMgr][%s]start, group[%s]", __func__, group.c_str());
      98           35 :     auto startTime = std::chrono::steady_clock::now();
      99           35 :     constexpr u32 pollIntervalUs = 10;
     100           35 :     constexpr u32 pollTimeoutMs = 10000;
     101           35 :     auto waitPollTimeOutMs = std::chrono::milliseconds(pollTimeoutMs);
     102              : 
     103              :     while (true) {
     104           35 :         std::unique_lock<std::shared_mutex> rwlock(commMapMutex_);
     105           35 :         auto iter = commMap_.find(group);
     106           35 :         if (iter == commMap_.end()) {
     107            1 :             HCCL_ERROR(
     108              :                 "[CollCommAicpuMgr][%s] group[%s] not found, exist size[%zu]", __func__, group.c_str(),
     109              :                 commMap_.size());
     110            1 :             auto curIter = commMap_.begin();
     111           12 :             while (curIter != commMap_.end()) {
     112           11 :                 HCCL_ERROR("[CollCommAicpuMgr][%s] exist group [%s]", __func__, curIter->first.c_str());
     113           11 :                 curIter++;
     114              :             }
     115            1 :             return nullptr;
     116              :         }
     117              : 
     118           34 :         if (iter->second.isUsed) {
     119            0 :             auto curTime = std::chrono::steady_clock::now();
     120            0 :             if ((curTime - startTime) >= waitPollTimeOutMs) {
     121            0 :                 startTime = curTime;
     122            0 :                 HCCL_RUN_INFO("[CollCommAicpuMgr][%s]wait, comm group [%s] has been used", __func__, group.c_str());
     123              :             }
     124            0 :             rwlock.unlock();
     125            0 :             usleep(pollIntervalUs);
     126            0 :             continue;
     127            0 :         }
     128           34 :         currentComm_ = iter->second.comm.get();
     129           34 :         iter->second.isUsed = true;
     130           34 :         HCCL_INFO("[CollCommAicpuMgr][%s]success, group[%s]", __func__, group.c_str());
     131           34 :         return iter->second.comm.get();
     132           35 :     }
     133              : }
     134              : 
     135           33 : void CollCommAicpuMgr::ReleaseComm(const std::string& group)
     136              : {
     137           33 :     std::unique_lock<std::shared_mutex> rwlock(commMapMutex_);
     138           33 :     auto iter = commMap_.find(group);
     139           33 :     if (iter == commMap_.end()) {
     140            1 :         return;
     141              :     }
     142           32 :     currentComm_ = nullptr;
     143           32 :     iter->second.isUsed = false;
     144           33 : }
     145              : 
     146           28 : CollCommAicpu* CollCommAicpuMgr::FindCommByGroup(const std::string& group)
     147              : {
     148           28 :     std::shared_lock<std::shared_mutex> lock(commMapMutex_);
     149           28 :     auto iter = commMap_.find(group);
     150           28 :     if (iter == commMap_.end()) {
     151            0 :         return nullptr;
     152              :     }
     153           28 :     return iter->second.comm.get();
     154           28 : }
     155              : 
     156            3 : CollCommAicpu* CollCommAicpuMgr::GetCurrentComm(const std::string& group)
     157              : {
     158            3 :     if (group.empty()) {
     159            1 :         HCCL_ERROR("[CollCommAicpuMgr][%s] comm group is empty", __func__);
     160            1 :         return nullptr;
     161              :     }
     162            2 :     if (currentComm_ == nullptr) {
     163            1 :         HCCL_ERROR("[CollCommAicpuMgr][%s] currentComm_ is nullptr", __func__);
     164            1 :         return nullptr;
     165              :     }
     166            1 :     if (currentComm_->GetIdentifier() != group) {
     167            0 :         HCCL_ERROR("[CollCommAicpuMgr][%s] comm group[%s] is not current comm group", __func__, group.c_str());
     168            0 :         return nullptr;
     169              :     }
     170            1 :     return currentComm_;
     171              : }
     172              : 
     173           11 : HcclResult CollCommAicpuMgr::DestroyComm(const std::string& group)
     174              : {
     175           11 :     std::unique_lock<std::shared_mutex> rwlock(commMapMutex_);
     176           11 :     auto iter = commMap_.find(group);
     177           11 :     if (iter == commMap_.end()) {
     178            2 :         HCCL_ERROR("[CollCommAicpuMgr][%s]group[%s] is not exist", __func__, group.c_str());
     179            2 :         return HCCL_E_PARA;
     180              :     }
     181              : 
     182            9 :     CollCommAicpu* aicpuComm = iter->second.comm.get();
     183            9 :     CHK_PTR_NULL(aicpuComm);
     184            9 :     aicpuComm->SetCommmStatus(HcclCommStatus::HCCL_COMM_STATUS_INVALID);
     185              : 
     186              :     // 正在使用中,不销毁,返回重试状态让调用方稍后再试
     187            9 :     if (iter->second.isUsed) {
     188            1 :         HCCL_RUN_WARNING("[CollCommAicpuMgr][%s]comm group [%s] has been used, skip erase", __func__, group.c_str());
     189            1 :         return HCCL_E_AGAIN;
     190              :     }
     191              : 
     192              :     // 防御性检查 legacy 通信域 busy 标记,避免 isUsed 与 legacy busy 不同步时误销毁
     193            8 :     if (aicpuComm->GetLegacy910CollComm() != nullptr && aicpuComm->IsLegacy910CollCommBusy()) {
     194            0 :         HCCL_RUN_WARNING("[CollCommAicpuMgr][%s]legacy comm group [%s] is busy, skip erase", __func__, group.c_str());
     195            0 :         return HCCL_E_AGAIN;
     196              :     }
     197              : 
     198            8 :     commMap_.erase(group);
     199            8 :     HCCL_RUN_INFO("[CollCommAicpuMgr][%s]Destroy comm group [%s] success.", __func__, group.c_str());
     200            8 :     return HCCL_SUCCESS;
     201           11 : }
     202              : 
     203        64812 : HcclResult CollCommAicpuMgr::GetAllComms(std::vector<std::pair<std::string, CollCommAicpu*>>& aicpuCommInfo)
     204              : {
     205              :     // 调用方必须在外部持有 commMapMutex_ 共享锁(保护遍历+访问 comm 成员的完整临界区)
     206        64824 :     for (auto& kv : commMap_) {
     207           12 :         aicpuCommInfo.push_back({kv.first, kv.second.comm.get()});
     208              :     }
     209        64812 :     return HCCL_SUCCESS;
     210              : }
     211              : 
     212        64810 : std::shared_mutex& CollCommAicpuMgr::GetMutex() { return commMapMutex_; }
     213              : 
     214              : // ==================== 全局环境初始化 ====================
     215              : 
     216            4 : void CollCommAicpuMgr::InitIndopEnv(CommAicpuParam* commAicpuParam)
     217              : {
     218            4 :     hcomm::SetTaskExceptionEnable(commAicpuParam->commConfig.taskExceptionEnable);
     219            4 :     Hccl::SetPlfDebugConfigValue(commAicpuParam->commConfig.plfDebugConfig);
     220            4 :     HCCL_RUN_INFO(
     221              :         "[%s]Env: taskExceptionEnable[%d], notifyWaitTimeout[%u s], plfDebugConfig[0x%llx]", __func__,
     222              :         commAicpuParam->commConfig.taskExceptionEnable, commAicpuParam->commConfig.notifyWaitTimeout,
     223              :         commAicpuParam->commConfig.plfDebugConfig);
     224            4 : }
     225              : 
     226            3 : void CollCommAicpuMgr::InitBackGroundThread(u32 devId)
     227              : {
     228              :     static auto commandToBackGroud = Hccl::CommandToBackGroud::Default;
     229            3 :     static auto daemonServiceRun = [](void* info) {
     230            3 :         Hccl::AicpuDaemonService::GetInstance().ServiceRun(info);
     231            3 :     };
     232            3 :     static auto daemonServiceStop = [](void* info) {
     233            3 :         Hccl::AicpuDaemonService::GetInstance().ServiceStop(info);
     234            3 :     };
     235              : 
     236            3 :     hcomm::HcclCommTaskExceptionLite::GetInstance().Init(devId);
     237            3 :     Hccl::AicpuDaemonService::GetInstance().Register(&hcomm::HcclCommTaskExceptionLite::GetInstance());
     238            3 :     Hccl::AicpuDaemonService::GetInstance().Register(&hccl::CollCommAicpuDestroyFunc::GetInstance());
     239            3 :     Hccl::AicpuDaemonService::GetInstance().Register(&NsRecoveryFuncLite::GetInstance());
     240              : 
     241            3 :     if (Hccl::StartMC2MaintenanceThread != nullptr) {
     242            3 :         Hccl::StartMC2MaintenanceThread(daemonServiceRun, &commandToBackGroud, daemonServiceStop, &commandToBackGroud);
     243            3 :         HCCL_RUN_INFO("[%s]start BackGround thread success.", __func__);
     244              :     } else {
     245            0 :         HCCL_WARNING("[%s]StartMC2MaintenanceThread func is nullptr", __func__);
     246              :     }
     247            3 : }
        

Generated by: LCOV version 2.0-1