LCOV - code coverage report
Current view: top level - adump/dump_statistics/dump_stat_op - kfc_dump_single_core.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.2 % 52 50
Test Date: 2026-08-31 10:09:28 Functions: 100.0 % 50 50

            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              : #ifndef __KFC_DUMP_SINGLE_CORE_H__
      12              : #define __KFC_DUMP_SINGLE_CORE_H__
      13              : 
      14              : #include "kfc_dump_op_base.h"
      15              : 
      16              : namespace KfcDumpStat {
      17              : using namespace AscendC;
      18              : 
      19              : // 单核模板:统计项按核均分,每个核独立完成分配到的整组统计
      20              : template <typename T>
      21              : class KfcDumpStatSingleCore : public KfcDumpStatOpBase<T> {
      22              : public:
      23              :     using KfcDumpStatOpBase<T>::KfcDumpStatOpBase;
      24              :     // 模板基类成员在派生类中不可见,统一引入
      25              :     using KfcDumpStatOpBase<T>::pPipe_;
      26              :     using KfcDumpStatOpBase<T>::maskBuf_;
      27              :     using KfcDumpStatOpBase<T>::cacheBuf1_;
      28              :     using KfcDumpStatOpBase<T>::blockIdx_;
      29              :     using KfcDumpStatOpBase<T>::blockOffset_;
      30              :     using KfcDumpStatOpBase<T>::aiCoreNum_;
      31              :     using KfcDumpStatOpBase<T>::xDtypeSize_;
      32              :     using KfcDumpStatOpBase<T>::dumpStatClass_;
      33              :     using KfcDumpStatOpBase<T>::statNum_;
      34              :     using KfcDumpStatOpBase<T>::workspace_;
      35              :     using KfcDumpStatOpBase<T>::sMsg_;
      36              :     using KfcDumpStatOpBase<T>::rMsg_;
      37              :     using KfcDumpStatOpBase<T>::RunStatCompute;
      38              :     using KfcDumpStatOpBase<T>::CopyOutStatResult;
      39              :     using KfcDumpStatOpBase<T>::SyncAllCores;
      40              :     using KfcDumpStatOpBase<T>::UpdateStatOutput;
      41              :     using KfcDumpStatOpBase<T>::InitCacheBuf;
      42              :     using KfcDumpStatOpBase<T>::ubSize_;
      43              :     using KfcDumpStatOpBase<T>::totalCount_;
      44              :     using KfcDumpStatOpBase<T>::maxProcCount_;
      45              :     using KfcDumpStatOpBase<T>::perBlockCount_;
      46              :     using KfcDumpStatOpBase<T>::tileNumMean_;
      47              :     using KfcDumpStatOpBase<T>::tileLengthMean_;
      48              :     using KfcDumpStatOpBase<T>::tileLengthEnd_;
      49              :     using KfcDumpStatOpBase<T>::tileNumEnd_;
      50              :     using KfcDumpStatOpBase<T>::innerLoopTime_;
      51              : 
      52           30 :     __aicore__ inline KfcDumpStatSingleCore(
      53              :         TPipe* pipe, __gm__ KfcDumpStatMsg* rMsg, __gm__ KfcDumpStatMsg* sMsg, KfcDumpContext* kfcDumpContext)
      54           30 :         : KfcDumpStatOpBase<T>(pipe, rMsg, sMsg, kfcDumpContext)
      55              :     {
      56              :         // Tiling 计算:单核模板每次都是计算所有数据
      57           30 :         blockOffset_ = 0;
      58           30 :         maxProcCount_ = CalculateMaxProcCount(xDtypeSize_, ubSize_);
      59           30 :         perBlockCount_ = BLOCK_SIZE / xDtypeSize_;
      60           30 :         tileLengthMean_ = maxProcCount_ / BUFFER_NUM;
      61           30 :         tileNumMean_ = totalCount_ / tileLengthMean_;
      62           30 :         tileLengthEnd_ = totalCount_ % tileLengthMean_;
      63           30 :         tileNumEnd_ = tileLengthEnd_ == 0 ? 0 : 1;
      64           30 :         innerLoopTime_ = tileNumMean_;
      65           30 :     }
      66              : 
      67           30 :     __aicore__ inline void Init()
      68              :     {
      69           30 :         KfcDumpStatOpBase<T>::Init();
      70              :         // 单核模板 mask 固定大小
      71           30 :         pPipe_->InitBuffer(maskBuf_, MAX_MASK_NUM * BLOCK_SIZE);
      72           30 :         InitCacheBuf();
      73           30 :     }
      74              : 
      75           30 :     __aicore__ inline void Process()
      76              :     {
      77              :         // 无使能统计项或核数为 0 时 eachCoreStatNum 为 0,直接回消息返回,避免除零
      78           30 :         int64_t eachCoreStatNum = (statNum_ == 0 || aiCoreNum_ == 0) ? 0 : CeilDiv(statNum_, aiCoreNum_);
      79           30 :         if (eachCoreStatNum == 0) {
      80            1 :             SyncAllCores();
      81            1 :             if (blockIdx_ == 0) {
      82            1 :                 UpdateMsg(sMsg_, rMsg_, true);
      83              :             }
      84            1 :             SyncAllCores();
      85            1 :             return;
      86              :         }
      87           29 :         int64_t enabledStatNum = 0; // 已遍历的使能统计项个数
      88          232 :         for (int64_t processStatIdx = 0; processStatIdx < MAX_STAT_NUM && enabledStatNum < statNum_; ++processStatIdx) {
      89          203 :             if ((dumpStatClass_ & (1ULL << processStatIdx)) == 0) {
      90            5 :                 continue;
      91              :             }
      92              :             // 单核模板按核序划分统计项:仅当该统计项落在当前核的分片内才执行
      93          198 :             if (IsStatOwner(enabledStatNum, eachCoreStatNum)) {
      94          198 :                 RunStatCompute(processStatIdx);
      95          198 :                 CopyOutStatResult(processStatIdx, enabledStatNum);
      96              :             }
      97          198 :             ++enabledStatNum;
      98              :         }
      99              : 
     100           29 :         SyncAllCores();
     101           29 :         CoreReduce(eachCoreStatNum);
     102           29 :         SyncAllCores();
     103              :     }
     104              : 
     105              : private:
     106              :     // 统计项使能序号 enabledStatIdx 是否属于当前核(每核承担 eachCoreStatNum 个统计项)
     107          198 :     __aicore__ inline bool IsStatOwner(int64_t enabledStatIdx, int64_t eachCoreStatNum) const
     108              :     {
     109          198 :         if (eachCoreStatNum == 0) { // 除零防护,正常流程不会为 0
     110            0 :             return false;
     111              :         }
     112          198 :         int64_t coreIdx = enabledStatIdx / eachCoreStatNum;
     113          198 :         return coreIdx == blockIdx_;
     114              :     }
     115              : 
     116           29 :     __aicore__ inline void CoreReduce(int64_t eachCoreStatNum)
     117              :     {
     118           29 :         if (blockIdx_ != 0 || eachCoreStatNum == 0) { // eachCoreStatNum 为 0 时无输出可汇总
     119            0 :             return;
     120              :         }
     121           29 :         int64_t curCoreStart = 0;
     122         1885 :         for (int64_t processStatIdx = 0; processStatIdx < MAX_STAT_NUM; ++processStatIdx) {
     123         1856 :             if ((dumpStatClass_ & (1ULL << processStatIdx)) != 0) {
     124          198 :                 auto coreIdx = curCoreStart / eachCoreStatNum;
     125          198 :                 uint64_t curWorkSpaceAddr = workspace_ + coreIdx * (statNum_ * MAX_WORKSPACE_BYTE_SIZE) +
     126          198 :                                             curCoreStart * MAX_WORKSPACE_BYTE_SIZE;
     127          198 :                 UpdateStatOutput(processStatIdx, curWorkSpaceAddr);
     128          198 :                 curCoreStart += 1;
     129              :             }
     130              :         }
     131              : 
     132           29 :         UpdateMsg(sMsg_, rMsg_, true);
     133              :     }
     134              : };
     135              : 
     136              : } // namespace KfcDumpStat
     137              : 
     138              : #endif // __KFC_DUMP_SINGLE_CORE_H__
        

Generated by: LCOV version 2.0-1