LCOV - code coverage report
Current view: top level - legacy/ascend910/platform/common/unfold_cache - op_unfold_cache_entry.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.7 % 998 7
Test Date: 2026-07-28 12:11:00 Functions: 2.4 % 42 1

            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 <cstdint>
      12              : #include <cstdlib>
      13              : 
      14              : #include "op_unfold_cache_entry.h"
      15              : 
      16              : #include "aicpu_hccl_sqcq.h"
      17              : #include "aicpu_hccl_sqcqv1.h"
      18              : #include "aicpu_hccl_sqcqv2.h"
      19              : #include "dispatcher_pub.h" // HCCL_SDMA_MAX_COUNT_4GB
      20              : #include "log.h"
      21              : #include "sal.h"
      22              : 
      23              : namespace hccl {
      24              : 
      25              :     // struct OpUnfoldMemRange
      26              : 
      27            0 :     OpUnfoldMemRange::OpUnfoldMemRange() : isValid(false), baseAddr(0), memSize(0) {
      28            0 :     }
      29              : 
      30            0 :     OpUnfoldMemRange::OpUnfoldMemRange(const uint64_t curBaseAddr, const uint64_t curMemSize) : isValid(true), baseAddr(curBaseAddr), memSize(curMemSize) {
      31              :         // 检查地址有效性
      32            0 :         CHK_PRT_CONT(curBaseAddr == 0, HCCL_ERROR("[OpUnfoldMemRange][OpUnfoldMemRange] curBaseAddr is 0"));
      33            0 :     }
      34              : 
      35            0 :     OpUnfoldMemRange::OpUnfoldMemRange(const OpUnfoldMemRange& other)
      36            0 :         : isValid(other.isValid), baseAddr(other.baseAddr), memSize(other.memSize) {
      37            0 :     }
      38              : 
      39            0 :     OpUnfoldMemRange::~OpUnfoldMemRange() {}
      40              : 
      41            0 :     const OpUnfoldMemRange& OpUnfoldMemRange::operator=(const OpUnfoldMemRange& other) {
      42            0 :         if (this != &other) {
      43            0 :             isValid = other.isValid;
      44            0 :             baseAddr = other.baseAddr;
      45            0 :             memSize = other.memSize;
      46              :         }
      47            0 :         return *this;
      48              :     }
      49              : 
      50            0 :     HcclResult OpUnfoldMemRange::GetEndAddr(uint64_t& endAddr) const {
      51              :         // 检查地址是否溢出
      52            0 :         CHK_PRT_RET(baseAddr + memSize < baseAddr,
      53              :             HCCL_ERROR("[OpUnfoldMemRange][InRange] baseAddr[0x%016llx] + memSize[%llu] overflows", baseAddr, memSize),
      54              :             HCCL_E_INTERNAL);
      55              :         
      56            0 :         endAddr = baseAddr + memSize;
      57            0 :         return HCCL_SUCCESS;
      58              :     }
      59              : 
      60            0 :     HcclResult OpUnfoldMemRange::InRange(const uint64_t addr, bool& isInRange) const {
      61            0 :         uint64_t endAddr = 0;
      62            0 :         CHK_RET(GetEndAddr(endAddr));
      63              : 
      64            0 :         if (isValid && addr >= baseAddr && addr < endAddr) {
      65            0 :             isInRange = true;
      66              :         } else {
      67            0 :             isInRange = false;
      68              :         }
      69              : 
      70            0 :         return HCCL_SUCCESS;
      71              :     }
      72              : 
      73              :     // struct RefreshAddrInfo
      74              : 
      75            0 :     RefreshAddrInfo::RefreshAddrInfo() : rankId(INVALID_VALUE_RANKID), memType(RefreshAddrInfo::INVALID_MEMTYPE) {
      76            0 :     }
      77              : 
      78            0 :     RefreshAddrInfo::RefreshAddrInfo(const uint32_t curRankId, const uint8_t curMemType) : rankId(curRankId), memType(curMemType) {
      79              :         // 注意: rankId可以为INVALID_VALUE_RANKID, 表示访问本地rank
      80            0 :         CHK_PRT_CONT(memType == INVALID_MEMTYPE, HCCL_ERROR("[RefreshAddrInfo][RefreshAddrInfo] invalid memType"));
      81            0 :     }
      82              : 
      83            0 :     RefreshAddrInfo::RefreshAddrInfo(const RefreshAddrInfo& other)
      84            0 :         : rankId(other.rankId), memType(other.memType) {
      85            0 :     }
      86              : 
      87            0 :     RefreshAddrInfo::~RefreshAddrInfo() {}
      88              : 
      89            0 :     const RefreshAddrInfo& RefreshAddrInfo::operator=(const RefreshAddrInfo& other) {
      90            0 :         if (this != &other) {
      91            0 :             rankId = other.rankId;
      92            0 :             memType = other.memType;
      93              :         }
      94            0 :         return *this;
      95              :     }
      96              : 
      97              :     // struct AlltoallvMetadata
      98              : 
      99           32 :     AlltoallvMetadata::AlltoallvMetadata() {
     100           32 :         sdmaDataBlockSize = 0;
     101           32 :         hcclInputMemRanges.clear();
     102           32 :         notifyIdRankRflagMap.clear();
     103           32 :         signalAddrRankRflagMap.clear();
     104              : 
     105           32 :         hcclOffsetDstRanksIdxMap.clear();
     106           32 :     }
     107              :     
     108            0 :     void AlltoallvMetadata::Clear() {
     109            0 :         sdmaDataBlockSize = 0;
     110            0 :         hcclInputMemRanges.clear();
     111            0 :         notifyIdRankRflagMap.clear();
     112            0 :         signalAddrRankRflagMap.clear();
     113            0 :         hcclOffsetDstRanksIdxMap.clear();
     114            0 :         return;
     115              :     }
     116              : 
     117            0 :     HcclResult AlltoallvMetadata::Check(const bool afterFirstOrch) const {
     118            0 :         CHK_PRT_RET(sdmaDataBlockSize == 0, HCCL_ERROR("[AlltoallvMetadata][Check] sdmaDataBlockSize is zero"), HCCL_E_INTERNAL);
     119              : 
     120            0 :         const uint32_t rankSize = hcclInputMemRanges.size();
     121            0 :         CHK_PRT_RET(rankSize == 0, HCCL_ERROR("[AlltoallvMetadata][Check] empty hcclInputMemRanges"), HCCL_E_INTERNAL);
     122              :         // 注意: 每个remote rank各有两个NotifyId/SignalAddr分别用于send/recv count对应的Wait/Record同步
     123            0 :         CHK_PRT_RET(notifyIdRankRflagMap.size() != 2*(rankSize - 1),
     124              :             HCCL_ERROR("[AlltoallvMetadata][Check] notifyIdRankRflagMap.size[%u] != rankSize-1[%u]",
     125              :                 notifyIdRankRflagMap.size(), 2*(rankSize - 1)),
     126              :             HCCL_E_INTERNAL);
     127            0 :         CHK_PRT_RET(signalAddrRankRflagMap.size() != 2*(rankSize - 1),
     128              :             HCCL_ERROR("[AlltoallvMetadata][Check] signalAddrRankRflagMap.size[%u] != rankSize-1[%u]",
     129              :                 signalAddrRankRflagMap.size(), 2*(rankSize - 1)),
     130              :             HCCL_E_INTERNAL);
     131              : 
     132              :         // 注意: 只有在第一次cache miss的executor->Orchestrate之后, 相关mapping才会被初始化
     133            0 :         if (afterFirstOrch) {
     134            0 :             CHK_PRT_RET(((rankSize > 1) && (hcclOffsetDstRanksIdxMap.size() == 0)),
     135              :                 HCCL_ERROR("[AlltoallvMetadata][Check] empty hcclOffsetDstRanksIdxMap for rankSize[%u]", rankSize),
     136              :                 HCCL_E_INTERNAL); // 注意: 只有当rankSize为1时, hcclOffsetDstRanksIdxMap的size才可以是0
     137              :         }
     138              : 
     139            0 :         return HCCL_SUCCESS;
     140              :     }
     141              : 
     142              :     // struct AlltoallvSendRecvInfo
     143              : 
     144            0 :     AlltoallvSendRecvInfo::AlltoallvSendRecvInfo() {
     145            0 :         sendType = HcclDataType::HCCL_DATA_TYPE_RESERVED;
     146            0 :         recvType = HcclDataType::HCCL_DATA_TYPE_RESERVED;
     147            0 :         sendCounts.clear();
     148            0 :         recvCounts.clear();
     149            0 :         sendOffsets.clear();
     150            0 :         recvOffsets.clear();
     151              : 
     152            0 :         return;
     153              :     }
     154              : 
     155            0 :     HcclResult AlltoallvSendRecvInfo::Check() const {
     156            0 :         CHK_PRT_RET(sendType == HcclDataType::HCCL_DATA_TYPE_RESERVED, HCCL_ERROR("[AlltoallvSendRecvInfo][Check] sendType is reserved"), HCCL_E_INTERNAL);
     157            0 :         CHK_PRT_RET(recvType == HcclDataType::HCCL_DATA_TYPE_RESERVED, HCCL_ERROR("[AlltoallvSendRecvInfo][Check] recvType is reserved"), HCCL_E_INTERNAL);
     158              :         
     159            0 :         const uint32_t rankSize = sendCounts.size();
     160            0 :         CHK_PRT_RET(rankSize == 0, HCCL_ERROR("[AlltoallvSendRecvInfo][Check] empty sendCounts"), HCCL_E_INTERNAL);
     161            0 :         CHK_PRT_RET(recvCounts.size() != rankSize, HCCL_ERROR("[AlltoallvSendRecvInfo][Check] recvCounts.size[%u] != rankSize[%u]", recvCounts.size(), rankSize), HCCL_E_INTERNAL);
     162            0 :         CHK_PRT_RET(sendOffsets.size() != rankSize, HCCL_ERROR("[AlltoallvSendRecvInfo][Check] sendOffsets.size[%u] != rankSize[%u]", sendOffsets.size(), rankSize), HCCL_E_INTERNAL);
     163            0 :         CHK_PRT_RET(recvOffsets.size() != rankSize, HCCL_ERROR("[AlltoallvSendRecvInfo][Check] recvOffsets.size[%u] != rankSize[%u]", recvOffsets.size(), rankSize), HCCL_E_INTERNAL);
     164              :         
     165            0 :         return HCCL_SUCCESS;
     166              :     }
     167              : 
     168              :     // class OpUnfoldCacheEntry
     169              : 
     170            0 :     OpUnfoldCacheEntry::OpUnfoldCacheEntry(const std::vector<OpUnfoldMemRange>& userInputMemRanges, const std::vector<OpUnfoldMemRange>& userOutputMemRanges)
     171            0 :         : userInputMemRanges_(userInputMemRanges), userOutputMemRanges_(userOutputMemRanges) {
     172            0 :         HCCL_INFO("[OpUnfoldCacheEntry][OpUnfoldCacheEntry] create a cache entry with %llu userInputMemRanges and %llu userOutputMemRanges",
     173              :             userInputMemRanges_.size(), userOutputMemRanges_.size());
     174            0 :     }
     175              : 
     176            0 :     OpUnfoldCacheEntry::~OpUnfoldCacheEntry() {
     177            0 :         size_t sqeArrayCount = sqeArrays_.size();
     178            0 :         size_t totalSqeCount = 0;
     179            0 :         for (size_t arrayIdx = 0; arrayIdx < sqeArrayCount; ++arrayIdx) {
     180            0 :             totalSqeCount += srcRefreshAddrInfoArrays_[arrayIdx].size();
     181              : 
     182              :             // 如果存在当前这段连续的SQE数组,则指向内容必不为空
     183              :             // 因为SQE数量为0时, DispatcherAicpu::LaunchTask()会直接返回, 不会添加SQE到OpUnfoldCache中
     184            0 :             uint8_t *curSqeArray = sqeArrays_[arrayIdx];
     185              : 
     186              :             // 释放当前SQE数组
     187            0 :             if (UNLIKELY(curSqeArray == nullptr)) { // 不能使用CHK_PTR_NULL,因为会return HcclResult
     188            0 :                 HCCL_ERROR("[OpUnfoldCacheEntry][~OpUnfoldCacheEntry] curSqeArray is nullptr");
     189              :             } else {
     190            0 :                 free(curSqeArray);
     191            0 :                 curSqeArray = nullptr;
     192              :             }
     193              : 
     194              :             // 同理释放其他空间
     195              : 
     196              :             // 释放当前SQE type数组
     197            0 :             uint8_t *curSqeTypeArray = sqeTypeArrays_[arrayIdx];
     198            0 :             if (UNLIKELY(curSqeTypeArray == nullptr)) {
     199            0 :                 HCCL_ERROR("[OpUnfoldCacheEntry][~OpUnfoldCacheEntry] curSqeTypeArray is nullptr");
     200              :             } else {
     201            0 :                 free(curSqeTypeArray);
     202            0 :                 curSqeTypeArray = nullptr;
     203              :             }
     204              : 
     205              :             // 释放当前SQE DfxInfo数组
     206            0 :             AicpuDfxInfo *curSqeDfxInfoArray = sqeDfxInfoArrays_[arrayIdx];
     207            0 :             if (UNLIKELY(curSqeDfxInfoArray == nullptr)) {
     208            0 :                 HCCL_ERROR("[OpUnfoldCacheEntry][~OpUnfoldCacheEntry] curSqeDfxInfoArray is nullptr");
     209              :             } else {
     210            0 :                 free(curSqeDfxInfoArray);
     211            0 :                 curSqeDfxInfoArray = nullptr;
     212              :             }
     213              :         }
     214              : 
     215            0 :         HCCL_INFO("[OpUnfoldCacheEntry][~OpUnfoldCacheEntry] release %u SQE arrays (%u SQEs in total) from the cache entry", sqeArrayCount, totalSqeCount);
     216            0 :     }
     217              : 
     218            0 :     HcclResult OpUnfoldCacheEntry::GetSqeArrayCount(size_t& sqeArrayCount) const {
     219            0 :         sqeArrayCount = sqeArrays_.size();
     220            0 :         CHK_PRT_RET(sqeArrayCount == 0, HCCL_ERROR("[OpUnfoldCacheEntry][OpUnfoldCacheEntry] sqeArrayCount is 0"), HCCL_E_INTERNAL);
     221            0 :         return HCCL_SUCCESS;
     222              :     }
     223              : 
     224            0 :     HcclResult OpUnfoldCacheEntry::AllocSqeArray(const size_t sqeCount, const int32_t streamId, size_t& arrayIdx) {
     225              :         // Allocate a new SQE array
     226            0 :         const size_t sqeBytes = sqeCount * HCCL_SQE_SIZE;
     227            0 :         uint8_t *newSqeArray = reinterpret_cast<uint8_t *>(malloc(sqeBytes));
     228            0 :         CHK_PTR_NULL(newSqeArray);
     229            0 :         sqeArrays_.emplace_back(newSqeArray);
     230              : 
     231              :         // Allocate a new SQE type array
     232            0 :         const size_t sqeTypeBytes = sqeCount * sizeof(uint8_t);
     233            0 :         uint8_t *newSqeTypeArray = reinterpret_cast<uint8_t *>(malloc(sqeTypeBytes));
     234            0 :         CHK_PTR_NULL(newSqeTypeArray);
     235            0 :         sqeTypeArrays_.emplace_back(newSqeTypeArray);
     236              : 
     237              :         // Allocate a new SQE DFX info array
     238            0 :         const size_t sqeDfxInfoBytes = sqeCount * sizeof(AicpuDfxInfo);
     239            0 :         AicpuDfxInfo *newSqeDfxInfoArray = reinterpret_cast<AicpuDfxInfo *>(malloc(sqeDfxInfoBytes));
     240            0 :         CHK_PTR_NULL(newSqeDfxInfoArray);
     241            0 :         sqeDfxInfoArrays_.emplace_back(newSqeDfxInfoArray);
     242              : 
     243              :         // Copy stream pointer
     244            0 :         CHK_PRT_RET(streamId < 0, HCCL_ERROR("[OpUnfoldCacheEntry][AllocSqeArray] streamId %d < 0", streamId), HCCL_E_INTERNAL);
     245            0 :         streamIds_.emplace_back(streamId);
     246              : 
     247              :         // 注意: streamSeqIdxes_在cache miss LaunchTask()结束后, HcclCommAicpu通过CalcStreamSeqIdxes更新
     248              : 
     249              :         // 初始化src/dst RefreshAddrInfo
     250            0 :         srcRefreshAddrInfoArrays_.emplace_back(sqeCount);
     251            0 :         dstRefreshAddrInfoArrays_.emplace_back(sqeCount);
     252              : 
     253              :         // Set index of allocated array
     254            0 :         arrayIdx = sqeArrays_.size() - 1;
     255              : 
     256            0 :         HCCL_INFO("[OpUnfoldCacheEntry][AllocSqeArray] allocate %uth sqe array with sqeCount of %u and streamId of %d", arrayIdx, sqeCount, streamId);
     257              : 
     258            0 :         return HCCL_SUCCESS;
     259              :     }
     260              : 
     261            0 :     HcclResult OpUnfoldCacheEntry::MemcpySqeArray(const size_t arrayIdx, const size_t sqeStartIdx, const size_t sqeCount, const uint8_t *sqeArray, const uint8_t *sqeTypeArray, const AicpuDfxInfo *sqeDfxInfoArray, const bool isAlltoallv, const AlltoallvMetadata* alltoallvMetadataPtr) {
     262              :         // Copy sqeArray[0:sqeCount) -> sqeArrays_[arrayIdx][sqeStartIdx:sqeStartIdx+sqeCount)
     263              : 
     264              :         // 检验入参
     265            0 :         CHK_PRT_RET(arrayIdx >= sqeArrays_.size(), HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] arrayIdx %u is out of range [0, %u)", arrayIdx, sqeArrays_.size()), HCCL_E_INTERNAL);
     266            0 :         const size_t totalSqeCount = srcRefreshAddrInfoArrays_[arrayIdx].size();
     267            0 :         CHK_PRT_RET(sqeStartIdx + sqeCount - 1 >= totalSqeCount, HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] sqeStartIdx %u + sqeCount %u - 1 is out of range [0, %u)", sqeStartIdx, sqeCount, totalSqeCount), HCCL_E_INTERNAL);
     268            0 :         CHK_PTR_NULL(sqeArray);
     269            0 :         CHK_PTR_NULL(sqeTypeArray);
     270            0 :         CHK_PTR_NULL(sqeDfxInfoArray);
     271            0 :         if (isAlltoallv) {
     272            0 :             CHK_PTR_NULL(alltoallvMetadataPtr);
     273            0 :             CHK_RET(alltoallvMetadataPtr->Check(false));
     274              :         }
     275              : 
     276            0 :         HCCL_INFO("[OpUnfoldCacheEntry][MemcpySqeArray] memcpy %uth sqe array[%u:%u]; isAlltoallv[%u]", arrayIdx, sqeStartIdx, sqeStartIdx + sqeCount - 1, isAlltoallv);
     277              : 
     278              :         // Copy SQE content
     279            0 :         const size_t sqeBytes = sqeCount * HCCL_SQE_SIZE;
     280            0 :         uint8_t *dstSqeArray = sqeArrays_[arrayIdx];
     281            0 :         CHK_PTR_NULL(dstSqeArray);
     282            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(dstSqeArray + sqeStartIdx * HCCL_SQE_SIZE, (totalSqeCount - sqeStartIdx) * HCCL_SQE_SIZE, sqeArray, sqeBytes));
     283              : 
     284              :         // Copy SQE type
     285            0 :         const size_t sqeTypeBytes = sqeCount * sizeof(uint8_t);
     286            0 :         uint8_t *dstSqeTypeArray = sqeTypeArrays_[arrayIdx];
     287            0 :         CHK_PTR_NULL(dstSqeTypeArray);
     288            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(dstSqeTypeArray + sqeStartIdx, (totalSqeCount - sqeStartIdx) * sizeof(uint8_t), sqeTypeArray, sqeTypeBytes));
     289              : 
     290              :         // Copy SQE DFX info
     291            0 :         const size_t sqeDfxInfoBytes = sqeCount * sizeof(AicpuDfxInfo);
     292            0 :         AicpuDfxInfo *dstSqeDfxInfoArray = sqeDfxInfoArrays_[arrayIdx];
     293            0 :         CHK_PTR_NULL(dstSqeDfxInfoArray);
     294            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(dstSqeDfxInfoArray + sqeStartIdx, (totalSqeCount - sqeStartIdx) * sizeof(AicpuDfxInfo), sqeDfxInfoArray, sqeDfxInfoBytes));
     295              : 
     296              :         // 遍历SQE, 根据type更新src/dst RefreshAddrInfo
     297            0 :         std::vector<RefreshAddrInfo>& srcRefreshAddrInfoArray = srcRefreshAddrInfoArrays_[arrayIdx];
     298            0 :         std::vector<RefreshAddrInfo>& dstRefreshAddrInfoArray = dstRefreshAddrInfoArrays_[arrayIdx];
     299            0 :         uint64_t sqeSrcAddr = 0;
     300            0 :         uint64_t sqeDstAddr = 0;
     301            0 :         const uint8_t *sqePtr = sqeArray;
     302            0 :         for (size_t tmpSqeIdx = 0; tmpSqeIdx < sqeCount; tmpSqeIdx++) {
     303            0 :             const size_t cacheSqeIdx = sqeStartIdx + tmpSqeIdx;
     304              : 
     305              :             // 获得当前SQE的信息
     306              :             // 注意: 不使用sqeDfxInfoArray[tmpSqeIdx].remoteRank来准备RefreshAddrInfo, 因为DfxInfo.remoteRank某些整网用例下存在维护异常
     307            0 :             const uint8_t sqeType = sqeTypeArray[tmpSqeIdx];
     308              : 
     309              :             // 根据SQE type更新RefreshAddrInfo
     310            0 :             switch(sqeType) {
     311            0 :                 case SqeType::NOTIFY_SQE:
     312              :                 case SqeType::EVENT_SQE: {
     313              :                     // No need to update src/dst RefreshAddrInfo due to no addr fields
     314            0 :                     break;
     315              :                 }
     316            0 :                 case SqeType::WRITE_VALUE_SQE:
     317              :                 case SqeType::RDMA_DB_SEND_SQE: {
     318            0 :                     const rtStarsWriteValueSqe_t *writeValueSqePtr = reinterpret_cast<const rtStarsWriteValueSqe_t *>(sqePtr);
     319              :                     
     320            0 :                     CombineUint32ToUint64(sqeDstAddr, writeValueSqePtr->write_addr_high, writeValueSqePtr->write_addr_low);
     321            0 :                     CHK_RET(CheckAndPrepareRefreshAddrInfo(sqeDstAddr, dstRefreshAddrInfoArray[cacheSqeIdx], false, nullptr)); // 注意: alltoallv算子有WRITE_VALUE_SQE, 但不会存在对于HCCL input buffer的访问, 无需确认HCCL input buffer对应的rank id进行地址刷新
     322              : 
     323            0 :                     break;
     324              :                 }
     325            0 :                 case SqeType::MEMCPY_ASYNC_SQE: {
     326            0 :                     const rtStarsMemcpyAsyncSqe_t *memcpyAsyncSqePtr = reinterpret_cast<const rtStarsMemcpyAsyncSqe_t *>(sqePtr);
     327              : 
     328            0 :                     CombineUint32ToUint64(sqeSrcAddr, memcpyAsyncSqePtr->src_addr_high, memcpyAsyncSqePtr->src_addr_low);
     329            0 :                     CHK_RET(CheckAndPrepareRefreshAddrInfo(sqeSrcAddr, srcRefreshAddrInfoArray[cacheSqeIdx], isAlltoallv, alltoallvMetadataPtr));
     330              : 
     331            0 :                     CombineUint32ToUint64(sqeDstAddr, memcpyAsyncSqePtr->dst_addr_high, memcpyAsyncSqePtr->dst_addr_low);
     332            0 :                     CHK_RET(CheckAndPrepareRefreshAddrInfo(sqeDstAddr, dstRefreshAddrInfoArray[cacheSqeIdx], isAlltoallv, alltoallvMetadataPtr));
     333              : 
     334            0 :                     break;
     335              :                 }
     336            0 :                 case SqeType::CCORE_WAIT_START_SQE: {
     337            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] SqeType::CCORE_WAIT_START_SQE is not supported in A3");
     338            0 :                     return HCCL_E_NOT_SUPPORT;
     339              :                 }
     340            0 :                 case SqeType::CCORE_WRITE_VALUE_SQE: {
     341            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] SqeType::CCORE_WRITE_VALUE_SQE is not supported in A3");
     342            0 :                     return HCCL_E_NOT_SUPPORT;
     343              :                 }
     344            0 :                 case SqeType::NOTIFY_SQE_V2: {
     345            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] SqeType::NOTIFY_SQE_V2 is not supported in A3");
     346            0 :                     return HCCL_E_NOT_SUPPORT;
     347              :                 }
     348            0 :                 case SqeType::WRITE_VALUE_SQE_V2: {
     349            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] SqeType::WRITE_VALUE_SQE_V2 is not supported in A3");
     350            0 :                     return HCCL_E_NOT_SUPPORT;
     351              :                 }
     352            0 :                 case SqeType::EVENT_SQE_V2: {
     353            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] SqeType::EVENT_SQE_V2 is not supported in A3");
     354            0 :                     return HCCL_E_NOT_SUPPORT;
     355              :                 }
     356            0 :                 case SqeType::MEMCPY_ASYNC_SQE_V2: {
     357            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] SqeType::MEMCPY_ASYNC_SQE_V2 is not supported in A3");
     358            0 :                     return HCCL_E_NOT_SUPPORT;
     359              :                 }
     360            0 :                 case SqeType::FLIP_PLACEHOLDER_SQE: {
     361            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] placeholder should not be cached, sqeType[%u] tmpSqeIdx[%u] cacheSqeIdx[%u]", sqeType, tmpSqeIdx, cacheSqeIdx);
     362            0 :                     return HCCL_E_INTERNAL;
     363              :                 }
     364            0 :                 case SqeType::CACHE_MEMCPY_PLACEHOLDER_SQE: {
     365              :                     // 注意: 只有alltoallv算子在cache时才会有此类SQE
     366            0 :                     CHK_PRT_RET(!isAlltoallv, HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] non-alltoallv op should not dispatch CACHE_MEMCPY_PLACEHOLDER_SQE"), HCCL_E_INTERNAL);
     367              : 
     368            0 :                     const rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<const rtStarsPlaceHolderSqe_t *>(sqePtr);
     369            0 :                     const struct rtCacheMemcpyTaskTag_t& unfoldCacheTaskTag = placeholderSqePtr->u.cache_memcpy_task_info;
     370              : 
     371            0 :                     CombineUint32ToUint64(sqeSrcAddr, unfoldCacheTaskTag.src_addr_high, unfoldCacheTaskTag.src_addr_low);
     372            0 :                     CHK_RET(CheckAndPrepareRefreshAddrInfo(sqeSrcAddr, srcRefreshAddrInfoArray[cacheSqeIdx], isAlltoallv, alltoallvMetadataPtr));
     373              : 
     374            0 :                     CombineUint32ToUint64(sqeDstAddr, unfoldCacheTaskTag.dst_addr_high, unfoldCacheTaskTag.dst_addr_low);
     375            0 :                     CHK_RET(CheckAndPrepareRefreshAddrInfo(sqeDstAddr, dstRefreshAddrInfoArray[cacheSqeIdx], isAlltoallv, alltoallvMetadataPtr));
     376              : 
     377            0 :                     break;
     378              :                 }
     379            0 :                 case SqeType::CACHE_NOTIFY_PLACEHOLDER_SQE:
     380              :                 case SqeType::CACHE_WRITE_VALUE_PLACEHOLDER_SQE:
     381              :                 case SqeType::CACHE_MEMCPY_RECORD_PLACEHOLDER_SQE: {
     382              :                     // Cache-notify placeholder: 无地址字段, 不需要更新src/dst RefreshAddrInfo
     383              :                     // Cache-write placeholder: 对应WriteValueRecord SQE, 地址为硬件映射的固定内存, 无需更新RefreshAddrInfo
     384              :                     // Cache-memcpy-record placeholder: 对应MemcpyRecord SQE, 地址为硬件映射的固定内存, 无需更新RefreshAddrInfo
     385            0 :                     break;
     386              :                 }
     387            0 :                 default: {
     388            0 :                     HCCL_WARNING("[OpUnfoldCacheEntry][MemcpySqeArray] sqeType %u is unsupported", sqeType);
     389            0 :                     return HCCL_E_NOT_SUPPORT;
     390              :                 }
     391              :             }
     392              : 
     393            0 :             sqePtr += HCCL_SQE_SIZE;
     394              :         }
     395              : 
     396            0 :         return HCCL_SUCCESS;
     397              :     }
     398              : 
     399            0 :     HcclResult OpUnfoldCacheEntry::CalcStreamSeqIdxes(Stream& mainStream, std::vector<Stream>& slaveStreams) {
     400            0 :         const size_t streamIdCount = streamIds_.size();
     401            0 :         HCCL_INFO("[OpUnfoldCacheEntry][CalcStreamSeqIdxes] calculate stream sequential indexes for %u stream ids", streamIdCount);
     402              : 
     403              :         // 对每个stream id找到对应的sequential stream index
     404            0 :         streamSeqIdxes_.resize(streamIdCount);
     405            0 :         for (size_t i = 0; i < streamIdCount; ++i) {
     406            0 :             const int32_t curStreamId = streamIds_[i];
     407              : 
     408            0 :             if (curStreamId == mainStream.GetHcclStreamInfo().actualStreamId) { // 主流
     409            0 :                 streamSeqIdxes_[i] = 0;
     410              :             } else { // 遍历从流
     411            0 :                 bool isFound = false;
     412            0 :                 for (size_t j = 0; j < slaveStreams.size(); ++j) {
     413            0 :                     if (curStreamId == slaveStreams[j].GetHcclStreamInfo().actualStreamId) { // 匹配某个从流
     414            0 :                         streamSeqIdxes_[i] = j + 1;
     415            0 :                         isFound = true;
     416            0 :                         break;
     417              :                     }
     418              :                 }
     419              : 
     420              :                 // No stream can match the stream id
     421            0 :                 if (!isFound) {
     422            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][CalcStreamSeqIdxes] cannot find any stream to match streamId %u", curStreamId);
     423            0 :                     return HCCL_E_INTERNAL;
     424              :                 }
     425              :             }
     426              :         }
     427              : 
     428            0 :         return HCCL_SUCCESS;
     429              :     }
     430              : 
     431            0 :     HcclResult OpUnfoldCacheEntry::UpdateRefreshAddrInfoForAlltoallv(const uint32_t curRank, AlltoallvMetadata& alltoallvMetadata) {
     432              :         // 校验入参
     433            0 :         CHK_RET(alltoallvMetadata.Check(true));
     434              : 
     435              :         // 获得rankSize
     436            0 :         const uint32_t rankSize = alltoallvMetadata.hcclInputMemRanges.size();
     437            0 :         CHK_PRT_RET(curRank >= rankSize,
     438              :             HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] curRank[%u] >= rankSize[%u]", curRank, rankSize),
     439              :             HCCL_E_INTERNAL);
     440              :         
     441            0 :         HCCL_RUN_INFO("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] curRank[%u] rankSize[%u]", curRank, rankSize);
     442              : 
     443              :         // 遍历每一段SQE数组
     444            0 :         const size_t sqeArrayCnt = dstRefreshAddrInfoArrays_.size();
     445            0 :         for (size_t arrayIdx = 0; arrayIdx < sqeArrayCnt; ++arrayIdx) {
     446              :             // 准备当前SQE数组的相关metadata
     447            0 :             const uint8_t *sqeArray = sqeArrays_[arrayIdx];
     448            0 :             CHK_PTR_NULL(sqeArray);
     449            0 :             const uint8_t *sqeTypeArray = sqeTypeArrays_[arrayIdx];
     450            0 :             CHK_PTR_NULL(sqeTypeArray);
     451            0 :             std::vector<RefreshAddrInfo>& srcRefreshAddrInfoArray = srcRefreshAddrInfoArrays_[arrayIdx];
     452            0 :             std::vector<RefreshAddrInfo>& dstRefreshAddrInfoArray = dstRefreshAddrInfoArrays_[arrayIdx];
     453              : 
     454              :             // 遍历数组中的每个SQE
     455            0 :             const size_t sqeCount = dstRefreshAddrInfoArray.size();
     456            0 :             HCCL_INFO("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] sqeArrayIdx[%u] sqeCount[%u]", arrayIdx, sqeCount);
     457            0 :             for (size_t sqeIdx = 0; sqeIdx < sqeCount; ++sqeIdx) {
     458              :                 // 准备当前SQE的相关metadata
     459            0 :                 const uint8_t *sqePtr = sqeArray + sqeIdx * HCCL_SQE_SIZE;
     460            0 :                 const uint8_t sqeType = sqeTypeArray[sqeIdx];
     461            0 :                 RefreshAddrInfo& srcRefreshAddrInfo = srcRefreshAddrInfoArray[sqeIdx];
     462            0 :                 RefreshAddrInfo& dstRefreshAddrInfo = dstRefreshAddrInfoArray[sqeIdx];
     463              : 
     464              :                 // 只有memcpy / cache-memcpy placeholder SQE可能需要更新RefreshAddrInfo
     465            0 :                 if (sqeType != SqeType::MEMCPY_ASYNC_SQE && sqeType != SqeType::CACHE_MEMCPY_PLACEHOLDER_SQE) {
     466            0 :                     continue;
     467              :                 }
     468              : 
     469              :                 // 跳过memcpy record SQE (src/dst memType为invalid)
     470            0 :                 const uint8_t srcMemType = srcRefreshAddrInfo.memType;
     471            0 :                 const uint8_t dstMemType = dstRefreshAddrInfo.memType;
     472            0 :                 if (sqeType == SqeType::MEMCPY_ASYNC_SQE && srcMemType == RefreshAddrInfo::INVALID_MEMTYPE &&
     473              :                     dstMemType == RefreshAddrInfo::INVALID_MEMTYPE) {
     474            0 :                     const rtStarsMemcpyAsyncSqe_t *memcpySqePtr = reinterpret_cast<const rtStarsMemcpyAsyncSqe_t *>(sqePtr);
     475            0 :                     HCCL_DEBUG("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] skip memcpy-record SQE: "\
     476              :                         "streamId[%u] taskId[%u] srcMemType[%u] dstMemType[%u]",
     477              :                             memcpySqePtr->header.rtStreamId, memcpySqePtr->header.taskId, srcMemType, dstMemType);
     478            0 :                     continue;
     479            0 :                 }
     480              : 
     481              :                 // (i) 更新invalid memType
     482              : 
     483              :                 // 只有cache-memcpy placeholder才有可能存在user input/output endAddr导致的src/dst invalid memType
     484            0 :                 if (sqeType == SqeType::CACHE_MEMCPY_PLACEHOLDER_SQE) {
     485              :                     // 校验src/dst memType
     486            0 :                     const rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<const rtStarsPlaceHolderSqe_t *>(sqePtr);
     487            0 :                     const uint16_t placeholderStreamId = placeholderSqePtr->header.rtStreamId;
     488            0 :                     const uint16_t placeholderTaskId = placeholderSqePtr->header.taskId;
     489            0 :                     if (srcMemType == RefreshAddrInfo::INVALID_MEMTYPE && dstMemType != RefreshAddrInfo::INVALID_MEMTYPE) {
     490              :                         // LocalCopy/PrepareIntraData: dst一定是local user output
     491              :                         // PrepareIntraData: 虽然dst RefreshAddrInfo的rank尚未更新 (see当前函数的第(ii)部分), memType一定是(local) hccl input
     492            0 :                         CHK_PRT_RET(dstMemType != RefreshAddrInfo::USER_OUTPUT_MEMTYPE && dstMemType != RefreshAddrInfo::HCCL_INPUT_MEMTYPE,
     493              :                             HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] cache-memcpy placeholder: "\
     494              :                                 "streamId[%u] taskId[%u] dstMemType[%u] != RefreshAddrInfo::HCCL_INPUT_MEMTYPE[%u]",
     495              :                                 placeholderStreamId, placeholderTaskId, dstMemType, RefreshAddrInfo::HCCL_INPUT_MEMTYPE),
     496              :                             HCCL_E_INTERNAL);
     497            0 :                     } else if (srcMemType != RefreshAddrInfo::INVALID_MEMTYPE && dstMemType == RefreshAddrInfo::INVALID_MEMTYPE) {
     498              :                         // LocalCopy/RemoteCopy: src一定是local user input
     499              :                         // RemoteCopy: src memType一定是(remote) hccl input
     500            0 :                         CHK_PRT_RET(srcMemType != RefreshAddrInfo::USER_INPUT_MEMTYPE && srcMemType != RefreshAddrInfo::HCCL_INPUT_MEMTYPE,
     501              :                             HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] cache-memcpy placeholder: "\
     502              :                                 "streamId[%u] taskId[%u] srcMemType[%u] != RefreshAddrInfo::HCCL_INPUT_MEMTYPE[%u]",
     503              :                                 placeholderStreamId, placeholderTaskId, srcMemType, RefreshAddrInfo::HCCL_INPUT_MEMTYPE),
     504              :                             HCCL_E_INTERNAL);
     505              :                     }
     506              : 
     507              :                     // 更新src/dst memType
     508            0 :                     const struct rtCacheMemcpyTaskTag_t& cacheMemcpyTaskInfo = placeholderSqePtr->u.cache_memcpy_task_info;
     509            0 :                     if (srcMemType == RefreshAddrInfo::INVALID_MEMTYPE) { // LocalCopy/PrepareIntraData
     510              :                         // srcAddr一定是local user input的end addr
     511            0 :                         uint64_t sqeSrcAddr = 0;
     512            0 :                         CombineUint32ToUint64(sqeSrcAddr, cacheMemcpyTaskInfo.src_addr_high, cacheMemcpyTaskInfo.src_addr_low);
     513            0 :                         uint64_t localUserInputEndAddr = 0;
     514            0 :                         CHK_RET(userInputMemRanges_[curRank].GetEndAddr(localUserInputEndAddr));
     515            0 :                         CHK_PRT_RET(sqeSrcAddr != localUserInputEndAddr,
     516              :                             HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] sqeSrcAddr[0x%016llx]"\
     517              :                                 "!= localUserInputEndAddr[0x%016llx]", sqeSrcAddr, localUserInputEndAddr),
     518              :                             HCCL_E_INTERNAL);
     519              :                         
     520              :                         // 更新src memType和rank, 即local user input
     521            0 :                         srcRefreshAddrInfo.memType = RefreshAddrInfo::USER_INPUT_MEMTYPE;
     522            0 :                         srcRefreshAddrInfo.rankId = curRank;
     523            0 :                         HCCL_INFO("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] update invalid src "\
     524              :                             "RefreshAddrInfo for cache-memcpy placeholder: streamId[%u] taskId[%u] memType[%u] rankId[%u]",
     525              :                             placeholderStreamId, placeholderTaskId, srcRefreshAddrInfo.memType, srcRefreshAddrInfo.rankId);
     526              :                     }
     527            0 :                     if (dstMemType == RefreshAddrInfo::INVALID_MEMTYPE) { // LocalCopy/RemoteCopy
     528              :                         // dstAddr一定是local user output的end addr
     529            0 :                         uint64_t sqeDstAddr = 0;
     530            0 :                         CombineUint32ToUint64(sqeDstAddr, cacheMemcpyTaskInfo.dst_addr_high, cacheMemcpyTaskInfo.dst_addr_low);
     531            0 :                         uint64_t localUserOutputEndAddr = 0;
     532            0 :                         CHK_RET(userOutputMemRanges_[curRank].GetEndAddr(localUserOutputEndAddr));
     533            0 :                         CHK_PRT_RET(sqeDstAddr != localUserOutputEndAddr,
     534              :                             HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] sqeDstAddr[0x%016llx]"\
     535              :                                 "!= localUserOutputEndAddr[0x%016llx]", sqeDstAddr, localUserOutputEndAddr),
     536              :                             HCCL_E_INTERNAL);
     537              :                         
     538              :                         // 更新dst memType和rank, 即local user output
     539            0 :                         dstRefreshAddrInfo.memType = RefreshAddrInfo::USER_OUTPUT_MEMTYPE;
     540            0 :                         dstRefreshAddrInfo.rankId = curRank;
     541            0 :                         HCCL_INFO("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] update invalid dst "\
     542              :                             "RefreshAddrInfo for cache-memcpy placeholder: streamId[%u] taskId[%u] memType[%u] rankId[%u]",
     543              :                             placeholderStreamId, placeholderTaskId, dstRefreshAddrInfo.memType, dstRefreshAddrInfo.rankId);
     544              :                     }
     545              :                 }
     546              : 
     547              :                 // (ii) 更新local dst rank (如果dst memType是local hccl input)
     548              : 
     549              :                 // PrepareIntraData: local user input -> local hccl input
     550              :                 // 注意: invalid memType已经在当前函数的第(i)部分被解决
     551            0 :                 if (srcRefreshAddrInfo.memType == RefreshAddrInfo::USER_INPUT_MEMTYPE &&
     552            0 :                     dstRefreshAddrInfo.memType == RefreshAddrInfo::HCCL_INPUT_MEMTYPE) {
     553              :                     // srcRank一定是current rank
     554            0 :                     const uint32_t srcRank = srcRefreshAddrInfo.rankId;
     555            0 :                     CHK_PRT_RET(srcRank != curRank,
     556              :                         HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] srcRank[%u] != curRank[%u], rankSize[%u]",
     557              :                             srcRank, curRank, rankSize),
     558              :                         HCCL_E_INTERNAL);
     559              : 
     560              :                     // 注意: 对于alltoallv算子, 原始dstRefreshAddrInfo.rankId在MemcpySqeArray时被刷新
     561              :                     // 因为alltoallvMetadata中的hcclOffsetDstRanksIdxMap要等第一次算子Orchestrate结束后才会被设置
     562              :                     // 而根据范围dstAddr落在local hccl input范围内, 因此当时刷新的rankId一定为current rank
     563            0 :                     CHK_PRT_RET(dstRefreshAddrInfo.rankId != curRank,
     564              :                         HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] original dstRank[%u] != curRank[%u]",
     565              :                             dstRefreshAddrInfo.rankId, curRank),
     566              :                         HCCL_E_INTERNAL);
     567              : 
     568              :                     // 根据SQE类型获得dst addr
     569            0 :                     uint64_t sqeDstAddr = 0;
     570            0 :                     if (sqeType == SqeType::MEMCPY_ASYNC_SQE) {
     571            0 :                         const rtStarsMemcpyAsyncSqe_t *memcpyAsyncSqePtr = reinterpret_cast<const rtStarsMemcpyAsyncSqe_t *>(sqePtr);
     572            0 :                         CombineUint32ToUint64(sqeDstAddr, memcpyAsyncSqePtr->dst_addr_high, memcpyAsyncSqePtr->dst_addr_low);
     573              :                     } else { // cache-memcpy placeholder
     574            0 :                         const rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<const rtStarsPlaceHolderSqe_t *>(sqePtr);
     575            0 :                         const struct rtCacheMemcpyTaskTag_t& cacheMemcpyTaskInfo = placeholderSqePtr->u.cache_memcpy_task_info;
     576            0 :                         CombineUint32ToUint64(sqeDstAddr, cacheMemcpyTaskInfo.dst_addr_high, cacheMemcpyTaskInfo.dst_addr_low);
     577              :                     }
     578              : 
     579              :                     // 本函数只会在第一次cache miss后处理时调用, dst addr一定落在local hccl input范围内
     580            0 :                     bool isInRange = false;
     581            0 :                     const OpUnfoldMemRange& localHcclInputMemRange = alltoallvMetadata.hcclInputMemRanges[curRank];
     582            0 :                     CHK_RET(localHcclInputMemRange.InRange(sqeDstAddr, isInRange));
     583            0 :                     if (UNLIKELY(!isInRange)) {
     584            0 :                         uint64_t localHcclInputEndAddr = 0;
     585            0 :                         CHK_RET(localHcclInputMemRange.GetEndAddr(localHcclInputEndAddr));
     586            0 :                         HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] sqeDstAddr[0x%016llx] not "\
     587              :                             "in localHcclInputMemRange[0x%016llx -- 0x%016llx]",
     588              :                             sqeDstAddr, localHcclInputMemRange.baseAddr, localHcclInputEndAddr);
     589            0 :                         return HCCL_E_INTERNAL;
     590              :                     }
     591              : 
     592              :                     // 参考alltoallv_direct_fullmesh.cc中的UpdateCurrRankSendInfo
     593              : 
     594              :                     // 计算local hccl input buffer下的offset
     595              :                     // 注意: 前面isInRange已经校验过必定为true, 即sqeDstAddr一定 >= localHcclInputBaseAddr
     596            0 :                     uint64_t localHcclInputBaseAddr = localHcclInputMemRange.baseAddr;
     597            0 :                     uint64_t hcclOffset = sqeDstAddr - localHcclInputBaseAddr;
     598              : 
     599              :                     // 根据hcclOffset-dstRanksInfo mapping获得对应的dst rank
     600            0 :                     std::unordered_map<uint64_t, RanksIdx>::iterator mapIter = alltoallvMetadata.hcclOffsetDstRanksIdxMap.find(hcclOffset);
     601            0 :                     if (mapIter == alltoallvMetadata.hcclOffsetDstRanksIdxMap.end()) {
     602            0 :                         HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] hcclOffset[%u] is not found", hcclOffset);
     603            0 :                         return HCCL_E_INTERNAL;
     604              :                     }
     605            0 :                     const std::vector<uint32_t>& dstRanks = mapIter->second.first;
     606            0 :                     uint32_t& curIdx = mapIter->second.second;
     607            0 :                     const uint32_t dstRank = dstRanks[curIdx % dstRanks.size()];
     608            0 :                     HCCL_INFO("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] hcclOffset[%llu] dstRanks.size[%u] "\
     609              :                         "curIdx[%u] dstRank[%u]", hcclOffset, dstRanks.size(), curIdx, dstRank);
     610              : 
     611              :                     // 新的dstRank一定是某个remoteRank, 即不等于curRank
     612            0 :                     CHK_PRT_RET(dstRank == curRank,
     613              :                         HCCL_ERROR("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv] dstRank[%u] = curRank[%u]",
     614              :                             dstRank, curRank),
     615              :                         HCCL_E_INTERNAL);
     616              : 
     617              :                     // Prepare for next-round dstRank (if any)
     618            0 :                     curIdx = (curIdx + 1) % dstRanks.size();
     619              : 
     620              :                     // 更新dst rank
     621            0 :                     dstRefreshAddrInfo.rankId = dstRank;
     622            0 :                     HCCL_INFO("[OpUnfoldCacheEntry][UpdateRefreshAddrInfoForAlltoallv]"\
     623              :                         "dstRefreshAddrInfoArrays_[%u][%u].rankId[%u -> %u]",
     624              :                         arrayIdx, sqeIdx, curRank, dstRefreshAddrInfo.rankId);
     625              :                 } // PrepareIntraData in alltoallv
     626              : 
     627              :                 // 刷新memcpy / cache-memcpy placeholder SQE后, 校验src/dst地址字段对应的memType
     628            0 :                 CHK_RET(CheckMemTypeForAlltoallv(sqePtr, sqeType, srcRefreshAddrInfo, dstRefreshAddrInfo));
     629              :             } // sqeIdx
     630              :         } // arrayIdx
     631              : 
     632            0 :         return HCCL_SUCCESS;
     633              :     }
     634              : 
     635            0 :     HcclResult OpUnfoldCacheEntry::UpdateAndGetSqeArray(const size_t arrayIdx, const std::vector<OpUnfoldMemRange>& curUserInputMemRanges,
     636              :         const std::vector<OpUnfoldMemRange>& curUserOutputMemRanges, Stream& mainStream, std::vector<Stream> &slaveStreams,
     637              :         const uint32_t opRingBufferIdx, size_t& sqeCount, uint8_t **sqeArrayPtr, uint8_t **sqeTypeArrayPtr,
     638              :         AicpuDfxInfo **sqeDfxInfoArrayPtr, Stream **streamPtrPtr, std::vector<FlipInfo>& flipInfos,
     639              :         const bool profL1Enable, std::vector<uint64_t>& profTimestamps, const bool isAlltoallv,
     640              :         const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo) {
     641            0 :         HCCL_INFO("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] update and get SQEs from %uth SQE array; isAlltoallv[%u]", arrayIdx, isAlltoallv);
     642              : 
     643              :         // 检验入参
     644            0 :         CHK_PRT_RET(arrayIdx >= sqeArrays_.size(), HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] arrayIdx %u is out of range [0, %u)", arrayIdx, sqeArrays_.size()), HCCL_E_INTERNAL);
     645            0 :         CHK_PRT_RET(arrayIdx >= streamSeqIdxes_.size(), HCCL_ERROR("[OpUnfoldCacheEntry][MemcpySqeArray] arrayIdx %u is out of range [0, %u)", arrayIdx, streamSeqIdxes_.size()), HCCL_E_INTERNAL);
     646              :         // 检查指针, arrayPtr不应该是null, 但*arrayPtr应该是null
     647            0 :         CHK_PTRPTR_NULL(sqeArrayPtr);
     648            0 :         CHK_PTRPTR_NULL(sqeTypeArrayPtr);
     649            0 :         CHK_PTRPTR_NULL(sqeDfxInfoArrayPtr);
     650            0 :         CHK_PTRPTR_NULL(streamPtrPtr);
     651              :         // Double-check alltoallv相关入参
     652            0 :         if (isAlltoallv) {
     653            0 :             CHK_RET(alltoallvMetadata.Check(true));
     654            0 :             CHK_RET(alltoallvSendRecvInfo.Check());
     655              :         }
     656              : 
     657              :         // 设置入参
     658            0 :         sqeCount = srcRefreshAddrInfoArrays_[arrayIdx].size();
     659            0 :         *sqeArrayPtr = sqeArrays_[arrayIdx];
     660            0 :         *sqeTypeArrayPtr = sqeTypeArrays_[arrayIdx];
     661            0 :         *sqeDfxInfoArrayPtr = sqeDfxInfoArrays_[arrayIdx];
     662            0 :         flipInfos.clear();
     663            0 :         if (profL1Enable) {
     664            0 :             profTimestamps.clear();
     665            0 :             profTimestamps.reserve(sqeCount); // 需要额外flip placeholder是小概率事件, 所以只reserve cached SQE个数 (即非flip placeholder类SQE)
     666              :         }
     667              : 
     668              :         // 设置入参的stream pointer
     669            0 :         const uint32_t streamSeqIdx = streamSeqIdxes_[arrayIdx];
     670            0 :         if (streamSeqIdx == 0) {
     671            0 :             *streamPtrPtr = &mainStream;
     672              :         } else {
     673            0 :             CHK_PRT_RET(streamSeqIdx > slaveStreams.size(), HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] invalid streamSeqIdx %u > slaveStreams.size() %u", streamSeqIdx, slaveStreams.size()), HCCL_E_MEMORY);
     674            0 :             *streamPtrPtr = &(slaveStreams[streamSeqIdx - 1]); // 0 < streamSeqIdx <= slaveStreams.size())
     675              :         }
     676              : 
     677              :         // 从stream中获取SQE刷新需要的当前task id
     678            0 :         HcclSqeContext *sqeContext = (*streamPtrPtr)->GetSqeContextPtr();
     679            0 :         CHK_PTR_NULL(sqeContext);
     680            0 :         SqeRingBuffer *sqeContextBuffer = &(sqeContext->buffer);
     681            0 :         CHK_PTR_NULL(sqeContextBuffer);
     682            0 :         uint16_t& curTaskId = sqeContextBuffer->tailSqeTaskId;
     683            0 :         uint16_t& curFlipNum = sqeContextBuffer->filpNum;
     684            0 :         HCCL_INFO("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] curTaskId[%u] curFlipNum[%u] from streamId %u for %u cached SQEs",
     685              :             curTaskId, curFlipNum, (*streamPtrPtr)->GetHcclStreamInfo().actualStreamId, sqeCount);
     686              : 
     687              :         // 执行SQE刷新
     688              :         // 注意: curUserInputMemRanges/curUserOutputMemRanges为当前算子执行时各rank输入输出的user memory range, userInputMemRanges_/userOutputMemRanges_为算子缓存时各rank输入输出的user memory range
     689            0 :         const std::vector<RefreshAddrInfo>& srcRefreshAddrInfoArray = srcRefreshAddrInfoArrays_[arrayIdx];
     690            0 :         const std::vector<RefreshAddrInfo>& dstRefreshAddrInfoArray = dstRefreshAddrInfoArrays_[arrayIdx];
     691            0 :         uint64_t sqeSrcAddr = 0;
     692            0 :         uint64_t sqeDstAddr = 0;
     693            0 :         uint8_t *sqePtr = (*sqeArrayPtr);
     694            0 :         for (size_t sqeIdx = 0 ; sqeIdx < sqeCount; ++sqeIdx){
     695              :             // 获取当前SQE的信息
     696            0 :             uint8_t& sqeType = (*sqeTypeArrayPtr)[sqeIdx];
     697            0 :             const RefreshAddrInfo& srcRefreshAddrInfo = srcRefreshAddrInfoArray[sqeIdx];
     698            0 :             const RefreshAddrInfo& dstRefreshAddrInfo = dstRefreshAddrInfoArray[sqeIdx];
     699            0 :             HCCL_INFO("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] update %uth cached SQE with sqeType[%u] srcRefreshAddrInfo[rankid[%u], memType[%u]] dstRefreshAddrInfo[rankid[%u], memType[%u]] curTaskId[%u]",
     700              :                 sqeIdx, sqeType, srcRefreshAddrInfo.rankId, srcRefreshAddrInfo.memType, dstRefreshAddrInfo.rankId, dstRefreshAddrInfo.memType, curTaskId);
     701              : 
     702              :             // 根据SQE type进行对应刷新 (task id始终要刷新; addr相关字段有条件刷新)
     703            0 :             switch(sqeType) {
     704            0 :                 case SqeType::NOTIFY_SQE: {
     705            0 :                     rtStarsNotifySqeV1_t *notifySqePtr = reinterpret_cast<rtStarsNotifySqeV1_t *>(sqePtr);
     706            0 :                     if (isAlltoallv && notifySqePtr->header.type == RT_STARS_SQE_TYPE_NOTIFY_WAIT) {
     707              :                         // 针对alltoallv算子, 动态刷新Notify SQE / 将Notify SQE生成为CacheNotifyPlaceholder SQE
     708              :                         // 注意: NotifyRecord SQE不需要针对alltoallv类算子做特殊刷新
     709            0 :                         CHK_RET(UpdateSyncSqeForAlltoallv(sqePtr, &sqeType, curTaskId, srcRefreshAddrInfo, dstRefreshAddrInfo, alltoallvMetadata, alltoallvSendRecvInfo));
     710            0 :                     } else {
     711            0 :                         notifySqePtr->header.taskId = curTaskId;
     712              :                     }
     713            0 :                     break;
     714              :                 }
     715            0 :                 case SqeType::WRITE_VALUE_SQE:
     716              :                 case SqeType::RDMA_DB_SEND_SQE: {
     717            0 :                     if (isAlltoallv) { // 针对alltoallv算子, 动态刷新WriteValue SQE / 将WriteValue SQE生成为CacheWriteValuePlaceholder SQE
     718            0 :                         CHK_RET(UpdateSyncSqeForAlltoallv(sqePtr, &sqeType, curTaskId, srcRefreshAddrInfo, dstRefreshAddrInfo, alltoallvMetadata, alltoallvSendRecvInfo));
     719              :                     } else {
     720            0 :                         rtStarsWriteValueSqe_t *writeValueSqePtr = reinterpret_cast<rtStarsWriteValueSqe_t *>(sqePtr);
     721            0 :                         writeValueSqePtr->header.taskId = curTaskId;
     722              : 
     723            0 :                         if (dstRefreshAddrInfo.memType != RefreshAddrInfo::INVALID_MEMTYPE) { // 需要刷新地址
     724            0 :                             CombineUint32ToUint64(sqeDstAddr, writeValueSqePtr->write_addr_high, writeValueSqePtr->write_addr_low);
     725            0 :                             if (dstRefreshAddrInfo.memType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE) { // user output
     726            0 :                                 CHK_RET(RefreshSqeAddr(sqeDstAddr, dstRefreshAddrInfo.rankId, userOutputMemRanges_, curUserOutputMemRanges, false, 0));
     727            0 :                             } else if (dstRefreshAddrInfo.memType == RefreshAddrInfo::USER_INPUT_MEMTYPE) { // user input
     728            0 :                                 CHK_RET(RefreshSqeAddr(sqeDstAddr, dstRefreshAddrInfo.rankId, userInputMemRanges_, curUserInputMemRanges, false, 0));
     729              :                             } else { // hccl input (alltoallv算子不需要对WRITE_VALUE_SQE刷新hccl地址)
     730            0 :                                 HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] isAlltoallv[%u] sqeType[%u]; memType should be user input/output", isAlltoallv, sqeType);
     731            0 :                                 HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] dstRefreshAddrInfo: rankId[%u] memType[%u]", dstRefreshAddrInfo.rankId, dstRefreshAddrInfo.memType);
     732            0 :                                 return HCCL_E_INTERNAL;
     733              :                             }
     734              : 
     735              :                             // Bit-field member不能直接传引用
     736            0 :                             uint32_t tmpHighAddr = 0;
     737            0 :                             SplitUint64ToUint32(sqeDstAddr, tmpHighAddr, writeValueSqePtr->write_addr_low);
     738            0 :                             writeValueSqePtr->write_addr_high = tmpHighAddr;
     739              :                         }
     740              :                     }
     741            0 :                     break;
     742              :                 }
     743            0 :                 case SqeType::EVENT_SQE: {
     744            0 :                     rtStarsEventSqe_t *eventSqePtr = reinterpret_cast<rtStarsEventSqe_t *>(sqePtr);
     745            0 :                     eventSqePtr->header.taskId = curTaskId;
     746            0 :                     break;
     747              :                 }
     748            0 :                 case SqeType::MEMCPY_ASYNC_SQE: {
     749            0 :                     if (isAlltoallv) { // 针对alltoallv算子
     750            0 :                         if (srcRefreshAddrInfo.memType == RefreshAddrInfo::INVALID_MEMTYPE &&
     751            0 :                             dstRefreshAddrInfo.memType == RefreshAddrInfo::INVALID_MEMTYPE) { // MemcpyRecord SQE
     752              :                             // 动态刷新MemcpyRecord SQE / 将MemcpyRecord SQE生成为CacheMemcpyRecordPlaceholder SQE
     753            0 :                             CHK_RET(UpdateSyncSqeForAlltoallv(sqePtr, &sqeType, curTaskId, srcRefreshAddrInfo, dstRefreshAddrInfo, alltoallvMetadata, alltoallvSendRecvInfo));
     754            0 :                         } else { // Memcpy SQE
     755              :                             // 动态刷新Memcpy SQE / 将Memcpy SQE生成为CacheMemcpyPlaceholder SQE
     756            0 :                             CHK_RET(UpdateTransferSqeForAlltoallv(sqePtr, &sqeType, curTaskId, srcRefreshAddrInfo, dstRefreshAddrInfo, curUserInputMemRanges, curUserOutputMemRanges, alltoallvMetadata, alltoallvSendRecvInfo));
     757              :                         }
     758              :                     } else { // 非V类算子, 动态刷新Memcpy SQE
     759            0 :                         rtStarsMemcpyAsyncSqe_t *memcpyAsyncSqePtr = reinterpret_cast<rtStarsMemcpyAsyncSqe_t *>(sqePtr);
     760            0 :                         memcpyAsyncSqePtr->header.taskId = curTaskId;
     761              : 
     762            0 :                         if (srcRefreshAddrInfo.memType != RefreshAddrInfo::INVALID_MEMTYPE) { // 需要刷新src addr
     763            0 :                             CombineUint32ToUint64(sqeSrcAddr, memcpyAsyncSqePtr->src_addr_high, memcpyAsyncSqePtr->src_addr_low);
     764            0 :                             if (srcRefreshAddrInfo.memType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE) { // user output
     765            0 :                                 CHK_RET(RefreshSqeAddr(sqeSrcAddr, srcRefreshAddrInfo.rankId, userOutputMemRanges_, curUserOutputMemRanges, false, 0));
     766            0 :                             } else if (srcRefreshAddrInfo.memType == RefreshAddrInfo::USER_INPUT_MEMTYPE) { // user input
     767            0 :                                 CHK_RET(RefreshSqeAddr(sqeSrcAddr, srcRefreshAddrInfo.rankId, userInputMemRanges_, curUserInputMemRanges, false, 0));
     768              :                             } else { // hccl input (非V类算子不需要对MEMCPY_ASYNC_SQE刷新hccl地址)
     769            0 :                                 HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] isAlltoallv[%u] sqeType[%u]; memType should be user input/output", isAlltoallv, sqeType);
     770            0 :                                 HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] srcRefreshAddrInfo: rankId[%u] memType[%u]", srcRefreshAddrInfo.rankId, srcRefreshAddrInfo.memType);
     771            0 :                                 return HCCL_E_INTERNAL;
     772              :                             }
     773            0 :                             SplitUint64ToUint32(sqeSrcAddr, memcpyAsyncSqePtr->src_addr_high, memcpyAsyncSqePtr->src_addr_low);
     774              :                         }
     775              : 
     776            0 :                         if (dstRefreshAddrInfo.memType != RefreshAddrInfo::INVALID_MEMTYPE) { // 需要刷新地址
     777            0 :                             CombineUint32ToUint64(sqeDstAddr, memcpyAsyncSqePtr->dst_addr_high, memcpyAsyncSqePtr->dst_addr_low);
     778            0 :                             if (dstRefreshAddrInfo.memType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE) { // user output
     779            0 :                                 CHK_RET(RefreshSqeAddr(sqeDstAddr, dstRefreshAddrInfo.rankId, userOutputMemRanges_, curUserOutputMemRanges, false, 0));
     780            0 :                             } else if (dstRefreshAddrInfo.memType == RefreshAddrInfo::USER_INPUT_MEMTYPE) { // user input
     781            0 :                                 CHK_RET(RefreshSqeAddr(sqeDstAddr, dstRefreshAddrInfo.rankId, userInputMemRanges_, curUserInputMemRanges, false, 0));
     782              :                             } else { // hccl input (非V类算子不需要对MEMCPY_ASYNC_SQE刷新hccl地址)
     783            0 :                                 HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] isAlltoallv[%u] sqeType[%u]; memType should be user input/output", isAlltoallv, sqeType);
     784            0 :                                 HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] dstRefreshAddrInfo: rankId[%u] memType[%u]", dstRefreshAddrInfo.rankId, dstRefreshAddrInfo.memType);
     785            0 :                                 return HCCL_E_INTERNAL;
     786              :                             }
     787            0 :                             SplitUint64ToUint32(sqeDstAddr, memcpyAsyncSqePtr->dst_addr_high, memcpyAsyncSqePtr->dst_addr_low);
     788              :                         }
     789              :                     }
     790              : 
     791            0 :                     break;
     792              :                 }
     793            0 :                 case SqeType::CCORE_WAIT_START_SQE: {
     794            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] SqeType::CCORE_WAIT_START_SQE is not supported in A3");
     795            0 :                     return HCCL_E_NOT_SUPPORT;
     796              :                 }
     797            0 :                 case SqeType::CCORE_WRITE_VALUE_SQE: {
     798            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] SqeType::CCORE_WRITE_VALUE_SQE is not supported in A3");
     799            0 :                     return HCCL_E_NOT_SUPPORT;
     800              :                 }
     801            0 :                 case SqeType::NOTIFY_SQE_V2: {
     802            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] SqeType::NOTIFY_SQE_V2 is not supported in A3");
     803            0 :                     return HCCL_E_NOT_SUPPORT;
     804              :                 }
     805            0 :                 case SqeType::WRITE_VALUE_SQE_V2: {
     806            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] SqeType::WRITE_VALUE_SQE_V2 is not supported in A3");
     807            0 :                     return HCCL_E_NOT_SUPPORT;
     808              :                 }
     809            0 :                 case SqeType::EVENT_SQE_V2: {
     810            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] SqeType::EVENT_SQE_V2 is not supported in A3");
     811            0 :                     return HCCL_E_NOT_SUPPORT;
     812              :                 }
     813            0 :                 case SqeType::MEMCPY_ASYNC_SQE_V2: {
     814            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] SqeType::MEMCPY_ASYNC_SQE_V2 is not supported in A3");
     815            0 :                     return HCCL_E_NOT_SUPPORT;
     816              :                 }
     817            0 :                 case SqeType::FLIP_PLACEHOLDER_SQE: {
     818            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] placeholder should not be cached, sqeType[%u] sqeIdx[%u]", sqeType, sqeIdx);
     819            0 :                     return HCCL_E_INTERNAL;
     820              :                 }
     821            0 :                 case SqeType::CACHE_MEMCPY_PLACEHOLDER_SQE: {
     822              :                     // 非V类算子, 不应该出现CacheMemcpyPlaceholder SQE
     823            0 :                     CHK_PRT_RET(!isAlltoallv,
     824              :                         HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] cache-memcpy placeholder"
     825              :                             "should be not cached for non-alltoallv op, sqeType[%u] sqeIdx[%u]", sqeType, sqeIdx),
     826              :                         HCCL_E_INTERNAL);
     827              : 
     828              :                     // 针对alltoallv类算子, 动态刷新CacheMemcpyPlaceholder SQE / 将CacheMemcpyPlaceholder SQE生成为Memcpy SQE
     829            0 :                     CHK_RET(UpdateTransferSqeForAlltoallv(sqePtr, &sqeType, curTaskId, srcRefreshAddrInfo, dstRefreshAddrInfo, curUserInputMemRanges, curUserOutputMemRanges, alltoallvMetadata, alltoallvSendRecvInfo));
     830              : 
     831            0 :                     break;
     832              :                 }
     833            0 :                 case SqeType::CACHE_NOTIFY_PLACEHOLDER_SQE:
     834              :                 case SqeType::CACHE_WRITE_VALUE_PLACEHOLDER_SQE:
     835              :                 case SqeType::CACHE_MEMCPY_RECORD_PLACEHOLDER_SQE: {
     836              :                     // 非V类算子, 不应该出现CacheNotify/Write/MemcpyRecordPlaceholder SQE
     837            0 :                     CHK_PRT_RET(!isAlltoallv,
     838              :                         HCCL_ERROR("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] cache-notify/write/memcpy-record placeholder"
     839              :                             "should be not cached for non-alltoallv op, sqeType[%u] sqeIdx[%u]", sqeType, sqeIdx),
     840              :                         HCCL_E_INTERNAL);
     841              :                     
     842              :                     // 针对alltoallv类算子, 动态刷新CacheNotify/WritePlaceholder SQE / 将CacheNotify/WritePlaceholder SQE生成为Notify/Write SQE
     843            0 :                     CHK_RET(UpdateSyncSqeForAlltoallv(sqePtr, &sqeType, curTaskId, srcRefreshAddrInfo, dstRefreshAddrInfo, alltoallvMetadata, alltoallvSendRecvInfo));
     844              : 
     845            0 :                     break;
     846              :                 }
     847            0 :                 default: {
     848            0 :                     HCCL_WARNING("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] sqeType %u is unsupported (sqeIdx[%u] curTaskId[%u])",
     849              :                         sqeType, sqeIdx, curTaskId);
     850            0 :                     return HCCL_E_NOT_SUPPORT;
     851              :                 }
     852              :             }
     853              : 
     854              :             // 记录SQE刷新时间用于profiling
     855            0 :             if (profL1Enable) {
     856            0 :                 const uint64_t curTime = ProfGetCurCpuTimestamp();
     857            0 :                 profTimestamps.push_back(curTime);
     858              :             }
     859              : 
     860              :             // 刷新taskId和flipNum
     861            0 :             if (curTaskId == UINT16_MAX) { // 更新flipNum和taskId
     862              :                 // 参考stream.cc中的GetNextSqeBufferAddr
     863            0 :                 curFlipNum += 1;
     864            0 :                 curTaskId = 0;
     865            0 :             } else if (curTaskId == 0 && curFlipNum != 0) { // 更新flipInfos和taskId
     866              :                 // 参考dispatcher_aicpu.cc中的GetStreamSqeBufferAddr
     867            0 :                 flipInfos.push_back(FlipInfo(sqeIdx, curFlipNum));
     868              : 
     869              :                 // 为placeholder SQE预留task id = 0
     870            0 :                 curTaskId = 1;
     871              : 
     872              :                 // Flip placeholder SQE在外侧dispatcher aicpu中生成, 这里记录当前时间作为flip placeholder SQE的生成时间
     873            0 :                 if (profL1Enable) {
     874            0 :                     const uint64_t curTime = ProfGetCurCpuTimestamp();
     875            0 :                     profTimestamps.push_back(curTime);
     876              :                 }
     877            0 :             } else { // 只更新taskid
     878            0 :                 curTaskId += 1;
     879              :             }
     880              : 
     881            0 :             sqePtr += HCCL_SQE_SIZE;
     882              :         }
     883              : 
     884              :         // 更新每个SQE的DfxInfo中的opRingBufferIdx
     885            0 :         HCCL_INFO("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] update opRingBufferIndx in DfxInfoArray as %u", opRingBufferIdx);
     886            0 :         for (size_t sqeIdx = 0; sqeIdx < sqeCount; ++sqeIdx) {
     887            0 :             (*sqeDfxInfoArrayPtr)[sqeIdx].opRingBufferIdx = opRingBufferIdx;
     888              :         }
     889              : 
     890            0 :         HCCL_INFO("[OpUnfoldCacheEntry][UpdateAndGetSqeArray] update and get %uth SQE array with %u SQEs, streamId[%u] and %u flipInfos",
     891              :             arrayIdx, sqeCount, (*streamPtrPtr)->GetHcclStreamInfo().actualStreamId, flipInfos.size());
     892              : 
     893            0 :         return HCCL_SUCCESS;
     894              :     }
     895              : 
     896            0 :     HcclResult OpUnfoldCacheEntry::SetInputOutputMemRanges(const std::vector<OpUnfoldMemRange>& curUserInputMemRanges, const std::vector<OpUnfoldMemRange>& curUserOutputMemRanges) {
     897            0 :         CHK_PRT_RET(userInputMemRanges_.size() != curUserInputMemRanges.size(), HCCL_ERROR("[OpUnfoldCacheEntry][SetInputOutputMemRanges] original rankSize %u != new rankSize %u", userInputMemRanges_.size(), curUserInputMemRanges.size()), HCCL_E_INTERNAL);
     898              : 
     899            0 :         userInputMemRanges_ = curUserInputMemRanges;
     900            0 :         userOutputMemRanges_ = curUserOutputMemRanges;
     901              : 
     902            0 :         return HCCL_SUCCESS;
     903              :     }
     904              : 
     905            0 :     HcclResult OpUnfoldCacheEntry::CheckAndPrepareRefreshAddrInfo(const uint64_t sqeAddr, RefreshAddrInfo& refreshAddrInfo, const bool isAlltoallv, const AlltoallvMetadata* alltoallvMetadataPtr) {
     906              :         // 遍历per-rank user input memory range
     907            0 :         for (size_t rankId = 0; rankId < userInputMemRanges_.size(); ++rankId) {
     908            0 :             bool isInRange = false;
     909            0 :             CHK_RET(userInputMemRanges_[rankId].InRange(sqeAddr, isInRange));
     910            0 :             if (isInRange) {
     911            0 :                 refreshAddrInfo.rankId = rankId;
     912            0 :                 refreshAddrInfo.memType = RefreshAddrInfo::USER_INPUT_MEMTYPE;
     913            0 :                 return HCCL_SUCCESS; // 确实是某rank下的user input mem, 则无需继续搜索output mem
     914              :             }
     915              :         }
     916              : 
     917              :         // 遍历per-rank user input memory range
     918            0 :         for (size_t rankId = 0; rankId < userOutputMemRanges_.size(); ++rankId) {
     919            0 :             bool isInRange = false;
     920            0 :             CHK_RET(userOutputMemRanges_[rankId].InRange(sqeAddr, isInRange));
     921            0 :             if (isInRange) {
     922            0 :                 refreshAddrInfo.rankId = rankId;
     923            0 :                 refreshAddrInfo.memType = RefreshAddrInfo::USER_OUTPUT_MEMTYPE;
     924            0 :                 return HCCL_SUCCESS;
     925              :             }
     926              :         }
     927              : 
     928              :         // 针对alltoallv算子, 遍历HCCL input buffer, 确定rank id
     929            0 :         if (isAlltoallv) {
     930            0 :             CHK_PTR_NULL(alltoallvMetadataPtr);
     931            0 :             CHK_RET(alltoallvMetadataPtr->Check(false));
     932              : 
     933            0 :             const std::vector<OpUnfoldMemRange>& hcclInputMemRanges = alltoallvMetadataPtr->hcclInputMemRanges;
     934            0 :             for (size_t rankId = 0; rankId < hcclInputMemRanges.size(); ++rankId) {
     935            0 :                 bool isInRange = false;
     936            0 :                 CHK_RET(hcclInputMemRanges[rankId].InRange(sqeAddr, isInRange));
     937            0 :                 if (isInRange) {
     938            0 :                     refreshAddrInfo.rankId = rankId;
     939            0 :                     refreshAddrInfo.memType = RefreshAddrInfo::HCCL_INPUT_MEMTYPE;
     940            0 :                     return HCCL_SUCCESS;
     941              :                 }
     942              :             }
     943              :         }
     944              : 
     945            0 :         return HCCL_SUCCESS;
     946              :     }
     947              : 
     948            0 :     HcclResult OpUnfoldCacheEntry::CheckMemTypeForAlltoallv(const uint8_t *sqePtr, const uint8_t sqeType,
     949              :         const RefreshAddrInfo& srcRefreshAddrInfo, const RefreshAddrInfo& dstRefreshAddrInfo) const {
     950              :         // 对于所有算子, SQE第一次admit时, 在MemcpySqeArray中, 遍历memory ranges获取每个地址字段对应的rankId和memType
     951              :         // 对于alltoallv算子, cache miss后处理时, 在UpdateRefreshAddrInfoForAlltoallv中, 进一步更新memType和dstRank
     952              : 
     953              :         // 如果src在user memory内, 说明是LocalCopy或者PrepareIntraData, 一定是local user input -> local user output / local hccl input
     954              :         // 如果dst在user memory内, 说明是LocalCopy或者RemoteCopy, 一定是local user input / remote hccl input -> local user output
     955              : 
     956              :         // 获取task id和stream id
     957            0 :         uint16_t taskId = 0;
     958            0 :         uint16_t streamId = 0;
     959            0 :         if (sqeType == SqeType::MEMCPY_ASYNC_SQE) {
     960            0 :             const rtStarsMemcpyAsyncSqe_t *memcpyAsyncSqePtr = reinterpret_cast<const rtStarsMemcpyAsyncSqe_t *>(sqePtr);
     961            0 :             taskId = memcpyAsyncSqePtr->header.taskId;
     962            0 :             streamId = memcpyAsyncSqePtr->header.rtStreamId;
     963            0 :         } else if (sqeType == SqeType::CACHE_MEMCPY_PLACEHOLDER_SQE) {
     964            0 :             const rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<const rtStarsPlaceHolderSqe_t *>(sqePtr);
     965            0 :             taskId = placeholderSqePtr->header.taskId;
     966            0 :             streamId = placeholderSqePtr->header.rtStreamId;
     967              :         } else {
     968            0 :             HCCL_ERROR("[OpUnfoldCacheEntry][CheckMemTypeForAlltoallv] invalid sqeType[%u]", sqeType);
     969            0 :             return HCCL_E_INTERNAL;
     970              :         }
     971              : 
     972              :         // memcpy / cache-memcpy placeholder SQE的src/dst memType一定不是invalid
     973              :         // 注意: memcpy-record SQE的src/dst一定是invalid, 但不会进入本函数
     974            0 :         const uint8_t srcMemType = srcRefreshAddrInfo.memType;
     975            0 :         const uint8_t dstMemType = dstRefreshAddrInfo.memType;
     976            0 :         CHK_PRT_RET(srcMemType == RefreshAddrInfo::INVALID_MEMTYPE || dstMemType == RefreshAddrInfo::INVALID_MEMTYPE,
     977              :             HCCL_ERROR("[OpUnfoldCacheEntry][CheckMemTypeForAlltoallv] sqeType[%u] streamId[%u] taskId[%u] srcMemType[%u] dstMemType[%u]",
     978              :                 sqeType, streamId, taskId, srcMemType, dstMemType),
     979              :             HCCL_E_INTERNAL);
     980              : 
     981              :         // src一定不是user output
     982            0 :         CHK_PRT_RET(srcMemType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE,
     983              :             HCCL_ERROR("[OpUnfoldCacheEntry][CheckMemTypeForAlltoallv] sqeType[%u] streamId[%u] taskId[%u] srcMemType[%u]",
     984              :                 sqeType, streamId, taskId, srcMemType),
     985              :             HCCL_E_INTERNAL);
     986              : 
     987              :         // src是user input时, dst一定是user output / hccl input
     988              :         // src是hccl input时, dst一定是user output
     989            0 :         if (srcMemType == RefreshAddrInfo::USER_INPUT_MEMTYPE) {
     990            0 :             CHK_PRT_RET(dstMemType != RefreshAddrInfo::USER_OUTPUT_MEMTYPE && dstMemType != RefreshAddrInfo::HCCL_INPUT_MEMTYPE,
     991              :                 HCCL_ERROR("[OpUnfoldCacheEntry][CheckMemTypeForAlltoallv] sqeType[%u] streamId[%u] taskId[%u] dstMemType[%u]",
     992              :                 sqeType, streamId, taskId, dstMemType),
     993              :             HCCL_E_INTERNAL);
     994            0 :         } else if (srcMemType == RefreshAddrInfo::HCCL_INPUT_MEMTYPE) {
     995            0 :             CHK_PRT_RET(dstMemType != RefreshAddrInfo::USER_OUTPUT_MEMTYPE,
     996              :                 HCCL_ERROR("[OpUnfoldCacheEntry][CheckMemTypeForAlltoallv] sqeType[%u] streamId[%u] taskId[%u] dstMemType[%u]",
     997              :                 sqeType, streamId, taskId, dstMemType),
     998              :             HCCL_E_INTERNAL);
     999              :         }
    1000              : 
    1001              :         // dst一定不是user input
    1002            0 :         CHK_PRT_RET(dstMemType == RefreshAddrInfo::USER_INPUT_MEMTYPE,
    1003              :             HCCL_ERROR("[OpUnfoldCacheEntry][CheckMemTypeForAlltoallv] sqeType[%u] streamId[%u] taskId[%u] dstMemType[%u]",
    1004              :                 sqeType, streamId, taskId, dstMemType),
    1005              :             HCCL_E_INTERNAL);
    1006              : 
    1007              :         // dst是user output时, src一定是user input / hccl input
    1008              :         // dst是hccl input时, src一定是user input
    1009            0 :         if (dstMemType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE) {
    1010            0 :             CHK_PRT_RET(srcMemType != RefreshAddrInfo::USER_INPUT_MEMTYPE && srcMemType != RefreshAddrInfo::HCCL_INPUT_MEMTYPE,
    1011              :                 HCCL_ERROR("[OpUnfoldCacheEntry][CheckMemTypeForAlltoallv] sqeType[%u] streamId[%u] taskId[%u] srcMemType[%u]",
    1012              :                 sqeType, streamId, taskId, srcMemType),
    1013              :             HCCL_E_INTERNAL);
    1014            0 :         } else if (dstMemType == RefreshAddrInfo::HCCL_INPUT_MEMTYPE) {
    1015            0 :             CHK_PRT_RET(srcMemType != RefreshAddrInfo::USER_INPUT_MEMTYPE,
    1016              :                 HCCL_ERROR("[OpUnfoldCacheEntry][CheckMemTypeForAlltoallv] sqeType[%u] streamId[%u] taskId[%u] srcMemType[%u]",
    1017              :                 sqeType, streamId, taskId, srcMemType),
    1018              :             HCCL_E_INTERNAL);
    1019              :         }
    1020              : 
    1021            0 :         return HCCL_SUCCESS;
    1022              :     }
    1023              : 
    1024            0 :     HcclResult OpUnfoldCacheEntry::UpdateTransferSqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId, const RefreshAddrInfo& srcRefreshAddrInfo, const RefreshAddrInfo& dstRefreshAddrInfo, const std::vector<OpUnfoldMemRange>& curUserInputMemRanges, const std::vector<OpUnfoldMemRange>& curUserOutputMemRanges, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo) {
    1025            0 :         HCCL_INFO("[OpUnfoldCacheEntry][UpdateTransferSqeForAlltoallv] curTaskId[%u] srcMemType[%u] dstMemType[%u]",
    1026              :             curTaskId, srcRefreshAddrInfo.memType, dstRefreshAddrInfo.memType);
    1027              :         
    1028              :         // 先判断是否需要刷新此memcpy SQE
    1029            0 :         if (srcRefreshAddrInfo.memType != RefreshAddrInfo::USER_INPUT_MEMTYPE && dstRefreshAddrInfo.memType != RefreshAddrInfo::USER_OUTPUT_MEMTYPE) {
    1030              :             // 注意: 由于alltoallv direct fullmesh不会调用InlineReduceAsync和基于memcpy的SignalRecord
    1031              :             // 理论上所有的memcpy / cache-memcpy SQE都需要地址刷新, 不会进入当前code block
    1032              : 
    1033              :             // 更新task id
    1034            0 :             if ((*sqeTypePtr) == SqeType::MEMCPY_ASYNC_SQE) {
    1035            0 :                 rtStarsMemcpyAsyncSqe_t *memcpyAsyncSqePtr = reinterpret_cast<rtStarsMemcpyAsyncSqe_t *>(sqePtr);
    1036            0 :                 memcpyAsyncSqePtr->header.taskId = curTaskId;
    1037            0 :             } else if ((*sqeTypePtr) == SqeType::CACHE_MEMCPY_PLACEHOLDER_SQE) {
    1038            0 :                 rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<rtStarsPlaceHolderSqe_t *>(sqePtr);
    1039            0 :                 placeholderSqePtr->header.taskId = curTaskId;
    1040              :             } else {
    1041            0 :                 HCCL_ERROR("[OpUnfoldCacheEntry][UpdateTransferSqeForAlltoallv] invalid sqeType[%u]", *sqeTypePtr);
    1042            0 :                 return HCCL_E_INTERNAL;
    1043              :             }
    1044              : 
    1045            0 :             return HCCL_SUCCESS;
    1046              :         }
    1047              :         // 注意: 从这里开始, srcAddr为userInput和dstAddr为userOutput至少有一个条件满足
    1048              : 
    1049              :         // 校验alltoallv相关参数
    1050            0 :         CHK_RET(alltoallvMetadata.Check(true));
    1051            0 :         CHK_RET(alltoallvSendRecvInfo.Check());
    1052            0 :         const uint32_t rankSize = alltoallvSendRecvInfo.sendOffsets.size();
    1053            0 :         CHK_PRT_RET(rankSize != alltoallvMetadata.hcclInputMemRanges.size(),
    1054              :             HCCL_ERROR("[OpUnfoldCacheEntry][UpdateTransferSqeForAlltoallv] hcclInputMemRanges.size[%u] != rankSize[%u]",
    1055              :                 alltoallvMetadata.hcclInputMemRanges.size(), rankSize),
    1056              :             HCCL_E_INTERNAL);
    1057              : 
    1058              :         // 获取当前memcpy类SQE对应的count和size
    1059            0 :         uint64_t count = 0;
    1060            0 :         uint64_t size = 0; // send/recv bytes
    1061            0 :         CHK_RET(GetTransferCountForAlltoallv(count, size, srcRefreshAddrInfo, dstRefreshAddrInfo, alltoallvMetadata, alltoallvSendRecvInfo));
    1062              : 
    1063              :         // 更新/生成相应SQE
    1064            0 :         if ((*sqeTypePtr) == SqeType::MEMCPY_ASYNC_SQE) {
    1065            0 :             CHK_RET(UpdateMemcpySqeForAlltoallv(sqePtr, sqeTypePtr, curTaskId, srcRefreshAddrInfo, dstRefreshAddrInfo, curUserInputMemRanges, curUserOutputMemRanges, alltoallvMetadata, alltoallvSendRecvInfo, count, size));
    1066            0 :         } else if ((*sqeTypePtr) == SqeType::CACHE_MEMCPY_PLACEHOLDER_SQE) {
    1067            0 :             CHK_RET(UpdateMemcpyPlaceholderSqeForAlltoallv(sqePtr, sqeTypePtr, curTaskId, srcRefreshAddrInfo, dstRefreshAddrInfo, curUserInputMemRanges, curUserOutputMemRanges, alltoallvMetadata, alltoallvSendRecvInfo, count, size));
    1068              :         } else {
    1069            0 :             HCCL_ERROR("[OpUnfoldCacheEntry][UpdateTransferSqeForAlltoallv] invalid sqeType[%u]", *sqeTypePtr);
    1070            0 :             return HCCL_E_INTERNAL;
    1071              :         }
    1072              : 
    1073            0 :         return HCCL_SUCCESS;
    1074              :     }
    1075              : 
    1076            0 :     HcclResult OpUnfoldCacheEntry::GetTransferCountForAlltoallv(uint64_t& count, uint64_t& size, const RefreshAddrInfo& srcRefreshAddrInfo, const RefreshAddrInfo& dstRefreshAddrInfo, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo) const {
    1077              :         // 注意: 如果对应send count, 一定是LocalCopy或者PrepareIntraData, 即local user input -> local user output / hccl input
    1078              :         // 注意: 如果对应recv count, 一定是RemoteCopy, 即remote hccl input -> local user output
    1079            0 :         const uint32_t rankSize = alltoallvSendRecvInfo.sendOffsets.size();
    1080            0 :         if (srcRefreshAddrInfo.memType == RefreshAddrInfo::USER_INPUT_MEMTYPE) { // LocalCopy/PrepareIntraData
    1081              :             // 获得local rank
    1082            0 :             uint32_t localRank = srcRefreshAddrInfo.rankId;
    1083            0 :             CHK_PRT_RET(localRank >= rankSize, HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] localRank[%u] >= rankSize[%u]", localRank, rankSize), HCCL_E_INTERNAL);
    1084              : 
    1085              :             // 获得dst rank
    1086            0 :             uint32_t dstRank = 0;
    1087            0 :             if (dstRefreshAddrInfo.memType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE) { // LocalCopy
    1088            0 :                 dstRank = dstRefreshAddrInfo.rankId; // dstRank = localRank
    1089            0 :                 CHK_PRT_RET(dstRank != localRank, HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] dstRank[%u] != localRank[%u]", dstRank, localRank), HCCL_E_INTERNAL);
    1090            0 :             } else if (dstRefreshAddrInfo.memType == RefreshAddrInfo::HCCL_INPUT_MEMTYPE) { // PrepareIntraData
    1091              :                 // dstRank在第一次cache miss后处理时, 被UpdateRefreshAddrInfoForAlltoallv更新, 一定不等于localRank
    1092            0 :                 dstRank = dstRefreshAddrInfo.rankId;
    1093            0 :                 CHK_PRT_RET(dstRank == localRank, HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] dstRank[%u] = localRank[%u]", dstRank, localRank), HCCL_E_INTERNAL);
    1094              :             } else {
    1095            0 :                 HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] invalid dstMemType[%u]", dstRefreshAddrInfo.memType);
    1096            0 :                 return HCCL_E_INTERNAL;
    1097              :             }
    1098              : 
    1099              :             // 获得dst rank对应的send count/size
    1100            0 :             CHK_PRT_RET(dstRank >= rankSize, HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] dstRank[%u] >= rankSize[%u]", dstRank, rankSize), HCCL_E_INTERNAL);
    1101            0 :             count = alltoallvSendRecvInfo.sendCounts[dstRank];
    1102            0 :             size = count * SIZE_TABLE[alltoallvSendRecvInfo.sendType];
    1103              : 
    1104            0 :             HCCL_INFO("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] sendCount[%llu] sendSize[%llu] dstRank[%u]", count, size, dstRank);
    1105            0 :         } else if (dstRefreshAddrInfo.memType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE) { // srcAddr不是user input, 但dstAddr是user output (remote copy: remote hccl input -> local user output)
    1106            0 :             CHK_PRT_RET(srcRefreshAddrInfo.memType != RefreshAddrInfo::HCCL_INPUT_MEMTYPE,
    1107              :                 HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] invalid srcMemType[%u] for remote copy", srcRefreshAddrInfo.memType),
    1108              :                 HCCL_E_INTERNAL);
    1109              : 
    1110              :             // 获得src rank对应的recv count/size
    1111            0 :             uint32_t srcRank = srcRefreshAddrInfo.rankId;
    1112            0 :             CHK_PRT_RET(srcRank >= rankSize, HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] srcRank[%u] >= rankSize[%u]", srcRank, rankSize), HCCL_E_INTERNAL);
    1113            0 :             count = alltoallvSendRecvInfo.recvCounts[srcRank];
    1114            0 :             size = count * SIZE_TABLE[alltoallvSendRecvInfo.recvType];
    1115              : 
    1116            0 :             HCCL_INFO("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] recvCount[%llu] recvSize[%llu] srcRank[%u]", count, size, srcRank);
    1117              :         } else {
    1118            0 :             HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] invalid srcMemType[%u] and dstMemType[%u]", srcRefreshAddrInfo.memType, dstRefreshAddrInfo.memType);
    1119            0 :             return HCCL_E_INTERNAL;
    1120              :         }
    1121              : 
    1122              :         // 一定不是大数据量的alltoallv, 否则会在aicpu communicator侧被拦截, 不会进入cache
    1123            0 :         CHK_PRT_RET(size > alltoallvMetadata.sdmaDataBlockSize || size > HCCL_SDMA_MAX_COUNT_4GB,
    1124              :             HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] invalid size[%u] sdmaDataBlockSize[%u] 4GB[%u]",
    1125              :                 size, alltoallvMetadata.sdmaDataBlockSize, HCCL_SDMA_MAX_COUNT_4GB),
    1126              :             HCCL_E_INTERNAL);
    1127              : 
    1128            0 :         return HCCL_SUCCESS;
    1129              :     }
    1130              : 
    1131            0 :     HcclResult OpUnfoldCacheEntry::UpdateMemcpySqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId, const RefreshAddrInfo& srcRefreshAddrInfo, const RefreshAddrInfo& dstRefreshAddrInfo, const std::vector<OpUnfoldMemRange>& curUserInputMemRanges, const std::vector<OpUnfoldMemRange>& curUserOutputMemRanges, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo, const uint64_t count, const uint64_t size) {
    1132              :         // 获取src/dst memType
    1133            0 :         const uint8_t srcMemType = srcRefreshAddrInfo.memType;
    1134            0 :         const uint8_t dstMemType = dstRefreshAddrInfo.memType;
    1135              : 
    1136              :         // 更新SQE (count > 0)或者生成SQE (count = 0)
    1137            0 :         const uint32_t rankSize = alltoallvSendRecvInfo.sendOffsets.size();
    1138            0 :         rtStarsMemcpyAsyncSqe_t *memcpyAsyncSqePtr = reinterpret_cast<rtStarsMemcpyAsyncSqe_t *>(sqePtr);
    1139            0 :         if (count > 0) { // Case 1: memcpy SQE -> memcpy SQE
    1140            0 :             HCCL_DEBUG("[OpUnfoldCacheEntry][UpdateMemcpySqeForAlltoallv] case 1: memcpy -> memcpy; curTaskId[%u]", curTaskId);
    1141              : 
    1142              :             // 校验length
    1143            0 :             CHK_PRT_RET(size == 0, HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpySqeForAlltoallv] size[%u] for positive count", size), HCCL_E_INTERNAL);
    1144              : 
    1145              :             // 更新task id
    1146            0 :             memcpyAsyncSqePtr->header.taskId = curTaskId;
    1147              : 
    1148              :             // 更新length
    1149            0 :             memcpyAsyncSqePtr->length = static_cast<uint32_t>(size);
    1150              : 
    1151              :             // 更新src/dst addr
    1152            0 :             if (srcMemType == RefreshAddrInfo::USER_INPUT_MEMTYPE) { // LocalCopy/PrepareIntraData
    1153              :                 // 获取send offset
    1154            0 :                 const uint32_t dstRank = dstRefreshAddrInfo.rankId; // LocalCopy下是localRank, PrepareIntraData下是remoteRank
    1155            0 :                 CHK_PRT_RET(dstRank >= rankSize, HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpySqeForAlltoallv] dstRank[%u] >= rankSize[%u]", dstRank, rankSize), HCCL_E_INTERNAL);
    1156            0 :                 const uint64_t sendOffset = alltoallvSendRecvInfo.sendOffsets[dstRank];
    1157              : 
    1158              :                 // 更新src addr (local user input)
    1159            0 :                 uint64_t sqeSrcAddr = 0;
    1160            0 :                 CombineUint32ToUint64(sqeSrcAddr, memcpyAsyncSqePtr->src_addr_high, memcpyAsyncSqePtr->src_addr_low);
    1161            0 :                 CHK_RET(RefreshSqeAddr(sqeSrcAddr, srcRefreshAddrInfo.rankId, userInputMemRanges_, curUserInputMemRanges, true, sendOffset));
    1162            0 :                 SplitUint64ToUint32(sqeSrcAddr, memcpyAsyncSqePtr->src_addr_high, memcpyAsyncSqePtr->src_addr_low);
    1163              : 
    1164              :                 // 只有LocalCopy才需要更新dst addr (hccl addr不用刷新)
    1165            0 :                 if (dstMemType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE) { // LocalCopy (local user input -> local user output)
    1166              :                     // 获取recv offset
    1167            0 :                     const uint64_t recvOffset = alltoallvSendRecvInfo.recvOffsets[dstRank];
    1168              : 
    1169              :                     // 更新dst addr (local user output)
    1170            0 :                     uint64_t sqeDstAddr = 0;
    1171            0 :                     CombineUint32ToUint64(sqeDstAddr, memcpyAsyncSqePtr->dst_addr_high, memcpyAsyncSqePtr->dst_addr_low);
    1172            0 :                     CHK_RET(RefreshSqeAddr(sqeDstAddr, dstRank, userOutputMemRanges_, curUserOutputMemRanges, true, recvOffset));
    1173            0 :                     SplitUint64ToUint32(sqeDstAddr, memcpyAsyncSqePtr->dst_addr_high, memcpyAsyncSqePtr->dst_addr_low);
    1174              :                 }
    1175              :             } else { // RemoteCopy
    1176              :                 // 获取recv offset
    1177            0 :                 uint32_t srcRank = srcRefreshAddrInfo.rankId;
    1178            0 :                 CHK_PRT_RET(srcRank >= rankSize,
    1179              :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpySqeForAlltoallv] srcRank[%u] >= rankSize[%u]",
    1180              :                         srcRank, rankSize),
    1181              :                     HCCL_E_INTERNAL);
    1182            0 :                 const uint64_t recvOffset = alltoallvSendRecvInfo.recvOffsets[srcRank];
    1183              : 
    1184              :                 // 更新dst addr (local user output)
    1185            0 :                 uint64_t sqeDstAddr = 0;
    1186            0 :                 CombineUint32ToUint64(sqeDstAddr, memcpyAsyncSqePtr->dst_addr_high, memcpyAsyncSqePtr->dst_addr_low);
    1187            0 :                 CHK_RET(RefreshSqeAddr(sqeDstAddr, dstRefreshAddrInfo.rankId, userOutputMemRanges_, curUserOutputMemRanges, true, recvOffset));
    1188            0 :                 SplitUint64ToUint32(sqeDstAddr, memcpyAsyncSqePtr->dst_addr_high, memcpyAsyncSqePtr->dst_addr_low);
    1189              :             }
    1190              :         } else { // Case 2: memcpy SQE -> placeholder SQE
    1191            0 :             HCCL_DEBUG("[OpUnfoldCacheEntry][UpdateMemcpySqeForAlltoallv] case 2: memcpy -> placeholder; curTaskId[%u]", curTaskId);
    1192              : 
    1193              :             // 校验length
    1194            0 :             CHK_PRT_RET(size != 0,
    1195              :                 HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpySqeForAlltoallv] size[%u] for zero count", size),
    1196              :                 HCCL_E_INTERNAL);
    1197              : 
    1198              :             // 保留original SQE中的相关信息
    1199            0 :             const uint16_t streamId = memcpyAsyncSqePtr->header.rtStreamId;
    1200            0 :             const uint8_t kernelCredit = memcpyAsyncSqePtr->kernel_credit;
    1201            0 :             const uint8_t linkType = memcpyAsyncSqePtr->linkType;
    1202            0 :             const uint32_t qos = memcpyAsyncSqePtr->qos;
    1203            0 :             uint32_t dstAddrHigh = 0;
    1204            0 :             uint32_t dstAddrLow = 0;
    1205            0 :             bool saveDstAddr = false;
    1206            0 :             if (srcMemType == RefreshAddrInfo::USER_INPUT_MEMTYPE && dstMemType == RefreshAddrInfo::HCCL_INPUT_MEMTYPE) { // PrepareIntraData
    1207              :                 // 保留dst addr (local hccl input)
    1208              :                 // 注意: 非PrepraeIntraData case下, dst addr为local user output, 会动态计算, 无需保留在placeholder中
    1209            0 :                 dstAddrHigh = memcpyAsyncSqePtr->dst_addr_high;
    1210            0 :                 dstAddrLow = memcpyAsyncSqePtr->dst_addr_low;
    1211            0 :                 saveDstAddr = true;
    1212              :             }
    1213            0 :             uint32_t srcAddrHigh = 0;
    1214            0 :             uint32_t srcAddrLow = 0;
    1215            0 :             bool saveSrcAddr = false;
    1216            0 :             if (srcMemType == RefreshAddrInfo::HCCL_INPUT_MEMTYPE && dstMemType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE) { // RemoteCopy
    1217              :                 // 保留src addr (remote hccl intput)
    1218              :                 // 注意: 非RemoteCopy case下, src addr为local user input, 会动态计算, 无需保留在placeholder中
    1219            0 :                 srcAddrHigh = memcpyAsyncSqePtr->src_addr_high;
    1220            0 :                 srcAddrLow = memcpyAsyncSqePtr->src_addr_low;
    1221            0 :                 saveSrcAddr = true;
    1222              :             }
    1223              : 
    1224              :             // 清空original SQE
    1225            0 :             CHK_SAFETY_FUNC_RET(memset_s(static_cast<void *>(sqePtr), HCCL_SQE_SIZE, 0, HCCL_SQE_SIZE));
    1226              : 
    1227              :             // 生成placeholder SQE
    1228              :             // 参考aicpu_hccl_sqcqv1.cc中的AddOneCacheMemcpyPlaceholderSqeV1
    1229            0 :             *sqeTypePtr = SqeType::CACHE_MEMCPY_PLACEHOLDER_SQE;
    1230            0 :             SetCachePlaceholderHeaderForAlltoallv(streamId, curTaskId, sqePtr);
    1231              : 
    1232              :             // 注意: 正常情况下无需设置placeholder SQE中的src/dst addr
    1233              :             // (只用于第一次算子执行发生cache miss时, 根据memory range获得对应的RefreshAddrInfo, 后续不再使用)
    1234            0 :             rtStarsPlaceHolderSqe_t * const placeholderSqePtr = (rtStarsPlaceHolderSqe_t *)sqePtr;
    1235            0 :             if (saveDstAddr) { // PrepareIntraData case下需要保留dst addr (local hccl input)
    1236            0 :                 placeholderSqePtr->u.cache_memcpy_task_info.dst_addr_high = dstAddrHigh;
    1237            0 :                 placeholderSqePtr->u.cache_memcpy_task_info.dst_addr_low = dstAddrLow;
    1238              :             }
    1239            0 :             if (saveSrcAddr) { // RemoteCopy case下需要保留src addr (remote hccl input)
    1240            0 :                 placeholderSqePtr->u.cache_memcpy_task_info.src_addr_high = srcAddrHigh;
    1241            0 :                 placeholderSqePtr->u.cache_memcpy_task_info.src_addr_low = srcAddrLow;
    1242              :             }
    1243            0 :             placeholderSqePtr->u.cache_memcpy_task_info.kernel_credit = kernelCredit;
    1244            0 :             placeholderSqePtr->u.cache_memcpy_task_info.linkType = linkType;
    1245            0 :             placeholderSqePtr->u.cache_memcpy_task_info.qos = qos;
    1246              :         }
    1247              : 
    1248            0 :         return HCCL_SUCCESS;
    1249              :     }
    1250              : 
    1251            0 :     HcclResult OpUnfoldCacheEntry::UpdateMemcpyPlaceholderSqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId, const RefreshAddrInfo& srcRefreshAddrInfo, const RefreshAddrInfo& dstRefreshAddrInfo, const std::vector<OpUnfoldMemRange>& curUserInputMemRanges, const std::vector<OpUnfoldMemRange>& curUserOutputMemRanges, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo, const uint64_t count, const uint64_t size) {
    1252              :         // 更新SQE (count = 0)或者生成SQE (count > 0)
    1253            0 :         const uint32_t rankSize = alltoallvSendRecvInfo.sendOffsets.size();
    1254            0 :         rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<rtStarsPlaceHolderSqe_t *>(sqePtr);
    1255            0 :         if (count == 0) { // Case 3: placeholder SQE -> placeholder SQE
    1256            0 :             HCCL_DEBUG("[OpUnfoldCacheEntry][UpdateMemcpyPlaceholderSqeForAlltoallv] case 3: placeholder -> placeholder; curTaskId[%u]", curTaskId);
    1257              : 
    1258              :             // 校验length
    1259            0 :             CHK_PRT_RET(size != 0, HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpyPlaceholderSqeForAlltoallv] size[%u] for zero count", size), HCCL_E_INTERNAL);
    1260              : 
    1261              :             // 更新task id
    1262            0 :             placeholderSqePtr->header.taskId = curTaskId;
    1263              : 
    1264              :             // 注意: 无需更新placeholder SQE中的src/dst addr (只用于第一次算子执行发生cache miss时, 根据memory range获得对应的RefreshAddrInfo, 后续不再使用)
    1265              :         } else { // Case 4: placeholder SQE -> memcpy SQE
    1266            0 :             HCCL_DEBUG("[OpUnfoldCacheEntry][UpdateMemcpyPlaceholderSqeForAlltoallv] case 4: placeholder -> memcpy; curTaskId[%u]", curTaskId);
    1267              : 
    1268              :             // 校验length
    1269            0 :             CHK_PRT_RET(size == 0, HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpyPlaceholderSqeForAlltoallv] size[%u] for positive count", size), HCCL_E_INTERNAL);
    1270              : 
    1271              :             // 保留original SQE中的相关信息
    1272            0 :             const uint16_t streamId = placeholderSqePtr->header.rtStreamId;
    1273            0 :             const uint8_t kernelCredit = placeholderSqePtr->u.cache_memcpy_task_info.kernel_credit;
    1274            0 :             const uint8_t linkType = placeholderSqePtr->u.cache_memcpy_task_info.linkType;
    1275            0 :             const uint32_t qos = placeholderSqePtr->u.cache_memcpy_task_info.qos;
    1276              : 
    1277              :             // 准备src/dst addr
    1278            0 :             uint64_t sqeSrcAddr = 0;
    1279            0 :             uint64_t sqeDstAddr = 0;
    1280            0 :             if (srcRefreshAddrInfo.memType == RefreshAddrInfo::USER_INPUT_MEMTYPE) { // LocalCopy/PrepareIntraData
    1281              :                 // 获取send offset
    1282            0 :                 const uint32_t dstRank = dstRefreshAddrInfo.rankId; // LocalCopy下是localRank, PrepareIntraData下是remoteRank
    1283            0 :                 CHK_PRT_RET(dstRank >= rankSize, HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpyPlaceholderSqeForAlltoallv] dstRank[%u] >= rankSize[%u]", dstRank, rankSize), HCCL_E_INTERNAL);
    1284            0 :                 const uint64_t sendOffset = alltoallvSendRecvInfo.sendOffsets[dstRank];
    1285              : 
    1286              :                 // 获得src addr (local user input)
    1287            0 :                 const uint32_t localRank = srcRefreshAddrInfo.rankId;
    1288            0 :                 CHK_PRT_RET(localRank >= rankSize, HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpyPlaceholderSqeForAlltoallv] localRank[%u] >= rankSize[%u]", localRank, rankSize), HCCL_E_INTERNAL);
    1289            0 :                 const uint64_t localUserInputBaseAddr = curUserInputMemRanges[localRank].baseAddr;
    1290            0 :                 sqeSrcAddr = localUserInputBaseAddr + sendOffset;
    1291              : 
    1292            0 :                 if (dstRefreshAddrInfo.memType == RefreshAddrInfo::USER_OUTPUT_MEMTYPE) { // LocalCopy
    1293              :                     // 获取recv offset
    1294            0 :                     const uint64_t recvOffset = alltoallvSendRecvInfo.recvOffsets[dstRank]; // dstRank = localRank
    1295              : 
    1296              :                     // 获得dst addr (local user output)
    1297            0 :                     const uint64_t localUserOutputBaseAddr = curUserOutputMemRanges[dstRank].baseAddr;
    1298            0 :                     sqeDstAddr = localUserOutputBaseAddr + recvOffset;
    1299            0 :                 } else if (dstRefreshAddrInfo.memType == RefreshAddrInfo::HCCL_INPUT_MEMTYPE) { // PrepareIntraData
    1300              :                     // 从placeholder中获取dst addr (local hccl input)
    1301            0 :                     const uint32_t dstAddrHigh = placeholderSqePtr->u.cache_memcpy_task_info.dst_addr_high;
    1302            0 :                     const uint32_t dstAddrLow = placeholderSqePtr->u.cache_memcpy_task_info.dst_addr_low;
    1303            0 :                     CombineUint32ToUint64(sqeDstAddr, dstAddrHigh, dstAddrLow);
    1304              :                 } else {
    1305            0 :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpyPlaceholderSqeForAlltoallv] invalid srcMemType[%u] dstMemType[%u]",\
    1306              :                         srcRefreshAddrInfo.memType, dstRefreshAddrInfo.memType);
    1307            0 :                     return HCCL_E_INTERNAL;
    1308              :                 }
    1309              :             } else { // RemoteCopy
    1310              :                 // 从placeholder中获取src addr (remote hccl input)
    1311            0 :                 const uint32_t srcAddrHigh = placeholderSqePtr->u.cache_memcpy_task_info.src_addr_high;
    1312            0 :                 const uint32_t srcAddrLow = placeholderSqePtr->u.cache_memcpy_task_info.src_addr_low;
    1313            0 :                 CombineUint32ToUint64(sqeSrcAddr, srcAddrHigh, srcAddrLow);
    1314              : 
    1315              :                 // 获得remote src rank
    1316            0 :                 const uint32_t srcRank = srcRefreshAddrInfo.rankId;
    1317            0 :                 CHK_PRT_RET(srcRank >= rankSize,
    1318              :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpyPlaceholderSqeForAlltoallv] srcRank[%u] >= rankSize[%u]",
    1319              :                         srcRank, rankSize),
    1320              :                     HCCL_E_INTERNAL);
    1321              : 
    1322              :                 // 获得recv offset
    1323            0 :                 const uint64_t recvOffset = alltoallvSendRecvInfo.recvOffsets[srcRank]; // srcRank = remoteRank
    1324              : 
    1325              :                 // 获得dst addr
    1326            0 :                 const uint32_t localRank = dstRefreshAddrInfo.rankId;
    1327            0 :                 CHK_PRT_RET(localRank >= rankSize,
    1328              :                     HCCL_ERROR("[OpUnfoldCacheEntry][UpdateMemcpyPlaceholderSqeForAlltoallv] localRank[%u] >= rankSize[%u]",
    1329              :                         localRank, rankSize),
    1330              :                     HCCL_E_INTERNAL);
    1331            0 :                 const uint64_t localUserOutputBaseAddr = curUserOutputMemRanges[localRank].baseAddr;
    1332            0 :                 sqeDstAddr = localUserOutputBaseAddr + recvOffset;
    1333              :             }
    1334              : 
    1335              :             // 清空original SQE
    1336            0 :             CHK_SAFETY_FUNC_RET(memset_s(static_cast<void *>(sqePtr), HCCL_SQE_SIZE, 0, HCCL_SQE_SIZE));
    1337              : 
    1338              :             // 生成memcpy SQE
    1339              :             // 参考aicpu_hccl_sqcqv1.cc中的AddOneMemcpySqeV1
    1340            0 :             *sqeTypePtr = SqeType::MEMCPY_ASYNC_SQE;
    1341            0 :             rtStarsMemcpyAsyncSqe_t *memcpySqePtr = reinterpret_cast<rtStarsMemcpyAsyncSqe_t *>(sqePtr);
    1342            0 :             memcpySqePtr->header.type = RT_STARS_SQE_TYPE_SDMA;
    1343            0 :             memcpySqePtr->header.rtStreamId = streamId;
    1344            0 :             memcpySqePtr->header.taskId = curTaskId;
    1345            0 :             memcpySqePtr->kernel_credit = kernelCredit;
    1346            0 :             memcpySqePtr->opcode = 0U;
    1347            0 :             memcpySqePtr->length = static_cast<uint32_t>(size);
    1348            0 :             SplitUint64ToUint32(sqeSrcAddr, memcpySqePtr->src_addr_high, memcpySqePtr->src_addr_low);
    1349            0 :             SplitUint64ToUint32(sqeDstAddr, memcpySqePtr->dst_addr_high, memcpySqePtr->dst_addr_low);
    1350            0 :             memcpySqePtr->sssv = 1U;
    1351            0 :             memcpySqePtr->dssv = 1U;
    1352            0 :             memcpySqePtr->sns = 1U;
    1353            0 :             memcpySqePtr->dns = 1U;
    1354            0 :             memcpySqePtr->qos = 6; // 6 is HCCL QoS
    1355            0 :             const uint32_t partId = 0; // 参考dispatcher_aicpu.cc中addOneMemcpySqe_的partId传参始终为0
    1356            0 :             memcpySqePtr->partid = partId;
    1357            0 :             memcpySqePtr->linkType = linkType;
    1358            0 :             memcpySqePtr->qos = qos;
    1359              :         }
    1360              : 
    1361            0 :         return HCCL_SUCCESS;
    1362              :     }
    1363              : 
    1364            0 :     HcclResult OpUnfoldCacheEntry::RefreshSqeAddr(uint64_t &sqeAddr, const uint32_t rankId, const std::vector<OpUnfoldMemRange>& cachedMemRanges, const std::vector<OpUnfoldMemRange>& curMemRanges, const bool isAlltoallv, const uint64_t offset) const {
    1365            0 :         CHK_PRT_RET(rankId == INVALID_VALUE_RANKID, HCCL_ERROR("[OpUnfoldCacheEntry][RefreshSqeAddr] invalid rankId"), HCCL_E_INTERNAL);
    1366            0 :         CHK_PRT_RET(rankId >= cachedMemRanges.size(), HCCL_ERROR("[OpUnfoldCacheEntry][RefreshSqeAddr] rankId %u exceeds rankSize %u", rankId, cachedMemRanges.size()), HCCL_E_INTERNAL);
    1367              : 
    1368              :         // 获取缓存的和当前的memory ranges
    1369            0 :         const OpUnfoldMemRange& cachedMemRange = cachedMemRanges[rankId];
    1370            0 :         const OpUnfoldMemRange& curMemRange = curMemRanges[rankId];
    1371            0 :         HCCL_DEBUG("[OpUnfoldCacheEntry][RefreshSqeAddr] cachedMemRange: isValid[%u] baseAddr[0x%016llx] memSize[%llu]; curMemRange: isValid[%u] baseAddr[0x%016llx] memSize[%llu] isAlltoallv[%u]",
    1372              :             cachedMemRange.isValid, cachedMemRange.baseAddr, cachedMemRange.memSize, curMemRange.isValid, curMemRange.baseAddr, curMemRange.memSize, isAlltoallv);
    1373              : 
    1374              :         // 刷新前地址校验
    1375              :         // (i) user memory: 非V类/alltoallv, SQE addr字段一定在user memory range内, 才需要调用本函数刷新addr
    1376              :         // (ii) hccl memory: alltoallv, SQE addr一定在hccl memory range内, 才需要调用本函数生成addr
    1377            0 :         bool isInRange = false;
    1378            0 :         CHK_RET(cachedMemRange.InRange(sqeAddr, isInRange));
    1379            0 :         CHK_PRT_RET(!isInRange,
    1380              :             HCCL_ERROR("[OpUnfoldCacheEntry][RefreshSqeAddr] sqeAddr[0x%016llx] not in the range of cachedMemRange[0x%016llx, 0x%016llx)",
    1381              :                 sqeAddr, cachedMemRange.baseAddr, cachedMemRange.baseAddr + cachedMemRange.memSize),
    1382              :             HCCL_E_INTERNAL);
    1383              : 
    1384              :         // 刷新SQE addr
    1385            0 :         uint64_t curOffset = 0;
    1386            0 :         if (isAlltoallv) { // alltoallv
    1387            0 :             curOffset = offset; // 使用给定的offset
    1388              :         } else { // 非V类算子
    1389            0 :             curOffset = sqeAddr - cachedMemRange.baseAddr; // 计算缓存的sqe addr相对于缓存的base addr的offset
    1390              :         }
    1391            0 :         sqeAddr = curMemRange.baseAddr + curOffset; // 用当前的base addr更新sqe addr
    1392              : 
    1393              :         // 刷新后地址校验: 一定在当前的memory range内
    1394            0 :         isInRange = false;
    1395            0 :         CHK_RET(curMemRange.InRange(sqeAddr, isInRange));
    1396            0 :         CHK_PRT_RET(!isInRange,
    1397              :             HCCL_ERROR("[OpUnfoldCacheEntry][RefreshSqeAddr] sqeAddr[0x%016llx] not in the range of curMemRange[0x%016llx, 0x%016llx)",
    1398              :                 sqeAddr, curMemRange.baseAddr, curMemRange.baseAddr + curMemRange.memSize),
    1399              :             HCCL_E_INTERNAL);
    1400              : 
    1401            0 :         return HCCL_SUCCESS;
    1402              :     }
    1403              : 
    1404            0 :     HcclResult OpUnfoldCacheEntry::UpdateSyncSqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId,
    1405              :         const RefreshAddrInfo& srcRefreshAddrInfo, const RefreshAddrInfo& dstRefreshAddrInfo,
    1406              :         const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo) {
    1407            0 :         HCCL_INFO("[OpUnfoldCacheEntry][UpdateSyncSqeForAlltoallv] curTaskId[%u]", curTaskId);
    1408              :         
    1409              :         // 校验alltoallv相关参数
    1410            0 :         CHK_RET(alltoallvMetadata.Check(true));
    1411            0 :         CHK_RET(alltoallvSendRecvInfo.Check());
    1412            0 :         const uint32_t rankSize = alltoallvSendRecvInfo.sendOffsets.size();
    1413            0 :         CHK_PRT_RET(rankSize != alltoallvMetadata.hcclInputMemRanges.size(),
    1414              :             HCCL_ERROR("[OpUnfoldCacheEntry][UpdateSyncSqeForAlltoallv] hcclInputMemRanges.size[%u] != rankSize[%u]",
    1415              :                 alltoallvMetadata.hcclInputMemRanges.size(), rankSize),
    1416              :             HCCL_E_INTERNAL);
    1417              : 
    1418              :         // 对于NotifyWait, 如果不在notifyid-rank map中, 则无需根据count进行处理, 只需要更新taskid
    1419              :         // 对于WriteValue/MemcpyRecord, 如果不在signaladdr-rank map中, 则无需根据count进行处理, 只需要更新taskid
    1420            0 :         if ((*sqeTypePtr) == SqeType::NOTIFY_SQE) {
    1421            0 :             rtStarsNotifySqeV1_t *notifySqePtr = reinterpret_cast<rtStarsNotifySqeV1_t *>(sqePtr);
    1422            0 :             const uint32_t notifyId = notifySqePtr->notify_id;
    1423            0 :             if (alltoallvMetadata.notifyIdRankRflagMap.find(notifyId) == alltoallvMetadata.notifyIdRankRflagMap.cend()) {
    1424            0 :                 notifySqePtr->header.taskId = curTaskId;
    1425            0 :                 return HCCL_SUCCESS;
    1426              :             }
    1427            0 :         } else if ((*sqeTypePtr) == SqeType::WRITE_VALUE_SQE) {
    1428            0 :             rtStarsWriteValueSqe_t *writeValueSqePtr = reinterpret_cast<rtStarsWriteValueSqe_t *>(sqePtr);
    1429            0 :             uint64_t signalAddr = 0;
    1430            0 :             const uint32_t lowAddr = writeValueSqePtr->write_addr_low;
    1431            0 :             const uint32_t highAddr = writeValueSqePtr->write_addr_high;
    1432            0 :             CombineUint32ToUint64(signalAddr, highAddr, lowAddr);
    1433            0 :             if (alltoallvMetadata.signalAddrRankRflagMap.find(signalAddr) == alltoallvMetadata.signalAddrRankRflagMap.cend()) {
    1434            0 :                 writeValueSqePtr->header.taskId = curTaskId;
    1435            0 :                 return HCCL_SUCCESS;
    1436              :             }
    1437            0 :         } else if ((*sqeTypePtr) == SqeType::MEMCPY_ASYNC_SQE) {
    1438              :             // Memcpy-record SQE的src/dst memtype一定是invalid
    1439            0 :             rtStarsMemcpyAsyncSqe_t *memcpySqePtr = reinterpret_cast<rtStarsMemcpyAsyncSqe_t *>(sqePtr);
    1440            0 :             CHK_PRT_RET(srcRefreshAddrInfo.memType != RefreshAddrInfo::INVALID_MEMTYPE ||
    1441              :                 dstRefreshAddrInfo.memType != RefreshAddrInfo::INVALID_MEMTYPE,
    1442              :                 HCCL_ERROR("[OpUnfoldCacheEntry][UpdateTransferSqeForAlltoallv] memcpy-record SQE: "\
    1443              :                     "streamId[%u] taskId[%u] curTaskId[%u] srcMemType[%u] dstMemType[%u]",
    1444              :                     memcpySqePtr->header.rtStreamId, memcpySqePtr->header.taskId, curTaskId,
    1445              :                     srcRefreshAddrInfo.memType, dstRefreshAddrInfo.memType),
    1446              :                 HCCL_E_INTERNAL);
    1447              : 
    1448            0 :             uint64_t dstSignalAddr = 0;
    1449            0 :             const uint32_t lowAddr = memcpySqePtr->dst_addr_low;
    1450            0 :             const uint32_t highAddr = memcpySqePtr->dst_addr_high;
    1451            0 :             CombineUint32ToUint64(dstSignalAddr, highAddr, lowAddr);
    1452            0 :             if (alltoallvMetadata.signalAddrRankRflagMap.find(dstSignalAddr) == alltoallvMetadata.signalAddrRankRflagMap.cend()) {
    1453            0 :                 memcpySqePtr->header.taskId = curTaskId;
    1454            0 :                 return HCCL_SUCCESS;
    1455              :             }
    1456              :         }
    1457              : 
    1458              :         // 获取当前sync类SQE对应的count和size
    1459            0 :         uint64_t count = 0;
    1460            0 :         uint64_t size = 0; // send/recv bytes
    1461            0 :         CHK_RET(GetTransferCountForAlltoallv(count, size, sqePtr, sqeTypePtr, alltoallvMetadata, alltoallvSendRecvInfo));
    1462              :         
    1463              :         // 更新/生成相应SQE
    1464            0 :         if ((*sqeTypePtr) == SqeType::CACHE_NOTIFY_PLACEHOLDER_SQE) {
    1465            0 :             CHK_RET(UpdateNotifyPlaceholderSqeForAlltoallv(sqePtr, sqeTypePtr, curTaskId, alltoallvMetadata, alltoallvSendRecvInfo, count, size));
    1466            0 :         } else if ((*sqeTypePtr) == SqeType::CACHE_WRITE_VALUE_PLACEHOLDER_SQE) {
    1467            0 :             CHK_RET(UpdateWritePlaceholderSqeForAlltoallv(sqePtr, sqeTypePtr, curTaskId, alltoallvMetadata, alltoallvSendRecvInfo, count, size));
    1468            0 :         } else if ((*sqeTypePtr) == SqeType::NOTIFY_SQE) {
    1469            0 :             CHK_RET(UpdateNotifySqeForAlltoallv(sqePtr, sqeTypePtr, curTaskId, alltoallvMetadata, alltoallvSendRecvInfo, count, size));
    1470            0 :         } else if ((*sqeTypePtr) == SqeType::WRITE_VALUE_SQE) {
    1471            0 :             CHK_RET(UpdateWriteValueSqeForAlltoallv(sqePtr, sqeTypePtr, curTaskId, alltoallvMetadata, alltoallvSendRecvInfo, count, size));
    1472            0 :         } else if ((*sqeTypePtr) == SqeType::MEMCPY_ASYNC_SQE) { // MemcpyRecord SQE
    1473            0 :             CHK_RET(UpdateMemcpyRecordSqeForAlltoallv(sqePtr, sqeTypePtr, curTaskId, alltoallvMetadata, alltoallvSendRecvInfo, count, size));
    1474            0 :         } else if ((*sqeTypePtr) == SqeType::CACHE_MEMCPY_RECORD_PLACEHOLDER_SQE) {
    1475            0 :             CHK_RET(UpdateMemcpyRecordPlaceholderSqeForAlltoallv(sqePtr, sqeTypePtr, curTaskId, alltoallvMetadata, alltoallvSendRecvInfo, count, size));
    1476              :         } else {
    1477            0 :             HCCL_ERROR("[OpUnfoldCacheEntry][UpdateTransferSqeForAlltoallv] invalid sqeType[%u]", *sqeTypePtr);
    1478            0 :             return HCCL_E_INTERNAL;
    1479              :         }
    1480              : 
    1481            0 :         return HCCL_SUCCESS;
    1482              :     }
    1483              : 
    1484            0 :     HcclResult OpUnfoldCacheEntry::GetTransferCountForAlltoallv(uint64_t& count, uint64_t& size, const uint8_t *sqePtr, const uint8_t *sqeTypePtr, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo) const {
    1485              :         // 获得notifyId或者signalAddr
    1486            0 :         bool isNotify = false;
    1487            0 :         uint32_t notifyId = 0;
    1488            0 :         uint64_t signalAddr = 0;
    1489            0 :         if ((*sqeTypePtr) == SqeType::NOTIFY_SQE) {
    1490              :             // 注意: 目前只有NotifyWait可能会生成cache-notify placeholder
    1491            0 :             const rtStarsNotifySqeV1_t *notifySqePtr = reinterpret_cast<const rtStarsNotifySqeV1_t *>(sqePtr);
    1492            0 :             CHK_PRT_RET(notifySqePtr->header.type != RT_STARS_SQE_TYPE_NOTIFY_WAIT,
    1493              :                 HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] header.type[%u]", notifySqePtr->header.type),
    1494              :                 HCCL_E_INTERNAL);
    1495              : 
    1496            0 :             notifyId = notifySqePtr->notify_id;
    1497            0 :             isNotify = true;
    1498            0 :         } else if ((*sqeTypePtr) == SqeType::CACHE_NOTIFY_PLACEHOLDER_SQE) {
    1499              :             // 注意: 目前只会存在对应NotifyWait的placeholder
    1500            0 :             const rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<const rtStarsPlaceHolderSqe_t *>(sqePtr);
    1501            0 :             CHK_PRT_RET(placeholderSqePtr->u.cache_notify_task_info.is_wait != 1,
    1502              :                 HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] is_wait[%u]",
    1503              :                     placeholderSqePtr->u.cache_notify_task_info.is_wait),
    1504              :                 HCCL_E_INTERNAL);
    1505              : 
    1506            0 :             notifyId = placeholderSqePtr->u.cache_notify_task_info.notify_id;
    1507            0 :             isNotify = true;
    1508            0 :         } else if ((*sqeTypePtr) == SqeType::WRITE_VALUE_SQE) {
    1509            0 :             const rtStarsWriteValueSqe_t *writeValueSqePtr = reinterpret_cast<const rtStarsWriteValueSqe_t *>(sqePtr);
    1510            0 :             const uint32_t lowAddr = writeValueSqePtr->write_addr_low;
    1511            0 :             const uint32_t highAddr = writeValueSqePtr->write_addr_high;
    1512            0 :             CombineUint32ToUint64(signalAddr, highAddr, lowAddr);
    1513            0 :             isNotify = false;
    1514            0 :         } else if ((*sqeTypePtr) == SqeType::CACHE_WRITE_VALUE_PLACEHOLDER_SQE) {
    1515            0 :             const rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<const rtStarsPlaceHolderSqe_t *>(sqePtr);
    1516            0 :             const uint32_t lowAddr = placeholderSqePtr->u.cache_write_value_task_info.write_addr_low;
    1517            0 :             const uint32_t highAddr = placeholderSqePtr->u.cache_write_value_task_info.write_addr_high;
    1518            0 :             CombineUint32ToUint64(signalAddr, highAddr, lowAddr);
    1519            0 :             isNotify = false;
    1520            0 :         } else if ((*sqeTypePtr) == SqeType::MEMCPY_ASYNC_SQE) {  // MemcpyRecord SQE
    1521            0 :             const rtStarsMemcpyAsyncSqe_t *memcpySqePtr = reinterpret_cast<const rtStarsMemcpyAsyncSqe_t *>(sqePtr);
    1522            0 :             const uint32_t lowAddr = memcpySqePtr->dst_addr_low;
    1523            0 :             const uint32_t highAddr = memcpySqePtr->dst_addr_high;
    1524            0 :             CombineUint32ToUint64(signalAddr, highAddr, lowAddr);
    1525            0 :             isNotify = false;
    1526            0 :         } else if ((*sqeTypePtr) == SqeType::CACHE_MEMCPY_RECORD_PLACEHOLDER_SQE) {
    1527            0 :             const rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<const rtStarsPlaceHolderSqe_t *>(sqePtr);
    1528            0 :             const uint32_t lowAddr = placeholderSqePtr->u.cache_memcpy_record_task_info.dst_addr_low;
    1529            0 :             const uint32_t highAddr = placeholderSqePtr->u.cache_memcpy_record_task_info.dst_addr_high;
    1530            0 :             CombineUint32ToUint64(signalAddr, highAddr, lowAddr);
    1531            0 :             isNotify = false;
    1532              :         }
    1533              :         else {
    1534            0 :             HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] invalid sqeType[%u]", *sqeTypePtr);
    1535            0 :             return HCCL_E_INTERNAL;
    1536              :         }
    1537            0 :         HCCL_INFO("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] notifyId[%u] signalAddr[0x%016llx]", notifyId, signalAddr);
    1538              : 
    1539              :         // 获得remoteRank
    1540            0 :         uint32_t remoteRank = 0;
    1541            0 :         bool recvFlag = false;
    1542            0 :         if (isNotify) {
    1543              :             // 校验notifyId一定在notifyid-rank map中
    1544            0 :             std::unordered_map<uint32_t, RankRflag>::const_iterator mapIter = alltoallvMetadata.notifyIdRankRflagMap.find(notifyId);
    1545            0 :             CHK_PRT_RET(mapIter == alltoallvMetadata.notifyIdRankRflagMap.cend(),
    1546              :                 HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] notifyId[%u] not in alltoallvMetadata", notifyId),
    1547              :                 HCCL_E_INTERNAL);
    1548              : 
    1549              :             // 根据notifyId获得remoteRank
    1550            0 :             remoteRank = mapIter->second.first;
    1551            0 :             recvFlag = mapIter->second.second;
    1552              :         } else {
    1553              :             // 校验signalAddr一定在signalAddr-rank map中
    1554            0 :             std::unordered_map<uint64_t, RankRflag>::const_iterator mapIter = alltoallvMetadata.signalAddrRankRflagMap.find(signalAddr);
    1555            0 :             CHK_PRT_RET(mapIter == alltoallvMetadata.signalAddrRankRflagMap.cend(),
    1556              :                 HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] signalAddr[%llu] not in alltoallvMetadata", signalAddr),
    1557              :                 HCCL_E_INTERNAL);
    1558              : 
    1559              :             // 根据signalAddr获得remoteRank
    1560            0 :             remoteRank = mapIter->second.first;
    1561            0 :             recvFlag = mapIter->second.second;
    1562              :         }
    1563            0 :         HCCL_INFO("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] remoteRank[%u] recvFlag[%u]", remoteRank, recvFlag);
    1564              : 
    1565              :         // 校验remoteRank (理论上一定不是localRank)
    1566            0 :         const uint32_t rankSize = alltoallvSendRecvInfo.sendOffsets.size();
    1567            0 :         CHK_PRT_RET(remoteRank >= rankSize,
    1568              :             HCCL_ERROR("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] remoteRank[%u] >= rankSize[%u]",
    1569              :                 remoteRank, rankSize),
    1570              :             HCCL_E_INTERNAL);
    1571              : 
    1572              :         // 根据remoteRank获得count和size
    1573            0 :         if (recvFlag) {
    1574            0 :             count = alltoallvSendRecvInfo.recvCounts[remoteRank];
    1575            0 :             size = count * SIZE_TABLE[alltoallvSendRecvInfo.recvType];
    1576            0 :             HCCL_INFO("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] recvCount[%llu] recvSize[%llu]", count, size);
    1577              :         } else {
    1578            0 :             count = alltoallvSendRecvInfo.sendCounts[remoteRank];
    1579            0 :             size = count * SIZE_TABLE[alltoallvSendRecvInfo.sendType];
    1580            0 :             HCCL_INFO("[OpUnfoldCacheEntry][GetTransferCountForAlltoallv] sendCount[%llu] sendSize[%llu]", count, size);
    1581              :         }
    1582              : 
    1583            0 :         return HCCL_SUCCESS;
    1584              :     }
    1585              : 
    1586            0 :     HcclResult OpUnfoldCacheEntry::UpdateNotifyPlaceholderSqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo, const uint64_t count, const uint64_t size) {
    1587              :         UNUSED_PARAM(size);
    1588              :         
    1589            0 :         rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<rtStarsPlaceHolderSqe_t *>(sqePtr);
    1590            0 :         if (count == 0) { // 只需要更新task id
    1591            0 :             placeholderSqePtr->header.taskId = curTaskId;
    1592              :         } else { // 需要将cache-notify placeholder转变成NotifyWait
    1593              :             // 保留original SQE中的相关信息
    1594            0 :             const uint16_t streamId = placeholderSqePtr->header.rtStreamId;
    1595            0 :             const uint8_t kernel_credit = placeholderSqePtr->u.cache_notify_task_info.kernel_credit;
    1596            0 :             const uint32_t timeout = placeholderSqePtr->u.cache_notify_task_info.timeout;
    1597            0 :             const uint32_t notifyId = placeholderSqePtr->u.cache_notify_task_info.notify_id;
    1598              : 
    1599              :             // 清空original SQE
    1600            0 :             CHK_SAFETY_FUNC_RET(memset_s(static_cast<void *>(sqePtr), HCCL_SQE_SIZE, 0, HCCL_SQE_SIZE));
    1601              : 
    1602              :             // 生成NotifyWait
    1603              :             // 参考aicpu_hccl_sqcqv1.cc中的AddOneNotifyWaitSqeV1
    1604            0 :             *sqeTypePtr = SqeType::NOTIFY_SQE;
    1605            0 :             rtStarsNotifySqeV1_t * const notifySqePtr = (rtStarsNotifySqeV1_t *)sqePtr;
    1606            0 :             notifySqePtr->header.type = RT_STARS_SQE_TYPE_NOTIFY_WAIT;
    1607            0 :             notifySqePtr->kernel_credit = kernel_credit;
    1608            0 :             notifySqePtr->timeout = timeout;
    1609            0 :             notifySqePtr->header.rtStreamId = streamId;
    1610            0 :             notifySqePtr->notify_id = notifyId;
    1611            0 :             notifySqePtr->header.taskId = curTaskId;
    1612              :         }
    1613              : 
    1614            0 :         return HCCL_SUCCESS;
    1615              :     }
    1616              : 
    1617            0 :     HcclResult OpUnfoldCacheEntry::UpdateWritePlaceholderSqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo, const uint64_t count, const uint64_t size) {
    1618              :         UNUSED_PARAM(size);
    1619              :         
    1620            0 :         rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<rtStarsPlaceHolderSqe_t *>(sqePtr);
    1621            0 :         if (count == 0) { // 只需要更新task id
    1622            0 :             placeholderSqePtr->header.taskId = curTaskId;
    1623              :         } else { // 需要将cache-write placeholder转变成WriteValue
    1624              :             // 保留original SQE中的相关信息
    1625            0 :             const uint16_t streamId = placeholderSqePtr->header.rtStreamId;
    1626            0 :             const uint32_t lowAddr = placeholderSqePtr->u.cache_write_value_task_info.write_addr_low;
    1627            0 :             const uint32_t highAddr = placeholderSqePtr->u.cache_write_value_task_info.write_addr_high;
    1628              : 
    1629              :             // 清空original SQE
    1630            0 :             CHK_SAFETY_FUNC_RET(memset_s(static_cast<void *>(sqePtr), HCCL_SQE_SIZE, 0, HCCL_SQE_SIZE));
    1631              : 
    1632              :             // 生成WriteValue
    1633              :             // 参考aicpu_hccl_sqcqv1.cc中的AddOneWriteValueRecordSqeV1
    1634            0 :             *sqeTypePtr = SqeType::WRITE_VALUE_SQE;
    1635            0 :             rtStarsWriteValueSqe_t * const writeValueSqePtr = (rtStarsWriteValueSqe_t *)sqePtr;
    1636            0 :             writeValueSqePtr->header.type = RT_STARS_SQE_TYPE_WRITE_VALUE;
    1637            0 :             writeValueSqePtr->header.rtStreamId = streamId;
    1638            0 :             writeValueSqePtr->header.taskId = curTaskId;
    1639            0 :             writeValueSqePtr->kernel_credit = RT_STARS_DEFAULT_KERNEL_CREDIT;
    1640            0 :             writeValueSqePtr->awsize = RT_STARS_WRITE_VALUE_SIZE_TYPE_32BIT;
    1641            0 :             writeValueSqePtr->write_value_part0 = 1U;
    1642            0 :             writeValueSqePtr->sub_type = RT_STARS_WRITE_VALUE_SUB_TYPE_NOTIFY_RECORD_IPC_NO_PCIE;
    1643            0 :             writeValueSqePtr->write_addr_low = lowAddr;
    1644            0 :             writeValueSqePtr->write_addr_high = highAddr;
    1645              :         }
    1646              : 
    1647            0 :         return HCCL_SUCCESS;
    1648              :     }
    1649              : 
    1650            0 :     HcclResult OpUnfoldCacheEntry::UpdateNotifySqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo, const uint64_t count, const uint64_t size) {
    1651              :         UNUSED_PARAM(size);
    1652              : 
    1653            0 :         rtStarsNotifySqeV1_t *notifySqePtr = reinterpret_cast<rtStarsNotifySqeV1_t *>(sqePtr);
    1654            0 :         if (count > 0) { // 只需要更新task id
    1655            0 :             notifySqePtr->header.taskId = curTaskId;
    1656              :         } else { // 需要将NotifyWait转变成cache-notify placeholder
    1657              :             // 保留original SQE中的相关信息
    1658            0 :             const uint16_t streamId = notifySqePtr->header.rtStreamId;
    1659            0 :             const uint8_t kernel_credit = notifySqePtr->kernel_credit;
    1660            0 :             const uint32_t timeout = notifySqePtr->timeout;
    1661            0 :             const uint32_t notifyId = notifySqePtr->notify_id;
    1662              : 
    1663              :             // 清空original SQE
    1664            0 :             CHK_SAFETY_FUNC_RET(memset_s(static_cast<void *>(sqePtr), HCCL_SQE_SIZE, 0, HCCL_SQE_SIZE));
    1665              : 
    1666              :             // 生成cache-notify placeholder
    1667              :             // 参考aicpu_hccl_sqcqv1.cc中的AddOneCacheNotifyWaitPlaceholderSqeV1
    1668            0 :             *sqeTypePtr = SqeType::CACHE_NOTIFY_PLACEHOLDER_SQE;
    1669            0 :             SetCachePlaceholderHeaderForAlltoallv(streamId, curTaskId, sqePtr);
    1670            0 :             rtStarsPlaceHolderSqe_t * const placeholderSqePtr = (rtStarsPlaceHolderSqe_t *)sqePtr;
    1671            0 :             placeholderSqePtr->u.cache_notify_task_info.is_wait = 1; // NotifyWait
    1672            0 :             placeholderSqePtr->u.cache_notify_task_info.kernel_credit = kernel_credit;
    1673            0 :             placeholderSqePtr->u.cache_notify_task_info.timeout = timeout;
    1674            0 :             placeholderSqePtr->u.cache_notify_task_info.notify_id = notifyId;
    1675              :         }
    1676              : 
    1677            0 :         return HCCL_SUCCESS;
    1678              :     }
    1679              : 
    1680            0 :     HcclResult OpUnfoldCacheEntry::UpdateWriteValueSqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo, const uint64_t count, const uint64_t size) {
    1681              :         UNUSED_PARAM(size);
    1682              : 
    1683            0 :         rtStarsWriteValueSqe_t *writeValueSqePtr = reinterpret_cast<rtStarsWriteValueSqe_t *>(sqePtr);
    1684            0 :         if (count > 0) { // 只需要更新task id
    1685            0 :             writeValueSqePtr->header.taskId = curTaskId;
    1686              :         } else { // 需要将WriteValue转变成cache-write placeholder
    1687              :             // 保留original SQE中的相关信息
    1688            0 :             const uint16_t streamId = writeValueSqePtr->header.rtStreamId;
    1689            0 :             const uint32_t lowAddr = writeValueSqePtr->write_addr_low;
    1690            0 :             const uint32_t highAddr = writeValueSqePtr->write_addr_high;
    1691              : 
    1692              :             // 清空original SQE
    1693            0 :             CHK_SAFETY_FUNC_RET(memset_s(static_cast<void *>(sqePtr), HCCL_SQE_SIZE, 0, HCCL_SQE_SIZE));
    1694              : 
    1695              :             // 生成cache-write placeholder
    1696              :             // 参考aicpu_hccl_sqcqv1.cc中的AddOneCacheWriteValuePlaceholderSqeV1
    1697            0 :             *sqeTypePtr = SqeType::CACHE_WRITE_VALUE_PLACEHOLDER_SQE;
    1698            0 :             SetCachePlaceholderHeaderForAlltoallv(streamId, curTaskId, sqePtr);
    1699            0 :             rtStarsPlaceHolderSqe_t * const placeholderSqePtr = (rtStarsPlaceHolderSqe_t *)sqePtr;
    1700            0 :             placeholderSqePtr->u.cache_write_value_task_info.write_addr_low = lowAddr;
    1701            0 :             placeholderSqePtr->u.cache_write_value_task_info.write_addr_high = highAddr;
    1702              :         }
    1703              : 
    1704            0 :         return HCCL_SUCCESS;
    1705              :     }
    1706              : 
    1707            0 :     HcclResult OpUnfoldCacheEntry::UpdateMemcpyRecordSqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo, const uint64_t count, const uint64_t size) {
    1708              :         UNUSED_PARAM(size);
    1709              : 
    1710            0 :         rtStarsMemcpyAsyncSqe_t *memcpySqePtr = reinterpret_cast<rtStarsMemcpyAsyncSqe_t *>(sqePtr);
    1711            0 :         if (count > 0) { // 只需要更新task id
    1712            0 :             memcpySqePtr->header.taskId = curTaskId;
    1713              :         } else { // 需要将MemcpyRecord转变成cache-memcpy-record placeholder
    1714              :             // 保留original SQE中的相关信息
    1715            0 :             const uint16_t streamId = memcpySqePtr->header.rtStreamId;
    1716            0 :             const uint8_t kernelCredit = memcpySqePtr->kernel_credit;
    1717            0 :             const uint32_t opCode = memcpySqePtr->opcode;
    1718            0 :             const uint32_t length = memcpySqePtr->length;
    1719            0 :             const uint32_t srcAddrLow = memcpySqePtr->src_addr_low;
    1720            0 :             const uint32_t srcAddrHigh = memcpySqePtr->src_addr_high;
    1721            0 :             const uint32_t dstAddrLow = memcpySqePtr->dst_addr_low;
    1722            0 :             const uint32_t dstAddrHigh = memcpySqePtr->dst_addr_high;
    1723            0 :             const uint32_t partId = memcpySqePtr->partid;
    1724            0 :             const uint8_t linkType = memcpySqePtr->linkType;
    1725            0 :             const uint32_t qos = memcpySqePtr->qos;
    1726              : 
    1727              :             // 清空original SQE
    1728            0 :             CHK_SAFETY_FUNC_RET(memset_s(static_cast<void *>(sqePtr), HCCL_SQE_SIZE, 0, HCCL_SQE_SIZE));
    1729              : 
    1730              :             // 生成cache-memcpy-record placeholder
    1731              :             // 参考aicpu_hccl_sqcqv1.cc中的AddOneCacheMemcpyRecordPlaceholderSqeV1
    1732            0 :             *sqeTypePtr = SqeType::CACHE_MEMCPY_RECORD_PLACEHOLDER_SQE;
    1733            0 :             SetCachePlaceholderHeaderForAlltoallv(streamId, curTaskId, sqePtr);
    1734            0 :             rtStarsPlaceHolderSqe_t * const placeholderSqePtr = (rtStarsPlaceHolderSqe_t *)sqePtr;
    1735            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.kernel_credit = kernelCredit;
    1736            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.opcode = opCode;
    1737            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.length = length;
    1738            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.src_addr_low = srcAddrLow;
    1739            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.src_addr_high = srcAddrHigh;
    1740            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.dst_addr_low = dstAddrLow;
    1741            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.dst_addr_high = dstAddrHigh;
    1742            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.partid = partId;
    1743            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.linkType = linkType;
    1744            0 :             placeholderSqePtr->u.cache_memcpy_record_task_info.qos = qos;
    1745              :         }
    1746              : 
    1747            0 :         return HCCL_SUCCESS;
    1748              :     }
    1749              : 
    1750            0 :     HcclResult OpUnfoldCacheEntry::UpdateMemcpyRecordPlaceholderSqeForAlltoallv(uint8_t *sqePtr, uint8_t *sqeTypePtr, const uint16_t curTaskId, const AlltoallvMetadata& alltoallvMetadata, const AlltoallvSendRecvInfo& alltoallvSendRecvInfo, const uint64_t count, const uint64_t size) {
    1751              :         UNUSED_PARAM(size);
    1752              :         
    1753            0 :         rtStarsPlaceHolderSqe_t *placeholderSqePtr = reinterpret_cast<rtStarsPlaceHolderSqe_t *>(sqePtr);
    1754            0 :         if (count == 0) { // 只需要更新task id
    1755            0 :             placeholderSqePtr->header.taskId = curTaskId;
    1756              :         } else { // 需要将cache-memcpy-record placeholder转变成MemcpyRecord
    1757              :             // 保留original SQE中的相关信息
    1758            0 :             const uint16_t streamId = placeholderSqePtr->header.rtStreamId;
    1759            0 :             const uint8_t kernelCredit = placeholderSqePtr->u.cache_memcpy_record_task_info.kernel_credit;
    1760            0 :             const uint32_t opCode = placeholderSqePtr->u.cache_memcpy_record_task_info.opcode;
    1761            0 :             const uint32_t length = placeholderSqePtr->u.cache_memcpy_record_task_info.length;
    1762            0 :             const uint32_t srcAddrLow = placeholderSqePtr->u.cache_memcpy_record_task_info.src_addr_low;
    1763            0 :             const uint32_t srcAddrHigh = placeholderSqePtr->u.cache_memcpy_record_task_info.src_addr_high;
    1764            0 :             const uint32_t dstAddrLow = placeholderSqePtr->u.cache_memcpy_record_task_info.dst_addr_low;
    1765            0 :             const uint32_t dstAddrHigh = placeholderSqePtr->u.cache_memcpy_record_task_info.dst_addr_high;
    1766            0 :             const uint32_t partId = placeholderSqePtr->u.cache_memcpy_record_task_info.partid;
    1767            0 :             const uint32_t linkType = placeholderSqePtr->u.cache_memcpy_record_task_info.linkType;
    1768            0 :             const uint32_t qos = placeholderSqePtr->u.cache_memcpy_record_task_info.qos;
    1769              : 
    1770              :             // 清空original SQE
    1771            0 :             CHK_SAFETY_FUNC_RET(memset_s(static_cast<void *>(sqePtr), HCCL_SQE_SIZE, 0, HCCL_SQE_SIZE));
    1772              : 
    1773              :             // 生成MemcpyRecord
    1774              :             // 参考aicpu_hccl_sqcqv1.cc中的AddOneMemcpySqeV1
    1775            0 :             *sqeTypePtr = SqeType::MEMCPY_ASYNC_SQE;
    1776            0 :             rtStarsMemcpyAsyncSqe_t * const memcpySqePtr = (rtStarsMemcpyAsyncSqe_t *)sqePtr;
    1777            0 :             memcpySqePtr->header.type = RT_STARS_SQE_TYPE_SDMA;
    1778            0 :             memcpySqePtr->header.rtStreamId = streamId;
    1779            0 :             memcpySqePtr->header.taskId = curTaskId;
    1780            0 :             memcpySqePtr->kernel_credit = kernelCredit;
    1781            0 :             memcpySqePtr->opcode = opCode;
    1782            0 :             memcpySqePtr->length = length;
    1783            0 :             memcpySqePtr->src_addr_low = srcAddrLow;
    1784            0 :             memcpySqePtr->src_addr_high = srcAddrHigh;
    1785            0 :             memcpySqePtr->dst_addr_low = dstAddrLow;
    1786            0 :             memcpySqePtr->dst_addr_high = dstAddrHigh;
    1787            0 :             memcpySqePtr->sssv = 1U;
    1788            0 :             memcpySqePtr->dssv = 1U;
    1789            0 :             memcpySqePtr->sns = 1U;
    1790            0 :             memcpySqePtr->dns = 1U;
    1791            0 :             memcpySqePtr->qos = 6; // 6 is HCCL QoS
    1792            0 :             memcpySqePtr->partid = partId;
    1793            0 :             memcpySqePtr->linkType = linkType;
    1794            0 :             memcpySqePtr->qos = qos;
    1795              :         }
    1796              : 
    1797            0 :         return HCCL_SUCCESS;
    1798              :     }
    1799              : 
    1800            0 :     void OpUnfoldCacheEntry::SetCachePlaceholderHeaderForAlltoallv(const uint16_t streamId, const uint16_t taskId, uint8_t *sqePtr) {
    1801              :         // 参考aicpu_hccl_sqcqv1.cc中的SetCachePlaceholderHeaderV1
    1802              :         // 注意: 不直接调用SetCachePlaceholderHeaderV1, 避免libhccl_plf对platform/task/rtsq_interact产生依赖
    1803              :         // 目前rtsq_interact只编译到ccl_kernel_plf与ccl_kernel_plf_a中
    1804            0 :         rtStarsPlaceHolderSqe_t *placeholderSqePtr = (rtStarsPlaceHolderSqe_t*)sqePtr;
    1805            0 :         placeholderSqePtr->header.type = RT_STARS_SQE_TYPE_PLACE_HOLDER;
    1806            0 :         placeholderSqePtr->header.ie = 0U;
    1807            0 :         placeholderSqePtr->header.preP = 0U; // 不需要STARS_FW参与任何预处理
    1808            0 :         placeholderSqePtr->header.postP = 0U;
    1809            0 :         placeholderSqePtr->header.wrCqe = 0U;
    1810            0 :         placeholderSqePtr->header.reserved = 0U;
    1811              :         // NOTE: task type在preP阶段被TASK_FW使用, 而此placeholder无preP阶段, 设置为RT_TASK_TYPE_FLIP不影响功能
    1812            0 :         placeholderSqePtr->header.blockDim = RT_TASK_TYPE_FLIP;
    1813            0 :         placeholderSqePtr->header.rtStreamId = streamId;
    1814            0 :         placeholderSqePtr->header.taskId = taskId;
    1815            0 :         placeholderSqePtr->kernel_credit = RT_STARS_DEFAULT_KERNEL_CREDIT;
    1816            0 :         return;
    1817              :     }
    1818              : 
    1819              : }; // namespace hccl
        

Generated by: LCOV version 2.0-1