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

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

MegEngine 安装包中集成了使用 GPU 运行代码所需的 CUDA 环境,不用区分 CPU 和 GPU 版。 如果想要运行 GPU 程序,请确保机器本身配有 GPU 硬件设备并安装好驱动。 如果你想体验在云端 GPU 算力平台进行深度学习开发的感觉,欢迎访问 MegStudio 平台