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

Generated by: LCOV version 2.0-1