26
26
* from 4. to 6. is the Inference Loop
27
27
*/
28
28
29
+ /* these limits are arbitrary. */
30
+ #define MAX_GRAPHS 4
31
+ #define MAX_EXECUTION_CONTEXTS 4
32
+
29
33
typedef struct {
30
34
ov_core_t * core ;
31
35
/* keep input model files */
32
- void * weight_data ;
33
- ov_tensor_t * weights_tensor ;
34
- ov_model_t * model ;
35
- ov_compiled_model_t * compiled_model ;
36
- ov_infer_request_t * infer_request ;
37
- ov_tensor_t * input_tensor ;
36
+ struct OpenVINOGraph {
37
+ void * weight_data ;
38
+ ov_tensor_t * weights_tensor ;
39
+ ov_model_t * model ;
40
+ ov_compiled_model_t * compiled_model ;
41
+ } graphs [MAX_GRAPHS ];
42
+ struct OpenVINOExecutionContext {
43
+ struct OpenVINOGraph * graph ;
44
+ ov_infer_request_t * infer_request ;
45
+ } execution_contexts [MAX_EXECUTION_CONTEXTS ];
46
+ unsigned int n_graphs ;
47
+ unsigned int n_execution_contexts ;
38
48
} OpenVINOContext ;
39
49
40
50
/*
@@ -179,6 +189,29 @@ wasi_nn_tensor_type_to_openvino_element_type(tensor_type wasi_nn_type)
179
189
return UNDEFINED ;
180
190
}
181
191
192
+ static void
193
+ free_graph (struct OpenVINOGraph * graph )
194
+ {
195
+ if (graph -> weight_data )
196
+ os_free (graph -> weight_data );
197
+
198
+ if (graph -> weights_tensor )
199
+ ov_tensor_free (graph -> weights_tensor );
200
+
201
+ if (graph -> model )
202
+ ov_model_free (graph -> model );
203
+
204
+ if (graph -> compiled_model )
205
+ ov_compiled_model_free (graph -> compiled_model );
206
+ }
207
+
208
+ static void
209
+ free_execution_context (struct OpenVINOExecutionContext * c )
210
+ {
211
+ if (c -> infer_request )
212
+ ov_infer_request_free (c -> infer_request );
213
+ }
214
+
182
215
static wasi_nn_error
183
216
uint32_array_to_int64_array (uint32_t array_size , uint32_t * src , int64_t * * dst )
184
217
{
@@ -198,6 +231,8 @@ load(void *ctx, graph_builder_array *builder, graph_encoding encoding,
198
231
execution_target target , graph * g )
199
232
{
200
233
OpenVINOContext * ov_ctx = (OpenVINOContext * )ctx ;
234
+ struct OpenVINOGraph * graph ;
235
+ unsigned int graph_idx ;
201
236
wasi_nn_error ret = unsupported_operation ;
202
237
203
238
if (encoding != openvino ) {
@@ -223,65 +258,127 @@ load(void *ctx, graph_builder_array *builder, graph_encoding encoding,
223
258
graph_builder xml = builder -> buf [0 ];
224
259
graph_builder weight = builder -> buf [1 ];
225
260
261
+ graph_idx = ov_ctx -> n_graphs ;
262
+ if (graph_idx >= MAX_GRAPHS ) {
263
+ return runtime_error ;
264
+ }
265
+ graph = & ov_ctx -> graphs [graph_idx ];
266
+ memset (graph , 0 , sizeof (* graph ));
267
+
226
268
/* transfer weight to an ov tensor */
227
269
{
228
- ov_ctx -> weight_data = os_malloc (weight .size );
229
- if (!ov_ctx -> weight_data )
270
+ graph -> weight_data = os_malloc (weight .size );
271
+ if (!graph -> weight_data )
230
272
goto fail ;
231
- memcpy (ov_ctx -> weight_data , weight .buf , weight .size );
273
+ memcpy (graph -> weight_data , weight .buf , weight .size );
232
274
233
275
ov_element_type_e type = U8 ;
234
276
int64_t dims [1 ] = { weight .size };
235
277
ov_shape_t shape = { 1 , dims };
236
278
CHECK_OV_STATUS (ov_tensor_create_from_host_ptr (type , shape ,
237
- ov_ctx -> weight_data ,
238
- & ov_ctx -> weights_tensor ),
279
+ graph -> weight_data ,
280
+ & graph -> weights_tensor ),
239
281
ret );
240
282
}
241
283
242
284
/* load model from buffer */
243
285
CHECK_OV_STATUS (ov_core_read_model_from_memory_buffer (
244
286
ov_ctx -> core , (char * )xml .buf , xml .size ,
245
- ov_ctx -> weights_tensor , & ov_ctx -> model ),
287
+ graph -> weights_tensor , & graph -> model ),
246
288
ret );
247
289
#ifndef NDEBUG
248
290
print_model_input_output_info (ov_ctx -> model );
249
291
#endif
250
292
251
- ret = success ;
293
+ CHECK_OV_STATUS (ov_core_compile_model (ov_ctx -> core , graph -> model , "CPU" , 0 ,
294
+ & graph -> compiled_model ),
295
+ ret );
296
+
297
+ * g = graph_idx ;
298
+ ov_ctx -> n_graphs ++ ;
299
+ return success ;
252
300
fail :
301
+ free_graph (graph );
253
302
return ret ;
254
303
}
255
304
256
305
__attribute__((visibility ("default" ))) wasi_nn_error
257
306
load_by_name (void * ctx , const char * filename , uint32_t filename_len , graph * g )
258
307
{
259
308
OpenVINOContext * ov_ctx = (OpenVINOContext * )ctx ;
309
+ struct OpenVINOGraph * graph ;
310
+ unsigned int graph_idx ;
260
311
wasi_nn_error ret = unsupported_operation ;
261
312
313
+ graph_idx = ov_ctx -> n_graphs ;
314
+ if (graph_idx >= MAX_GRAPHS ) {
315
+ return runtime_error ;
316
+ }
317
+ graph = & ov_ctx -> graphs [graph_idx ];
318
+
319
+ memset (graph , 0 , sizeof (* graph ));
262
320
CHECK_OV_STATUS (
263
- ov_core_read_model (ov_ctx -> core , filename , NULL , & ov_ctx -> model ), ret );
321
+ ov_core_read_model (ov_ctx -> core , filename , NULL , & graph -> model ), ret );
264
322
265
- ret = success ;
323
+ CHECK_OV_STATUS (ov_core_compile_model (ov_ctx -> core , graph -> model , "CPU" , 0 ,
324
+ & graph -> compiled_model ),
325
+ ret );
326
+
327
+ * g = graph_idx ;
328
+ ov_ctx -> n_graphs ++ ;
329
+ return success ;
266
330
fail :
331
+ free_graph (graph );
267
332
return ret ;
268
333
}
269
334
270
335
__attribute__((visibility ("default" ))) wasi_nn_error
271
336
init_execution_context (void * ctx , graph g , graph_execution_context * exec_ctx )
272
337
{
338
+ OpenVINOContext * ov_ctx = (OpenVINOContext * )ctx ;
339
+ struct OpenVINOGraph * graph ;
340
+ struct OpenVINOExecutionContext * exec ;
341
+ unsigned int exec_idx ;
342
+ wasi_nn_error ret ;
343
+
344
+ if (g >= ov_ctx -> n_graphs )
345
+ return runtime_error ;
346
+ graph = & ov_ctx -> graphs [g ];
347
+
348
+ exec_idx = ov_ctx -> n_execution_contexts ;
349
+ if (exec_idx >= MAX_EXECUTION_CONTEXTS )
350
+ return runtime_error ;
351
+ exec = & ov_ctx -> execution_contexts [exec_idx ];
352
+
353
+ memset (exec , 0 , sizeof (* exec ));
354
+ exec -> graph = graph ;
355
+
356
+ CHECK_OV_STATUS (ov_compiled_model_create_infer_request (
357
+ graph -> compiled_model , & exec -> infer_request ),
358
+ ret );
359
+
360
+ * exec_ctx = exec_idx ;
361
+ ov_ctx -> n_execution_contexts ++ ;
273
362
return success ;
363
+ fail :
364
+ return ret ;
274
365
}
275
366
276
367
__attribute__((visibility ("default" ))) wasi_nn_error
277
368
set_input (void * ctx , graph_execution_context exec_ctx , uint32_t index ,
278
369
tensor * wasi_nn_tensor )
279
370
{
280
371
OpenVINOContext * ov_ctx = (OpenVINOContext * )ctx ;
372
+ struct OpenVINOExecutionContext * exec ;
281
373
wasi_nn_error ret = unsupported_operation ;
282
374
ov_shape_t input_shape = { 0 };
375
+ ov_tensor_t * input_tensor = NULL ;
283
376
int64_t * ov_dims = NULL ;
284
377
378
+ if (exec_ctx >= ov_ctx -> n_execution_contexts )
379
+ return runtime_error ;
380
+ exec = & ov_ctx -> execution_contexts [exec_ctx ];
381
+
285
382
/* wasi_nn_tensor -> ov_tensor */
286
383
{
287
384
ret = uint32_array_to_int64_array (wasi_nn_tensor -> dimensions -> size ,
@@ -306,27 +403,20 @@ set_input(void *ctx, graph_execution_context exec_ctx, uint32_t index,
306
403
307
404
CHECK_OV_STATUS (ov_tensor_create_from_host_ptr (input_type , input_shape ,
308
405
wasi_nn_tensor -> data ,
309
- & ov_ctx -> input_tensor ),
406
+ & input_tensor ),
310
407
ret );
311
408
}
312
409
313
- CHECK_OV_STATUS (ov_core_compile_model (ov_ctx -> core , ov_ctx -> model , "CPU" , 0 ,
314
- & ov_ctx -> compiled_model ),
315
- ret );
316
-
317
- CHECK_OV_STATUS (ov_compiled_model_create_infer_request (
318
- ov_ctx -> compiled_model , & ov_ctx -> infer_request ),
319
- ret );
320
-
321
410
/* install ov_tensor -> infer_request */
322
411
CHECK_OV_STATUS (ov_infer_request_set_input_tensor_by_index (
323
- ov_ctx -> infer_request , index , ov_ctx -> input_tensor ),
412
+ exec -> infer_request , index , input_tensor ),
324
413
ret );
325
414
ret = success ;
326
-
327
415
fail :
328
416
if (ov_dims )
329
417
os_free (ov_dims );
418
+ if (input_tensor )
419
+ ov_tensor_free (input_tensor );
330
420
ov_shape_free (& input_shape );
331
421
332
422
return ret ;
@@ -336,9 +426,14 @@ __attribute__((visibility("default"))) wasi_nn_error
336
426
compute (void * ctx , graph_execution_context exec_ctx )
337
427
{
338
428
OpenVINOContext * ov_ctx = (OpenVINOContext * )ctx ;
429
+ struct OpenVINOExecutionContext * exec ;
339
430
wasi_nn_error ret = unsupported_operation ;
340
431
341
- CHECK_OV_STATUS (ov_infer_request_infer (ov_ctx -> infer_request ), ret );
432
+ if (exec_ctx >= ov_ctx -> n_execution_contexts )
433
+ return runtime_error ;
434
+ exec = & ov_ctx -> execution_contexts [exec_ctx ];
435
+
436
+ CHECK_OV_STATUS (ov_infer_request_infer (exec -> infer_request ), ret );
342
437
ret = success ;
343
438
fail :
344
439
return ret ;
@@ -349,13 +444,18 @@ get_output(void *ctx, graph_execution_context exec_ctx, uint32_t index,
349
444
tensor_data output_tensor , uint32_t * output_tensor_size )
350
445
{
351
446
OpenVINOContext * ov_ctx = (OpenVINOContext * )ctx ;
447
+ struct OpenVINOExecutionContext * exec ;
352
448
wasi_nn_error ret = unsupported_operation ;
353
449
ov_tensor_t * ov_tensor = NULL ;
354
450
void * data = NULL ;
355
451
size_t byte_size = 0 ;
356
452
453
+ if (exec_ctx >= ov_ctx -> n_execution_contexts )
454
+ return runtime_error ;
455
+ exec = & ov_ctx -> execution_contexts [exec_ctx ];
456
+
357
457
CHECK_OV_STATUS (ov_infer_request_get_output_tensor_by_index (
358
- ov_ctx -> infer_request , index , & ov_tensor ),
458
+ exec -> infer_request , index , & ov_tensor ),
359
459
ret );
360
460
361
461
CHECK_OV_STATUS (ov_tensor_get_byte_size (ov_tensor , & byte_size ), ret );
@@ -421,27 +521,16 @@ __attribute__((visibility("default"))) wasi_nn_error
421
521
deinit_backend (void * ctx )
422
522
{
423
523
OpenVINOContext * ov_ctx = (OpenVINOContext * )ctx ;
524
+ unsigned int i ;
424
525
425
526
if (!ov_ctx )
426
527
return invalid_argument ;
427
528
428
- if (ov_ctx -> weight_data )
429
- os_free (ov_ctx -> weight_data );
430
-
431
- if (ov_ctx -> weights_tensor )
432
- ov_tensor_free (ov_ctx -> weights_tensor );
433
-
434
- if (ov_ctx -> input_tensor )
435
- ov_tensor_free (ov_ctx -> input_tensor );
436
-
437
- if (ov_ctx -> infer_request )
438
- ov_infer_request_free (ov_ctx -> infer_request );
439
-
440
- if (ov_ctx -> compiled_model )
441
- ov_compiled_model_free (ov_ctx -> compiled_model );
529
+ for (i = 0 ; i < ov_ctx -> n_execution_contexts ; i ++ )
530
+ free_execution_context (& ov_ctx -> execution_contexts [i ]);
442
531
443
- if ( ov_ctx -> model )
444
- ov_model_free ( ov_ctx -> model );
532
+ for ( i = 0 ; i < ov_ctx -> n_graphs ; i ++ )
533
+ free_graph ( & ov_ctx -> graphs [ i ] );
445
534
446
535
if (ov_ctx -> core )
447
536
ov_core_free (ov_ctx -> core );
0 commit comments