utils.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "utils.h"
  6. #include "logger.h"
  7. #include "wasi_nn.h"
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. wasi_nn_error
  11. wasm_load(char *model_name, graph *g, execution_target target)
  12. {
  13. FILE *pFile = fopen(model_name, "r");
  14. if (pFile == NULL)
  15. return invalid_argument;
  16. uint8_t *buffer;
  17. size_t result;
  18. // allocate memory to contain the whole file:
  19. buffer = (uint8_t *)malloc(sizeof(uint8_t) * MAX_MODEL_SIZE);
  20. if (buffer == NULL) {
  21. fclose(pFile);
  22. return too_large;
  23. }
  24. result = fread(buffer, 1, MAX_MODEL_SIZE, pFile);
  25. if (result <= 0) {
  26. fclose(pFile);
  27. free(buffer);
  28. return too_large;
  29. }
  30. graph_builder_array arr;
  31. arr.size = 1;
  32. arr.buf = (graph_builder *)malloc(sizeof(graph_builder));
  33. if (arr.buf == NULL) {
  34. fclose(pFile);
  35. free(buffer);
  36. return too_large;
  37. }
  38. arr.buf[0].size = result;
  39. arr.buf[0].buf = buffer;
  40. wasi_nn_error res = load(&arr, tensorflowlite, target, g);
  41. fclose(pFile);
  42. free(buffer);
  43. free(arr.buf);
  44. return res;
  45. }
  46. wasi_nn_error
  47. wasm_load_by_name(const char *model_name, graph *g)
  48. {
  49. wasi_nn_error res = load_by_name(model_name, strlen(model_name), g);
  50. return res;
  51. }
  52. wasi_nn_error
  53. wasm_init_execution_context(graph g, graph_execution_context *ctx)
  54. {
  55. return init_execution_context(g, ctx);
  56. }
  57. wasi_nn_error
  58. wasm_set_input(graph_execution_context ctx, float *input_tensor, uint32_t *dim)
  59. {
  60. tensor_dimensions dims;
  61. dims.size = INPUT_TENSOR_DIMS;
  62. dims.buf = (uint32_t *)malloc(dims.size * sizeof(uint32_t));
  63. if (dims.buf == NULL)
  64. return too_large;
  65. tensor tensor;
  66. tensor.dimensions = &dims;
  67. for (int i = 0; i < tensor.dimensions->size; ++i)
  68. tensor.dimensions->buf[i] = dim[i];
  69. tensor.type = fp32;
  70. tensor.data = (uint8_t *)input_tensor;
  71. wasi_nn_error err = set_input(ctx, 0, &tensor);
  72. free(dims.buf);
  73. return err;
  74. }
  75. wasi_nn_error
  76. wasm_compute(graph_execution_context ctx)
  77. {
  78. return compute(ctx);
  79. }
  80. wasi_nn_error
  81. wasm_get_output(graph_execution_context ctx, uint32_t index, float *out_tensor,
  82. uint32_t *out_size)
  83. {
  84. return get_output(ctx, index, (uint8_t *)out_tensor, out_size);
  85. }
  86. float *
  87. run_inference(execution_target target, float *input, uint32_t *input_size,
  88. uint32_t *output_size, char *model_name,
  89. uint32_t num_output_tensors)
  90. {
  91. graph graph;
  92. if (wasm_load_by_name(model_name, &graph) != success) {
  93. NN_ERR_PRINTF("Error when loading model.");
  94. exit(1);
  95. }
  96. graph_execution_context ctx;
  97. if (wasm_init_execution_context(graph, &ctx) != success) {
  98. NN_ERR_PRINTF("Error when initialixing execution context.");
  99. exit(1);
  100. }
  101. if (wasm_set_input(ctx, input, input_size) != success) {
  102. NN_ERR_PRINTF("Error when setting input tensor.");
  103. exit(1);
  104. }
  105. if (wasm_compute(ctx) != success) {
  106. NN_ERR_PRINTF("Error when running inference.");
  107. exit(1);
  108. }
  109. float *out_tensor = (float *)malloc(sizeof(float) * MAX_OUTPUT_TENSOR_SIZE);
  110. if (out_tensor == NULL) {
  111. NN_ERR_PRINTF("Error when allocating memory for output tensor.");
  112. exit(1);
  113. }
  114. uint32_t offset = 0;
  115. for (int i = 0; i < num_output_tensors; ++i) {
  116. *output_size = MAX_OUTPUT_TENSOR_SIZE - *output_size;
  117. if (wasm_get_output(ctx, i, &out_tensor[offset], output_size)
  118. != success) {
  119. NN_ERR_PRINTF("Error when getting index %d.", i);
  120. break;
  121. }
  122. offset += *output_size;
  123. }
  124. *output_size = offset;
  125. return out_tensor;
  126. }
  127. input_info
  128. create_input(int *dims)
  129. {
  130. input_info input = { .dim = NULL, .input_tensor = NULL, .elements = 1 };
  131. input.dim = malloc(INPUT_TENSOR_DIMS * sizeof(uint32_t));
  132. if (input.dim)
  133. for (int i = 0; i < INPUT_TENSOR_DIMS; ++i) {
  134. input.dim[i] = dims[i];
  135. input.elements *= dims[i];
  136. }
  137. input.input_tensor = malloc(input.elements * sizeof(float));
  138. for (int i = 0; i < input.elements; ++i)
  139. input.input_tensor[i] = i;
  140. return input;
  141. }