Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / runtime / onert / api / src / nnfw_api.cc
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "nnfw_api_internal.h"
18 #include "nnfw_version.h"
19
20 // Double-check enum value changes
21
22 #define STATIC_ASSERT_ENUM_CHECK(ENUM, VAL) static_assert((ENUM) == (VAL), #ENUM " has changed")
23
24 STATIC_ASSERT_ENUM_CHECK(NNFW_TYPE_TENSOR_FLOAT32, 0);
25 STATIC_ASSERT_ENUM_CHECK(NNFW_TYPE_TENSOR_INT32, 1);
26 STATIC_ASSERT_ENUM_CHECK(NNFW_TYPE_TENSOR_QUANT8_ASYMM, 2);
27 STATIC_ASSERT_ENUM_CHECK(NNFW_TYPE_TENSOR_BOOL, 3);
28 STATIC_ASSERT_ENUM_CHECK(NNFW_TYPE_TENSOR_UINT8, 4);
29 STATIC_ASSERT_ENUM_CHECK(NNFW_TYPE_TENSOR_INT64, 5);
30 STATIC_ASSERT_ENUM_CHECK(NNFW_TYPE_TENSOR_QUANT8_ASYMM_SIGNED, 6);
31 STATIC_ASSERT_ENUM_CHECK(NNFW_TYPE_TENSOR_QUANT16_SYMM_SIGNED, 7);
32
33 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_NO_ERROR, 0);
34 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_ERROR, 1);
35 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_UNEXPECTED_NULL, 2);
36 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_INVALID_STATE, 3);
37 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_OUT_OF_MEMORY, 4);
38 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_INSUFFICIENT_OUTPUT_SIZE, 5);
39
40 STATIC_ASSERT_ENUM_CHECK(NNFW_LAYOUT_NONE, 0);
41 STATIC_ASSERT_ENUM_CHECK(NNFW_LAYOUT_CHANNELS_LAST, 1);
42 STATIC_ASSERT_ENUM_CHECK(NNFW_LAYOUT_CHANNELS_FIRST, 2);
43
44 STATIC_ASSERT_ENUM_CHECK(NNFW_INFO_ID_VERSION, 0);
45
46 #undef STATIC_ASSERT_ENUM_CHECK
47
48 #define NNFW_RETURN_ERROR_IF_NULL(p)      \
49   do                                      \
50   {                                       \
51     if ((p) == NULL)                      \
52       return NNFW_STATUS_UNEXPECTED_NULL; \
53   } while (0)
54
55 /*
56  * Create a new session instance
57  *
58  * @param session the session to be created
59  * @return NNFW_STATUS_NO_ERROR if successful
60  */
61 NNFW_STATUS nnfw_create_session(nnfw_session **session) { return nnfw_session::create(session); }
62
63 /*
64  * Close a session instance
65  *
66  * @param session the session to be closed
67  * @return NNFW_STATUS_NO_ERROR if successful
68  */
69 NNFW_STATUS nnfw_close_session(nnfw_session *session)
70 {
71   delete session;
72   return NNFW_STATUS_NO_ERROR;
73 }
74
75 /*
76  * Load model from nnpackage file or directory
77  *
78  * @param session nnfw_session loading the given nnpackage file/dir
79  * @param package_file_path path to the nnpackage file or unzipped directory to be loaded
80  *
81  * @return NNFW_STATUS_NO_ERROR if successful
82  */
83 NNFW_STATUS nnfw_load_model_from_file(nnfw_session *session, const char *pacakge_file_path)
84 {
85   NNFW_RETURN_ERROR_IF_NULL(session);
86   return session->load_model_from_nnpackage(pacakge_file_path);
87 }
88
89 /*
90  * Prepare session to be ready for inference
91  * This phase may finalize model compilation, scheduling, and additional settings.
92  *
93  * @param session the session to be prepared
94  * @return NNFW_STATUS_NO_ERROR if successful
95  */
96 NNFW_STATUS nnfw_prepare(nnfw_session *session)
97 {
98   NNFW_RETURN_ERROR_IF_NULL(session);
99   return session->prepare();
100 }
101
102 /*
103  * Run inference
104  *
105  * @param session the session to run inference
106  * @return NNFW_STATUS_NO_ERROR if successful
107  */
108 NNFW_STATUS nnfw_run(nnfw_session *session)
109 {
110   NNFW_RETURN_ERROR_IF_NULL(session);
111   return session->run();
112 }
113
114 NNFW_STATUS nnfw_run_async(nnfw_session *session)
115 {
116   NNFW_RETURN_ERROR_IF_NULL(session);
117   return session->run_async();
118 }
119
120 NNFW_STATUS nnfw_await(nnfw_session *session)
121 {
122   NNFW_RETURN_ERROR_IF_NULL(session);
123   return session->await();
124 }
125
126 /*
127  * Set input
128  *
129  * @param session session to the input is to be set
130  * @param index index of input to be set (0-indexed)
131  * @param type type of the input
132  * @param buffer raw buffer for input
133  * @param length size of bytes of input
134  *
135  * @return NNFW_STATUS_NO_ERROR if successful
136  */
137
138 NNFW_STATUS nnfw_set_input(nnfw_session *session, uint32_t index, NNFW_TYPE type,
139                            const void *buffer, size_t length)
140 {
141   NNFW_RETURN_ERROR_IF_NULL(session);
142   return session->set_input(index, type, buffer, length);
143 }
144
145 /*
146  * Set output
147  *
148  * @param session session from inference output is to be extracted
149  * @param index index of output to be set (0-indexed)
150  * @param type type of the output
151  * @param buffer raw buffer for output
152  * @param length size of bytes of output
153  *
154  * @return NNFW_STATUS_NO_ERROR if successful
155  */
156
157 NNFW_STATUS nnfw_set_output(nnfw_session *session, uint32_t index, NNFW_TYPE type, void *buffer,
158                             size_t length)
159 {
160   NNFW_RETURN_ERROR_IF_NULL(session);
161   return session->set_output(index, type, buffer, length);
162 }
163
164 /*
165  * Get the number of inputs
166  *
167  * @param[in] session session from input information is to be extracted
168  * @param[out] number variable which the number of inputs is put into
169  *
170  * @return NNFW_STATUS_NO_ERROR if successful
171  */
172
173 NNFW_STATUS nnfw_input_size(nnfw_session *session, uint32_t *number)
174 {
175   NNFW_RETURN_ERROR_IF_NULL(session);
176   return session->input_size(number);
177 }
178
179 /*
180  * Get the number of outputs
181  *
182  * @param[in] session session from output information is to be extracted
183  * @param[out] number variable which the number of outputs is put into
184  *
185  * @return NNFW_STATUS_NO_ERROR if successful
186  */
187 NNFW_STATUS nnfw_output_size(nnfw_session *session, uint32_t *number)
188 {
189   NNFW_RETURN_ERROR_IF_NULL(session);
190   return session->output_size(number);
191 }
192
193 /*
194  * Set the layout of an input
195  * @note The input that does not call this has NNFW_LAYOUT_CHANNELS_LAST layout
196  *
197  * @param[in] session session from inference input is to be extracted
198  * @param[in] index   index of input to be set (0-indexed)
199  * @param[in] layout  layout to set to target input
200  *
201  * @return NNFW_STATUS_NO_ERROR if successful
202  */
203 NNFW_STATUS nnfw_set_input_layout(nnfw_session *session, uint32_t index, NNFW_LAYOUT layout)
204 {
205   NNFW_RETURN_ERROR_IF_NULL(session);
206   return session->set_input_layout(index, layout);
207 }
208
209 /*
210  * Set the layout of an output
211  * @note The output that does not call this has NNFW_LAYOUT_CHANNELS_LAST layout
212  *
213  * @param[in] session session from inference output is to be extracted
214  * @param[in] index   index of output to be set (0-indexed)
215  * @param[in] layout  layout to set to target output
216  *
217  * @return NNFW_STATUS_NO_ERROR if successful
218  */
219 NNFW_STATUS nnfw_set_output_layout(nnfw_session *session, uint32_t index, NNFW_LAYOUT layout)
220 {
221   NNFW_RETURN_ERROR_IF_NULL(session);
222   return session->set_output_layout(index, layout);
223 }
224
225 /*
226  * Get i-th input tensor info
227  *
228  * @param[in] session session from input information is to be extracted
229  * @param[in] index index of input
230  * @param[out] tensor_info nnfw_tensor_info
231  *
232  * @return NNFW_STATUS_NO_ERROR if successful
233  */
234 NNFW_STATUS nnfw_input_tensorinfo(nnfw_session *session, uint32_t index,
235                                   nnfw_tensorinfo *tensor_info)
236 {
237   NNFW_RETURN_ERROR_IF_NULL(session);
238   return session->input_tensorinfo(index, tensor_info);
239 }
240
241 /*
242  * Get i-th output tensor info
243  *
244  * @param[in] session session from output information is to be extracted
245  * @param[in] index index of output
246  * @param[out] tensor_info nnfw_tensor_info
247  *
248  * @return NNFW_STATUS_NO_ERROR if successful
249  */
250 NNFW_STATUS nnfw_output_tensorinfo(nnfw_session *session, uint32_t index,
251                                    nnfw_tensorinfo *tensor_info)
252 {
253   NNFW_RETURN_ERROR_IF_NULL(session);
254   return session->output_tensorinfo(index, tensor_info);
255 }
256
257 /*
258  * Register custom operation
259  * @param session session to register this operation
260  * @param id operation id
261  * @param info registration info ( eval function, etc. )
262  * @return NNFW_STATUS_NO_ERROR if successful
263  */
264 NNFW_STATUS nnfw_register_custom_op_info(nnfw_session *session, const char *id,
265                                          custom_kernel_registration_info *info)
266 {
267   NNFW_RETURN_ERROR_IF_NULL(session);
268   return session->register_custom_operation(id, info->eval_function);
269 }
270
271 NNFW_STATUS nnfw_apply_tensorinfo(nnfw_session *session, uint32_t index,
272                                   nnfw_tensorinfo tensor_info)
273 {
274   NNFW_RETURN_ERROR_IF_NULL(session);
275   return session->apply_tensorinfo(index, tensor_info);
276 }
277
278 NNFW_STATUS nnfw_set_input_tensorinfo(nnfw_session *session, uint32_t index,
279                                       const nnfw_tensorinfo *tensor_info)
280 {
281   NNFW_RETURN_ERROR_IF_NULL(session);
282   return session->set_input_tensorinfo(index, tensor_info);
283 }
284
285 /*
286  * Set available backends
287  *
288  * @param[in] session session to which a avilable backends are set
289  * @param[in] backends available backends on which nnfw uses
290  */
291 NNFW_STATUS nnfw_set_available_backends(nnfw_session *session, const char *backends)
292 {
293   NNFW_RETURN_ERROR_IF_NULL(session);
294   return session->set_available_backends(backends);
295 }
296
297 /*
298  * Set the operation's backend
299  *
300  * @param[in] session session to be modified
301  * @param[in] op operation to be set
302  * @param[in] backend bakcend on which operation run
303  *
304  * @return NNFW_STATUS_NO_ERROR if successful
305  */
306 NNFW_STATUS nnfw_set_op_backend(nnfw_session *session, const char *op, const char *backend)
307 {
308   NNFW_RETURN_ERROR_IF_NULL(session);
309   return session->set_op_backend(op, backend);
310 }
311
312 /*
313  * Retrieve uint32 type of nnfw information for given information ID.
314  *
315  * @param[in] session session to be queried on
316  * @param[in] information ID to be queried
317  * @param[out] val uint32 value to be returned
318  *
319  * @return @c NNFW_STATUS_NO_ERROR if successful
320  */
321 NNFW_STATUS nnfw_query_info_u32(nnfw_session *session, NNFW_INFO_ID id, uint32_t *val)
322 {
323   (void)session;
324   switch (id)
325   {
326     case NNFW_INFO_ID_VERSION:
327       if (val)
328       {
329         *val = NNFW_VERSION;
330         return NNFW_STATUS_NO_ERROR;
331       }
332       break;
333     default:
334       return NNFW_STATUS_ERROR;
335   }
336   // It should not be reached.
337   return NNFW_STATUS_ERROR;
338 }
339
340 NNFW_STATUS nnfw_load_circle_from_buffer(nnfw_session *session, uint8_t *buffer, size_t size)
341 {
342   NNFW_RETURN_ERROR_IF_NULL(session);
343   return session->load_circle_from_buffer(buffer, size);
344 }
345
346 NNFW_STATUS nnfw_load_model_from_modelfile(nnfw_session *session, const char *file_path)
347 {
348   NNFW_RETURN_ERROR_IF_NULL(session);
349   return session->load_model_from_modelfile(file_path);
350 }
351
352 NNFW_STATUS nnfw_input_tensorindex(nnfw_session *session, const char *tensorname, uint32_t *index)
353 {
354   NNFW_RETURN_ERROR_IF_NULL(session);
355   return session->input_tensorindex(tensorname, index);
356 }
357
358 NNFW_STATUS nnfw_output_tensorindex(nnfw_session *session, const char *tensorname, uint32_t *index)
359 {
360   NNFW_RETURN_ERROR_IF_NULL(session);
361   return session->output_tensorindex(tensorname, index);
362 }
363
364 NNFW_STATUS nnfw_set_backends_per_operation(nnfw_session *session, const char *backend_settings)
365 {
366   NNFW_RETURN_ERROR_IF_NULL(session);
367   return session->set_backends_per_operation(backend_settings);
368 }
369
370 NNFW_STATUS nnfw_prepare_pipeline(nnfw_session *session, const char *map_file_path)
371 {
372   NNFW_RETURN_ERROR_IF_NULL(session);
373   return session->prepare_pipeline(map_file_path);
374 }
375
376 NNFW_STATUS nnfw_push_pipeline_input(nnfw_session *session, void *inputs, void *lengths)
377 {
378   NNFW_RETURN_ERROR_IF_NULL(session);
379   return session->push_pipeline_input((std::vector<void *> *)inputs,
380                                       (std::vector<uint32_t> *)lengths);
381 }
382
383 NNFW_STATUS nnfw_pop_pipeline_output(nnfw_session *session, void *outputs)
384 {
385   NNFW_RETURN_ERROR_IF_NULL(session);
386   return session->pop_pipeline_output((std::vector<void *> *)outputs);
387 }
388
389 // Training
390
391 #ifdef ONERT_TRAIN
392
393 NNFW_STATUS nnfw_train_prepare(nnfw_session *session, const nnfw_train_info *info)
394 {
395   NNFW_RETURN_ERROR_IF_NULL(session);
396   return session->train_prepare(info);
397 }
398
399 NNFW_STATUS nnfw_train_input_tensorinfo(nnfw_session *session, uint32_t index,
400                                         nnfw_tensorinfo *info)
401 {
402   NNFW_RETURN_ERROR_IF_NULL(session);
403   return session->train_input_tensorinfo(index, info);
404 }
405
406 NNFW_STATUS nnfw_train_expected_tensorinfo(nnfw_session *session, uint32_t index,
407                                            nnfw_tensorinfo *info)
408 {
409   NNFW_RETURN_ERROR_IF_NULL(session);
410   return session->train_expected_tensorinfo(index, info);
411 }
412
413 NNFW_STATUS nnfw_train_set_input(nnfw_session *session, uint32_t index, const void *input,
414                                  const nnfw_tensorinfo *input_info)
415 {
416   NNFW_RETURN_ERROR_IF_NULL(session);
417   return session->train_set_input(index, input, input_info);
418 }
419
420 NNFW_STATUS nnfw_train_set_expected(nnfw_session *session, uint32_t index, const void *expected,
421                                     const nnfw_tensorinfo *expected_info)
422 {
423   NNFW_RETURN_ERROR_IF_NULL(session);
424   return session->train_set_expected(index, expected, expected_info);
425 }
426
427 NNFW_STATUS nnfw_train(nnfw_session *session, bool update_weights)
428 {
429   NNFW_RETURN_ERROR_IF_NULL(session);
430   return session->train_run(update_weights);
431 }
432
433 NNFW_STATUS nnfw_train_get_loss(nnfw_session *session, uint32_t index, float *loss)
434 {
435   NNFW_RETURN_ERROR_IF_NULL(session);
436   return session->train_get_loss(index, loss);
437 }
438
439 NNFW_STATUS nnfw_train_export_circle(nnfw_session *session, const char *path)
440 {
441   NNFW_RETURN_ERROR_IF_NULL(session);
442   return session->train_export_circle(path);
443 }
444
445 #else // ONERT_TRAIN
446
447 NNFW_STATUS nnfw_train_prepare(nnfw_session *session, const nnfw_train_info *)
448 {
449   NNFW_RETURN_ERROR_IF_NULL(session);
450   return NNFW_STATUS_ERROR;
451 }
452
453 NNFW_STATUS nnfw_train_input_tensorinfo(nnfw_session *session, uint32_t, nnfw_tensorinfo *)
454 {
455   NNFW_RETURN_ERROR_IF_NULL(session);
456   return NNFW_STATUS_ERROR;
457 }
458
459 NNFW_STATUS nnfw_train_expected_tensorinfo(nnfw_session *session, uint32_t, nnfw_tensorinfo *)
460 {
461   NNFW_RETURN_ERROR_IF_NULL(session);
462   return NNFW_STATUS_ERROR;
463 }
464
465 NNFW_STATUS nnfw_train_set_input(nnfw_session *session, uint32_t, const void *,
466                                  const nnfw_tensorinfo *)
467 {
468   NNFW_RETURN_ERROR_IF_NULL(session);
469   return NNFW_STATUS_ERROR;
470 }
471
472 NNFW_STATUS nnfw_train_set_expected(nnfw_session *session, uint32_t, const void *,
473                                     const nnfw_tensorinfo *)
474 {
475   NNFW_RETURN_ERROR_IF_NULL(session);
476   return NNFW_STATUS_ERROR;
477 }
478
479 NNFW_STATUS nnfw_train(nnfw_session *session, bool)
480 {
481   NNFW_RETURN_ERROR_IF_NULL(session);
482   return NNFW_STATUS_ERROR;
483 }
484
485 NNFW_STATUS nnfw_train_get_loss(nnfw_session *session, uint32_t, float *)
486 {
487   NNFW_RETURN_ERROR_IF_NULL(session);
488   return NNFW_STATUS_ERROR;
489 }
490
491 NNFW_STATUS nnfw_train_export_circle(nnfw_session *session, const char *)
492 {
493   NNFW_RETURN_ERROR_IF_NULL(session);
494   return NNFW_STATUS_ERROR;
495 }
496
497 #endif // ONERT_TRAIN
498
499 // Quantization
500
501 NNFW_STATUS nnfw_set_quantization_type(nnfw_session *session, NNFW_QUANTIZE_TYPE qtype)
502 {
503   NNFW_RETURN_ERROR_IF_NULL(session);
504   return session->set_quantization_type(qtype);
505 }
506
507 NNFW_STATUS nnfw_set_quantized_model_path(nnfw_session *session, const char *path)
508 {
509   NNFW_RETURN_ERROR_IF_NULL(session);
510   return session->set_quantized_model_path(path);
511 }
512
513 NNFW_STATUS nnfw_quantize(nnfw_session *session)
514 {
515   NNFW_RETURN_ERROR_IF_NULL(session);
516   return session->quantize();
517 }