LCOV - code coverage report
Current view: top level - aicpu_schedule/core - aicpusd_msg_send.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.8 % 139 129
Test Date: 2026-08-12 11:05:02 Functions: 100.0 % 8 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 "aicpusd_msg_send.h"
      11              : 
      12              : #include <unistd.h>
      13              : #include <sys/syscall.h>
      14              : #include "ts_api.h"
      15              : #include "aicpusd_info.h"
      16              : #include "aicpusd_drv_manager.h"
      17              : #include "aicpusd_status.h"
      18              : #include "aicpu_async_event.h"
      19              : #include "aicpusd_context.h"
      20              : #include "type_def.h"
      21              : 
      22              : namespace AicpuSchedule {
      23              : namespace {
      24              : thread_local AICPUSendType g_sendType(AICPUSendType::NO_NEED_SEND);
      25              : thread_local AICPUESchedSubmitEvent g_eschedSubmitEvent = {};
      26              : thread_local AICPUTsDevSendMsgAsync g_tsDevSendMsgAsync = {};
      27              : constexpr uint32_t AICPU_KERNEL_END_OF_SEQUENCE_FLAG = 201U;
      28              : constexpr uint32_t TSDEV_SEND_MSG_ASYNC_RETRY_NUM = 10U;
      29              : constexpr uint32_t TSDEV_SEND_MSG_ASYNC_RETRY_INTERVAL = 1000U; // sleep 1ms to retry
      30              : } // namespace
      31              : 
      32           13 : void AicpuMsgSend::SetSchedSubmitEvent(const uint32_t devId, const event_summary& event)
      33              : {
      34           13 :     aicpusd_info("Begin to SetSchedSubmitEvent devId[%u].", devId);
      35           13 :     CheckAndSendEvent();
      36           13 :     AICPUESchedSubmitEvent sched = {};
      37           13 :     sched.deviceId = devId;
      38           13 :     const AICPUSubEventInfo* const subEventInfo = PtrToPtr<char_t, AICPUSubEventInfo>(event.msg);
      39           13 :     sched.modelId = subEventInfo->modelId;
      40           13 :     sched.streamId = subEventInfo->para.streamInfo.streamId;
      41           13 :     sched.summary.pid = event.pid;
      42           13 :     sched.summary.event_id = event.event_id;
      43           13 :     sched.summary.subevent_id = event.subevent_id;
      44           13 :     sched.summary.msg_len = event.msg_len;
      45           13 :     g_eschedSubmitEvent = sched;
      46           13 :     g_sendType = AICPUSendType::SCHED_SUBMIT;
      47           13 : }
      48              : 
      49            7 : void AicpuMsgSend::SetTsDevSendMsgAsync(
      50              :     const uint32_t devId, const uint32_t tsId, const TsAicpuSqe& aicpuSqe, const uint32_t handleId)
      51              : {
      52            7 :     CheckAndSendEvent();
      53              :     AICPUTsDevSendMsgAsync tsDev;
      54            7 :     tsDev.deviceId = devId;
      55            7 :     tsDev.modelId = handleId;
      56            7 :     tsDev.tsId = tsId;
      57            7 :     tsDev.sqe = aicpuSqe;
      58            7 :     tsDev.useSqe = true;
      59            7 :     g_tsDevSendMsgAsync = tsDev;
      60            7 :     g_sendType = AICPUSendType::TS_DEV_SEND;
      61            7 : }
      62              : 
      63            2 : void AicpuMsgSend::SetTsDevSendMsgAsync(
      64              :     const uint32_t devId, const uint32_t tsId, const TsAicpuMsgInfo& msgInfo, const uint32_t handleId)
      65              : {
      66            2 :     CheckAndSendEvent();
      67              :     AICPUTsDevSendMsgAsync tsDev;
      68            2 :     tsDev.deviceId = devId;
      69            2 :     tsDev.modelId = handleId;
      70            2 :     tsDev.tsId = tsId;
      71            2 :     tsDev.msgInfo = msgInfo;
      72            2 :     tsDev.useSqe = false;
      73            2 :     g_tsDevSendMsgAsync = tsDev;
      74            2 :     g_sendType = AICPUSendType::TS_DEV_SEND;
      75            2 : }
      76              : 
      77          156 : void AicpuMsgSend::SendEvent()
      78              : {
      79          156 :     if (g_sendType == AICPUSendType::SCHED_SUBMIT) {
      80           12 :         aicpusd_info("Begin to send event, type[%d].", g_sendType);
      81           12 :         event_summary sched = {};
      82           12 :         sched.pid = g_eschedSubmitEvent.summary.pid;
      83           12 :         sched.event_id = g_eschedSubmitEvent.summary.event_id;
      84           12 :         sched.subevent_id = g_eschedSubmitEvent.summary.subevent_id;
      85           12 :         sched.msg_len = g_eschedSubmitEvent.summary.msg_len;
      86           12 :         AICPUSubEventInfo subEventInfo = {};
      87           12 :         subEventInfo.modelId = g_eschedSubmitEvent.modelId;
      88           12 :         subEventInfo.para.streamInfo.streamId = g_eschedSubmitEvent.streamId;
      89           12 :         sched.msg = PtrToPtr<AICPUSubEventInfo, char_t>(&subEventInfo);
      90           12 :         sched.grp_id = 0U; // default : 0
      91           12 :         DeployContext deployCtx = DeployContext::DEVICE;
      92           12 :         (void)GetAicpuDeployContext(deployCtx);
      93           12 :         if (deployCtx == DeployContext::HOST) {
      94            0 :             sched.dst_engine = static_cast<uint32_t>(CCPU_HOST);
      95            0 :             aicpusd_info("SendEvent to dst engine: %u, modelId: %u", sched.dst_engine, subEventInfo.modelId);
      96              :         }
      97           12 :         const drvError_t ret = halEschedSubmitEvent(g_eschedSubmitEvent.deviceId, &sched);
      98           12 :         if (ret != DRV_ERROR_NONE) {
      99            0 :             aicpusd_err("Submit event failed. ret=%d", ret);
     100              :         }
     101           12 :         g_sendType = AICPUSendType::NO_NEED_SEND;
     102           12 :         return;
     103              :     }
     104          144 :     if (g_sendType == AICPUSendType::TS_DEV_SEND) {
     105            8 :         aicpusd_info("Begin to send event, type[%d].", g_sendType);
     106            8 :         int32_t ret = DRV_ERROR_NONE;
     107            8 :         for (uint32_t index = 0; index < TSDEV_SEND_MSG_ASYNC_RETRY_NUM; index++) {
     108            8 :             if (g_tsDevSendMsgAsync.useSqe) {
     109            7 :                 ret = tsDevSendMsgAsync(
     110              :                     g_tsDevSendMsgAsync.deviceId, g_tsDevSendMsgAsync.tsId,
     111              :                     PtrToPtr<TsAicpuSqe, char_t>(&(g_tsDevSendMsgAsync.sqe)), static_cast<uint32_t>(sizeof(TsAicpuSqe)),
     112              :                     g_tsDevSendMsgAsync.modelId);
     113              :             } else {
     114            1 :                 ret = tsDevSendMsgAsync(
     115              :                     g_tsDevSendMsgAsync.deviceId, g_tsDevSendMsgAsync.tsId,
     116              :                     PtrToPtr<TsAicpuMsgInfo, char_t>(&(g_tsDevSendMsgAsync.msgInfo)),
     117              :                     static_cast<uint32_t>(sizeof(TsAicpuMsgInfo)), g_tsDevSendMsgAsync.modelId);
     118              :             }
     119            8 :             if (ret == DRV_ERROR_NONE) {
     120            8 :                 aicpusd_info(
     121              :                     "Send async msg to ts success, deviceId=%u, tsId=%u", g_tsDevSendMsgAsync.deviceId,
     122              :                     g_tsDevSendMsgAsync.tsId);
     123            8 :                 g_sendType = AICPUSendType::NO_NEED_SEND;
     124            8 :                 return;
     125              :             } else {
     126            0 :                 aicpusd_run_info(
     127              :                     "Sending async msg to ts was not successful. ret=%d, deviceId=%u, tsId=%u, retry times=%d", ret,
     128              :                     g_tsDevSendMsgAsync.deviceId, g_tsDevSendMsgAsync.tsId, index);
     129              :             }
     130            0 :             (void)usleep(TSDEV_SEND_MSG_ASYNC_RETRY_INTERVAL);
     131              :         }
     132            0 :         if (ret != DRV_ERROR_NONE) {
     133            0 :             aicpusd_err(
     134              :                 "After retry, Send async msg to ts failed. ret=%d, deviceId=%u, tsId=%u", ret,
     135              :                 g_tsDevSendMsgAsync.deviceId, g_tsDevSendMsgAsync.tsId);
     136              :         }
     137            0 :         return;
     138              :     }
     139              : }
     140              : 
     141           17 : int32_t AicpuMsgSend::SendAICPUSubEvent(
     142              :     const char_t* const msg, const uint32_t msgLen, const uint32_t subEventId, const uint32_t grpId,
     143              :     const bool syncSendFlag)
     144              : {
     145           17 :     aicpusd_info("Begin to send aicpu subevent, syncflag is %d", static_cast<int32_t>(syncSendFlag));
     146           17 :     if (msg == nullptr) {
     147            1 :         aicpusd_err("The message is null.");
     148            1 :         return AICPU_SCHEDULE_ERROR_INVALID_EVENT_SUBMIT;
     149              :     }
     150              : 
     151           16 :     if (msgLen == 0U) {
     152            1 :         aicpusd_err("The size of message is zero.");
     153            1 :         return AICPU_SCHEDULE_ERROR_INVALID_EVENT_SUBMIT;
     154              :     }
     155           15 :     event_summary eventInfoSummary = {};
     156           15 :     eventInfoSummary.pid = getpid();
     157           15 :     eventInfoSummary.event_id = EVENT_AICPU_MSG;
     158           15 :     eventInfoSummary.subevent_id = subEventId;
     159           15 :     std::string msgStr(msg, static_cast<size_t>(msgLen));
     160           15 :     eventInfoSummary.msg = &msgStr[0];
     161           15 :     eventInfoSummary.msg_len = msgLen;
     162           15 :     eventInfoSummary.grp_id = grpId;
     163           15 :     DeployContext deployCtx = DeployContext::DEVICE;
     164           15 :     (void)GetAicpuDeployContext(deployCtx);
     165           15 :     if ((deployCtx == DeployContext::HOST) || (subEventId == static_cast<uint32_t>(AICPU_SUB_EVENT_ACTIVE_MODEL))) {
     166            2 :         eventInfoSummary.dst_engine = static_cast<uint32_t>(CCPU_LOCAL);
     167            2 :         aicpusd_info("SendAICPUSubEvent to dst engine: %u", eventInfoSummary.dst_engine);
     168              :     }
     169              : 
     170           15 :     if (syncSendFlag) {
     171            9 :         const drvError_t ret = halEschedSubmitEvent(AicpuDrvManager::GetInstance().GetDeviceId(), &eventInfoSummary);
     172            9 :         if (ret != DRV_ERROR_NONE) {
     173            0 :             aicpusd_err("Failed to submit aicpu event. ret is %d.", ret);
     174            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     175              :         }
     176            9 :         return AICPU_SCHEDULE_OK;
     177              :     }
     178              : 
     179            6 :     AicpuMsgSend::SetSchedSubmitEvent(AicpuDrvManager::GetInstance().GetDeviceId(), eventInfoSummary);
     180            6 :     return AICPU_SCHEDULE_OK;
     181           15 : }
     182              : 
     183           22 : void AicpuMsgSend::CheckAndSendEvent()
     184              : {
     185           22 :     if (g_sendType != AICPUSendType::NO_NEED_SEND) {
     186           12 :         SendEvent();
     187              :     }
     188           22 : }
     189              : 
     190            2 : void AicpuMsgSend::AicpuReportNotifyInfo(const aicpu::AsyncNotifyInfo& notifyInfo)
     191              : {
     192            2 :     aicpusd_err(
     193              :         "Send aicpu notify info to ts, streamId=%u, taskId=%lu, retcode=%u.", notifyInfo.streamId, notifyInfo.taskId,
     194              :         notifyInfo.retCode);
     195              : 
     196            2 :     AicpuSqeAdapter aicpuSqeAdapter(FeatureCtrl::GetTsMsgVersion());
     197              :     AicpuSqeAdapter::AicpuRecordInfo recordInfo(
     198            2 :         notifyInfo.waitId, notifyInfo.waitType, notifyInfo.retCode, static_cast<uint8_t>(notifyInfo.ctx.tsId),
     199            2 :         notifyInfo.taskId, notifyInfo.streamId, notifyInfo.ctx.deviceId);
     200            2 :     const int32_t ret = aicpuSqeAdapter.AicpuRecordResponseToTs(recordInfo);
     201            2 :     if (ret != AICPU_SCHEDULE_OK) {
     202            1 :         aicpusd_err(
     203              :             "AicpuRecordResponseToTs failed. ret=%d, streamId=%u, taskId=%lu.", ret, notifyInfo.streamId,
     204              :             notifyInfo.taskId);
     205              :     }
     206            2 : }
     207              : 
     208            5 : void AicpuMsgSend::SendAicpuRecordMsg(const void* const notifyParam, const uint32_t paramLen)
     209              : {
     210            5 :     if ((notifyParam == nullptr) || (paramLen != sizeof(aicpu::AsyncNotifyInfo))) {
     211            1 :         aicpusd_err(
     212              :             "NotifyEventWait param is null or paramLen not matched. paramLen = %u, AsyncNotifyInfo size = %zu",
     213              :             paramLen, sizeof(aicpu::AsyncNotifyInfo));
     214            2 :         return;
     215              :     }
     216            4 :     const aicpu::AsyncNotifyInfo* const notifyInfo = reinterpret_cast<const aicpu::AsyncNotifyInfo*>(notifyParam);
     217            4 :     if ((notifyInfo->retCode != 0U) && (notifyInfo->retCode != AICPU_KERNEL_END_OF_SEQUENCE_FLAG)) {
     218            3 :         aicpusd_err(
     219              :             "Aicpu recevied error code, wait_type[%u], wait_id[%u], task_id[%lu], stream_id[%u], ret_code[%u].",
     220              :             notifyInfo->waitType, notifyInfo->waitId, notifyInfo->taskId, notifyInfo->streamId, notifyInfo->retCode);
     221              :     } else {
     222            1 :         aicpusd_info(
     223              :             "NotifyEventWait, wait_type[%u], wait_id[%u], task_id[%lu], stream_id[%u], ret_code[%u].",
     224              :             notifyInfo->waitType, notifyInfo->waitId, notifyInfo->taskId, notifyInfo->streamId, notifyInfo->retCode);
     225              :     }
     226              : 
     227              :     // create param.
     228            4 :     int32_t sendRet = 0;
     229            4 :     int32_t retCode = 0;
     230            4 :     bool retSucc = notifyInfo->retCode == 0U;
     231            4 :     bool isRetEndSequence = (notifyInfo->retCode == AICPU_KERNEL_END_OF_SEQUENCE_FLAG);
     232            4 :     retCode = retSucc ? (notifyInfo->retCode) :
     233              :                         (isRetEndSequence ? static_cast<uint16_t>(TS_ERROR_END_OF_SEQUENCE) :
     234              :                                             static_cast<uint16_t>(TS_ERROR_AICPU_EXCEPTION));
     235            4 :     AicpuSqeAdapter aicpuSqeAdapter(FeatureCtrl::GetTsMsgVersion());
     236              :     AicpuSqeAdapter::AicpuRecordInfo recordInfo(
     237            4 :         notifyInfo->waitId, notifyInfo->waitType, retCode, static_cast<uint8_t>(notifyInfo->ctx.tsId),
     238            4 :         notifyInfo->taskId, notifyInfo->streamId, notifyInfo->ctx.deviceId);
     239            4 :     sendRet = aicpuSqeAdapter.AicpuRecordResponseToTs(recordInfo);
     240            4 :     if (sendRet != static_cast<uint32_t>(AICPU_SCHEDULE_OK)) {
     241            1 :         aicpusd_err(
     242              :             "Send event notify to ts failed, sendRet=%d, notifyId=%u, retVal=%d.", sendRet, notifyInfo->waitId,
     243              :             notifyInfo->retCode);
     244            1 :         return;
     245              :     }
     246            3 :     aicpusd_info(
     247              :         "send event notify to ts success, notifyId=%u, hostpid=%u, retCode=%d.", notifyInfo->waitId,
     248              :         AicpuDrvManager::GetInstance().GetHostPid(), notifyInfo->retCode);
     249            4 : }
     250              : } // namespace AicpuSchedule
        

Generated by: LCOV version 2.0-1