LCOV - code coverage report
Current view: top level - legacy/ascend910/framework/common/src/order_launch - order_launch.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 24.0 % 175 42
Test Date: 2026-08-18 17:47:01 Functions: 40.0 % 15 6

            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 "order_launch.h"
      12              : #include "log.h"
      13              : #include "acl/acl_rt.h"
      14              : #include "config_log.h"
      15              : #include "hccl_types.h"
      16              : #include "adapter_rts_common.h"
      17              : 
      18              : namespace hccl {
      19         1330 : OrderLaunch& OrderLaunch::GetInstance(s32 deviceLogicID)
      20              : {
      21         2110 :     static OrderLaunch orderLaunch[MAX_MODULE_DEVICE_NUM];
      22         1330 :     if (static_cast<u32>(deviceLogicID) >= MAX_MODULE_DEVICE_NUM) {
      23          273 :         HCCL_WARNING("[OrderLaunch][GetInstance]Invalid deviceLogicID[%d]", deviceLogicID);
      24          273 :         return orderLaunch[0];
      25              :     }
      26         1057 :     HCCL_DEBUG("[OrderLaunch][GetInstance]Valid deviceLogicID[%d]", deviceLogicID);
      27         1057 :     return orderLaunch[deviceLogicID];
      28              : }
      29              : 
      30          780 : OrderLaunch::OrderLaunch() : initialized_(true) {}
      31              : 
      32          780 : OrderLaunch::~OrderLaunch()
      33              : {
      34          780 :     std::unique_lock<std::mutex> mapLock(streamMutex_);
      35          780 :     initialized_ = false;
      36          780 :     groupCtxMap_.clear();
      37          780 :     DestroyRes();
      38          780 : }
      39              : 
      40          780 : void OrderLaunch::DestroyRes()
      41              : {
      42          780 :     for (auto& entry : contextResMgrMap_) {
      43            0 :         entry.second.DestroyResources();
      44              :     }
      45          780 :     contextResMgrMap_.clear();
      46          780 :     hcomStreamMap_.clear();
      47          780 : }
      48              : 
      49          523 : HcclResult OrderLaunch::RegisterOrderLaunch(const std::string& group)
      50              : {
      51          523 :     std::unique_lock<std::mutex> mapLock(streamMutex_);
      52          523 :     if (groupCtxMap_.find(group) != groupCtxMap_.end()) {
      53            1 :         HCCL_WARNING("%s skip, group[%s] has already been registered", __func__, group.c_str());
      54            1 :         return HCCL_SUCCESS;
      55              :     }
      56              :     // 只记录group,context暂不赋值,只在算子下发阶段对context赋值
      57          522 :     groupCtxMap_.insert({group, INVALID_U64});
      58          522 :     HCCL_INFO("%s success, group[%s]", __func__, group.c_str());
      59          522 :     return HCCL_SUCCESS;
      60          523 : }
      61              : 
      62              : /**
      63              :  * @brief 从order launch系统注销group
      64              :  * 注销group时,会清理group与context的映射关系。
      65              :  * 只有当context下没有其他group时,才会清理context对应的资源。
      66              :  */
      67          807 : HcclResult OrderLaunch::UnRegisterOrderLaunch(const std::string& group)
      68              : {
      69          807 :     CHK_PRT_RET(initialized_ == false, HCCL_WARNING("OrderLaunch has been destroyed"), HCCL_SUCCESS);
      70          807 :     std::unique_lock<std::mutex> mapLock(streamMutex_);
      71          807 :     auto it = groupCtxMap_.find(group);
      72          805 :     if (it == groupCtxMap_.end()) {
      73          285 :         HCCL_WARNING("%s skip, group[%s] has not been registered", __func__, group.c_str());
      74          285 :         return HCCL_SUCCESS;
      75              :     }
      76              : 
      77          519 :     u64 context = it->second;
      78          521 :     HCCL_INFO(
      79              :         "[OrderLaunch][UnRegisterOrderLaunch] group[%s] context[0x%llx], contextGroupsMap_.size[%zu]", group.c_str(),
      80              :         context, contextGroupsMap_.size());
      81          522 :     if (contextGroupsMap_.find(context) != contextGroupsMap_.end()) {
      82            0 :         contextGroupsMap_[context].erase(group);
      83            0 :         if (contextGroupsMap_[context].empty()) {
      84            0 :             contextGroupsMap_.erase(context);
      85            0 :             if (contextResMgrMap_.find(context) != contextResMgrMap_.end()) {
      86            0 :                 contextResMgrMap_[context].DestroyResources();
      87            0 :                 contextResMgrMap_.erase(context);
      88              :             }
      89            0 :             HCCL_INFO("%s contextGroupsMap_ erase context[0x%llx]", __func__, context);
      90              :         }
      91              :     }
      92              : 
      93          519 :     groupCtxMap_.erase(it);
      94          520 :     HCCL_INFO("%s success, group[%s]", __func__, group.c_str());
      95          522 :     return HCCL_SUCCESS;
      96          807 : }
      97              : 
      98              : /**
      99              :  * @brief 设置图模式使用的HCOM stream
     100              :  * 图模式下,通信使用的附属从流预先设置到hcomStreamMap_中
     101              :  */
     102            0 : HcclResult OrderLaunch::SetHcomStream(u32 graphId, const Stream& hcomAttachedStream)
     103              : {
     104            0 :     std::unique_lock<std::mutex> mapLock(streamMutex_);
     105            0 :     hcomStreamMap_[graphId] = hcomAttachedStream;
     106            0 :     HCCL_INFO("%s success, graphId[%u], hcomStreamId[%u]", __func__, graphId, hcomAttachedStream.id());
     107            0 :     return HCCL_SUCCESS;
     108            0 : }
     109              : 
     110              : /**
     111              :  * @brief 初始化group的context映射关系
     112              :  *
     113              :  * 获取当前线程的context,建立以下映射关系:
     114              :  *   - groupCtxMap_[group] = currentContext
     115              :  *   - contextGroupsMap_[currentContext] 包含 group
     116              :  *   - contextResMgrMap_[currentContext] 包含该context的资源管理器
     117              :  */
     118            0 : HcclResult OrderLaunch::InitGroupCtx(const std::string& group)
     119              : {
     120            0 :     u64 currentContext = INVALID_U64;
     121            0 :     HcclResult ret = GetCurrentContext(currentContext);
     122            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[%s]GetCurrentContext failed, ret[%d]", __func__, ret), ret);
     123              : 
     124            0 :     if (contextResMgrMap_.find(currentContext) == contextResMgrMap_.end()) {
     125            0 :         contextResMgrMap_[currentContext] = OrderLaunchResMgr();
     126            0 :         HCCL_INFO("[OrderLaunch][InitGroupCtx] created new OrderLaunchResMgr for context[0x%llx]", currentContext);
     127              :     }
     128              : 
     129            0 :     auto& resMgr = contextResMgrMap_[currentContext];
     130            0 :     if (!resMgr.contextInitialized) {
     131            0 :         resMgr.MarkContextInitialized(currentContext);
     132              :     }
     133              : 
     134            0 :     groupCtxMap_[group] = currentContext;
     135            0 :     contextGroupsMap_[currentContext].insert(group);
     136              : 
     137            0 :     HCCL_RUN_INFO("[%s]group[%s] init or update context[0x%llx]", __func__, group.c_str(), currentContext);
     138            0 :     return HCCL_SUCCESS;
     139              : }
     140              : 
     141              : // aclgraph模式下,先在kernel stream上写record,再在上order stream写wait;解order stream的wait
     142            0 : HcclResult OrderLaunch::AclgraphLaunchInOrderToOrderStream(
     143              :     std::string& group, const Stream& kernelStream, std::shared_ptr<LocalNotify> notify0,
     144              :     std::shared_ptr<LocalNotify> notify1, u32 timeOut, HcclRtEvent event)
     145              : {
     146            0 :     std::unique_lock<std::mutex> mapLock(streamMutex_);
     147              :     // group未注册过,或者未记录过算子下发阶段的线程context
     148            0 :     if (groupCtxMap_.find(group) == groupCtxMap_.end() || groupCtxMap_[group] == INVALID_U64) {
     149            0 :         CHK_RET(InitGroupCtx(group));
     150              :     }
     151              : 
     152            0 :     u64 context = groupCtxMap_[group];
     153            0 :     Stream& aclgraphStream = contextResMgrMap_[context].aclgraphStream;
     154            0 :     EnsureOrderStreamForGroup(group, context, aclgraphStream); // aclgraph控制流
     155              : 
     156            0 :     aclError ret = ACL_SUCCESS;
     157              :     // kernelStream -> aclgraphStream
     158            0 :     ret = aclrtRecordEvent(event, kernelStream.ptr());
     159            0 :     CHK_PRT_RET(ret != ACL_SUCCESS, HCCL_ERROR("[%s]aclrtRecordEvent failed, ret[%d]", __func__, ret), HCCL_E_RUNTIME);
     160            0 :     HCCL_CONFIG_INFO(HCCL_TASK, "[%s]aclrtRecordEvent para: kernelStreamId[%d]", __func__, kernelStream.id());
     161              : 
     162            0 :     ret = aclrtStreamWaitEvent(aclgraphStream.ptr(), event);
     163            0 :     CHK_PRT_RET(
     164              :         ret != ACL_SUCCESS, HCCL_ERROR("[%s]aclrtStreamWaitEvent failed, ret[%d]", __func__, ret), HCCL_E_RUNTIME);
     165            0 :     HCCL_CONFIG_INFO(HCCL_TASK, "[%s]aclrtStreamWaitEvent para: orderStreamId[%d]", __func__, aclgraphStream.id());
     166              : 
     167            0 :     HCCL_INFO(
     168              :         "[%s] group[%s], kernelStreamId[%u], orderStreamId[%u], context[0x%llx]", __func__, group.c_str(),
     169              :         kernelStream.id(), aclgraphStream.id(), context);
     170            0 :     CHK_RET(LaunchInOrder(group, kernelStream, aclgraphStream, notify0, notify1, timeOut));
     171            0 :     return HCCL_SUCCESS;
     172            0 : }
     173              : 
     174              : /**
     175              :  * @brief ACLGRAPH模式第二步:在order stream上record事件并解kernel stream的wait
     176              :  * 执行流程:
     177              :  * 1. 在order stream上record事件
     178              :  * 2. 在kernel stream上wait该事件,解开kernel stream的阻塞
     179              :  */
     180              : HcclResult
     181            0 : OrderLaunch::AclgraphLaunchInOrderToKernelStream(std::string& group, const Stream& kernelStream, HcclRtEvent event)
     182              : {
     183            0 :     std::unique_lock<std::mutex> mapLock(streamMutex_);
     184              : 
     185            0 :     auto ctxIt = groupCtxMap_.find(group);
     186            0 :     CHK_PRT_RET(
     187              :         ctxIt == groupCtxMap_.end(), HCCL_ERROR("[%s]fail, group[%s] is not in groupCtxMap_", __func__, group.c_str()),
     188              :         HCCL_E_NOT_FOUND);
     189              : 
     190            0 :     u64 context = ctxIt->second;
     191            0 :     if (contextResMgrMap_.find(context) == contextResMgrMap_.end()) {
     192            0 :         HCCL_ERROR("[%s]fail, context[0x%llx] is not in contextResMgrMap_", __func__, context);
     193            0 :         return HCCL_E_NOT_FOUND;
     194              :     }
     195              : 
     196            0 :     Stream& aclgraphStream = contextResMgrMap_[context].aclgraphStream;
     197              : 
     198            0 :     aclError ret = ACL_SUCCESS;
     199            0 :     ret = aclrtRecordEvent(event, aclgraphStream.ptr());
     200            0 :     CHK_PRT_RET(ret != ACL_SUCCESS, HCCL_ERROR("[%s]aclrtRecordEvent failed, ret[%d]", __func__, ret), HCCL_E_RUNTIME);
     201            0 :     HCCL_CONFIG_INFO(HCCL_TASK, "[%s]aclrtRecordEvent para: orderStreamId[%d]", __func__, aclgraphStream.id());
     202              : 
     203            0 :     ret = aclrtStreamWaitEvent(kernelStream.ptr(), event);
     204            0 :     CHK_PRT_RET(
     205              :         ret != ACL_SUCCESS, HCCL_ERROR("[%s]aclrtStreamWaitEvent failed, ret[%d]", __func__, ret), HCCL_E_RUNTIME);
     206            0 :     HCCL_CONFIG_INFO(HCCL_TASK, "[%s]aclrtStreamWaitEvent para: kernelStreamId[%d]", __func__, kernelStream.id());
     207              : 
     208            0 :     HCCL_INFO(
     209              :         "[%s] group[%s], kernelStreamId[%u], orderStreamId[%u], context[0x%llx]", __func__, group.c_str(),
     210              :         kernelStream.id(), aclgraphStream.id(), ctxIt->second);
     211            0 :     return HCCL_SUCCESS;
     212            0 : }
     213              : 
     214            0 : HcclResult OrderLaunch::OpbaseLaunchInOrder(
     215              :     std::string& group, const Stream& kernelStream, std::shared_ptr<LocalNotify> notify0,
     216              :     std::shared_ptr<LocalNotify> notify1, u32 timeOut)
     217              : {
     218            0 :     std::unique_lock<std::mutex> mapLock(streamMutex_);
     219            0 :     HCCL_INFO(
     220              :         "[OrderLaunch][OpbaseLaunchInOrder] group[%s], kernelStreamId[%u], timeOut[%d ms]", group.c_str(),
     221              :         kernelStream.id(), timeOut);
     222              :     // group未注册过,或者未记录过算子下发阶段的线程context
     223            0 :     if (groupCtxMap_.find(group) == groupCtxMap_.end() || groupCtxMap_[group] == INVALID_U64) {
     224            0 :         CHK_RET(InitGroupCtx(group));
     225              :     }
     226              : 
     227            0 :     u64 context = groupCtxMap_[group];
     228            0 :     Stream& opbaseStream = contextResMgrMap_[context].opbaseStream;
     229            0 :     EnsureOrderStreamForGroup(group, context, opbaseStream); // 单算子控制流
     230              : 
     231            0 :     HCCL_INFO(
     232              :         "[%s] group[%s], kernelStreamId[%u], orderStreamId[%u], context[0x%llx]", __func__, group.c_str(),
     233              :         kernelStream.id(), opbaseStream.id(), context);
     234            0 :     CHK_RET(LaunchInOrder(group, kernelStream, opbaseStream, notify0, notify1, timeOut));
     235            0 :     return HCCL_SUCCESS;
     236            0 : }
     237              : 
     238              : /**
     239              :  * @brief 图模式下的按序下发
     240              :  *
     241              :  * 图模式下,使用预先设置的hcomAttachedStream作为order stream
     242              :  */
     243            0 : HcclResult OrderLaunch::HcomLaunchInOrder(
     244              :     std::string& group, const Stream& kernelStream, u32 graphId, std::shared_ptr<LocalNotify> notify0,
     245              :     std::shared_ptr<LocalNotify> notify1, u32 timeOut)
     246              : {
     247            0 :     std::unique_lock<std::mutex> mapLock(streamMutex_);
     248            0 :     Stream hostOrderStream;
     249            0 :     if (hcomStreamMap_.find(graphId) == hcomStreamMap_.end()) {
     250            0 :         HCCL_ERROR("[%s] graphId[%u] group[%s] stream not found", __func__, graphId, group.c_str());
     251            0 :         return HCCL_E_NOT_FOUND;
     252              :     }
     253            0 :     hostOrderStream = hcomStreamMap_[graphId];
     254            0 :     CHK_PTR_NULL(hostOrderStream.ptr());
     255            0 :     HCCL_INFO("[%s] group[%s], graphId[%u], streamId[%u]", __func__, group.c_str(), graphId, hostOrderStream.id());
     256            0 :     CHK_RET(LaunchInOrder(group, kernelStream, hostOrderStream, notify0, notify1, timeOut));
     257            0 :     return HCCL_SUCCESS;
     258            0 : }
     259              : 
     260              : /**
     261              :  * @brief 使用notify机制实现stream间的按序下发
     262              :  * 1. wait notify0 on kernelStream - 等待kernel stream上的算子完成
     263              :  * 2. record notify0 on hostOrderStream - 在order stream上record notify
     264              :  * 3. wait notify1 on hostOrderStream - 等待其他算子在order stream上完成
     265              :  */
     266            0 : HcclResult OrderLaunch::LaunchInOrder(
     267              :     [[maybe_unused]] std::string& group, const Stream& kernelStream, const Stream& hostOrderStream,
     268              :     std::shared_ptr<LocalNotify> notify0, std::shared_ptr<LocalNotify> notify1, u32 timeOut)
     269              : {
     270            0 :     CHK_SMART_PTR_NULL(notify0);
     271            0 :     CHK_SMART_PTR_NULL(notify1);
     272            0 :     aclError ret = ACL_SUCCESS;
     273            0 :     ret = aclrtWaitAndResetNotify(notify0->ptr(), kernelStream.ptr(), timeOut);
     274            0 :     CHK_PRT_RET(
     275              :         ret != ACL_SUCCESS,
     276              :         HCCL_ERROR(
     277              :             "[%s] aclrtWaitAndResetNotify failed, ret[%d], notifyId[%u], streamId[%d], timeOut[%d s]", __func__, ret,
     278              :             notify0->notifyId_, kernelStream.id(), timeOut),
     279              :         HCCL_E_RUNTIME);
     280            0 :     HCCL_CONFIG_INFO(
     281              :         HCCL_TASK, "[%s] aclrtWaitAndResetNotify para: notifyId[%u], streamId[%d], timeOut[%d s]", __func__,
     282              :         notify0->notifyId_, kernelStream.id(), timeOut);
     283              : 
     284            0 :     ret = aclrtRecordNotify(notify0->ptr(), hostOrderStream.ptr());
     285            0 :     CHK_PRT_RET(
     286              :         ret != ACL_SUCCESS,
     287              :         HCCL_ERROR(
     288              :             "[%s] aclrtRecordNotify failed, ret[%d], notifyId[%u], streamId[%d]", __func__, ret, notify0->notifyId_,
     289              :             hostOrderStream.id()),
     290              :         HCCL_E_RUNTIME);
     291            0 :     HCCL_CONFIG_INFO(
     292              :         HCCL_TASK, "[%s] aclrtRecordNotify para: notifyId[%u], streamId[%d]", __func__, notify0->notifyId_,
     293              :         hostOrderStream.id());
     294              : 
     295            0 :     ret = aclrtWaitAndResetNotify(notify1->ptr(), hostOrderStream.ptr(), timeOut);
     296            0 :     CHK_PRT_RET(
     297              :         ret != ACL_SUCCESS,
     298              :         HCCL_ERROR(
     299              :             "[%s] aclrtWaitAndResetNotify failed, ret[%d], notifyId[%u], streamId[%d], timeOut[%d s]", __func__, ret,
     300              :             notify1->notifyId_, hostOrderStream.id(), timeOut),
     301              :         HCCL_E_RUNTIME);
     302            0 :     HCCL_CONFIG_INFO(
     303              :         HCCL_TASK, "[%s] aclrtWaitAndResetNotify para: notifyId[%u], streamId[%d], timeOut[%d s]", __func__,
     304              :         notify1->notifyId_, hostOrderStream.id(), timeOut);
     305            0 :     return HCCL_SUCCESS;
     306              : }
     307              : 
     308            0 : HcclResult OrderLaunch::EnsureOrderStreamForGroup(std::string& group, u64 context, Stream& orderStream)
     309              : {
     310            0 :     auto it = groupCtxMap_.find(group);
     311            0 :     if (it == groupCtxMap_.end()) {
     312            0 :         HCCL_ERROR("[%s] group[%s] not found", __func__, group.c_str());
     313            0 :         return HCCL_E_PARA;
     314              :     }
     315              : 
     316            0 :     if (contextResMgrMap_.find(context) == contextResMgrMap_.end()) {
     317            0 :         HCCL_ERROR("[%s] context[0x%llx] not found for group[%s]", __func__, context, group.c_str());
     318            0 :         return HCCL_E_PARA;
     319              :     }
     320              : 
     321            0 :     auto& groupCtxRes = contextResMgrMap_[context];
     322              : 
     323            0 :     if (orderStream.ptr() == nullptr) {
     324            0 :         HCCL_INFO(
     325              :             "[OrderLaunch][EnsureOrderStreamForGroup] creating new order stream for group[%s], context[0x%llx]",
     326              :             group.c_str(), context);
     327              :         // Stream 尚未创建,基于传入的 context 创建
     328              :         // 创建新的order stream; streamMode = 1 使能遇错即停,避免出错后流卡住不退
     329            0 :         constexpr u32 streamMode = 1;
     330            0 :         orderStream = Stream(StreamType::STREAM_TYPE_ONLINE);
     331            0 :         CHK_RET(hrtStreamSetMode(orderStream.ptr(), streamMode));
     332            0 :         HCCL_INFO(
     333              :             "[OrderLaunch] Created new order stream with id[%d] with context [0x%llx]", orderStream.id(), context);
     334              : 
     335              :         // 对group->contextResource的映射关系进行更新
     336            0 :         if (!groupCtxRes.contextInitialized) {
     337            0 :             groupCtxRes.MarkContextInitialized(context);
     338              :         } else {
     339            0 :             groupCtxRes.UpdateContext(context);
     340              :         }
     341              :         // 对context->group的映射关系进行更新
     342            0 :         contextGroupsMap_[context].insert(group);
     343            0 :         HCCL_INFO(
     344              :             "[OrderLaunch] Added group[%s] to context [0x%llx] with order stream id[%d]", group.c_str(), context,
     345              :             orderStream.id());
     346              :     } else {
     347            0 :         HCCL_INFO(
     348              :             "[OrderLaunch][EnsureOrderStreamForGroup] order stream already exists, group[%s], context[0x%llx], "
     349              :             "streamId[%d]",
     350              :             group.c_str(), context, orderStream.id());
     351              :     }
     352            0 :     return HCCL_SUCCESS;
     353              : }
     354              : 
     355              : /**
     356              :  * @brief 获取当前线程的context
     357              :  * 通过hrtCtxGetCurrent接口获取当前线程关联的runtime context
     358              :  */
     359            0 : HcclResult OrderLaunch::GetCurrentContext(u64& currentContext)
     360              : {
     361            0 :     HcclRtContext rtCtx = nullptr;
     362            0 :     CHK_RET(hrtCtxGetCurrent(&rtCtx));
     363            0 :     currentContext = reinterpret_cast<u64>(rtCtx);
     364              : 
     365            0 :     if (currentContext == INVALID_U64) {
     366            0 :         HCCL_ERROR("[%s] GetCurrentContext failed", __func__);
     367            0 :         return HCCL_E_RUNTIME;
     368              :     }
     369              : 
     370            0 :     return HCCL_SUCCESS;
     371              : }
     372              : } // namespace hccl
        

Generated by: LCOV version 2.0-1