1 /*
2  * Copyright (c) 2023 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 #ifndef NEURAL_NETWORK_RUNTIME_NNEXECUTOR_H
17 #define NEURAL_NETWORK_RUNTIME_NNEXECUTOR_H
18 
19 #include "executor.h"
20 #include "device.h"
21 #include "prepared_model.h"
22 #include "nn_tensor.h"
23 
24 namespace OHOS {
25 namespace NeuralNetworkRuntime {
26 class NNExecutor : public Executor {
27 public:
28     NNExecutor(size_t backendID,
29                std::shared_ptr<Device> device,
30                std::shared_ptr<PreparedModel> preparedModel,
31                const std::vector<std::pair<std::shared_ptr<TensorDesc>, OH_NN_TensorType>>& inputTensorDescs,
32                const std::vector<std::pair<std::shared_ptr<TensorDesc>, OH_NN_TensorType>>& outputTensorDescs);
33     ~NNExecutor() override;
34 
35     OH_NN_ReturnCode GetInputDimRange(size_t inputIndex,
36                                       size_t** minInputDims,
37                                       size_t** maxInputDims,
38                                       size_t* shapeNum) const override;
39     OH_NN_ReturnCode GetOutputShape(uint32_t outputIndex, int32_t** shape, uint32_t* shapeNum) const override;
40 
41     size_t GetInputNum() const override;
42     size_t GetOutputNum() const override;
43     NN_TensorDesc* CreateInputTensorDesc(size_t index) const override;
44     NN_TensorDesc* CreateOutputTensorDesc(size_t index) const override;
45 
46     OH_NN_ReturnCode SetOnRunDone(NN_OnRunDone onRunDone) override;
47     OH_NN_ReturnCode SetOnServiceDied(NN_OnServiceDied onServiceDied) override;
48     OH_NN_ReturnCode RunSync(NN_Tensor* inputTensors[],
49                              size_t inputSize,
50                              NN_Tensor* outputTensors[],
51                              size_t outputSize) override;
52     OH_NN_ReturnCode RunAsync(NN_Tensor* inputTensors[],
53                               size_t inputSize,
54                               NN_Tensor* outputTensors[],
55                               size_t outputSize,
56                               int32_t timeout,
57                               void* userData) override;
58     OH_NN_ReturnCode GetModelID(uint32_t& modelId) const override;
59     size_t GetBackendID() override;
60     OH_NN_ReturnCode SetExtensionConfig(const std::unordered_map<std::string, std::vector<char>>& configs) override;
61     ExecutorConfig* GetExecutorConfig() const override;
62 
63     // The following APIs are compatible with older versions
64     OH_NN_ReturnCode SetInput(uint32_t index, const OH_NN_Tensor& nnTensor, const void* buffer, size_t length);
65     OH_NN_ReturnCode SetInputFromMemory(uint32_t index, const OH_NN_Tensor& nnTensor, const OH_NN_Memory& memory);
66     OH_NN_ReturnCode SetOutput(uint32_t index, void* buffer, size_t length);
67     OH_NN_ReturnCode SetOutputFromMemory(uint32_t index, const OH_NN_Memory& memory);
68 
69     OH_NN_ReturnCode CreateInputMemory(uint32_t index, size_t length, OH_NN_Memory** memory);
70     OH_NN_ReturnCode CreateOutputMemory(uint32_t index, size_t length, OH_NN_Memory** memory);
71     OH_NN_ReturnCode DestroyInputMemory(uint32_t index, OH_NN_Memory** memory);
72     OH_NN_ReturnCode DestroyOutputMemory(uint32_t index, OH_NN_Memory** memory);
73 
74     OH_NN_ReturnCode Run();
75 
76 private:
77     OH_NN_ReturnCode GetInputDimVec() const;
78     OH_NN_ReturnCode CheckInputDimRanges(NN_Tensor* inputTensors[], size_t inputSize);
79 
80     // The following APIs are compatible with older versions
81     OH_NN_ReturnCode Run(const std::vector<std::shared_ptr<NNTensor>>& inputTensors,
82                          std::vector<std::shared_ptr<NNTensor>>& outputTensors);
83     bool CompareAttribute(
84         const std::pair<std::shared_ptr<TensorDesc>, OH_NN_TensorType>& tensorDesc, const NNTensor& tensor) const;
85     std::shared_ptr<NNTensor> BuildNNTensorFromDesc(
86         const std::pair<std::shared_ptr<TensorDesc>, OH_NN_TensorType>& tensorDesc);
87     OH_NN_ReturnCode BuildInputTensor(uint32_t index, const OH_NN_Tensor& nnTensor,
88                                       std::shared_ptr<NNTensor> inputTensor) const;
89     OH_NN_ReturnCode SetInputTensorWithCurrentBuffer(uint32_t index, std::shared_ptr<NNTensor> inputTensor,
90                                                      const void* buffer, size_t dataLength, size_t curBufferLength);
91     void SetInputTensorWithNewBuffer(uint32_t index, std::shared_ptr<NNTensor> inputTensor,
92                                      const void* inputBuffer, size_t length, bool isInnerMem);
93     OH_NN_ReturnCode CheckInputDimRanges(uint32_t index, const OH_NN_Tensor& nnTensor) const;
94 
95 private:
96     size_t m_backendID {0};
97     std::shared_ptr<Device> m_device {nullptr};
98     std::shared_ptr<PreparedModel> m_preparedModel {nullptr};
99     std::vector<std::pair<std::shared_ptr<TensorDesc>, OH_NN_TensorType>> m_inputTensorDescs;
100     std::vector<std::pair<std::shared_ptr<TensorDesc>, OH_NN_TensorType>> m_outputTensorDescs;
101 
102     // The following parameters are provided for compatibility with older versions
103     struct ExeTensor {
104         std::shared_ptr<NNTensor> tensor {nullptr};
105         void* userBuffer {nullptr};
106         size_t userBufferLength {0};
107         bool isInnerMem {false};
108     };
109     bool m_isRun {false};
110     ExecutorConfig* m_executorConfig {nullptr};
111     std::unordered_map<int, ExeTensor> m_inputTensors;
112     std::unordered_map<int, ExeTensor> m_outputTensors;
113     std::unordered_map<int, std::vector<void*>> m_inputCreatedMem;
114     std::unordered_map<int, std::vector<void*>> m_outputCreatedMem;
115     mutable std::vector<std::vector<size_t>> m_minInputDimsVec;
116     mutable std::vector<std::vector<size_t>> m_maxInputDimsVec;
117 };
118 }  // namespace NeuralNetworkRuntime
119 }  // namespace OHOS
120 #endif  // NEURAL_NETWORK_RUNTIME_NNEXECUTOR_H
121