LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/alg_template/temp_all_gather - all_gather_mesh_direct.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 98 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 9 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 "all_gather_mesh_direct.h"
      12              : #include "alg_template_register.h"
      13              : // userin -> dmaout -> userout
      14              : namespace hccl {
      15            0 : AllgatherMeshDirect::AllgatherMeshDirect(const HcclDispatcher dispatcher) : AlgTemplateBase(dispatcher) {}
      16              : 
      17            0 : AllgatherMeshDirect::~AllgatherMeshDirect() {}
      18              : 
      19            0 : HcclResult AllgatherMeshDirect::Prepare(
      20              :     std::vector<Stream>& meshStreams, std::vector<std::shared_ptr<LocalNotify>>& meshSignal,
      21              :     std::vector<std::shared_ptr<LocalNotify>>& meshSignalAux, u32 userRank, HcomCollOpInfo* opInfo, u32 interRank,
      22              :     u32 interRankSize)
      23              : {
      24            0 :     meshStreams_ = meshStreams;
      25            0 :     meshSignal_ = &meshSignal;
      26            0 :     meshSignalAux_ = &meshSignalAux;
      27            0 :     opInfo_ = opInfo;
      28            0 :     interRank_ = interRank;
      29            0 :     interRankSize_ = interRankSize;
      30            0 :     userRank_ = userRank;
      31            0 :     return HCCL_SUCCESS;
      32              : }
      33              : 
      34            0 : HcclResult AllgatherMeshDirect::MainRecordSub()
      35              : {
      36            0 :     for (u32 signalIndex = 0; signalIndex < (*meshSignalAux_).size(); signalIndex++) {
      37            0 :         CHK_RET(LocalNotify::Post(stream_, dispatcher_, (*meshSignalAux_)[signalIndex], profilerInput_.stage));
      38              :     }
      39            0 :     return HCCL_SUCCESS;
      40              : }
      41              : 
      42            0 : HcclResult AllgatherMeshDirect::SubWaitMain()
      43              : {
      44            0 :     for (u32 streamIndex = 0; streamIndex < (*meshSignalAux_).size(); streamIndex++) {
      45            0 :         CHK_RET(LocalNotify::Wait(
      46              :             meshStreams_[streamIndex], dispatcher_, (*meshSignalAux_)[streamIndex], profilerInput_.stage));
      47              :     }
      48            0 :     return HCCL_SUCCESS;
      49              : }
      50              : 
      51            0 : HcclResult AllgatherMeshDirect::MainWaitSub()
      52              : {
      53            0 :     for (u32 signalIndex = 0; signalIndex < (*meshSignal_).size(); signalIndex++) {
      54            0 :         CHK_RET(LocalNotify::Wait(stream_, dispatcher_, (*meshSignal_)[signalIndex], profilerInput_.stage));
      55              :     }
      56            0 :     return HCCL_SUCCESS;
      57              : }
      58              : 
      59            0 : HcclResult AllgatherMeshDirect::SubRecordMain()
      60              : {
      61            0 :     for (u32 streamIndex = 0; streamIndex < (*meshSignal_).size(); streamIndex++) {
      62            0 :         CHK_RET(LocalNotify::Post(
      63              :             meshStreams_[streamIndex], dispatcher_, (*meshSignal_)[streamIndex], profilerInput_.stage));
      64              :     }
      65            0 :     return HCCL_SUCCESS;
      66              : }
      67              : 
      68              : // allgather的入口函数
      69            0 : HcclResult AllgatherMeshDirect::RunAsync(const u32 rank, const u32 rankSize, const std::vector<LINK>& links)
      70              : {
      71            0 :     CHK_SMART_PTR_NULL(dispatcher_);
      72            0 :     CHK_PTR_NULL(stream_.ptr());
      73            0 :     HCCL_INFO(
      74              :         "AllGatherMeshDirect run: rank[%u] totalrank[%u] inputMem[%p] outputMem[%p] count[%llu]", rank, rankSize,
      75              :         inputMem_.ptr(), outputMem_.ptr(), count_);
      76              : 
      77            0 :     char* curUerMemInPtr = static_cast<char*>(opInfo_->inputAddr);
      78            0 :     char* curUerMemOutPtr = static_cast<char*>(opInfo_->outputAddr);
      79            0 :     char* curCommMemOutPtr = static_cast<char*>(outputMem_.ptr());
      80              : 
      81            0 :     u32 unitSize = DataUnitSize(dataType_);
      82            0 :     u64 curSize = count_ * unitSize;           // 当前count
      83            0 :     u64 sliceSize = opInfo_->count * unitSize; // 总输入count
      84              : 
      85            0 :     if (rankSize == 1) {
      86            0 :         if (opInfo_->inputAddr != opInfo_->outputAddr) {
      87            0 :             HCCL_DEBUG("rank[%u] mem copy async from input to output", rank);
      88            0 :             DeviceMem userMemIn = DeviceMem::create(curUerMemInPtr, curSize);
      89            0 :             DeviceMem userMemOut = DeviceMem::create(curUerMemOutPtr, curSize);
      90            0 :             CHK_RET(HcclD2DMemcpyAsync(dispatcher_, userMemOut, userMemIn, stream_));
      91            0 :         }
      92            0 :         return HCCL_SUCCESS;
      93              :     }
      94              : 
      95            0 :     DeviceMem emptyMem = outputMem_.range(0, 0);
      96              : 
      97            0 :     std::vector<Slice> inputSlices(slices_);
      98            0 :     if (slices_.size() == 0) {
      99              :         // slices_为空,临时构造等长slices
     100            0 :         slices_.resize(interRankSize_);
     101            0 :         inputSlices.resize(interRankSize_);
     102              : 
     103            0 :         for (u32 i = 0; i < interRankSize_; i++) {
     104            0 :             slices_[i].size = curSize;
     105            0 :             slices_[i].offset = (i * sliceSize);
     106              : 
     107            0 :             inputSlices[i].size = curSize;
     108            0 :             inputSlices[i].offset = (inputMem_.size() < outputMem_.size()) ? 0 : (sliceSize * i);
     109              :         }
     110              :     } else {
     111              :         // allgather_v场景下走else分支,每张卡的数据在CCLbuffer上偏移地址相同
     112            0 :         for (u32 i = 0; i < interRankSize_; i++) {
     113            0 :             inputSlices[i].offset = 0;
     114              :         }
     115              :     }
     116              : 
     117            0 :     for (u32 i = 0; i < interRankSize_; i++) {
     118            0 :         HCCL_DEBUG(
     119              :             "[AllGatherMeshDirect][Slice]: rank[%u], outputslice: size[%llu] offset[%llu] "
     120              :             "inputslice: size[%llu] offset[%llu]",
     121              :             i, slices_[i].size, slices_[i].offset, inputSlices[i].size, inputSlices[i].offset);
     122              :     }
     123              : 
     124            0 :     DeviceMem src;
     125            0 :     DeviceMem dst;
     126            0 :     src = DeviceMem::create(curUerMemInPtr, inputSlices[rank].size);
     127            0 :     u64 localOffsetByte = inputSlices[rank].offset % HCCL_MIN_SLICE_ALIGN_910B;
     128            0 :     dst = DeviceMem::create(curCommMemOutPtr + localOffsetByte, inputSlices[rank].size);
     129            0 :     CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dst, src, stream_));
     130              : 
     131            0 :     CHK_RET(MainRecordSub());
     132            0 :     CHK_RET(SubWaitMain());
     133              : 
     134            0 :     for (u32 round = 1; round < rankSize; round++) {
     135            0 :         u32 dstRank = BackwardRank(rank, rankSize, round);
     136            0 :         Stream& subStream = meshStreams_[round - 1];
     137            0 :         CHK_RET(links[dstRank]->TxAck(subStream));
     138            0 :         CHK_RET(links[dstRank]->RxAck(subStream));
     139              :     }
     140              : 
     141            0 :     HCCL_DEBUG("[AllgatherMeshDirect]runAsync now rankSize is %u", rankSize);
     142            0 :     CHK_RET(SubRecordMain());
     143            0 :     CHK_RET(MainWaitSub());
     144              : 
     145            0 :     CHK_RET(HcclD2DMemcpyAsync(dispatcher_, emptyMem, emptyMem, stream_));
     146              : 
     147            0 :     CHK_RET(SubWaitMain());
     148            0 :     CHK_RET(MainRecordSub());
     149              : 
     150            0 :     src = dst;
     151            0 :     dst = DeviceMem::create(curUerMemOutPtr + slices_[rank].offset, slices_[rank].size);
     152            0 :     CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dst, src, stream_));
     153              : 
     154            0 :     for (u32 round = 1; round < rankSize; round++) {
     155            0 :         u32 dstRank = BackwardRank(rank, rankSize, round);
     156            0 :         Stream& subStream = meshStreams_[round - 1];
     157              :         // 本rank要收数据
     158            0 :         void* remMemPtr = nullptr;
     159              :         // DMA消减场景,从对端的ccl out内存拿数据到本端的user out
     160            0 :         CHK_RET(links[dstRank]->GetRemoteMem(UserMemType::OUTPUT_MEM, &remMemPtr));
     161            0 :         u64 remoteOffsetByte = inputSlices[dstRank].offset % HCCL_MIN_SLICE_ALIGN_910B;
     162            0 :         src = DeviceMem::create(static_cast<char*>(remMemPtr) + remoteOffsetByte, inputSlices[dstRank].size);
     163            0 :         dst = DeviceMem::create(curUerMemOutPtr + slices_[dstRank].offset, slices_[dstRank].size);
     164            0 :         CHK_RET(HcclD2DMemcpyAsync(
     165              :             dispatcher_, dst, src, subStream, links[dstRank]->GetRemoteRank(), links[dstRank]->GetLinkType()));
     166            0 :         CHK_RET(links[dstRank]->TxDataSignal(subStream));
     167            0 :         CHK_RET(links[dstRank]->RxDataSignal(subStream));
     168              :     }
     169            0 :     CHK_RET(SubRecordMain());
     170            0 :     CHK_RET(MainWaitSub());
     171            0 :     CHK_RET(HcclD2DMemcpyAsync(dispatcher_, emptyMem, emptyMem, stream_));
     172              : 
     173            0 :     HCCL_INFO("AllGatherMeshDirect finished: rank[%u]", rank);
     174            0 :     return HCCL_SUCCESS;
     175            0 : }
     176              : REGISTER_TEMPLATE(TemplateType::TEMPLATE_ALL_GATHER_MESH_DIRECT, AllgatherMeshDirect);
     177              : } // namespace hccl
        

Generated by: LCOV version 2.0-1