fc_op.cc 4.0 KB
Newer Older
Y
Yan Chunwei 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
// Copyright (c) 2019 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.

#include "lite/operators/fc_op.h"
#include "lite/core/op_registry.h"

namespace paddle {
namespace lite {
namespace operators {

bool FcOpLite::CheckShape() const {
  CHECK_OR_FALSE(param_.input);
  CHECK_OR_FALSE(param_.output);
  CHECK_OR_FALSE(param_.w);
  // bias is optional.

  const auto input_dims = param_.input->dims();
  const auto w_dims = param_.w->dims();
30
  CHECK_EQ_OR_FALSE(w_dims.size(), 2UL);
Y
Yan Chunwei 已提交
31

32
  int64_t w_dims_1 = param_.padding_weights ? w_dims[1] - 4 : w_dims[1];
Y
Yan Chunwei 已提交
33 34 35 36
  if (param_.bias) {
    const auto bias_dims = param_.bias->dims();
    if (bias_dims.size() == 2) {
      CHECK_EQ_OR_FALSE(bias_dims[0], 1);
37
      CHECK_EQ_OR_FALSE(bias_dims[1], w_dims_1);
Y
Yan Chunwei 已提交
38
    } else if (bias_dims.size() == 1) {
39
      CHECK_EQ_OR_FALSE(bias_dims[0], w_dims_1);
Y
Yan Chunwei 已提交
40 41 42 43 44 45 46 47 48 49 50
    }
  }

  CHECK_GT_OR_FALSE(input_dims.size(),
                    static_cast<size_t>(param_.in_num_col_dims));
  param_.in_mat_dims = input_dims.Flatten2D(param_.in_num_col_dims);
  // CHECK_EQ_OR_FALSE(param_.in_mat_dims[1], w_dims[0]);

  return true;
}

51
bool FcOpLite::InferShapeImpl() const {
52 53 54 55
  const auto& input_dims = param_.input->dims();
  const auto& w_dims = param_.w->dims();
  int in_num_col_dims = param_.in_num_col_dims;
  int64_t w_dims_1 = param_.padding_weights ? w_dims[1] - 4 : w_dims[1];
Y
Yan Chunwei 已提交
56 57

  // Set output dims
58 59
  std::vector<DDim::value_type> output_dims(in_num_col_dims + 1);
  for (int i = 0; i < in_num_col_dims; ++i) {
Y
Yan Chunwei 已提交
60 61
    output_dims[i] = input_dims[i];
  }
62 63
  output_dims[in_num_col_dims] = w_dims_1;
  param_.output->Resize(output_dims);
Y
Yan Chunwei 已提交
64 65

  // share LoD
66
  param_.output->set_lod(param_.input->lod());
X
xiaogang 已提交
67

Y
Yan Chunwei 已提交
68 69 70
  return true;
}

71
bool FcOpLite::AttachImpl(const cpp::OpDesc& op_desc, lite::Scope* scope) {
Y
Yan Chunwei 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
  auto input = op_desc.Input("Input").front();
  auto W = op_desc.Input("W").front();
  auto out = op_desc.Output("Out").front();

  param_.input = scope->FindVar(input)->GetMutable<lite::Tensor>();
  param_.w = scope->FindVar(W)->GetMutable<lite::Tensor>();
  std::vector<std::string> input_arg_names = op_desc.InputArgumentNames();
  if (std::find(input_arg_names.begin(), input_arg_names.end(), "Bias") !=
      input_arg_names.end()) {
    auto bias_arguments = op_desc.Input("Bias");
    if (bias_arguments.size() > 0) {
      auto bias_var = scope->FindVar(bias_arguments.front());
      if (bias_var != nullptr) {
        param_.bias = bias_var->GetMutable<lite::Tensor>();
      }
    }
  }
  CHECK(scope->FindVar(out));
  param_.output = scope->FindVar(out)->GetMutable<lite::Tensor>();
  param_.in_num_col_dims = op_desc.GetAttr<int>("in_num_col_dims");

93 94 95
  if (op_desc.HasAttr("activation_type")) {
    param_.activation_type = op_desc.GetAttr<std::string>("activation_type");
  }
96
  if (op_desc.HasAttr("padding_weights")) {
97 98 99
    param_.padding_weights = op_desc.GetAttr<bool>("padding_weights");
  } else {
    param_.padding_weights = false;
100
  }
101

Y
Yan Chunwei 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
  // For Int8
  if (op_desc.HasAttr("enable_int8")) {
    param_.enable_int8 = op_desc.GetAttr<bool>("enable_int8");
    if (op_desc.HasAttr("input_scale"))
      param_.input_scale = op_desc.GetAttr<float>("input_scale");
    if (op_desc.HasAttr("weight_scale"))
      param_.weight_scale = op_desc.GetAttr<std::vector<float>>("weight_scale");
    if (op_desc.HasAttr("output_scale"))
      param_.output_scale = op_desc.GetAttr<float>("output_scale");
  }
  return true;
}

}  // namespace operators
}  // namespace lite
}  // namespace paddle

REGISTER_LITE_OP(fc, paddle::lite::operators::FcOpLite);