LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/primitive - primitive.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.3 % 249 205
Test Date: 2026-07-28 12:11:00 Functions: 91.2 % 34 31

            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 "primitive.h"
      12              : #include "null_ptr_exception.h"
      13              : #include "prim_queue.h"
      14              : 
      15              : #include <set>
      16              : 
      17              : namespace Hccl {
      18            6 : PrimPostTo::PrimPostTo(const weak_ptr<PrimQueue> queue, NotifyType notifyType, u32 topicId)
      19            6 :     : Primitive(PrimType::POST_TO), queue(queue), notifyType(notifyType), topicId(topicId)
      20              : {
      21            6 :     if (queue.lock().get() == nullptr) {
      22            1 :         THROW<NullPtrException>("queue");
      23              :     }
      24            8 : }
      25              : 
      26            4 : void PrimPostTo::SetParent(const weak_ptr<PrimQueue> &que)
      27              : {
      28            4 :     if (que.lock().get() == nullptr) {
      29            1 :         THROW<NullPtrException>("parent");
      30              :     }
      31            3 :     if (GetQid() == que.lock()->GetId()) {
      32            1 :         THROW<InvalidParamsException>("parent Qid is equal to queue Qid");
      33              :     }
      34            2 :     parent = que;
      35            2 : }
      36              : 
      37            1 : std::string PrimPostTo::Describe() const
      38              : {
      39            1 :     if (parent.lock().get() == nullptr) {
      40            0 :         return StringFormat("%s Qid[%u] NotifyType[%s]", type.Describe().c_str(), queue.lock()->GetId(),
      41            0 :                             notifyType.Describe().c_str());
      42              :     } else {
      43            2 :         return StringFormat("%s parent[%u] postTo Qid[%u] NotifyType[%s]", type.Describe().c_str(),
      44            3 :                             parent.lock()->GetId(), queue.lock()->GetId(), notifyType.Describe().c_str());
      45              :     }
      46              : }
      47              : 
      48            4 : QId PrimPostTo::GetQid() const
      49              : {
      50            4 :     return queue.lock()->GetId();
      51              : }
      52              : 
      53            2 : QId PrimPostTo::GetParentQid() const
      54              : {
      55            2 :     if (parent.lock().get() == nullptr) {
      56            1 :         return INVALID_PRIM_QID;
      57              :     } else {
      58            1 :         return parent.lock()->GetId();
      59              :     }
      60              : }
      61              : 
      62            6 : PrimWaitFrom::PrimWaitFrom(const weak_ptr<PrimQueue> queue, u32 topicId)
      63            6 :     : Primitive(PrimType::WAIT_FROM), queue(queue), topicId(topicId)
      64              : {
      65            6 :     if (queue.lock().get() == nullptr) {
      66            1 :         THROW<NullPtrException>("queue");
      67              :     }
      68            8 : }
      69              : 
      70            1 : std::string PrimWaitFrom::Describe() const
      71              : {
      72            1 :     if (parent.lock().get() == nullptr) {
      73            0 :         return StringFormat("%s Qid[%u]", type.Describe().c_str(), queue.lock()->GetId());
      74              :     } else {
      75            3 :         return StringFormat("%s parent[%u] waitFrom Qid[%u]", type.Describe().c_str(), parent.lock()->GetId(),
      76            4 :                             queue.lock()->GetId());
      77              :     }
      78              : }
      79              : 
      80            4 : void PrimWaitFrom::SetParent(const weak_ptr<PrimQueue> &que)
      81              : {
      82            4 :     if (que.lock().get() == nullptr) {
      83            1 :         THROW<NullPtrException>("parent");
      84              :     }
      85            3 :     if (GetQid() == que.lock()->GetId()) {
      86            1 :         THROW<InvalidParamsException>("parent Qid is equal to queue Qid");
      87              :     }
      88            2 :     parent = que;
      89            2 : }
      90              : 
      91            4 : QId PrimWaitFrom::GetQid() const
      92              : {
      93            4 :     return queue.lock()->GetId();
      94              : }
      95              : 
      96            2 : QId PrimWaitFrom::GetParentQid() const
      97              : {
      98            2 :     if (parent.lock().get() == nullptr) {
      99            1 :         return INVALID_PRIM_QID;
     100              :     } else {
     101            1 :         return parent.lock()->GetId();
     102              :     }
     103              : }
     104              : 
     105            4 : PrimWaitGroup::PrimWaitGroup(u32 topicId) : Primitive(PrimType::WAIT_GROUP), topicId(topicId)
     106              : {
     107            4 : }
     108              : 
     109            2 : void PrimWaitGroup::Append(const weak_ptr<PrimQueue> queue)
     110              : {
     111            2 :     if (queue.lock().get() == nullptr) {
     112            0 :         THROW<NullPtrException>("queue");
     113              :     }
     114            2 :     qids.push_back(queue.lock()->GetId());
     115            2 : }
     116              : 
     117            2 : std::string PrimWaitGroup::Describe() const
     118              : {
     119            2 :     std::string qidsStr;
     120            2 :     for (u32 idx = 0; idx < qids.size(); idx++) {
     121            0 :         qidsStr += StringFormat("qid[%u], ", qids[idx]);
     122              :     }
     123            2 :     if (!qidsStr.empty()) {
     124            0 :         u32 redundantLen = 2;
     125            0 :         qidsStr          = qidsStr.substr(0, qidsStr.size() - redundantLen);
     126              :     }
     127              : 
     128            2 :     if (parent.lock().get() == nullptr) {
     129            2 :         return StringFormat("%s: qidNum[%u] qids[%s]", type.Describe().c_str(), qids.size(), qidsStr.c_str());
     130              :     } else {
     131            3 :         return StringFormat("%s: parent[%u] qidNum[%u] qids[%s]", type.Describe().c_str(), parent.lock()->GetId(),
     132            3 :                             qids.size(), qidsStr.c_str());
     133              :     }
     134            2 : }
     135              : 
     136            4 : void PrimWaitGroup::SetParent(const weak_ptr<PrimQueue> &que)
     137              : {
     138            4 :     if (que.lock().get() == nullptr) {
     139            0 :         THROW<NullPtrException>("parent");
     140              :     }
     141              : 
     142            4 :     QId parentQid = que.lock()->GetId();
     143            6 :     for (auto qid = qids.begin(); qid != qids.end(); ++qid) {
     144            3 :         if (*qid == parentQid) {
     145            1 :             THROW<InvalidParamsException>("parent Qid is equal to one of queue Qids");
     146              :         }
     147              :     }
     148              : 
     149            3 :     parent = que;
     150            3 : }
     151              : 
     152            3 : QId PrimWaitGroup::GetParentQid() const
     153              : {
     154            3 :     if (parent.lock().get() == nullptr) {
     155            1 :         return INVALID_PRIM_QID;
     156              :     } else {
     157            2 :         return parent.lock()->GetId();
     158              :     }
     159              : }
     160              : 
     161            7 : PrimLocalCopy::PrimLocalCopy(const DataSlice &srcSlice, const DataSlice &dstSlice)
     162            7 :     : Primitive(PrimType::LOCAL_COPY), srcSlice(srcSlice), dstSlice(dstSlice)
     163              : {
     164            7 :     if (srcSlice.GetSize() != dstSlice.GetSize()) {
     165            1 :         THROW<InvalidParamsException>("The size of dstSlice is not equal to srcSlice");
     166              :     }
     167            6 :     if (srcSlice.GetType() == dstSlice.GetType()) {
     168            2 :         u64 srcStart = srcSlice.GetOffset();
     169            2 :         u64 srcEnd   = srcStart + srcSlice.GetSize();
     170            2 :         u64 dstStart = dstSlice.GetOffset();
     171            2 :         u64 dstEnd   = dstStart + dstSlice.GetSize();
     172            2 :         if (srcStart >= dstStart && srcStart < dstEnd) {
     173            0 :             THROW<InvalidParamsException>("The addresses of dstSlice and srcSlice overlap");
     174              :         }
     175            2 :         if (dstStart >= srcStart && dstStart < srcEnd) {
     176            1 :             THROW<InvalidParamsException>("The addresses of dstSlice and srcSlice overlap");
     177              :         }
     178              :     }
     179            7 : }
     180              : 
     181            4 : std::string PrimLocalCopy::Describe() const
     182              : {
     183           12 :     return StringFormat("%s: src[%s], dst[%s]", type.Describe().c_str(), srcSlice.Describe().c_str(),
     184           16 :                         dstSlice.Describe().c_str());
     185              : }
     186              : 
     187            0 : PrimLocalReduce::PrimLocalReduce(const DataSlice &srcSlice, const DataSlice &dstSlice, DataType dataType,
     188            0 :                                  ReduceOp reduceOp)
     189            0 :     : Primitive(PrimType::LOCAL_REDUCE), srcSlice(srcSlice), dstSlice(dstSlice), dataType(dataType), reduceOp(reduceOp)
     190              : {
     191            0 :     if (srcSlice.GetSize() != dstSlice.GetSize()) {
     192            0 :         THROW<InvalidParamsException>("The size of dstSlice is not equal to srcSlice");
     193              :     }
     194            0 :     if (srcSlice.GetType() == dstSlice.GetType()) {
     195            0 :         u64 srcStart = srcSlice.GetOffset();
     196            0 :         u64 srcEnd   = srcStart + srcSlice.GetSize();
     197            0 :         u64 dstStart = dstSlice.GetOffset();
     198            0 :         u64 dstEnd   = dstStart + dstSlice.GetSize();
     199            0 :         if (srcStart >= dstStart && srcStart < dstEnd) {
     200            0 :             THROW<InvalidParamsException>("The addresses of dstSlice and srcSlice overlap");
     201              :         }
     202            0 :         if (dstStart >= srcStart && dstStart < srcEnd) {
     203            0 :             THROW<InvalidParamsException>("The addresses of dstSlice and srcSlice overlap");
     204              :         }
     205              :     }
     206            0 : }
     207              : 
     208            0 : std::string PrimLocalReduce::Describe() const
     209              : {
     210            0 :     return StringFormat("%s: %s, %s, src[%s], dst[%s]", type.Describe().c_str(), reduceOp.Describe().c_str(),
     211            0 :                         dataType.Describe().c_str(), srcSlice.Describe().c_str(), dstSlice.Describe().c_str());
     212              : }
     213              : 
     214           28 : PrimSend::PrimSend(RankId remoteRank, const LinkData &link, const DataSlice &localSlice, const DataSlice &remoteSlice,
     215           28 :                    DmaMode dmaMode)
     216           28 :     : Primitive(PrimType::SEND), remoteRank(remoteRank), link(link), dmaMode(dmaMode)
     217              : {
     218           28 :     if (localSlice.GetSize() != remoteSlice.GetSize()) {
     219            0 :         THROW<InvalidParamsException>("The size of remoteSlice is not equal to localSlice");
     220              :     }
     221           28 :     localSlices.push_back(localSlice);
     222           28 :     remoteSlices.push_back(remoteSlice);
     223           28 : }
     224              : 
     225           10 : std::string PrimSend::Describe() const
     226              : {
     227           20 :     string desc = StringFormat("%s: remoteRank[%u], %s, %s, sliceNUm[%u]", type.Describe().c_str(), remoteRank,
     228           30 :                                link.Describe().c_str(), dmaMode.Describe().c_str(), localSlices.size());
     229           23 :     for (u32 idx = 0; idx < localSlices.size(); idx++) {
     230           26 :         desc += StringFormat(" sliceIdx[%d]: local%s, remote%s;", idx, localSlices[idx].Describe().c_str(),
     231           39 :                              remoteSlices[idx].Describe().c_str());
     232              :     }
     233           10 :     return desc;
     234            0 : }
     235              : 
     236            3 : void PrimSend::Append(const DataSlice &localSlice, const DataSlice &remoteSlice)
     237              : {
     238            3 :     if (localSlice.GetSize() != remoteSlice.GetSize()) {
     239            0 :         THROW<InvalidParamsException>("The size of remoteSlice is not equal to localSlice");
     240              :     }
     241            3 :     localSlices.push_back(localSlice);
     242            3 :     remoteSlices.push_back(remoteSlice);
     243            3 : }
     244              : 
     245           30 : PrimRecv::PrimRecv(RankId remoteRank, const LinkData &link, const DataSlice &localSlice, const DataSlice &remoteSlice,
     246           30 :                    DmaMode dmaMode)
     247           30 :     : Primitive(PrimType::RECV), remoteRank(remoteRank), link(link), dmaMode(dmaMode)
     248              : {
     249           30 :     if (localSlice.GetSize() != remoteSlice.GetSize()) {
     250            1 :         THROW<InvalidParamsException>("The size of remoteSlice is not equal to localSlice");
     251              :     }
     252           29 :     localSlices.push_back(localSlice);
     253           29 :     remoteSlices.push_back(remoteSlice);
     254           32 : }
     255              : 
     256            9 : std::string PrimRecv::Describe() const
     257              : {
     258           18 :     string desc = StringFormat("%s: remoteRank[%u], %s, %s, sliceNUm[%u]", type.Describe().c_str(), remoteRank,
     259           27 :                                link.Describe().c_str(), dmaMode.Describe().c_str(), localSlices.size());
     260           21 :     for (u32 idx = 0; idx < localSlices.size(); idx++) {
     261           24 :         desc += StringFormat(" sliceIdx[%d]: local%s, remote%s;", idx, localSlices[idx].Describe().c_str(),
     262           36 :                              remoteSlices[idx].Describe().c_str());
     263              :     }
     264            9 :     return desc;
     265            0 : }
     266              : 
     267            4 : void PrimRecv::Append(const DataSlice &localSlice, const DataSlice &remoteSlice)
     268              : {
     269            4 :     if (localSlice.GetSize() != remoteSlice.GetSize()) {
     270            1 :         THROW<InvalidParamsException>("The size of remoteSlice is not equal to localSlice");
     271              :     }
     272            3 :     localSlices.push_back(localSlice);
     273            3 :     remoteSlices.push_back(remoteSlice);
     274            3 : }
     275              : 
     276           11 : PrimSendReduce::PrimSendReduce(RankId remoteRank, const LinkData &link, const DataSlice &localSlice,
     277              :                                const DataSlice &remoteSrcSlice, const DataSlice &remoteDstSlice,
     278           11 :                                const DataType &dataType, const ReduceOp &reduceOp, DmaMode dmaMode)
     279           22 :     : Primitive(PrimType::SEND_REDUCE), remoteRank(remoteRank), link(link), dataType(dataType), reduceOp(reduceOp),
     280           11 :       dmaMode(dmaMode)
     281              : {
     282           11 :     if (localSlice.GetSize() != remoteSrcSlice.GetSize() || remoteSrcSlice.GetSize() != remoteDstSlice.GetSize()) {
     283            0 :         THROW<InvalidParamsException>("The size of localSlice, remoteSrcSlice, and remoteDstSlice are not equal");
     284              :     }
     285           11 :     localSlices.push_back(localSlice);
     286           11 :     remoteSrcSlices.push_back(remoteSrcSlice);
     287           11 :     remoteDstSlices.push_back(remoteDstSlice);
     288           11 : }
     289              : 
     290            8 : std::string PrimSendReduce::Describe() const
     291              : {
     292           16 :     string desc = StringFormat("%s: remoteRank[%u], %s, %s, sliceNum[%u]", type.Describe().c_str(), remoteRank,
     293           24 :                                link.Describe().c_str(), dmaMode.Describe().c_str(), localSlices.size());
     294           18 :     for (u32 idx = 0; idx < localSlices.size(); idx++) {
     295           40 :         desc += StringFormat(" sliceIdx[%d]: local%s, remoteSrc%s, remoteDst%s;", idx,
     296           30 :                              localSlices[idx].Describe().c_str(), remoteSrcSlices[idx].Describe().c_str(),
     297           30 :                              remoteDstSlices[idx].Describe().c_str());
     298              :     }
     299            8 :     return desc;
     300            0 : }
     301              : 
     302            2 : void PrimSendReduce::Append(const DataSlice &localSlice, const DataSlice &remoteSrcSlice,
     303              :                             const DataSlice &remoteDstSlice)
     304              : {
     305            2 :     if (localSlice.GetSize() != remoteSrcSlice.GetSize() || remoteSrcSlice.GetSize() != remoteDstSlice.GetSize()) {
     306            0 :         THROW<InvalidParamsException>("The size of localSlice, remoteSrcSlice, and remoteDstSlice are not equal");
     307              :     }
     308            2 :     localSlices.push_back(localSlice);
     309            2 :     remoteSrcSlices.push_back(remoteSrcSlice);
     310            2 :     remoteDstSlices.push_back(remoteDstSlice);
     311            2 : }
     312              : 
     313           11 : PrimRecvReduce::PrimRecvReduce(RankId remoteRank, const LinkData &link, const DataSlice &remoteSlice,
     314              :                                const DataSlice &localSrcSlice, const DataSlice &localDstSlice, const DataType &dataType,
     315           11 :                                const ReduceOp &reduceOp, DmaMode dmaMode)
     316           22 :     : Primitive(PrimType::RECV_REDUCE), remoteRank(remoteRank), link(link), dataType(dataType), reduceOp(reduceOp),
     317           11 :       dmaMode(dmaMode)
     318              : {
     319           11 :     if (remoteSlice.GetSize() != localSrcSlice.GetSize() || localSrcSlice.GetSize() != localDstSlice.GetSize()) {
     320            0 :         THROW<InvalidParamsException>("The size of remoteSlice, localSrcSlice, and localDstSlice are not equal");
     321              :     }
     322           11 :     remoteSlices.push_back(remoteSlice);
     323           11 :     localSrcSlices.push_back(localSrcSlice);
     324           11 :     localDstSlices.push_back(localDstSlice);
     325           11 : }
     326              : 
     327            8 : std::string PrimRecvReduce::Describe() const
     328              : {
     329           16 :     string desc = StringFormat("%s: remoteRank[%u], %s, %s, sliceNum[%u]", type.Describe().c_str(), remoteRank,
     330           24 :                                link.Describe().c_str(), dmaMode.Describe().c_str(), remoteSlices.size());
     331           20 :     for (u32 idx = 0; idx < remoteSlices.size(); idx++) {
     332           48 :         desc += StringFormat(" sliceIdx[%d]: local%s, localSrc%s, localDst%s;", idx,
     333           36 :                              remoteSlices[idx].Describe().c_str(), localSrcSlices[idx].Describe().c_str(),
     334           36 :                              localDstSlices[idx].Describe().c_str());
     335              :     }
     336            8 :     return desc;
     337            0 : }
     338              : 
     339            4 : void PrimRecvReduce::Append(const DataSlice &remoteSlice, const DataSlice &localSrcSlice,
     340              :                             const DataSlice &localDstSlice)
     341              : {
     342            4 :     if (remoteSlice.GetSize() != localSrcSlice.GetSize() || localSrcSlice.GetSize() != localDstSlice.GetSize()) {
     343            0 :         THROW<InvalidParamsException>("The size of remoteSlice, localSrcSlice, and localDstSlice are not equal");
     344              :     }
     345            4 :     remoteSlices.push_back(remoteSlice);
     346            4 :     localSrcSlices.push_back(localSrcSlice);
     347            4 :     localDstSlices.push_back(localDstSlice);
     348            4 : }
     349              : 
     350            0 : std::string PrimGroup::Describe() const
     351              : {
     352            0 :     string desc     = StringFormat("%s: primSize[%u]", type.Describe().c_str(), prims.size());
     353            0 :     auto   primIter = prims.begin();
     354            0 :     for (; primIter != prims.end(); primIter++) {
     355            0 :         desc += (*primIter)->Describe() + "\n";
     356              :     }
     357            0 :     return desc;
     358            0 : }
     359              : 
     360           11 : void PrimGroup::CheckValid() const
     361              : {
     362           11 :     std::set<LinkData> sendLink;
     363           11 :     std::set<LinkData> recvLink;
     364           29 :     for (auto iter = Iter(); iter.HasNext(); ++iter) {
     365           23 :         if (iter->GetType() == PrimType::SEND) {
     366            7 :             PrimSend *primSend = dynamic_cast<PrimSend *>(const_cast<Primitive *>(&(*iter)));
     367            7 :             if (sendLink.count(primSend->GetLink()) > 0) {
     368            1 :                 THROW<InvalidParamsException>("One link has two Send Prims");
     369              :             }
     370            6 :             sendLink.insert(primSend->GetLink());
     371           16 :         } else if (iter->GetType() == PrimType::SEND_REDUCE) {
     372            4 :             PrimSendReduce *primSendReduce = dynamic_cast<PrimSendReduce *>(const_cast<Primitive *>(&(*iter)));
     373            4 :             if (sendLink.count(primSendReduce->GetLink()) > 0) {
     374            1 :                 THROW<InvalidParamsException>("One link has two Send Prims");
     375              :             }
     376            3 :             sendLink.insert(primSendReduce->GetLink());
     377           12 :         } else if (iter->GetType() == PrimType::RECV) {
     378            8 :             PrimRecv *primRecv = dynamic_cast<PrimRecv *>(const_cast<Primitive *>(&(*iter)));
     379            8 :             if (recvLink.count(primRecv->GetLink()) > 0) {
     380            2 :                 THROW<InvalidParamsException>("One link has two Recv Prims");
     381              :             }
     382            6 :             recvLink.insert(primRecv->GetLink());
     383              :         } else { // when come here , the PrimType is PrimType::RECV_REDUCE
     384            4 :             PrimRecvReduce *primRecvReduce = dynamic_cast<PrimRecvReduce *>(const_cast<Primitive *>(&(*iter)));
     385            4 :             if (recvLink.count(primRecvReduce->GetLink()) > 0) {
     386            1 :                 THROW<InvalidParamsException>("One link has two Recv Prims");
     387              :             }
     388            3 :             recvLink.insert(primRecvReduce->GetLink());
     389              :         }
     390           11 :     }
     391           12 :     return;
     392           16 : }
     393              : 
     394           26 : void PrimGroup::Append(unique_ptr<Primitive> prim)
     395              : {
     396           45 :     if (prim->GetType() != PrimType::SEND && prim->GetType() != PrimType::RECV
     397           45 :         && prim->GetType() != PrimType::SEND_REDUCE && prim->GetType() != PrimType::RECV_REDUCE) {
     398            1 :         THROW<InvalidParamsException>("PrimGroup only support PrimSend or PrimRecv or "
     399              :                                       "PrimSendReduce or PrimRecvReduce");
     400              :     }
     401           25 :     prims.push_back(std::move(prim));
     402           25 :     return;
     403              : }
     404              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1