LCOV - code coverage report
Current view: top level - coll_communicator_mgr/dfx/ns_recovery - ns_recovery.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 75.9 % 83 63
Test Date: 2026-08-04 10:52:23 Functions: 100.0 % 7 7

            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 "ns_recovery.h"
      12              : #include "channel_process.h"
      13              : #include "log.h"
      14              : #include "comm_engine_utils.h"
      15              : 
      16              : 
      17              : namespace hccl 
      18              : {
      19              : 
      20          119 : void NsRecoveryProcessor::SetKfcControlTransfer(std::shared_ptr<HDCommunicate> kfcControlTransferH2D, 
      21              :         std::shared_ptr<HDCommunicate> kfcStatusTransferD2H)
      22              : {
      23          119 :     kfcControlTransferH2D_ = kfcControlTransferH2D;
      24          119 :     kfcStatusTransferD2H_ = kfcStatusTransferD2H;
      25          119 : }
      26              : 
      27           14 : void NsRecoveryProcessor::AddNsRecoveryData(const CommEngine& engine, const ChannelHandle *const channelHandles, 
      28              :     const ChannelHandle *const hostChannelHandleList, uint32_t channelNum, const std::string &commTag)
      29              : {
      30           14 :     HCCL_INFO("[NsRecovery][AddData] AddNsRecoveryData for engine[%s], channelNum[%u], commTag[%s]", 
      31              :         GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), channelNum, commTag.c_str());
      32           14 :     std::vector<ChannelHandle> deviceList;
      33           14 :     std::vector<ChannelHandle> hostList;
      34           29 :     for (uint32_t index = 0; index < channelNum; ++index) {
      35           15 :         deviceList.push_back(channelHandles[index]);
      36           15 :         hostList.push_back(hostChannelHandleList[index]);
      37              :     }
      38           14 :     NsRecoveryData data{deviceList, hostList, channelNum, commTag};
      39           14 :     nsRecoveryDatas_[engine].emplace_back(std::move(data));
      40           14 : }
      41              : 
      42              : constexpr u32 WAIT_CMD_TIMEOUT = 10 * 1000; // 最大等待10秒
      43            2 : HcclResult NsRecoveryProcessor::PollStopStatus()
      44              : {
      45            2 :     Hccl::KfcExecStatus opInfo;
      46            2 :     auto timeout   = std::chrono::milliseconds(WAIT_CMD_TIMEOUT);
      47            2 :     auto startTime = std::chrono::steady_clock::now();
      48              :     while (true) {
      49            2 :         CHK_RET(kfcStatusTransferD2H_->Get(0, sizeof(Hccl::KfcExecStatus), reinterpret_cast<uint8_t *>(&opInfo)));
      50            2 :         if (opInfo.kfcStatus == Hccl::KfcStatus::STOP_LAUNCH_DONE) {
      51            2 :             HCCL_INFO("[NsRecovery][Suspend] received KfcStatus[%d], which is STOP_LAUNCH_DONE", static_cast<int>(opInfo.kfcStatus));
      52            2 :             return HcclResult::HCCL_E_SUSPENDING;
      53            0 :         } else if (opInfo.kfcStatus == Hccl::KfcStatus::ERROR){
      54            0 :             HCCL_ERROR("[NsRecovery][Suspend] received KfcStatus[%d], which is ERROR", static_cast<int>(opInfo.kfcStatus));
      55            0 :             return HcclResult::HCCL_E_INTERNAL;
      56              :         } else {
      57            0 :             if((std::chrono::steady_clock::now() - startTime) >= timeout){
      58            0 :                 HCCL_ERROR("[NsRecovery][Suspend] Wait suspend response status timeout[%u ms] and get the kfcStatus is [%d].", WAIT_CMD_TIMEOUT,
      59              :                         static_cast<int>(opInfo.kfcStatus));
      60            0 :                 return HcclResult::HCCL_E_TIMEOUT;
      61              :             }
      62            0 :             continue;
      63              :         }
      64            0 :     }
      65              :     return HcclResult::HCCL_E_INTERNAL;
      66              : }
      67              : 
      68            1 : HcclResult NsRecoveryProcessor::ListenBackGround(Hccl::KfcExecStatus& opInfo)
      69              : {
      70            1 :     auto timeout   = std::chrono::milliseconds(WAIT_CMD_TIMEOUT);
      71            1 :     auto startTime = std::chrono::steady_clock::now();
      72              :     while (true) {
      73            1 :         CHK_RET(kfcStatusTransferD2H_->Get(0, sizeof(Hccl::KfcExecStatus), reinterpret_cast<uint8_t *>(&opInfo)));
      74            1 :         if (opInfo.kfcStatus == Hccl::KfcStatus::CLEAN_DONE) {
      75            1 :             HCCL_INFO("[NsRecovery][Clean] received KfcStatus[%d], which is CLEAN_DONE", static_cast<int>(opInfo.kfcStatus));
      76            1 :             return HcclResult::HCCL_E_SUSPENDING;
      77            0 :         } else if (opInfo.kfcStatus == Hccl::KfcStatus::ERROR){
      78            0 :             HCCL_ERROR("[NsRecovery][Clean] received KfcStatus[%d], which is ERROR", static_cast<int>(opInfo.kfcStatus));
      79            0 :             return HcclResult::HCCL_E_INTERNAL;
      80              :         } else {
      81            0 :             if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
      82            0 :                 HCCL_ERROR("[NsRecovery][Clean] Wait clean response status timeout[%u ms] and get the kfcStatus is [%d].", WAIT_CMD_TIMEOUT,
      83              :                         static_cast<int>(opInfo.kfcStatus));
      84            0 :                 return HcclResult::HCCL_E_TIMEOUT;
      85              :             }
      86            0 :             continue;
      87              :         }
      88            0 :     }
      89              :     return HcclResult::HCCL_E_INTERNAL;
      90              : }
      91              : 
      92            3 : HcclResult NsRecoveryProcessor::StopLaunch()
      93              : {
      94            4 :     for (const auto& recoveryData : nsRecoveryDatas_) {
      95            3 :         if (recoveryData.first == COMM_ENGINE_AICPU || recoveryData.first == COMM_ENGINE_AICPU_TS) {
      96              :             // Aicpu场景
      97            2 :             Hccl::KfcCommand opCmd = Hccl::KfcCommand::NS_STOP_LAUNCH;
      98            2 :             CHK_RET(kfcControlTransferH2D_->Put(0, sizeof(Hccl::KfcCommand), reinterpret_cast<uint8_t *>(&opCmd)));
      99            2 :             HCCL_INFO("[NsRecovery][Suspend] send KfcCommand[%d] success, which is NS_STOP_LAUNCH.", static_cast<int>(opCmd));
     100              : 
     101            2 :             auto ret = PollStopStatus();  // todo:多CommEngine的管理存在问题
     102            2 :             if (ret != HcclResult::HCCL_E_SUSPENDING) {
     103            0 :                 HCCL_ERROR("[NsRecovery][Suspend] PollStopStatus failed, ret[%d]", ret);
     104            0 :                 return ret;
     105              :             }
     106            2 :             return HcclResult::HCCL_SUCCESS;
     107              :         } else {
     108            1 :             HCCL_INFO("[NsRecovery][Suspend] Aicpu kernel is not launched yet. Suspend host only.");
     109              :         }
     110              :     }
     111              :     
     112            1 :     return HcclResult::HCCL_SUCCESS;
     113              : }
     114              : 
     115            4 : HcclResult NsRecoveryProcessor::Clean()
     116              : {
     117            5 :     for (const auto& recoveryData : nsRecoveryDatas_) {
     118            4 :         if (recoveryData.first == COMM_ENGINE_AICPU || recoveryData.first == COMM_ENGINE_AICPU_TS) {
     119              :             // 再清理device,后续优化全用host管理
     120            3 :             HCCL_INFO("[NsRecovery][Clean] start to clean device, waiting for device STOP_LAUNCH_DONE");
     121            3 :             Hccl::KfcExecStatus opInfo;
     122            3 :             CHK_RET(kfcStatusTransferD2H_->Get(0, sizeof(Hccl::KfcExecStatus), reinterpret_cast<uint8_t *>(&opInfo)));
     123            3 :             if (opInfo.kfcStatus == Hccl::KfcStatus::STOP_LAUNCH_DONE) {
     124            1 :                 HCCL_INFO("[NsRecovery][Clean] received KfcStatus[%d], which is STOP_LAUNCH_DONE", static_cast<int>(opInfo.kfcStatus));
     125              :                 // 通知背景线程清理device侧资源
     126            1 :                 Hccl::KfcCommand opCmd = Hccl::KfcCommand::NS_CLEAN;
     127            1 :                 CHK_RET(kfcControlTransferH2D_->Put(0, sizeof(Hccl::KfcCommand), reinterpret_cast<uint8_t *>(&opCmd)));
     128            1 :                 HCCL_INFO("[NsRecovery][Clean] send KfcCommand [%d] success, which is NS_CLEAN", static_cast<int>(opCmd));
     129              :                 
     130              :                 // 监听背景线程状态
     131            1 :                 auto ret = ListenBackGround(opInfo);
     132            1 :                 if (ret != HcclResult::HCCL_E_SUSPENDING) {
     133            0 :                     HCCL_ERROR("[NsRecovery][Clean] ListenBackGround failed, ret[%d]", ret);
     134            0 :                     return ret;
     135              :                 }
     136            1 :                 return HcclResult::HCCL_SUCCESS;
     137              :             } else {
     138            2 :                 HCCL_ERROR("[NsRecovery][Clean] Aicpu kernel is not stopped yet. Cannot clean, kfcStatus is [%s]", 
     139              :                     opInfo.kfcStatus.Describe().c_str());
     140            2 :                 return HcclResult::HCCL_E_INTERNAL;
     141              :             }
     142              :             return HcclResult::HCCL_SUCCESS;
     143              :         }
     144              :     }
     145              : 
     146            1 :     return HcclResult::HCCL_SUCCESS;
     147              : }
     148              : 
     149            3 : HcclResult NsRecoveryProcessor::Resume(aclrtBinHandle binHandle)
     150              : {
     151            5 :     for (auto& recoveryData : nsRecoveryDatas_) {
     152            3 :         if (recoveryData.first == COMM_ENGINE_AICPU || recoveryData.first == COMM_ENGINE_AICPU_TS) {
     153            3 :             for (auto& handleData : recoveryData.second) {
     154            2 :                 CHK_RET(hcomm::ChannelProcess::ChannelUpdateKernelLaunch(handleData.channelHandles_.data(), handleData.hostChannelHandleList_.data(), 
     155              :                 handleData.channelNum_, handleData.commTag_, binHandle));
     156              :             }
     157              :         }
     158              :     }
     159            2 :     return HCCL_SUCCESS;
     160              : }
     161              : 
     162              : }
        

Generated by: LCOV version 2.0-1