stack_op.cc 3.5 KB
Newer Older
X
Xin Pan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 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.

15 16
#include <memory>
#include <vector>
17

C
csy0225 已提交
18 19 20
#include "paddle/fluid/framework/infershape_utils.h"
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/phi/core/infermeta_utils.h"
21
#include "paddle/phi/infermeta/backward.h"
C
csy0225 已提交
22
#include "paddle/phi/infermeta/multiary.h"
X
Xin Pan 已提交
23 24 25

namespace plat = paddle::platform;
namespace ops = paddle::operators;
26 27 28 29 30 31 32 33

namespace paddle {
namespace operators {

class StackOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

34 35 36 37 38 39 40 41 42 43 44 45 46 47
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext &ctx) const override {
    auto input_data_type =
        framework::OperatorWithKernel::IndicateVarDataType(ctx, "X");

#ifdef PADDLE_WITH_MKLDNN
    if (this->CanMKLDNNBeUsed(ctx, input_data_type)) {
      return framework::OpKernelType(input_data_type, ctx.GetPlace(),
                                     framework::DataLayout::kMKLDNN,
                                     framework::LibraryType::kMKLDNN);
    }
#endif
    return framework::OpKernelType(input_data_type, ctx.GetPlace());
  }
48 49 50 51 52 53 54 55 56 57
};

class StackOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X", "The input of stack op.").AsDuplicable();
    AddOutput("Y", "The output of stack op.");
    AddAttr<int>("axis",
                 "The axis along which all of the Inputs(X) should be stacked.")
        .SetDefault(0);
58 59 60 61 62
    AddAttr<bool>(
        "use_mkldnn",
        "(bool, default false) Indicates if MKL-DNN kernel will be used")
        .SetDefault(false)
        .AsExtra();
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
    AddComment(R"DOC(
Stack Operator.
Stack all of the Inputs(X) into one tensor along Attr(axis). The dims of all Inputs(X) must be the same.
)DOC");
  }
};

class StackOpGrad : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;
};

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

 protected:
81
  void Apply(GradOpPtr<T> op) const override {
82 83 84 85 86 87 88 89 90 91
    op->SetType("stack_grad");
    op->SetInput(framework::GradVarName("Y"), this->OutputGrad("Y"));
    op->SetOutput(framework::GradVarName("X"), this->InputGrad("X", false));
    op->SetAttrMap(this->Attrs());
  }
};

}  // namespace operators
}  // namespace paddle

C
csy0225 已提交
92 93
DECLARE_INFER_SHAPE_FUNCTOR(stack, StackInferMetaFunctor,
                            PD_INFER_META(phi::StackInferMeta));
94 95
DECLARE_INFER_SHAPE_FUNCTOR(stack_grad, StackGradInferMetaFunctor,
                            PD_INFER_META(phi::StackGradInferMeta));
X
Xin Pan 已提交
96
REGISTER_OPERATOR(stack, ops::StackOp, ops::StackOpMaker,
H
hong 已提交
97
                  ops::StackGradOpMaker<paddle::framework::OpDesc>,
C
csy0225 已提交
98 99
                  ops::StackGradOpMaker<paddle::imperative::OpBase>,
                  StackInferMetaFunctor);
100
REGISTER_OPERATOR(stack_grad, ops::StackOpGrad, StackGradInferMetaFunctor);