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.

test_c_api.cpp 8.6 kB

5 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. // Tencent is pleased to support the open source community by making ncnn available.
  2. //
  3. // Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
  4. //
  5. // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // https://opensource.org/licenses/BSD-3-Clause
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #include <string.h>
  15. #include "c_api.h"
  16. static int test_c_api_0()
  17. {
  18. ncnn_mat_t a = ncnn_mat_create_1d(2, NULL);
  19. ncnn_mat_t b = ncnn_mat_create_1d(2, NULL);
  20. ncnn_mat_t c = 0;
  21. ncnn_option_t opt = ncnn_option_create();
  22. // set a and b
  23. {
  24. ncnn_mat_fill_float(a, 2.f);
  25. ncnn_mat_fill_float(b, 3.f);
  26. }
  27. // c = a + b
  28. {
  29. ncnn_layer_t op = ncnn_layer_create_by_type("BinaryOp");
  30. // load param
  31. {
  32. ncnn_paramdict_t pd = ncnn_paramdict_create();
  33. ncnn_paramdict_set_int(pd, 0, 0); // op_type = ADD
  34. op->load_param(op, pd);
  35. ncnn_paramdict_destroy(pd);
  36. }
  37. // load model
  38. {
  39. ncnn_modelbin_t mb = ncnn_modelbin_create_from_mat_array(0, 0);
  40. op->load_model(op, mb);
  41. ncnn_modelbin_destroy(mb);
  42. }
  43. op->create_pipeline(op, opt);
  44. const ncnn_mat_t bottom_blobs[2] = {a, b};
  45. ncnn_mat_t top_blobs[1] = {0};
  46. op->forward_n(op, bottom_blobs, 2, top_blobs, 1, opt);
  47. c = top_blobs[0];
  48. op->destroy_pipeline(op, opt);
  49. ncnn_layer_destroy(op);
  50. }
  51. // check c == a + b
  52. bool success = false;
  53. if (c)
  54. {
  55. int dims = ncnn_mat_get_dims(c);
  56. int w = ncnn_mat_get_w(c);
  57. const float* c_data = (const float*)ncnn_mat_get_data(c);
  58. success = dims == 1 && w == 2 && c_data[0] == 5.f && c_data[1] == 5.f;
  59. }
  60. ncnn_option_destroy(opt);
  61. ncnn_mat_destroy(a);
  62. ncnn_mat_destroy(b);
  63. ncnn_mat_destroy(c);
  64. if (!success)
  65. {
  66. fprintf(stderr, "test_c_api_0 failed\n");
  67. }
  68. return success ? 0 : -1;
  69. }
  70. static int test_c_api_1()
  71. {
  72. ncnn_mat_t a = ncnn_mat_create_1d(24, NULL);
  73. // set a
  74. {
  75. const float data[] = {
  76. 0, 1, 2, 3, 4, 5, 6, 7,
  77. 10, 11, 12, 13, 14, 15, 16, 17,
  78. 20, 21, 22, 23, 24, 25, 26, 27
  79. };
  80. float* a_data = (float*)ncnn_mat_get_data(a);
  81. memcpy(a_data, data, 24 * sizeof(float));
  82. }
  83. ncnn_mat_t b = ncnn_mat_reshape_3d(a, 4, 2, 3, NULL);
  84. ncnn_mat_t c = 0;
  85. ncnn_option_t opt = ncnn_option_create();
  86. // c = reorg(b, 2)
  87. {
  88. ncnn_layer_t op = ncnn_layer_create_by_type("Reorg");
  89. // load param
  90. {
  91. ncnn_paramdict_t pd = ncnn_paramdict_create();
  92. ncnn_paramdict_set_int(pd, 0, 2); // stride
  93. op->load_param(op, pd);
  94. ncnn_paramdict_destroy(pd);
  95. }
  96. // load model
  97. {
  98. ncnn_modelbin_t mb = ncnn_modelbin_create_from_mat_array(0, 0);
  99. op->load_model(op, mb);
  100. ncnn_modelbin_destroy(mb);
  101. }
  102. op->create_pipeline(op, opt);
  103. op->forward_1(op, b, &c, opt);
  104. op->destroy_pipeline(op, opt);
  105. ncnn_layer_destroy(op);
  106. }
  107. // check c
  108. bool success = false;
  109. if (c)
  110. {
  111. int dims = ncnn_mat_get_dims(c);
  112. int w = ncnn_mat_get_w(c);
  113. int h = ncnn_mat_get_h(c);
  114. int ch = ncnn_mat_get_c(c);
  115. success = dims == 3 && w == 2 && h == 1 && ch == 12;
  116. const float expected[] = {
  117. 0, 2,
  118. 1, 3,
  119. 4, 6,
  120. 5, 7,
  121. 10, 12,
  122. 11, 13,
  123. 14, 16,
  124. 15, 17,
  125. 20, 22,
  126. 21, 23,
  127. 24, 26,
  128. 25, 27
  129. };
  130. ncnn_mat_t c2 = 0;
  131. ncnn_flatten(c, &c2, opt);
  132. const float* c2_data = (const float*)ncnn_mat_get_data(c2);
  133. if (memcmp(c2_data, expected, 24) != 0)
  134. {
  135. success = false;
  136. }
  137. ncnn_mat_destroy(c2);
  138. }
  139. ncnn_option_destroy(opt);
  140. ncnn_mat_destroy(a);
  141. ncnn_mat_destroy(b);
  142. ncnn_mat_destroy(c);
  143. if (!success)
  144. {
  145. fprintf(stderr, "test_c_api_1 failed\n");
  146. }
  147. return success ? 0 : -1;
  148. }
  149. static int mylayer_forward_inplace_1(const ncnn_layer_t layer, ncnn_mat_t bottom_top_blob, const ncnn_option_t opt)
  150. {
  151. int w = ncnn_mat_get_w(bottom_top_blob);
  152. int h = ncnn_mat_get_h(bottom_top_blob);
  153. int channels = ncnn_mat_get_c(bottom_top_blob);
  154. int size = w * h;
  155. #pragma omp parallel for num_threads(ncnn_option_get_num_threads(opt))
  156. for (int q = 0; q < channels; q++)
  157. {
  158. float* ptr = (float*)ncnn_mat_get_channel_data(bottom_top_blob, q);
  159. for (int i = 0; i < size; i++)
  160. {
  161. *ptr = *ptr + 100.f;
  162. ptr++;
  163. }
  164. }
  165. return 0;
  166. }
  167. static ncnn_layer_t mylayer_creator(void* /*userdata*/)
  168. {
  169. ncnn_layer_t layer = ncnn_layer_create();
  170. ncnn_layer_set_one_blob_only(layer, 1);
  171. ncnn_layer_set_support_inplace(layer, 1);
  172. layer->forward_inplace_1 = mylayer_forward_inplace_1;
  173. return layer;
  174. }
  175. static void mylayer_destroyer(ncnn_layer_t layer, void* /*userdata*/)
  176. {
  177. ncnn_layer_destroy(layer);
  178. }
  179. static size_t emptydr_read(ncnn_datareader_t /*dr*/, void* buf, size_t size)
  180. {
  181. memset(buf, 0, size);
  182. return size;
  183. }
  184. static int test_c_api_2()
  185. {
  186. // datareader from empty
  187. ncnn_datareader_t emptydr = ncnn_datareader_create();
  188. {
  189. emptydr->read = emptydr_read;
  190. }
  191. ncnn_allocator_t blob_allocator = ncnn_allocator_create_pool_allocator();
  192. ncnn_allocator_t workspace_allocator = ncnn_allocator_create_unlocked_pool_allocator();
  193. ncnn_option_t opt = ncnn_option_create();
  194. {
  195. ncnn_option_set_num_threads(opt, 1);
  196. ncnn_option_set_blob_allocator(opt, blob_allocator);
  197. ncnn_option_set_workspace_allocator(opt, workspace_allocator);
  198. }
  199. ncnn_net_t net = ncnn_net_create();
  200. {
  201. ncnn_net_set_option(net, opt);
  202. ncnn_net_register_custom_layer_by_type(net, "MyLayer", mylayer_creator, mylayer_destroyer, 0);
  203. const char param_txt[] = "7767517\n2 2\nInput input 0 1 data\nMyLayer mylayer 1 1 data output\n";
  204. ncnn_net_load_param_memory(net, param_txt);
  205. ncnn_net_load_model_datareader(net, emptydr);
  206. }
  207. ncnn_mat_t a = ncnn_mat_create_1d(24, blob_allocator);
  208. // set a
  209. {
  210. const float data[] = {
  211. 0, 1, 2, 3, 4, 5, 6, 7,
  212. 10, 11, 12, 13, 14, 15, 16, 17,
  213. 20, 21, 22, 23, 24, 25, 26, 27
  214. };
  215. float* a_data = (float*)ncnn_mat_get_data(a);
  216. memcpy(a_data, data, 24 * sizeof(float));
  217. }
  218. ncnn_mat_t b = ncnn_mat_reshape_3d(a, 4, 2, 3, blob_allocator);
  219. ncnn_mat_t c = 0;
  220. {
  221. ncnn_extractor_t ex = ncnn_extractor_create(net);
  222. ncnn_extractor_input(ex, "data", b);
  223. ncnn_extractor_extract(ex, "output", &c);
  224. ncnn_extractor_destroy(ex);
  225. }
  226. ncnn_net_destroy(net);
  227. // check c
  228. bool success = false;
  229. if (c)
  230. {
  231. int dims = ncnn_mat_get_dims(c);
  232. int w = ncnn_mat_get_w(c);
  233. int h = ncnn_mat_get_h(c);
  234. int ch = ncnn_mat_get_c(c);
  235. success = dims == 3 && w == 4 && h == 2 && ch == 3;
  236. const float expected[] = {
  237. 100, 101, 102, 103, 104, 105, 106, 107,
  238. 110, 111, 112, 113, 114, 115, 116, 117,
  239. 120, 121, 122, 123, 124, 125, 126, 127
  240. };
  241. ncnn_mat_t c2 = 0;
  242. ncnn_flatten(c, &c2, opt);
  243. const float* c2_data = (const float*)ncnn_mat_get_data(c2);
  244. if (memcmp(c2_data, expected, 24) != 0)
  245. {
  246. success = false;
  247. }
  248. ncnn_mat_destroy(c2);
  249. }
  250. ncnn_mat_destroy(a);
  251. ncnn_mat_destroy(b);
  252. ncnn_mat_destroy(c);
  253. ncnn_option_destroy(opt);
  254. ncnn_allocator_destroy(blob_allocator);
  255. ncnn_allocator_destroy(workspace_allocator);
  256. ncnn_datareader_destroy(emptydr);
  257. if (!success)
  258. {
  259. fprintf(stderr, "test_c_api_2 failed\n");
  260. }
  261. return success ? 0 : -1;
  262. }
  263. int main()
  264. {
  265. return test_c_api_0() || test_c_api_1() || test_c_api_2();
  266. }