fill_constant_op.cc 5.3 KB
Newer Older
1
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14

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 16 17
#include "paddle/fluid/framework/data_type.h"
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/operators/math/math_function.h"
18 19 20 21

namespace paddle {
namespace operators {

22
class FillConstantInferShape : public framework::InferShapeBase {
23
 public:
24
  void operator()(framework::InferShapeContext *ctx) const override {
25 26
    PADDLE_ENFORCE(ctx->HasOutput("Out"),
                   "Output(Out) of FillConstantOp should not be null.");
T
tangwei12 已提交
27
    auto &shape = ctx->Attrs().Get<std::vector<int64_t>>("shape");
Y
Yu Yang 已提交
28
    ctx->SetOutputDim("Out", framework::make_ddim(shape));
29
  }
30 31 32 33 34 35 36 37 38 39 40 41 42
};

class FillConstantOp : public framework::OperatorBase {
 public:
  using framework::OperatorBase::OperatorBase;

 private:
  void RunImpl(const framework::Scope &scope,
               const platform::Place &dev_place) const override {
    auto data_type =
        static_cast<framework::proto::VarType::Type>(Attr<int>("dtype"));
    auto value = Attr<float>("value");
    auto force_cpu = Attr<bool>("force_cpu");
T
tangwei12 已提交
43 44 45 46 47

    framework::Tensor *tensor = nullptr;

    auto &out_var = *scope.FindVar(Output("Out"));

X
Xin Pan 已提交
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
    if (out_var.IsType<framework::LoDTensor>()) {
      tensor = out_var.GetMutable<framework::LoDTensor>();
      tensor->Resize(framework::make_ddim(Attr<std::vector<int64_t>>("shape")));
    } else if (out_var.IsType<framework::SelectedRows>()) {
      tensor = out_var.GetMutable<framework::SelectedRows>()->mutable_value();
      tensor->Resize(framework::make_ddim(Attr<std::vector<int64_t>>("shape")));
    } else {
      PADDLE_THROW(
          "fill constant op's output only"
          "supports SelectedRows and LoDTensor");
    }

    if (force_cpu) {
      auto cpu = platform::CPUPlace();
      tensor->mutable_data(cpu, data_type);
    } else {
      tensor->mutable_data(dev_place, data_type);
    }

    platform::DeviceContextPool &pool = platform::DeviceContextPool::Instance();
    auto &dev_ctx = *pool.Get(dev_place);
    math::set_constant(dev_ctx, tensor, value);
  }

  void RunImpl(const framework::RuntimeContext &ctx,
               const platform::Place &dev_place) const override {
    auto data_type =
        static_cast<framework::proto::VarType::Type>(Attr<int>("dtype"));
    auto value = Attr<float>("value");
    auto force_cpu = Attr<bool>("force_cpu");

    framework::Tensor *tensor = nullptr;

    auto &out_var = *ctx.outputs.at("Out")[0];

T
tangwei12 已提交
83 84
    if (out_var.IsType<framework::LoDTensor>()) {
      tensor = out_var.GetMutable<framework::LoDTensor>();
T
tangwei12 已提交
85
      tensor->Resize(framework::make_ddim(Attr<std::vector<int64_t>>("shape")));
T
tangwei12 已提交
86 87
    } else if (out_var.IsType<framework::SelectedRows>()) {
      tensor = out_var.GetMutable<framework::SelectedRows>()->mutable_value();
T
tangwei12 已提交
88
      tensor->Resize(framework::make_ddim(Attr<std::vector<int64_t>>("shape")));
T
tangwei12 已提交
89 90 91 92 93 94
    } else {
      PADDLE_THROW(
          "fill constant op's output only"
          "supports SelectedRows and LoDTensor");
    }

95 96
    if (force_cpu) {
      auto cpu = platform::CPUPlace();
Y
Yu Yang 已提交
97
      tensor->mutable_data(cpu, data_type);
98
    } else {
Y
Yu Yang 已提交
99
      tensor->mutable_data(dev_place, data_type);
100
    }
D
dzhwinter 已提交
101

102 103
    platform::DeviceContextPool &pool = platform::DeviceContextPool::Instance();
    auto &dev_ctx = *pool.Get(dev_place);
T
tangwei12 已提交
104
    math::set_constant(dev_ctx, tensor, value);
105 106 107
  }
};

108 109 110 111 112 113
class FillConstantOpVarTypeInference : public framework::VarTypeInference {
 public:
  void operator()(const framework::OpDesc &op_desc,
                  framework::BlockDesc *block) const override {}
};

114 115
class FillConstantOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
Y
Yu Yang 已提交
116
  void Make() override {
F
fengjiayi 已提交
117
    AddAttr<int>("dtype",
118 119
                 "(int, default 5 (FP32)) "
                 "Output data type")
120
        .SetDefault(framework::proto::VarType::FP32);
T
tangwei12 已提交
121 122
    AddAttr<std::vector<int64_t>>("shape",
                                  "(vector<int64_t>) The shape of the output");
123 124
    AddAttr<float>("value", "(float, default 0) The value to be filled")
        .SetDefault(0.0f);
Y
Yu Yang 已提交
125 126 127 128 129
    AddAttr<bool>("force_cpu",
                  "(bool, default false) Force fill output variable to cpu "
                  "memory. Otherwise, fill output variable to the running "
                  "device")
        .SetDefault(false);
130 131 132
    AddOutput("Out",
              "(Tensor) Tensor of specified shape will be filled "
              "with the specified value");
K
kexinzhao 已提交
133 134 135 136 137 138
    AddComment(R"DOC(
FillConstantBatchSizeLike Operator.

Fill up a variable with specified constant value.

)DOC");
139 140 141 142 143 144
  }
};
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
145 146
REGISTER_OPERATOR(fill_constant, ops::FillConstantOp,
                  ops::FillConstantInferShape, ops::FillConstantOpMaker,
147 148
                  paddle::framework::EmptyGradOpMaker,
                  ops::FillConstantOpVarTypeInference);