LCOV - code coverage report
Current view: top level - legacy/ascend950/framework/service/aicpu - ins_executor.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.2 % 215 151
Test Date: 2026-08-18 17:47:01 Functions: 72.7 % 11 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 <algorithm>
      12              : #include "ins_to_sqe_rule.h"
      13              : #include "null_ptr_exception.h"
      14              : #include "ins_executor.h"
      15              : #include "communicator_impl_lite_manager.h"
      16              : 
      17              : namespace Hccl {
      18              : 
      19              : constexpr u64 FOUR_BYTES = 4;
      20              : constexpr u32 LAUNCH_PRINT_INTERVAL = 20;
      21              : 
      22            0 : void InsExecutor::Execute(const InsQueue& insQueue)
      23              : {
      24            0 :     StreamLiteMgr* streamLiteMgr = resMgrFetcher_->GetStreamLiteMgr();
      25            0 :     int slaveStreamIndex = 0;
      26            0 :     for (auto slaveIter = insQueue.IterSlaves(); slaveIter.HasNext(); ++slaveIter) {
      27            0 :         ExecuteSingleQue(*slaveIter, streamLiteMgr->GetSlave(slaveStreamIndex++));
      28            0 :     }
      29            0 :     CHECK_NULLPTR(streamLiteMgr->GetMaster(), "[Execute]master stream is nullptr!");
      30            0 :     ExecuteSingleQue(insQueue, streamLiteMgr->GetMaster(), true);
      31            0 : }
      32              : 
      33            8 : void InsExecutor::AddOpCounter(const StreamLite& stream, bool isHead) const
      34              : {
      35            8 :     CHECK_NULLPTR(resMgrFetcher_, "[InsExecutor::AddOpCounter] resMgrFetcher_ is nullptr!");
      36            8 :     auto rtsq = stream.GetRtsq();
      37            8 :     if (rtsq == nullptr) {
      38            0 :         HCCL_ERROR("[InsExecutor::%s] stream.GetRtsq() is nullptr", __func__);
      39            8 :         return;
      40              :     }
      41            8 :     u64 counterSrcAddr = resMgrFetcher_->GetCounterAddr();
      42            8 :     if (counterSrcAddr == 0) {
      43           24 :         HCCL_ERROR("InsExecutor::%s counter addr is null.", __func__);
      44            8 :         return;
      45              :     }
      46            0 :     u64 dstAddr = isHead == true ? counterSrcAddr + FOUR_BYTES : counterSrcAddr + FOUR_BYTES * 2;
      47            0 :     u64 count = FOUR_BYTES;
      48            0 :     HCCL_INFO("%s AddOpCounter start", __func__);
      49            0 :     auto taskId = rtsq->GetTaskId();
      50            0 :     rtsq->SdmaReduce(counterSrcAddr, dstAddr, count, 0, ReduceIn(DataType::FP32, ReduceOp::SUM));
      51              : 
      52            0 :     TaskParam taskParam{};
      53            0 :     taskParam.taskType = TaskParamType::TASK_REDUCE_INLINE;
      54            0 :     taskParam.beginTime = ProfGetCurCpuTimestamp();
      55            0 :     taskParam.taskPara.Reduce.src = reinterpret_cast<void*>(counterSrcAddr);
      56            0 :     taskParam.taskPara.Reduce.dst = reinterpret_cast<void*>(dstAddr);
      57            0 :     taskParam.taskPara.Reduce.size = count;
      58            0 :     taskParam.taskPara.Reduce.notifyID = INVALID_VALUE_NOTIFYID;
      59            0 :     taskParam.taskPara.Reduce.linkType = DfxLinkType::ONCHIP;
      60            0 :     taskParam.taskPara.Reduce.reduceOp = HcclReduceOp::HCCL_REDUCE_SUM;
      61            0 :     taskParam.taskPara.Reduce.dataType = HcclDataType::HCCL_DATA_TYPE_FP32;
      62            0 :     auto taskInfo = std::make_unique<TaskInfo>(stream.GetSqId(), taskId, INVALID_VALUE_RANKID, taskParam);
      63            0 :     resMgrFetcher_->GetMirrorTaskMgrLite()->AddTaskInfo(std::move(taskInfo));
      64            0 : }
      65              : 
      66            5 : void InsExecutor::ExecuteV82(const InsQueue& insQueue, bool isMc2)
      67              : {
      68              :     // InsQueue 非空已经在外部进行了校验
      69            5 :     if (resMgrFetcher_ == nullptr) {
      70            0 :         THROW<NullPtrException>(StringFormat("InsExecutor::%s resMgrFetcher is null, isMc2 %d.", __func__, isMc2));
      71              :         return;
      72              :     }
      73            5 :     StreamLiteMgr* streamLiteMgr = resMgrFetcher_->GetStreamLiteMgr();
      74            5 :     if (streamLiteMgr == nullptr) {
      75            0 :         THROW<NullPtrException>(StringFormat("InsExecutor::%s streamLiteMgr is null, isMc2 %d.", __func__, isMc2));
      76              :         return;
      77              :     }
      78              :     // 先下主流上的notify wait任务,包括和host同步和op计数任务
      79            5 :     StreamLite* masterStream = streamLiteMgr->GetMaster();
      80            5 :     if (masterStream == nullptr) {
      81            2 :         THROW<NullPtrException>(StringFormat("InsExecutor::%s masterStream is null, isMc2 %d.", __func__, isMc2));
      82              :         return;
      83              :     }
      84            4 :     ReportMainStreamTask(*masterStream, MainStreamTaskType::HEAD);
      85            4 :     auto deviceWaitNotifyId = resMgrFetcher_->GetHostDeviceSyncNotifyLiteMgr()->GetDeviceWaitNotify()->GetId();
      86           12 :     HCCL_INFO("InsExecutor::%s GetDeviceWaitNotify id %u", __func__, deviceWaitNotifyId);
      87            4 :     if (!isMc2) {
      88            4 :         auto taskId = masterStream->GetRtsq()->GetTaskId();
      89            4 :         masterStream->GetRtsq()->NotifyWait(deviceWaitNotifyId);
      90            4 :         TaskParam taskParam{};
      91            4 :         taskParam.taskType = TaskParamType::TASK_NOTIFY_WAIT;
      92            4 :         taskParam.beginTime = ProfGetCurCpuTimestamp();
      93            4 :         taskParam.taskPara.Notify.notifyID = deviceWaitNotifyId;
      94            4 :         taskParam.taskPara.Notify.value = 1;
      95            4 :         auto taskInfo = std::make_unique<TaskInfo>(masterStream->GetSqId(), taskId, INVALID_VALUE_RANKID, taskParam);
      96            4 :         resMgrFetcher_->GetMirrorTaskMgrLite()->AddTaskInfo(std::move(taskInfo));
      97            4 :     }
      98            4 :     AddOpCounter(*masterStream, true);
      99              : 
     100              :     // 将主流和从流上的Task分别下发执行
     101            4 :     ExecuteAllQueues950(insQueue, streamLiteMgr);
     102              : 
     103              :     // 下主流上的notify record任务,包括和host同步和op计数任务
     104            4 :     AddOpCounter(*masterStream, false);
     105            4 :     ReportMainStreamTask(*masterStream, MainStreamTaskType::TAIL);
     106            4 :     auto hostWaitNotifyId = resMgrFetcher_->GetHostDeviceSyncNotifyLiteMgr()->GetHostWaitNotify()->GetId();
     107           12 :     HCCL_INFO("InsExecutor::%s GetHostWaitNotify id %u", __func__, hostWaitNotifyId);
     108            4 :     if (!isMc2) {
     109            4 :         auto taskId = masterStream->GetRtsq()->GetTaskId();
     110            4 :         masterStream->GetRtsq()->NotifyRecordLoc(hostWaitNotifyId);
     111            4 :         TaskParam taskParam{};
     112            4 :         taskParam.taskType = TaskParamType::TASK_NOTIFY_RECORD;
     113            4 :         taskParam.beginTime = ProfGetCurCpuTimestamp();
     114            4 :         taskParam.taskPara.Notify.notifyID = hostWaitNotifyId;
     115            4 :         taskParam.taskPara.Notify.value = 1;
     116            4 :         auto taskInfo = std::make_unique<TaskInfo>(masterStream->GetSqId(), taskId, INVALID_VALUE_RANKID, taskParam);
     117            4 :         resMgrFetcher_->GetMirrorTaskMgrLite()->AddTaskInfo(std::move(taskInfo));
     118            4 :     }
     119            4 :     masterStream->GetRtsq()->LaunchTask();
     120              : }
     121              : 
     122            8 : void InsExecutor::ReportMainStreamTask(const StreamLite& stream, MainStreamTaskType type) const
     123              : {
     124            8 :     FlagTaskInfo flagTaskInfo;
     125            8 :     flagTaskInfo.taskId = stream.GetRtsq()->GetTaskId();
     126            8 :     flagTaskInfo.type = type;
     127           24 :     HCCL_INFO("[%s] TaskInfo taskId %u", __func__, flagTaskInfo.taskId);
     128            8 :     ProfilingHandlerLite::GetInstance().ReportMainStreamTask(flagTaskInfo);
     129            8 : }
     130              : 
     131            4 : void InsExecutor::ExecuteAllQueues950(const InsQueue& insQueue, StreamLiteMgr* streamLiteMgr)
     132              : {
     133           12 :     HCCL_INFO("InsExecutor::%s start", __func__);
     134            4 :     list<InsQueue::Iterator> slaveQueueIters;
     135            4 :     std::set<u32> slaveStreamIndexSet;
     136              : 
     137            4 :     bool isMasterInsIterEnd = false;
     138              :     // 用于判断一轮下发task过程中,是否有成功下发Task,以及开始记时
     139            4 :     bool isLaunchTask = false;
     140            4 :     auto startTime = std::chrono::steady_clock::now();
     141            4 :     auto timeoutValue = CommunicatorImplLiteMgr::GetInstance().GetEnvConfig().hcclExecTimeout + 20;
     142            4 :     auto timeout = std::chrono::seconds(timeoutValue);
     143            4 :     const std::chrono::seconds printInterval(LAUNCH_PRINT_INTERVAL); // 打印间隔30s
     144            4 :     auto lastPrintTime = std::chrono::steady_clock::now() - printInterval;
     145            4 :     InsQueue::Iterator masterQueueIter = insQueue.Iter();
     146            4 :     StreamLite* masterStream = streamLiteMgr->GetMaster();
     147            4 :     CHK_PRT_THROW(
     148              :         masterStream == nullptr, HCCL_ERROR("[InsExecutor::%s] masterStream is null.", __func__), InternalException,
     149              :         "masterStream is null");
     150              :     // 将准备下发到从流的subInsQueue的迭代器都存到迭代器数组内部
     151            8 :     for (auto slaveQueueIter = insQueue.IterSlaves(); slaveQueueIter.HasNext(); ++slaveQueueIter) {
     152            4 :         slaveQueueIters.emplace_back((*slaveQueueIter).Iter());
     153            4 :     }
     154            4 :     u32 maxSlaveQueuesSize = slaveQueueIters.size();
     155              :     // 创建和slaveQueueIter相对应的从流索引容器,用于后续下发任务一一对应
     156            8 :     for (u32 slaveStreamIndex = 0; slaveStreamIndex < slaveQueueIters.size(); ++slaveStreamIndex) {
     157            4 :         slaveStreamIndexSet.insert(slaveStreamIndex);
     158              :     }
     159              :     // 遍历迭代器数组,一个流上的InsQueue去下一个任务
     160           21 :     while (!slaveQueueIters.empty() || !isMasterInsIterEnd) {
     161              :         // 遍历从流InsQueue,每一次下发一个Task
     162           17 :         ExecuteSlaveQueue950(slaveQueueIters, streamLiteMgr, isLaunchTask, slaveStreamIndexSet);
     163              :         // 每一次循环,下发一次主流Task
     164           17 :         if (!isMasterInsIterEnd) {
     165           15 :             ExecuteMasterQueue950(masterQueueIter, masterStream, isMasterInsIterEnd, isLaunchTask);
     166              :         }
     167              : 
     168           17 :         CheckPreStreamSync(streamLiteMgr, maxSlaveQueuesSize);
     169              :         // 如果没有下发任务就开始记录超时时间
     170           17 :         if (isLaunchTask) {
     171           17 :             startTime = std::chrono::steady_clock::now();
     172            0 :         } else if (std::chrono::steady_clock::now() - lastPrintTime >= printInterval) {
     173            0 :             HCCL_INFO("[ExecuteAllQueues950]All Rtsq Queues full, wait for executor");
     174            0 :             lastPrintTime = std::chrono::steady_clock::now();
     175              :         }
     176           17 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     177            0 :             auto msg = StringFormat("[ExecuteAllQueues950]All Rtsq Queues full, timeout[%u s]", timeoutValue);
     178            0 :             HCCL_ERROR("%s", msg.c_str());
     179            0 :             THROW<InternalException>(msg);
     180            0 :         }
     181              :     }
     182           12 :     HCCL_INFO("InsExecutor::%s success", __func__);
     183            4 : }
     184              : 
     185           17 : void InsExecutor::ExecuteSlaveQueue950(
     186              :     list<InsQueue::Iterator>& slaveQueueIters, StreamLiteMgr* streamLiteMgr, bool& isLaunchTask,
     187              :     std::set<u32>& slaveStreamIndexSet)
     188              : {
     189           17 :     auto slaveStreamIndexIter = slaveStreamIndexSet.begin();
     190           17 :     isLaunchTask = false;
     191           39 :     for (auto slaveQueueIter = slaveQueueIters.begin(); slaveQueueIter != slaveQueueIters.end();) {
     192           22 :         StreamLite* slaveStream = streamLiteMgr->GetSlave(*slaveStreamIndexIter);
     193           22 :         if (UNLIKELY(slaveStream == nullptr)) {
     194            0 :             THROW<NullPtrException>(StringFormat("InsExecutor::%s slaveStream is null,", __func__));
     195              :         }
     196           22 :         if (slaveStream->GetRtsq() == nullptr) {
     197            0 :             THROW<NullPtrException>(StringFormat(
     198              :                 "InsExecutor::%s GetRtsq returned null for slaveStream Id(%u)", __func__, slaveStream->GetId()));
     199              :         }
     200              :         // 判断rtsq队列中的空间是否充足
     201           22 :         bool isRtsqQueueSpaceSufficient = slaveStream->GetRtsq()->IsRtsqQueueSpaceSufficient();
     202              :         // 判断当前从流是否有Int64类型reduce算子,是否需要等其他流任务下发完成
     203           22 :         bool isPreStreamSync = slaveStream->GetRtsq()->GetPreStreamSyncStatus();
     204           22 :         if (isRtsqQueueSpaceSufficient && !isPreStreamSync) {
     205           19 :             if (slaveQueueIter->HasNext()) {
     206           45 :                 HCCL_INFO(
     207              :                     "[ExecuteAllQueues950]InsExecutor::%s slave stream InsQueue start %s SqId(%u) stream Id(%u)",
     208              :                     __func__, (*slaveQueueIter)->Describe().c_str(), slaveStream->GetSqId(), slaveStream->GetId());
     209           15 :                 Interpret(**slaveQueueIter, *slaveStream, resMgrFetcher_);
     210              :                 // 给迭代器内部Iter指向这条流上的InsQueue里下一个task
     211           15 :                 ++(*slaveQueueIter);
     212              :                 // 将迭代器指向下一条流上的InsQueue
     213           15 :                 ++slaveQueueIter;
     214              :                 // 将对应的流的索引执行下一条流
     215           15 :                 ++slaveStreamIndexIter;
     216              :             } else {
     217              :                 // 如果这个InsQueue上没有下一个task了,就擦掉容器内的对应迭代器
     218           12 :                 HCCL_INFO(
     219              :                     "[ExecuteAllQueues950]InsExecutor::%s slave stream Id(%u) Interpret insQueue finish", __func__,
     220              :                     slaveStream->GetId());
     221            4 :                 slaveQueueIter = slaveQueueIters.erase(slaveQueueIter);
     222              :                 // 擦掉对应的从流索引,避免下任务下错从流
     223            4 :                 slaveStreamIndexIter = slaveStreamIndexSet.erase(slaveStreamIndexIter);
     224            4 :                 slaveStream->GetRtsq()->LaunchTask();
     225           12 :                 HCCL_INFO(
     226              :                     "[ExecuteAllQueues950]InsExecutor::%s slave stream Id(%u) launch task finish", __func__,
     227              :                     slaveStream->GetId());
     228              :             }
     229           19 :             isLaunchTask = true;
     230           19 :         } else {
     231              :             // Rtsq上位置不足,先跳去下一个
     232            3 :             ++slaveQueueIter;
     233              :             // 将对应的流的索引执行下一条流
     234            3 :             ++slaveStreamIndexIter;
     235              :         }
     236           22 :         isPreStreamSyncExist_ = slaveStream->GetRtsq()->GetPreStreamSyncStatus() || isPreStreamSyncExist_;
     237              :     }
     238           17 : }
     239              : 
     240           15 : void InsExecutor::ExecuteMasterQueue950(
     241              :     InsQueue::Iterator& masterQueueIter, StreamLite* masterStream, bool& isMasterInsIterEnd, bool& isLaunchTask)
     242              : {
     243              :     // 判断rtsq队列中的空间是否充足
     244           15 :     bool isRtsqQueueSpaceSufficient = masterStream->GetRtsq()->IsRtsqQueueSpaceSufficient();
     245              :     // 判断当前主流是否有Int64类型reduce算子,是否需要等其他流任务下发完成
     246           15 :     bool isPreStreamSync = masterStream->GetRtsq()->GetPreStreamSyncStatus();
     247           15 :     if (isRtsqQueueSpaceSufficient && !isPreStreamSync) {
     248           11 :         if (masterQueueIter.HasNext()) {
     249           21 :             HCCL_INFO(
     250              :                 "[ExecuteAllQueues950]InsExecutor::%s master stream InsQueue start %s SqId(%u) stream Id(%u)", __func__,
     251              :                 masterQueueIter->Describe().c_str(), masterStream->GetSqId(), masterStream->GetId());
     252            7 :             Interpret(*masterQueueIter, *masterStream, resMgrFetcher_);
     253            7 :             ++masterQueueIter;
     254            4 :         } else if (!masterQueueIter.HasNext() && !isMasterInsIterEnd) {
     255           12 :             HCCL_INFO(
     256              :                 "[ExecuteAllQueues950]InsExecutor::%s master stream Id(%u) Interpret insQueue finish", __func__,
     257              :                 masterStream->GetId());
     258            4 :             isMasterInsIterEnd = true;
     259            4 :             masterStream->GetRtsq()->LaunchTask();
     260              :         }
     261           11 :         isLaunchTask = true;
     262              :     }
     263           15 :     isPreStreamSyncExist_ = masterStream->GetRtsq()->GetPreStreamSyncStatus() || isPreStreamSyncExist_;
     264           15 : }
     265              : 
     266           17 : void InsExecutor::CheckPreStreamSync(StreamLiteMgr* streamLiteMgr, u32 slaveQueuesSize)
     267              : {
     268           17 :     if (!isPreStreamSyncExist_) {
     269           12 :         return;
     270              :     }
     271            5 :     u32 preStreamSyncValue = 0;
     272           15 :     for (u32 slaveStreamIndex = 0; slaveStreamIndex < slaveQueuesSize; ++slaveStreamIndex) {
     273           10 :         StreamLite* slaveStream = streamLiteMgr->GetSlave(slaveStreamIndex);
     274           10 :         if (slaveStream == nullptr) {
     275            0 :             THROW<NullPtrException>(StringFormat("InsExecutor::%s slaveStream is null,", __func__));
     276              :         }
     277           10 :         if (slaveStream->GetRtsq() == nullptr) {
     278            0 :             THROW<NullPtrException>(StringFormat(
     279              :                 "InsExecutor::%s GetRtsq returned null for slaveStream Id(%u)", __func__, slaveStream->GetId()));
     280              :         }
     281           10 :         if (slaveStream->GetRtsq()->GetPreStreamSyncStatus()) {
     282            5 :             ++preStreamSyncValue;
     283              :         }
     284              :     }
     285            5 :     StreamLite* masterStream = streamLiteMgr->GetMaster();
     286            5 :     if (masterStream->GetRtsq()->GetPreStreamSyncStatus()) {
     287            5 :         ++preStreamSyncValue;
     288              :     }
     289            5 :     if (preStreamSyncValue == slaveQueuesSize + 1) {
     290            3 :         for (u32 slaveStreamIndex = 0; slaveStreamIndex < slaveQueuesSize; ++slaveStreamIndex) {
     291            2 :             StreamLite* slaveStream = streamLiteMgr->GetSlave(slaveStreamIndex);
     292            2 :             CHK_RET_THROW(
     293              :                 InternalException, StringFormat("[InsExecutor][%s] SetPreStreamSyncFin", __func__),
     294              :                 slaveStream->GetRtsq()->SetPreStreamSyncFin());
     295              :         }
     296            1 :         masterStream->GetRtsq()->SetPreStreamSyncFin();
     297            1 :         CHK_RET_THROW(
     298              :             InternalException, StringFormat("[InsExecutor][%s] SetPreStreamSyncFin", __func__),
     299              :             masterStream->GetRtsq()->SetPreStreamSyncFin());
     300            1 :         isPreStreamSyncExist_ = false;
     301              :     }
     302              : }
     303              : 
     304            0 : void InsExecutor::ExecuteSingleQue(const InsQueue& insQueue, const StreamLite* streamLite, const bool isMaster)
     305              : {
     306            0 :     sqeMgr->Begin(streamLite->GetSqId());
     307            0 :     if (isMaster) {
     308            0 :         HcclNotifyWaitSqe waitSqe;
     309            0 :         waitSqe.Config(
     310            0 :             streamLite->GetSqId(), 0, resMgrFetcher_->GetHostDeviceSyncNotifyLiteMgr()->GetDeviceWaitNotify()->GetId());
     311            0 :         sqeMgr->Add(streamLite->GetSqId(), &waitSqe);
     312            0 :     }
     313              : 
     314            0 :     for (auto iter = insQueue.Iter(); iter.HasNext(); ++iter) {
     315            0 :         HCCL_INFO("InsExecutor::%s start %s", __func__, iter->Describe().c_str());
     316            0 :         vector<std::unique_ptr<HcclSqe>> sqeItems = Interpret(*iter, streamLite->GetSqId(), resMgrFetcher_);
     317            0 :         std::for_each(sqeItems.begin(), sqeItems.end(), [streamLite, this](std::unique_ptr<HcclSqe>& sqeItem) {
     318            0 :             sqeMgr->Add(streamLite->GetSqId(), sqeItem.get());
     319            0 :         });
     320            0 :     }
     321              : 
     322            0 :     if (isMaster) {
     323            0 :         HcclNotifyRecordSqe recordSqe;
     324            0 :         recordSqe.Config(
     325            0 :             streamLite->GetSqId(), 0, resMgrFetcher_->GetHostDeviceSyncNotifyLiteMgr()->GetHostWaitNotify()->GetId());
     326            0 :         sqeMgr->Add(streamLite->GetSqId(), &recordSqe);
     327            0 :     }
     328              : 
     329            0 :     sqeMgr->Commit(streamLite->GetSqId());
     330            0 : }
     331              : 
     332           88 : InsExecutor::InsExecutor(ResMgrFetcher* resMgrFetcher) : resMgrFetcher_(resMgrFetcher)
     333              : {
     334           88 :     CHECK_NULLPTR(resMgrFetcher, "[InsExecutor] resMgrFetcher is nullptr!");
     335           88 :     sqeMgr = make_unique<SqeMgr>(resMgrFetcher->GetDevPhyId());
     336           88 : }
     337              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1