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_check_input_tensor_desc.h"
12 :
13 : #include "aicpusd_status.h"
14 : #include "aicpusd_model_execute.h"
15 : #include "aicpusd_model_statistic.h"
16 : #include "operator_kernel_common.h"
17 :
18 : namespace AicpuSchedule {
19 : namespace {
20 : const std::string KERNEL_CHECK_INPUT_TENSOR_DESC = "checkInputTensorDesc";
21 : } // namespace
22 :
23 7 : int32_t OperatorKernelCheckInputTensorDesc::Compute(const AicpuTaskInfo& kernelTaskInfo, const RunContext& taskContext)
24 : {
25 : // check whether the data is empty.
26 7 : const auto model = AicpuModelManager::GetInstance().GetModel(taskContext.modelId);
27 7 : if ((model != nullptr) && (model->GetNullDataFlag())) {
28 1 : aicpusd_info("null data, no need check static shape");
29 1 : return AICPU_SCHEDULE_OK;
30 : }
31 6 : ShapeValidationInfo* allTensorDesc = PtrToPtr<void, ShapeValidationInfo>(ValueToPtr(kernelTaskInfo.paraBase));
32 6 : if (allTensorDesc == nullptr) {
33 1 : aicpusd_err(
34 : "Model check input tensor para is nullptr, modelId[%u], streamId[%u], taskId[%u]", taskContext.modelId,
35 : taskContext.streamId, kernelTaskInfo.taskID);
36 1 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
37 : }
38 5 : aicpusd_info(
39 : "tensor nums[%u], modelId[%u], streamId[%u], taskId[%u]", allTensorDesc->inputNums, taskContext.modelId,
40 : taskContext.streamId, kernelTaskInfo.taskID);
41 :
42 5 : const uint64_t tensorDescNums = allTensorDesc->inputNums;
43 5 : std::vector<ModelConfigTensorDesc> tensorDescArr;
44 5 : const int32_t result = AicpuModelManager::GetInstance().GetModelConfigShape(taskContext.modelId, tensorDescArr);
45 5 : if ((result != AICPU_SCHEDULE_OK) || tensorDescArr.empty()) {
46 : // check aicpu model has tensor info
47 1 : aicpusd_warn("aicpumodel task has not tensordesc, no need check");
48 1 : return AICPU_SCHEDULE_OK;
49 : }
50 :
51 : // check tensor desc nums
52 4 : if (tensorDescArr.size() != tensorDescNums) {
53 1 : aicpusd_err(
54 : "tensorDesc number is not as expected. the expected number is[%zu], but is[%u]", tensorDescArr.size(),
55 : tensorDescNums);
56 1 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
57 : }
58 3 : std::vector<uint64_t> inputSizeList;
59 4 : for (uint64_t i = 0UL; i < tensorDescNums; i++) {
60 3 : uint64_t curSize = 0UL;
61 3 : const int32_t ret = CheckInputTensorDesc(allTensorDesc->shapeValidationAddr, i, tensorDescArr[i], curSize);
62 3 : if (ret != AICPU_SCHEDULE_OK) {
63 2 : aicpusd_err(
64 : "check static shape failed, modelId[%u], streamId[%u], taskId[%u], i = %llu, tensorDescNums = %llu",
65 : taskContext.modelId, taskContext.streamId, kernelTaskInfo.taskID, i, tensorDescNums);
66 2 : return ret;
67 : }
68 1 : inputSizeList.emplace_back(curSize);
69 : }
70 1 : AicpuSdModelStatistic::GetInstance().StatNNModelInput(taskContext.modelId, inputSizeList, tensorDescArr);
71 1 : aicpusd_info("check static shape success");
72 1 : return AICPU_SCHEDULE_OK;
73 5 : }
74 :
75 9 : int32_t OperatorKernelCheckInputTensorDesc::CheckInputTensorDesc(
76 : const uint64_t shapeValidationAddr, const uint64_t index, const ModelConfigTensorDesc& modelTensorDesc,
77 : uint64_t& curSize) const
78 : {
79 : ShapeValidation* const shapeInfo =
80 9 : PtrToPtr<void, ShapeValidation>(ValueToPtr(shapeValidationAddr + sizeof(ShapeValidation) * index));
81 9 : if (shapeInfo == nullptr) {
82 1 : aicpusd_err("input shape info is nullptr");
83 1 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
84 : }
85 8 : aicpusd_info("shapeInfo offset = %u", shapeInfo->offset);
86 8 : const auto msgTypeCheckRet = CheckMsgType(PtrToPtr<void, Mbuf*>(ValueToPtr(shapeInfo->mbufAddrs)));
87 8 : if (msgTypeCheckRet != AICPU_SCHEDULE_OK) {
88 2 : return msgTypeCheckRet;
89 : }
90 :
91 6 : uint64_t dataSize = 0UL;
92 6 : int32_t ret = OperatorKernelCommon::GetMbufDataSize(shapeInfo->mbufAddrs, dataSize);
93 6 : if (ret != AICPU_SCHEDULE_OK) {
94 0 : aicpusd_err("Failed to get mbuf data size, ret = %d.", ret);
95 0 : return ret;
96 : }
97 :
98 6 : void* dataPtr = nullptr;
99 6 : ret = OperatorKernelCommon::GetMbufDataPtr(shapeInfo->mbufAddrs, &dataPtr);
100 6 : if (ret != AICPU_SCHEDULE_OK) {
101 1 : aicpusd_err("Failed to get mbuf data addr. srcAddr is [%lu].", shapeInfo->mbufAddrs);
102 1 : return ret;
103 : }
104 :
105 5 : if (shapeInfo->offset > 0) {
106 3 : uint64_t totalOffset = 0UL;
107 6 : ret = OperatorKernelCommon::UpdateDataPtr(
108 3 : shapeInfo->mbufAddrs, static_cast<int32_t>(shapeInfo->offset), dataPtr, totalOffset);
109 3 : if (ret != AICPU_SCHEDULE_OK) {
110 1 : aicpusd_err(
111 : "Failed to update data addr. fusion offset[%llu], totalOffset[%llu]", shapeInfo->offset, totalOffset);
112 1 : return ret;
113 : }
114 : }
115 :
116 4 : RuntimeTensorDesc* const tensorDesc = PtrToPtr<void, RuntimeTensorDesc>(dataPtr);
117 4 : if (tensorDesc == nullptr) {
118 1 : aicpusd_err("tensorDesc is nullptr");
119 1 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
120 : }
121 3 : aicpusd_info(
122 : "index[%llu], dtype[%u], shape[0] = %u, datasize:%llu", index, tensorDesc->dtype, tensorDesc->shape[0],
123 : tensorDesc->dataSize);
124 3 : ret = CheckShapeInfo(modelTensorDesc, *tensorDesc);
125 3 : if (ret != AICPU_SCHEDULE_OK) {
126 2 : aicpusd_err("check tensor info failed, tensor index = %llu", index);
127 2 : return ret;
128 : }
129 1 : curSize = tensorDesc->dataSize;
130 1 : return AICPU_SCHEDULE_OK;
131 : }
132 :
133 5 : int32_t OperatorKernelCheckInputTensorDesc::CheckMsgType(Mbuf** const mbufPtr) const
134 : {
135 5 : if ((mbufPtr == nullptr) || (*mbufPtr == nullptr)) {
136 1 : aicpusd_err("Invalid mbuf.");
137 1 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
138 : }
139 4 : uint32_t headSize = 0U;
140 4 : void* headBuf = nullptr;
141 4 : const auto drvRet = halMbufGetPrivInfo(*mbufPtr, &headBuf, &headSize);
142 4 : if ((drvRet != static_cast<int32_t>(DRV_ERROR_NONE)) || (headBuf == nullptr) ||
143 4 : (static_cast<size_t>(headSize) < sizeof(MbufHeadMsg))) {
144 0 : aicpusd_err("Failed to get mbuf head, ret[%d], headSize[%u].", drvRet, headSize);
145 0 : return AICPU_SCHEDULE_ERROR_FROM_DRV;
146 : }
147 :
148 4 : const MbufHeadMsg* const msg = PtrToPtr<uint8_t, MbufHeadMsg>(PtrAdd<uint8_t>(
149 : PtrToPtr<void, uint8_t>(headBuf), static_cast<size_t>(headSize),
150 4 : static_cast<size_t>(headSize) - sizeof(MbufHeadMsg)));
151 4 : if ((msg->msgType == static_cast<uint16_t>(MsgType::MSG_TYPE_RAW_MSG)) ||
152 3 : (msg->msgType >= static_cast<uint16_t>(MsgType::MSG_TYPE_USER_DEFINE_START))) {
153 2 : aicpusd_err("Invalid msg_type[%d].", msg->msgType);
154 2 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
155 : }
156 :
157 2 : return AICPU_SCHEDULE_OK;
158 : }
159 :
160 4 : int32_t OperatorKernelCheckInputTensorDesc::CheckShapeInfo(
161 : const ModelConfigTensorDesc& modelTensorDesc, const RuntimeTensorDesc& tensorDesc) const
162 : {
163 4 : if (modelTensorDesc.dtype != tensorDesc.dtype) {
164 0 : aicpusd_err(
165 : "Failed to check modelTensorDesc dtype. modelTensorDesc.dtype[%lld], tensorDesc.dtype[%lld]",
166 : modelTensorDesc.dtype, tensorDesc.dtype);
167 0 : PrintErrShapeInfo(modelTensorDesc, tensorDesc);
168 0 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
169 : }
170 :
171 4 : if (modelTensorDesc.shape[0] > MAX_DIM_SIZE + 1) {
172 1 : aicpusd_err(
173 : "Failed to check modelTensorDesc shape. shape size[%d] should less than %d", modelTensorDesc.shape[0],
174 : MAX_DIM_SIZE + 1);
175 1 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
176 : }
177 6 : for (int64_t index = 0; index <= modelTensorDesc.shape[0]; index++) {
178 5 : if (modelTensorDesc.shape[index] != tensorDesc.shape[index]) {
179 2 : aicpusd_err(
180 : "Failed to check shape. expect shape[%lld] = [%lld], but is [%lld]", index,
181 : modelTensorDesc.shape[index], tensorDesc.shape[index]);
182 2 : PrintErrShapeInfo(modelTensorDesc, tensorDesc);
183 2 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
184 : }
185 : }
186 1 : return AICPU_SCHEDULE_OK;
187 : }
188 :
189 2 : void OperatorKernelCheckInputTensorDesc::PrintErrShapeInfo(
190 : const ModelConfigTensorDesc& modelTensorDesc, const RuntimeTensorDesc& tensorDesc) const
191 : {
192 2 : if ((modelTensorDesc.shape[0] > MAX_DIM_SIZE + 1) || (tensorDesc.shape[0] > MAX_DIM_SIZE + 1)) {
193 0 : aicpusd_err(
194 : "Failed to check modelTensorDesc shape. shape size[%d] should less than %d", modelTensorDesc.shape[0],
195 : MAX_DIM_SIZE + 1);
196 0 : return;
197 : }
198 2 : std::ostringstream oss;
199 2 : oss << "expect dtype = " << AicpuUtil::GetDTypeString(static_cast<ge::DataType>(modelTensorDesc.dtype));
200 2 : oss << ", actual dtype = " << AicpuUtil::GetDTypeString(static_cast<ge::DataType>(tensorDesc.dtype));
201 2 : oss << ", expect dims = " << modelTensorDesc.shape[0] << ", actual dims = " << tensorDesc.shape[0];
202 2 : oss << ", and expect shape = [ ";
203 2 : if (modelTensorDesc.shape[0] > 0) {
204 5 : for (int64_t index = 1; index <= modelTensorDesc.shape[0]; index++) {
205 3 : oss << modelTensorDesc.shape[index] << " ";
206 : }
207 : }
208 :
209 2 : oss << "], actual shape = [ ";
210 2 : if (tensorDesc.shape[0] > 0) {
211 8 : for (int64_t index = 1; index <= tensorDesc.shape[0]; index++) {
212 6 : oss << tensorDesc.shape[index] << " ";
213 : }
214 : }
215 2 : oss << "]";
216 2 : aicpusd_err("%s", oss.str().c_str());
217 2 : }
218 :
219 6 : REGISTER_OPERATOR_KERNEL(KERNEL_CHECK_INPUT_TENSOR_DESC, OperatorKernelCheckInputTensorDesc);
220 : } // namespace AicpuSchedule
|