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