LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/alg_template/temp_alltoallv - alltoallv_pairwise.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 173 0
Test Date: 2026-08-04 10:52:23 Functions: 0.0 % 13 0

            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 "alltoallv_pairwise.h"
      12              : #include "alg_template_register.h"
      13              : 
      14              : 
      15              : namespace hccl {
      16            0 : AlltoAllVPairWise::AlltoAllVPairWise(const HcclDispatcher dispatcher)
      17            0 :     : AlgTemplateBase(dispatcher)
      18              : {
      19            0 : }
      20              : 
      21            0 : AlltoAllVPairWise::~AlltoAllVPairWise() {}
      22              : 
      23            0 : HcclResult AlltoAllVPairWise::Prepare(AlltoAllVBufferInfo& sendBuffer, AlltoAllVBufferInfo& recvBuffer,
      24              :     bool isAlltoAllZCopyMode, const Stream &stream, HcclWorkflowMode workMode,
      25              :     std::map<u32, std::vector<u64>> &rankSendDisplsMap,
      26              :     std::map<u32, std::vector<u64>> &rankRecvDisplsMap)
      27              : {
      28            0 :     DeviceMem scratchInputMem = DeviceMem();
      29            0 :     DeviceMem scratchOutputMem = DeviceMem();
      30            0 :     CHK_RET(AlltoAllVPairWise::Prepare(sendBuffer, recvBuffer, scratchInputMem, scratchOutputMem,
      31              :                                        isAlltoAllZCopyMode, stream, workMode,
      32              :                                        rankSendDisplsMap, rankRecvDisplsMap));
      33            0 :     return HCCL_SUCCESS;
      34            0 : }
      35              : 
      36            0 : HcclResult AlltoAllVPairWise::Prepare(AlltoAllVBufferInfo &sendBuffer, AlltoAllVBufferInfo &recvBuffer,
      37              :     DeviceMem &scratchInputMem, DeviceMem &scratchOutputMem, bool isAlltoAllZCopyMode, const Stream &stream,
      38              :     HcclWorkflowMode workMode, std::map<u32, std::vector<u64>> &rankSendDisplsMap,
      39              :     std::map<u32, std::vector<u64>> &rankRecvDisplsMap)
      40              : {
      41            0 :     HCCL_INFO("[AlltoAllVPairWise][Prepare] Begin");
      42            0 :     scratchMemSize_ = 0;
      43            0 :     sendDataUnitBytes_ = 0;
      44            0 :     recvDataUnitBytes_ = 0;
      45            0 :     isAlltoAllZCopyMode_ = isAlltoAllZCopyMode;
      46            0 :     workMode_ = workMode;
      47            0 :     rankSendDisplsMapPtr_ = &rankSendDisplsMap;
      48            0 :     rankRecvDisplsMapPtr_ = &rankRecvDisplsMap;
      49              : 
      50            0 :     if (workMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
      51            0 :         CHK_PRT_RET((!isAlltoAllZCopyMode_ && scratchInputMem.size() != scratchOutputMem.size()),
      52              :             HCCL_ERROR("[AlltoAllVPairWise][Prepare]scratchInputMem and scratchOutputMem should be the same size, "
      53              :             "ScratchInputMem[%llu] ScratchOutputMem[%llu]", scratchInputMem.size(), scratchOutputMem.size()),
      54              :             HCCL_E_MEMORY);
      55              : 
      56            0 :         CHK_PRT_RET(scratchInputMem.size() == 0 || scratchOutputMem.size() == 0,
      57              :             HCCL_ERROR("[AlltoAllVPairWise][Prepare] invilad scratchMemSize[%llu]", scratchInputMem.size()),
      58              :             HCCL_E_PARA);
      59            0 :         scratchInputMem_ = scratchInputMem;
      60            0 :         scratchOutputMem_ = scratchOutputMem;
      61            0 :         scratchMemSize_ = scratchInputMem.size();
      62              :     }
      63              : 
      64            0 :     sendBuffer_ = sendBuffer;
      65            0 :     recvBuffer_ = recvBuffer;
      66            0 :     stream_ = stream;
      67              : 
      68            0 :     CHK_RET(SalGetDataTypeSize(sendBuffer_.dataType, sendDataUnitBytes_));
      69            0 :     CHK_RET(SalGetDataTypeSize(recvBuffer_.dataType, recvDataUnitBytes_));
      70              : 
      71            0 :     return HCCL_SUCCESS;
      72              : }
      73              : 
      74            0 : HcclResult AlltoAllVPairWise::RunAsync(const u32 rank, const u32 rankSize, const std::vector<LINK> &links)
      75              : {
      76            0 :     HCCL_INFO("[AlltoAllVPairWise][RunAsync]: rank[%u] transportSize[%llu]", rank, links.size());
      77            0 :     CHK_SMART_PTR_NULL(dispatcher_);
      78            0 :     CHK_PTR_NULL(stream_.ptr());
      79              : 
      80            0 :     CHK_PRT_RET(rankSize == 0, HCCL_ERROR("[AlltoAllVPairWise][Prepare] invilad rankSize[%u]", rankSize), HCCL_E_PARA);
      81              : 
      82            0 :     CHK_PRT_RET(rankSize != links.size(),
      83              :         HCCL_ERROR("[AlltoAllVPairWise][RunAsync]: rankSize[%u] and transport size[%llu] do not match", rankSize,
      84              :         links.size()),
      85              :         HCCL_E_PARA);
      86              : 
      87            0 :     CHK_RET(LocalCopy(rank));
      88            0 :     if (workMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
      89            0 :         !isAlltoAllZCopyMode_) { // 单算子 && BCopy模式
      90            0 :         CHK_RET(RunBCopyAlltoAll(rank, rankSize, links));
      91            0 :     } else {
      92            0 :         CHK_RET(RunZCopyAlltoAll(rank, rankSize, links));
      93              :     }
      94            0 :     return HCCL_SUCCESS;
      95              : }
      96              : 
      97              : // 从本rank的sendbuffer拷贝到本rank的recvbuffer
      98            0 : HcclResult AlltoAllVPairWise::LocalCopy(const u32 rank)
      99              : {
     100            0 :     DeviceMem dstMem = recvBuffer_.mem.range(recvDataUnitBytes_ * recvBuffer_.displs[rank],
     101            0 :         recvBuffer_.counts[rank] * recvDataUnitBytes_);
     102            0 :     DeviceMem srcMem = sendBuffer_.mem.range(sendDataUnitBytes_ * sendBuffer_.displs[rank],
     103            0 :         sendBuffer_.counts[rank] * sendDataUnitBytes_);
     104            0 :     HCCL_DEBUG("[AlltoAllVPairWise][LocalCopy]: Rank[%u] destAddr[%p], destMax[%llu], srcAddr[%p], size[%llu]",
     105              :         rank, dstMem.ptr(), dstMem.size(), srcMem.ptr(), srcMem.size());
     106            0 :     CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstMem, srcMem, stream_));
     107              : 
     108            0 :     return HCCL_SUCCESS;
     109            0 : }
     110              : 
     111            0 : HcclResult AlltoAllVPairWise::RunBCopyAlltoAll(const u32 rank, const u32 rankSize, const std::vector<LINK> &links)
     112              : {
     113            0 :     for (u32 i = 1; i < rankSize; i++) {
     114            0 :         u32 prevRank = (rank + rankSize - i) % rankSize;
     115            0 :         u32 nextRank = (rank + i) % rankSize;
     116            0 :         std::shared_ptr<Transport> prevTransport = links[prevRank];
     117            0 :         std::shared_ptr<Transport> nextTransport = links[nextRank];
     118              : 
     119            0 :         CHK_SMART_PTR_NULL(prevTransport);
     120            0 :         CHK_SMART_PTR_NULL(nextTransport);
     121              : 
     122            0 :         HCCL_DEBUG("[AlltoAllVPairWise][RunBCopyAlltoAll]: prevRank[%u] nextRank[%u], step[%u]", prevRank, nextRank, i);
     123              : 
     124            0 :         u64 sendBytes = sendBuffer_.counts[nextRank] * sendDataUnitBytes_;
     125            0 :         u64 recvBytes = recvBuffer_.counts[prevRank] * recvDataUnitBytes_;
     126              : 
     127            0 :         u64 sendDispBytes = sendBuffer_.displs[nextRank] * sendDataUnitBytes_;
     128            0 :         u64 recvDispBytes = recvBuffer_.displs[prevRank] * recvDataUnitBytes_;
     129              : 
     130              :         // scratchMemSize_ 的合法性已经在 Prepare 函数中校验
     131            0 :         u32 sendTimes = (sendBytes / scratchMemSize_) + ((sendBytes % scratchMemSize_) == 0 ? 0 : 1);
     132            0 :         u32 recvTimes = (recvBytes / scratchMemSize_) + ((recvBytes % scratchMemSize_) == 0 ? 0 : 1);
     133              : 
     134            0 :         HCCL_DEBUG("[AlltoAllVPairWise][RunBCopyAlltoAll]: rank[%u] "\
     135              :                    "sendTimes[%u] recvTimes[%u] sendBytes[%llu] recvBytes[%llu] scratchMemSize_[%llu]",
     136              :                    rank, sendTimes, recvTimes, sendBytes, recvBytes, scratchMemSize_);
     137              : 
     138            0 :         u32 curSendTime = 0;
     139            0 :         u32 curRecvTime = 0;
     140            0 :         while (sendTimes != 0 || recvTimes != 0) {
     141              :             u8 *sendAddr =
     142            0 :                 reinterpret_cast<u8 *>(sendBuffer_.mem.ptr()) + sendDispBytes + curSendTime * scratchMemSize_;
     143              :             u8 *recvAddr =
     144            0 :                 reinterpret_cast<u8 *>(recvBuffer_.mem.ptr()) + recvDispBytes + curRecvTime * scratchMemSize_;
     145            0 :             u64 curSendBytes = 0;
     146            0 :             u64 curRecvBytes = 0;
     147            0 :             CHK_RET(CalcSendRecvCounts(sendTimes, curSendTime, sendBytes, curSendBytes));
     148            0 :             CHK_RET(CalcSendRecvCounts(recvTimes, curRecvTime, recvBytes, curRecvBytes));
     149              : 
     150            0 :             HCCL_DEBUG("[AlltoAllVPairWise][RunBCopyAlltoAll]: "\
     151              :                         "curSendTime[%llu] curRecvTime[%llu] curSendBytes[%llu] curRecvBytes[%llu]",
     152              :                 curSendTime, curRecvTime, curSendBytes, curRecvBytes);
     153              : 
     154            0 :             HcclResult ret = SendRecv(curSendBytes, curRecvBytes, sendAddr, recvAddr, prevTransport, nextTransport);
     155            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     156              :                 HCCL_ERROR("[AlltoAllVPairWise][RunBCopyAlltoAll]: errNo[0x%016llx] "\
     157              :                 "curSendBytes[%llu] curRecvBytes[%llu] sendAddr[%p] recvAddr[%p]",
     158              :                 HCCL_ERROR_CODE(ret), curSendBytes, curRecvBytes, sendAddr, recvAddr),
     159              :                 ret);
     160              : 
     161            0 :             curSendTime = curSendBytes != 0 ? curSendTime + 1 : curSendTime;
     162            0 :             curRecvTime = curRecvBytes != 0 ? curRecvTime + 1 : curRecvTime;
     163            0 :             if (curSendTime == sendTimes && curRecvTime == recvTimes) {
     164            0 :                 break;
     165              :             }
     166              :         }
     167            0 :     }
     168              : 
     169            0 :     return HCCL_SUCCESS;
     170              : }
     171              : 
     172            0 : HcclResult AlltoAllVPairWise::CalcSendRecvCounts(u32 times, u32 curTime, u64 totalBytes, u64 &curBytes) const
     173              : {
     174            0 :     if (times == 0) { // 不需要发送
     175            0 :         curBytes = 0;
     176            0 :     } else if (times == 1 && curTime == times - 1) { // 只发一次
     177            0 :         curBytes = totalBytes;
     178            0 :     } else if (times > 1 && totalBytes % scratchMemSize_ == 0 && curTime < times) {
     179            0 :         curBytes = scratchMemSize_;
     180            0 :     } else if (times > 1 && totalBytes % scratchMemSize_ != 0 && curTime < times - 1) {
     181            0 :         curBytes = scratchMemSize_;
     182            0 :     } else if (times > 1 && totalBytes % scratchMemSize_ != 0 && curTime == times - 1) {
     183            0 :         curBytes = totalBytes % scratchMemSize_;
     184              :     } else {
     185            0 :         curBytes = 0;
     186              :     }
     187            0 :     return HCCL_SUCCESS;
     188              : }
     189              : 
     190            0 : HcclResult AlltoAllVPairWise::SendRecv(u64 curSendBytes, u64 curRecvBytes, u8 *sendAddr, u8 *recvAddr,
     191              :     std::shared_ptr<Transport> prevTransport, std::shared_ptr<Transport> nextTransport)
     192              : {
     193            0 :     if (curRecvBytes > 0) {
     194            0 :         CHK_RET(prevTransport->TxAck(stream_)); // transport sync record
     195              :     }
     196            0 :     if (curSendBytes > 0) {
     197            0 :         CHK_RET(nextTransport->RxAck(stream_)); // transport sync wait
     198            0 :         DeviceMem srcMem1 = DeviceMem::create(sendAddr, curSendBytes);
     199            0 :         CHK_RET(HcclD2DMemcpyAsync(dispatcher_, scratchInputMem_, srcMem1, stream_));
     200              :         // send payload + notify
     201            0 :         CHK_RET(nextTransport->TxAsync(UserMemType::OUTPUT_MEM, 0, scratchInputMem_.ptr(), curSendBytes, stream_));
     202            0 :     }
     203            0 :     if (curRecvBytes > 0) {
     204            0 :         CHK_RET(prevTransport->RxAsync(UserMemType::INPUT_MEM, 0, scratchOutputMem_.ptr(), curRecvBytes, stream_));
     205            0 :         DeviceMem dstMem = DeviceMem::create(recvAddr, curRecvBytes);
     206            0 :         DeviceMem srcMem = scratchOutputMem_.range(0, curRecvBytes);
     207            0 :         CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstMem, srcMem, stream_));
     208            0 :         CHK_RET(prevTransport->TxAck(stream_)); // record
     209            0 :     }
     210            0 :     if (curSendBytes > 0) {
     211            0 :         CHK_RET(nextTransport->RxAck(stream_)); // wait
     212            0 :         CHK_RET(nextTransport->TxDataSignal(stream_)); // record
     213              :     }
     214            0 :     if (curRecvBytes > 0) {
     215            0 :         CHK_RET(prevTransport->RxDataSignal(stream_)); // wait
     216            0 :         CHK_RET(prevTransport->RxWaitDone(stream_));
     217              :     }
     218            0 :     if (curSendBytes > 0) {
     219            0 :         CHK_RET(nextTransport->TxWaitDone(stream_));
     220              :     }
     221            0 :     return HCCL_SUCCESS;
     222              : }
     223              : 
     224            0 : HcclResult AlltoAllVPairWise::SendRecv(TxMemoryInfo txMemoryInfo, RxMemoryInfo rxMemoryInfo,
     225              :     std::shared_ptr<Transport> prevTransport, std::shared_ptr<Transport> nextTransport)
     226              : {
     227              :     // send payload + notify
     228            0 :     CHK_RET(nextTransport->TxAsync(txMemoryInfo.dstMemType, txMemoryInfo.dstOffset, txMemoryInfo.src,
     229              :         txMemoryInfo.len, stream_));
     230            0 :     CHK_RET(prevTransport->RxAsync(rxMemoryInfo.srcMemType, rxMemoryInfo.srcOffset, rxMemoryInfo.dst,
     231              :         rxMemoryInfo.len, stream_));
     232            0 :     CHK_RET(prevTransport->TxAck(stream_)); // record
     233            0 :     CHK_RET(nextTransport->RxAck(stream_)); // wait
     234            0 :     CHK_RET(nextTransport->TxDataSignal(stream_)); // record
     235            0 :     CHK_RET(prevTransport->RxDataSignal(stream_)); // wait
     236            0 :     CHK_RET(prevTransport->RxWaitDone(stream_));
     237            0 :     CHK_RET(nextTransport->TxWaitDone(stream_));
     238            0 :     return HCCL_SUCCESS;
     239              : }
     240              : 
     241            0 : HcclResult AlltoAllVPairWise::RunZCopyAlltoAll(const u32 rank, const u32 rankSize, const std::vector<LINK> &links)
     242              : {
     243            0 :     for (u32 i = 1; i < rankSize; i++) {
     244            0 :         u32 prevRank = (rank + rankSize - i) % rankSize;
     245            0 :         u32 nextRank = (rank + i) % rankSize;
     246            0 :         std::shared_ptr<Transport> prevTransport = links[prevRank];
     247            0 :         std::shared_ptr<Transport> nextTransport = links[nextRank];
     248              : 
     249            0 :         CHK_SMART_PTR_NULL(prevTransport);
     250            0 :         CHK_SMART_PTR_NULL(nextTransport);
     251              : 
     252            0 :         HCCL_DEBUG("[AlltoAllVPairWise][RunZCopyAlltoAll]: prevRank[%u] nextRank[%u], step[%u]", prevRank, nextRank, i);
     253              : 
     254            0 :         CHK_RET(prevTransport->TxAck(stream_)); // transport sync record
     255            0 :         CHK_RET(nextTransport->RxAck(stream_)); // transport sync wait
     256              : 
     257            0 :         u64 sendBytes = sendBuffer_.counts[nextRank] * sendDataUnitBytes_;
     258            0 :         u64 recvBytes = recvBuffer_.counts[prevRank] * recvDataUnitBytes_;
     259            0 :         u64 sendDispBytes = sendBuffer_.displs[nextRank] * sendDataUnitBytes_;
     260            0 :         u64 recvDispBytes = recvBuffer_.displs[prevRank] * recvDataUnitBytes_;
     261            0 :         u8 *sendAddr = reinterpret_cast<u8 *>(sendBuffer_.mem.ptr()) + sendDispBytes;
     262            0 :         u8 *recvAddr = reinterpret_cast<u8 *>(recvBuffer_.mem.ptr()) + recvDispBytes;
     263              : 
     264            0 :         u64 dstOffset = rankRecvDisplsMapPtr_->at(nextRank)[rank];
     265            0 :         u64 srcOffset = rankSendDisplsMapPtr_->at(prevRank)[rank];
     266              : 
     267            0 :         TxMemoryInfo txMemoryInfo{UserMemType::OUTPUT_MEM, dstOffset, sendAddr, sendBytes};
     268            0 :         RxMemoryInfo rxMemoryInfo{UserMemType::INPUT_MEM, srcOffset, recvAddr, recvBytes};
     269              : 
     270            0 :         HCCL_DEBUG("[AlltoAllVPairWise][RunZCopyAlltoAll]: sendBytes[%llu] recvBytes[%llu] sendDispBytes[%llu]" \
     271              :             " dstOffset[%llu]", sendBytes, recvBytes, sendDispBytes, dstOffset);
     272            0 :         HcclResult ret = SendRecv(txMemoryInfo, rxMemoryInfo, prevTransport, nextTransport);
     273            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     274              :             HCCL_ERROR("[AlltoAllVPairWise][RunZCopyAlltoAll]errNo[0x%016llx] "\
     275              :             "sendBytes[%llu] recvBytes[%llu] sendAddr[%p] dstOffset[%llu]",
     276              :             HCCL_ERROR_CODE(ret), sendBytes, recvBytes, sendAddr, dstOffset),
     277              :             ret);
     278            0 :     }
     279              : 
     280            0 :     return HCCL_SUCCESS;
     281              : }
     282            0 : HcclResult AlltoAllVPairWise::GetNslbAdjInfo(const u32 rank, const u32 rankSize,
     283              :                                          const std::vector<LINK> &links, AdjInfo& nslbAdjInfo)
     284              : {
     285              :     (void) links;
     286            0 :     for (u32 i = 1; i < rankSize; i++) {
     287            0 :         u32 nextRank = (rank + i) % rankSize;
     288            0 :         if (i < NSLBDP_PAIRWISE_MAXPHASE) {
     289            0 :             NslbDpAdjInfo adjInfoStep = {0};
     290            0 :             adjInfoStep.dstLocalRankId = nextRank;
     291            0 :             adjInfoStep.phaseId = i;
     292            0 :             adjInfoStep.rev = 0;
     293            0 :             HCCL_INFO("AlltoAllVPairWise-nslb: adjInfoStep.phaseId[%u], remoteuserRank[%u]", adjInfoStep.phaseId, nextRank);
     294            0 :             nslbAdjInfo.nsAdjInfo.push_back(adjInfoStep);
     295              :         }
     296              :     }
     297            0 :     nslbAdjInfo.dstRankNum = nslbAdjInfo.nsAdjInfo.size();
     298              : 
     299            0 :     return HCCL_SUCCESS;
     300              : }
     301              : REGISTER_TEMPLATE(TemplateType::TEMPLATE_ALL_2_ALL_V_PAIRWISE, AlltoAllVPairWise);
     302              : } // namespace hccl
        

Generated by: LCOV version 2.0-1