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

Generated by: LCOV version 2.0-1