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

Generated by: LCOV version 2.0-1