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
|