set_value_op.cc 11.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
//   Copyright (c) 2020 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 "paddle/fluid/operators/set_value_op.h"
16

17
#include <string>
18 19

#include "paddle/fluid/framework/infershape_utils.h"
20
#include "paddle/fluid/framework/op_version_registry.h"
21 22 23
#include "paddle/phi/core/infermeta_utils.h"
#include "paddle/phi/infermeta/unary.h"

24 25 26 27 28 29 30 31 32 33 34 35
namespace paddle {
namespace framework {
class InferShapeContext;
class OpDesc;
template <typename T>
class EmptyGradOpMaker;
}  // namespace framework
namespace imperative {
class OpBase;
}  // namespace imperative
}  // namespace paddle

36 37 38 39 40
namespace paddle {
namespace operators {

class SetValue : public framework::OperatorWithKernel {
 public:
41 42
  SetValue(const std::string &type,
           const framework::VariableNameMap &inputs,
43 44 45 46 47 48 49 50
           const framework::VariableNameMap &outputs,
           const framework::AttributeMap &attrs)
      : OperatorWithKernel(type, inputs, outputs, attrs) {}

 protected:
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext &ctx) const override {
    return framework::OpKernelType(
51
        OperatorWithKernel::IndicateVarDataType(ctx, "Input"), ctx.GetPlace());
52
  }
53 54

  framework::OpKernelType GetKernelTypeForVar(
55
      const std::string &var_name,
56
      const phi::DenseTensor &tensor,
57 58 59 60 61
      const framework::OpKernelType &expected_kernel_type) const override {
    if (var_name == "StartsTensorList" || var_name == "EndsTensorList" ||
        var_name == "StepsTensorList") {
      return expected_kernel_type;
    }
62 63
    return framework::OpKernelType(
        expected_kernel_type.data_type_, tensor.place(), tensor.layout());
64
  }
65 66 67 68 69
};

class SetValueMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
70
    // Input
71 72 73
    AddInput("Input", "(phi::DenseTensor) Input tensor of set_value operator.");
    AddInput("ValueTensor",
             "(phi::DenseTensor) Value tensor of set_value operator.")
74
        .AsDispensable();
75
    AddInput("StartsTensorList",
76 77
             "(vector<phi::DenseTensor<int32>>, optional) If provided, "
             "set_value will "
78 79 80 81 82
             "use this. The shape of the tensor in vector must be [1]."
             "It has higher priority compare with attr(starts).")
        .AsDuplicable()
        .AsDispensable();
    AddInput("EndsTensorList",
83 84
             "(vector<phi::DenseTensor<int32>>, optional) If provided, "
             "set_value will "
85 86 87 88 89 90
             "use this. The shape of the tensor in vector must BE [1]."
             "It has higher priority compare with attr(ends).")
        .AsDuplicable()
        .AsDispensable();

    AddInput("StepsTensorList",
91 92
             "(vector<phi::DenseTensor<int32>>, optional) If provided, "
             "set_value will "
93 94 95 96 97 98
             "use this. The shape of the tensor in vector must BE [1]."
             "It has higher priority compare with attr(steps).")
        .AsDuplicable()
        .AsDispensable();

