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.

scale_arm.cpp 3.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Tencent is pleased to support the open source community by making ncnn available.
  2. //
  3. // Copyright (C) 2017 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 "scale_arm.h"
  15. #if __ARM_NEON
  16. #include <arm_neon.h>
  17. #endif // __ARM_NEON
  18. namespace ncnn {
  19. DEFINE_LAYER_CREATOR(Scale_arm)
  20. int Scale_arm::forward_inplace(Mat& bottom_top_blob, const Option& opt) const
  21. {
  22. int dims = bottom_top_blob.dims;
  23. if (dims != 3)
  24. return Scale::forward_inplace(bottom_top_blob, opt);
  25. int w = bottom_top_blob.w;
  26. int h = bottom_top_blob.h;
  27. int channels = bottom_top_blob.c;
  28. int size = w * h;
  29. if (bias_term)
  30. {
  31. const float* scale_ptr = scale_data;
  32. const float* bias_ptr = bias_data;
  33. #pragma omp parallel for num_threads(opt.num_threads)
  34. for (int q=0; q<channels; q++)
  35. {
  36. float* ptr = bottom_top_blob.channel(q);
  37. float s = scale_ptr[q];
  38. float bias = bias_ptr[q];
  39. #if __ARM_NEON
  40. int nn = size >> 2;
  41. int remain = size - (nn << 2);
  42. #else
  43. int remain = size;
  44. #endif // __ARM_NEON
  45. #if __ARM_NEON
  46. float32x4_t _s = vdupq_n_f32(s);
  47. float32x4_t _bias = vdupq_n_f32(bias);
  48. for (; nn>0; nn--)
  49. {
  50. float32x4_t _p = vld1q_f32(ptr);
  51. _p = vmlaq_f32(_bias, _p, _s);
  52. vst1q_f32(ptr, _p);
  53. ptr += 4;
  54. }
  55. #endif // __ARM_NEON
  56. for (; remain>0; remain--)
  57. {
  58. *ptr = *ptr * s + bias;
  59. ptr++;
  60. }
  61. }
  62. }
  63. else
  64. {
  65. const float* scale_ptr = scale_data;
  66. #pragma omp parallel for num_threads(opt.num_threads)
  67. for (int q=0; q<channels; q++)
  68. {
  69. float* ptr = bottom_top_blob.channel(q);
  70. float s = scale_ptr[q];
  71. #if __ARM_NEON
  72. int nn = size >> 2;
  73. int remain = size - (nn << 2);
  74. #else
  75. int remain = size;
  76. #endif // __ARM_NEON
  77. #if __ARM_NEON
  78. float32x4_t _s = vdupq_n_f32(s);
  79. for (; nn>0; nn--)
  80. {
  81. float32x4_t _p = vld1q_f32(ptr);
  82. _p = vmulq_f32(_p, _s);
  83. vst1q_f32(ptr, _p);
  84. ptr += 4;
  85. }
  86. #endif // __ARM_NEON
  87. for (; remain>0; remain--)
  88. {
  89. *ptr *= s;
  90. ptr++;
  91. }
  92. }
  93. }
  94. return 0;
  95. }
  96. } // namespace ncnn