LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/coll_alg_factory/alg_ccu_context/broadcast - ccu_context_broadcast_nhr1d_mem2mem.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 216 0
Test Date: 2026-08-18 17:47:01 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 "ccu_context_broadcast_nhr1d_mem2mem.h"
      12              : 
      13              : namespace Hccl {
      14              : 
      15              : constexpr uint16_t TOKEN_XN_ID = 2;
      16              : constexpr uint16_t OUTPUT_XN_ID = 1;
      17              : constexpr uint16_t RANK_NUM_PER_CKE = 16; // 本rank给远端置位时应当写的CKE,16个对端一个CKE
      18              : constexpr uint16_t CKE_IDX_0 = 0;         // 后同步
      19              : constexpr uint16_t CKE_IDX_1 = 1;         // 前同步addr
      20              : constexpr uint16_t CKE_IDX_2 = 2;         // 前同步token
      21              : constexpr uint16_t CKE_IDX_3 = 3;         // NHR step同步信号0,用于RS前同步,AG后同步
      22              : constexpr uint16_t CKE_IDX_4 = 4;         // NHR step同步信号1,用于RS后同步
      23              : constexpr uint16_t FST_AXIS_ID = 0;
      24              : constexpr uint16_t SEC_AXIS_ID = 1;
      25              : 
      26            0 : CcuContextBroadcastNHRMem2Mem1D::CcuContextBroadcastNHRMem2Mem1D(
      27            0 :     const CcuCtxArg& arg, const std::vector<CcuTransport*>& transports, const CcuTransportGroup& group)
      28            0 :     : CcuContextAlgBase(arg, transports, group)
      29              : {
      30            0 :     const CcuCtxArgBroadcastNHRMem2Mem1D* ctxArg = dynamic_cast<const CcuCtxArgBroadcastNHRMem2Mem1D*>(&arg);
      31            0 :     rankId_ = ctxArg->rankId_;
      32            0 :     axisId_ = ctxArg->axisId_;
      33            0 :     axisSize_ = ctxArg->axisSize_;
      34            0 :     dimSize_ = ctxArg->dimSize_[0];
      35            0 :     localAxisSignalName_ = "CcuContextBroadcastNHR1DDieSync_" + std::to_string(axisId_);
      36            0 :     anotherAxisSignalName_ = "CcuContextBroadcastNHR1DDieSync_" + std::to_string(1 - axisId_);
      37            0 :     stepInfoVector_ = ctxArg->stepInfoVector_;
      38            0 :     indexMap_ = ctxArg->indexMap_;
      39            0 :     localSize_ = indexMap_.size();
      40            0 :     myRankIdx_ = indexMap_.size();
      41            0 :     dataType_ = ctxArg->op_.dataType;
      42            0 :     signalNum_ = (dimSize_ + RANK_NUM_PER_CKE - 1) / RANK_NUM_PER_CKE; // 每个CKE有16个bit
      43            0 :     HCCL_INFO(
      44              :         "[CcuContextBroadcastNHRMem2Mem1D] CtxArg: rankId_[%u], axisId_[%u], axisSize_[%u], dimSize_[%u], "
      45              :         "localSize_[%u], "
      46              :         "signalNum_[%u], dataType[%s]",
      47              :         rankId_, axisId_, axisSize_, dimSize_, localSize_, signalNum_, dataType_.Describe().c_str());
      48            0 : }
      49              : 
      50            0 : void CcuContextBroadcastNHRMem2Mem1D::InitResources()
      51              : {
      52            0 :     die0Size_ = CreateVariable();
      53            0 :     die1Size_ = CreateVariable();
      54            0 :     die0SliceSize_ = CreateVariable();
      55            0 :     die1SliceSize_ = CreateVariable();
      56            0 :     die0LastSliceSize_ = CreateVariable();
      57            0 :     die1LastSliceSize_ = CreateVariable();
      58            0 :     localAxisSignal_ = CreateMaskSignal();
      59            0 :     localSignal_ = CreateMaskSignal();
      60              : 
      61            0 :     if (axisSize_ > 1) {
      62            0 :         anotherAxisSignal_ = CreateMaskSignal();
      63              : 
      64            0 :         ExportMaskSignal(localAxisSignal_, localAxisSignalName_);
      65            0 :         anotherAxisSignal_ = ImportMaskSignal(anotherAxisSignalName_);
      66              :     }
      67              : 
      68            0 :     input_ = CreateVariable();
      69            0 :     for (uint32_t transportIdx = 0; transportIdx < localSize_; transportIdx++) {
      70            0 :         HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] MyRank[%u], TransportId[%u]", rankId_, transportIdx);
      71            0 :         CHK_PRT_RET(
      72              :             transports[transportIdx] == nullptr,
      73              :             HCCL_ERROR("[CcuContextBroadcastNHRMem2Mem1D] Algorithm transport ptr is null"), );
      74            0 :         output_.push_back(
      75            0 :             CreateVariable((*transports[transportIdx]), OUTPUT_XN_ID)); // 获取transport中id=1的Var来传递output
      76            0 :         token_.push_back(CreateVariable((*transports[transportIdx]), TOKEN_XN_ID));
      77              :     }
      78            0 :     output_.push_back(CreateVariable());
      79            0 :     token_.push_back(CreateVariable());
      80              : 
      81            0 :     srcMem_ = CreateMemory();
      82            0 :     dstMem_ = CreateMemory();
      83              : 
      84            0 :     CcuRep::Variable tmpSliceOffset = CreateVariable();
      85            0 :     tmpSliceOffset = 0;
      86              : 
      87            0 :     for (u64 i = 0; i < dimSize_; i++) {
      88            0 :         sliceOffset_.push_back(CreateVariable());
      89            0 :         sliceOffset_[i] = tmpSliceOffset;
      90            0 :         tmpSliceOffset += axisId_ == 0 ? die0SliceSize_ : die1SliceSize_;
      91              :     }
      92              : 
      93            0 :     HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] InitResources finished");
      94            0 : }
      95              : 
      96            0 : void CcuContextBroadcastNHRMem2Mem1D::LoadArgs()
      97              : {
      98            0 :     Load(input_);
      99            0 :     Load(output_[myRankIdx_]);
     100            0 :     Load(token_[myRankIdx_]);
     101            0 :     Load(die0Size_);
     102            0 :     Load(die1Size_);
     103            0 :     Load(die0SliceSize_);
     104            0 :     Load(die1SliceSize_);
     105            0 :     Load(die0LastSliceSize_);
     106            0 :     Load(die1LastSliceSize_);
     107            0 :     HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] LoadArgs run finished");
     108            0 : }
     109              : 
     110            0 : void CcuContextBroadcastNHRMem2Mem1D::AxisSync(uint32_t signalIndex)
     111              : {
     112            0 :     const uint32_t DIE_NUM = 2;
     113            0 :     if (signalIndex > 1) {
     114            0 :         THROW<InvalidParamsException>(
     115            0 :             StringFormat("[CcuContextBroadcastNHRMem2Mem1D] Unexpected SignalInex[%u]", signalIndex));
     116              :     }
     117            0 :     LocalCtxPost(anotherAxisSignal_, 1 << (axisId_ + signalIndex * DIE_NUM));
     118            0 :     LocalWait(localAxisSignal_, 1 << (1 - axisId_ + signalIndex * DIE_NUM));
     119            0 :     HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] AxisSync run finished");
     120            0 :     return;
     121              : }
     122              : 
     123            0 : void CcuContextBroadcastNHRMem2Mem1D::PreSync()
     124              : {
     125            0 :     HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] PreSync start");
     126            0 :     uint16_t selfSignalId = rankId_ / RANK_NUM_PER_CKE;
     127            0 :     uint16_t selfBit = 1 << (rankId_ % RANK_NUM_PER_CKE);
     128            0 :     for (auto t : transports) {
     129            0 :         WriteVariableWithSignal(*t, output_[localSize_], OUTPUT_XN_ID, selfSignalId + signalNum_ * CKE_IDX_1, selfBit);
     130            0 :         WriteVariableWithSignal(*t, token_[localSize_], TOKEN_XN_ID, selfSignalId + signalNum_ * CKE_IDX_2, selfBit);
     131              :     }
     132            0 :     std::vector<uint16_t> waitBitVector(signalNum_, 0);
     133            0 :     for (auto& pair : indexMap_) {
     134            0 :         uint16_t pairSignalId = pair.first / RANK_NUM_PER_CKE;
     135            0 :         uint16_t pairBit = 1 << (pair.first % RANK_NUM_PER_CKE);
     136            0 :         waitBitVector[pairSignalId] = waitBitVector[pairSignalId] | pairBit;
     137              :     }
     138            0 :     for (uint16_t sId = 0; sId < waitBitVector.size(); sId++) {
     139            0 :         GroupWait(*transportGroup, sId + signalNum_ * CKE_IDX_1, waitBitVector[sId]);
     140            0 :         GroupWait(*transportGroup, sId + signalNum_ * CKE_IDX_2, waitBitVector[sId]);
     141              :     }
     142            0 :     HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] PreSync end");
     143            0 : }
     144              : 
     145            0 : void CcuContextBroadcastNHRMem2Mem1D::PostSync()
     146              : {
     147            0 :     uint16_t selfSignalId = rankId_ / RANK_NUM_PER_CKE;
     148            0 :     uint16_t selfBit = 1 << (rankId_ % RANK_NUM_PER_CKE);
     149            0 :     for (auto& t : transports) {
     150            0 :         RemotePost(*t, selfSignalId + signalNum_ * CKE_IDX_0, selfBit);
     151              :     }
     152            0 :     std::vector<uint16_t> waitBitVector(signalNum_, 0);
     153            0 :     for (auto& pair : indexMap_) {
     154            0 :         uint16_t pairSignalId = pair.first / RANK_NUM_PER_CKE;
     155            0 :         uint16_t pairBit = 1 << (pair.first % RANK_NUM_PER_CKE);
     156            0 :         waitBitVector[pairSignalId] = waitBitVector[pairSignalId] | pairBit;
     157              :     }
     158            0 :     for (uint32_t sId = 0; sId < signalNum_; sId++) {
     159            0 :         GroupWait(*transportGroup, sId + signalNum_ * CKE_IDX_0, waitBitVector[sId]);
     160              :     }
     161            0 :     HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] PostSync run finished");
     162            0 : }
     163              : 
     164            0 : void CcuContextBroadcastNHRMem2Mem1D::DoScatterNHR()
     165              : {
     166            0 :     const uint32_t NHR_NUM = 2;
     167            0 :     for (u64 i = 0; i < stepInfoVector_.size() / NHR_NUM; i++) {
     168            0 :         const NHRStepInfo& nhrStepInfo = stepInfoVector_[i];
     169            0 :         DoScatterNHRSingleStep(nhrStepInfo);
     170              :     }
     171            0 : }
     172              : 
     173            0 : void CcuContextBroadcastNHRMem2Mem1D::DoScatterNHRSingleStep(const NHRStepInfo& nhrStepInfo)
     174              : {
     175            0 :     const std::vector<u32>& sendSliceIdxList = nhrStepInfo.txSliceIdxs;
     176            0 :     const std::vector<u32>& recvSliceIdxList = nhrStepInfo.rxSliceIdxs;
     177              :     // 只需要发
     178            0 :     if (sendSliceIdxList.size() != 0) {
     179            0 :         u32& toRankIdx = indexMap_[nhrStepInfo.toRank];
     180            0 :         u32 sendSliceIdx = 0;
     181            0 :         CcuTransport* sendTransport = transports[toRankIdx];
     182            0 :         srcMem_.token = token_[myRankIdx_];
     183            0 :         dstMem_.token = token_[toRankIdx];
     184              : 
     185            0 :         uint16_t selfSignalId = rankId_ / RANK_NUM_PER_CKE;
     186            0 :         uint16_t selfBit = 1 << (rankId_ % RANK_NUM_PER_CKE);
     187              : 
     188            0 :         for (u32 i = 0; i < sendSliceIdxList.size(); i++) {
     189            0 :             sendSliceIdx = sendSliceIdxList[i];
     190              : 
     191            0 :             if (i != 0) {
     192            0 :                 if (i % RANK_NUM_PER_CKE == 0) {
     193            0 :                     LocalWait(localSignal_, (1 << RANK_NUM_PER_CKE) - 1);
     194              :                 }
     195              :             }
     196              : 
     197            0 :             if (nhrStepInfo.step == 0) {
     198              :                 // 只有第0步的源数据从input中取
     199            0 :                 HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] nhrStepInfo 0.");
     200            0 :                 srcMem_.addr = input_;
     201            0 :                 srcMem_.addr += sliceOffset_[sendSliceIdx];
     202              :             } else {
     203            0 :                 srcMem_.addr = output_[myRankIdx_];
     204            0 :                 srcMem_.addr += sliceOffset_[sendSliceIdx];
     205              :             }
     206              : 
     207            0 :             dstMem_.addr = output_[toRankIdx];
     208            0 :             dstMem_.addr += sliceOffset_[sendSliceIdx];
     209              : 
     210            0 :             DoSendRecvSlice(nhrStepInfo.toRank, srcMem_, dstMem_, sendSliceIdx, i % RANK_NUM_PER_CKE);
     211              :         }
     212              : 
     213            0 :         LocalWait(localSignal_, (1 << (sendSliceIdxList.size() % RANK_NUM_PER_CKE)) - 1);
     214              : 
     215              :         // 通知toRank数据写入完毕
     216            0 :         RemotePost(*sendTransport, selfSignalId + signalNum_ * CKE_IDX_4, selfBit, true);
     217              :     }
     218              : 
     219              :     // 只需要收
     220            0 :     if (recvSliceIdxList.size() != 0) {
     221            0 :         u32& fromRankIdx = indexMap_[nhrStepInfo.fromRank];
     222            0 :         CcuTransport* recvTransport = transports[fromRankIdx];
     223              : 
     224            0 :         uint16_t recvSignalId = nhrStepInfo.fromRank / RANK_NUM_PER_CKE;
     225            0 :         uint16_t recvBit = 1 << (nhrStepInfo.fromRank % RANK_NUM_PER_CKE);
     226            0 :         RemoteWait(*recvTransport, recvSignalId + signalNum_ * CKE_IDX_4, recvBit);
     227              :     }
     228            0 : }
     229              : 
     230            0 : void CcuContextBroadcastNHRMem2Mem1D::DoSendRecvSlice(
     231              :     const u32& toRank, CcuRep::Memory& src, CcuRep::Memory& dst, const u32& sendSliceIdx, u32 signalIndex)
     232              : {
     233            0 :     CcuTransport* sendTransport = transports[indexMap_[toRank]];
     234              :     bool islastSlice;
     235              : 
     236              :     // 添加 die1 偏移
     237            0 :     if (axisId_ == 1) {
     238            0 :         src.addr += die0Size_;
     239            0 :         dst.addr += die0Size_;
     240              :     }
     241              : 
     242            0 :     islastSlice = (sendSliceIdx + 1 == dimSize_);
     243            0 :     const CcuRep::Variable& sliceSize = axisId_ == 0 ? (islastSlice ? die0LastSliceSize_ : die0SliceSize_) :
     244              :                                                        (islastSlice ? die1LastSliceSize_ : die1SliceSize_);
     245              : 
     246            0 :     CCU_IF(sliceSize == 0) { LocalPost(localSignal_, 1 << signalIndex); }
     247              : 
     248            0 :     CCU_IF(sliceSize != 0) { Write(*sendTransport, dst, src, sliceSize, localSignal_, 1 << signalIndex); }
     249            0 : }
     250              : 
     251            0 : void CcuContextBroadcastNHRMem2Mem1D::DoAllGatherNHR()
     252              : {
     253            0 :     const uint32_t NHR_NUM = 2;
     254            0 :     for (u64 i = stepInfoVector_.size() / NHR_NUM; i < stepInfoVector_.size(); i++) {
     255            0 :         const NHRStepInfo& nhrStepInfo = stepInfoVector_[i];
     256            0 :         DoAllGatherNHRSingleStep(nhrStepInfo);
     257              :     }
     258            0 : }
     259              : 
     260            0 : void CcuContextBroadcastNHRMem2Mem1D::DoAllGatherNHRSingleStep(const NHRStepInfo& nhrStepInfo)
     261              : {
     262            0 :     u32& toRankIdx = indexMap_[nhrStepInfo.toRank];
     263            0 :     u32& fromRankIdx = indexMap_[nhrStepInfo.fromRank];
     264            0 :     u32 sendSliceIdx = 0;
     265            0 :     CcuTransport* sendTransport = transports[toRankIdx];
     266            0 :     CcuTransport* recvTransport = transports[fromRankIdx];
     267            0 :     const std::vector<u32>& sendSliceIdxList = nhrStepInfo.txSliceIdxs;
     268            0 :     dstMem_.token = token_[toRankIdx];
     269            0 :     srcMem_.token = token_[myRankIdx_];
     270              : 
     271            0 :     uint16_t selfSignalId = rankId_ / RANK_NUM_PER_CKE;
     272            0 :     uint16_t selfBit = 1 << (rankId_ % RANK_NUM_PER_CKE);
     273              : 
     274            0 :     for (u32 i = 0; i < sendSliceIdxList.size(); i++) {
     275            0 :         sendSliceIdx = sendSliceIdxList[i];
     276              : 
     277            0 :         if (i != 0) {
     278            0 :             if (i % RANK_NUM_PER_CKE == 0) {
     279            0 :                 LocalWait(localSignal_, (1 << RANK_NUM_PER_CKE) - 1);
     280              :             }
     281              :         }
     282              : 
     283            0 :         srcMem_.addr = output_[myRankIdx_];
     284            0 :         srcMem_.addr += sliceOffset_[sendSliceIdx];
     285              : 
     286            0 :         dstMem_.addr = output_[toRankIdx];
     287            0 :         dstMem_.addr += sliceOffset_[sendSliceIdx];
     288            0 :         DoSendRecvSlice(nhrStepInfo.toRank, srcMem_, dstMem_, sendSliceIdx, i % RANK_NUM_PER_CKE);
     289              :     }
     290              : 
     291            0 :     LocalWait(localSignal_, (1 << (sendSliceIdxList.size() % RANK_NUM_PER_CKE)) - 1);
     292              : 
     293            0 :     if (nhrStepInfo.step + 1 != stepInfoVector_.size()) { // 最后一步不需要同步
     294              :         // 通知toRank,写入完毕
     295            0 :         RemotePost(*sendTransport, selfSignalId + signalNum_ * CKE_IDX_3, selfBit, true);
     296              :         // 等待fromRank通知写入完毕
     297            0 :         uint16_t recvSignalId = nhrStepInfo.fromRank / RANK_NUM_PER_CKE;
     298            0 :         uint16_t recvBit = 1 << (nhrStepInfo.fromRank % RANK_NUM_PER_CKE);
     299            0 :         RemoteWait(*recvTransport, recvSignalId + signalNum_ * CKE_IDX_3, recvBit);
     300              :     }
     301              : 
     302            0 :     HCCL_DEBUG(
     303              :         "[DoAllGatherNHRSingleStep] rank %u step %u, toRank=%u, fromRank=%u, nSlice=%lu", rankId_, nhrStepInfo.step,
     304              :         nhrStepInfo.toRank, nhrStepInfo.fromRank, sendSliceIdxList.size());
     305            0 : }
     306              : 
     307            0 : void CcuContextBroadcastNHRMem2Mem1D::Algorithm()
     308              : {
     309            0 :     HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] BroadcastNHR1D run");
     310              : 
     311            0 :     InitResources();
     312            0 :     LoadArgs();
     313            0 :     if (axisSize_ > 1) {
     314            0 :         AxisSync(FST_AXIS_ID);
     315              :     }
     316            0 :     PreSync();
     317            0 :     DoScatterNHR();
     318            0 :     DoAllGatherNHR();
     319            0 :     PostSync();
     320            0 :     if (axisSize_ > 1) {
     321            0 :         AxisSync(SEC_AXIS_ID);
     322              :     }
     323              : 
     324            0 :     HCCL_INFO("[CcuContextBroadcastNHRMem2Mem1D] BroadcastNHR1D end");
     325            0 :     return;
     326              : }
     327              : 
     328            0 : std::vector<uint64_t> CcuContextBroadcastNHRMem2Mem1D::GeneArgs(const CcuTaskArg& arg)
     329              : {
     330            0 :     const CcuTaskArgBroadcastNHRMem2Mem1D* taskArg = dynamic_cast<const CcuTaskArgBroadcastNHRMem2Mem1D*>(&arg);
     331            0 :     if (taskArg == nullptr) {
     332            0 :         THROW<NullPtrException>(StringFormat("CcuContextBroadcastNHRMem2Mem1D::taskArg ptr is null"));
     333              :     }
     334              :     // input&output&buffer地址
     335            0 :     uint64_t inputAddr = taskArg->inputAddr_;
     336            0 :     uint64_t outputAddr = taskArg->outputAddr_;
     337            0 :     uint64_t token = taskArg->token_;
     338            0 :     uint64_t die0Size = taskArg->die0Size_;
     339            0 :     uint64_t die1Size = taskArg->die1Size_;
     340            0 :     uint64_t die0SliceSize = taskArg->die0SliceSize_;
     341            0 :     uint64_t die1SliceSize = taskArg->die1SliceSize_;
     342            0 :     uint64_t die0LastSliceSize = taskArg->die0LastSliceSize_;
     343            0 :     uint64_t die1LastSliceSize = taskArg->die1LastSliceSize_;
     344              : 
     345            0 :     HCCL_INFO(
     346              :         "[CcuContextBroadcastNHRMem2Mem1D] TaskArgs: inputAddr[%llu], outputAddr[%llu], "
     347              :         "die0Size[%llu], die1Size[%llu], die0SliceSize[%llu], die1SliceSize[%llu],"
     348              :         "die0LastSliceSize[%llu], die1LastSliceSize[%llu]",
     349              :         inputAddr, outputAddr, die0Size, die1Size, die0SliceSize, die1SliceSize, die0LastSliceSize, die1LastSliceSize);
     350              : 
     351              :     return {inputAddr,         outputAddr,       token, die0Size, die1Size, die0SliceSize, die1SliceSize,
     352            0 :             die0LastSliceSize, die1LastSliceSize};
     353              : }
     354              : 
     355              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1