    // Output
99
    AddOutput("Out",
100 101 102
              "(phi::DenseTensor) Output tensor of set_value operator. The "
              "output is the "
              "same phi::DenseTensor as input");
103

104
    // Attr
105
    AddAttr<int>("dtype", "data type of input.")
106 107 108 109
        .InEnum({framework::proto::VarType::BOOL,
                 framework::proto::VarType::INT32,
                 framework::proto::VarType::INT64,
                 framework::proto::VarType::FP32,
110 111
                 framework::proto::VarType::FP64,
                 framework::proto::VarType::FP16})
112 113 114 115 116
        .SetDefault(framework::proto::VarType::FP32);
    AddAttr<std::vector<int64_t>>(
        "axes", "(list<int64_t>) Axes that `starts` and `ends` apply to.");
    AddAttr<std::vector<int64_t>>(
        "starts",
117 118
        "(list<int64_t>) Starting indices of corresponding axis in `axes`.")
        .SetDefault({});
119 120
    AddAttr<std::vector<int64_t>>(
        "ends",
121 122 123 124 125
        "(list<int64_t>) Ending indices of corresponding axis in `axes`.")
        .SetDefault({});
    AddAttr<std::vector<int64_t>>(
        "steps", "(list<int64_t>) Stride step from the start to the end.")
        .SetDefault({});
126 127 128
    AddAttr<std::vector<int64_t>>("decrease_axes",
                                  "(list<int>) The axes to decrease.")
        .SetDefault({});
Z
zyfncg 已提交
129 130
    AddAttr<std::vector<int64_t>>("none_axes", "(list<int>) The axes to none.")
        .SetDefault({});
131

132
    AddAttr<std::vector<int>>("bool_values", "Store the bool values.")
133
        .SetDefault({});
134
    AddAttr<std::vector<float>>("fp32_values", "Store the float32 values.")
135
        .SetDefault({});
136
    AddAttr<std::vector<int>>("int32_values", "Store the int32 values.")
137
        .SetDefault({});
138
    AddAttr<std::vector<int64_t>>("int64_values", "Store the int64 values.")
139
        .SetDefault({});
140
    AddAttr<std::vector<double>>("fp64_values", "Store the float64 values.")
141
        .SetDefault({});
142 143
    AddAttr<std::vector<float>>("fp16_values", "Store the float16 values.")
        .SetDefault({});
144 145 146 147

    AddAttr<std::vector<int64_t>>("shape", "(vector<int64_t>) Shape of values.")
        .SetDefault({});
    AddComment(R"DOC(SetValue operator.
148
Assignment to a phi::DenseTensor in static graph mode.
149 150 151
)DOC");
  }
};
152 153 154 155 156 157 158 159 160

template <typename T>
class SetValueGradMaker : public framework::SingleGradOpMaker<T> {
 public:
  using framework::SingleGradOpMaker<T>::SingleGradOpMaker;

 protected:
  void Apply(GradOpPtr<T> op) const override {
    if (this->HasInput("ValueTensor")) {
161 162 163 164
      op->SetType("set_value_grad");

      op->SetInput(framework::GradVarName("Out"), this->OutputGrad("Out"));
      op->SetInput("ValueTensor", this->Input("ValueTensor"));
165 166 167 168 169 170
      if (this->HasInput("StartsTensorList")) {
        op->SetInput("StartsTensorList", this->Input("StartsTensorList"));
      }
      if (this->HasInput("EndsTensorList")) {
        op->SetInput("EndsTensorList", this->Input("EndsTensorList"));
      }
171 172 173 174 175 176 177 178 179
      if (this->HasInput("StepsTensorList")) {
        op->SetInput("StepsTensorList", this->Input("StepsTensorList"));
      }

      op->SetAttrMap(this->Attrs());

      op->SetOutput(framework::GradVarName("ValueTensor"),
                    this->InputGrad("ValueTensor"));
      op->SetOutput(framework::GradVarName("Input"), this->InputGrad("Input"));
180 181 182 183 184 185 186 187 188

    } else {
      op->SetType("assign");
      op->SetInput("X", this->OutputGrad("Out"));
      op->SetOutput("Out", this->InputGrad("Input"));
    }
  }
};

189 190 191 192 193
class SetValueGrad : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext *ctx) const override {
194 195 196 197
    OP_INOUT_CHECK(ctx->HasInput(framework::GradVarName("Out")),
                   "Input",
                   framework::GradVarName("Out"),
                   "set_value_grad");
198 199 200

    auto in_dims = ctx->GetInputDim(framework::GradVarName("Out"));
    PADDLE_ENFORCE_LT(
201 202
        in_dims.size(),
        7,
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
        platform::errors::InvalidArgument(
            "The dimension of set_value_grad operator's input should be less "
            "than 7, but received dimension is %d.",
            in_dims.size()));

