1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "execution_plan.h"
17
18 #include <vector>
19
20 #include "common/log.h"
21 #include "cpp_type.h"
22
23
24 namespace OHOS {
25 namespace NeuralNetworkRuntime {
Run(const std::vector<std::shared_ptr<NNTensor>> & inputTensors,std::vector<std::shared_ptr<NNTensor>> & outputTensors)26 OH_NN_ReturnCode ExecutionPlan::Run(const std::vector<std::shared_ptr<NNTensor>>& inputTensors,
27 std::vector<std::shared_ptr<NNTensor>>& outputTensors)
28 {
29 OH_NN_ReturnCode ret {OH_NN_FAILED};
30 IOTensor tensor;
31 std::vector<IOTensor> inputIOTensors;
32 size_t inputSize = inputTensors.size();
33 size_t outputSize = outputTensors.size();
34 for (size_t i = 0; i < inputSize; ++i) {
35 inputTensors[i]->ConvertToIOTensor(tensor);
36 inputIOTensors.emplace_back(std::move(tensor));
37 }
38
39 std::vector<IOTensor> outputIOTensors;
40 for (size_t i = 0; i < outputSize; ++i) {
41 outputTensors[i]->ConvertToIOTensor(tensor);
42 outputIOTensors.emplace_back(std::move(tensor));
43 }
44
45 std::vector<std::vector<int32_t>> outputsDims;
46 std::vector<bool> isSufficientDataBuffer;
47 ret = m_preparedModel->Run(inputIOTensors, outputIOTensors, outputsDims, isSufficientDataBuffer);
48 if (ret != OH_NN_SUCCESS) {
49 LOGE("PrepardModel Run() failed.");
50 return ret;
51 }
52
53 // Check if the output buffer is sufficient
54 bool bufferFailed {false};
55 for (size_t i = 0; i < outputSize; ++i) {
56 if (!isSufficientDataBuffer[i]) {
57 // Print all output indices with insufficient buffer, don't return until traversing all outputs.
58 LOGE("Run failed, Output %zu does not have enough buffer to store the data.", i);
59 bufferFailed = true;
60 }
61 }
62 if (bufferFailed) {
63 return OH_NN_FAILED;
64 }
65
66 // Set the output NNTensor's dimensions from output IOTensor if it is dynamic.
67 // NNTensor::SetDimensions will check if the tensor buffer is enough for the new dimensions.
68 for (size_t i = 0; i < outputSize; ++i) {
69 ret = outputTensors[i]->SetDimensions(outputsDims[i]);
70 if (ret != OH_NN_SUCCESS) {
71 LOGE("Run failed, error happened when setting output tensor's dimensions, output id: %zu.", i);
72 return ret;
73 }
74 }
75
76 return OH_NN_SUCCESS;
77 }
78
79
GetInputDevice() const80 std::shared_ptr<Device> ExecutionPlan::GetInputDevice() const
81 {
82 return m_device;
83 }
84
85
GetOutputDevice() const86 std::shared_ptr<Device> ExecutionPlan::GetOutputDevice() const
87 {
88 return m_device;
89 }
90 } // NeuralNetworkRuntime
91 } // OHOS