LCOV - code coverage report
Current view: top level - legacy/ascend910/platform/typical - send_recv_executor.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 33.2 % 503 167
Test Date: 2026-08-04 10:52:23 Functions: 51.6 % 31 16

            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 "send_recv_executor.h"
      12              : #include "device_capacity.h"
      13              : #include "dispatcher_pub.h"
      14              : #include "adapter_rts.h"
      15              : #include "externalinput_pub.h"
      16              : 
      17              : namespace hccl {
      18              : constexpr u32 HCCL_POLL_CQ_DEPTH = 32;
      19              : constexpr s32 HCCL_POLL_CQ_ONETIME = 1;
      20              : constexpr u32 HCCL_POLL_CQ_INTERVAL = 100;
      21              : constexpr u64 MAX_RDMA_WQE_SIZE = 2ULL * 1024 * 1024 * 1024; // RDMA最大WQE限制, 2G限制是RDMA导致
      22              : 
      23          172 : struct MrInfoT AscendMrInfo2MrInfo(AscendMrInfo* ascendMrInfo)
      24              : {
      25          172 :     struct MrInfoT innerMrInfo = {};
      26          172 :     innerMrInfo.addr = reinterpret_cast<void*>(ascendMrInfo->addr);
      27          172 :     innerMrInfo.size = ascendMrInfo->size;
      28          172 :     innerMrInfo.lkey = ascendMrInfo->key;
      29          172 :     return innerMrInfo;
      30              : }
      31              : 
      32            0 : SendRecvExecutor::SendRecvExecutor(HcclRtStream stream, QpHandle qpHandle,
      33              :     const struct MrInfoT& localWindowMem, const struct MrInfoT& remoteWindowMem,
      34              :     const struct MrInfoT& localSyncMemPrepare, const struct MrInfoT& localSyncMemDone, const struct MrInfoT& localSyncMemAck,
      35              :     const struct MrInfoT& remoteSyncMemPrepare, const struct MrInfoT& remoteSyncMemDone, const struct MrInfoT& remoteSyncMemAck,
      36            0 :     u32 immData, const u64 chunkNum)
      37            0 :     : stream_(stream), qpHandle_(qpHandle), localWindowMem_(localWindowMem), remoteWindowMem_(remoteWindowMem),
      38            0 :     localSyncMemPrepare_(localSyncMemPrepare), localSyncMemDone_(localSyncMemDone), localSyncMemAck_(localSyncMemAck),
      39            0 :     remoteSyncMemPrepare_(remoteSyncMemPrepare), remoteSyncMemDone_(remoteSyncMemDone),
      40            0 :     remoteSyncMemAck_(remoteSyncMemAck), immData_(immData), chunkSize_(chunkNum), 
      41            0 :     notifyWaitMode_(SyncMode::DEFAULT_TIMEWAITSYNCMODE)
      42              : {
      43            0 : }
      44              : 
      45           19 : SendRecvExecutor::SendRecvExecutor(HcclRtStream stream, QpHandle qpHandle, AscendSendRecvLinkInfo* linkInfo)
      46           19 :     : stream_(stream), qpHandle_(qpHandle),
      47           19 :     localSyncMemPrepare_(AscendMrInfo2MrInfo(linkInfo->localSyncMemPrepare)),
      48           19 :     localSyncMemDone_(AscendMrInfo2MrInfo(linkInfo->localSyncMemDone)), 
      49           19 :     localSyncMemAck_(AscendMrInfo2MrInfo(linkInfo->localSyncMemAck)),
      50           19 :     remoteSyncMemPrepare_(AscendMrInfo2MrInfo(linkInfo->remoteSyncMemPrepare)),
      51           19 :     remoteSyncMemDone_(AscendMrInfo2MrInfo(linkInfo->remoteSyncMemDone)),
      52           19 :     remoteSyncMemAck_(AscendMrInfo2MrInfo(linkInfo->remoteSyncMemAck)),
      53           19 :     immData_(linkInfo->immData), wqePerDoorBell_(linkInfo->wqePerDoorbell)
      54              : {
      55           19 : }
      56              : 
      57           10 : SendRecvExecutor::SendRecvExecutor(HcclRtStream stream, QpHandle qpHandle, AscendSendLinkInfo* linkInfo)
      58           10 :     : stream_(stream), qpHandle_(qpHandle),
      59           10 :     localSyncMemAck_(AscendMrInfo2MrInfo(linkInfo->localSyncMemAck)),
      60           10 :     wqePerDoorBell_(linkInfo->wqePerDoorbell),
      61           10 :     remoteNotifyValueMem_(AscendMrInfo2MrInfo(linkInfo->remoteNotifyValueMem))
      62           10 : {}
      63              : 
      64           19 : SendRecvExecutor::SendRecvExecutor(HcclRtStream stream, QpHandle qpHandle, AscendMrInfo* localSyncMemDone, 
      65           19 :     AscendMrInfo* remoteSyncMemAck)
      66           19 :     : stream_(stream), qpHandle_(qpHandle),
      67           19 :     localSyncMemDone_(AscendMrInfo2MrInfo(localSyncMemDone)), 
      68           19 :     remoteSyncMemAck_(AscendMrInfo2MrInfo(remoteSyncMemAck))
      69              : {
      70           19 : }
      71              : 
      72           48 : SendRecvExecutor::~SendRecvExecutor()
      73           48 : {}
      74              : 
      75           19 : HcclResult SendRecvExecutor::Init()
      76              : {
      77           19 :     CHK_RET(hrtGetNotifySize(notifySize_));
      78           19 :     if (GetExternalInputHcclExecTimeoutSet() != HcclExecTimeoutSet::HCCL_EXEC_TIMEOUT_NOT_SET) {
      79            0 :         notifyWaitMode_ = SyncMode::CONFIGURABLE_TIMEWAITSYNCMODE;
      80              :     }
      81           19 :     CHK_RET(TypicalSyncMem::GetInstance().GetNotifyHandle(reinterpret_cast<u64>(localSyncMemPrepare_.addr),
      82              :         prepareNotify_));
      83           19 :     CHK_PTR_NULL(prepareNotify_);
      84              : 
      85           19 :     CHK_RET(TypicalSyncMem::GetInstance().GetNotifyHandle(reinterpret_cast<u64>(localSyncMemAck_.addr),
      86              :         ackNotify_));
      87           19 :     CHK_PTR_NULL(ackNotify_);
      88              : 
      89           19 :     CHK_RET(TypicalSyncMem::GetInstance().GetNotifyHandle(reinterpret_cast<u64>(localSyncMemDone_.addr),
      90              :         doneNotify_));
      91           19 :     CHK_PTR_NULL(doneNotify_);
      92              : 
      93           19 :     CHK_RET(TypicalSyncMem::GetInstance().GetNotifySrcMem(notifySrcMem_));
      94           19 :     CHK_PTR_NULL(notifySrcMem_.addr);
      95              : 
      96           19 :     HCCL_INFO("[SendRecvExecutor][Init] SendRecvExecutor init success! notifySize[%u], notifyWaitMode[%d], "\
      97              :         "prepareNotify[%p], ackNotify[%p], doneNotify[%p], notifySrcMem addr[%p], localWindowMem addr[%p], "\
      98              :         "remoteWindowMem addr[%p], remoteSyncMemPrepare addr[%p], remoteSyncMemDone addr[%p], "\
      99              :         "remoteSyncMemAck addr[%p], immData[%u], wqePerDoorBell[%u]",
     100              :         notifySize_, notifyWaitMode_, prepareNotify_, ackNotify_, doneNotify_,
     101              :         notifySrcMem_.addr, localWindowMem_.addr, remoteWindowMem_.addr,
     102              :         remoteSyncMemPrepare_.addr, remoteSyncMemDone_.addr, remoteSyncMemAck_.addr, immData_,
     103              :         wqePerDoorBell_);
     104           19 :     return HCCL_SUCCESS;
     105              : }
     106              : 
     107           19 : HcclResult SendRecvExecutor::WaitPutInit()
     108              : {
     109           19 :     CHK_RET(hrtGetNotifySize(notifySize_));
     110           19 :     if (GetExternalInputHcclExecTimeoutSet() != HcclExecTimeoutSet::HCCL_EXEC_TIMEOUT_NOT_SET) {
     111            0 :         notifyWaitMode_ = SyncMode::CONFIGURABLE_TIMEWAITSYNCMODE;
     112              :     }
     113           19 :     CHK_RET(TypicalSyncMem::GetInstance().GetNotifyHandle(reinterpret_cast<u64>(localSyncMemDone_.addr),
     114              :         doneNotify_));
     115           19 :     CHK_PTR_NULL(doneNotify_);
     116              : 
     117           19 :     CHK_RET(TypicalSyncMem::GetInstance().GetNotifySrcMem(notifySrcMem_));
     118           19 :     CHK_PTR_NULL(notifySrcMem_.addr);
     119              : 
     120           19 :     HCCL_INFO("[SendRecvExecutor][WaitPutInit] SendRecvExecutor init success! notifySize[%u], notifyWaitMode[%d], "\
     121              :         "prepareNotify[%p], ackNotify[%p], doneNotify[%p], notifySrcMem addr[%p], localWindowMem addr[%p], "\
     122              :         "remoteWindowMem addr[%p], remoteSyncMemPrepare addr[%p], remoteSyncMemDone addr[%p], "\
     123              :         "remoteSyncMemAck addr[%p], immData[%u], wqePerDoorBell[%u]",
     124              :         notifySize_, notifyWaitMode_, prepareNotify_, ackNotify_, doneNotify_,
     125              :         notifySrcMem_.addr, localWindowMem_.addr, remoteWindowMem_.addr,
     126              :         remoteSyncMemPrepare_.addr, remoteSyncMemDone_.addr, remoteSyncMemAck_.addr, immData_,
     127              :         wqePerDoorBell_);
     128           19 :     return HCCL_SUCCESS;
     129              : }
     130              : 
     131            0 : HcclResult SendRecvExecutor::IsOverlappedWithWinMem(void* userPtr, u64 userMemSize, bool& isOverlapped)
     132              : {
     133            0 :     if (userPtr >= localWindowMem_.addr &&
     134            0 :         static_cast<u8*>(userPtr) + userMemSize <= static_cast<u8*>(localWindowMem_.addr) + localWindowMem_.size) {
     135            0 :         isOverlapped = true;
     136            0 :     } else if (static_cast<u8*>(userPtr) + userMemSize <= static_cast<u8*>(localWindowMem_.addr) ||
     137            0 :         static_cast<u8*>(userPtr) >= static_cast<u8*>(localWindowMem_.addr) + localWindowMem_.size){
     138            0 :         isOverlapped = false;
     139              :     } else {
     140            0 :         HCCL_ERROR("[SendRecvExecutor][IsOverlappedWithWinMem] The user mem addr or size is illegal. "\
     141              :         "The addr of user mem is %p, user mem size is %llu. The addr of window mem is %p, window mem size is %llu.",
     142              :         userPtr, userMemSize, localWindowMem_.addr, localWindowMem_.size);
     143            0 :         return HCCL_E_PARA;
     144              :     }
     145            0 :     return HCCL_SUCCESS;
     146              : }
     147              : 
     148            0 : HcclResult SendRecvExecutor::Send(void* inputPtr, u64 count, HcclDataType dataType)
     149              : {
     150            0 :     HcclResult ret = HCCL_SUCCESS;
     151            0 :     void *windowsMemPtr = localWindowMem_.addr;
     152            0 :     uint32_t unitSize = SIZE_TABLE[dataType];
     153            0 :     uint8_t *curInputPtr = static_cast<uint8_t *>(inputPtr);
     154            0 :     CHK_PTR_NULL(curInputPtr);
     155            0 :     uint64_t inputOffset = 0;
     156            0 :     uint64_t countLeft = count;
     157            0 :     Stream streamObj(stream_);
     158              :     // 判断userMem是否是windowMem的一部分
     159            0 :     bool isOverlapped = false;
     160            0 :     CHK_RET(IsOverlappedWithWinMem(inputPtr, count * unitSize, isOverlapped));
     161              : 
     162            0 :     u64 maxCountPerLoop = localWindowMem_.size / unitSize;
     163              : 
     164            0 :     while (countLeft > 0) {
     165              :         // 防止数据回绕
     166            0 :         CHK_PRT_RET(countLeft > count, HCCL_ERROR("[SendRecvExecutor][Send] countLeft is underflow."),
     167              :             HCCL_E_PARA);
     168            0 :         curInputPtr += inputOffset;
     169            0 :         HCCL_DEBUG("[SendRecvExecutor]][Send] InputOffset[%llu]", inputOffset);
     170            0 :         u64 curCount = (countLeft > maxCountPerLoop) ? maxCountPerLoop : countLeft;
     171            0 :         u64 curSize = curCount * unitSize;
     172            0 :         HCCL_DEBUG("[SendRecvExecutor][Send] curInputPtr[%p], curCount[%llu], curSize[%llu]", curInputPtr,
     173              :             curCount, curSize);
     174            0 :         DeviceMem inMem(curInputPtr, curSize);
     175              :         // 如果userMem是否是windowMem的一部分,跳过D2D拷
     176            0 :         if (isOverlapped) {
     177            0 :             ret = SendRun(inMem);
     178              :         } else {
     179            0 :             DeviceMem inWindowMem(windowsMemPtr, curSize);
     180            0 :             CHK_RET(MemcpyAsyncD2D(inWindowMem, inMem, streamObj));
     181            0 :             ret = SendRun(inWindowMem);
     182            0 :         }
     183            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     184              :             HCCL_ERROR("[SendRecvExecutor][Send] errNo[0x%016llx] send error, ptr[%p], count[%llu], dataType[%d]",
     185              :             HCCL_ERROR_CODE(ret), windowsMemPtr, curCount, dataType), ret);
     186            0 :         CHK_PRT_RET((curCount == 0), HCCL_ERROR("[SendRecvExecutor]][Send]In OP_BASE curCount is zero"), HCCL_E_PARA);
     187            0 :         countLeft -= curCount;
     188            0 :         inputOffset = curSize;
     189            0 :     }
     190            0 :     return HCCL_SUCCESS;
     191            0 : }
     192              : 
     193            0 : HcclResult SendRecvExecutor::Receive(void* outputPtr, u64 count, HcclDataType dataType)
     194              : {
     195            0 :     HcclResult ret = HCCL_SUCCESS;
     196            0 :     void *windowsMemPtr = localWindowMem_.addr;
     197            0 :     uint32_t unitSize = SIZE_TABLE[dataType];
     198            0 :     uint8_t *curOutPutPtr = static_cast<uint8_t *>(outputPtr);
     199            0 :     CHK_PTR_NULL(curOutPutPtr);
     200            0 :     uint64_t outputOffset = 0;
     201            0 :     uint64_t countLeft = count;
     202            0 :     Stream streamObj(stream_);
     203            0 :     u64 maxCountPerLoop = localWindowMem_.size / unitSize;
     204              : 
     205            0 :     while (countLeft > 0) {
     206              :         // 防止数据回绕
     207            0 :         CHK_PRT_RET(countLeft > count, HCCL_ERROR("[SendRecvExecutor][Receive] countLeft is underflow."),
     208              :             HCCL_E_PARA);
     209            0 :         curOutPutPtr += outputOffset;
     210            0 :         HCCL_INFO("[SendRecvExecutor][Receive] inputOffset[%llu]", outputOffset);
     211            0 :         u64 curCount = (countLeft > maxCountPerLoop) ? maxCountPerLoop : countLeft;
     212            0 :         u64 curSize = curCount * unitSize; // 单位 byte
     213            0 :         HCCL_INFO("[SendRecvExecutor][Receive] curOutPutPtr[%p], curCount[%llu], curSize[%llu]", curOutPutPtr,
     214              :             curCount, curSize);
     215            0 :         DeviceMem outMem(curOutPutPtr, curSize);
     216            0 :         DeviceMem outWindowMem(windowsMemPtr, curSize);
     217            0 :         if (immData_ != 0) {
     218            0 :             ret = ReceiveRunByPollCq(outWindowMem);
     219              :         } else {
     220            0 :             ret = ReceiveRun(outWindowMem);
     221              :         }
     222            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     223              :             HCCL_ERROR("[SendRecvExecutor][Receive] errNo[0x%016llx] Receive error, ptr[%p], count[%llu], dataType[%d]",
     224              :             HCCL_ERROR_CODE(ret), windowsMemPtr, curCount, dataType), ret);
     225            0 :         CHK_RET(MemcpyAsyncD2D(outMem, outWindowMem, streamObj));
     226            0 :         CHK_PRT_RET((curCount == 0), HCCL_ERROR("[SendRecvExecutor][Receive]In OP_BASE curCount is zero"), HCCL_E_PARA);
     227            0 :         countLeft -= curCount;
     228            0 :         outputOffset = curSize;
     229            0 :     }
     230            0 :     return HCCL_SUCCESS;
     231            0 : }
     232              : 
     233            0 : HcclResult SendRecvExecutor::Put(void* inputPtr, u64 count, HcclDataType dataType)
     234              : {
     235            0 :     HcclResult ret = HCCL_SUCCESS;
     236            0 :     void *windowsMemPtr = localWindowMem_.addr;
     237            0 :     uint32_t unitSize = SIZE_TABLE[dataType];
     238            0 :     uint8_t *curInputPtr = static_cast<uint8_t *>(inputPtr);
     239            0 :     CHK_PTR_NULL(curInputPtr);
     240            0 :     uint64_t inputOffset = 0;
     241            0 :     uint64_t countLeft = count;
     242            0 :     Stream streamObj(stream_);
     243              :     // 判断userMem是否是windowMem的一部分
     244            0 :     bool isOverlapped = false;
     245            0 :     CHK_RET(IsOverlappedWithWinMem(inputPtr, count * unitSize, isOverlapped));
     246              :  
     247            0 :     u64 maxCountPerLoop = localWindowMem_.size / unitSize;
     248              :  
     249            0 :     while (countLeft > 0) {
     250              :         // 防止数据回绕
     251            0 :         CHK_PRT_RET(countLeft > count, HCCL_ERROR("[SendRecvExecutor][Put] countLeft is underflow."),
     252              :             HCCL_E_PARA);
     253            0 :         curInputPtr += inputOffset;
     254            0 :         HCCL_DEBUG("[SendRecvExecutor][Put] InputOffset[%llu]", inputOffset);
     255            0 :         u64 curCount = (countLeft > maxCountPerLoop) ? maxCountPerLoop : countLeft;
     256            0 :         u64 curSize = curCount * unitSize;
     257            0 :         HCCL_DEBUG("[SendRecvExecutor][Put] curInputPtr[%p], curCount[%llu], curSize[%llu]", curInputPtr,
     258              :             curCount, curSize);
     259            0 :         DeviceMem inMem(curInputPtr, curSize);
     260              :         // 如果userMem是否是windowMem的一部分,跳过D2D拷贝
     261            0 :         if (isOverlapped) {
     262            0 :             ret = PutRun(inMem);
     263              :         } else {
     264            0 :             DeviceMem inWindowMem(windowsMemPtr, curSize);
     265            0 :             CHK_RET(MemcpyAsyncD2D(inWindowMem, inMem, streamObj));
     266            0 :             ret = PutRun(inWindowMem);
     267            0 :         }
     268            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     269              :             HCCL_ERROR("[SendRecvExecutor][Put] errNo[0x%016llx] send error, ptr[%p], count[%llu], dataType[%d]",
     270              :             HCCL_ERROR_CODE(ret), windowsMemPtr, curCount, dataType), ret);
     271            0 :         CHK_PRT_RET((curCount == 0), HCCL_ERROR("[SendRecvExecutor]][Put]In OP_BASE curCount is zero"), HCCL_E_PARA);
     272            0 :         countLeft -= curCount;
     273            0 :         inputOffset = curSize;
     274            0 :     }
     275            0 :     return HCCL_SUCCESS;
     276            0 : }
     277              : 
     278            0 : HcclResult SendRecvExecutor::SendRun(DeviceMem& sendBuffer)
     279              : {
     280            0 :     HcclResult ret = HCCL_SUCCESS;
     281            0 :     if (!sendBuffer) {
     282            0 :         HCCL_ERROR("[SendRecvExecutor][SendRun] Send buffer ptr is null.");
     283            0 :         return HCCL_E_PTR;
     284              :     }
     285            0 :     u64 sizePerRound = 0;
     286            0 :     u64 sizePerSlice = chunkSize_;
     287            0 :     u64 length = sendBuffer.size();
     288            0 :     u64 offset = 0;
     289              : 
     290            0 :     for (u64 sizeResidue = length; sizeResidue > 0; sizeResidue -= sizePerRound) {
     291              :         // 防止数据回绕
     292            0 :         CHK_PRT_RET(sizeResidue > length, HCCL_ERROR("[SendRecvExecutor][SendRun] countLeft is underflow."),
     293              :             HCCL_E_PARA);
     294            0 :         ret = WaitSignal(prepareNotify_);
     295            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][SendRun] Wait prepare failed"), ret);
     296            0 :         offset += sizePerRound;
     297            0 :         sizePerRound = (sizeResidue > sizePerSlice) ? sizePerSlice : sizeResidue;
     298            0 :         void* localAddr = static_cast<u8 *>(localWindowMem_.addr) + offset;
     299            0 :         HCCL_INFO("rx async inputmem's offset[%llu] size[%llu]", offset, sizePerRound);
     300              : 
     301            0 :         ret = PayLoad(localAddr, offset, sizePerRound);
     302            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][SendRun] Send data fail with offset[%llu] "\
     303              :             "size[%llu] failed", offset, sizePerRound), ret);
     304              : 
     305            0 :         if(immData_ == 0) {
     306            0 :             ret = RecordNotify(remoteSyncMemDone_.addr, remoteSyncMemDone_.lkey,
     307            0 :                 notifySrcMem_.addr, notifySrcMem_.lkey, notifySize_);
     308            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][SendRun] Record done failed"), ret);
     309              :         }
     310              : 
     311            0 :         ret = WaitSignal(ackNotify_);
     312            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][SendRun] Wait ack failed"), ret);
     313              :     }
     314            0 :     return HCCL_SUCCESS;
     315              : }
     316              : 
     317            0 : HcclResult SendRecvExecutor::PutRun(DeviceMem& putBuffer)
     318              : {
     319            0 :     HcclResult ret = HCCL_SUCCESS;
     320            0 :     if (!putBuffer) {
     321            0 :         HCCL_ERROR("[SendRecvExecutor][PutRun] Send buffer ptr is null.");
     322            0 :         return HCCL_E_PTR;
     323              :     }
     324            0 :     u64 sizePerRound = 0;
     325            0 :     u64 sizePerSlice = chunkSize_;
     326            0 :     u64 length = putBuffer.size();
     327            0 :     u64 offset = 0;
     328              :  
     329            0 :     for (u64 sizeResidue = length; sizeResidue > 0; sizeResidue -= sizePerRound) {
     330              :         // 防止数据回绕
     331            0 :         CHK_PRT_RET(sizeResidue > length, HCCL_ERROR("[SendRecvExecutor][PutRun] countLeft is underflow."),
     332              :             HCCL_E_PARA);
     333            0 :         offset += sizePerRound;
     334            0 :         sizePerRound = (sizeResidue > sizePerSlice) ? sizePerSlice : sizeResidue;
     335            0 :         void* localAddr = static_cast<u8 *>(localWindowMem_.addr) + offset;
     336            0 :         HCCL_INFO("rx async inputmem's offset[%llu] size[%llu]", offset, sizePerRound);
     337              :  
     338            0 :         ret = PayLoad(localAddr, offset, sizePerRound);
     339            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][PutRun] Send data fail with offset[%llu] "\
     340              :             "size[%llu] failed", offset, sizePerRound), ret);
     341              :  
     342            0 :         if(immData_ == 0) {
     343            0 :             ret = RecordNotify(remoteSyncMemDone_.addr, remoteSyncMemDone_.lkey,
     344            0 :                 notifySrcMem_.addr, notifySrcMem_.lkey, notifySize_);
     345            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][PutRun] Record done failed"), ret);
     346              :         }
     347              :  
     348            0 :         ret = WaitSignal(ackNotify_);
     349            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][PutRun] Wait ack failed"), ret);
     350              :     }
     351            0 :     return HCCL_SUCCESS;
     352              : }
     353              :  
     354              : 
     355            0 : HcclResult SendRecvExecutor::PollCq()
     356              : {
     357            0 :     auto startTime = std::chrono::steady_clock::now();
     358            0 :     auto timeout = std::chrono::seconds(static_cast<s32>(GetExternalInputHcclExecTimeOut()));
     359              : 
     360              :     struct ibv_wc wc[HCCL_POLL_CQ_DEPTH];
     361            0 :     while ((std::chrono::steady_clock::now() - startTime) < timeout) {
     362            0 :         s32 num = hrtRaPollCq(qpHandle_, false, HCCL_POLL_CQ_ONETIME, wc);
     363            0 :         if (num < 0) {
     364            0 :             HCCL_ERROR("[SendRecvExecutor][PollCq] Poll Cq error, return [%d]", num);
     365            0 :             return HCCL_E_INTERNAL;
     366            0 :         } else if (num < HCCL_POLL_CQ_ONETIME) {
     367            0 :             SaluSleep(HCCL_POLL_CQ_INTERVAL);
     368            0 :             continue;
     369              :         }
     370            0 :         for (int i = 0; i < num; i++) {
     371            0 :             if (wc[i].status != 0) {
     372            0 :                 HCCL_ERROR("rdma poll tag sq failed, cqe status[%u]", wc[i].status);
     373            0 :                 return HCCL_E_INTERNAL;
     374              :             }
     375              :         }
     376            0 :         return HCCL_SUCCESS;
     377              :     }
     378            0 :     HCCL_ERROR("[SendRecvExecutor][PollCq] Wait Cqe timeOut[%d] s", GetExternalInputHcclLinkTimeOut());
     379            0 :     return HCCL_E_TIMEOUT;
     380              : }
     381              : 
     382            0 : HcclResult SendRecvExecutor::ReceiveRunByPollCq(DeviceMem& receiveBuffer)
     383              : {
     384            0 :     HcclResult ret = HCCL_SUCCESS;
     385            0 :     if (!receiveBuffer) {
     386            0 :         HCCL_ERROR("[SendRecvExecutor][ReceiveRunByPollCq] Receive buffer ptr is null.");
     387            0 :         return HCCL_E_PTR;
     388              :     }
     389            0 :     u64 sizePerRound = 0;
     390            0 :     u64 sizePerSlice = chunkSize_;
     391            0 :     u64 length = receiveBuffer.size();
     392              :  
     393            0 :     u64 offset = 0;
     394              :  
     395            0 :     for (u64 sizeResidue = length; sizeResidue > 0; sizeResidue -= sizePerRound) {
     396              :         // 防止数据回绕
     397            0 :         CHK_PRT_RET(sizeResidue > length, HCCL_ERROR("[SendRecvExecutor][ReceiveRunByPollCq] countLeft is underflow."),
     398              :             HCCL_E_PARA);
     399            0 :         offset += sizePerRound;
     400            0 :         sizePerRound = (sizeResidue > sizePerSlice) ? sizePerSlice : sizeResidue;
     401            0 :         HCCL_INFO("rx async inputmem's offset[%llu] size[%llu]", offset, sizePerRound);
     402              :  
     403            0 :         void* localAddr = static_cast<u8 *>(localWindowMem_.addr) + offset;
     404              :         
     405            0 :         std::vector<struct RecvWrlistData> recvWrVec(1);
     406            0 :         recvWrVec[0].wrId = reinterpret_cast<u64>(localWindowMem_.addr);
     407            0 :         recvWrVec[0].memList.addr = reinterpret_cast<u64>(localAddr);
     408            0 :         recvWrVec[0].memList.len = sizePerRound;
     409            0 :         recvWrVec[0].memList.lkey = localWindowMem_.lkey;
     410              :  
     411            0 :         struct RecvWrlistData *recvWr = recvWrVec.data();
     412            0 :         u32 completeNum = 0;
     413            0 :         ret = hrtRaRecvWrlist(qpHandle_, recvWr, 1, &completeNum);
     414            0 :         if (ret == HCCL_SUCCESS && completeNum == 1) {
     415            0 :             HCCL_INFO("[SendRecvExecutor][ReceiveRunByPollCq] Exec hrtRaRecvWrlist success.");
     416              :         } else {
     417            0 :             HCCL_ERROR("[SendRecvExecutor][ReceiveRunByPollCq] In RdmaDataTransport, hrtRaRecvWrlist failed. ret[%d], completeNum[%d].",
     418              :                 ret, completeNum);
     419            0 :             return HCCL_E_NETWORK;
     420              :         }
     421              :  
     422            0 :         ret = RecordNotify(remoteSyncMemPrepare_.addr, remoteSyncMemPrepare_.lkey,
     423            0 :             notifySrcMem_.addr, notifySrcMem_.lkey, notifySize_);
     424            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("SendRecvExecutor][ReceiveRunByPollCq] Record prepare failed"), ret);
     425              : 
     426            0 :         CHK_RET(PollCq());
     427              : 
     428            0 :         ret = RecordNotify(remoteSyncMemAck_.addr, remoteSyncMemAck_.lkey,
     429            0 :             notifySrcMem_.addr, notifySrcMem_.lkey, notifySize_);
     430            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][ReceiveRunByPollCq] Record ack failed"), ret);
     431            0 :     }
     432            0 :     return HCCL_SUCCESS;
     433              : }
     434              : 
     435            0 : HcclResult SendRecvExecutor::ReceiveRun(DeviceMem& receiveBuffer)
     436              : {
     437            0 :     HcclResult ret = HCCL_SUCCESS;
     438            0 :     if (!receiveBuffer) {
     439            0 :         HCCL_ERROR("[SendRecvExecutor][ReceiveRun] Receive buffer ptr is null.");
     440            0 :         return HCCL_E_PTR;
     441              :     }
     442            0 :     u64 sizePerRound = 0;
     443            0 :     u64 sizePerSlice = chunkSize_;
     444            0 :     u64 length = receiveBuffer.size();
     445            0 :     u64 offset = 0;
     446              : 
     447            0 :     for (u64 sizeResidue = length; sizeResidue > 0; sizeResidue -= sizePerRound) {
     448              :         // 防止数据回绕
     449            0 :         CHK_PRT_RET(sizeResidue > length, HCCL_ERROR("[SendRecvExecutor][ReceiveRun] countLeft is underflow."),
     450              :             HCCL_E_PARA);
     451            0 :         ret = RecordNotify(remoteSyncMemPrepare_.addr, remoteSyncMemPrepare_.lkey,
     452            0 :             notifySrcMem_.addr, notifySrcMem_.lkey, notifySize_);
     453            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("SendRecvExecutor][ReceiveRun] Record prepare failed"), ret);
     454            0 :         offset += sizePerRound;
     455            0 :         sizePerRound = (sizeResidue > sizePerSlice) ? sizePerSlice : sizeResidue;
     456              : 
     457            0 :         HCCL_INFO("[SendRecvExecutor][ReceiveRun]rx async inputmem's offset[%llu] size[%llu]", offset, sizePerRound);
     458              : 
     459            0 :         ret = WaitSignal(doneNotify_);
     460            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][ReceiveRun] Wait done failed"), ret);
     461              : 
     462            0 :         ret = RecordNotify(remoteSyncMemAck_.addr, remoteSyncMemAck_.lkey,
     463            0 :             notifySrcMem_.addr, notifySrcMem_.lkey, notifySize_);
     464            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][ReceiveRun] Wait ack failed"), ret);
     465              :     }
     466            0 :     return HCCL_SUCCESS;
     467              : }
     468              : 
     469              : 
     470           48 : HcclResult SendRecvExecutor::RecordNotify(void *dstMemPtr, u32 rkey, const void *srcMemPtr, u32 lkey, u64 srcMemSize,
     471              :         uint32_t rdmaOp, int sendFlag)
     472              : {
     473           48 :     struct SgList list = {0};
     474           48 :     struct SendWrV2 wr = {0};
     475              :     // 构造wr信息
     476           48 :     list.addr = static_cast<u64>(reinterpret_cast<uintptr_t>(srcMemPtr));
     477           48 :     list.len = srcMemSize;
     478           48 :     list.lkey = lkey;
     479              : 
     480           48 :     wr.bufList = &list;
     481           48 :     wr.bufNum = 1; /* 此处list只有一个,设置为1 */
     482           48 :     wr.dstAddr = static_cast<u64>(reinterpret_cast<uintptr_t>(dstMemPtr));
     483           48 :     wr.rkey = rkey;
     484           48 :     wr.op = rdmaOp;
     485           48 :     wr.sendFlag = sendFlag;
     486              : 
     487           48 :     HCCL_INFO("[SendRecvExecutor][RecordNotify] " \
     488              :         "Notify's dst addr[%p], local addr[%p], data's len[%u], remote mr key[%u], local mr key[%u]",
     489              :         wr.dstAddr, wr.bufList->addr, wr.bufList->len, wr.rkey, wr.bufList->lkey);
     490              : 
     491              :     // RDMA异步发送
     492           48 :     CHK_RET(RdmaSendAsync(wr));
     493           48 :     return HCCL_SUCCESS;
     494              : }
     495              : 
     496           29 : HcclResult SendRecvExecutor::WaitSignal(HcclRtSignal signal)
     497              : {
     498           29 :     if (notifyWaitMode_ == SyncMode::CONFIGURABLE_TIMEWAITSYNCMODE) {
     499            0 :         CHK_RET(hrtNotifyWaitWithTimeOut(static_cast<HcclRtNotify>(signal), stream_,
     500              :             GetExternalInputHcclExecTimeOut()));
     501              :     } else {
     502           29 :         CHK_RET(hrtNotifyWaitWithTimeOut(static_cast<HcclRtNotify>(signal), stream_, NOTIFY_DEFAULT_WAIT_TIME));
     503              :     }
     504           29 :     return HCCL_SUCCESS;
     505              : }
     506              : 
     507            0 : HcclResult SendRecvExecutor::PayLoad(const void *src, u64 dstOffset, u64 len)
     508              : {
     509              :     HcclResult ret;
     510            0 :     HCCL_DEBUG("[SendRecvExecutor][PayLoad] Local window memory srcPtr[%p] len[%llu] dstOffset[%llu]",
     511              :         src, len, dstOffset);
     512              : 
     513            0 :     u32 txSendDataTimes = (len == 0) ? 1 : (len + RDMA_SEND_MAX_SIZE - 1) / RDMA_SEND_MAX_SIZE;
     514              : 
     515            0 :     for (u32 txSendDataIdx = 0; txSendDataIdx < txSendDataTimes; txSendDataIdx++) {
     516            0 :         u64 txSendDataOffset = txSendDataIdx * RDMA_SEND_MAX_SIZE;
     517            0 :         u64 txSendDataSize = (txSendDataIdx == (txSendDataTimes - 1)) ? len - txSendDataOffset : RDMA_SEND_MAX_SIZE;
     518              : 
     519            0 :         void* txdstMemPtr = reinterpret_cast<void *>(reinterpret_cast<u8*>(remoteWindowMem_.addr) + dstOffset +
     520              :             txSendDataOffset);
     521              : 
     522            0 :         const void* txsrcMemPtr = reinterpret_cast<const void *>(reinterpret_cast<const char *>(src) +
     523              :             txSendDataOffset);
     524            0 :         struct SendWrV2 wr{};
     525              :         // 构造wr信息
     526            0 :         wr.bufNum = 1; /* 此处list只有一个,设置为1 */
     527            0 :         wr.dstAddr = static_cast<u64>(reinterpret_cast<uintptr_t>(txdstMemPtr));
     528            0 :         wr.rkey = remoteWindowMem_.lkey;
     529            0 :         wr.sendFlag = RA_SEND_SIGNALED;
     530            0 :         if(immData_ != 0) {
     531            0 :             wr.op = RA_WR_RDMA_WRITE_WITH_IMM;
     532            0 :             wr.ext.immData = immData_;
     533              :         } else {
     534            0 :             wr.op = RA_WR_RDMA_WRITE;
     535              :         }
     536            0 :         struct SgList list = {0};
     537            0 :         list.addr = static_cast<u64>(reinterpret_cast<uintptr_t>(txsrcMemPtr));
     538            0 :         list.len = txSendDataSize;
     539            0 :         list.lkey = localWindowMem_.lkey;
     540            0 :         wr.bufList = &list;
     541            0 :         ret = RdmaSendAsync(wr);
     542            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     543              :             HCCL_ERROR("[SendRecvExecutor][PayLoad]errNo[0x%016llx] In lbv exp, add wqe list failed."\
     544              :                 "srcMemSize[%llu]", HCCL_ERROR_CODE(ret), txSendDataSize), ret);
     545              :     }
     546              : 
     547            0 :     return HCCL_SUCCESS;
     548              : }
     549              : 
     550           48 : HcclResult SendRecvExecutor::RdmaSendAsync(struct SendWrV2 &wr)
     551              : {
     552           48 :     HcclResult ret = HCCL_SUCCESS;
     553           48 :     struct SendWrRsp opRsp = {0};
     554           48 :     HCCL_DEBUG("[SendRecvExecutor][RdmaSendAsync] dst_addr[%p], src_addr[%p], len[%u]",
     555              :         wr.dstAddr, wr.bufList->addr, wr.bufList->len);
     556              : 
     557           48 :     CHK_RET(HrtRaSendWrV2(qpHandle_, &wr, &opRsp, HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE));
     558              : 
     559           48 :     u32 dbIndex = static_cast<u32>(opRsp.db.dbIndex);
     560           48 :     u64 dbInfo = static_cast<u64>(opRsp.db.dbInfo);
     561              : 
     562           48 :     if ((dbIndex == INVALID_UINT) && (dbInfo == INVALID_U64)) {
     563              :         // zero byte message 不需要下发rdma send task
     564            0 :         HCCL_DEBUG("[SendRecvExecutor][RdmaSendAsync] dbIndex and dbInfo is invalid.");
     565            0 :         return HCCL_SUCCESS;
     566              :     }
     567              : 
     568           48 :     ret = hrtRDMADBSend(dbIndex, dbInfo, stream_);
     569           48 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     570              :         HCCL_ERROR("[SendRecvExecutor][RdmaSendAsync]errNo[0x%016llx] In lbv exp op base mode, "\
     571              :         "rdma send failed. dbIndex[%u] dbInfo[%llu]", HCCL_ERROR_CODE(ret), dbIndex, dbInfo), ret);
     572           48 :     return HCCL_SUCCESS;
     573              : }
     574              : 
     575            0 : HcclResult SendRecvExecutor::MemcpyAsyncD2D(hccl::DeviceMem &dst, const hccl::DeviceMem &src, hccl::Stream &stream)
     576              : {
     577            0 :     CHK_PTR_NULL(dst.ptr());
     578            0 :     CHK_PTR_NULL(src.ptr());
     579              : 
     580            0 :     if (stream.ptr() == nullptr) {
     581            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(dst.ptr(), dst.size(), src.ptr(), src.size()));
     582            0 :         return HCCL_E_PARA;
     583              :     }
     584              : 
     585            0 :     if (src.size() == 0) {
     586            0 :         HCCL_DEBUG("[SendRecvExecutor][MemcpyAsyncD2D] count is 0, return success.");
     587            0 :         return HCCL_SUCCESS;
     588              :     }
     589              : 
     590            0 :     uint64_t spiltLoop = 0;
     591            0 :     uint64_t addrOffset = 0;
     592            0 :     uint64_t contSplit = 0;
     593            0 :     if (src.size() > HCCL_SDMA_MAX_COUNT_4GB) {
     594            0 :         spiltLoop = (src.size() % HCCL_SDMA_MAX_COUNT_4GB) ?
     595            0 :             (src.size() / HCCL_SDMA_MAX_COUNT_4GB) : ((src.size() / HCCL_SDMA_MAX_COUNT_4GB) - 1);
     596            0 :         HCCL_INFO("[SendRecvExecutor][MemcpyAsyncD2D] MemcpyAsync SDMA task countSize is bigger than 4GB "\
     597              :             "and do segmentation splitloop[%llu]", spiltLoop);
     598              :     }
     599              :     /* SDMA任务拆分 */
     600            0 :     for (uint64_t index = 0 ; index <= spiltLoop; index++) {
     601            0 :         addrOffset = index * HCCL_SDMA_MAX_COUNT_4GB;
     602            0 :         contSplit = (index == spiltLoop) ? (src.size() - index * HCCL_SDMA_MAX_COUNT_4GB) : (HCCL_SDMA_MAX_COUNT_4GB);
     603            0 :         void *srcSplit = static_cast<void *>(static_cast<u8*>(const_cast<void*>(src.ptr())) + addrOffset);
     604            0 :         void *dstSplit = static_cast<void *>(static_cast<u8*>(dst.ptr()) + addrOffset);
     605              : 
     606            0 :         CHK_RET(hrtMemAsyncCopy(dstSplit, dst.size(), const_cast<const void*>(srcSplit),
     607              :             contSplit, HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_DEVICE, stream.ptr()));
     608              :     }
     609            0 :     return HCCL_SUCCESS;
     610              : }
     611              : 
     612           19 : HcclResult SendRecvExecutor::BatchPutMR(u32 num, AscendMrInfo* putMRList, AscendMrInfo* remoteMRList)
     613              : {
     614           19 :     HcclResult ret = HCCL_SUCCESS;
     615           19 :     u32 sendWrNum = 0;
     616           38 :     for (u32 i = 0; i < num; i++){
     617           19 :         if (i != num - 1) {
     618            0 :             CHK_RET(PayLoadMR(putMRList + i, remoteMRList + i, sendWrNum));
     619              :         } else {
     620              :             // 最后一组数据特殊处理,发送立即数
     621           19 :             CHK_RET(PayLoadMR(putMRList + i, remoteMRList + i, sendWrNum, true));
     622              :         }
     623              :     }
     624              : 
     625           19 :     if(immData_ == 0) {
     626           38 :         ret = RecordNotify(remoteSyncMemDone_.addr, remoteSyncMemDone_.lkey,
     627           19 :             notifySrcMem_.addr, notifySrcMem_.lkey, notifySize_);
     628           19 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][BatchPutMR] Record done failed"), ret);
     629              :     }
     630              : 
     631           19 :     ret = WaitSignal(ackNotify_);
     632           19 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][BatchPutMR] Wait ack failed"), ret);
     633              : 
     634           19 :     return HCCL_SUCCESS;
     635              : }
     636              : 
     637           29 : HcclResult SendRecvExecutor::PayLoadMR(AscendMrInfo* putMRInfo, AscendMrInfo* remoteMRInfo, u32& wrNum,
     638              :     bool isLastMRtoPut)
     639              : {
     640           29 :     CHK_PRT_RET(putMRInfo->size != remoteMRInfo->size, HCCL_ERROR("[SendRecvExecutor][PayLoadMR] The size of localMR" \
     641              :         "is different from remoteMR. LocalMR size is [%u], remoteMR size is[%u].", putMRInfo->size, remoteMRInfo->size),
     642              :         HCCL_E_PARA);
     643           29 :     u64 remainingSize = putMRInfo->size;
     644           29 :     u64 offSet = 0;
     645           29 :     u64 byteChunkSize = 0;
     646           29 :     u64 localAddr = 0;
     647           29 :     u64 remoteAddr = 0;
     648           29 :     bool isLastSlice = false;
     649           58 :     while (remainingSize > 0) {
     650           29 :         localAddr = putMRInfo->addr + offSet;
     651           29 :         remoteAddr = remoteMRInfo->addr + offSet;
     652           29 :         byteChunkSize = remainingSize > MAX_RDMA_WQE_SIZE ? MAX_RDMA_WQE_SIZE : remainingSize;
     653           29 :         isLastSlice = remainingSize > MAX_RDMA_WQE_SIZE ? false : true;
     654           29 :         struct SgList list = {};
     655           29 :         list.addr = localAddr;
     656           29 :         list.len = byteChunkSize;
     657           29 :         list.lkey = putMRInfo->key;
     658           29 :         struct SendWrV2 wr = {};
     659           29 :         wr.bufList = &list;
     660           29 :         wr.bufNum = 1; /* 此处list只有一个,设置为1 */
     661           29 :         wr.dstAddr = remoteAddr;
     662           29 :         wr.rkey = remoteMRInfo->key;
     663           29 :         if (isLastMRtoPut && isLastSlice && immData_ != 0) {
     664            0 :             wr.op = RA_WR_RDMA_WRITE_WITH_IMM;
     665            0 :             wr.ext.immData = immData_;
     666              :         } else {
     667           29 :             wr.op = RA_WR_RDMA_WRITE;
     668              :         }
     669              : 
     670           29 :         CHK_RET(MultiWqeOneDoorBellSend(isLastMRtoPut && isLastSlice, wrNum, wr));
     671           29 :         remainingSize -= byteChunkSize;
     672           29 :         offSet += byteChunkSize;
     673              :     }
     674           29 :     return HCCL_SUCCESS;
     675              : }
     676              : 
     677           29 : HcclResult SendRecvExecutor::MultiWqeOneDoorBellSend(bool isLastWr, u32& wrNum, struct SendWrV2& wr)
     678              : {
     679           29 :     HcclResult ret = HCCL_SUCCESS;
     680           29 :     wrNum++;
     681              :     // 多个wqe生成一个cqe
     682           29 :     if (isLastWr || wrNum == wqePerDoorBell_) {
     683           29 :         wr.sendFlag = RA_SEND_SIGNALED;
     684              :     } else {
     685            0 :         wr.sendFlag = 0;
     686              :     }
     687           29 :     struct SendWrRsp opRsp = {};
     688           29 :     CHK_RET(HrtRaSendWrV2(qpHandle_, &wr, &opRsp, HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE));
     689           29 :     HCCL_DEBUG("[SendRecvExecutor][MultiWqeOneDoorBellSend] End SendWr, wr op[%d], localAddr[%p], remoteAddr[%p], "\
     690              :         "len[%llu], local key[%u], remote key[%u].", 
     691              :         wr.op, wr.bufList->addr, wr.dstAddr, wr.bufList->len, wr.bufList->lkey, wr.rkey);
     692              : 
     693           29 :     if (static_cast<u32>(opRsp.db.dbIndex) == INVALID_UINT && static_cast<u64>(opRsp.db.dbInfo) == INVALID_U64) {
     694              :         // zero byte message 不需要下发rdma send task
     695            0 :         HCCL_DEBUG("[SendRecvExecutor][MultiWqeOneDoorBellSend] dbIndex and dbInfo is invalid.");
     696            0 :         return HCCL_SUCCESS;
     697              :     }
     698              : 
     699              :     // 每下发wqePerDoorBell_个wr敲一次doorbell
     700           29 :     if (isLastWr || wrNum == wqePerDoorBell_) {
     701           29 :         u32 dbIndex = static_cast<u32>(opRsp.db.dbIndex);
     702           29 :         u64 dbInfo = static_cast<u64>(opRsp.db.dbInfo);
     703           29 :         HCCL_DEBUG("[SendRecvExecutor][MultiWqeOneDoorBellSend] Start RDMADBSend, dbIndex[%u], dbInfo[%llu], wrNum[%u], "\
     704              :         "isLastMR[%d].", dbIndex, dbInfo, wrNum, isLastWr);
     705           29 :         ret = hrtRDMADBSend(dbIndex, dbInfo, stream_);
     706           29 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     707              :             HCCL_ERROR("[SendRecvExecutor][MultiWqeOneDoorBellSend]errNo[0x%016llx] In lbv exp op base mode, "\
     708              :             "rdma send failed. dbIndex[%u] dbInfo[%llu]", HCCL_ERROR_CODE(ret), dbIndex, dbInfo), ret);
     709           29 :         wrNum = 0;
     710              :     }
     711           29 :     return HCCL_SUCCESS;
     712              : }
     713              : 
     714           19 : HcclResult SendRecvExecutor::WaitPutMR()
     715              : {
     716           19 :     HcclResult ret = HCCL_SUCCESS;
     717              : 
     718           19 :     ret = WaitSignalUnlimitedTime(doneNotify_);
     719           19 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][WaitPutMR] Wait done failed"), ret);
     720              : 
     721           38 :     ret = RecordNotify(remoteSyncMemAck_.addr, remoteSyncMemAck_.lkey,
     722           19 :         notifySrcMem_.addr, notifySrcMem_.lkey, notifySize_);
     723           19 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][WaitPutMR] Record ack failed"), ret);
     724              : 
     725           19 :     return HCCL_SUCCESS;
     726              : }
     727              : 
     728            0 : HcclResult SendRecvExecutor::ProcessRCQ(AscendMrInfo* lastMRInfo)
     729              : {
     730            0 :     HcclResult ret = HCCL_SUCCESS;
     731            0 :     u64 remainingSize = lastMRInfo->size;
     732            0 :     u64 localAddr = lastMRInfo->addr;
     733            0 :     u64 offSet = 0;
     734            0 :     while (remainingSize > MAX_RDMA_WQE_SIZE) {
     735            0 :         remainingSize -= MAX_RDMA_WQE_SIZE;
     736            0 :         offSet += MAX_RDMA_WQE_SIZE;
     737              :     }
     738            0 :     std::vector<struct RecvWrlistData> recvWrVec(1);
     739            0 :     recvWrVec[0].wrId = localAddr;
     740            0 :     recvWrVec[0].memList.addr = localAddr + offSet;
     741            0 :     recvWrVec[0].memList.len = remainingSize;
     742            0 :     recvWrVec[0].memList.lkey = lastMRInfo->key;
     743              : 
     744            0 :     struct RecvWrlistData *recvWr = recvWrVec.data();
     745            0 :     u32 completeNum = 0;
     746            0 :     ret = hrtRaRecvWrlist(qpHandle_, recvWr, 1, &completeNum);
     747            0 :     if (ret == HCCL_SUCCESS && completeNum == 1) {
     748            0 :         HCCL_INFO("[SendRecvExecutor][TestBatchPutMR] Exec hrtRaRecvWrlist success.");
     749              :     } else {
     750            0 :         HCCL_ERROR("[SendRecvExecutor][TestBatchPutMR] In RdmaDataTransport, hrtRaRecvWrlist failed. ret[%d], completeNum[%d].",
     751              :             ret, completeNum);
     752            0 :         return HCCL_E_NETWORK;
     753              :     }
     754              : 
     755            0 :     CHK_RET(PollCq());
     756            0 :     return HCCL_SUCCESS;
     757            0 : }
     758              : 
     759           19 : HcclResult SendRecvExecutor::WaitSignalUnlimitedTime(HcclRtSignal signal)
     760              : {
     761              :     // 超时时间配置成0,代表永不超时
     762           19 :     CHK_RET(hrtNotifyWaitWithTimeOut(static_cast<HcclRtNotify>(signal), stream_, 0));
     763           19 :     return HCCL_SUCCESS;
     764              : }
     765              : 
     766            0 : HcclResult SendRecvExecutor::WaitPutMROnlyWait()
     767              : {
     768            0 :     HcclResult ret = HCCL_SUCCESS;
     769              : 
     770            0 :     ret = WaitSignalUnlimitedTime(doneNotify_);
     771            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][WaitPutMROnlyWait] Wait done failed"), ret);
     772              : 
     773            0 :     return HCCL_SUCCESS;
     774              : }
     775              : 
     776            0 : HcclResult SendRecvExecutor::WaitPutMROnlyRecord()
     777              : {
     778            0 :     HcclResult ret = HCCL_SUCCESS;
     779              : 
     780            0 :     ret = RecordNotify(remoteSyncMemAck_.addr, remoteSyncMemAck_.lkey,
     781            0 :         notifySrcMem_.addr, notifySrcMem_.lkey, notifySize_);
     782            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SendRecvExecutor][WaitPutMROnlyWait] Record ack failed"), ret);
     783              : 
     784            0 :     return HCCL_SUCCESS;
     785              : }
     786              : 
     787           10 : HcclResult SendRecvExecutor::OneSideBatchPutMR(u32 num, AscendMrInfo* putMRList, AscendMrInfo* remoteMRList)
     788              : {
     789           10 :     CHK_RET(hrtGetNotifySize(notifySize_));
     790           10 :     if (GetExternalInputHcclExecTimeoutSet() != HcclExecTimeoutSet::HCCL_EXEC_TIMEOUT_NOT_SET) {
     791            0 :         notifyWaitMode_ = SyncMode::CONFIGURABLE_TIMEWAITSYNCMODE;
     792              :     }
     793           10 :     CHK_RET(TypicalSyncMem::GetInstance().GetNotifyHandle(reinterpret_cast<u64>(localSyncMemAck_.addr),
     794              :         ackNotify_));
     795           10 :     CHK_PTR_NULL(ackNotify_);
     796           10 :     HCCL_INFO("[OneSideBatchPutMR] notifySize[%u], notifyWaitMode[%d], "\
     797              :         "ackNotify[%p], remoteNotifyValueMem addr[%p], remoteNotifyValueMem len[%llu], remoteNotifyValueMem key[%u], wqePerDoorBell[%u]",
     798              :         notifySize_, notifyWaitMode_, ackNotify_, remoteNotifyValueMem_.addr, remoteNotifyValueMem_.size, remoteNotifyValueMem_.lkey, wqePerDoorBell_);
     799              : 
     800           10 :     u32 sendWrNum = 0;
     801           20 :     for (u32 i = 0; i < num; i++){
     802           10 :         if (i != num - 1) {
     803            0 :             CHK_RET(PayLoadMR(putMRList + i, remoteMRList + i, sendWrNum));
     804              :         } else {
     805              :             // 最后一组数据特殊处理,发送立即数
     806           10 :             CHK_RET(PayLoadMR(putMRList + i, remoteMRList + i, sendWrNum, true));
     807              :         }
     808              :     }
     809              : 
     810           20 :     HcclResult ret = RecordNotify(remoteNotifyValueMem_.addr, remoteNotifyValueMem_.lkey, localSyncMemAck_.addr, localSyncMemAck_.lkey,
     811           10 :         notifySize_, RA_WR_RDMA_READ, RA_SEND_SIGNALED | RA_SEND_FENCE);
     812           10 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[OneSideBatchPutMR] Record ack failed"), ret);
     813              :  
     814           10 :     ret = WaitSignal(ackNotify_);
     815           10 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[OneSideBatchPutMR] Wait ack failed"), ret);
     816              :  
     817           10 :     return ret;
     818              : }
     819              : 
     820              : } // namespace hccl
        

Generated by: LCOV version 2.0-1