Skip to content

Commit 8feb99b

Browse files
authored
Merge pull request #14740 from chengduoZH/cherry-pick_fix_clip.py
Cherry-pick Fix clip.py
2 parents 446af09 + 951f91f commit 8feb99b

16 files changed

+772
-122
lines changed

paddle/fluid/API.spec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ paddle.fluid.layers.grid_sampler ArgSpec(args=['x', 'grid', 'name'], varargs=Non
194194
paddle.fluid.layers.log_loss ArgSpec(args=['input', 'label', 'epsilon', 'name'], varargs=None, keywords=None, defaults=(0.0001, None))
195195
paddle.fluid.layers.add_position_encoding ArgSpec(args=['input', 'alpha', 'beta', 'name'], varargs=None, keywords=None, defaults=(None,))
196196
paddle.fluid.layers.bilinear_tensor_product ArgSpec(args=['x', 'y', 'size', 'act', 'name', 'param_attr', 'bias_attr'], varargs=None, keywords=None, defaults=(None, None, None, None))
197+
paddle.fluid.layers.merge_selected_rows ArgSpec(args=['x', 'name'], varargs=None, keywords=None, defaults=(None,))
198+
paddle.fluid.layers.get_tensor_from_selected_rows ArgSpec(args=['x', 'name'], varargs=None, keywords=None, defaults=(None,))
197199
paddle.fluid.layers.lstm ArgSpec(args=['input', 'init_h', 'init_c', 'max_len', 'hidden_size', 'num_layers', 'dropout_prob', 'is_bidirec', 'is_test', 'name', 'default_initializer', 'seed'], varargs=None, keywords=None, defaults=(0.0, False, False, None, None, -1))
198200
paddle.fluid.layers.data ArgSpec(args=['name', 'shape', 'append_batch_size', 'dtype', 'lod_level', 'type', 'stop_gradient'], varargs=None, keywords=None, defaults=(True, 'float32', 0, VarType.LOD_TENSOR, True))
199201
paddle.fluid.layers.open_files ArgSpec(args=['filenames', 'shapes', 'lod_levels', 'dtypes', 'thread_num', 'buffer_size', 'pass_num', 'is_test'], varargs=None, keywords=None, defaults=(None, None, 1, None))

paddle/fluid/operators/activation_op.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ framework::OpKernelType GetKernelType(const framework::ExecutionContext& ctx,
7676
}
7777
#endif
7878
return framework::OpKernelType(
79-
framework::ToDataType(ctx.Input<framework::Tensor>(name)->type()),
80-
ctx.GetPlace(), layout, library);
79+
framework::GetDataTypeOfVar(ctx.InputVar(name)), ctx.GetPlace(), layout,
80+
library);
8181
}
8282

