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

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
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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] = {&c};
  46. op->forward_n(op, bottom_blobs, 2, top_blobs, 1, opt);
  47. op->destroy_pipeline(op, opt);
  48. ncnn_layer_destroy(op);
  49. }
  50. // check c == a + b
  51. bool success = false;
  52. if (c)
  53. {
  54. int dims = ncnn_mat_get_dims(c);
  55. int w = ncnn_mat_get_w(c);
  56. const float* c_data = (const float*)ncnn_mat_get_data(c);
  57. success = dims == 1 && w == 2 && c_data[0] == 5.f && c_data[1] == 5.f;
  58. }
  59. ncnn_option_destroy(opt);
  60. ncnn_mat_destroy(a);
  61. ncnn_mat_destroy(b);
  62. ncnn_mat_destroy(c);
  63. if (!success)
  64. {
  65. fprintf(stderr, "test_c_api_0 failed\n");
  66. }
  67. return success ? 0 : -1;
  68. }
  69. static int test_c_api_1()
  70. {
  71. ncnn_mat_t a = ncnn_mat_create_1d(24, NULL);
  72. // set a
  73. {
  74. const float data[] = {
  75. 0, 1, 2, 3, 4, 5, 6, 7,
  76. 10, 11, 12, 13, 14, 15, 16, 17,
  77. 20, 21, 22, 23, 24, 25, 26, 27
  78. };
  79. float* a_data = (float*)ncnn_mat_get_data(a);
  80. memcpy(a_data, data, 24 * sizeof(float));
  81. }
  82. ncnn_mat_t b = ncnn_mat_reshape_3d(a, 4, 2, 3, NULL);
  83. ncnn_mat_t c = 0;
  84. ncnn_option_t opt = ncnn_option_create();
  85. // c = reorg(b, 2)
  86. {
  87. ncnn_layer_t op = ncnn_layer_create_by_type("Reorg");
  88. // load param
  89. {
  90. ncnn_paramdict_t pd = ncnn_paramdict_create();
  91. ncnn_paramdict_set_int(pd, 0, 2); // stride
  92. op->load_param(op, pd);
  93. ncnn_paramdict_destroy(pd);
  94. }
  95. // load model
  96. {
  97. ncnn_modelbin_t mb = ncnn_modelbin_create_from_mat_array(0, 0);
  98. op->load_model(op, mb);
  99. ncnn_modelbin_destroy(mb);
  100. }
  101. op->create_pipeline(op, opt);
  102. op->forward_1(op, b, &c, opt);
  103. op->destroy_pipeline(op, opt);
  104. ncnn_layer_destroy(op);
  105. }
  106. // check c
  107. bool success = false;
  108. if (c)
  109. {
  110. int dims = ncnn_mat_get_dims(c);
  111. int w = ncnn_mat_get_w(c);
  112. int h = ncnn_mat_get_h(c);
  113. int ch = ncnn_mat_get_c(c);
  114. success = dims == 3 && w == 2 && h == 1 && ch == 12;
  115. const float expected[] = {
  116. 0, 2,
  117. 1, 3,
  118. 4, 6,
  119. 5, 7,
  120. 10, 12,
  121. 11, 13,
  122. 14, 16,
  123. 15, 17,
  124. 20, 22,
  125. 21, 23,
  126. 24, 26,
  127. 25, 27
  128. };
  129. ncnn_mat_t c2 = 0;
  130. ncnn_flatten(c, &c2, opt);
  131. const float* c2_data = (const float*)ncnn_mat_get_data(c2);
  132. if (memcmp(c2_data, expected, 24) != 0)
  133. {
  134. success = false;
  135. }
  136. ncnn_mat_destroy(c2);
  137. }
  138. ncnn_option_destroy(opt);
  139. ncnn_mat_destroy(a);
  140. ncnn_mat_destroy(b);
  141. ncnn_mat_destroy(c);
  142. if (!success)
  143. {
  144. fprintf(stderr, "test_c_api_1 failed\n");
  145. }
  146. return success ? 0 : -1;
  147. }
  148. static int mylayer_forward_inplace_1(const ncnn_layer_t layer, ncnn_mat_t bottom_top_blob, const ncnn_option_t opt)
  149. {
  150. int w = ncnn_mat_get_w(bottom_top_blob);
  151. int h = ncnn_mat_get_h(bottom_top_blob);
  152. int channels = ncnn_mat_get_c(bottom_top_blob);
  153. int size = w * h;
  154. #pragma omp parallel for num_threads(ncnn_option_get_num_threads(opt))
  155. for (int q = 0; q < channels; q++)
  156. {
  157. float* ptr = (float*)ncnn_mat_get_channel_data(bottom_top_blob, q);
  158. for (int i = 0; i < size; i++)
  159. {
  160. *ptr = *ptr + 100.f;
  161. ptr++;
  162. }
  163. }
  164. return 0;
  165. }
  166. static ncnn_layer_t mylayer_creator(void* /*userdata*/)
  167. {
  168. ncnn_layer_t layer = ncnn_layer_create();
  169. ncnn_layer_set_one_blob_only(layer, 1);
  170. ncnn_layer_set_support_inplace(layer, 1);
  171. layer->forward_inplace_1 = mylayer_forward_inplace_1;
  172. return layer;
  173. }
  174. static void mylayer_destroyer(ncnn_layer_t layer, void* /*userdata*/)
  175. {
  176. ncnn_layer_destroy(layer);
  177. }
  178. static size_t emptydr_read(ncnn_datareader_t /*dr*/, void* buf, size_t size)
  179. {
  180. memset(buf, 0, size);
  181. return size;
  182. }
  183. static int test_c_api_2()
  184. {
  185. // datareader from empty
  186. ncnn_datareader_t emptydr = ncnn_datareader_create();
  187. {
  188. emptydr->read = emptydr_read;
  189. }
  190. ncnn_option_t opt = ncnn_option_create();
  191. {
  192. ncnn_option_set_num_threads(opt, 1);
  193. }
  194. ncnn_net_t net = ncnn_net_create();
  195. {
  196. ncnn_net_set_option(net, opt);
  197. ncnn_net_register_custom_layer_by_type(net, "MyLayer", mylayer_creator, mylayer_destroyer, 0);
  198. const char param_txt[] = "7767517\n2 2\nInput input 0 1 data\nMyLayer mylayer 1 1 data output\n";
  199. ncnn_net_load_param_memory(net, param_txt);
  200. ncnn_net_load_model_datareader(net, emptydr);
  201. }
  202. ncnn_mat_t a = ncnn_mat_create_1d(24, NULL);
  203. // set a
  204. {
  205. const float data[] = {
  206. 0, 1, 2, 3, 4, 5, 6, 7,
  207. 10, 11, 12, 13, 14, 15, 16, 17,
  208. 20, 21, 22, 23, 24, 25, 26, 27
  209. };
  210. float* a_data = (float*)ncnn_mat_get_data(a);
  211. memcpy(a_data, data, 24 * sizeof(float));
  212. }
  213. ncnn_mat_t b = ncnn_mat_reshape_3d(a, 4, 2, 3, NULL);
  214. ncnn_mat_t c = 0;
  215. {
  216. ncnn_extractor_t ex = ncnn_extractor_create(net);
  217. ncnn_extractor_input(ex, "data", b);
  218. ncnn_extractor_extract(ex, "output", &c);
  219. ncnn_extractor_destroy(ex);
  220. }
  221. ncnn_net_destroy(net);
  222. // check c
  223. bool success = false;
  224. if (c)
  225. {
  226. int dims = ncnn_mat_get_dims(c);
  227. int w = ncnn_mat_get_w(c);
  228. int h = ncnn_mat_get_h(c);
  229. int ch = ncnn_mat_get_c(c);
  230. success = dims == 3 && w == 4 && h == 2 && ch == 3;
  231. const float expected[] = {
  232. 100, 101, 102, 103, 104, 105, 106, 107,
  233. 110, 111, 112, 113, 114, 115, 116, 117,
  234. 120, 121, 122, 123, 124, 125, 126, 127
  235. };
  236. ncnn_mat_t c2 = 0;
  237. ncnn_flatten(c, &c2, opt);
  238. const float* c2_data = (const float*)ncnn_mat_get_data(c2);
  239. if (memcmp(c2_data, expected, 24) != 0)
  240. {
  241. success = false;
  242. }
  243. ncnn_mat_destroy(c2);
  244. }
  245. ncnn_option_destroy(opt);
  246. ncnn_mat_destroy(a);
  247. ncnn_mat_destroy(b);
  248. ncnn_mat_destroy(c);
  249. ncnn_datareader_destroy(emptydr);
  250. if (!success)
  251. {
  252. fprintf(stderr, "test_c_api_2 failed\n");
  253. }
  254. return success ? 0 : -1;
  255. }
  256. int main()
  257. {
  258. return test_c_api_0() || test_c_api_1() || test_c_api_2();
  259. }