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 "operator_kernel_enqueue_base.h"
12 :
13 : #include "aicpusd_profiler.h"
14 : #include "aicpusd_drv_manager.h"
15 : #include "aicpusd_model_execute.h"
16 : #include "aicpusd_resource_manager.h"
17 : #include "operator_kernel_common.h"
18 :
19 :
20 : namespace AicpuSchedule {
21 19 : int32_t OperatorKernelEnqueueBase::EnqueueTask(BufEnQueueInfo &bufInfo, const RunContext &taskContext) const
22 : {
23 19 : const auto model = AicpuModelManager::GetInstance().GetModel(taskContext.modelId);
24 19 : if ((model != nullptr) && (model->GetModelRetCode() != 0) && (!model->AbnormalNeedEnqueue())) {
25 1 : aicpusd_info("Model execution was not successful, no need to enqueue. modelId=%u, modelRetCode=%d.",
26 : taskContext.modelId, model->GetModelRetCode());
27 1 : return AICPU_SCHEDULE_OK;
28 : }
29 :
30 18 : auto mBufPptr = reinterpret_cast<Mbuf **>(static_cast<uintptr_t>(bufInfo.mBufPtr));
31 18 : if (mBufPptr == nullptr) {
32 1 : aicpusd_err("param mBufPptr is null.");
33 1 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
34 : }
35 17 : if (*mBufPptr == nullptr) {
36 0 : aicpusd_err("param *mBufPptr is null.");
37 0 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
38 : }
39 17 : uint32_t headSize = 0U;
40 17 : void *headBuf = nullptr;
41 17 : const auto ret = halMbufGetPrivInfo(*mBufPptr, &headBuf, &headSize);
42 17 : if (ret != DRV_ERROR_NONE) {
43 1 : aicpusd_err("Failed to get head info in input information, ret[%d].", ret);
44 1 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
45 : }
46 16 : SetMbufRetCode(taskContext.modelId, headBuf, headSize);
47 16 : SetMbufEndOfSequence(taskContext.modelId, headBuf, headSize);
48 16 : SetMbufNullData(taskContext.modelId, headBuf, headSize);
49 :
50 16 : g_aicpuProfiler.SetMbufHead(headBuf);
51 16 : const uint32_t queueId = bufInfo.queueID;
52 16 : const uint32_t streamId = taskContext.streamId;
53 16 : const auto deviceId = AicpuDrvManager::GetInstance().GetDeviceId();
54 : // clear unused eventState
55 16 : EventWaitManager::QueueNotFullWaitManager().ResetEventState(static_cast<size_t>(queueId));
56 16 : g_aicpuProfiler.SetQueueId(queueId);
57 16 : auto backupMsg = OperatorKernelCommon::BackupHeadMsg(headBuf, headSize, "Enqueued");
58 : do {
59 16 : const auto drvRet = halQueueEnQueue(deviceId, queueId, *mBufPptr);
60 16 : if (drvRet == DRV_ERROR_NONE) {
61 12 : AicpuModel * const modelPtr = AicpuModelManager::GetInstance().GetModel(taskContext.modelId);
62 12 : if (modelPtr == nullptr) {
63 0 : aicpusd_err("cannot get aicpuModel by modelId:[%u]!", taskContext.modelId);
64 0 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
65 : }
66 12 : const auto guardRet = modelPtr->UnGardModelBuf(*mBufPptr);
67 12 : if (guardRet != AICPU_SCHEDULE_OK) {
68 0 : aicpusd_warn("BufManager unguard enqueued failed, modelId[%u], drvRet[%d].", taskContext.modelId,
69 : guardRet);
70 : }
71 12 : break;
72 4 : } else if (drvRet == DRV_ERROR_QUEUE_FULL) {
73 2 : aicpusd_run_info("Enqueue full on queueId[%u], drvRet[%d].", queueId, drvRet);
74 2 : bool needWait = false;
75 : // if exist NotFullEvent, needWait return true and not record wait stream
76 2 : EventWaitManager::QueueNotFullWaitManager().WaitEvent(static_cast<size_t>(queueId), streamId, needWait);
77 2 : if (needWait) {
78 2 : aicpusd_run_info("ModelEnqueueTaskKernel pending, queueId:%u, streamId:%u.", queueId, streamId);
79 2 : bool *pending = const_cast<bool *>(&taskContext.pending);
80 2 : *pending = true;
81 2 : return AICPU_SCHEDULE_OK;
82 : }
83 : } else {
84 2 : aicpusd_err("Failed to enqueue on queueId[%u], drvRet[%d].", queueId, drvRet);
85 2 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
86 : }
87 0 : } while (true);
88 12 : OperatorKernelCommon::DoTraceQueueData(taskContext, backupMsg.get(), "Enqueued");
89 12 : return AICPU_SCHEDULE_OK;
90 16 : }
91 :
92 18 : void OperatorKernelEnqueueBase::SetMbufRetCode(const uint32_t modelId, void * const headBuf,
93 : const uint32_t headSize) const
94 : {
95 18 : if ((headBuf != nullptr) && (static_cast<size_t>(headSize) >= sizeof(MbufHeadMsg))) {
96 6 : int32_t retCode = 0;
97 6 : const auto model = AicpuModelManager::GetInstance().GetModel(modelId);
98 6 : if (model != nullptr) {
99 6 : retCode = model->GetModelRetCode();
100 6 : if (!model->AbnormalEnabled() || (retCode == 0)) {
101 6 : return;
102 : }
103 : }
104 0 : MbufHeadMsg * const msg = PtrToPtr<uint8_t, MbufHeadMsg>(PtrAdd<uint8_t>(PtrToPtr<void, uint8_t>(headBuf),
105 0 : MBUF_HEAD_MAX_SIZE, static_cast<size_t>(headSize) - sizeof(MbufHeadMsg)));
106 0 : msg->retCode = retCode;
107 : }
108 : }
109 :
110 18 : void OperatorKernelEnqueueBase::SetMbufEndOfSequence(const uint32_t modelId, void * const headBuf,
111 : const uint32_t headSize) const
112 : {
113 18 : if ((headBuf != nullptr) && (headSize > MBUF_HEAD_END_OF_SEQUENCE_POS)) {
114 3 : const auto model = AicpuModelManager::GetInstance().GetModel(modelId);
115 3 : if ((model != nullptr) && (model->IsEndOfSequence())) {
116 1 : uint8_t * const ret = PtrAdd<uint8_t>(PtrToPtr<void, uint8_t>(headBuf), MBUF_HEAD_MAX_SIZE,
117 : static_cast<size_t>(MBUF_HEAD_END_OF_SEQUENCE_POS));
118 1 : *ret = END_OF_SEQUENCE_FLAG;
119 : }
120 : }
121 18 : }
122 :
123 17 : void OperatorKernelEnqueueBase::SetMbufNullData(const uint32_t modelId, void * const headBuf,
124 : const uint32_t headSize) const
125 : {
126 17 : if ((headBuf != nullptr) && (static_cast<size_t>(headSize) >= sizeof(MbufHeadMsg))) {
127 7 : const auto model = AicpuModelManager::GetInstance().GetModel(modelId);
128 7 : if ((model != nullptr) && model->GetNullDataFlag()) {
129 1 : MbufHeadMsg * const msg = PtrToPtr<uint8_t, MbufHeadMsg>(PtrAdd<uint8_t>(PtrToPtr<void, uint8_t>(headBuf),
130 1 : MBUF_HEAD_MAX_SIZE, static_cast<size_t>(headSize) - sizeof(MbufHeadMsg)));
131 1 : msg->dataFlag |= MBUF_HEAD_DATA_FLAG_MASK;
132 : }
133 : }
134 17 : }
135 : } // namespace AicpuSchedule
|