8383
class ActivationOp : public framework::OperatorWithKernel {

paddle/fluid/operators/activation_op.h

Lines changed: 96 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ static std::unordered_set<std::string> InplaceOpSet = {
4141
"floor", "reciprocal", "relu6", "soft_relu", "hard_sigmoid",
4242
};
4343

44+
/* The following operator can be used to process SelectedRows, because the
45+
* output of those operator for zero is zero too.
46+
*/
47+
static std::unordered_set<std::string> CanBeUsedBySelectedRows = {
48+
"abs", "abs_grad", "square", "square_grad", "sqrt", "sqrt_grad"};
49+
4450
static bool IsInplace(std::string op) { return InplaceOpSet.count(op); }
4551

4652
template <typename DeviceContext, typename Functor>
@@ -50,16 +56,38 @@ class ActivationKernel
5056
using T = typename Functor::ELEMENT_TYPE;
5157

5258
void Compute(const framework::ExecutionContext& context) const override {
53-
auto& X = detail::Ref(context.Input<framework::Tensor>("X"),
54-
"Cannot get input tensor X, variable name = %s",
55-
context.op().Input("X"));
56-
57-
auto& Out = detail::Ref(context.Output<framework::Tensor>("Out"),
58-
"Cannot get output tensor Out, variable name = %s",
59-
context.op().Output("Out"));
60-
Out.mutable_data<T>(context.GetPlace());
59+
auto x_var = context.InputVar("X");
60+
auto out_var = context.OutputVar("Out");
61+
PADDLE_ENFORCE(x_var != nullptr,
62+
"Cannot get input Variable X, variable name = %s",
63+
context.op().Input("X"));
64+
PADDLE_ENFORCE(out_var != nullptr,
65+
"Cannot get output Variable Out, variable name = %s",
66+
context.op().Output("Out"));
67+
68+
framework::Tensor X, *Out;
69+
70+
if (CanBeUsedBySelectedRows.count(context.op().Type())) {
71+
X = detail::Ref(
72+
paddle::framework::GetLoDTensorOrSelectedRowsValueFromVar(*x_var),
73+
"Cannot get input Tensor X, variable name = %s",
74+
context.op().Input("X"));
75+
Out = paddle::framework::GetMutableLoDTensorOrSelectedRowsValueFromVar(
76+
out_var);
77+
} else {
78+
X = detail::Ref(context.Input<framework::Tensor>("X"),
79+
"Cannot get input Tensor X, variable name = %s",
80+
context.op().Input("X"));
81+
Out = context.Output<framework::Tensor>("Out");
82+
}
83+
84+
PADDLE_ENFORCE(Out != nullptr,
85+
"Cannot get output tensor Out, variable name = %s",
86+
context.op().Output("Out"));
87+
88+
Out->mutable_data<T>(context.GetPlace());
6189
auto x = framework::EigenVector<T>::Flatten(X);
62-
auto out = framework::EigenVector<T>::Flatten(Out);
90+
auto out = framework::EigenVector<T>::Flatten(*Out);
6391
auto* place =
6492
context.template device_context<DeviceContext>().eigen_device();
6593
Functor functor;
@@ -78,14 +106,54 @@ class ActivationGradKernel
78106
public:
79107
using T = typename Functor::ELEMENT_TYPE;
80108
void Compute(const framework::ExecutionContext& context) const override {
81-
auto* Out = context.Input<framework::Tensor>("Out");
82-
auto* dOut =
83-
context.Input<framework::Tensor>(framework::GradVarName("Out"));
84-
auto* dX = context.Output<framework::Tensor>(framework::GradVarName("X"));
109+
auto out_var = context.InputVar("Out");
110+
auto out_grad_var = context.InputVar(framework::GradVarName("Out"));
111+
auto x_grad_var = context.OutputVar(framework::GradVarName("X"));
112+
PADDLE_ENFORCE(out_var != nullptr,
113+
"Cannot get input Variable Out, variable name = %s",
114+
context.op().Input("Out"));
115+
PADDLE_ENFORCE(out_grad_var != nullptr,
116+
"Cannot get input Variable %s, variable name = %s",
117+
framework::GradVarName("Out"),
118+
context.op().Input(framework::GradVarName("Out")));
119+
PADDLE_ENFORCE(x_grad_var != nullptr,
120+
"Cannot get output Variable %s, variable name = %s",
121+
framework::GradVarName("X"),
122+
context.op().Output(framework::GradVarName("X")));
123+
124+
framework::Tensor Out, dOut, *dX;
125+
if (CanBeUsedBySelectedRows.count(context.op().Type())) {
126+
Out = detail::Ref(
127+
paddle::framework::GetLoDTensorOrSelectedRowsValueFromVar(*out_var),
128+
"Cannot get input Tensor Out, variable name = %s",
129+
context.op().Input("Out"));
130+
dOut =
131+
detail::Ref(paddle::framework::GetLoDTensorOrSelectedRowsValueFromVar(
132+
*out_grad_var),
133+
"Cannot get input Tensor %s, variable name = %s",
134+
framework::GradVarName("Out"),
135+
context.op().Input(framework::GradVarName("Out")));
136+
dX = paddle::framework::GetMutableLoDTensorOrSelectedRowsValueFromVar(
137+
x_grad_var);
138+
} else {
139+
Out = detail::Ref(context.Input<framework::Tensor>("Out"),
140+
"Cannot get input Tensor Out, variable name = %s",
141+
context.op().Input("Out"));
142+
dOut = detail::Ref(
143+
context.Input<framework::Tensor>(framework::GradVarName("Out")),
144+
"Cannot get input Tensor %s, variable name = %s",
145+
framework::GradVarName("Out"),
146+
context.op().Input(framework::GradVarName("Out")));
147+
dX = context.Output<framework::Tensor>(framework::GradVarName("X"));
148+
}
149+
PADDLE_ENFORCE(dX != nullptr,
150+
"Cannot get output tensor %s, variable name = %s",
151+
framework::GradVarName("X"),
152+
context.op().Output(framework::GradVarName("X")));
85153
dX->mutable_data<T>(context.GetPlace());
86154

87-
auto dout = framework::EigenVector<T>::Flatten(*dOut);
88-
auto out = framework::EigenVector<T>::Flatten(*Out);
155+
auto dout = framework::EigenVector<T>::Flatten(dOut);
156+
auto out = framework::EigenVector<T>::Flatten(Out);
89157
auto dx = framework::EigenVector<T>::Flatten(*dX);
90158
auto* place =
91159
context.template device_context<DeviceContext>().eigen_device();
@@ -96,8 +164,19 @@ class ActivationGradKernel
96164
}
97165
bool inplace = functor.Inplace();
98166
if (!inplace) {
99-
auto* X = context.Input<framework::Tensor>("X");
100-
auto x = framework::EigenVector<T>::Flatten(*X);
167+
auto x_var = context.InputVar("X");
168+
PADDLE_ENFORCE(x_var != nullptr,
169+
"Cannot get input tensor X, variable name = %s",
170+
context.op().Input("X"));
171+
framework::Tensor X;
172+
if (CanBeUsedBySelectedRows.count(context.op().Type())) {
173+
X = detail::Ref(
174+
paddle::framework::GetLoDTensorOrSelectedRowsValueFromVar(*x_var));
175+
} else {
176+
X = detail::Ref(context.Input<framework::Tensor>("X"));
177+
}
178+
179+
auto x = framework::EigenVector<T>::Flatten(X);
101180
functor(*place, x, out, dout, dx);
102181
} else {
103182
VLOG(10) << " Inplace activation ";

paddle/fluid/operators/elementwise/elementwise_mul_op.h

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,37 @@ template <typename DeviceContext, typename T>
6060
class ElementwiseMulKernel : public framework::OpKernel<T> {
6161
public:
6262
void Compute(const framework::ExecutionContext& ctx) const override {
63-
auto* x = ctx.Input<framework::LoDTensor>("X");
63+
auto x_var = ctx.InputVar("X");
64+
PADDLE_ENFORCE(x_var != nullptr,
65+
"Cannot get input Variable X, variable name = %s",
66+
ctx.op().Input("X"));
6467
auto* y = ctx.Input<framework::LoDTensor>("Y");
65-
auto* z = ctx.Output<framework::LoDTensor>("Out");
68+
69+
framework::Tensor x, *z;
70+
if (x_var->IsType<framework::SelectedRows>()) {
71+
PADDLE_ENFORCE(y->dims().size() == 1 && y->dims()[0] == 1,
72+
"For elementwise_op, if X is Sparse, Y must be scalar.");
73+
auto& x_sele = x_var->Get<framework::SelectedRows>();
74+
auto out_sele = ctx.Output<framework::SelectedRows>("Out");
75+
x = x_sele.value();
76+
out_sele->set_rows(x_sele.rows());
77+
out_sele->set_height(x_sele.height());
78+
out_sele->mutable_value()->Resize(x_sele.value().dims());
79+
out_sele->mutable_value()->mutable_data(ctx.GetPlace(), x.type());
80+
z = ctx.Output<framework::SelectedRows>("Out")->mutable_value();
81+
} else if (x_var->IsType<framework::LoDTensor>()) {
82+
x = x_var->Get<framework::LoDTensor>();
83+
z = ctx.Output<framework::LoDTensor>("Out");
84+
} else {
85+
PADDLE_THROW("X's type[%s] is not supported by elementwise_op.",
86+
x_var->Type().name());
87+
}
6688

6789
z->mutable_data<T>(ctx.GetPlace());
68-
if (x->numel() == y->numel()) {
69-
elementwise_mul<DeviceContext, T>(ctx, x, y, z);
90+
if (x.numel() == y->numel()) {
91+
elementwise_mul<DeviceContext, T>(ctx, &x, y, z);
7092
} else {
71-
default_elementwise_mul<DeviceContext, T>(ctx, x, y, z);
93+
default_elementwise_mul<DeviceContext, T>(ctx, &x, y, z);
7294
}
7395
}
7496
};

paddle/fluid/operators/elementwise/elementwise_op.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,28 @@ class ElementwiseOp : public framework::OperatorWithKernel {
4040
PADDLE_ENFORCE(ctx->HasOutput("Out"),
4141
"Output(Out) of elementwise op should not be null.");
4242

43-
PADDLE_ENFORCE(
44-
ctx->GetInputsVarType("X").front() ==
45-
framework::proto::VarType::LOD_TENSOR,
46-
"The input var's type should be LoDTensor, but the received is %s",
47-
ctx->Inputs("X").front(), ctx->GetInputsVarType("X").front());
4843
PADDLE_ENFORCE(
4944
ctx->GetInputsVarType("Y").front() ==
5045
framework::proto::VarType::LOD_TENSOR,
51-
"The input var's type should be LoDTensor, but the received is %s",
52-
ctx->Inputs("Y").front(), ctx->GetInputsVarType("Y").front());
53-
54-
auto x_dim = ctx->GetInputDim("X");
55-
auto y_dim = ctx->GetInputDim("Y");
56-
PADDLE_ENFORCE_GE(x_dim.size(), y_dim.size(),
57-
"Rank of first input must >= rank of second input.");
46+
"The input var's type should be LoDTensor, but the received is %s [%s]",
47+
ctx->GetInputsVarType("Y").front(), ctx->Inputs("Y").front());
48+
49+
if (ctx->GetInputsVarType("X").front() ==
50+
framework::proto::VarType::LOD_TENSOR) {
51+
auto x_dim = ctx->GetInputDim("X");
52+
auto y_dim = ctx->GetInputDim("Y");
53+
PADDLE_ENFORCE_GE(x_dim.size(), y_dim.size(),
54+
"Rank of first input must >= rank of second input.");
55+
} else if (ctx->GetInputsVarType("X").front() ==
56+
framework::proto::VarType::SELECTED_ROWS) {
57+
PADDLE_ENFORCE((ctx->GetInputDim("Y").size() == 1u) &&
58+
(ctx->GetInputDim("Y")[0] == 1),
59+
"For elementwise_op, if X is Sparse, "
60+
"Y must be scalar.");
61+
} else {
62+
PADDLE_THROW("X's type[%s] is not supported by elementwise_op.",
63+
ctx->GetInputsVarType("X").front());
64+
}
5865

5966
ctx->ShareDim("X", /*->*/ "Out");
6067
ctx->ShareLoD("X", /*->*/ "Out");
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
15+
#include "paddle/fluid/framework/op_registry.h"
16+
#include "paddle/fluid/framework/tensor_util.h"
17+
18+
namespace paddle {
19+
namespace operators {
20+
21+
class GetTensorFromSelectedRowsOp : public framework::OperatorWithKernel {
22+
public:
23+
using framework::OperatorWithKernel::OperatorWithKernel;
24+
25+
void InferShape(framework::InferShapeContext *ctx) const override {
26+
PADDLE_ENFORCE(ctx->HasInput("X"),
27+
"GetTensorFromSelectedRowsOp must has input X.");
28+
PADDLE_ENFORCE(ctx->HasOutput("Out"),
29+
"GetTensorFromSelectedRowsOp must has output Out.");
30+
PADDLE_ENFORCE(
31+
ctx->GetInputsVarType("X").front() ==
32+
framework::proto::VarType::SELECTED_ROWS,
33+
"The input X's type should be SelectedRows, but the received is %s",
34+
ctx->Inputs("X").front(), ctx->GetInputsVarType("X").front());
35+
PADDLE_ENFORCE(
36+
ctx->GetOutputsVarType("Out").front() ==
37+
framework::proto::VarType::LOD_TENSOR,
38+
"The output Out's type should be LoDTensor, but the received is %s",
39+
ctx->Outputs("Out").front(), ctx->GetOutputsVarType("Out").front());
40+
41+
ctx->SetOutputDim("Out", ctx->GetInputDim("X"));
42+
}
43+
44+
protected:
45+
framework::OpKernelType GetExpectedKernelType(
46+
const framework::ExecutionContext &ctx) const override {
47+
return framework::OpKernelType(
48+
framework::GetDataTypeOfVar(ctx.InputVar("X")), ctx.device_context());
49+
}
50+
};
51+
52+
class GetTensorFromSelectedRowsKernel {
53+
public:
54+
void operator()(const framework::ExecutionContext &ctx) const {
55+
auto *x = ctx.Input<framework::SelectedRows>("X");
56+
auto *out = ctx.Output<framework::LoDTensor>("Out");
57+
58+
out->Resize(x->value().dims());
59+
out->mutable_data(ctx.GetPlace(), x->value().type());
60+
framework::TensorCopy(x->value(), ctx.GetPlace(), ctx.device_context(),
61+
out);
62+
}
63+
};
64+
65+
class GetTensorFromSelectedRowsOpProtoMaker
66+
: public framework::OpProtoAndCheckerMaker {
67+
public:
68+
void Make() override {
69+
AddInput("X", "The input type is SelectedRows.");
70+
AddOutput("Out", "The output type is LoDTensor.");
71+
AddComment(
72+
R"DOC(
73+
GetTensorFromSelectedRows Operator
74+
75+
GetTensorFromSelectedRows is used to get the tensor from SelectedRows.
76+
77+
)DOC");
78+
}
79+
};
80+
81+
class GetTensorFromSelectedRowsOpVarTypeInference
82+
: public framework::VarTypeInference {
83+
public:
84+
void operator()(const framework::OpDesc &op_desc,
85+
framework::BlockDesc *block) const final {
86+
auto out_var_name = op_desc.Output("Out").front();
87+
auto in_var_name = op_desc.Input("X").front();
88+
89+
auto out_var = block->FindRecursiveOrCreateVar(out_var_name);
90+
auto in_var = block->FindRecursiveOrCreateVar(in_var_name);
91+
out_var.SetType(framework::proto::VarType::LOD_TENSOR);
92+
out_var.SetDataType(in_var.GetDataType());
93+
}
94+
};
95+
96+
} // namespace operators
97+
} // namespace paddle
98+
99+
namespace ops = paddle::operators;
100+
REGISTER_OPERATOR(get_tensor_from_selected_rows,
101+
ops::GetTensorFromSelectedRowsOp,
102+
ops::GetTensorFromSelectedRowsOpProtoMaker,
103+
ops::GetTensorFromSelectedRowsOpVarTypeInference);
104+
105+
REGISTER_OP_CPU_KERNEL_FUNCTOR(get_tensor_from_selected_rows, float,
106+
ops::GetTensorFromSelectedRowsKernel, double,
107+
ops::GetTensorFromSelectedRowsKernel, int,
108+
ops::GetTensorFromSelectedRowsKernel, int64_t,
109+
ops::GetTensorFromSelectedRowsKernel);
110+
111+
#ifdef PADDLE_WITH_CUDA
112+
REGISTER_OP_CUDA_KERNEL_FUNCTOR(get_tensor_from_selected_rows, float,
113+
ops::GetTensorFromSelectedRowsKernel, double,
114+
ops::GetTensorFromSelectedRowsKernel, int,
115+
ops::GetTensorFromSelectedRowsKernel, int64_t,
116+
ops::GetTensorFromSelectedRowsKernel);
117+
#endif

0 commit comments

Comments
 (0)