LCOV - code coverage report
Current view: top level - base_comm/primitives/aicpu/task_cache - aicpu_task_cache_entry.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.0 % 25 21
Test Date: 2026-08-18 17:47:01 Functions: 75.0 % 8 6

            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 HCOMM_AICPU_TASK_CACHE_ENTRY_H
      12              : #define HCOMM_AICPU_TASK_CACHE_ENTRY_H
      13              : 
      14              : #include <cstdint>
      15              : #include <vector>
      16              : #include <unordered_map>
      17              : 
      18              : #include "ub_conn_lite.h"
      19              : #include "udma_data_struct.h"
      20              : #include "ub_transport_lite_impl.h"
      21              : #include "rtsq_a5.h"
      22              : #include "dfx_profiling_handler_lite.h"
      23              : #include "aicpu_ts_thread.h"
      24              : #include "sqe.h"
      25              : #include "res_pub.h"
      26              : 
      27              : using std::vector;
      28              : 
      29              : using Hccl::AC_SQE_SIZE;
      30              : using hccl::AicpuTsThread;
      31              : using Hccl::DbSqeProfInfo;
      32              : using Hccl::RtsqA5;
      33              : using Hccl::TaskParamTypeVal;
      34              : using Hccl::UbConnLite;
      35              : using Hccl::UbTransportLiteImpl;
      36              : using Hccl::WqeTask;
      37              : 
      38              : using Hccl::Rt91095StarsMemcpySqe;
      39              : using Hccl::Rt91095StarsSqeHeader;
      40              : using Hccl::Rt91095StarsSqeType;
      41              : using Hccl::Rt91095StarsUbdmaDBmodeSqe;
      42              : using Hccl::Rt91095StarsWriteValueSqe;
      43              : using Hccl::StreamLite;
      44              : using Hccl::UdmaSqeCommon;
      45              : using Hccl::UdmaSqeRead;
      46              : using Hccl::UdmaSqeWrite;
      47              : using Hccl::UdmaSqeWriteWithNotify;
      48              : using Hccl::UdmaSqOpcode;
      49              : 
      50              : namespace hcomm {
      51              : 
      52              : // 注意: 与ub_conn_lite.cc保持一致
      53              : constexpr uint32_t WRITE_WITH_NOTIFY_OPCODE = 0x5;
      54              : 
      55              : // 记录wqeTaskArrayInfos_中的每一段WQE数组, 对应的DbSqe在sqeArrayInfos_中的位置
      56              : struct DbSqeLocation {
      57              :     uint32_t sqeArrayIdx = 0; // sqeArrayInfos_中第几个SQE数组
      58              :     uint32_t dbSqeIdx = 0;    // sqeArrayInfos_[sqeArrayIdx]数组中第几个SQE是DbSqe
      59              : 
      60            0 :     bool operator==(const DbSqeLocation& other) const
      61              :     {
      62            0 :         return sqeArrayIdx == other.sqeArrayIdx && dbSqeIdx == other.dbSqeIdx;
      63              :     }
      64              : };
      65              : 
      66              : } // namespace hcomm
      67              : 
      68              : namespace std {
      69              : template <>
      70              : struct hash<hcomm::DbSqeLocation> {
      71            0 :     inline size_t operator()(const hcomm::DbSqeLocation& loc) const noexcept
      72              :     {
      73            0 :         return (static_cast<size_t>(loc.sqeArrayIdx) << 32) | loc.dbSqeIdx;
      74              :     }
      75              : };
      76              : } // namespace std
      77              : 
      78              : namespace hcomm {
      79              : 
      80              : enum class TaskArrayType : uint8_t {
      81              :     kTaskArrayTypeInvalid = 0,
      82              :     kTaskArrayTypeSqe = 1,
      83              :     kTaskArrayTypeWqe = 2,
      84              : };
      85              : 
      86              : struct AddrRefreshInfo {
      87              :     explicit AddrRefreshInfo();
      88              :     explicit AddrRefreshInfo(const uint32_t curMemIdx);
      89              :     explicit AddrRefreshInfo(const AddrRefreshInfo& other);
      90              :     ~AddrRefreshInfo();
      91              : 
      92              :     const AddrRefreshInfo& operator=(const AddrRefreshInfo& other); // 拷贝赋值操作符
      93              : 
      94              :     bool needRefresh
      95              :         = false; // false: fixed memory (例如硬件地址, ccl buffer); true: dynamic memory (e.g., user memory)
      96              :     uint32_t memIdx = 0; // 第几个memory range (cachedBaseAddrs_ + cachedSizes_)
      97              :     size_t offset = 0;   // 刷新地址的偏移
      98              : };
      99              : 
     100              : struct SqeArrayInfo {
     101              :     uint8_t* sqeArray = nullptr;
     102              :     RtsqA5* rtsqPtr = nullptr;
     103              :     AicpuTsThread* aicpuTsThreadPtr = nullptr;
     104              :     uint64_t sqeCount = 0;
     105              :     vector<AddrRefreshInfo> srcAddrRefreshInfoArray;
     106              :     vector<AddrRefreshInfo> dstAddrRefreshInfoArray;
     107              : 
     108           33 :     uint64_t GetSize() const
     109              :     {
     110           33 :         return sqeCount * AC_SQE_SIZE + sizeof(RtsqA5*) + sizeof(AicpuTsThread*) + sizeof(uint64_t)
     111           33 :                + sizeof(AddrRefreshInfo) * sqeCount + sizeof(AddrRefreshInfo) * sqeCount;
     112              :     }
     113              : };
     114              : 
     115              : struct WqeTaskArrayInfo {
     116              :     vector<WqeTask> wqeTaskArray;
     117              :     UbConnLite* ubConnLitePtr = nullptr;
     118              :     UbTransportLiteImpl* ubTransportLiteImplPtr = nullptr;
     119              :     DbSqeLocation dbSqeLocation; // 根据DbSqeLocation定位对应的SQE数组和其中的DbSqe
     120              :     vector<AddrRefreshInfo> locAddrRefreshInfoArray;
     121              :     vector<AddrRefreshInfo> rmtAddrRefreshInfoArray;
     122              : 
     123           12 :     uint64_t GetSize() const
     124              :     {
     125           12 :         return wqeTaskArray.size() * sizeof(WqeTask) + sizeof(UbConnLite*) + sizeof(UbTransportLiteImpl*)
     126           12 :                + sizeof(DbSqeLocation) + sizeof(AddrRefreshInfo) * wqeTaskArray.size()
     127           12 :                + sizeof(AddrRefreshInfo) * wqeTaskArray.size();
     128              :     }
     129              : };
     130              : 
     131              : // DbSqe的临时信息, 用于cache miss时构造DbSqeLocation (DbSqe所在的SQE数组插入缓存时才能确定)
     132              : struct DbSqeTmpInfo {
     133              :     uint32_t wqeArrayIdx = 0;
     134              :     uint32_t dbSqeIdx = 0;
     135              :     bool isReportTask = false;
     136              :     DbSqeProfInfo dbSqeProfInfo;
     137              : };
     138              : 
     139              : // DbSqe的profiling信息, 用于cache hit时填充DfxTaskInfo
     140              : struct DbSqeProfAndRefreshInfo {
     141              :     DbSqeProfInfo dbSqeProfInfo;
     142              : 
     143              :     // 用于刷新DbSqeProfInfo中的地址, SubmitCacheEntry时设置, RefreshAndLaunch时使用
     144              :     AddrRefreshInfo srcAddrRefreshInfo;
     145              :     AddrRefreshInfo dstAddrRefreshInfo;
     146              : 
     147              :     uint32_t wqeArrayIdx; // 反向定位DbSqe对应的WQE数组
     148              : };
     149              : 
     150              : struct TokenInfo {
     151              :     bool needLocTokenIdFlag = false;
     152              :     uint32_t locTokenId = 0;
     153              : 
     154              :     bool needRmtTokenIdAndValueFlag = false;
     155              :     uint32_t rmtTokenId = 0;
     156              :     uint32_t rmtTokenValue = 0;
     157              : };
     158              : 
     159              : // aicpu task cache单向依赖RtsqA5/UbConnLite, 下发SQE/WQE
     160              : // aicpu task cache单向依赖UbTransportLiteImpl, 获取token id/value
     161              : // aicpu task cache单向依赖AicpuTsThread/UbTransportLiteImpl, 按需填充DfxTaskInfo并上报profiling
     162              : // 注意: aicpu task cache通过在RtsqA5/UbConnLite注册回调函数, 捕捉下发的SQE/WQE并插入缓存
     163              : class AicpuTaskCacheEntry {
     164              : public:
     165              :     explicit AicpuTaskCacheEntry();
     166              :     ~AicpuTaskCacheEntry();
     167              : 
     168              :     // Cache admission (cache miss)
     169              :     HcclResult
     170              :     InitCacheEntry(const uint64_t* baseAddrs, const uint64_t* memSizes, const uint32_t count); // 算子展开前保存地址信息
     171              :     HcclResult AddSqeArray(
     172              :         RtsqA5* rtsqPtr, AicpuTsThread* aicpuTsThreadPtr, const uint64_t sqeCount, const uint8_t* sqeArray,
     173              :         const uint32_t streamId);
     174              :     HcclResult AddWqeArray(
     175              :         UbConnLite* ubConnLitePtr, UbTransportLiteImpl* ubTransportLiteImplPtr, const vector<WqeTask>& wqeTasks,
     176              :         const uint32_t streamId, const uint32_t dbSqeIdx, const bool isReportTask, const DbSqeProfInfo& dbSqeProfInfo);
     177              :     HcclResult SubmitCacheEntry(); // 算子展开后, 更新AddrRefreshInfo和token信息
     178           17 :     inline uint64_t GetEntryBytes() const { return entryBytes_; }
     179              : 
     180              :     // Cache hit
     181              :     // 注意: 如果需要支持profiling, 参考AicpuTsThread和UbTransportLiteImpl填充DfxTaskInfo并经NextTaskSlot上报
     182              :     // 注意: inplace刷新缓存的task, 下发完成后需要更新缓存的user input/output memory range
     183              :     HcclResult RefreshAndLaunch(const uint64_t* baseAddrs, const uint64_t* memSizes, const uint32_t count);
     184              : 
     185              : private:
     186              :     typedef void* UbTransportLiteImplHandle; // UbTransportLiteImpl*
     187              : 
     188           40 :     inline static void CombineUint32ToUint64(uint64_t& addr, const uint32_t high, const uint32_t low)
     189              :     {
     190           40 :         constexpr uint64_t uintBitWidth = 32;
     191           40 :         addr = (static_cast<uint64_t>(high) << uintBitWidth) | static_cast<uint64_t>(low);
     192           40 :         return;
     193              :     }
     194              : 
     195           10 :     inline static void SplitUint64ToUint32(const uint64_t addr, uint32_t& high, uint32_t& low)
     196              :     {
     197           10 :         constexpr uint64_t uintBitWidth = 32;
     198           10 :         high = static_cast<uint32_t>(addr >> uintBitWidth);
     199           10 :         low = static_cast<uint32_t>(addr & 0xFFFFFFFFULL);
     200           10 :         return;
     201              :     }
     202              : 
     203              :     inline static bool InRange(const uint64_t baseAddr, const uint64_t memSize, const uint64_t addr);
     204              : 
     205              :     inline HcclResult
     206              :     AddSqeArray_(uint8_t* newSqeArray, const size_t sqeBytes, const uint8_t* sqeArray, const uint32_t streamId);
     207              : 
     208              :     // 插入WQE/SQE数组时, 更新AddrRefreshInfo
     209              :     HcclResult UpdateSqeAddrRefreshInfo_(
     210              :         const uint8_t* sqePtr, AddrRefreshInfo& srcAddrRefreshInfo, AddrRefreshInfo& dstAddrRefreshInfo) const;
     211              :     HcclResult UpdateWqeAddrRefreshInfoAndTokenInfo_(
     212              :         const WqeTask& wqeTask, AddrRefreshInfo& locAddrRefreshInfo, AddrRefreshInfo& rmtAddrRefreshInfo,
     213              :         vector<TokenInfo>& tokenInfos);
     214              :     inline HcclResult UpdateTokenFlagsByAddrRefreshInfo_(
     215              :         const AddrRefreshInfo& addrRefreshInfo, vector<TokenInfo>& tokenInfos, bool isLoc);
     216              :     inline HcclResult
     217           28 :     UpdateAddrRefreshInfo_(const uint32_t addrLow, const uint32_t addrHigh, AddrRefreshInfo& addrRefreshInfo) const
     218              :     {
     219              :         // 拼接地址
     220           28 :         uint64_t addr = 0;
     221           28 :         AicpuTaskCacheEntry::CombineUint32ToUint64(addr, addrHigh, addrLow);
     222           56 :         return UpdateAddrRefreshInfo_(addr, addrRefreshInfo);
     223              :     }
     224              :     HcclResult UpdateAddrRefreshInfo_(const uint64_t addr, AddrRefreshInfo& addrRefreshInfo) const;
     225              : 
     226              :     // 刷新下发SQE
     227              :     inline HcclResult RefreshSqeTasks_(const SqeArrayInfo& sqeArrayInfo, const uint64_t* baseAddrs);
     228              :     inline HcclResult LaunchSqeTasks_(const SqeArrayInfo& sqeArrayInfo);
     229              : 
     230              :     // 刷新下发WQE, 并刷新对应的DbSqe
     231              :     inline HcclResult RefreshWqeTasks_(
     232              :         WqeTaskArrayInfo& wqeTaskArrayInfo, const uint64_t* baseAddrs, const uint64_t* memSizes, const uint32_t count);
     233              :     inline HcclResult LaunchWqeTasks_(WqeTaskArrayInfo& wqeTaskArrayInfo);
     234              :     inline HcclResult RefreshDbSqe_(WqeTaskArrayInfo& wqeTaskArrayInfo);
     235              : 
     236              :     // 根据AddrRefreshInfo刷新WQE/SQE/DbSqeProfInfo地址字段
     237              :     inline void RefreshTaskAddr_(
     238              :         uint32_t& addrLow, uint32_t& addrHigh, const AddrRefreshInfo& addrRefreshInfo, const uint64_t* baseAddrs) const;
     239              :     inline void
     240              :     RefreshTaskAddr_(uint64_t& addr, const AddrRefreshInfo& addrRefreshInfo, const uint64_t* baseAddrs) const;
     241              : 
     242              :     // 根据刷新后的新地址, 按需刷新WQE的token id/value
     243              :     inline HcclResult RefreshWqeLocTokenId_(
     244              :         uint32_t& tokenId, const AddrRefreshInfo& addrRefreshInfo, const vector<TokenInfo>& tokenInfos) const;
     245              :     inline HcclResult RefreshWqeRmtTokenIdAndValue_(
     246              :         uint32_t& tokenId, uint32_t& tokenValue, const AddrRefreshInfo& addrRefreshInfo,
     247              :         const vector<TokenInfo>& tokenInfos) const;
     248              : 
     249              :     // 使能profiling时, 对每个刷新的SQE填充DfxTaskInfo并经NextTaskSlot上报
     250              :     HcclResult ReportSqeArrayProfiling_(
     251              :         size_t arrayIdx, const uint64_t* baseAddrs, const uint64_t* memSizes, const uint32_t count);
     252              :     HcclResult ReportSqeProfiling_(
     253              :         uint8_t* sqePtr, size_t arrayIdx, uint32_t sqeIdx, const uint64_t* baseAddrs, const uint64_t* memSizes,
     254              :         const uint32_t count, StreamLite* streamLite, const u32 sqId);
     255              :     HcclResult ReportDbSqeProfiling_(
     256              :         uint8_t* dbSqePtr, size_t arrayIdx, uint32_t dbSqeIdx, const uint64_t* baseAddrs, const uint64_t* memSizes,
     257              :         const uint32_t count, StreamLite* streamLite, const u32 sqId, const u32 taskId);
     258              : 
     259              :     // SubmitCacheEntry子方法
     260              :     inline HcclResult SubmitSqeAddrRefreshInfo_();
     261              :     inline HcclResult SubmitWqeAddrRefreshInfoAndTokenInfo_();
     262              :     inline HcclResult SubmitDbSqeProfRefreshInfo_();
     263              :     inline HcclResult ValidateLaunchOrder_();
     264              : 
     265              :     // RefreshAndLaunch子方法
     266              :     inline HcclResult RefreshTokenInfos_(const uint64_t* baseAddrs, const uint64_t* memSizes, const uint32_t count);
     267              :     inline HcclResult
     268              :     LaunchTasksByOrder_(const uint64_t* baseAddrs, const uint64_t* memSizes, const uint32_t count, bool needTaskParam);
     269              :     inline HcclResult PrintRefreshResult_(const uint64_t* baseAddrs, const uint64_t* memSizes, const uint32_t count);
     270              : 
     271              :     // RefreshSqeTasks_子方法
     272              :     inline HcclResult RefreshOneSqe_(
     273              :         uint8_t* sqeArrayPtr, const AddrRefreshInfo& srcAddrRefreshInfo, const AddrRefreshInfo& dstAddrRefreshInfo,
     274              :         const uint64_t* baseAddrs);
     275              : 
     276              :     // RefreshWqeTasks_子方法
     277              :     inline void DumpWqeTasksHeader_(uint64_t wqeCount, const UbConnLite* ubConnLitePtr) const;
     278              :     inline HcclResult DumpWqeTasksPerWqe_(size_t wqeIdx, const WqeTask& wqeTask, const UbConnLite* ubConnLitePtr) const;
     279              :     inline HcclResult RefreshWqeRead_(
     280              :         WqeTask& wqeTask, const AddrRefreshInfo& locAddrRefreshInfo, const AddrRefreshInfo& rmtAddrRefreshInfo,
     281              :         const uint64_t* baseAddrs, const vector<TokenInfo>& tokenInfos);
     282              :     inline HcclResult RefreshWqeWrite_(
     283              :         WqeTask& wqeTask, const AddrRefreshInfo& locAddrRefreshInfo, const AddrRefreshInfo& rmtAddrRefreshInfo,
     284              :         const uint64_t* baseAddrs, const vector<TokenInfo>& tokenInfos);
     285              :     inline HcclResult RefreshWqeWriteWithNotify_(
     286              :         WqeTask& wqeTask, const AddrRefreshInfo& locAddrRefreshInfo, const AddrRefreshInfo& rmtAddrRefreshInfo,
     287              :         const uint64_t* baseAddrs, const vector<TokenInfo>& tokenInfos);
     288              : 
     289              :     // ReportDbSqeProfiling_子方法
     290              :     inline HcclResult FillSlotUbDma_(
     291              :         Hccl::DfxTaskInfo* slot, const uint8_t* sqePtr, const DbSqeProfAndRefreshInfo& profAndRefreshInfo,
     292              :         UbTransportLiteImpl* ubTransportLiteImplPtr, StreamLite* streamLite, u32 taskId) const;
     293              :     inline HcclResult FillSlotReduce_(
     294              :         Hccl::DfxTaskInfo* slot, const uint8_t* sqePtr, const DbSqeProfAndRefreshInfo& profAndRefreshInfo,
     295              :         UbTransportLiteImpl* ubTransportLiteImplPtr, StreamLite* streamLite, u32 taskId) const;
     296              :     inline HcclResult RefreshDbSqeProfAddrs_(
     297              :         DbSqeProfAndRefreshInfo& profAndRefreshInfo, const uint64_t* baseAddrs, const uint64_t* memSizes,
     298              :         const uint32_t count);
     299              : 
     300              :     // ReportSqeProfiling_子方法
     301              :     inline HcclResult
     302              :     FillSlotNotify_(Hccl::DfxTaskInfo* slot, const uint8_t* sqePtr, StreamLite* streamLite, u32 taskId) const;
     303              :     inline HcclResult
     304              :     FillSlotSdma_(Hccl::DfxTaskInfo* slot, const uint8_t* sqePtr, StreamLite* streamLite, u32 taskId) const;
     305              :     inline void FillSlotCommonFields_(
     306              :         Hccl::DfxTaskInfo* slot, StreamLite* streamLite, u32 taskId, u8 linkType, u8 transportType,
     307              :         u64 channelHandle) const;
     308              :     inline u8 ConvertSdmaOpCodeToReduceOp_(uint8_t opcode) const;
     309              : 
     310              :     // 统计当前cache entry的bytes开销
     311              :     uint64_t entryBytes_ = 0;
     312              : 
     313              :     // AddWqeArray时临时记录该段WQE数组对应的DbSqe的streamId, sqeIdx, 和profInfo;
     314              :     // 后续AddSqeArray时, 根据streamId才能确定对应的DbSqe在sqeArrayInfos_中的arrayIdx,
     315              :     //     从而确定DbSqeLocation并更新dbSqeLocInfoMap_;
     316              :     // 注意: 只有第一次cache miss时, 才会使用该map; 第一次算子展开完成后, 该map一定为空, 因此无需更新entryBytes_
     317              :     std::unordered_map<uint32_t, vector<DbSqeTmpInfo>> streamIdToDbSqeTmpInfoMap_;
     318              : 
     319              :     // 多段SQE数组: 每段SQE数组对应一次LaunchTask, 以及相应的RtsqA5指针
     320              :     vector<SqeArrayInfo> sqeArrayInfos_;
     321              : 
     322              :     // 多段WQE数组: 每段WQE数组对应多次ProcessOneWqe/ProcessOneWqeWithNotify (按256MiB切分, 但始终只对应**一个**DbSqe),
     323              :     //     以及相应的ubConnLite指针和DbSqeLocation
     324              :     vector<WqeTaskArrayInfo> wqeTaskArrayInfos_;
     325              : 
     326              :     // 维护DbSqeLocation-DbSqeProfAndRefreshInfo的映射 (只有profiling使能时, 才需要维护)
     327              :     // 注意: dbSqeLocInfoMap_不计入entryBytes_, 避免开启profiling与关闭profiling时aicpu task cache行为不一致
     328              :     std::unordered_map<DbSqeLocation, DbSqeProfAndRefreshInfo> dbSqeLocInfoMap_; // AddSqeArray时更新
     329              : 
     330              :     // 下发顺序
     331              :     vector<TaskArrayType> launchOrder_; // 大小一定为SQE+WQE数组之和
     332              : 
     333              :     // Cached memory ranges: InitCacheEntry时初始化, SubmitCacheEntry时用于计算AddrRefreshInfo,
     334              :     // RefreshAndLaunch时无需更新
     335              :     vector<uint64_t> cachedBaseAddrs_;
     336              :     vector<uint64_t> cachedMemSizes_;
     337              : 
     338              :     // 每个UbTransportLiteImplHandle 每段动态内存 对应的token信息
     339              :     std::unordered_map<UbTransportLiteImplHandle, vector<TokenInfo>> tokenInfosMap_;
     340              : 
     341              :     // 合并task-level config debug日志打印判断 (构造cache entry时设置)
     342              :     bool isTaskConfigDebug_ = false;
     343              : };
     344              : 
     345              : } // namespace hcomm
     346              : 
     347              : #endif // HCOMM_AICPU_TASK_CACHE_ENTRY_H
        

Generated by: LCOV version 2.0-1