LCOV - code coverage report
Current view: top level - legacy/ascend950/framework/dfx/aicpu/task_exception - task_exception_func.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 65.1 % 106 69
Test Date: 2026-07-28 12:11:00 Functions: 85.7 % 14 12

            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 "task_exception_func.h"
      12              : #include "communicator_impl_lite_manager.h"
      13              : #include "log.h"
      14              : #include <map>
      15              : #include <vector>
      16              : #include <memory>
      17              : #include <string>
      18              : 
      19              : namespace Hccl {
      20           46 : TaskExceptionFunc &TaskExceptionFunc::GetInstance()
      21              : {
      22           46 :     static TaskExceptionFunc instance;
      23           46 :     return instance;
      24              : }
      25              : 
      26            6 : void TaskExceptionFunc::SetEnable(bool isEnable)
      27              : {
      28            6 :     isEnable_ = isEnable;
      29            6 :     if (isEnable_) {
      30           18 :         HCCL_INFO("[TaskExceptionFunc] Task Exception enabled.");
      31              :     } else {
      32            0 :         HCCL_INFO("[TaskExceptionFunc] Task Exception disabled.");
      33              :     }
      34            6 : }
      35              : 
      36            1 : void TaskExceptionFunc::SetDevId(uint32_t devId)
      37              : {
      38            1 :     devId_ = devId;
      39            1 : }
      40              : 
      41            2 : void TaskExceptionFunc::RegisterCallback(const Callback &callback)
      42              : {
      43            2 :     callback_ = callback;
      44            2 : }
      45              : 
      46            8 : void TaskExceptionFunc::Register(StreamLite *streamLite)
      47              : {
      48            8 :     streamLiteMap_[streamLite->GetSqId()] = streamLite;
      49            8 : }
      50              : 
      51           19 : void TaskExceptionFunc::UnRegister(StreamLite *streamLite)
      52              : {
      53           19 :     streamLiteMap_.erase(streamLite->GetSqId());
      54           19 : }
      55              : 
      56           14 : std::string TaskExceptionFunc::ErrorType2Str(uint8_t errorType) const
      57              : {
      58              :     static const std::map<uint8_t, std::string> errorType2Str{
      59            0 :         {0b1, "exception"},                 // bit0:代表是否有exception
      60            0 :         {0b11, "bus error"},                // bit1:代表是否为bus_error
      61            0 :         {0b101, "rsv"},                     // bit2:代表为rsv域段(该域段硬件值可能为0或1)
      62            0 :         {0b1001, "sqe error"},              // bit3:代表是否为sqe_error
      63            0 :         {0b10001, "res conflict error"},    // bit4:代表是否为res_conflict_error
      64            0 :         {0b100001, "pre_p/post_p error"},   // bit5:表示软件在pre_p或post_p过程中发生了错误,写入了sq_sw_status
      65           22 :     };
      66           14 :     const auto res = errorType2Str.find(errorType);
      67           24 :     return res == errorType2Str.end() ? "" : res->second;
      68            1 : }
      69              : 
      70            2 : std::string TaskExceptionFunc::CqeStatus2Str(uint32_t errorCode) const
      71              : {
      72            2 :     uint8_t status = errorCode & 0xFF;  // errorCode低8bit是UB CQE的status
      73              :     static const std::map<uint8_t, std::string> code2Str{
      74            0 :         {0x00, "OK"},
      75            0 :         {0x01, "Unsupported OpCode"},
      76            0 :         {0x02, "Local Operation Error"},
      77            0 :         {0x03, "Remote Operation Error"},
      78            0 :         {0x04, "Transaction Retry Counter Exceeded"},
      79            0 :         {0x05, "Transaction ACK Timeout"},
      80            0 :         {0x06, "Jetty work Request Flushed"},
      81           11 :     };
      82            2 :     const auto res = code2Str.find(status);
      83            4 :     return res == code2Str.end() ? "Reserved" : res->second;
      84            1 : }
      85              : 
      86           14 : std::string TaskExceptionFunc::StringLogicCqReportInfo(const rtLogicCqReport_t &reportOfOne) const
      87              : {
      88           14 :     std::stringstream ss;
      89           14 :     ss << "streamId :" << reportOfOne.streamId;
      90           14 :     ss << " taskId :" << reportOfOne.taskId;
      91           14 :     ss << " errorCode :" << reportOfOne.errorCode;
      92           14 :     if (reportOfOne.sqeType == 9) { // sqeType等于9时, errorCode才按照UB的格式解析, 不等于9时可不关注errorCode
      93            2 :         const std::string errorStatus = CqeStatus2Str(reportOfOne.errorCode);
      94            2 :         ss << "(" << errorStatus << ")";
      95            2 :     }
      96           14 :     ss << " errorType :" << static_cast<uint32_t>(reportOfOne.errorType);
      97           14 :     const std::string errorTypeStr = ErrorType2Str(reportOfOne.errorType);
      98           14 :     if (!errorTypeStr.empty()) {
      99            9 :         ss << "(" << errorTypeStr << ")";
     100              :     }
     101           14 :     ss << " sqeType :" << static_cast<uint32_t>(reportOfOne.sqeType);
     102           14 :     ss << " sqId :" << reportOfOne.sqId;
     103           14 :     ss << " sqHead :" << reportOfOne.sqHead;
     104           14 :     ss << " matchFlag :" << reportOfOne.matchFlag;
     105           14 :     ss << " dropFlag :" << reportOfOne.dropFlag;
     106           14 :     ss << " errorBit :" << reportOfOne.errorBit;
     107           14 :     ss << " accError :" << reportOfOne.accError;
     108           28 :     return ss.str();
     109           14 : }
     110              : 
     111            1 : unsigned int TaskExceptionFunc::GetTrailingZeros(uint8_t num) const
     112              : {
     113            1 :     uint8_t count = 0;
     114            4 :     while ((num & 1U) == 0) {
     115            4 :         count++;
     116            4 :         num >>= 1;
     117            4 :         if (num == 1U) {
     118            1 :             break;
     119              :         }
     120              :     }
     121            1 :     return count;
     122              : }
     123              : 
     124              : constexpr uint8_t RT_STARS_EXIST_ERROR = 0x3FU;
     125              : 
     126            6 : bool TaskExceptionFunc::IsExceptionCqe(const rtLogicCqReport_t &reportOfOne) const
     127              : {
     128            6 :     if ((reportOfOne.errorType & RT_STARS_EXIST_ERROR) == 0U) { // 取低6位
     129            9 :         HCCL_INFO("ReportOfOne info [%s]", StringLogicCqReportInfo(reportOfOne).c_str());
     130            3 :         return false;
     131              :     }
     132            9 :     HCCL_ERROR("ReportOfOne error info [%s]", StringLogicCqReportInfo(reportOfOne).c_str());
     133            3 :     return true;
     134              : }
     135              : 
     136              : constexpr uint32_t MAX_REPORT_CNT     = 256U;
     137              : constexpr uint32_t AC_SQE_REV_MAX_CNT = 32U;
     138              : enum class CqeStatus : int64_t {
     139              :     kDefault = 0,
     140              :     kCqeException,
     141              :     kCqeTimeOut,
     142              :     kCqeInnerError,
     143              :     kCqeUnknown,
     144              : };
     145              : 
     146            0 : uint32_t TaskExceptionFunc::GetReporterInfo(const StreamLite *curStream, std::shared_ptr<halReportRecvInfo> recvInfo)
     147              : {
     148            0 :     recvInfo->type = static_cast<drvSqCqType_t>(DRV_LOGIC_TYPE);
     149            0 :     recvInfo->tsId = 0;
     150            0 :     recvInfo->report_cqe_num = 0;
     151            0 :     recvInfo->timeout = 0;               // 不设置超时时间,非阻塞
     152            0 :     recvInfo->task_id = 0xFFFF;          // 接收所有类型
     153            0 :     recvInfo->cqe_num = MAX_REPORT_CNT;  // 单次接收的最大cqe数量
     154            0 :     recvInfo->stream_id = curStream->GetId();
     155            0 :     recvInfo->cqId = curStream->GetCqId();
     156            0 :     auto exceptionInfo = reinterpret_cast<rtLogicCqReport_t *>(recvInfo->cqe_addr);
     157              : 
     158              :     // 接收错误信息
     159            0 :     drvError_t ret = halCqReportRecv(devId_, recvInfo.get());
     160            0 :     if (recvInfo->report_cqe_num != 0) {
     161            0 :         HCCL_INFO("[TaskExceptionFunc]after exceptionInfo deviceId[%u], streamId[%u], taskId[%u], recvInfo->report_cqe_num[%u].",
     162              :                     devId_, exceptionInfo->streamId, exceptionInfo->taskId, recvInfo->report_cqe_num);
     163              :     }
     164              : 
     165            0 :     if (ret == DRV_ERROR_WAIT_TIMEOUT) {
     166            0 :         HCCL_INFO("[TaskExceptionFunc]halCqReportRecv has found nothing, ret:%d", ret);
     167            0 :         return 1;
     168              :     }
     169            0 :     if (ret != DRV_ERROR_NONE) {
     170            0 :         HCCL_WARNING("[TaskExceptionFunc]halCqReportRecv failed, ret:%d", ret);
     171            0 :         return 1;
     172              :     }
     173            0 :     if (recvInfo->type != DRV_LOGIC_TYPE) {  // 非DRV_LOGIC_TYPE不支持解析
     174            0 :         HCCL_WARNING("[TaskExceptionFunc]halCqReportRecv type is not %d, recvInfo->type:%d", DRV_LOGIC_TYPE, recvInfo->type);
     175            0 :         return 1;
     176              :     }
     177            0 :     return 0;
     178              : }
     179              : 
     180            4 : void TaskExceptionFunc::Call()
     181              : {   
     182           12 :     TRY_CATCH_PRINT_ERROR(
     183              :         if (!isEnable_) {
     184              :             return;
     185              :         }
     186              :         auto recvInfo = std::make_shared<halReportRecvInfo>();
     187              :         constexpr uint32_t cqeSize = MAX_REPORT_CNT * sizeof(rtLogicCqReport_t);
     188              :         uint8_t tmpAddr[cqeSize] = {};     // cqe byte size
     189              :         recvInfo->cqe_addr = tmpAddr;  // 外部保证是有效的地址
     190              : 
     191              :         std::vector<CommunicatorImplLite *> aicpuComms = CommunicatorImplLiteMgr::GetInstance().GetAll();
     192              :         for (auto aicpuComm : aicpuComms) {
     193              :             std::vector<StreamLite *> aicpuStreams = aicpuComm-> GetStreamLiteMgr()->GetAllStreams();
     194              :             for (auto &aicpuStream : aicpuStreams) {
     195              :                 if (aicpuStream == nullptr) {
     196              :                     HCCL_ERROR("[TaskExceptionFunc]stream of in aicpuComm[%s] is nullptr", aicpuComm->GetId().c_str());
     197              :                     continue;
     198              :                 }
     199              :                 if (GetReporterInfo(aicpuStream, recvInfo) != 0) {
     200              :                     continue;
     201              :                 }
     202              :                 uint32_t reportNum = recvInfo->report_cqe_num;
     203              :                 if (reportNum > MAX_REPORT_CNT) {
     204              :                     HCCL_ERROR("[TaskExceptionFunc]report cqe num %u should not big than %u", reportNum, MAX_REPORT_CNT);
     205              :                     continue;
     206              :                 }
     207              :                 for (uint32_t idx = 0U; idx < reportNum; ++idx) {
     208              :                     auto &reportOfOne
     209              :                         = *((reinterpret_cast<rtLogicCqReport_t *>(recvInfo->cqe_addr)) + idx); // 外部保证是有效的地址
     210              :                     if (IsExceptionCqe(reportOfOne)) {
     211              :                         callback_(aicpuComm, &reportOfOne);
     212              :                     }
     213              :                 }
     214              :             }
     215              :         }
     216              :     );
     217              : }
     218              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1