LCOV - code coverage report
Current view: top level - legacy/ascend910/framework/cluster_maintenance/recovery/operator_retry - opretry_manager.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 177 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 13 0

            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 "opretry_manager.h"
      12              : #include "opretry_link_manage.h"
      13              : #include "opretry_connection_pub.h"
      14              : #include "opretry_agent.h"
      15              : #include "opretry_server.h"
      16              : #include "externalinput_pub.h"
      17              : #include "adapter_rts_common.h"
      18              : #include "sal_pub.h"
      19              : 
      20              : namespace hccl {
      21            0 : HcclResult OpRetryManager::Init()
      22              : {
      23            0 :     CHK_PRT_RET(initialized_ == true, HCCL_WARNING("OpRetryManager has already initialized"), HCCL_SUCCESS);
      24            0 :     initialized_ = true;
      25            0 :     HCCL_INFO("OpRetryManager Init success");
      26            0 :     return HCCL_SUCCESS;
      27              : }
      28              : 
      29            0 : HcclResult OpRetryManager::RegisterOpRetryMachine(
      30              :     OpRetryAgentParam& agentParam, u32 rankSize, bool isRoot,
      31              :     std::map<u32, std::shared_ptr<HcclSocket>>& serverConnections, const OpRetryServerInfo& serverInfo)
      32              : {
      33            0 :     std::unique_lock<std::mutex> lock(ProcessLock_);
      34            0 :     CHK_SMART_PTR_NULL(agentParam.h2dPtr);
      35            0 :     CHK_SMART_PTR_NULL(agentParam.d2hPtr);
      36            0 :     CHK_SMART_PTR_NULL(agentParam.opStreamPtr);
      37            0 :     CHK_PRT_RET(
      38              :         agentParam.group.empty(), HCCL_ERROR("[OpRetryManager][RegisterOpRetryMachine]params invalid, group is empty"),
      39              :         HCCL_E_PARA);
      40            0 :     if (agentParam.agentConnection == nullptr && serverConnections.empty()) {
      41            0 :         CHK_RET(OpRetryConnectionPub::Init(agentParam.group, rankSize, serverInfo, agentParam.agentInfo));
      42            0 :         CHK_RET(
      43              :             OpRetryConnectionPub::GetConns(agentParam.group, isRoot, agentParam.agentConnection, serverConnections));
      44              :     }
      45              :     // 初始化
      46            0 :     if (initialized_ == false) {
      47            0 :         CHK_RET(Init());
      48              :     }
      49              : 
      50              :     // 注册agent状态机
      51            0 :     CHK_RET(RegisterAgentRetryMachine(agentParam));
      52              : 
      53              :     // 注册server状态机
      54            0 :     if (isRoot) {
      55            0 :         CHK_RET(RegisterServerRetryMachine(agentParam.group, serverConnections, agentParam.agentInfo));
      56              :     }
      57            0 :     HCCL_INFO("[Register][RetryMachine]group[%s] register success", agentParam.group.c_str());
      58            0 :     return HCCL_SUCCESS;
      59            0 : }
      60              : 
      61            0 : HcclResult OpRetryManager::RegisterAgentRetryMachine(OpRetryAgentParam& agentParam)
      62              : {
      63            0 :     std::string& group = agentParam.group;
      64            0 :     if (agentOpRetry_.find(group) != agentOpRetry_.end()) {
      65            0 :         HCCL_INFO("[Register][AgentRetryMachine]group[%s] has Registered to agentOpRetry, skip", group.c_str());
      66            0 :         return HCCL_SUCCESS;
      67              :     }
      68              : 
      69            0 :     RetryCtrl retryCtrl;
      70            0 :     agentOpRetry_.insert(std::make_pair(group, std::move(retryCtrl)));
      71            0 :     std::shared_ptr<OpRetryBase> retryPtr;
      72            0 :     EXCEPTION_CATCH((retryPtr = std::make_shared<OpRetryAgentRunning>()), return HCCL_E_PTR);
      73            0 :     EXCEPTION_CATCH(
      74              :         (agentOpRetry_[group].retryCtx = std::make_shared<RetryContext>(agentParam, retryPtr)), return HCCL_E_PTR);
      75            0 :     agentOpRetry_[group].startExec = true;
      76            0 :     agentOpRetry_[group].retryCtx->SetRetryState(RETRY_STATE_AGENT_RUNNING, retryPtr);
      77              : 
      78            0 :     aclrtContext ctx = nullptr;
      79            0 :     CHK_RET(hrtCtxGetCurrent(&ctx));
      80            0 :     agentOpRetry_[group].thread.reset(new (std::nothrow) std::thread(
      81            0 :         &OpRetryManager::RetryStateMonitor, this, group, agentOpRetry_[group].retryCtx,
      82            0 :         std::ref(agentOpRetry_[group].startExec), ctx));
      83            0 :     CHK_SMART_PTR_NULL(agentOpRetry_[group].thread);
      84            0 :     HCCL_INFO(
      85              :         "[%s]group[%s] rank[%u], register to agentOpRetry success", __func__, group.c_str(),
      86              :         agentParam.agentInfo.userRank);
      87            0 :     return HCCL_SUCCESS;
      88            0 : }
      89              : 
      90            0 : HcclResult OpRetryManager::RegisterServerRetryMachine(
      91              :     const std::string& group, std::map<u32, std::shared_ptr<HcclSocket>>& serverConnections,
      92              :     const OpRetryAgentInfo& agentInfo)
      93              : {
      94            0 :     if (serverOpRetry.find(group) != serverOpRetry.end()) {
      95            0 :         HCCL_INFO("[Register][ServerRetryMachine]group[%s] has Registered to serverOpRetry, skip", group.c_str());
      96            0 :         return HCCL_SUCCESS;
      97              :     }
      98            0 :     for (auto it = serverConnections.begin(); it != serverConnections.end(); ++it) {
      99            0 :         CHK_SMART_PTR_NULL(it->second);
     100              :     }
     101              : 
     102            0 :     RetryCtrl retryCtrl;
     103            0 :     serverOpRetry.insert(std::make_pair(group, std::move(retryCtrl)));
     104            0 :     std::shared_ptr<OpRetryBase> retryPtr = nullptr;
     105            0 :     EXCEPTION_CATCH((retryPtr = std::make_shared<OpRetryServerRunning>()), return HCCL_E_PTR);
     106              : 
     107            0 :     EXCEPTION_CATCH(
     108              :         (serverOpRetry[group].retryCtx = std::make_shared<RetryContext>(serverConnections, retryPtr, agentInfo)),
     109              :         return HCCL_E_PTR);
     110            0 :     serverOpRetry[group].startExec = true;
     111            0 :     serverOpRetry[group].retryCtx->SetRetryState(RETRY_STATE_SERVER_RUNNING, retryPtr);
     112              : 
     113            0 :     HcclRtContext ctx = nullptr;
     114            0 :     CHK_RET(hrtCtxGetCurrent(&ctx));
     115            0 :     serverOpRetry[group].thread.reset(new (std::nothrow) std::thread(
     116            0 :         &OpRetryManager::RetryStateMonitor, this, group, serverOpRetry[group].retryCtx,
     117            0 :         std::ref(serverOpRetry[group].startExec), ctx));
     118            0 :     CHK_SMART_PTR_NULL(serverOpRetry[group].thread);
     119            0 :     HCCL_INFO("[%s]group[%s] rank[%u], register to serverOpRetry success", __func__, group.c_str(), agentInfo.userRank);
     120            0 :     return HCCL_SUCCESS;
     121            0 : }
     122              : 
     123            0 : HcclResult OpRetryManager::UnRegisterOpRetryManager(const std::string& group)
     124              : {
     125            0 :     std::unique_lock<std::mutex> lock(ProcessLock_);
     126            0 :     CHK_PRT_RET(
     127              :         group.empty(), HCCL_ERROR("[OpRetryManager][UnRegisterOpRetryManager]params invalid, group is empty"),
     128              :         HCCL_E_PARA);
     129            0 :     HCCL_INFO("[UnRegister][OpRetryManager]group[%s] unregister start", group.c_str());
     130            0 :     CHK_PRT_RET(initialized_ == false, HCCL_WARNING("OpRetryManager has been destroyed"), HCCL_SUCCESS);
     131              : 
     132            0 :     if (agentOpRetry_.find(group) != agentOpRetry_.end()) {
     133            0 :         agentOpRetry_[group].startExec = false;
     134            0 :         if (agentOpRetry_[group].thread != nullptr && agentOpRetry_[group].thread->joinable()) {
     135            0 :             agentOpRetry_[group].thread->join();
     136              :         }
     137            0 :         agentOpRetry_.erase(group);
     138            0 :         HCCL_INFO("[UnRegister][OpRetryManager]group[%s] unregister agentOpRetry success", group.c_str());
     139              :     }
     140              : 
     141            0 :     if (serverOpRetry.find(group) != serverOpRetry.end()) {
     142            0 :         serverOpRetry[group].startExec = false;
     143            0 :         if (serverOpRetry[group].thread != nullptr && serverOpRetry[group].thread->joinable()) {
     144            0 :             serverOpRetry[group].thread->join();
     145              :         }
     146            0 :         serverOpRetry.erase(group);
     147            0 :         HCCL_INFO("[UnRegister][OpRetryManager]group[%s] unregister serverOpRetry success", group.c_str());
     148              :     }
     149            0 :     HCCL_INFO("[UnRegister][OpRetryManager]group[%s] unregister success", group.c_str());
     150            0 :     OpRetryConnectionPub::DeInit(group);
     151            0 :     return HCCL_SUCCESS;
     152            0 : }
     153              : 
     154            0 : void OpRetryManager::RetryStateMonitor(
     155              :     const std::string& group, std::shared_ptr<RetryContext> retryCtx, const bool& startExec, HcclRtContext rtCtx)
     156              : {
     157            0 :     CHK_SMART_PTR_RET_NULL(retryCtx);
     158            0 :     CHK_SMART_PTR_RET_NULL(rtCtx);
     159            0 :     CHK_RET_NULL(hrtCtxSetCurrent(rtCtx));
     160              : 
     161              :     // 给当前线程添加名字
     162            0 :     SetThreadName("Hccl_OpRetry");
     163              : 
     164            0 :     HCCL_RUN_INFO(
     165              :         "[%s]%s start, group[%s], rankId[%u], IpInfo[%s]", __func__, retryCtx->GetOpRetryMachineType(), group.c_str(),
     166              :         retryCtx->GetRankId(), retryCtx->GetDfxIpInfo());
     167              : 
     168            0 :     HcclResult ret = HCCL_SUCCESS;
     169            0 :     while (initialized_ && startExec) {
     170            0 :         ret = retryCtx->Request();
     171            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("RetryStateMonitor group[%s] exec fail", group.c_str()), );
     172              :     }
     173            0 :     HCCL_INFO(
     174              :         "RetryStateMonitor group[%s] exit, ret[%d], initialized_[%d], startExec[%d]", group.c_str(), ret, initialized_,
     175              :         startExec);
     176              : }
     177              : 
     178            0 : HcclResult OpRetryManager::AddLinkInfoByIdentifier(
     179              :     s32 deviceLogicID, const std::string& identifier, const std::string& newTag, std::vector<u32>& remoteRankList,
     180              :     bool incre)
     181              : {
     182            0 :     return OpretryLinkManage::GetInstance(deviceLogicID)
     183            0 :         .AddLinkInfoByIdentifier(identifier, newTag, remoteRankList, incre);
     184              : }
     185              : 
     186            0 : HcclResult OpRetryManager::GetLinkInfoByIdentifier(
     187              :     s32 deviceLogicID, const std::string& identifier, const std::string& newTag, std::vector<u32>& remoteRankList,
     188              :     bool isGetGroupAllRemoteRank)
     189              : {
     190            0 :     if (isGetGroupAllRemoteRank) {
     191            0 :         return OpretryLinkManage::GetInstance(deviceLogicID).GetLinkInfoByIdentifier(identifier, remoteRankList);
     192              :     }
     193            0 :     return OpretryLinkManage::GetInstance(deviceLogicID).GetLinkInfoByIdentifier(identifier, newTag, remoteRankList);
     194              : }
     195              : 
     196            0 : HcclResult OpRetryManager::DeleteLinkInfoByIdentifier(s32 deviceLogicID, const std::string& identifier)
     197              : {
     198            0 :     return OpretryLinkManage::GetInstance(deviceLogicID).DeleteLinkInfoByIdentifier(identifier);
     199              : }
     200              : 
     201            0 : HcclResult OpRetryManager::SetRetryStateToWaitResume(const std::string& group, bool isRoot)
     202              : {
     203            0 :     std::unique_lock<std::mutex> lock(ProcessLock_);
     204            0 :     std::chrono::seconds setTimeout = std::chrono::seconds(GetExternalInputHcclLinkTimeOut());
     205            0 :     std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
     206            0 :     if (agentOpRetry_.find(group) != agentOpRetry_.end()) {
     207            0 :         agentOpRetry_[group].retryCtx->isAgentStateWaitResume_ = true;
     208            0 :         while (agentOpRetry_[group].retryCtx->GetRetryState() != RETRY_STATE_AGENT_WAIT_RESUME) {
     209            0 :             std::chrono::steady_clock::time_point curTime = std::chrono::steady_clock::now();
     210            0 :             const auto setTime = std::chrono::duration_cast<std::chrono::seconds>(curTime - startTime);
     211            0 :             if (setTime > setTimeout) {
     212            0 :                 HCCL_ERROR(
     213              :                     "[OpRetryManager][SetRetryStateToWaitResume]group[%s], set agent state to wait resume timeout.",
     214              :                     group.c_str());
     215            0 :                 return HCCL_E_TIMEOUT;
     216              :             }
     217            0 :             if (agentOpRetry_[group].retryCtx->isOpRetryQuit) {
     218            0 :                 agentOpRetry_[group].retryCtx->isOpRetryQuit = false;
     219            0 :                 break;
     220              :             }
     221              :         }
     222              :     }
     223              : 
     224            0 :     if (isRoot && serverOpRetry.find(group) != serverOpRetry.end()) {
     225            0 :         serverOpRetry[group].retryCtx->isServerStateWaitResume_ = true;
     226            0 :         while (serverOpRetry[group].retryCtx->GetRetryState() != RETRY_STATE_SERVER_WAIT_RESUME) {
     227            0 :             std::chrono::steady_clock::time_point curTime = std::chrono::steady_clock::now();
     228            0 :             const auto setTime = std::chrono::duration_cast<std::chrono::seconds>(curTime - startTime);
     229            0 :             if (setTime > setTimeout) {
     230            0 :                 HCCL_ERROR(
     231              :                     "[OpRetryManager][SetRetryStateToWaitResume]group[%s], set server state to wait resume timeout.",
     232              :                     group.c_str());
     233            0 :                 return HCCL_E_TIMEOUT;
     234              :             }
     235            0 :             if (serverOpRetry[group].retryCtx->isOpRetryQuit) {
     236            0 :                 serverOpRetry[group].retryCtx->isOpRetryQuit = false;
     237            0 :                 break;
     238              :             }
     239              :         }
     240              :     }
     241            0 :     HCCL_INFO("[OpRetryManager][SetRetryStateToWaitResume]group[%s], set state to wait resume success", group.c_str());
     242            0 :     return HCCL_SUCCESS;
     243            0 : }
     244              : 
     245            0 : HcclResult OpRetryManager::ExitWaitResumeState(
     246              :     const std::string& group, bool isRoot, bool haveCommEnableBackupLink, bool& isChangedLink)
     247              : {
     248            0 :     HCCL_RUN_INFO(
     249              :         "[OpRetryManager][ExitWaitResumeState]group[%s], haveCommEnableBackupLink[%d] exit wait resume state start",
     250              :         group.c_str(), haveCommEnableBackupLink);
     251            0 :     std::unique_lock<std::mutex> lock(ProcessLock_);
     252            0 :     std::chrono::seconds exitTimeout = std::chrono::seconds(GetExternalInputHcclLinkTimeOut());
     253            0 :     std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
     254            0 :     if (isRoot && serverOpRetry.find(group) != serverOpRetry.end()) {
     255            0 :         serverOpRetry[group].retryCtx->haveCommEnableBackupLink_ = haveCommEnableBackupLink;
     256              :         std::atomic_thread_fence(std::memory_order_seq_cst);
     257            0 :         serverOpRetry[group].retryCtx->isServerStateWaitResume_ = false;
     258              :     }
     259            0 :     if (agentOpRetry_.find(group) != agentOpRetry_.end()) {
     260            0 :         agentOpRetry_[group].retryCtx->haveCommEnableBackupLink_ = haveCommEnableBackupLink;
     261              :         std::atomic_thread_fence(std::memory_order_seq_cst);
     262            0 :         agentOpRetry_[group].retryCtx->isAgentStateWaitResume_ = false;
     263              :     }
     264            0 :     while (isRoot && serverOpRetry.find(group) != serverOpRetry.end()
     265            0 :            && serverOpRetry[group].retryCtx->GetRetryState() != RETRY_STATE_SERVER_RUNNING) {
     266            0 :         std::chrono::steady_clock::time_point curTime = std::chrono::steady_clock::now();
     267            0 :         const auto exitTime = std::chrono::duration_cast<std::chrono::seconds>(curTime - startTime);
     268            0 :         if (exitTime > exitTimeout) {
     269            0 :             HCCL_ERROR(
     270              :                 "[OpRetryManager][ExitWaitResumeState]group[%s], state[%d], server exit wait resume state timeout",
     271              :                 group.c_str(), serverOpRetry[group].retryCtx->GetRetryState());
     272            0 :             return HCCL_E_TIMEOUT;
     273              :         }
     274            0 :         if (haveCommEnableBackupLink) {
     275            0 :             isChangedLink = true;
     276              :         }
     277              :     }
     278            0 :     while (agentOpRetry_.find(group) != agentOpRetry_.end()
     279            0 :            && agentOpRetry_[group].retryCtx->GetRetryState() != RETRY_STATE_AGENT_RUNNING) {
     280            0 :         std::chrono::steady_clock::time_point curTime = std::chrono::steady_clock::now();
     281            0 :         const auto exitTime = std::chrono::duration_cast<std::chrono::seconds>(curTime - startTime);
     282            0 :         if (exitTime > exitTimeout) {
     283            0 :             HCCL_ERROR(
     284              :                 "[OpRetryManager][ExitWaitResumeState]group[%s], state[%d], agent exit wait resume state timeout",
     285              :                 group.c_str(), agentOpRetry_[group].retryCtx->GetRetryState());
     286            0 :             return HCCL_E_TIMEOUT;
     287              :         }
     288            0 :         if (agentOpRetry_[group].retryCtx->isRecivedCmdToCheckLink) {
     289            0 :             isChangedLink = true;
     290              :         }
     291              :     }
     292            0 :     HCCL_RUN_INFO(
     293              :         "[OpRetryManager][ExitWaitResumeState]group[%s], exit wait resume state success, isChangedLink[%d]",
     294              :         group.c_str(), isChangedLink);
     295            0 :     return HCCL_SUCCESS;
     296            0 : }
     297              : 
     298            0 : bool OpRetryManager::IsPaused(const std::string& group)
     299              : {
     300            0 :     return (serverOpRetry.find(group) == serverOpRetry.end() || serverOpRetry[group].retryCtx == nullptr
     301            0 :             || serverOpRetry[group].retryCtx->IsPaused())
     302            0 :            && (agentOpRetry_.find(group) == agentOpRetry_.end() || agentOpRetry_[group].retryCtx == nullptr
     303            0 :                || agentOpRetry_[group].retryCtx->IsPaused());
     304              : }
     305              : 
     306            0 : bool OpRetryManager::IsResumed(const std::string& group)
     307              : {
     308            0 :     return (serverOpRetry.find(group) == serverOpRetry.end() || serverOpRetry[group].retryCtx == nullptr
     309            0 :             || !serverOpRetry[group].retryCtx->IsPaused())
     310            0 :            && (agentOpRetry_.find(group) == agentOpRetry_.end() || agentOpRetry_[group].retryCtx == nullptr
     311            0 :                || !agentOpRetry_[group].retryCtx->IsPaused());
     312              : }
     313              : } // namespace hccl
        

Generated by: LCOV version 2.0-1