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.3 kB

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

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