You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

lite_c_interface.cpp 8.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /**
  2. * \file example/cpp_example/basic_c_interface.cpp
  3. * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  4. *
  5. * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
  6. *
  7. * Unless required by applicable law or agreed to in writing,
  8. * software distributed under the License is distributed on an
  9. * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. */
  11. #include "example.h"
  12. #include "misc.h"
  13. #if LITE_BUILD_WITH_MGE
  14. #include "lite-c/global_c.h"
  15. #include "lite-c/network_c.h"
  16. #include "lite-c/tensor_c.h"
  17. #include <thread>
  18. #define LITE_CAPI_CHECK(_expr) \
  19. do { \
  20. int _ret = (_expr); \
  21. if (_ret) { \
  22. LITE_THROW(LITE_get_last_error()); \
  23. } \
  24. } while (0)
  25. bool basic_c_interface(const lite::example::Args& args) {
  26. std::string network_path = args.model_path;
  27. std::string input_path = args.input_path;
  28. //! read input data to lite::tensor
  29. auto src_tensor = lite::example::parse_npy(input_path);
  30. void* src_ptr = src_tensor->get_memory_ptr();
  31. //! create and load the network
  32. LiteNetwork c_network;
  33. LITE_CAPI_CHECK(
  34. LITE_make_network(&c_network, *default_config(), *default_network_io()));
  35. LITE_CAPI_CHECK(LITE_load_model_from_path(c_network, network_path.c_str()));
  36. //! set input data to input tensor
  37. LiteTensor c_input_tensor;
  38. LITE_CAPI_CHECK(LITE_get_io_tensor(c_network, "data", LITE_IO, &c_input_tensor));
  39. void* dst_ptr;
  40. size_t length_in_byte;
  41. LITE_CAPI_CHECK(
  42. LITE_get_tensor_total_size_in_byte(c_input_tensor, &length_in_byte));
  43. LITE_CAPI_CHECK(LITE_get_tensor_memory(c_input_tensor, &dst_ptr));
  44. //! copy or forward data to network
  45. memcpy(dst_ptr, src_ptr, length_in_byte);
  46. //! forward
  47. LITE_CAPI_CHECK(LITE_forward(c_network));
  48. LITE_CAPI_CHECK(LITE_wait(c_network));
  49. //! get the output data or read tensor data
  50. const char* output_name;
  51. LiteTensor c_output_tensor;
  52. //! get the first output tensor name
  53. LITE_CAPI_CHECK(LITE_get_output_name(c_network, 0, &output_name));
  54. LITE_CAPI_CHECK(
  55. LITE_get_io_tensor(c_network, output_name, LITE_IO, &c_output_tensor));
  56. void* output_ptr;
  57. size_t length_output_in_byte;
  58. LITE_CAPI_CHECK(LITE_get_tensor_memory(c_output_tensor, &output_ptr));
  59. LITE_CAPI_CHECK(LITE_get_tensor_total_size_in_byte(
  60. c_output_tensor, &length_output_in_byte));
  61. size_t out_length = length_output_in_byte / sizeof(float);
  62. printf("length=%zu\n", out_length);
  63. float max = -1.0f;
  64. float sum = 0.0f;
  65. for (size_t i = 0; i < out_length; i++) {
  66. float data = static_cast<float*>(output_ptr)[i];
  67. sum += data;
  68. if (max < data)
  69. max = data;
  70. }
  71. printf("max=%e, sum=%e\n", max, sum);
  72. return true;
  73. }
  74. bool device_io_c_interface(const lite::example::Args& args) {
  75. std::string network_path = args.model_path;
  76. std::string input_path = args.input_path;
  77. //! read input data to lite::tensor
  78. auto src_tensor = lite::example::parse_npy(input_path);
  79. void* src_ptr = src_tensor->get_memory_ptr();
  80. size_t length_read_in = src_tensor->get_tensor_total_size_in_byte();
  81. //! create and load the network
  82. LiteNetwork c_network;
  83. LITE_CAPI_CHECK(
  84. LITE_make_network(&c_network, *default_config(), *default_network_io()));
  85. LITE_CAPI_CHECK(LITE_load_model_from_path(c_network, network_path.c_str()));
  86. //! set input data to input tensor
  87. LiteTensor c_input_tensor;
  88. size_t length_tensor_in;
  89. LITE_CAPI_CHECK(LITE_get_io_tensor(c_network, "data", LITE_IO, &c_input_tensor));
  90. LITE_CAPI_CHECK(
  91. LITE_get_tensor_total_size_in_byte(c_input_tensor, &length_tensor_in));
  92. if (length_read_in != length_tensor_in) {
  93. LITE_THROW(
  94. "The input data size is not match the network input tensro "
  95. "size,\n");
  96. }
  97. LITE_CAPI_CHECK(
  98. LITE_reset_tensor_memory(c_input_tensor, src_ptr, length_tensor_in));
  99. //! reset the output tensor memory with user allocated memory
  100. size_t out_length = 1000;
  101. LiteLayout output_layout{{1, 1000}, 2, LiteDataType::LITE_FLOAT};
  102. std::shared_ptr<float> ptr(new float[out_length], [](float* ptr) { delete[] ptr; });
  103. const char* output_name;
  104. LiteTensor c_output_tensor;
  105. LITE_CAPI_CHECK(LITE_get_output_name(c_network, 0, &output_name));
  106. LITE_CAPI_CHECK(
  107. LITE_get_io_tensor(c_network, output_name, LITE_IO, &c_output_tensor));
  108. LITE_CAPI_CHECK(LITE_reset_tensor(c_output_tensor, output_layout, ptr.get()));
  109. //! forward
  110. LITE_CAPI_CHECK(LITE_forward(c_network));
  111. LITE_CAPI_CHECK(LITE_wait(c_network));
  112. printf("length=%zu\n", out_length);
  113. float max = -1.0f;
  114. float sum = 0.0f;
  115. void* out_data = ptr.get();
  116. for (size_t i = 0; i < out_length; i++) {
  117. float data = static_cast<float*>(out_data)[i];
  118. sum += data;
  119. if (max < data)
  120. max = data;
  121. }
  122. printf("max=%e, sum=%e\n", max, sum);
  123. return true;
  124. }
  125. namespace {
  126. volatile bool finished = false;
  127. int async_callback(void) {
  128. #if !__DEPLOY_ON_XP_SP2__
  129. std::cout << "worker thread_id:" << std::this_thread::get_id() << std::endl;
  130. #endif
  131. finished = true;
  132. return 0;
  133. }
  134. } // namespace
  135. bool async_c_interface(const lite::example::Args& args) {
  136. std::string network_path = args.model_path;
  137. std::string input_path = args.input_path;
  138. //! read input data to lite::tensor
  139. auto src_tensor = lite::example::parse_npy(input_path);
  140. void* src_ptr = src_tensor->get_memory_ptr();
  141. LiteNetwork c_network;
  142. LiteConfig config = *default_config();
  143. config.options.var_sanity_check_first_run = false;
  144. LITE_CAPI_CHECK(LITE_make_network(&c_network, config, *default_network_io()));
  145. LITE_CAPI_CHECK(LITE_load_model_from_path(c_network, network_path.c_str()));
  146. //! set input data to input tensor
  147. LiteTensor c_input_tensor;
  148. size_t length_tensor_in;
  149. LITE_CAPI_CHECK(LITE_get_io_tensor(c_network, "data", LITE_IO, &c_input_tensor));
  150. LITE_CAPI_CHECK(
  151. LITE_get_tensor_total_size_in_byte(c_input_tensor, &length_tensor_in));
  152. LITE_CAPI_CHECK(
  153. LITE_reset_tensor_memory(c_input_tensor, src_ptr, length_tensor_in));
  154. #if !__DEPLOY_ON_XP_SP2__
  155. std::cout << "user thread_id:" << std::this_thread::get_id() << std::endl;
  156. #endif
  157. LITE_CAPI_CHECK(LITE_set_async_callback(c_network, async_callback));
  158. //! forward
  159. LITE_CAPI_CHECK(LITE_forward(c_network));
  160. size_t count = 0;
  161. while (finished == false) {
  162. count++;
  163. }
  164. printf("The count is %zu\n", count);
  165. finished = false;
  166. //! get the output data or read tensor data
  167. const char* output_name;
  168. LiteTensor c_output_tensor;
  169. //! get the first output tensor name
  170. LITE_CAPI_CHECK(LITE_get_output_name(c_network, 0, &output_name));
  171. LITE_CAPI_CHECK(
  172. LITE_get_io_tensor(c_network, output_name, LITE_IO, &c_output_tensor));
  173. void* output_ptr;
  174. size_t length_output_in_byte;
  175. LITE_CAPI_CHECK(LITE_get_tensor_memory(c_output_tensor, &output_ptr));
  176. LITE_CAPI_CHECK(LITE_get_tensor_total_size_in_byte(
  177. c_output_tensor, &length_output_in_byte));
  178. size_t out_length = length_output_in_byte / sizeof(float);
  179. printf("length=%zu\n", out_length);
  180. float max = -1.0f;
  181. float sum = 0.0f;
  182. for (size_t i = 0; i < out_length; i++) {
  183. float data = static_cast<float*>(output_ptr)[i];
  184. sum += data;
  185. if (max < data)
  186. max = data;
  187. }
  188. printf("max=%e, sum=%e\n", max, sum);
  189. return true;
  190. }
  191. REGIST_EXAMPLE("basic_c_interface", basic_c_interface);
  192. REGIST_EXAMPLE("device_io_c_interface", device_io_c_interface);
  193. REGIST_EXAMPLE("async_c_interface", async_c_interface);
  194. #endif
  195. // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}