Imported Upstream version 1.9.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
31 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_NO_ERROR, 0);
32 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_ERROR, 1);
33 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_UNEXPECTED_NULL, 2);
34 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_INVALID_STATE, 3);
35 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_OUT_OF_MEMORY, 4);
36 STATIC_ASSERT_ENUM_CHECK(NNFW_STATUS_INSUFFICIENT_OUTPUT_SIZE, 5);
37
38 STATIC_ASSERT_ENUM_CHECK(NNFW_LAYOUT_NONE, 0);
39 STATIC_ASSERT_ENUM_CHECK(NNFW_LAYOUT_CHANNELS_LAST, 1);
40 STATIC_ASSERT_ENUM_CHECK(NNFW_LAYOUT_CHANNELS_FIRST, 2);
41
42 STATIC_ASSERT_ENUM_CHECK(NNFW_INFO_ID_VERSION, 0);
43
44 #undef STATIC_ASSERT_ENUM_CHECK
45
46 #define NNFW_RETURN_ERROR_IF_NULL(p)      \
47   do                                      \
48   {                                       \
49     if ((p) == NULL)                      \
50       return NNFW_STATUS_UNEXPECTED_NULL; \
51   } while (0)
52
53 /*
54  * Create a new session instance
55  *
56  * @param session the session to be created
57  * @return NNFW_STATUS_NO_ERROR if successful
58  */
59 NNFW_STATUS nnfw_create_session(nnfw_session **session)
60 {
61   NNFW_RETURN_ERROR_IF_NULL(session);
62
63   *session = new (std::nothrow) nnfw_session();
64   if (*session == nullptr)
65     return NNFW_STATUS_OUT_OF_MEMORY;
66   return NNFW_STATUS_NO_ERROR;
67 }
68
69 /*
70  * Close a session instance
71  *
72  * @param session the session to be closed
73  * @return NNFW_STATUS_NO_ERROR if successful
74  */
75 NNFW_STATUS nnfw_close_session(nnfw_session *session)
76 {
77   delete session;
78   return NNFW_STATUS_NO_ERROR;
79 }
80
81 /*
82  * Load model from nnpackage file or directory
83  *
84  * @param session nnfw_session loading the given nnpackage file/dir
85  * @param package_file_path path to the nnpackage file or unzipped directory to be loaded
86  *
87  * @return NNFW_STATUS_NO_ERROR if successful
88  */
89 NNFW_STATUS nnfw_load_model_from_file(nnfw_session *session, const char *pacakge_file_path)
90 {
91   NNFW_RETURN_ERROR_IF_NULL(session);
92   return session->load_model_from_file(pacakge_file_path);
93 }
94
95 /*
96  * Prepare session to be ready for inference
97  * This phase may finalize model compilation, scheduling, and additional settings.
98  *
99  * @param session the session to be prepared
100  * @return NNFW_STATUS_NO_ERROR if successful
101  */
102 NNFW_STATUS nnfw_prepare(nnfw_session *session)
103 {
104   NNFW_RETURN_ERROR_IF_NULL(session);
105   return session->prepare();
106 }
107
108 /*
109  * Run inference
110  *
111  * @param session the session to run inference
112  * @return NNFW_STATUS_NO_ERROR if successful
113  */
114 NNFW_STATUS nnfw_run(nnfw_session *session)
115 {
116   NNFW_RETURN_ERROR_IF_NULL(session);
117   return session->run();
118 }
119
120 NNFW_STATUS nnfw_run_async(nnfw_session *session)
121 {
122   NNFW_RETURN_ERROR_IF_NULL(session);
123   return session->run_async();
124 }
125
126 NNFW_STATUS nnfw_await(nnfw_session *session)
127 {
128   NNFW_RETURN_ERROR_IF_NULL(session);
129   return session->await();
130 }
131
132 /*
133  * Set input
134  *
135  * @param session session to the input is to be set
136  * @param index index of input to be set (0-indexed)
137  * @param type type of the input
138  * @param buffer raw buffer for input
139  * @param length size of bytes of input
140  *
141  * @return NNFW_STATUS_NO_ERROR if successful
142  */
143
144 NNFW_STATUS nnfw_set_input(nnfw_session *session, uint32_t index, NNFW_TYPE type,
145                            const void *buffer, size_t length)
146 {
147   NNFW_RETURN_ERROR_IF_NULL(session);
148   return session->set_input(index, type, buffer, length);
149 }
150
151 /*
152  * Set output
153  *
154  * @param session session from inference output is to be extracted
155  * @param index index of output to be set (0-indexed)
156  * @param type type of the output
157  * @param buffer raw buffer for output
158  * @param length size of bytes of output
159  *
160  * @return NNFW_STATUS_NO_ERROR if successful
161  */
162
163 NNFW_STATUS nnfw_set_output(nnfw_session *session, uint32_t index, NNFW_TYPE type, void *buffer,
164                             size_t length)
165 {
166   NNFW_RETURN_ERROR_IF_NULL(session);
167   return session->set_output(index, type, buffer, length);
168 }
169
170 /*
171  * Get the number of inputs
172  *
173  * @param[in] session session from input information is to be extracted
174  * @param[out] number variable which the number of inputs is put into
175  *
176  * @return NNFW_STATUS_NO_ERROR if successful
177  */
178
179 NNFW_STATUS nnfw_input_size(nnfw_session *session, uint32_t *number)
180 {
181   NNFW_RETURN_ERROR_IF_NULL(session);
182   return session->input_size(number);
183 }
184
185 /*
186  * Get the number of outputs
187  *
188  * @param[in] session session from output information is to be extracted
189  * @param[out] number variable which the number of outputs is put into
190  *
191  * @return NNFW_STATUS_NO_ERROR if successful
192  */
193 NNFW_STATUS nnfw_output_size(nnfw_session *session, uint32_t *number)
194 {
195   NNFW_RETURN_ERROR_IF_NULL(session);
196   return session->output_size(number);
197 }
198
199 /*
200  * Set the layout of an input
201  * @note The input that does not call this has NNFW_LAYOUT_CHANNELS_LAST layout
202  *
203  * @param[in] session session from inference input is to be extracted
204  * @param[in] index   index of input to be set (0-indexed)
205  * @param[in] layout  layout to set to target input
206  *
207  * @return NNFW_STATUS_NO_ERROR if successful
208  */
209 NNFW_STATUS nnfw_set_input_layout(nnfw_session *session, uint32_t index, NNFW_LAYOUT layout)
210 {
211   NNFW_RETURN_ERROR_IF_NULL(session);
212   return session->set_input_layout(index, layout);
213 }
214
215 /*
216  * Set the layout of an output
217  * @note The output that does not call this has NNFW_LAYOUT_CHANNELS_LAST layout
218  *
219  * @param[in] session session from inference output is to be extracted
220  * @param[in] index   index of output to be set (0-indexed)
221  * @param[in] layout  layout to set to target output
222  *
223  * @return NNFW_STATUS_NO_ERROR if successful
224  */
225 NNFW_STATUS nnfw_set_output_layout(nnfw_session *session, uint32_t index, NNFW_LAYOUT layout)
226 {
227   NNFW_RETURN_ERROR_IF_NULL(session);
228   return session->set_output_layout(index, layout);
229 }
230
231 /*
232  * Get i-th input tensor info
233  *
234  * @param[in] session session from input information is to be extracted
235  * @param[in] index index of input
236  * @param[out] tensor_info nnfw_tensor_info
237  *
238  * @return NNFW_STATUS_NO_ERROR if successful
239  */
240 NNFW_STATUS nnfw_input_tensorinfo(nnfw_session *session, uint32_t index,
241                                   nnfw_tensorinfo *tensor_info)
242 {
243   NNFW_RETURN_ERROR_IF_NULL(session);
244   return session->input_tensorinfo(index, tensor_info);
245 }
246
247 /*
248  * Get i-th output tensor info
249  *
250  * @param[in] session session from output information is to be extracted
251  * @param[in] index index of output
252  * @param[out] tensor_info nnfw_tensor_info
253  *
254  * @return NNFW_STATUS_NO_ERROR if successful
255  */
256 NNFW_STATUS nnfw_output_tensorinfo(nnfw_session *session, uint32_t index,
257                                    nnfw_tensorinfo *tensor_info)
258 {
259   NNFW_RETURN_ERROR_IF_NULL(session);
260   return session->output_tensorinfo(index, tensor_info);
261 }
262
263 /*
264  * Register custom operation
265  * @param session session to register this operation
266  * @param id operation id
267  * @param info registration info ( eval function, etc. )
268  * @return NNFW_STATUS_NO_ERROR if successful
269  */
270 NNFW_STATUS nnfw_register_custom_op_info(nnfw_session *session, const char *id,
271                                          custom_kernel_registration_info *info)
272 {
273   NNFW_RETURN_ERROR_IF_NULL(session);
274   return session->register_custom_operation(id, info->eval_function);
275 }
276
277 NNFW_STATUS nnfw_apply_tensorinfo(nnfw_session *session, uint32_t index,
278                                   nnfw_tensorinfo tensor_info)
279 {
280   NNFW_RETURN_ERROR_IF_NULL(session);
281   return session->apply_tensorinfo(index, tensor_info);
282 }
283
284 NNFW_STATUS nnfw_set_input_tensorinfo(nnfw_session *session, uint32_t index,
285                                       const nnfw_tensorinfo *tensor_info)
286 {
287   NNFW_RETURN_ERROR_IF_NULL(session);
288   return session->set_input_tensorinfo(index, tensor_info);
289 }
290
291 /*
292  * Set available backends
293  *
294  * @param[in] session session to which a avilable backends are set
295  * @param[in] backends available backends on which nnfw uses
296  */
297 NNFW_STATUS nnfw_set_available_backends(nnfw_session *session, const char *backends)
298 {
299   NNFW_RETURN_ERROR_IF_NULL(session);
300   return session->set_available_backends(backends);
301 }
302
303 /*
304  * Set the operation's backend
305  *
306  * @param[in] session session to be modified
307  * @param[in] op operation to be set
308  * @param[in] backend bakcend on which operation run
309  *
310  * @return NNFW_STATUS_NO_ERROR if successful
311  */
312 NNFW_STATUS nnfw_set_op_backend(nnfw_session *session, const char *op, const char *backend)
313 {
314   NNFW_RETURN_ERROR_IF_NULL(session);
315   return session->set_op_backend(op, backend);
316 }
317
318 /*
319  * Retrieve uint32 type of nnfw information for given information ID.
320  *
321  * @param[in] session session to be queried on
322  * @param[in] information ID to be queried
323  * @param[out] val uint32 value to be returned
324  *
325  * @return @c NNFW_STATUS_NO_ERROR if successful
326  */
327 NNFW_STATUS nnfw_query_info_u32(nnfw_session *session, NNFW_INFO_ID id, uint32_t *val)
328 {
329   (void)session;
330   switch (id)
331   {
332     case NNFW_INFO_ID_VERSION:
333       if (val)
334       {
335         *val = NNFW_VERSION;
336         return NNFW_STATUS_NO_ERROR;
337       }
338       break;
339     default:
340       return NNFW_STATUS_ERROR;
341   }
342   // It should not be reached.
343   return NNFW_STATUS_ERROR;
344 }
345
346 NNFW_STATUS nnfw_load_circle_from_buffer(nnfw_session *session, uint8_t *buffer, size_t size)
347 {
348   NNFW_RETURN_ERROR_IF_NULL(session);
349   return session->load_circle_from_buffer(buffer, size);
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 }