LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/coll_alg_factory/alg_template/ccu_alg_template - ccu_temp_all_to_all_mesh2d.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 83.8 % 105 88
Test Date: 2026-07-28 12:11:00 Functions: 88.9 % 9 8

            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 <ios>
      12              : #include <iostream>
      13              : 
      14              : #include "log.h"
      15              : #include "ccu_temp_all_to_all_mesh2d.h"
      16              : #include "ccu_rank_group.h"
      17              : #include "ccu_ctx_creator_registry.h"
      18              : #include "ccu_context_all_to_all_mesh2d.h"
      19              : #include "ccu_ins_group.h"
      20              : 
      21              : namespace Hccl {
      22              : 
      23              : static CcuInstRegister<CcuContextAlltoAllMesh2D> registerAlltoAll(CcuInstType::CCU_ALLTOALL_MESH_2D_DIRECT);
      24              : 
      25            5 : CcuTempAlltoAllMesh2D::CcuTempAlltoAllMesh2D(const RankId virtualRank, const u32 tempRankSize,
      26              :                                            const std::vector<std::vector<RankId>> &tempVTopo,
      27            5 :                                            const std::map<RankId, u32>            &tempVirtRankMap)
      28            5 :     : CcuAlgTemplateBase(virtualRank, tempRankSize, tempVTopo, tempVirtRankMap)
      29              : {
      30              :     // 填充框内的维度大小
      31            5 :     if (tempVTopo_.size() != 2 || tempVTopo_[0].size() <= 1 || tempVTopo_[1].size() <= 1) { // concurrmesh的topoMatch返回的vTopo大小应当为2,对应X轴和Y轴的大小
      32            0 :         THROW<InvalidParamsException>(StringFormat("[CcuTempAlltoAllMesh2D] Rank[%d], Invalid tempVTopo "
      33              :                                                    "Size[%u] or Invalid tempVTopo[0] size [%u] or tempVTopo[1] size [%u].",
      34            0 :                                                    myRank_, tempVTopo_.size(), tempVTopo_[0].size(),
      35            0 :                                                    tempVTopo_[1].size()));
      36              :     }
      37            5 :     dimSize_.emplace_back(tempVTopo[0].size());
      38            5 :     dimSize_.emplace_back(tempVTopo[1].size());
      39            5 : }
      40              : 
      41            5 : CcuTempAlltoAllMesh2D::~CcuTempAlltoAllMesh2D()
      42              : {
      43            5 : }
      44              : 
      45            2 : void CcuTempAlltoAllMesh2D::SetA2ASendRecvInfo(const A2ASendRecvInfo &sendRecvInfo)
      46              : {
      47            2 :     localSendRecvInfo_ = sendRecvInfo;
      48            2 :     return;
      49              : }
      50              : 
      51            3 : HcclResult CcuTempAlltoAllMesh2D::CalcRes(AlgTempResReq &tempResReq)
      52              : {
      53            3 :     tempResReq.queNum = 1;  // 只申请一个insQue,填充一个insGroup,由框架将其中的ins放在多个stream上
      54            3 :     tempResReq.streamNum = tempResReq.queNum + 1;  // 多申请一个 stream 给 ccuInsGroup
      55            3 :     uint32_t dieNum = tempVTopo_.size();
      56            3 :     if (dieNum != 2) {  // concurrmesh的topoMatch返回的vTopo大小应当为2,对应X轴和Y轴的大小
      57            0 :         THROW<InvalidParamsException>(StringFormat("[CcuTempAlltoAllMesh2D] Rank[%d], Invalid IODieNum[%u].",
      58              :             myRank_, dieNum));
      59              :     }
      60            9 :     HCCL_INFO("[CcuTempAlltoAllMesh2D] Rank[%d] requiredQueNum[%u] VtopoSize[%u], VtopoSize0[%u] VtopoSize1[%u].",
      61              :         myRank_, tempResReq.queNum, tempVTopo_.size(), tempVTopo_[0].size(), tempVTopo_[1].size());
      62              : 
      63              :     uint32_t myAlgRank;
      64            9 :     for (u32 dim = 0; dim < tempVTopo_.size(); dim++) {
      65            6 :         CHK_RET(GetAlgRank(myRank_, tempVTopo_[dim], myAlgRank));
      66           14 :         for (u32 queIdx = 0; queIdx < tempVTopo_[dim].size() - 1; queIdx++) {
      67              :             // find neighbors -> virtualRank
      68            8 :             u32    neighborAlgRank = (myAlgRank + 1 + queIdx) % (tempVTopo_[dim].size());
      69            8 :             RankId neighborRank    = tempVTopo_[dim][neighborAlgRank];
      70           24 :             HCCL_INFO("[CollAlgFactory] [CcuTempAlltoAllMesh2D] Rank[%d], Dim[%u], NeighborRank[%d].", myRank_,
      71              :                        dim, neighborRank);
      72              : 
      73              :             // LinkNum
      74            8 :             tempResReq.links[neighborRank] = 1;
      75              :         }
      76              :     }
      77              : 
      78            3 :     return HcclResult::HCCL_SUCCESS;
      79              : }
      80              : 
      81            2 : HcclResult CcuTempAlltoAllMesh2D::FillLinks(const ResLinks &tempLinks)
      82              : {
      83            8 :     for (auto pair : tempLinks) {
      84            6 :         if (pair.second.size() == 0) {  // ESL环境上暂只有直连链路
      85            0 :             THROW<InvalidParamsException>(
      86            0 :                 StringFormat("[CcuTempAlltoAllMesh2D] Rank[%d]--Peer[%d].", myRank_, pair.first));
      87              :         }
      88            6 :         if (pair.first / dimSize_[0] == myRank_ / dimSize_[0]) {
      89           12 :             HCCL_INFO("[CcuTempAlltoAllMesh2D][Run] Rank[%d] insert link to Rank[%d] in linksX", myRank_, pair.first);
      90            4 :             linksX_.emplace_back(pair.second[0]);
      91            2 :         } else if (pair.first % dimSize_[0] == myRank_ % dimSize_[0]) {
      92            6 :             HCCL_INFO("[CcuTempAlltoAllMesh2D][Run] Rank[%d] insert link to Rank[%d] in linksY", myRank_, pair.first);
      93            2 :             linksY_.emplace_back(pair.second[0]);
      94              :         } else {
      95            0 :             THROW<InvalidParamsException>(StringFormat(
      96            0 :                 "[CcuTempAlltoAllMesh2D] Rank[%d], Unexpected peerRank[%d] in tempLinks.", myRank_, pair.first));
      97              :         }
      98            6 :     }
      99            8 :     for (auto &peer : tempVTopo_[0]) {
     100            6 :         rankGroupX_.AddRank(peer);
     101              :     }
     102            6 :     for (auto &peer : tempVTopo_[1]) {
     103            4 :         rankGroupY_.AddRank(peer);
     104              :     }
     105              : 
     106            2 :     return HcclResult::HCCL_SUCCESS;
     107              : }
     108              : 
     109            2 : HcclResult CcuTempAlltoAllMesh2D::RunOneStep(uint64_t sendRecvSize, uint64_t maxTransportSize, uint32_t sendRecvTimes,
     110              :     uint32_t step, std::vector<InsQuePtr> &tempInsQues)
     111              : {
     112            6 :     HCCL_INFO("[CcuTempAlltoAllMesh2D][Run] Rank[%d], Step[%u], sendRecvTimes[%u].", myRank_, step, sendRecvTimes);
     113              : 
     114            2 :     uint64_t inputAddr = op_.inputMem->GetAddr();
     115            2 :     uint64_t outputAddr = op_.outputMem->GetAddr();
     116            2 :     uint64_t scratchAddr = op_.scratchMem->GetAddr();
     117            2 :     uint32_t typeSize = DataTypeSizeGet(op_.all2AllDataDes.sendType);
     118            2 :     uint64_t sendStrideSize = 0 * typeSize;
     119            2 :     uint64_t recvStrideSize = 0 * typeSize;
     120              :     uint64_t token;
     121            2 :     CHK_RET(GetToken(op_, token));
     122              : 
     123            2 :     uint64_t stepSize = (step == sendRecvTimes - 1) ? (sendRecvSize - step * maxTransportSize) : maxTransportSize;
     124            2 :     uint64_t aSize = static_cast<uint64_t>((stepSize / 2) / typeSize) * typeSize;  // 暂定X和Y方向每轮传输大小一致,按照count对齐
     125            2 :     uint64_t bSize = stepSize - aSize;
     126            2 :     uint64_t baseOffset = step * maxTransportSize;  // 已传输完成的数据量
     127            2 :     std::unique_ptr<CcuInsGroup> insGroupPtr = std::make_unique<CcuInsGroup>();
     128            6 :     for (uint32_t axisId = 0; axisId < 2; axisId++) {  // 2D算法,需要执行两次
     129           12 :         HCCL_INFO("[CcuTempAlltoAllMesh2D][Run] Rank[%d], Step[%u], axisId[%u], aSize[%llu], bSize[%llu], baseOffset[%llu].",
     130              :             myRank_, step, axisId, aSize, bSize, baseOffset);
     131              : 
     132            4 :         CcuInstructionAlltoAllMesh2D ins = CcuInstructionAlltoAllMesh2D(op_, dimSize_, tempVTopo_);
     133            4 :         ins.Init(myRank_, inputAddr, outputAddr, scratchAddr, axisId, sendStrideSize, recvStrideSize,
     134            4 :             localSendRecvInfo_.sendLength[0], aSize, bSize, baseOffset, token);
     135            4 :         ins.SetLinks(axisId == 0 ? linksX_ : linksY_);
     136            4 :         ins.SetRankGroup(axisId == 0 ? rankGroupX_ : rankGroupY_);
     137            4 :         ins.SetCntCkeNum(4);  // 每个transport用4个CKE
     138            4 :         insGroupPtr->Append(std::move(std::make_unique<CcuInstructionAlltoAllMesh2D>(ins)));
     139            4 :     }
     140            2 :     tempInsQues[0]->Append(std::move(insGroupPtr));  // 只有一条流
     141              : 
     142            2 :     return HcclResult::HCCL_SUCCESS;
     143            2 : }
     144              : 
     145            2 : HcclResult CcuTempAlltoAllMesh2D::Run(const TempFuncs &tempFuncs, const RankSliceInfo &sliceInfoVec,
     146              :                                       const BuffInfo &buffInfo, const ResLinks &tempLinks,
     147              :                                       std::vector<InsQuePtr> &tempInsQues)
     148              : {
     149              :     // 分别记录两个Die上的link,构造rankGroup
     150              :     (void)tempFuncs;
     151              :     (void)sliceInfoVec;
     152              :     (void)buffInfo;
     153            2 :     CHK_RET(FillLinks(tempLinks));
     154              : 
     155              :     // scratch分两组,每组rankSize份,放一个分片,按照传输大小限制与buffer大小限制分多轮执行算子
     156            6 :     HCCL_INFO("[CcuTempAlltoAllMesh2D] dataType[%s] sendType[%s]", op_.dataType.Describe().c_str(),
     157              :         op_.all2AllDataDes.sendType.Describe().c_str());
     158            2 :     uint32_t typeSize = DataTypeSizeGet(op_.all2AllDataDes.sendType);
     159            2 :     uint64_t sendRecvSize = localSendRecvInfo_.sendLength[0];
     160            2 :     uint64_t blockBufferSize = static_cast<uint64_t>((scratchBufferSize_ / tempRankSize_ / 2) / typeSize) * typeSize;  // 分2组buffer
     161            2 :     uint64_t maxTransportSize = min(min(CalcLGMaxTransSize(), UB_MAX_TRANS_SIZE), blockBufferSize);
     162            2 :     uint32_t sendRecvTimes = (sendRecvSize + maxTransportSize - 1) / maxTransportSize;
     163            6 :     HCCL_INFO("[CollAlgFactory][Run] Rank[%d], blockBufferSize[%llu], sendRecvTimes[%u].",
     164              :         myRank_, blockBufferSize, sendRecvTimes);
     165              : 
     166              :     uint64_t token;
     167            2 :     CHK_RET(GetToken(op_, token));
     168            6 :     HCCL_INFO("[CcuTempAlltoAllMesh2D] Rank[%d], input[%llu], output[%llu], scratch[%llu], sendStride[%llu], \
     169              :         recvStride[%llu].",
     170              :         myRank_, op_.inputMem->GetAddr(), op_.outputMem->GetAddr(), op_.scratchMem->GetAddr(), 0, 0);
     171              : 
     172            2 :     if (tempInsQues.size() == 0) {
     173            0 :         HCCL_ERROR("[CcuTempAlltoAllMesh2D][Run] invalid tempInsQues size is [%zu].", tempInsQues.size());
     174            0 :         return HcclResult::HCCL_E_PARA;
     175              :     }
     176            4 :     for (uint32_t step = 0; step < sendRecvTimes; step++) {  // 零数据量时会跳过
     177            2 :         if (tempRankSize_ == 1) {
     178              :             // alltoall算子的单P场景单独处理
     179            0 :             DataSlice usrInSlice = DataSlice(BufferType::INPUT, 0, sendRecvSize);
     180            0 :             DataSlice usrOutSlice = DataSlice(BufferType::OUTPUT, 0, sendRecvSize);
     181            0 :             std::unique_ptr<Instruction> insLocalCopy = std::make_unique<InsLocalCopy>(usrInSlice, usrOutSlice);
     182            0 :             tempInsQues[0]->Append(std::move(insLocalCopy));
     183            0 :             HCCL_INFO("[CcuTempAlltoAllMesh2D] rankSize = 1, use InsLocalCopy for sliceSize[%llu].", sendRecvSize);
     184            0 :             break;
     185            0 :         }
     186            2 :         CHK_RET(RunOneStep(sendRecvSize, maxTransportSize, sendRecvTimes, step, tempInsQues));
     187              :     }
     188              : 
     189            2 :     return HcclResult::HCCL_SUCCESS;
     190              : }
     191              : 
     192            2 : HcclResult CcuTempAlltoAllMesh2D::GetScratchBufferInfo(const uint64_t scratchBufferSize, DataType dataType)
     193              : {
     194            2 :     scratchBufferSize_ = scratchBufferSize;
     195            2 :     dataType_ = dataType;
     196            2 :     return HcclResult::HCCL_SUCCESS;
     197              : }
     198              : 
     199              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1