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.

mat.cpp 40 kB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707
  1. // Copyright 2017 Tencent
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. #include "mat.h"
  4. #include "layer.h"
  5. #include "layer_type.h"
  6. #if NCNN_VULKAN
  7. #if NCNN_PLATFORM_API
  8. #if __ANDROID_API__ >= 26
  9. #include <android/hardware_buffer.h>
  10. #endif // __ANDROID_API__ >= 26
  11. #endif // NCNN_PLATFORM_API
  12. #endif // NCNN_VULKAN
  13. namespace ncnn {
  14. Mat Mat::clone(Allocator* _allocator) const
  15. {
  16. if (empty())
  17. return Mat();
  18. Mat m;
  19. if (dims == 1)
  20. m.create(w, elemsize, elempack, _allocator);
  21. else if (dims == 2)
  22. m.create(w, h, elemsize, elempack, _allocator);
  23. else if (dims == 3)
  24. m.create(w, h, c, elemsize, elempack, _allocator);
  25. else if (dims == 4)
  26. m.create(w, h, d, c, elemsize, elempack, _allocator);
  27. if (m.empty())
  28. return m;
  29. if (total() > 0)
  30. {
  31. if (cstep == m.cstep)
  32. memcpy(m.data, data, total() * elemsize);
  33. else
  34. {
  35. // copy by channel for differnet cstep
  36. size_t size = (size_t)w * h * d * elemsize;
  37. for (int i = 0; i < c; i++)
  38. {
  39. memcpy(m.channel(i), channel(i), size);
  40. }
  41. }
  42. }
  43. return m;
  44. }
  45. void Mat::clone_from(const ncnn::Mat& mat, Allocator* allocator)
  46. {
  47. *this = mat.clone(allocator);
  48. }
  49. Mat Mat::reshape(int _w, Allocator* _allocator) const
  50. {
  51. if (w * h * d * c != _w)
  52. return Mat();
  53. if (dims >= 3 && cstep != (size_t)w * h * d)
  54. {
  55. Mat m;
  56. m.create(_w, elemsize, elempack, _allocator);
  57. if (m.empty())
  58. return m;
  59. // flatten
  60. for (int i = 0; i < c; i++)
  61. {
  62. const void* ptr = (unsigned char*)data + i * cstep * elemsize;
  63. void* mptr = (unsigned char*)m.data + i * (size_t)w * h * d * elemsize;
  64. memcpy(mptr, ptr, (size_t)w * h * d * elemsize);
  65. }
  66. return m;
  67. }
  68. Mat m = *this;
  69. m.dims = 1;
  70. m.w = _w;
  71. m.h = 1;
  72. m.d = 1;
  73. m.c = 1;
  74. m.cstep = alignSize(_w * elemsize, 16) / elemsize;
  75. return m;
  76. }
  77. Mat Mat::reshape(int _w, int _h, Allocator* _allocator) const
  78. {
  79. if (w * h * d * c != _w * _h)
  80. return Mat();
  81. if (dims >= 3 && cstep != (size_t)w * h * d)
  82. {
  83. Mat m;
  84. m.create(_w, _h, elemsize, elempack, _allocator);
  85. if (m.empty())
  86. return m;
  87. // flatten
  88. for (int i = 0; i < c; i++)
  89. {
  90. const void* ptr = (unsigned char*)data + i * cstep * elemsize;
  91. void* mptr = (unsigned char*)m.data + i * (size_t)w * h * d * elemsize;
  92. memcpy(mptr, ptr, (size_t)w * h * d * elemsize);
  93. }
  94. return m;
  95. }
  96. Mat m = *this;
  97. m.dims = 2;
  98. m.w = _w;
  99. m.h = _h;
  100. m.d = 1;
  101. m.c = 1;
  102. m.cstep = alignSize((size_t)_w * _h * elemsize, 16) / elemsize;
  103. return m;
  104. }
  105. Mat Mat::reshape(int _w, int _h, int _c, Allocator* _allocator) const
  106. {
  107. if (w * h * d * c != _w * _h * _c)
  108. return Mat();
  109. if (dims < 3)
  110. {
  111. if ((size_t)_w * _h != alignSize((size_t)_w * _h * elemsize, 16) / elemsize)
  112. {
  113. Mat m;
  114. m.create(_w, _h, _c, elemsize, elempack, _allocator);
  115. if (m.empty())
  116. return m;
  117. // align channel
  118. for (int i = 0; i < _c; i++)
  119. {
  120. const void* ptr = (unsigned char*)data + i * (size_t)_w * _h * elemsize;
  121. void* mptr = (unsigned char*)m.data + i * m.cstep * m.elemsize;
  122. memcpy(mptr, ptr, (size_t)_w * _h * elemsize);
  123. }
  124. return m;
  125. }
  126. }
  127. else if (c != _c)
  128. {
  129. // flatten and then align
  130. Mat tmp = reshape(_w * _h * _c, _allocator);
  131. return tmp.reshape(_w, _h, _c, _allocator);
  132. }
  133. Mat m = *this;
  134. m.dims = 3;
  135. m.w = _w;
  136. m.h = _h;
  137. m.d = 1;
  138. m.c = _c;
  139. m.cstep = alignSize((size_t)_w * _h * elemsize, 16) / elemsize;
  140. return m;
  141. }
  142. Mat Mat::reshape(int _w, int _h, int _d, int _c, Allocator* _allocator) const
  143. {
  144. if (w * h * d * c != _w * _h * _d * _c)
  145. return Mat();
  146. if (dims < 3)
  147. {
  148. if ((size_t)_w * _h * _d != alignSize((size_t)_w * _h * _d * elemsize, 16) / elemsize)
  149. {
  150. Mat m;
  151. m.create(_w, _h, _d, _c, elemsize, elempack, _allocator);
  152. if (m.empty())
  153. return m;
  154. // align channel
  155. for (int i = 0; i < _c; i++)
  156. {
  157. const void* ptr = (unsigned char*)data + i * (size_t)_w * _h * _d * elemsize;
  158. void* mptr = (unsigned char*)m.data + i * m.cstep * m.elemsize;
  159. memcpy(mptr, ptr, (size_t)_w * _h * _d * elemsize);
  160. }
  161. return m;
  162. }
  163. }
  164. else if (c != _c)
  165. {
  166. // flatten and then align
  167. Mat tmp = reshape(_w * _h * _d * _c, _allocator);
  168. return tmp.reshape(_w, _h, _d, _c, _allocator);
  169. }
  170. Mat m = *this;
  171. m.dims = 4;
  172. m.w = _w;
  173. m.h = _h;
  174. m.d = _d;
  175. m.c = _c;
  176. m.cstep = alignSize((size_t)_w * _h * _d * elemsize, 16) / elemsize;
  177. return m;
  178. }
  179. void Mat::create(int _w, size_t _elemsize, Allocator* _allocator)
  180. {
  181. if (dims == 1 && w == _w && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  182. return;
  183. release();
  184. elemsize = _elemsize;
  185. elempack = 1;
  186. allocator = _allocator;
  187. dims = 1;
  188. w = _w;
  189. h = 1;
  190. d = 1;
  191. c = 1;
  192. cstep = alignSize(w * elemsize, 16) / elemsize;
  193. size_t totalsize = alignSize(total() * elemsize, 4);
  194. if (totalsize > 0)
  195. {
  196. if (allocator)
  197. data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
  198. else
  199. data = fastMalloc(totalsize + (int)sizeof(*refcount));
  200. }
  201. if (data)
  202. {
  203. refcount = (int*)(((unsigned char*)data) + totalsize);
  204. *refcount = 1;
  205. }
  206. }
  207. void Mat::create(int _w, int _h, size_t _elemsize, Allocator* _allocator)
  208. {
  209. if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  210. return;
  211. release();
  212. elemsize = _elemsize;
  213. elempack = 1;
  214. allocator = _allocator;
  215. dims = 2;
  216. w = _w;
  217. h = _h;
  218. d = 1;
  219. c = 1;
  220. cstep = alignSize((size_t)w * h * elemsize, 16) / elemsize;
  221. size_t totalsize = alignSize(total() * elemsize, 4);
  222. if (totalsize > 0)
  223. {
  224. if (allocator)
  225. data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
  226. else
  227. data = fastMalloc(totalsize + (int)sizeof(*refcount));
  228. }
  229. if (data)
  230. {
  231. refcount = (int*)(((unsigned char*)data) + totalsize);
  232. *refcount = 1;
  233. }
  234. }
  235. void Mat::create(int _w, int _h, int _c, size_t _elemsize, Allocator* _allocator)
  236. {
  237. if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  238. return;
  239. release();
  240. elemsize = _elemsize;
  241. elempack = 1;
  242. allocator = _allocator;
  243. dims = 3;
  244. w = _w;
  245. h = _h;
  246. d = 1;
  247. c = _c;
  248. cstep = alignSize((size_t)w * h * elemsize, 16) / elemsize;
  249. size_t totalsize = alignSize(total() * elemsize, 4);
  250. if (totalsize > 0)
  251. {
  252. if (allocator)
  253. data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
  254. else
  255. data = fastMalloc(totalsize + (int)sizeof(*refcount));
  256. }
  257. if (data)
  258. {
  259. refcount = (int*)(((unsigned char*)data) + totalsize);
  260. *refcount = 1;
  261. }
  262. }
  263. void Mat::create(int _w, int _h, int _d, int _c, size_t _elemsize, Allocator* _allocator)
  264. {
  265. if (dims == 4 && w == _w && h == _h && d == _d && c == _c && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  266. return;
  267. release();
  268. elemsize = _elemsize;
  269. elempack = 1;
  270. allocator = _allocator;
  271. dims = 4;
  272. w = _w;
  273. h = _h;
  274. d = _d;
  275. c = _c;
  276. cstep = alignSize((size_t)w * h * d * elemsize, 16) / elemsize;
  277. size_t totalsize = alignSize(total() * elemsize, 4);
  278. if (totalsize > 0)
  279. {
  280. if (allocator)
  281. data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
  282. else
  283. data = fastMalloc(totalsize + (int)sizeof(*refcount));
  284. }
  285. if (data)
  286. {
  287. refcount = (int*)(((unsigned char*)data) + totalsize);
  288. *refcount = 1;
  289. }
  290. }
  291. void Mat::create(int _w, size_t _elemsize, int _elempack, Allocator* _allocator)
  292. {
  293. if (dims == 1 && w == _w && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  294. return;
  295. release();
  296. elemsize = _elemsize;
  297. elempack = _elempack;
  298. allocator = _allocator;
  299. dims = 1;
  300. w = _w;
  301. h = 1;
  302. d = 1;
  303. c = 1;
  304. cstep = alignSize(w * elemsize, 16) / elemsize;
  305. size_t totalsize = alignSize(total() * elemsize, 4);
  306. if (totalsize > 0)
  307. {
  308. if (allocator)
  309. data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
  310. else
  311. data = fastMalloc(totalsize + (int)sizeof(*refcount));
  312. }
  313. if (data)
  314. {
  315. refcount = (int*)(((unsigned char*)data) + totalsize);
  316. *refcount = 1;
  317. }
  318. }
  319. void Mat::create(int _w, int _h, size_t _elemsize, int _elempack, Allocator* _allocator)
  320. {
  321. if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  322. return;
  323. release();
  324. elemsize = _elemsize;
  325. elempack = _elempack;
  326. allocator = _allocator;
  327. dims = 2;
  328. w = _w;
  329. h = _h;
  330. d = 1;
  331. c = 1;
  332. cstep = alignSize((size_t)w * h * elemsize, 16) / elemsize;
  333. size_t totalsize = alignSize(total() * elemsize, 4);
  334. if (totalsize > 0)
  335. {
  336. if (allocator)
  337. data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
  338. else
  339. data = fastMalloc(totalsize + (int)sizeof(*refcount));
  340. }
  341. if (data)
  342. {
  343. refcount = (int*)(((unsigned char*)data) + totalsize);
  344. *refcount = 1;
  345. }
  346. }
  347. void Mat::create(int _w, int _h, int _c, size_t _elemsize, int _elempack, Allocator* _allocator)
  348. {
  349. if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  350. return;
  351. release();
  352. elemsize = _elemsize;
  353. elempack = _elempack;
  354. allocator = _allocator;
  355. dims = 3;
  356. w = _w;
  357. h = _h;
  358. d = 1;
  359. c = _c;
  360. cstep = alignSize((size_t)w * h * elemsize, 16) / elemsize;
  361. size_t totalsize = alignSize(total() * elemsize, 4);
  362. if (totalsize > 0)
  363. {
  364. if (allocator)
  365. data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
  366. else
  367. data = fastMalloc(totalsize + (int)sizeof(*refcount));
  368. }
  369. if (data)
  370. {
  371. refcount = (int*)(((unsigned char*)data) + totalsize);
  372. *refcount = 1;
  373. }
  374. }
  375. void Mat::create(int _w, int _h, int _d, int _c, size_t _elemsize, int _elempack, Allocator* _allocator)
  376. {
  377. if (dims == 4 && w == _w && h == _h && d == _d && c == _c && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  378. return;
  379. release();
  380. elemsize = _elemsize;
  381. elempack = _elempack;
  382. allocator = _allocator;
  383. dims = 4;
  384. w = _w;
  385. h = _h;
  386. d = _d;
  387. c = _c;
  388. cstep = alignSize((size_t)w * h * d * elemsize, 16) / elemsize;
  389. size_t totalsize = alignSize(total() * elemsize, 4);
  390. if (totalsize > 0)
  391. {
  392. if (allocator)
  393. data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount));
  394. else
  395. data = fastMalloc(totalsize + (int)sizeof(*refcount));
  396. }
  397. if (data)
  398. {
  399. refcount = (int*)(((unsigned char*)data) + totalsize);
  400. *refcount = 1;
  401. }
  402. }
  403. void Mat::create_like(const Mat& m, Allocator* _allocator)
  404. {
  405. int _dims = m.dims;
  406. if (_dims == 1)
  407. create(m.w, m.elemsize, m.elempack, _allocator);
  408. if (_dims == 2)
  409. create(m.w, m.h, m.elemsize, m.elempack, _allocator);
  410. if (_dims == 3)
  411. create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator);
  412. if (_dims == 4)
  413. create(m.w, m.h, m.d, m.c, m.elemsize, m.elempack, _allocator);
  414. }
  415. #if NCNN_VULKAN
  416. void Mat::create_like(const VkMat& m, Allocator* _allocator)
  417. {
  418. int _dims = m.dims;
  419. if (_dims == 1)
  420. create(m.w, m.elemsize, m.elempack, _allocator);
  421. if (_dims == 2)
  422. create(m.w, m.h, m.elemsize, m.elempack, _allocator);
  423. if (_dims == 3)
  424. create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator);
  425. if (_dims == 4)
  426. create(m.w, m.h, m.d, m.c, m.elemsize, m.elempack, _allocator);
  427. }
  428. void Mat::create_like(const VkImageMat& im, Allocator* _allocator)
  429. {
  430. int _dims = im.dims;
  431. if (_dims == 1)
  432. create(im.w, im.elemsize, im.elempack, _allocator);
  433. if (_dims == 2)
  434. create(im.w, im.h, im.elemsize, im.elempack, _allocator);
  435. if (_dims == 3)
  436. create(im.w, im.h, im.c, im.elemsize, im.elempack, _allocator);
  437. if (_dims == 4)
  438. create(im.w, im.h, im.d, im.c, im.elemsize, im.elempack, _allocator);
  439. }
  440. #endif // NCNN_VULKAN
  441. #if NCNN_VULKAN
  442. void VkMat::create(int _w, size_t _elemsize, VkAllocator* _allocator)
  443. {
  444. if (dims == 1 && w == _w && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  445. return;
  446. release();
  447. elemsize = _elemsize;
  448. elempack = 1;
  449. allocator = _allocator;
  450. dims = 1;
  451. w = _w;
  452. h = 1;
  453. d = 1;
  454. c = 1;
  455. cstep = alignSize(w * elemsize, 16) / elemsize;
  456. if (total() > 0)
  457. {
  458. size_t totalsize = alignSize(total() * elemsize, 4);
  459. data = allocator->fastMalloc(totalsize);
  460. }
  461. if (data)
  462. {
  463. refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
  464. *refcount = 1;
  465. }
  466. }
  467. void VkMat::create(int _w, int _h, size_t _elemsize, VkAllocator* _allocator)
  468. {
  469. if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  470. return;
  471. release();
  472. elemsize = _elemsize;
  473. elempack = 1;
  474. allocator = _allocator;
  475. dims = 2;
  476. w = _w;
  477. h = _h;
  478. d = 1;
  479. c = 1;
  480. cstep = alignSize((size_t)w * h * elemsize, 16) / elemsize;
  481. if (total() > 0)
  482. {
  483. size_t totalsize = alignSize(total() * elemsize, 4);
  484. data = allocator->fastMalloc(totalsize);
  485. }
  486. if (data)
  487. {
  488. refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
  489. *refcount = 1;
  490. }
  491. }
  492. void VkMat::create(int _w, int _h, int _c, size_t _elemsize, VkAllocator* _allocator)
  493. {
  494. if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  495. return;
  496. release();
  497. elemsize = _elemsize;
  498. elempack = 1;
  499. allocator = _allocator;
  500. dims = 3;
  501. w = _w;
  502. h = _h;
  503. d = 1;
  504. c = _c;
  505. cstep = alignSize((size_t)w * h * elemsize, 16) / elemsize;
  506. if (total() > 0)
  507. {
  508. size_t totalsize = alignSize(total() * elemsize, 4);
  509. data = allocator->fastMalloc(totalsize);
  510. }
  511. if (data)
  512. {
  513. refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
  514. *refcount = 1;
  515. }
  516. }
  517. void VkMat::create(int _w, int _h, int _d, int _c, size_t _elemsize, VkAllocator* _allocator)
  518. {
  519. if (dims == 4 && w == _w && h == _h && d == _d && c == _c && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  520. return;
  521. release();
  522. elemsize = _elemsize;
  523. elempack = 1;
  524. allocator = _allocator;
  525. dims = 4;
  526. w = _w;
  527. h = _h;
  528. d = _d;
  529. c = _c;
  530. cstep = alignSize((size_t)w * h * d * elemsize, 16) / elemsize;
  531. if (total() > 0)
  532. {
  533. size_t totalsize = alignSize(total() * elemsize, 4);
  534. data = allocator->fastMalloc(totalsize);
  535. }
  536. if (data)
  537. {
  538. refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
  539. *refcount = 1;
  540. }
  541. }
  542. void VkMat::create(int _w, size_t _elemsize, int _elempack, VkAllocator* _allocator)
  543. {
  544. if (dims == 1 && w == _w && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  545. return;
  546. release();
  547. elemsize = _elemsize;
  548. elempack = _elempack;
  549. allocator = _allocator;
  550. dims = 1;
  551. w = _w;
  552. h = 1;
  553. d = 1;
  554. c = 1;
  555. cstep = alignSize(w * elemsize, 16) / elemsize;
  556. if (total() > 0)
  557. {
  558. size_t totalsize = alignSize(total() * elemsize, 4);
  559. data = allocator->fastMalloc(totalsize);
  560. }
  561. if (data)
  562. {
  563. refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
  564. *refcount = 1;
  565. }
  566. }
  567. void VkMat::create(int _w, int _h, size_t _elemsize, int _elempack, VkAllocator* _allocator)
  568. {
  569. if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  570. return;
  571. release();
  572. elemsize = _elemsize;
  573. elempack = _elempack;
  574. allocator = _allocator;
  575. dims = 2;
  576. w = _w;
  577. h = _h;
  578. d = 1;
  579. c = 1;
  580. cstep = alignSize((size_t)w * h * elemsize, 16) / elemsize;
  581. if (total() > 0)
  582. {
  583. size_t totalsize = alignSize(total() * elemsize, 4);
  584. data = allocator->fastMalloc(totalsize);
  585. }
  586. if (data)
  587. {
  588. refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
  589. *refcount = 1;
  590. }
  591. }
  592. void VkMat::create(int _w, int _h, int _c, size_t _elemsize, int _elempack, VkAllocator* _allocator)
  593. {
  594. if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  595. return;
  596. release();
  597. elemsize = _elemsize;
  598. elempack = _elempack;
  599. allocator = _allocator;
  600. dims = 3;
  601. w = _w;
  602. h = _h;
  603. d = 1;
  604. c = _c;
  605. cstep = alignSize((size_t)w * h * elemsize, 16) / elemsize;
  606. if (total() > 0)
  607. {
  608. size_t totalsize = alignSize(total() * elemsize, 4);
  609. data = allocator->fastMalloc(totalsize);
  610. }
  611. if (data)
  612. {
  613. refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
  614. *refcount = 1;
  615. }
  616. }
  617. void VkMat::create(int _w, int _h, int _d, int _c, size_t _elemsize, int _elempack, VkAllocator* _allocator)
  618. {
  619. if (dims == 4 && w == _w && h == _h && d == _d && c == _c && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  620. return;
  621. release();
  622. elemsize = _elemsize;
  623. elempack = _elempack;
  624. allocator = _allocator;
  625. dims = 4;
  626. w = _w;
  627. h = _h;
  628. d = _d;
  629. c = _c;
  630. cstep = alignSize((size_t)w * h * d * elemsize, 16) / elemsize;
  631. if (total() > 0)
  632. {
  633. size_t totalsize = alignSize(total() * elemsize, 4);
  634. data = allocator->fastMalloc(totalsize);
  635. }
  636. if (data)
  637. {
  638. refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount));
  639. *refcount = 1;
  640. }
  641. }
  642. void VkMat::create_like(const Mat& m, VkAllocator* _allocator)
  643. {
  644. int _dims = m.dims;
  645. if (_dims == 1)
  646. create(m.w, m.elemsize, m.elempack, _allocator);
  647. if (_dims == 2)
  648. create(m.w, m.h, m.elemsize, m.elempack, _allocator);
  649. if (_dims == 3)
  650. create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator);
  651. if (_dims == 4)
  652. create(m.w, m.h, m.d, m.c, m.elemsize, m.elempack, _allocator);
  653. }
  654. void VkMat::create_like(const VkMat& m, VkAllocator* _allocator)
  655. {
  656. int _dims = m.dims;
  657. if (_dims == 1)
  658. create(m.w, m.elemsize, m.elempack, _allocator);
  659. if (_dims == 2)
  660. create(m.w, m.h, m.elemsize, m.elempack, _allocator);
  661. if (_dims == 3)
  662. create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator);
  663. if (_dims == 4)
  664. create(m.w, m.h, m.d, m.c, m.elemsize, m.elempack, _allocator);
  665. }
  666. void VkMat::create_like(const VkImageMat& im, VkAllocator* _allocator)
  667. {
  668. int _dims = im.dims;
  669. if (_dims == 1)
  670. create(im.w, im.elemsize, im.elempack, _allocator);
  671. if (_dims == 2)
  672. create(im.w, im.h, im.elemsize, im.elempack, _allocator);
  673. if (_dims == 3)
  674. create(im.w, im.h, im.c, im.elemsize, im.elempack, _allocator);
  675. if (_dims == 4)
  676. create(im.w, im.h, im.d, im.c, im.elemsize, im.elempack, _allocator);
  677. }
  678. void VkImageMat::create(int _w, size_t _elemsize, VkAllocator* _allocator)
  679. {
  680. if (dims == 1 && w == _w && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  681. return;
  682. release();
  683. elemsize = _elemsize;
  684. elempack = 1;
  685. allocator = _allocator;
  686. dims = 1;
  687. w = _w;
  688. h = 1;
  689. d = 1;
  690. c = 1;
  691. if (total() > 0)
  692. {
  693. data = allocator->fastMalloc(w, h, c, elemsize, elempack);
  694. }
  695. if (data)
  696. {
  697. refcount = (int*)((unsigned char*)data + offsetof(VkImageMemory, refcount));
  698. *refcount = 1;
  699. }
  700. }
  701. void VkImageMat::create(int _w, int _h, size_t _elemsize, VkAllocator* _allocator)
  702. {
  703. if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  704. return;
  705. release();
  706. elemsize = _elemsize;
  707. elempack = 1;
  708. allocator = _allocator;
  709. dims = 2;
  710. w = _w;
  711. h = _h;
  712. d = 1;
  713. c = 1;
  714. if (total() > 0)
  715. {
  716. data = allocator->fastMalloc(w, h, c, elemsize, elempack);
  717. }
  718. if (data)
  719. {
  720. refcount = (int*)((unsigned char*)data + offsetof(VkImageMemory, refcount));
  721. *refcount = 1;
  722. }
  723. }
  724. void VkImageMat::create(int _w, int _h, int _c, size_t _elemsize, VkAllocator* _allocator)
  725. {
  726. if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  727. return;
  728. release();
  729. elemsize = _elemsize;
  730. elempack = 1;
  731. allocator = _allocator;
  732. dims = 3;
  733. w = _w;
  734. h = _h;
  735. d = 1;
  736. c = _c;
  737. if (total() > 0)
  738. {
  739. data = allocator->fastMalloc(w, h, c, elemsize, elempack);
  740. }
  741. if (data)
  742. {
  743. refcount = (int*)((unsigned char*)data + offsetof(VkImageMemory, refcount));
  744. *refcount = 1;
  745. }
  746. }
  747. void VkImageMat::create(int _w, int _h, int _d, int _c, size_t _elemsize, VkAllocator* _allocator)
  748. {
  749. if (dims == 4 && w == _w && h == _h && d == _d && c == _c && elemsize == _elemsize && elempack == 1 && allocator == _allocator)
  750. return;
  751. release();
  752. elemsize = _elemsize;
  753. elempack = 1;
  754. allocator = _allocator;
  755. dims = 4;
  756. w = _w;
  757. h = _h;
  758. d = _d;
  759. c = _c;
  760. if (total() > 0)
  761. {
  762. // underlying image is 3d
  763. data = allocator->fastMalloc(w, h * d, c, elemsize, elempack);
  764. }
  765. if (data)
  766. {
  767. refcount = (int*)((unsigned char*)data + offsetof(VkImageMemory, refcount));
  768. *refcount = 1;
  769. }
  770. }
  771. void VkImageMat::create(int _w, size_t _elemsize, int _elempack, VkAllocator* _allocator)
  772. {
  773. if (dims == 1 && w == _w && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  774. return;
  775. release();
  776. elemsize = _elemsize;
  777. elempack = _elempack;
  778. allocator = _allocator;
  779. dims = 1;
  780. w = _w;
  781. h = 1;
  782. d = 1;
  783. c = 1;
  784. if (total() > 0)
  785. {
  786. data = allocator->fastMalloc(w, h, c, elemsize, elempack);
  787. }
  788. if (data)
  789. {
  790. refcount = (int*)((unsigned char*)data + offsetof(VkImageMemory, refcount));
  791. *refcount = 1;
  792. }
  793. }
  794. void VkImageMat::create(int _w, int _h, size_t _elemsize, int _elempack, VkAllocator* _allocator)
  795. {
  796. if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  797. return;
  798. release();
  799. elemsize = _elemsize;
  800. elempack = _elempack;
  801. allocator = _allocator;
  802. dims = 2;
  803. w = _w;
  804. h = _h;
  805. d = 1;
  806. c = 1;
  807. if (total() > 0)
  808. {
  809. data = allocator->fastMalloc(w, h, c, elemsize, elempack);
  810. }
  811. if (data)
  812. {
  813. refcount = (int*)((unsigned char*)data + offsetof(VkImageMemory, refcount));
  814. *refcount = 1;
  815. }
  816. }
  817. void VkImageMat::create(int _w, int _h, int _c, size_t _elemsize, int _elempack, VkAllocator* _allocator)
  818. {
  819. if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  820. return;
  821. release();
  822. elemsize = _elemsize;
  823. elempack = _elempack;
  824. allocator = _allocator;
  825. dims = 3;
  826. w = _w;
  827. h = _h;
  828. d = 1;
  829. c = _c;
  830. if (total() > 0)
  831. {
  832. data = allocator->fastMalloc(w, h, c, elemsize, elempack);
  833. }
  834. if (data)
  835. {
  836. refcount = (int*)((unsigned char*)data + offsetof(VkImageMemory, refcount));
  837. *refcount = 1;
  838. }
  839. }
  840. void VkImageMat::create(int _w, int _h, int _d, int _c, size_t _elemsize, int _elempack, VkAllocator* _allocator)
  841. {
  842. if (dims == 4 && w == _w && h == _h && d == _d && c == _c && elemsize == _elemsize && elempack == _elempack && allocator == _allocator)
  843. return;
  844. release();
  845. elemsize = _elemsize;
  846. elempack = _elempack;
  847. allocator = _allocator;
  848. dims = 4;
  849. w = _w;
  850. h = _h;
  851. d = _d;
  852. c = _c;
  853. if (total() > 0)
  854. {
  855. // underlying image is 3d
  856. data = allocator->fastMalloc(w, h * d, c, elemsize, elempack);
  857. }
  858. if (data)
  859. {
  860. refcount = (int*)((unsigned char*)data + offsetof(VkImageMemory, refcount));
  861. *refcount = 1;
  862. }
  863. }
  864. void VkImageMat::create_like(const Mat& m, VkAllocator* _allocator)
  865. {
  866. int _dims = m.dims;
  867. if (_dims == 1)
  868. create(m.w, m.elemsize, m.elempack, _allocator);
  869. if (_dims == 2)
  870. create(m.w, m.h, m.elemsize, m.elempack, _allocator);
  871. if (_dims == 3)
  872. create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator);
  873. if (_dims == 4)
  874. create(m.w, m.h, m.d, m.c, m.elemsize, m.elempack, _allocator);
  875. }
  876. void VkImageMat::create_like(const VkMat& m, VkAllocator* _allocator)
  877. {
  878. int _dims = m.dims;
  879. if (_dims == 1)
  880. create(m.w, m.elemsize, m.elempack, _allocator);
  881. if (_dims == 2)
  882. create(m.w, m.h, m.elemsize, m.elempack, _allocator);
  883. if (_dims == 3)
  884. create(m.w, m.h, m.c, m.elemsize, m.elempack, _allocator);
  885. if (_dims == 4)
  886. create(m.w, m.h, m.d, m.c, m.elemsize, m.elempack, _allocator);
  887. }
  888. void VkImageMat::create_like(const VkImageMat& im, VkAllocator* _allocator)
  889. {
  890. int _dims = im.dims;
  891. if (_dims == 1)
  892. create(im.w, im.elemsize, im.elempack, _allocator);
  893. if (_dims == 2)
  894. create(im.w, im.h, im.elemsize, im.elempack, _allocator);
  895. if (_dims == 3)
  896. create(im.w, im.h, im.c, im.elemsize, im.elempack, _allocator);
  897. if (_dims == 4)
  898. create(im.w, im.h, im.d, im.c, im.elemsize, im.elempack, _allocator);
  899. }
  900. #endif // NCNN_VULKAN
  901. void Mat::substract_mean_normalize(const float* mean_vals, const float* norm_vals)
  902. {
  903. Layer* op;
  904. if (mean_vals && !norm_vals)
  905. {
  906. // substract mean only
  907. op = create_layer(LayerType::Bias);
  908. ParamDict pd;
  909. pd.set(0, c);
  910. op->load_param(pd);
  911. Mat weights[1];
  912. weights[0] = Mat(c);
  913. for (int q = 0; q < c; q++)
  914. {
  915. weights[0][q] = -mean_vals[q];
  916. }
  917. op->load_model(ModelBinFromMatArray(weights));
  918. }
  919. else if (!mean_vals && norm_vals)
  920. {
  921. // normalize only
  922. op = create_layer(LayerType::Scale);
  923. ParamDict pd;
  924. pd.set(0, c);
  925. op->load_param(pd);
  926. Mat weights[1];
  927. weights[0] = Mat(c);
  928. for (int q = 0; q < c; q++)
  929. {
  930. weights[0][q] = norm_vals[q];
  931. }
  932. op->load_model(ModelBinFromMatArray(weights));
  933. }
  934. else if (mean_vals && norm_vals)
  935. {
  936. // substract mean and normalize
  937. op = create_layer(LayerType::Scale);
  938. ParamDict pd;
  939. pd.set(0, c);
  940. pd.set(1, 1);
  941. op->load_param(pd);
  942. Mat weights[2];
  943. weights[0] = Mat(c);
  944. weights[1] = Mat(c);
  945. for (int q = 0; q < c; q++)
  946. {
  947. weights[0][q] = norm_vals[q];
  948. weights[1][q] = -mean_vals[q] * norm_vals[q];
  949. }
  950. op->load_model(ModelBinFromMatArray(weights));
  951. }
  952. else // if (!mean_vals && !norm_vals)
  953. {
  954. return;
  955. }
  956. Option opt;
  957. opt.num_threads = 1; // TODO
  958. op->create_pipeline(opt);
  959. op->forward_inplace(*this, opt);
  960. op->destroy_pipeline(opt);
  961. delete op;
  962. }
  963. Mat Mat::from_float16(const unsigned short* data, int size)
  964. {
  965. Mat src(size, (void*)data, (size_t)2u);
  966. Mat dst;
  967. Option opt;
  968. opt.num_threads = 1; // TODO
  969. cast_float16_to_float32(src, dst, opt);
  970. return dst;
  971. }
  972. #if NCNN_VULKAN
  973. #if NCNN_PLATFORM_API
  974. #if __ANDROID_API__ >= 26
  975. VkImageMat VkImageMat::from_android_hardware_buffer(VkAndroidHardwareBufferImageAllocator* allocator)
  976. {
  977. int width = allocator->width();
  978. int height = allocator->height();
  979. size_t elemsize = 4u; // elemsize for ahb is actually just a placeholder
  980. return VkImageMat(width, height, elemsize, allocator);
  981. }
  982. #endif // __ANDROID_API__ >= 26
  983. #endif // NCNN_PLATFORM_API
  984. #endif // NCNN_VULKAN
  985. unsigned short float32_to_float16(float value)
  986. {
  987. // 1 : 8 : 23
  988. union
  989. {
  990. unsigned int u;
  991. float f;
  992. } tmp;
  993. tmp.f = value;
  994. // 1 : 8 : 23
  995. unsigned short sign = (tmp.u & 0x80000000) >> 31;
  996. unsigned short exponent = (tmp.u & 0x7F800000) >> 23;
  997. unsigned int significand = tmp.u & 0x7FFFFF;
  998. // NCNN_LOGE("%d %d %d", sign, exponent, significand);
  999. // 1 : 5 : 10
  1000. unsigned short fp16;
  1001. if (exponent == 0)
  1002. {
  1003. // zero or denormal, always underflow
  1004. fp16 = (sign << 15) | (0x00 << 10) | 0x00;
  1005. }
  1006. else if (exponent == 0xFF)
  1007. {
  1008. // infinity or NaN
  1009. fp16 = (sign << 15) | (0x1F << 10) | (significand ? 0x200 : 0x00);
  1010. }
  1011. else
  1012. {
  1013. // normalized
  1014. short newexp = exponent + (-127 + 15);
  1015. if (newexp >= 31)
  1016. {
  1017. // overflow, return infinity
  1018. fp16 = (sign << 15) | (0x1F << 10) | 0x00;
  1019. }
  1020. else if (newexp <= 0)
  1021. {
  1022. // Some normal fp32 cannot be expressed as normal fp16
  1023. fp16 = (sign << 15) | (0x00 << 10) | 0x00;
  1024. }
  1025. else
  1026. {
  1027. // normal fp16
  1028. fp16 = (sign << 15) | (newexp << 10) | (significand >> 13);
  1029. }
  1030. }
  1031. return fp16;
  1032. }
  1033. float float16_to_float32(unsigned short value)
  1034. {
  1035. // 1 : 5 : 10
  1036. unsigned short sign = (value & 0x8000) >> 15;
  1037. unsigned short exponent = (value & 0x7c00) >> 10;
  1038. unsigned short significand = value & 0x03FF;
  1039. // NCNN_LOGE("%d %d %d", sign, exponent, significand);
  1040. // 1 : 8 : 23
  1041. union
  1042. {
  1043. unsigned int u;
  1044. float f;
  1045. } tmp;
  1046. if (exponent == 0)
  1047. {
  1048. if (significand == 0)
  1049. {
  1050. // zero
  1051. tmp.u = (sign << 31);
  1052. }
  1053. else
  1054. {
  1055. // denormal
  1056. exponent = 0;
  1057. // find non-zero bit
  1058. while ((significand & 0x200) == 0)
  1059. {
  1060. significand <<= 1;
  1061. exponent++;
  1062. }
  1063. significand <<= 1;
  1064. significand &= 0x3FF;
  1065. tmp.u = (sign << 31) | ((-exponent + (-15 + 127)) << 23) | (significand << 13);
  1066. }
  1067. }
  1068. else if (exponent == 0x1F)
  1069. {
  1070. // infinity or NaN
  1071. tmp.u = (sign << 31) | (0xFF << 23) | (significand << 13);
  1072. }
  1073. else
  1074. {
  1075. // normalized
  1076. tmp.u = (sign << 31) | ((exponent + (-15 + 127)) << 23) | (significand << 13);
  1077. }
  1078. return tmp.f;
  1079. }
  1080. void copy_make_border(const Mat& src, Mat& dst, int top, int bottom, int left, int right, int type, float v, const Option& opt)
  1081. {
  1082. Layer* padding = create_layer(LayerType::Padding);
  1083. ParamDict pd;
  1084. pd.set(0, top);
  1085. pd.set(1, bottom);
  1086. pd.set(2, left);
  1087. pd.set(3, right);
  1088. pd.set(4, type);
  1089. pd.set(5, v);
  1090. padding->load_param(pd);
  1091. padding->create_pipeline(opt);
  1092. padding->forward(src, dst, opt);
  1093. padding->destroy_pipeline(opt);
  1094. delete padding;
  1095. }
  1096. void copy_make_border_3d(const Mat& src, Mat& dst, int top, int bottom, int left, int right, int front, int behind, int type, float v, const Option& opt)
  1097. {
  1098. Layer* padding = create_layer(LayerType::Padding);
  1099. ParamDict pd;
  1100. pd.set(0, top);
  1101. pd.set(1, bottom);
  1102. pd.set(2, left);
  1103. pd.set(3, right);
  1104. pd.set(4, type);
  1105. pd.set(5, v);
  1106. pd.set(7, front);
  1107. pd.set(8, behind);
  1108. padding->load_param(pd);
  1109. padding->create_pipeline(opt);
  1110. padding->forward(src, dst, opt);
  1111. padding->destroy_pipeline(opt);
  1112. delete padding;
  1113. }
  1114. void copy_cut_border(const Mat& src, Mat& dst, int top, int bottom, int left, int right, const Option& opt)
  1115. {
  1116. if (left + right > src.w || top + bottom > src.h)
  1117. {
  1118. NCNN_LOGE("copy_cut_border parameter error, top: %d, bottom: %d, left: %d, right: %d, src.w: %d, src.h: %d", top, bottom, left, right, src.w, src.h);
  1119. return;
  1120. }
  1121. Layer* crop = create_layer(LayerType::Crop);
  1122. ParamDict pd;
  1123. pd.set(0, left);
  1124. pd.set(1, top);
  1125. pd.set(2, 0);
  1126. pd.set(3, src.w - left - right);
  1127. pd.set(4, src.h - top - bottom);
  1128. pd.set(5, -233);
  1129. crop->load_param(pd);
  1130. crop->create_pipeline(opt);
  1131. crop->forward(src, dst, opt);
  1132. crop->destroy_pipeline(opt);
  1133. delete crop;
  1134. }
  1135. void copy_cut_border_3d(const Mat& src, Mat& dst, int top, int bottom, int left, int right, int front, int behind, const Option& opt)
  1136. {
  1137. if (left + right > src.w || top + bottom > src.h || front + behind > src.d)
  1138. {
  1139. NCNN_LOGE("copy_cut_border_3d parameter error, top: %d, bottom: %d, left: %d, right: %d, front: %d, behind: %d, src.w: %d, src.h: %d, src.d: %d", top, bottom, left, right, front, behind, src.w, src.h, src.d);
  1140. return;
  1141. }
  1142. Layer* crop = create_layer(LayerType::Crop);
  1143. ParamDict pd;
  1144. pd.set(0, left);
  1145. pd.set(1, top);
  1146. pd.set(13, front);
  1147. pd.set(2, 0);
  1148. pd.set(3, src.w - left - right);
  1149. pd.set(4, src.h - top - bottom);
  1150. pd.set(14, src.d - front - behind);
  1151. pd.set(5, -233);
  1152. crop->load_param(pd);
  1153. crop->create_pipeline(opt);
  1154. crop->forward(src, dst, opt);
  1155. crop->destroy_pipeline(opt);
  1156. delete crop;
  1157. }
  1158. void resize_nearest(const Mat& src, Mat& dst, int w, int h, const Option& opt)
  1159. {
  1160. Layer* interp = create_layer(LayerType::Interp);
  1161. ParamDict pd;
  1162. pd.set(0, 1);
  1163. pd.set(3, h);
  1164. pd.set(4, w);
  1165. interp->load_param(pd);
  1166. interp->create_pipeline(opt);
  1167. interp->forward(src, dst, opt);
  1168. interp->destroy_pipeline(opt);
  1169. delete interp;
  1170. }
  1171. void resize_bilinear(const Mat& src, Mat& dst, int w, int h, const Option& opt)
  1172. {
  1173. Layer* interp = create_layer(LayerType::Interp);
  1174. ParamDict pd;
  1175. pd.set(0, 2);
  1176. pd.set(3, h);
  1177. pd.set(4, w);
  1178. interp->load_param(pd);
  1179. interp->create_pipeline(opt);
  1180. interp->forward(src, dst, opt);
  1181. interp->destroy_pipeline(opt);
  1182. delete interp;
  1183. }
  1184. void resize_bicubic(const Mat& src, Mat& dst, int w, int h, const Option& opt)
  1185. {
  1186. Layer* interp = create_layer(LayerType::Interp);
  1187. ParamDict pd;
  1188. pd.set(0, 3);
  1189. pd.set(3, h);
  1190. pd.set(4, w);
  1191. interp->load_param(pd);
  1192. interp->create_pipeline(opt);
  1193. interp->forward(src, dst, opt);
  1194. interp->destroy_pipeline(opt);
  1195. delete interp;
  1196. }
  1197. void convert_packing(const Mat& src, Mat& dst, int _elempack, const Option& opt)
  1198. {
  1199. Layer* packing = create_layer(LayerType::Packing);
  1200. ParamDict pd;
  1201. pd.set(0, _elempack);
  1202. packing->load_param(pd);
  1203. packing->create_pipeline(opt);
  1204. packing->forward(src, dst, opt);
  1205. packing->destroy_pipeline(opt);
  1206. delete packing;
  1207. }
  1208. void flatten(const Mat& src, Mat& dst, const Option& opt)
  1209. {
  1210. Layer* flatten = create_layer(LayerType::Flatten);
  1211. ParamDict pd;
  1212. flatten->load_param(pd);
  1213. flatten->create_pipeline(opt);
  1214. flatten->forward(src, dst, opt);
  1215. flatten->destroy_pipeline(opt);
  1216. delete flatten;
  1217. }
  1218. void cast_float32_to_float16(const Mat& src, Mat& dst, const Option& opt)
  1219. {
  1220. Layer* cast = create_layer(LayerType::Cast);
  1221. ParamDict pd;
  1222. pd.set(0, 1);
  1223. pd.set(1, 2);
  1224. cast->load_param(pd);
  1225. cast->create_pipeline(opt);
  1226. cast->forward(src, dst, opt);
  1227. cast->destroy_pipeline(opt);
  1228. delete cast;
  1229. }
  1230. void cast_float16_to_float32(const Mat& src, Mat& dst, const Option& opt)
  1231. {
  1232. Layer* cast = create_layer(LayerType::Cast);
  1233. ParamDict pd;
  1234. pd.set(0, 2);
  1235. pd.set(1, 1);
  1236. cast->load_param(pd);
  1237. cast->create_pipeline(opt);
  1238. cast->forward(src, dst, opt);
  1239. cast->destroy_pipeline(opt);
  1240. delete cast;
  1241. }
  1242. void cast_int8_to_float32(const Mat& src, Mat& dst, const Option& opt)
  1243. {
  1244. Layer* cast = create_layer(LayerType::Cast);
  1245. ParamDict pd;
  1246. pd.set(0, 3);
  1247. pd.set(1, 1);
  1248. cast->load_param(pd);
  1249. cast->create_pipeline(opt);
  1250. cast->forward(src, dst, opt);
  1251. cast->destroy_pipeline(opt);
  1252. delete cast;
  1253. }
  1254. void cast_float32_to_bfloat16(const Mat& src, Mat& dst, const Option& opt)
  1255. {
  1256. Layer* cast = create_layer(LayerType::Cast);
  1257. ParamDict pd;
  1258. pd.set(0, 1);
  1259. pd.set(1, 4);
  1260. cast->load_param(pd);
  1261. cast->create_pipeline(opt);
  1262. cast->forward(src, dst, opt);
  1263. cast->destroy_pipeline(opt);
  1264. delete cast;
  1265. }
  1266. void cast_bfloat16_to_float32(const Mat& src, Mat& dst, const Option& opt)
  1267. {
  1268. Layer* cast = create_layer(LayerType::Cast);
  1269. ParamDict pd;
  1270. pd.set(0, 4);
  1271. pd.set(1, 1);
  1272. cast->load_param(pd);
  1273. cast->create_pipeline(opt);
  1274. cast->forward(src, dst, opt);
  1275. cast->destroy_pipeline(opt);
  1276. delete cast;
  1277. }
  1278. void quantize_to_int8(const Mat& src, Mat& dst, const Mat& scale_data, const Option& opt)
  1279. {
  1280. Layer* quantize = create_layer(LayerType::Quantize);
  1281. ParamDict pd;
  1282. pd.set(0, scale_data.w);
  1283. quantize->load_param(pd);
  1284. Mat weights[1];
  1285. weights[0] = scale_data;
  1286. quantize->load_model(ModelBinFromMatArray(weights));
  1287. quantize->create_pipeline(opt);
  1288. quantize->forward(src, dst, opt);
  1289. quantize->destroy_pipeline(opt);
  1290. delete quantize;
  1291. }
  1292. void dequantize_from_int32(const Mat& src, Mat& dst, const Mat& scale_data, const Mat& bias_data, const Option& opt)
  1293. {
  1294. Layer* dequantize = create_layer(LayerType::Dequantize);
  1295. ParamDict pd;
  1296. pd.set(0, scale_data.w);
  1297. pd.set(1, bias_data.w);
  1298. dequantize->load_param(pd);
  1299. Mat weights[2];
  1300. weights[0] = scale_data;
  1301. weights[1] = bias_data;
  1302. dequantize->load_model(ModelBinFromMatArray(weights));
  1303. dequantize->create_pipeline(opt);
  1304. dequantize->forward(src, dst, opt);
  1305. dequantize->destroy_pipeline(opt);
  1306. delete dequantize;
  1307. }
  1308. void requantize_from_int32_to_int8(const Mat& src, Mat& dst, const Mat& scale_in_data, const Mat& scale_out_data, const Mat& bias_data, int activation_type, const Mat& activation_params, const Option& opt)
  1309. {
  1310. Layer* requantize = create_layer(LayerType::Requantize);
  1311. ParamDict pd;
  1312. pd.set(0, scale_in_data.w);
  1313. pd.set(1, scale_out_data.w);
  1314. pd.set(2, bias_data.w);
  1315. pd.set(3, activation_type);
  1316. pd.set(4, activation_params);
  1317. requantize->load_param(pd);
  1318. Mat weights[3];
  1319. weights[0] = scale_in_data;
  1320. weights[1] = scale_out_data;
  1321. weights[2] = bias_data;
  1322. requantize->load_model(ModelBinFromMatArray(weights));
  1323. requantize->create_pipeline(opt);
  1324. requantize->forward(src, dst, opt);
  1325. requantize->destroy_pipeline(opt);
  1326. delete requantize;
  1327. }
  1328. } // namespace ncnn