    if (ctx->HasOutput(framework::GradVarName("ValueTensor"))) {
      ctx->ShareDim("ValueTensor",
                    /*->*/ framework::GradVarName("ValueTensor"));
      ctx->ShareLoD("ValueTensor",
                    /*->*/ framework::GradVarName("ValueTensor"));
    }
  }

 protected:
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext &ctx) const override {
219
    auto in_tensor = ctx.Input<phi::DenseTensor>(framework::GradVarName("Out"));
220 221 222 223 224
    return framework::OpKernelType(OperatorWithKernel::IndicateVarDataType(
                                       ctx, framework::GradVarName("Out")),
                                   in_tensor->place());
  }
  framework::OpKernelType GetKernelTypeForVar(
225
      const std::string &var_name,
226
      const phi::DenseTensor &tensor,
227 228 229 230 231
      const framework::OpKernelType &expected_kernel_type) const override {
    if (var_name == "StartsTensorList" || var_name == "EndsTensorList" ||
        var_name == "StepsTensorList") {
      return expected_kernel_type;
    }
232 233
    return framework::OpKernelType(
        expected_kernel_type.data_type_, tensor.place(), tensor.layout());
234 235 236
  }
};

237 238
DECLARE_INPLACE_OP_INFERER(SetValueOpInplaceInferer, {"Input", "Out"});

239 240 241 242
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
243
namespace plat = paddle::platform;
244

245 246
DECLARE_INFER_SHAPE_FUNCTOR(set_value,
                            SetValueInferShapeFunctor,
247 248
                            PD_INFER_META(phi::SetValueInferMeta));

249 250 251
REGISTER_OPERATOR(set_value,
                  ops::SetValue,
                  ops::SetValueMaker,
252 253
                  ops::SetValueGradMaker<paddle::framework::OpDesc>,
                  ops::SetValueGradMaker<paddle::imperative::OpBase>,
254 255
                  ops::SetValueOpInplaceInferer,
                  SetValueInferShapeFunctor);
256

257 258
REGISTER_OPERATOR(set_value_grad, ops::SetValueGrad);

259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
REGISTER_OP_VERSION(set_value)
    .AddCheckpoint(
        R"ROC(
Upgrade set_value, add 3 inputs [StartsTensorList, EndsTensorList, StepsTensorList] and 1 attribute [steps].
              )ROC",
        paddle::framework::compatible::OpVersionDesc()
            .NewInput("StartsTensorList",
                      "If provided, set_value will use this.The shape of the "
                      "tensor in vector must be [1]. It has higher priority "
                      "compare with attr(starts).")
            .NewInput("EndsTensorList",
                      "If provided, set_value will use this.The shape of the "
                      "tensor in vector must be [1]. It has higher priority "
                      "compare with attr(ends).")
            .NewInput("StepsTensorList",
                      "If provided, set_value will use this.The shape of the "
                      "tensor in vector must be [1]. It has higher priority "
                      "compare with attr(steps).")
            .ModifyAttr("starts",
                        "Starting indices of corresponding axis in `axes`.",
                        std::vector<int64_t>{})
            .ModifyAttr("ends",
                        "Ending indices of corresponding axis in `axes`.",
                        std::vector<int64_t>{})
283 284
            .NewAttr("steps",
                     "Stride step from the start to the end.",
285 286 287 288 289 290
                     std::vector<int64_t>{}))
    .AddCheckpoint(
        R"ROC(
Upgrade set_value, add 1 attribute [decrease_axes].
              )ROC",
        paddle::framework::compatible::OpVersionDesc().NewAttr(
Z
zyfncg 已提交
291 292 293 294 295 296 297
            "decrease_axes", "The axes to decrease.", std::vector<int64_t>{}))
    .AddCheckpoint(
        R"ROC(
Upgrade set_value, add 1 attribute [none_axes].
              )ROC",
        paddle::framework::compatible::OpVersionDesc().NewAttr(
            "none_axes", "The axes with none index.", std::vector<int64_t>{}));