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.9 % 141 131
Test Date: 2026-07-28 10:54:05 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              : }
      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(const uint32_t devId, const uint32_t tsId, const TsAicpuSqe &aicpuSqe,
      50              :     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(const uint32_t devId, const uint32_t tsId, const TsAicpuMsgInfo &msgInfo,
      64              :         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          155 : void AicpuMsgSend::SendEvent()
      78              : {
      79          155 :     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          143 :     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(g_tsDevSendMsgAsync.deviceId, g_tsDevSendMsgAsync.tsId,
     110              :                 PtrToPtr<TsAicpuSqe, char_t>(&(g_tsDevSendMsgAsync.sqe)), static_cast<uint32_t>(sizeof(TsAicpuSqe)),
     111              :                 g_tsDevSendMsgAsync.modelId);
     112              :             } else {
     113            1 :                 ret = tsDevSendMsgAsync(g_tsDevSendMsgAsync.deviceId, g_tsDevSendMsgAsync.tsId,
     114              :                 PtrToPtr<TsAicpuMsgInfo, char_t>(&(g_tsDevSendMsgAsync.msgInfo)), 
     115              :                 static_cast<uint32_t>(sizeof(TsAicpuMsgInfo)), g_tsDevSendMsgAsync.modelId);
     116              :             }
     117            8 :             if (ret == DRV_ERROR_NONE) {
     118            8 :                 aicpusd_info("Send async msg to ts success, deviceId=%u, tsId=%u",
     119              :                              g_tsDevSendMsgAsync.deviceId, g_tsDevSendMsgAsync.tsId);
     120            8 :                 g_sendType = AICPUSendType::NO_NEED_SEND;
     121            8 :                 return;
     122              :             } else {
     123            0 :                 aicpusd_run_info("Sending async msg to ts was not successful. ret=%d, deviceId=%u, tsId=%u, retry times=%d",
     124              :                                  ret, g_tsDevSendMsgAsync.deviceId,  g_tsDevSendMsgAsync.tsId, index);
     125              :             }
     126            0 :             (void)usleep(TSDEV_SEND_MSG_ASYNC_RETRY_INTERVAL);
     127              :         }
     128            0 :         if (ret != DRV_ERROR_NONE) {
     129            0 :             aicpusd_err("After retry, Send async msg to ts failed. ret=%d, deviceId=%u, tsId=%u",
     130              :                         ret, g_tsDevSendMsgAsync.deviceId,  g_tsDevSendMsgAsync.tsId);
     131              :         }
     132            0 :         return;
     133              :     }
     134              : }
     135              : 
     136           17 : int32_t AicpuMsgSend::SendAICPUSubEvent(const char_t * const msg, const uint32_t msgLen,
     137              :                                         const uint32_t subEventId, const uint32_t grpId,
     138              :                                         const bool syncSendFlag)
     139              : {
     140           17 :     aicpusd_info("Begin to send aicpu subevent, syncflag is %d", static_cast<int32_t>(syncSendFlag));
     141           17 :     if (msg == nullptr) {
     142            1 :         aicpusd_err("The message is null.");
     143            1 :         return AICPU_SCHEDULE_ERROR_INVAILD_EVENT_SUBMIT;
     144              :     }
     145              : 
     146           16 :     if (msgLen == 0U) {
     147            1 :         aicpusd_err("The size of message is zero.");
     148            1 :         return AICPU_SCHEDULE_ERROR_INVAILD_EVENT_SUBMIT;
     149              :     }
     150           15 :     event_summary eventInfoSummary = {};
     151           15 :     eventInfoSummary.pid = getpid();
     152           15 :     eventInfoSummary.event_id = EVENT_AICPU_MSG;
     153           15 :     eventInfoSummary.subevent_id = subEventId;
     154           15 :     std::string msgStr(msg, static_cast<size_t>(msgLen));
     155           15 :     eventInfoSummary.msg = &msgStr[0];
     156           15 :     eventInfoSummary.msg_len = msgLen;
     157           15 :     eventInfoSummary.grp_id = grpId;
     158           15 :     DeployContext deployCtx = DeployContext::DEVICE;
     159           15 :     (void)GetAicpuDeployContext(deployCtx);
     160           15 :     if ((deployCtx == DeployContext::HOST) ||
     161              :         (subEventId == static_cast<uint32_t>(AICPU_SUB_EVENT_ACTIVE_MODEL))) {
     162            2 :         eventInfoSummary.dst_engine = static_cast<uint32_t>(CCPU_LOCAL);
     163            2 :         aicpusd_info("SendAICPUSubEvent to dst engine: %u", eventInfoSummary.dst_engine);
     164              :     }
     165              : 
     166           15 :     if (syncSendFlag) {
     167            9 :         const drvError_t ret = halEschedSubmitEvent(AicpuDrvManager::GetInstance().GetDeviceId(),
     168              :                                                     &eventInfoSummary);
     169            9 :         if (ret != DRV_ERROR_NONE) {
     170            0 :             aicpusd_err("Failed to submit aicpu event. ret is %d.", ret);
     171            0 :             return AICPU_SCHEDULE_ERROR_DRV_ERR;
     172              :         }
     173            9 :         return AICPU_SCHEDULE_OK;
     174              :     }
     175              : 
     176            6 :     AicpuMsgSend::SetSchedSubmitEvent(AicpuDrvManager::GetInstance().GetDeviceId(), eventInfoSummary);
     177            6 :     return AICPU_SCHEDULE_OK;
     178           15 : }
     179              : 
     180           22 : void AicpuMsgSend::CheckAndSendEvent()
     181              : {
     182           22 :     if (g_sendType != AICPUSendType::NO_NEED_SEND) {
     183           12 :         SendEvent();
     184              :     }
     185           22 : }
     186              : 
     187            2 : void AicpuMsgSend::AicpuReportNotifyInfo(const aicpu::AsyncNotifyInfo &notifyInfo)
     188              : {
     189            2 :     aicpusd_err("Send aicpu notify info to ts, streamId=%u, taskId=%lu, retcode=%u.",
     190              :                 notifyInfo.streamId, notifyInfo.taskId, notifyInfo.retCode);
     191              :     
     192            2 :     AicpuSqeAdapter aicpuSqeAdapter(FeatureCtrl::GetTsMsgVersion());
     193            2 :     AicpuSqeAdapter::AicpuRecordInfo recordInfo(notifyInfo.waitId, notifyInfo.waitType, notifyInfo.retCode,
     194            2 :                                                 static_cast<uint8_t>(notifyInfo.ctx.tsId), notifyInfo.taskId,
     195            2 :                                                 notifyInfo.streamId, notifyInfo.ctx.deviceId);
     196            2 :     const int32_t ret =  aicpuSqeAdapter.AicpuRecordResponseToTs(recordInfo);
     197            2 :     if (ret != AICPU_SCHEDULE_OK) {
     198            1 :         aicpusd_err("AicpuRecordResponseToTs failed. ret=%d, streamId=%u, taskId=%lu.",
     199              :                     ret, notifyInfo.streamId, notifyInfo.taskId);
     200              :     }
     201            2 : }
     202              : 
     203            5 : void AicpuMsgSend::SendAicpuRecordMsg(const void *const notifyParam, const uint32_t paramLen)
     204              : {
     205            5 :     if ((notifyParam == nullptr) || (paramLen != sizeof(aicpu::AsyncNotifyInfo))) {
     206            1 :         aicpusd_err("NotifyEventWait param is null or paramLen not matched. paramLen = %u, AsyncNotifyInfo size = %zu",
     207              :             paramLen, sizeof(aicpu::AsyncNotifyInfo));
     208            2 :         return;
     209              :     }
     210            4 :     const aicpu::AsyncNotifyInfo *const notifyInfo = reinterpret_cast<const aicpu::AsyncNotifyInfo *>(notifyParam);
     211            4 :     if ((notifyInfo->retCode != 0U) && (notifyInfo->retCode != AICPU_KERNEL_END_OF_SEQUENCE_FLAG)) {
     212            3 :         aicpusd_err("Aicpu recevied error code, wait_type[%u], wait_id[%u], task_id[%lu], stream_id[%u], ret_code[%u].",
     213              :                     notifyInfo->waitType, notifyInfo->waitId, notifyInfo->taskId, notifyInfo->streamId,
     214              :                     notifyInfo->retCode);
     215              :     } else {
     216            1 :         aicpusd_info("NotifyEventWait, wait_type[%u], wait_id[%u], task_id[%lu], stream_id[%u], ret_code[%u].",
     217              :                      notifyInfo->waitType, notifyInfo->waitId, notifyInfo->taskId, notifyInfo->streamId,
     218              :                      notifyInfo->retCode);
     219              :     }
     220              : 
     221              :     // create param.
     222            4 :     int32_t sendRet = 0;
     223            4 :     int32_t retCode = 0;
     224            4 :     bool retSucc = notifyInfo->retCode == 0U;
     225            4 :     bool isRetEndSequence = (notifyInfo->retCode == AICPU_KERNEL_END_OF_SEQUENCE_FLAG);
     226            4 :     retCode = retSucc ? (notifyInfo->retCode) : (isRetEndSequence
     227              :                                                 ? static_cast<uint16_t>(TS_ERROR_END_OF_SEQUENCE)
     228              :                                                 : static_cast<uint16_t>(TS_ERROR_AICPU_EXCEPTION));
     229            4 :     AicpuSqeAdapter aicpuSqeAdapter(FeatureCtrl::GetTsMsgVersion());
     230            4 :     AicpuSqeAdapter::AicpuRecordInfo recordInfo(notifyInfo->waitId, notifyInfo->waitType, retCode,
     231            4 :                                                 static_cast<uint8_t>(notifyInfo->ctx.tsId), notifyInfo->taskId,
     232            4 :                                                 notifyInfo->streamId, notifyInfo->ctx.deviceId);
     233            4 :     sendRet = aicpuSqeAdapter.AicpuRecordResponseToTs(recordInfo);
     234            4 :     if (sendRet != static_cast<uint32_t>(AICPU_SCHEDULE_OK)) {
     235            1 :         aicpusd_err("Send event notify to ts failed, sendRet=%d, notifyId=%u, retVal=%d.", sendRet, notifyInfo->waitId,
     236              :             notifyInfo->retCode);
     237            1 :         return;
     238              :     }
     239            3 :     aicpusd_info("send event notify to ts success, notifyId=%u, hostpid=%u, retCode=%d.", notifyInfo->waitId,
     240              :                  AicpuDrvManager::GetInstance().GetHostPid(), notifyInfo->retCode);
     241            4 : }
     242              : }
        

Generated by: LCOV version 2.0-1