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.

reshape_vulkan.cpp 6.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Tencent is pleased to support the open source community by making ncnn available.
  2. //
  3. // Copyright (C) 2019 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 "reshape_vulkan.h"
  15. namespace ncnn {
  16. DEFINE_LAYER_CREATOR(Reshape_vulkan)
  17. Reshape_vulkan::Reshape_vulkan()
  18. {
  19. support_vulkan = true;
  20. pipeline_reshape = 0;
  21. pipeline_reshape_pack4 = 0;
  22. pipeline_reshape_pack1to4 = 0;
  23. pipeline_reshape_pack4to1 = 0;
  24. }
  25. int Reshape_vulkan::create_pipeline(const Option& opt)
  26. {
  27. std::vector<vk_specialization_type> specializations(1);
  28. specializations[0].i = ndim;
  29. // pack1
  30. {
  31. pipeline_reshape = new Pipeline(vkdev);
  32. pipeline_reshape->set_optimal_local_size_xyz();
  33. pipeline_reshape->create("reshape", opt, specializations, 2, 10);
  34. }
  35. // pack4
  36. {
  37. pipeline_reshape_pack4 = new Pipeline(vkdev);
  38. pipeline_reshape_pack4->set_optimal_local_size_xyz();
  39. pipeline_reshape_pack4->create("reshape_pack4", opt, specializations, 2, 10);
  40. }
  41. // pack1to4
  42. {
  43. pipeline_reshape_pack1to4 = new Pipeline(vkdev);
  44. pipeline_reshape_pack1to4->set_optimal_local_size_xyz();
  45. pipeline_reshape_pack1to4->create("reshape_pack1to4", opt, specializations, 2, 10);
  46. }
  47. // pack4to1
  48. {
  49. pipeline_reshape_pack4to1 = new Pipeline(vkdev);
  50. pipeline_reshape_pack4to1->set_optimal_local_size_xyz();
  51. pipeline_reshape_pack4to1->create("reshape_pack4to1", opt, specializations, 2, 10);
  52. }
  53. return 0;
  54. }
  55. int Reshape_vulkan::destroy_pipeline(const Option& opt)
  56. {
  57. delete pipeline_reshape;
  58. pipeline_reshape = 0;
  59. delete pipeline_reshape_pack4;
  60. pipeline_reshape_pack4 = 0;
  61. delete pipeline_reshape_pack1to4;
  62. pipeline_reshape_pack1to4 = 0;
  63. delete pipeline_reshape_pack4to1;
  64. pipeline_reshape_pack4to1 = 0;
  65. return 0;
  66. }
  67. int Reshape_vulkan::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt) const
  68. {
  69. int dims = bottom_blob.dims;
  70. size_t elemsize = bottom_blob.elemsize;
  71. int packing = bottom_blob.packing;
  72. int out_packing;
  73. int total = bottom_blob.w * bottom_blob.h * bottom_blob.c * packing;
  74. if (ndim == 1)
  75. {
  76. int _w = w;
  77. if (_w == 0)
  78. _w = dims == 1 ? bottom_blob.w * packing : bottom_blob.w;
  79. if (_w == -1)
  80. _w = total;
  81. // TODO permute support
  82. out_packing = _w % 4 == 0 ? 4 : 1;
  83. size_t out_elemsize = elemsize / packing * out_packing;
  84. if (opt.use_fp16_packed && !opt.use_fp16_storage)
  85. {
  86. if (out_packing == 4) out_elemsize = 4*2u;
  87. if (out_packing == 1) out_elemsize = 4u;
  88. }
  89. if (dims == 1 && bottom_blob.w == _w && packing == out_packing)
  90. {
  91. top_blob = bottom_blob;
  92. return 0;
  93. }
  94. top_blob.create(_w / out_packing, out_elemsize, out_packing, opt.blob_vkallocator, opt.staging_vkallocator);
  95. }
  96. else if (ndim == 2)
  97. {
  98. int _w = w;
  99. int _h = h;
  100. if (_w == 0)
  101. _w = dims == 1 ? bottom_blob.w * packing : bottom_blob.w;
  102. if (_h == 0)
  103. _h = dims == 2 ? bottom_blob.h * packing : bottom_blob.h;
  104. if (_w == -1)
  105. _w = total / _h;
  106. if (_h == -1)
  107. _h = total / _w;
  108. out_packing = _h % 4 == 0 ? 4 : 1;
  109. size_t out_elemsize = elemsize / packing * out_packing;
  110. if (opt.use_fp16_packed && !opt.use_fp16_storage)
  111. {
  112. if (out_packing == 4) out_elemsize = 4*2u;
  113. if (out_packing == 1) out_elemsize = 4u;
  114. }
  115. if (dims == 2 && bottom_blob.h == _h && packing == out_packing)
  116. {
  117. top_blob = bottom_blob;
  118. return 0;
  119. }
  120. top_blob.create(_w, _h / out_packing, out_elemsize, out_packing, opt.blob_vkallocator, opt.staging_vkallocator);
  121. }
  122. else // if (ndim == 3)
  123. {
  124. int _w = w;
  125. int _h = h;
  126. int _c = c;
  127. if (_w == 0)
  128. _w = dims == 1 ? bottom_blob.w * packing : bottom_blob.w;
  129. if (_h == 0)
  130. _h = dims == 2 ? bottom_blob.h * packing : bottom_blob.h;
  131. if (_c == 0)
  132. _c = dims == 3 ? bottom_blob.c * packing : bottom_blob.c;
  133. if (_w == -1)
  134. _w = total / _c / _h;
  135. if (_h == -1)
  136. _h = total / _c / _w;
  137. if (_c == -1)
  138. _c = total / _h / _w;
  139. out_packing = _c % 4 == 0 ? 4 : 1;
  140. size_t out_elemsize = elemsize / packing * out_packing;
  141. if (opt.use_fp16_packed && !opt.use_fp16_storage)
  142. {
  143. if (out_packing == 4) out_elemsize = 4*2u;
  144. if (out_packing == 1) out_elemsize = 4u;
  145. }
  146. if (dims == 3 && bottom_blob.c == _c && packing == out_packing)
  147. {
  148. top_blob = bottom_blob;
  149. top_blob.w = _w;
  150. top_blob.h = _h;
  151. return 0;
  152. }
  153. top_blob.create(_w, _h, _c / out_packing, out_elemsize, out_packing, opt.blob_vkallocator, opt.staging_vkallocator);
  154. }
  155. if (top_blob.empty())
  156. return -100;
  157. std::vector<VkMat> bindings(2);
  158. bindings[0] = bottom_blob;
  159. bindings[1] = top_blob;
  160. std::vector<vk_constant_type> constants(10);
  161. constants[0].i = bottom_blob.dims;
  162. constants[1].i = bottom_blob.w;
  163. constants[2].i = bottom_blob.h;
  164. constants[3].i = bottom_blob.c;
  165. constants[4].i = bottom_blob.cstep;
  166. constants[5].i = top_blob.dims;
  167. constants[6].i = top_blob.w;
  168. constants[7].i = top_blob.h;
  169. constants[8].i = top_blob.c;
  170. constants[9].i = top_blob.cstep;
  171. const Pipeline* pipeline = 0;
  172. if (packing == 1 && out_packing == 1)
  173. {
  174. pipeline = pipeline_reshape;
  175. }
  176. else if (packing == 4 && out_packing == 4)
  177. {
  178. pipeline = pipeline_reshape_pack4;
  179. }
  180. else if (packing == 1 && out_packing == 4)
  181. {
  182. pipeline = pipeline_reshape_pack1to4;
  183. }
  184. else if (packing == 4 && out_packing == 1)
  185. {
  186. pipeline = pipeline_reshape_pack4to1;
  187. }
  188. if (packing == 4 && out_packing == 1)
  189. {
  190. cmd.record_pipeline(pipeline, bindings, constants, bottom_blob);
  191. }
  192. else
  193. {
  194. cmd.record_pipeline(pipeline, bindings, constants, top_blob);
  195. }
  196. return 0;
  197. }
  198. } // namespace ncnn