conv_bn_kernel.cpp 2.8 KB
Newer Older
Z
zhangyang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#ifdef FUSION_CONVBN_OP

#include "operators/kernel/conv_bn_kernel.h"
H
hjchen2 已提交
18
#include <cmath>
Z
zhangyang 已提交
19 20 21 22 23

namespace paddle_mobile {
namespace operators {

template <>
N
nhzlx 已提交
24
bool ConvBNKernel<FPGA, float>::Init(FusionConvBNParam<FPGA> *param) {
qnqinan's avatar
qnqinan 已提交
25 26 27 28
  // bool relu_enabled = false;
  paddle_mobile::fpga::ActivationType activation_enable =
      paddle_mobile::fpga::NONE;
  int16_t leaky_relu_negative_slope = 0;
Z
zhangyang 已提交
29 30 31
  auto input = const_cast<Tensor *>(param->Input());
  auto filter = const_cast<Tensor *>(param->Filter());
  auto out = param->Output();
Z
zhangyang 已提交
32 33 34 35 36
  auto bn_mean_ptr = param->InputMean()->data<float>();
  auto bn_var_ptr = param->InputVariance()->data<float>();
  auto bn_scale_ptr = param->InputScale()->data<float>();
  auto bn_bias_ptr = param->InputBias()->data<float>();
  const float epsilon = param->Epsilon();
Z
zhangyang 已提交
37 38 39
  PADDLE_MOBILE_ENFORCE(out->dims()[1] == param->InputBias()->dims()[0],
                        "Output channel should be equal to bias number");
  const int channel = out->dims()[1];
40
  auto bs_ptr =
41
      (float *)fpga::fpga_malloc(2 * channel * sizeof(float));  // // NOLINT
Z
zhangyang 已提交
42 43
  auto new_scale = new Tensor();
  auto new_bias = new Tensor();
Z
zhangyang 已提交
44 45 46 47 48 49
  auto new_scale_ptr = new_scale->mutable_data<float>({channel});
  auto new_bias_ptr = new_bias->mutable_data<float>({channel});

  for (int i = 0; i < channel; i++) {
    new_scale_ptr[i] = bn_scale_ptr[i] /
                       static_cast<float>(pow((bn_var_ptr[i] + epsilon), 0.5));
Z
zhangyang 已提交
50
    new_bias_ptr[i] = bn_bias_ptr[i] + (0 - bn_mean_ptr[i]) * new_scale_ptr[i];
Z
zhangyang 已提交
51 52
    bs_ptr[i + channel] = new_scale_ptr[i];
    bs_ptr[i] = new_bias_ptr[i];
Z
zhangyang 已提交
53 54 55
  }
  param->SetNewScale(new_scale);
  param->SetNewBias(new_bias);
Z
zhangyang 已提交
56

57
  fpga::format_conv_data(filter, out, &bs_ptr, param->Groups());
Z
zhangyang 已提交
58
  fpga::SplitConvArgs conv_arg = {0};
qnqinan's avatar
qnqinan 已提交
59 60 61 62
  fpga::fill_split_arg(&conv_arg, input, out, filter, activation_enable,
                       leaky_relu_negative_slope, param->Groups(),
                       param->Strides()[0], param->Strides()[1],
                       param->Paddings()[0], param->Paddings()[1], bs_ptr);
63
  param->SetFpgaArgs(conv_arg);
Z
zhangyang 已提交
64 65 66 67
  return true;
}

template <>
68
void ConvBNKernel<FPGA, float>::Compute(const FusionConvBNParam<FPGA> &param) {
Z
zhangyang 已提交
69 70 71 72 73 74 75
  fpga::ComputeFpgaConv(param.FpgaArgs());
}

}  // namespace operators
}  // namespace paddle_mobile

#endif