softmax_op.cc 4.8 KB
Newer Older
H
hong19860320 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 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.

15
#include "lite/core/subgraph_bridge_registry.h"
H
hong19860320 已提交
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
#include "lite/kernels/apu/bridges/graph.h"
#include "lite/kernels/apu/bridges/utility.h"

namespace paddle {
namespace lite {
namespace subgraph {
namespace apu {

int SoftmaxConverter(void* ctx, OpLite* op, KernelBase* kernel) {
  CHECK(ctx != nullptr);
  CHECK(op != nullptr);
  auto graph = static_cast<Graph*>(ctx);
  auto model = graph->model();
  auto op_info = op->op_info();
  auto op_type = op_info->Type();
  auto scope = op->scope();
  VLOG(3) << "[APU] Converting [" + op_type + "]";

34 35 36
  CHECK(op_info->HasAttr("enable_int8") &&
        op_info->GetAttr<bool>("enable_int8"));

H
hong19860320 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50
  // Get input and output vars and op attributes
  auto x_name = op_info->Input("X").front();
  auto x = scope->FindMutableTensor(x_name);
  auto x_dims = x->dims();
  CHECK_GE(x_dims.size(), 2UL);
  auto x_rank = x_dims.size();
  auto out_name = op_info->Output("Out").front();

  // Check output shape
  auto axis = op_info->GetAttr<int>("axis");
  if (axis < 0) {
    axis += x_rank;
  }

51 52 53 54
  CHECK(op_info->HasInputScale(x_name));
  auto input_scale = op_info->GetInputScale(x_name)[0];
  CHECK(op_info->HasOutputScale(out_name));
  auto out_scale = op_info->GetOutputScale(out_name)[0];
H
hong19860320 已提交
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

  // Check output scale
  NeuronOperandType xType;
  xType.type = NEURON_TENSOR_QUANT8_ASYMM;
  xType.scale = input_scale;
  xType.zeroPoint = 128;
  xType.dimensionCount = x_dims.size();
  std::vector<uint32_t> dims_x;
  for (int i = 0; i < x_dims.size(); i++) dims_x.push_back(x_dims[i]);
  xType.dimensions = &dims_x[0];
  std::shared_ptr<Node> x_node = nullptr;
  if (graph->Has(x_name)) {
    x_node = graph->Get(x_name);
    VLOG(3) << "Graph has " << x_name << ",index: " << x_node->index();
  } else {
70
    NeuronModel_addOperand(model, &xType);  // Operand 0: input
H
hong19860320 已提交
71 72 73 74 75 76 77 78 79 80
    x_node = graph->Add(x_name, dims_x);
  }
  VLOG(3) << "input_scale size: " << input_scale
          << " ,x_dims size: " << x_dims.size() << " ,x_dims: " << x_dims;

  // Add beta operand
  std::vector<uint32_t> dims_int32 = {0};
  NeuronOperandType betaType;
  betaType.type = NEURON_FLOAT32;
  betaType.dimensionCount = 0;
81
  NeuronModel_addOperand(model, &betaType);  // Operand 1: beta
H
hong19860320 已提交
82 83 84 85 86 87 88
  std::shared_ptr<Node> beta_node = nullptr;
  beta_node = graph->Add(x_name + "_beta", dims_int32);

  // Add axis operand
  NeuronOperandType axisType;
  axisType.type = NEURON_INT32;
  axisType.dimensionCount = 0;
89
  NeuronModel_addOperand(model, &axisType);  // Operand 2: axis
H
hong19860320 已提交
90 91 92 93 94 95
  std::shared_ptr<Node> axis_node = nullptr;
  axis_node = graph->Add(x_name + "_axis", dims_int32);

  // Add out operand
  NeuronOperandType outType;
  outType.type = NEURON_TENSOR_QUANT8_ASYMM;
96
  outType.scale = out_scale;
H
hong19860320 已提交
97 98 99
  outType.zeroPoint = 128;
  outType.dimensionCount = x_dims.size();
  outType.dimensions = &dims_x[0];
100
  NeuronModel_addOperand(model, &outType);  // Operand 3: output
H
hong19860320 已提交
101 102
  std::shared_ptr<Node> out_node = nullptr;
  out_node = graph->Add(out_name, dims_x);
103
  VLOG(3) << "out_scale: " << out_scale;
H
hong19860320 已提交
104 105

  float beta_val[] = {1.0f};
106
  NeuronModel_setOperandValue(
H
hong19860320 已提交
107 108 109 110
      model, beta_node->index(), beta_val, sizeof(float) * 1);

  int32_t axis_val[1];
  axis_val[0] = axis;
111
  NeuronModel_setOperandValue(
H
hong19860320 已提交
112
      model, axis_node->index(), axis_val, sizeof(int32_t) * 1);
113 114 115
  std::vector<uint32_t> addInIndex = {x_node->index(),      // 0: input
                                      beta_node->index(),   // 1: beta
                                      axis_node->index()};  // 2: axis
H
hong19860320 已提交
116
  std::vector<uint32_t> addOutIndex = {out_node->index()};
117 118 119 120 121 122
  int neuron_errCode = NeuronModel_addOperation(model,
                                                NEURON_SOFTMAX,
                                                addInIndex.size(),
                                                &addInIndex[0],
                                                addOutIndex.size(),
                                                &addOutIndex[0]);
H
hong19860320 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
  if (NEURON_NO_ERROR != neuron_errCode) {
    LOG(WARNING) << "Add op fail:" << op_type;
    return FAILED;
  }

  return REBUILD_WHEN_SHAPE_CHANGED;
}

}  // namespace apu
}  // namespace subgraph
}  // namespace lite
}  // namespace paddle

REGISTER_SUBGRAPH_BRIDGE(softmax,
                         kAPU,
                         paddle::lite::subgraph::apu::SoftmaxConverter);