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.

element-packing.md 3.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. ### what is packing and why
  2. packing is the form of storing multiple short-sized values as one long-sized value.
  3. element packing is well mapped with the underlying simd register, which usually use one very wide register to store different types of values.
  4. |C|elemsize|elempack|
  5. |---|---|---|
  6. |double|8|1|
  7. |float|4|1|
  8. |int|4|1|
  9. |short|2|1|
  10. |signed char|1|1|
  11. |arm neon|elemsize|elempack|
  12. |---|---|---|
  13. |float64x2_t|16|2|
  14. |float32x4_t|16|4|
  15. |int32x4_t|16|4|
  16. |float16x4_t|8|4|
  17. |int8x8_t|8|8|
  18. Though the real count of values doubles when elempack is two, the wide-sized value is still treated as one value in the view of Mat structure. For example, we want to store 40 float values in Mat object, if elempack 1 is used, Mat width is then 40, while 10 if elempack 4 is used.
  19. |dims|w|h|c|cstep|elemsize|elempack|
  20. |---|---|---|---|---|---|---|
  21. |1|40|1|1|40|4|1|
  22. |1|10|1|1|10|16|4|
  23. ### packing style convention
  24. In practise, elempack 1, 4, 8 are the most common cases. It is possible to use any other packing style in theory.
  25. The following table show the packing axis used in ncnn for different dimension.
  26. |dims|packing axis|shape before packing|shape after packing|
  27. |---|---|---|---|
  28. |1|w|w|w/elempack|
  29. |2|h|w, h|w, h/elempack|
  30. |3|c|w, h, c|w, h, c/elempack|
  31. If the packing axis dim is not evenly divisible by elempack, zero padding may be used.
  32. ```
  33. outw = (w + elempack - 1) / elempack;
  34. ```
  35. The following snippet shows the memory layout after elempack=4 on 3-dim Mat
  36. ```
  37. // w=2 h=3 c=4 elempack=1
  38. 0 1
  39. 2 3
  40. 4 5
  41. 6 7
  42. 8 9
  43. 10 11
  44. 12 13
  45. 14 15
  46. 16 17
  47. 18 19
  48. 20 21
  49. 22 23
  50. // w=2 h=3 c=1 elempack=4
  51. (0,6,12,18) (1,7,13,19)
  52. (2,8,14,20) (3,9,15,21)
  53. (4,10,16,22) (5,11,17,23)
  54. ```
  55. ### how to convert elempack
  56. There is a convenient wrapper function provided
  57. ```
  58. // convert to elempack 4 if packing axis dim is evenly divisible by elempack
  59. // return the identity Mat otherwise
  60. ncnn::Mat a;
  61. ncnn::Mat a_packed;
  62. ncnn::convert_packing(a, a_packed, 4);
  63. if (a_packed.elempack == 4)
  64. {
  65. // check if packing is successful
  66. }
  67. // convert to packing 1, aka unpacking, shall be always successful
  68. ncnn::Mat b;
  69. ncnn::Mat b_unpacked;
  70. ncnn::convert_packing(b, b_unpacked, 1);
  71. ```
  72. ### handle general interleaved data
  73. Here is an example of using convert packing to convert RGB interleaved data to planar
  74. **NOTE:** The following code is just presented to explain what packing is and the conversion process. Do not use it in production due to its poor performance. Do use ncnn::Mat::from_pixels()
  75. ```cpp
  76. // rgb_interleaved_u8 is RGB RGB RGB ...
  77. // rgb_interleaved_u8.w = w;
  78. // rgb_interleaved_u8.h = h;
  79. // rgb_interleaved_u8.c = 1;
  80. // rgb_interleaved_u8.elemsize = 3;
  81. // rgb_interleaved_u8.elempack = 3;
  82. ncnn::Mat rgb_interleaved_u8(w, h, 1, 3, 3);
  83. ncnn::Mat rgb_planar_u8;
  84. ncnn::convert_packing(rgb_interleaved_u8, rgb_planar_u8, 1);
  85. // rgb_planar_u8 is now RRR ... GGG ... BBB ...
  86. // rgb_planar_u8.w = w;
  87. // rgb_planar_u8.h = h;
  88. // rgb_planar_u8.c = 3;
  89. // rgb_planar_u8.elemsize = 1;
  90. // rgb_planar_u8.elempack = 1;
  91. ```