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

Generated by: LCOV version 2.0-1