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 ¬ifyInfo)
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 : }
|