• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 #include "interfaces/innerkits/c/neural_network_runtime_inner.h"
17 #include "interfaces/kits/c/neural_network_runtime/neural_network_runtime.h"
18 
19 #include "compilation.h"
20 #include "executor.h"
21 #include "inner_model.h"
22 #include "common/log.h"
23 #include "quant_param.h"
24 #include "validation.h"
25 
26 using namespace OHOS::NeuralNetworkRuntime;
27 
28 #define NNRT_API __attribute__((visibility("default")))
29 
OH_NNQuantParam_Create()30 NNRT_API NN_QuantParam *OH_NNQuantParam_Create()
31 {
32     auto* quantParamImpl = new (std::nothrow) QuantParams();
33     if (quantParamImpl == nullptr) {
34         LOGE("OH_NNQuantParam_Create failed, please check whether it has enough memory.");
35         return nullptr;
36     }
37 
38     return (NN_QuantParam*)(quantParamImpl);
39 }
40 
OH_NNQuantParam_SetScales(NN_QuantParam * quantParams,const double * scales,size_t quantNum)41 NNRT_API OH_NN_ReturnCode OH_NNQuantParam_SetScales(NN_QuantParam* quantParams, const double* scales, size_t quantNum)
42 {
43     if (quantParams == nullptr) {
44         LOGE("OH_NNQuantParam_SetScales failed, passed nullptr to quantParams.");
45         return OH_NN_INVALID_PARAMETER;
46     }
47 
48     if (scales == nullptr) {
49         LOGE("OH_NNQuantParam_SetScales failed, passed nullptr to scales.");
50         return OH_NN_INVALID_PARAMETER;
51     }
52 
53     if (quantNum == 0) {
54         LOGE("OH_NNQuantParam_SetScales failed, passed 0 to quantNum.");
55         return OH_NN_INVALID_PARAMETER;
56     }
57 
58     auto* quantParamImpl = reinterpret_cast<QuantParams*>(quantParams);
59     std::vector<double> scaleVector(scales, scales + quantNum);
60     quantParamImpl->SetScales(scaleVector);
61 
62     return OH_NN_SUCCESS;
63 }
64 
OH_NNQuantParam_SetZeroPoints(NN_QuantParam * quantParams,const int32_t * zeroPoints,size_t quantNum)65 NNRT_API OH_NN_ReturnCode OH_NNQuantParam_SetZeroPoints(NN_QuantParam* quantParams,
66                                                         const int32_t* zeroPoints,
67                                                         size_t quantNum)
68 {
69     if (quantParams == nullptr) {
70         LOGE("OH_NNQuantParam_SetZeroPoints failed, passed nullptr to quantParams.");
71         return OH_NN_INVALID_PARAMETER;
72     }
73 
74     if (zeroPoints == nullptr) {
75         LOGE("OH_NNQuantParam_SetZeroPoints failed, passed nullptr to zeroPoints.");
76         return OH_NN_INVALID_PARAMETER;
77     }
78 
79     if (quantNum == 0) {
80         LOGE("OH_NNQuantParam_SetZeroPoints failed, passed 0 to quantNum.");
81         return OH_NN_INVALID_PARAMETER;
82     }
83 
84     auto* quantParamImpl = reinterpret_cast<QuantParams*>(quantParams);
85     std::vector<int32_t> zeroPointVector(zeroPoints, zeroPoints + quantNum);
86     quantParamImpl->SetZeroPoints(zeroPointVector);
87 
88     return OH_NN_SUCCESS;
89 }
90 
OH_NNQuantParam_SetNumBits(NN_QuantParam * quantParams,const uint32_t * numBits,size_t quantNum)91 OH_NN_ReturnCode OH_NNQuantParam_SetNumBits(NN_QuantParam* quantParams, const uint32_t* numBits, size_t quantNum)
92 {
93     if (quantParams == nullptr) {
94         LOGE("OH_NNQuantParam_SetNumBits failed, passed nullptr to quantParams.");
95         return OH_NN_INVALID_PARAMETER;
96     }
97 
98     if (numBits == nullptr) {
99         LOGE("OH_NNQuantParam_SetNumBits failed, passed nullptr to numBits.");
100         return OH_NN_INVALID_PARAMETER;
101     }
102 
103     if (quantNum == 0) {
104         LOGE("OH_NNQuantParam_SetNumBits failed, passed 0 to quantNum.");
105         return OH_NN_INVALID_PARAMETER;
106     }
107 
108     auto* quantParamImpl = reinterpret_cast<QuantParams*>(quantParams);
109     std::vector<uint32_t> numBitVector(numBits, numBits + quantNum);
110     quantParamImpl->SetNumBits(numBitVector);
111 
112     return OH_NN_SUCCESS;
113 }
114 
OH_NNQuantParam_Destroy(NN_QuantParam ** quantParams)115 OH_NN_ReturnCode OH_NNQuantParam_Destroy(NN_QuantParam** quantParams)
116 {
117     if (quantParams == nullptr) {
118         LOGE("OH_NNQuantParam_Destroy failed, passed nullptr to quantParams.");
119         return OH_NN_INVALID_PARAMETER;
120     }
121 
122     if (*quantParams == nullptr) {
123         LOGW("OH_NNQuantParam_Destroy failed, passed nullptr to *quantParams.");
124         return OH_NN_INVALID_PARAMETER;
125     }
126 
127     auto* quantParamImpl = reinterpret_cast<QuantParams*>(*quantParams);
128     delete quantParamImpl;
129     *quantParams = nullptr;
130 
131     return OH_NN_SUCCESS;
132 }
133 
OH_NNModel_AddTensorToModel(OH_NNModel * model,const NN_TensorDesc * tensorDesc)134 OH_NN_ReturnCode OH_NNModel_AddTensorToModel(OH_NNModel* model, const NN_TensorDesc* tensorDesc)
135 {
136     if (model == nullptr) {
137         LOGE("OH_NNModel_AddTensorToModel failed, passed nullptr to model.");
138         return OH_NN_INVALID_PARAMETER;
139     }
140 
141     if (tensorDesc == nullptr) {
142         LOGE("OH_NNModel_AddTensorToModel failed, passed nullptr to tensorDesc.");
143         return OH_NN_INVALID_PARAMETER;
144     }
145 
146     auto* innerModel = reinterpret_cast<OHOS::NeuralNetworkRuntime::InnerModel*>(model);
147     OH_NN_ReturnCode returnCode = innerModel->AddTensorDesc(tensorDesc);
148     if (returnCode != OH_NN_SUCCESS) {
149         LOGE("OH_NNModel_AddTensorToModel failed, error happened when adding tensor to model.");
150     }
151 
152     return returnCode;
153 }
154 
OH_NNModel_SetTensorQuantParams(OH_NNModel * model,uint32_t index,NN_QuantParam * quantParam)155 OH_NN_ReturnCode OH_NNModel_SetTensorQuantParams(OH_NNModel* model, uint32_t index, NN_QuantParam* quantParam)
156 {
157     if (model == nullptr) {
158         LOGE("OH_NNModel_SetTensorQuantParams failed, passed nullptr to model.");
159         return OH_NN_INVALID_PARAMETER;
160     }
161 
162     if (quantParam == nullptr) {
163         LOGE("OH_NNModel_SetTensorQuantParams failed, passed nullptr to quantParam.");
164         return OH_NN_INVALID_PARAMETER;
165     }
166 
167     auto* innerModel = reinterpret_cast<OHOS::NeuralNetworkRuntime::InnerModel*>(model);
168     OH_NN_ReturnCode returnCode = innerModel->SetTensorQuantParam((uint32_t)(index), quantParam);
169     if (returnCode != OH_NN_SUCCESS) {
170         LOGE("OH_NNModel_SetTensorQuantParams failed, error happened when setting tensor quantParam.");
171     }
172 
173     return returnCode;
174 }
175 
OH_NNModel_SetTensorType(OH_NNModel * model,uint32_t index,OH_NN_TensorType tensorType)176 OH_NN_ReturnCode OH_NNModel_SetTensorType(OH_NNModel* model, uint32_t index, OH_NN_TensorType tensorType)
177 {
178     if (model == nullptr) {
179         LOGE("OH_NNModel_SetTensorType failed, passed nullptr to model.");
180         return OH_NN_INVALID_PARAMETER;
181     }
182 
183     if (!Validation::ValidateTensorType(tensorType)) {
184         LOGE("OH_NNModel_SetTensorType failed, invalid tensor type.");
185         return OH_NN_INVALID_PARAMETER;
186     }
187 
188     auto* innerModel = reinterpret_cast<OHOS::NeuralNetworkRuntime::InnerModel*>(model);
189     OH_NN_ReturnCode returnCode = innerModel->SetTensorType((uint32_t)(index), tensorType);
190     if (returnCode != OH_NN_SUCCESS) {
191         LOGE("OH_NNModel_SetTensorType failed, error happened when setting tensor type.");
192     }
193 
194     return returnCode;
195 }
196 
OH_NNModel_Construct(void)197 NNRT_API OH_NNModel *OH_NNModel_Construct(void)
198 {
199     InnerModel *innerModel = new(std::nothrow) InnerModel();
200     if (innerModel == nullptr) {
201         LOGE("OH_NNModel_Construct failed, please check whether it has enough memory.");
202         return nullptr;
203     }
204 
205     OH_NNModel *nnModel = reinterpret_cast<OH_NNModel*>(innerModel);
206     return nnModel;
207 }
208 
OH_NNModel_AddOperation(OH_NNModel * model,OH_NN_OperationType op,const OH_NN_UInt32Array * paramIndices,const OH_NN_UInt32Array * inputIndices,const OH_NN_UInt32Array * outputIndices)209 NNRT_API OH_NN_ReturnCode OH_NNModel_AddOperation(OH_NNModel *model,
210                                                   OH_NN_OperationType op,
211                                                   const OH_NN_UInt32Array *paramIndices,
212                                                   const OH_NN_UInt32Array *inputIndices,
213                                                   const OH_NN_UInt32Array *outputIndices)
214 {
215     if (model == nullptr) {
216         LOGE("OH_NNModel_AddOperation failed, passed nullptr to model.");
217         return OH_NN_INVALID_PARAMETER;
218     }
219 
220     if (paramIndices == nullptr) {
221         LOGE("OH_NNModel_AddOperation failed, passed nullptr to paramIndices.");
222         return OH_NN_INVALID_PARAMETER;
223     }
224 
225     if (inputIndices == nullptr) {
226         LOGE("OH_NNModel_AddOperation failed, passed nullptr to inputIndices.");
227         return OH_NN_INVALID_PARAMETER;
228     }
229 
230     if (outputIndices == nullptr) {
231         LOGE("OH_NNModel_AddOperation failed, passed nullptr to outputIndices.");
232         return OH_NN_INVALID_PARAMETER;
233     }
234 
235     InnerModel *innerModel = reinterpret_cast<InnerModel*>(model);
236     return innerModel->AddOperation(op, *paramIndices, *inputIndices, *outputIndices);
237 }
238 
OH_NNModel_SetTensorData(OH_NNModel * model,uint32_t index,const void * dataBuffer,size_t length)239 NNRT_API OH_NN_ReturnCode OH_NNModel_SetTensorData(OH_NNModel *model,
240                                                    uint32_t index,
241                                                    const void *dataBuffer,
242                                                    size_t length)
243 {
244     if (model == nullptr) {
245         LOGE("OH_NNModel_SetTensorData failed, passed nullptr to model.");
246         return OH_NN_INVALID_PARAMETER;
247     }
248 
249     if (dataBuffer == nullptr) {
250         LOGE("OH_NNModel_SetTensorData failed, passed nullptr to dataBuffer, which has no effect.");
251         return OH_NN_INVALID_PARAMETER;
252     }
253 
254     if (length == 0) {
255         LOGE("OH_NNModel_SetTensorData failed, passed dataBuffer with length 0, which has no effect.");
256         return OH_NN_INVALID_PARAMETER;
257     }
258 
259     InnerModel *innerModel = reinterpret_cast<InnerModel*>(model);
260     return innerModel->SetTensorValue(index, dataBuffer, length);
261 }
262 
OH_NNModel_SpecifyInputsAndOutputs(OH_NNModel * model,const OH_NN_UInt32Array * inputIndices,const OH_NN_UInt32Array * outputIndices)263 NNRT_API OH_NN_ReturnCode OH_NNModel_SpecifyInputsAndOutputs(OH_NNModel *model,
264                                                              const OH_NN_UInt32Array *inputIndices,
265                                                              const OH_NN_UInt32Array *outputIndices)
266 {
267     if (model == nullptr) {
268         LOGE("OH_NNModel_SpecifyInputsAndOutputs failed, passed nullptr to model.");
269         return OH_NN_INVALID_PARAMETER;
270     }
271 
272     if (inputIndices == nullptr) {
273         LOGE("OH_NNModel_SpecifyInputsAndOutputs failed, passed nullptr to inputIndices.");
274         return OH_NN_INVALID_PARAMETER;
275     }
276 
277     if (outputIndices == nullptr) {
278         LOGE("OH_NNModel_SpecifyInputsAndOutputs failed, passed nullptr to outputIndices.");
279         return OH_NN_INVALID_PARAMETER;
280     }
281 
282     InnerModel *innerModel = reinterpret_cast<InnerModel*>(model);
283     return innerModel->SpecifyInputsAndOutputs(*inputIndices, *outputIndices);
284 }
285 
OH_NNModel_Finish(OH_NNModel * model)286 NNRT_API OH_NN_ReturnCode OH_NNModel_Finish(OH_NNModel *model)
287 {
288     if (model == nullptr) {
289         LOGE("OH_NNModel_Finish failed, passed nullptr to model.");
290         return OH_NN_INVALID_PARAMETER;
291     }
292 
293     InnerModel *innerModel = reinterpret_cast<InnerModel*>(model);
294     return innerModel->Build();
295 }
296 
OH_NNModel_BuildFromLiteGraph(OH_NNModel * model,const void * liteGraph)297 NNRT_API OH_NN_ReturnCode OH_NNModel_BuildFromLiteGraph(OH_NNModel *model, const void *liteGraph)
298 {
299     if (model == nullptr) {
300         LOGE("OH_NNModel_BuildFromLiteGraph failed, passed nullptr to model.");
301         return OH_NN_INVALID_PARAMETER;
302     }
303 
304     if (liteGraph == nullptr) {
305         LOGE("OH_NNModel_BuildFromLiteGraph failed, passed nullptr to liteGraph.");
306         return OH_NN_INVALID_PARAMETER;
307     }
308 
309     auto *pLiteGraph = static_cast<const mindspore::lite::LiteGraph*>(liteGraph);
310     InnerModel *innerModel = reinterpret_cast<InnerModel*>(model);
311 
312     // Once the innerModel built from the liteGraph successfully, the innerModel
313     // owns the liteGraph, in which case, the invoker should not delete
314     // the liteGraph actively. Otherwise, the invoker still has the ownership.
315     return innerModel->BuildFromLiteGraph(pLiteGraph);
316 }
317 
OH_NNModel_BuildFromMetaGraph(OH_NNModel * model,const void * metaGraph,const OH_NN_Extension * extensions,size_t extensionSize)318 NNRT_API OH_NN_ReturnCode OH_NNModel_BuildFromMetaGraph(OH_NNModel *model, const void *metaGraph,
319     const OH_NN_Extension *extensions, size_t extensionSize)
320 {
321     if (model == nullptr) {
322         LOGE("OH_NNModel_BuildFromMetaGraph failed, passed nullptr to model.");
323         return OH_NN_INVALID_PARAMETER;
324     }
325 
326     if (metaGraph == nullptr) {
327         LOGE("OH_NNModel_BuildFromMetaGraph failed, passed nullptr to metaGraph.");
328         return OH_NN_INVALID_PARAMETER;
329     }
330 
331     Buffer buffer;
332     std::string modelName;
333     for (size_t i = 0; i < extensionSize; ++i) {
334         std::string name = extensions[i].name;
335         if (name == "QuantBuffer") {
336             buffer.data = extensions[i].value;
337             buffer.length = extensions[i].valueSize;
338         } else if (name == "ModelName") {
339             modelName.assign(extensions[i].value, extensions[i].value + extensions[i].valueSize);
340         }
341     }
342 
343     InnerModel *innerModel = reinterpret_cast<InnerModel*>(model);
344     return innerModel->BuildFromMetaGraph(metaGraph, buffer, modelName);
345 }
346 
OH_NNModel_SetInputsAndOutputsInfo(OH_NNModel * model,const OH_NN_TensorInfo * inputsInfo,size_t inputSize,const OH_NN_TensorInfo * outputsInfo,size_t outputSize)347 NNRT_API OH_NN_ReturnCode OH_NNModel_SetInputsAndOutputsInfo(OH_NNModel *model, const OH_NN_TensorInfo *inputsInfo,
348     size_t inputSize, const OH_NN_TensorInfo *outputsInfo, size_t outputSize)
349 {
350     if (model == nullptr) {
351         LOGE("OH_NNModel_SetInputsAndOutputsInfo failed, passed nullptr to model.");
352         return OH_NN_INVALID_PARAMETER;
353     }
354 
355     if ((inputsInfo == nullptr) || (inputSize == 0)) {
356         LOGE("OH_NNModel_SetInputsAndOutputsInfo failed, inputsInfo is empty.");
357         return OH_NN_INVALID_PARAMETER;
358     }
359 
360     if ((outputsInfo == nullptr) || (outputSize == 0)) {
361         LOGE("OH_NNModel_SetInputsAndOutputsInfo failed, outputsInfo is empty.");
362         return OH_NN_INVALID_PARAMETER;
363     }
364 
365     InnerModel *innerModel = reinterpret_cast<InnerModel*>(model);
366     return innerModel->SetInputsAndOutputsInfo(inputsInfo, inputSize, outputsInfo, outputSize);
367 }
368 
OH_NNModel_Destroy(OH_NNModel ** model)369 NNRT_API void OH_NNModel_Destroy(OH_NNModel **model)
370 {
371     if (model == nullptr) {
372         LOGW("OH_NNModel_Destroy has no effect, passed nullptr to model.");
373         return;
374     }
375 
376     if (*model == nullptr) {
377         LOGW("OH_NNModel_Destroy has no effect, passed nullptr to *model.");
378         return;
379     }
380 
381     InnerModel *innerModel = reinterpret_cast<InnerModel*>(*model);
382     delete innerModel;
383     *model = nullptr;
384 }
385 
OH_NNModel_GetAvailableOperations(OH_NNModel * model,size_t deviceID,const bool ** isAvailable,uint32_t * opCount)386 NNRT_API OH_NN_ReturnCode OH_NNModel_GetAvailableOperations(OH_NNModel *model,
387                                                             size_t deviceID,
388                                                             const bool **isAvailable,
389                                                             uint32_t *opCount)
390 {
391     if (model == nullptr) {
392         LOGE("OH_NNModel_GetAvailableOperations failed, passed nullptr to model.");
393         return OH_NN_INVALID_PARAMETER;
394     }
395 
396     if (isAvailable == nullptr) {
397         LOGE("OH_NNModel_GetAvailableOperations failed, passed nullptr to isAvailable.");
398         return OH_NN_INVALID_PARAMETER;
399     }
400 
401     if (*isAvailable != nullptr) {
402         LOGE("OH_NNModel_GetAvailableOperations failed, *isAvailable is not nullptr.");
403         return OH_NN_INVALID_PARAMETER;
404     }
405 
406     if (opCount == nullptr) {
407         LOGE("OH_NNModel_GetAvailableOperations failed, passed nullptr to opCount.");
408         return OH_NN_INVALID_PARAMETER;
409     }
410 
411     InnerModel *innerModel = reinterpret_cast<InnerModel*>(model);
412     return innerModel->GetSupportedOperations(deviceID, isAvailable, *opCount);
413 }