LCOV - code coverage report
Current view: top level - legacy/ascend910/framework/cluster_maintenance/recovery/operator_retry - opretry_base.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 77.1 % 83 64
Test Date: 2026-08-18 17:47:01 Functions: 55.0 % 20 11

            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              : #ifndef HCCL_RETRY_BASE_H
      12              : #define HCCL_RETRY_BASE_H
      13              : 
      14              : #include <memory>
      15              : #include "hccl_socket.h"
      16              : #include "notify_pool.h"
      17              : #include "hccl_op_retry_pub.h"
      18              : #include "hdc_pub.h"
      19              : #include "exception_handler.h"
      20              : #include "hccl_common.h"
      21              : 
      22              : namespace hccl {
      23              : constexpr u32 OP_RETRY_MAX_CNT = 3;
      24              : constexpr u32 OP_RETRY_WAIT_AICPU_TIMEOUT = 5;            // 等待Aicpu的时长, 单位s
      25              : constexpr u32 OP_RETRY_WAIT_AGENT_AICPU_TIMEOUT = 10;     // 等待Agent+Aicpu的时长, 单位s
      26              : constexpr u32 OP_RETRY_POLL_AICPU_ERROR_INTERVAL = 1;     // 正常状态轮询Aicpu错误码的间隔, 单位s
      27              : constexpr u32 OP_RETRY_POLL_RDMA_ERROR_INTERVAL = 1;      // 正常状态轮询RDMA错误码的间隔, 单位s
      28              : constexpr u32 OP_RETRY_POLL_AICPU_STATE_INTERVAL = 10000; // 重执行状态轮询Aicpu状态的间隔, 单位us
      29              : constexpr u32 OP_RETRY_SEND_RECV_TIMEOUT = 200;           // 发送和接收的超时时间, 单位s
      30              : constexpr u32 OP_RETRY_SEND_RECV_INTERVAL = 10000;        // 发送和接收的间隔时间, 单位us
      31              : constexpr u32 OP_RETRY_KEEP_INTERVAL = 1;                 // 保活时间间隔, 单位s
      32              : constexpr u32 OP_RETRY_RUNNING_POLL_INTERVAL = 100000;    // 重执行状态轮询状态的间隔, 单位us
      33              : constexpr u32 TIME_MS_TO_US = 1000;
      34              : 
      35              : // 重执行初始化需要用到的参数
      36              : struct OpRetryAgentParam {
      37              :     std::string group;
      38              :     std::shared_ptr<HcclSocket> agentConnection;
      39              :     std::shared_ptr<HDCommunicate> h2dPtr;
      40              :     std::shared_ptr<HDCommunicate> d2hPtr;
      41              :     std::shared_ptr<HcclOpStreamRes> opStreamPtr;
      42              :     OpRetryResetNotifyCallback notifyResetCallback;
      43              :     OpRetrySetTransportStatusCallback setTransportStatusCallback;
      44              :     OpRetryGetSwitchRanksCallback getSwitchRanksCallback;
      45              :     OpRetrySetTransportResumeStatusCallBack setTransportResumeStatusCallback;
      46              :     bool isEnableBackupLink;
      47              :     bool isEnableSdmaRetry;
      48              :     OpRetryAgentInfo agentInfo;
      49              : };
      50              : 
      51            3 : struct LinkPortStatus {
      52              :     u32 cmd = LINK_PORT_STATUS_CMD;
      53              :     bool defaultPort = false;
      54              :     bool backupPort = false;
      55              :     u32 rankSize = 0;
      56              :     u32 rankList[AICPU_MAX_RANK_NUM] = {};
      57              : };
      58              : 
      59            5 : struct ActiveSwitchInfo {
      60              :     u32 cmd = ACTIVE_SWITCH_INFO_CMD;
      61              :     u32 switchRankNum;
      62              :     u32 remoteRankNum;
      63              :     bool refreshTransportFin = false;
      64              :     bool defaultPortStatus = false;
      65              :     bool backupPortStatus = false;
      66              :     bool localPortsCheckRet = false;
      67              :     u32 switchRankList[AICPU_MAX_RANK_NUM] = {};
      68              :     bool switchUseBackup[AICPU_MAX_RANK_NUM] = {};
      69              :     u8 remoteRankNicStatus[AICPU_MAX_RANK_NUM] = {};
      70              : };
      71              : 
      72            5 : using HcclAgentRetryInfo = struct HcclAgentRetryInfoDef {
      73              :     std::shared_ptr<HcclSocket> socket{nullptr};
      74              :     RetryInfo retryInfo;
      75              :     ChangeLinkInfo changeLinkInfo;
      76              :     LinkPortStatus linkPortStatus;
      77              :     ActiveSwitchInfo switchInfo;
      78              : };
      79              : 
      80           57 : inline const char* GetReadableState(RetryState retryState)
      81              : {
      82           57 :     auto it = RETRY_STATE_STR_MAP.find(retryState);
      83           57 :     return (it != RETRY_STATE_STR_MAP.end()) ? it->second.c_str() : "unknown state";
      84              : }
      85              : 
      86            4 : inline const char* GetReadableCmd(RetryCommand retryCommand)
      87              : {
      88            4 :     auto it = RETRY_COMMAND_STR_MAP.find(retryCommand);
      89            4 :     return (it != RETRY_COMMAND_STR_MAP.end()) ? it->second.c_str() : "unknown cmd";
      90              : }
      91              : 
      92              : class RetryContext;
      93              : 
      94              : // 状态基类
      95              : class OpRetryBase {
      96              : public:
      97              :     virtual HcclResult Handle(RetryContext* retryCtx);
      98              :     virtual HcclResult ProcessEvent(RetryContext* retryCtx) = 0;
      99              :     virtual HcclResult ProcessError(RetryContext* retryCtx) = 0;
     100              : 
     101           38 :     OpRetryBase() {};
     102           38 :     virtual ~OpRetryBase() {};
     103              : 
     104              :     // 设置是否直接退出send/recv循环状态,规避长时间阻塞,无法切换状态
     105              :     void SetEnableSendRecv(bool enable);
     106              : 
     107              : protected:
     108              :     /* server-agent 交互 */
     109              :     HcclResult IssueResponse(std::shared_ptr<HcclSocket> socket, RetryInfo& retryInfo); // agent向server发送数据
     110              :     HcclResult WaitResponse(std::shared_ptr<HcclSocket> socket, RetryInfo& retryInfo);  // server等待agent回复
     111              : 
     112              :     HcclResult IssueCommand(std::shared_ptr<HcclSocket> socket, RetryCommand command); // server向agent发送命令
     113              :     HcclResult WaitCommand(std::shared_ptr<HcclSocket> socket, RetryCommand& command); // agent轮询命令
     114              : 
     115              :     // server向agent发送命令,携带opid
     116              :     HcclResult IssueCommandWithOpId(std::shared_ptr<HcclSocket> socket, RetryCommandInfo& commandInfo);
     117              :     // agent轮询命令,携带opid
     118              :     HcclResult WaitCommandWithOpId(std::shared_ptr<HcclSocket> socket, RetryCommandInfo& commandInfo);
     119              : 
     120              :     // server向agent发送借轨信息
     121              :     HcclResult IssueChangeLink(std::shared_ptr<HcclSocket> socket, ChangeLinkInfo& changeLinkInfo);
     122              :     // agent轮询借轨信息
     123              :     HcclResult WaitChangeLink(std::shared_ptr<HcclSocket> socket, ChangeLinkInfo& changeLinkInfo);
     124              :     // agent向server发送当前网口情况
     125              :     HcclResult IssueLinkPortCheckResult(std::shared_ptr<HcclSocket> socket, LinkPortStatus& linkPortStatus);
     126              :     // server接收当前网口情况
     127              :     HcclResult WaitLinkPortCheckResult(std::shared_ptr<HcclSocket> socket, LinkPortStatus& linkPortStatus);
     128              :     // agent向device发送借轨信息
     129              :     HcclResult
     130              :     SetOpChangeLinkInfo(std::shared_ptr<HDCommunicate> hdcPtr, KfcCommand opCmd, ChangeLinkInfo& changeLinkInfo);
     131              :     // agent向server发送主动借轨信息
     132              :     HcclResult IssueActiveSwitchInfo(std::shared_ptr<HcclSocket> socket, ActiveSwitchInfo& switchInfo);
     133              :     // server收到主动借轨信息
     134              :     HcclResult WaitActiveSwitchInfo(std::shared_ptr<HcclSocket> socket, ActiveSwitchInfo& switchInfo);
     135              :     // server处理收到主动借轨信息函数
     136              :     HcclResult RecvActiveSwitchInfo(std::shared_ptr<HcclSocket> socket, const u32 rankId, ActiveSwitchInfo& switchInfo);
     137              : 
     138              :     // 获取SwitchRanks等信息
     139              :     HcclResult GetSwitchRanks(RetryContext* retryCtx, bool& needCheckDefaultNic, bool& needCheckBackupNic);
     140              : 
     141              :     /* 校验 */
     142              :     HcclResult CheckRetryInfo(RetryContext& retryCtx); // 校验收到的N个RetryInfo
     143              :     HcclResult GetRetryInfo(RetryContext* retryCtx, RetryInfo& retryInfo);
     144              : 
     145              :     /* agent-device 交互 */
     146              :     HcclResult GetOpExecInfo(std::shared_ptr<HDCommunicate> hdcPtr, KfcExecStatus& opInfo);
     147              :     HcclResult SetOpExecCmd(std::shared_ptr<HDCommunicate> hdcPtr, KfcCommand opCmd);
     148              :     HcclResult ClearStream(std::shared_ptr<HcclOpStreamRes> opStreamPtr_, HcclRtStreamClearStep clearStep);
     149              :     HcclResult SetOpExecCmdWithOpId(std::shared_ptr<HDCommunicate> hdcPtr, KfcCommand opCmd, HcclOpIdentifier& opId);
     150              :     HcclResult ClearStreamWithOpId(
     151              :         std::shared_ptr<HcclOpStreamRes> opStreamPtr_, HcclRtStreamClearStep clearStep, HcclOpIdentifier& opId,
     152              :         HcclOpIdentifier& curOpId);
     153              :     HcclResult ResetNotify(RetryContext* retryCtx);
     154              :     HcclResult SetTransportStatusForStop(RetryContext* retryCtx);
     155              :     HcclResult SetTransportStatusForResume(RetryContext* retryCtx);
     156              :     HcclResult
     157              :     GetLinkPortStatus(RetryContext* retryCtx, LinkPortStatus& linkPortStatus, bool isGetGroupAllRemoteRank = false);
     158              :     HcclResult InitChangeLinkInfo(RetryContext* retryCtx, bool incre = false, bool isGetGroupAllRemoteRank = false);
     159              :     /*获取batchsendrecv rdma重执行时的故障信息*/
     160              :     HcclResult SetBsrOpId(RetryContext* retryCtx, HcclSendRecvType type);
     161              :     HcclResult GetBsrOpId(RetryContext* retryCtx, HcclSendRecvType type);
     162              : 
     163              : private:
     164              :     // 阻塞式发送 && 非阻塞式接收, 接口内部不报错, 返回值在上层判断并打印日志, 避免未进入重执行时出现ERROR日志
     165              :     HcclResult Send(std::shared_ptr<HcclSocket> socket, void* data, u64 size);
     166              :     HcclResult Recv(std::shared_ptr<HcclSocket> socket, void* data, u64 size);
     167              : 
     168              :     HcclResult CheckOpName(const RetryInfo& opInfo1, const RetryInfo& opInfo2); // 校验算子一致
     169              :     HcclResult
     170              :     CheckMaxRetryCnt(const RetryInfo& retryInfo, const std::string& identifier = HCCL_WORLD_GROUP); // 校验重执行次数
     171              :     HcclResult CheckLinkStates(const RetryInfo& retryInfo);                                         // 校验link状态
     172              :     void CheckSnapshotStatus(RetryContext* retryCtx);
     173              :     bool enableSendRecv = true;
     174              : };
     175              : 
     176              : class RetryContext {
     177              : public:
     178              :     // agent状态机初始化
     179            6 :     RetryContext(OpRetryAgentParam& param, std::shared_ptr<OpRetryBase> retryBase)
     180           18 :     {
     181            6 :         group_ = param.group;
     182            6 :         agentSocket_ = param.agentConnection;
     183            6 :         h2dPtr_ = param.h2dPtr;
     184            6 :         d2hPtr_ = param.d2hPtr;
     185            6 :         opStreamPtr_ = param.opStreamPtr;
     186            6 :         notifyResetCallback_ = param.notifyResetCallback;
     187            6 :         setTransportStatusCallback_ = param.setTransportStatusCallback;
     188            6 :         getSwitchRanksCallback_ = param.getSwitchRanksCallback;
     189            6 :         setTransportReseumeStatusCallback_ = param.setTransportResumeStatusCallback;
     190            6 :         isEnableBackupLink_ = param.isEnableBackupLink;
     191            6 :         isEnableSdmaRetry_ = param.isEnableSdmaRetry;
     192            6 :         retryBase_ = retryBase;
     193            6 :         isRootRetryCtx_ = false;
     194              : 
     195            6 :         rankId_ = param.agentInfo.userRank;
     196            6 :         deviceLogicId_ = param.agentInfo.deviceLogicId;
     197            6 :         netDevCtx_ = param.agentInfo.netDevCtx;
     198            6 :         backUpNetDevCtx_ = param.agentInfo.backUpNetDevCtx;
     199           12 :         std::string dfxInfo = "deviceIP:" + std::string(param.agentInfo.deviceIP.GetReadableIP())
     200           18 :                               + ";hostIP:" + std::string(param.agentInfo.hostIP.GetReadableIP());
     201            6 :         EXCEPTION_THROW_IF_COND_ERR(
     202              :             memcpy_s(localRetryInfo_.dfxIpInfo, sizeof(localRetryInfo_.dfxIpInfo), dfxInfo.c_str(), dfxInfo.size())
     203              :                 != EOK,
     204              :             "memcpy_s dfxIpInfo failed.");
     205            6 :         localRetryInfo_.dfxIpInfo[dfxInfo.size()] = '\0';
     206            6 :     }
     207              : 
     208              :     // server状态机初始化
     209            8 :     RetryContext(
     210              :         std::map<u32, std::shared_ptr<HcclSocket>>& sockets, std::shared_ptr<OpRetryBase> retryBase,
     211              :         const OpRetryAgentInfo& agentInfo)
     212           24 :     {
     213            8 :         retryBase_ = retryBase;
     214            8 :         isRootRetryCtx_ = true;
     215           20 :         for (auto it = sockets.begin(); it != sockets.end(); ++it) {
     216           12 :             HcclAgentRetryInfo tempAgentInfo;
     217           12 :             tempAgentInfo.socket = it->second;
     218           14 :             serverSockets_.insert(std::make_pair(it->first, std::move(tempAgentInfo)));
     219           10 :         }
     220            8 :         rankId_ = agentInfo.userRank;
     221            8 :         deviceLogicId_ = agentInfo.deviceLogicId;
     222           13 :         std::string dfxInfo = "deviceIP:" + std::string(agentInfo.deviceIP.GetReadableIP())
     223           24 :                               + ",hostIP:" + std::string(agentInfo.hostIP.GetReadableIP());
     224            8 :         EXCEPTION_THROW_IF_COND_ERR(
     225              :             memcpy_s(localRetryInfo_.dfxIpInfo, sizeof(localRetryInfo_.dfxIpInfo), dfxInfo.c_str(), dfxInfo.size())
     226              :                 != EOK,
     227              :             "memcpy_s dfxIpInfo failed.");
     228            8 :         localRetryInfo_.dfxIpInfo[dfxInfo.size()] = '\0';
     229            8 :     }
     230              : 
     231            1 :     RetryState GetRetryState() { return state_; }
     232            0 :     const char* GetReadableCtxState() const { return GetReadableState(state_); }
     233              : 
     234           18 :     void SetRetryState(RetryState nextState, std::shared_ptr<OpRetryBase> retryBase)
     235              :     {
     236           18 :         HCCL_RUN_INFO(
     237              :             "[OpRetry][%s]State Transfer, cur state %s, next state %s", GetOpRetryMachineType(),
     238              :             GetReadableState(state_), GetReadableState(nextState));
     239           18 :         state_ = nextState;
     240           18 :         retryBase_ = retryBase;
     241           18 :         localRetryInfo_.retryState = state_;
     242           18 :     }
     243              : 
     244              :     void SetEnableSendRecv(bool enable) { retryBase_->SetEnableSendRecv(enable); };
     245              : 
     246              :     // 外部接口调用Request()
     247            0 :     HcclResult Request()
     248              :     {
     249            0 :         CHK_SMART_PTR_NULL(retryBase_);
     250            0 :         return retryBase_->Handle(this);
     251              :     }
     252              : 
     253            0 :     u32 GetRankId() { return rankId_; }
     254              : 
     255           18 :     const char* GetOpRetryMachineType() const
     256              :     {
     257           18 :         std::string ctxType = isRootRetryCtx_ ? "Server" : "Agent";
     258           36 :         return ctxType.c_str();
     259           18 :     }
     260              : 
     261            0 :     bool IsRootRetryCtx() { return isRootRetryCtx_; }
     262              : 
     263            0 :     const char* GetDfxIpInfo() const { return localRetryInfo_.dfxIpInfo; }
     264              : 
     265            0 :     void ResetAgentState()
     266              :     {
     267            0 :         localRetryInfo_.opInfo.execStatus.kfcError = KfcError::kNone;
     268            0 :         localRetryInfo_.isNeedReportOpRetryErr = false;
     269            0 :         isBSRRdmaRecvError_ = false;
     270            0 :         isBSRRdmaSendError_ = false;
     271            0 :     }
     272              : 
     273            0 :     void ResetServerState()
     274              :     {
     275            0 :         errorRankList_.clear();
     276            0 :         needRetryServerRanks_.clear();
     277            0 :         isNeedReportOpRetryErr = false;
     278            0 :     }
     279              : 
     280            3 :     std::shared_ptr<HDCommunicate> GetH2dPtr() { return h2dPtr_; }
     281              : 
     282      2460105 :     std::shared_ptr<HDCommunicate> GetD2hPtr() { return d2hPtr_; }
     283              : 
     284            0 :     bool IsPaused() const { return isPaused_; }
     285              : 
     286              :     std::string group_ = "";
     287              :     s32 deviceLogicId_ = INVALID_INT;
     288              :     u32 rankId_ = INVALID_UINT;
     289              :     bool haveCommEnableBackupLink_ = false;
     290              : 
     291              :     // agent状态机储存信息
     292              :     std::shared_ptr<HcclSocket> agentSocket_ = nullptr;
     293              :     std::shared_ptr<HcclOpStreamRes> opStreamPtr_ = nullptr;
     294              :     OpRetryResetNotifyCallback notifyResetCallback_ = nullptr;
     295              :     OpRetrySetTransportStatusCallback setTransportStatusCallback_ = nullptr;
     296              :     OpRetryGetSwitchRanksCallback getSwitchRanksCallback_ = nullptr;
     297              :     OpRetrySetTransportResumeStatusCallBack setTransportReseumeStatusCallback_ = nullptr;
     298              :     bool isEnableBackupLink_ = false;
     299              :     bool isEnableSdmaRetry_ = false;
     300              :     RetryInfo localRetryInfo_;
     301              :     ChangeLinkInfo localChangeLinkInfo_;
     302              :     LinkPortStatus linkPortStatus_;
     303              :     bool isChangeLinkInfoInit_ = false;
     304              :     std::map<u32, bool> lastLinkPortStatus_;
     305              :     bool isUseDefaultPort_ = true;
     306              :     HcclNetDevCtx netDevCtx_ = nullptr;
     307              :     HcclNetDevCtx backUpNetDevCtx_ = nullptr;
     308              :     bool isBSRRdmaRecvError_ = false;
     309              :     bool isBSRRdmaSendError_ = false;
     310              :     HcclOpIdentifier RemainSendOpId_;
     311              :     HcclOpIdentifier RemainRecvOpId_;
     312              :     ActiveSwitchInfo switchInfo_;
     313              :     bool isAgentStateWaitResume_ = false;
     314              : 
     315              :     bool isRecivedCmdToRunning = false;
     316              :     bool isRecivedCmdToCheckLink = false;
     317              :     // server状态机储存信息
     318              :     std::map<u32, HcclAgentRetryInfo> serverSockets_;
     319              :     std::vector<u32> needRetryServerRanks_;
     320              :     HcclOpIdentifier curFaultOpId;
     321              :     std::map<u32, HcclOpIdentifier> errorRankList_;
     322              :     bool isRdmaError = false;
     323              :     bool isAlreadyChangeLink = false;
     324              :     std::map<u32, ActiveSwitchInfo> switchInfoMap_;
     325              :     bool isServerStateWaitResume_ = false;
     326              :     bool isNeedReportOpRetryErr = false; // 针对重执行算子不一致和inplace场景,上报故障
     327              : 
     328              :     bool isOpRetryQuit = false;
     329              :     bool isPaused_ = false;
     330              : 
     331              : private:
     332              :     std::shared_ptr<OpRetryBase> retryBase_ = nullptr;
     333              :     RetryState state_ = RETRY_STATE_RESERVED;
     334              :     bool isRootRetryCtx_ = false;
     335              : 
     336              :     std::shared_ptr<HDCommunicate> h2dPtr_ = nullptr;
     337              :     std::shared_ptr<HDCommunicate> d2hPtr_ = nullptr;
     338              : };
     339              : } // namespace hccl
     340              : #endif
        

Generated by: LCOV version 2.0-1