Skip to content

Commit 79df026

Browse files
authored
Merge pull request #16208 from PaddlePaddle/revert-16144-rnn_mem_opt
Revert "PaddingRNN model memory optimize"
2 parents 1c6caf8 + e993eff commit 79df026

File tree

12 files changed

+53
-418
lines changed

12 files changed

+53
-418
lines changed

paddle/fluid/operators/cross_entropy_op.cc

Lines changed: 19 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,19 @@ See the License for the specific language governing permissions and
1313
limitations under the License. */
1414

1515
#include "paddle/fluid/operators/cross_entropy_op.h"
16-
#include <memory>
1716
#include <string>
1817
#include <unordered_map>
1918

2019
namespace paddle {
2120
namespace operators {
2221

23-
class CrossEntropyOpBase : public framework::OperatorWithKernel {
22+
class CrossEntropyOp : public framework::OperatorWithKernel {
2423
public:
2524
using framework::OperatorWithKernel::OperatorWithKernel;
2625

2726
void InferShape(framework::InferShapeContext* ctx) const override {
2827
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
2928
PADDLE_ENFORCE(ctx->HasInput("Label"), "Input(Label) should be not null.");
30-
3129
PADDLE_ENFORCE(ctx->HasOutput("Y"), "Output(Y) should be not null.");
3230

3331
auto x_dims = ctx->GetInputDim("X");
@@ -46,8 +44,7 @@ class CrossEntropyOpBase : public framework::OperatorWithKernel {
4644
"Input(X) and Input(Label) shall have the same shape "
4745
"except the last dimension.");
4846
}
49-
50-
if (IsSoftLabel(ctx)) {
47+
if (ctx->Attrs().Get<bool>("soft_label")) {
5148
if (check) {
5249
PADDLE_ENFORCE_EQ(x_dims[rank - 1], label_dims[rank - 1],
5350
"If Attr(soft_label) == true, the last dimension of "
@@ -73,24 +70,21 @@ class CrossEntropyOpBase : public framework::OperatorWithKernel {
7370
return framework::OpKernelType(ctx.Input<Tensor>("X")->type(),
7471
ctx.device_context());
7572
}
76-
77-
virtual bool IsSoftLabel(framework::InferShapeContext* ctx) const {
78-
return ctx->Attrs().Get<bool>("soft_label");
79-
}
8073
};
8174

82-
class CrossEntropyGradientOpBase : public framework::OperatorWithKernel {
75+
class CrossEntropyGradientOp : public framework::OperatorWithKernel {
8376
public:
8477
using framework::OperatorWithKernel::OperatorWithKernel;
8578

86-
void InferShape(framework::InferShapeContext* ctx) const {
79+
void InferShape(framework::InferShapeContext* ctx) const override {
80+
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
8781
PADDLE_ENFORCE(ctx->HasInput("Label"), "Input(Label) should be not null.");
8882
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Y")),
8983
"Input(Y@GRAD) shoudl be not null.");
9084
PADDLE_ENFORCE(ctx->HasOutput(framework::GradVarName("X")),
9185
"Output(X@GRAD) should be not null.");
9286

93-
auto x_dims = GetXDim(ctx);
87+
auto x_dims = ctx->GetInputDim("X");
9488
auto label_dims = ctx->GetInputDim("Label");
9589
auto dy_dims = ctx->GetInputDim(framework::GradVarName("Y"));
9690
int rank = x_dims.size();
@@ -115,7 +109,9 @@ class CrossEntropyGradientOpBase : public framework::OperatorWithKernel {
115109
"The Input(X) and Input(Y@Grad) should have the same "
116110
"shape except the last dimension.");
117111
}
118-
if (IsSoftLabel(ctx)) {
112+
PADDLE_ENFORCE_EQ(dy_dims[rank - 1], 1,
113+
"The last dimension of Input(Y@Grad) should be 1.");
114+
if (ctx->Attrs().Get<bool>("soft_label")) {
119115
if (check) {
120116
PADDLE_ENFORCE_EQ(
121117
x_dims[rank - 1], label_dims[rank - 1],
@@ -128,39 +124,16 @@ class CrossEntropyGradientOpBase : public framework::OperatorWithKernel {
128124
"Input(Label) should be 1.");
129125
}
130126
ctx->SetOutputDim(framework::GradVarName("X"), x_dims);
131-
PADDLE_ENFORCE_EQ(dy_dims[rank - 1], 1,
132-
"The last dimension of Input(Y@Grad) should be 1.");
133-
ctx->SetOutputDim(framework::GradVarName("X"), x_dims);
134-
ctx->ShareLoD(VarNameWithXLoD(), framework::GradVarName("X"));
127+
ctx->ShareLoD("X", framework::GradVarName("X"));
135128
}
136129

137130
protected:
138131
// Explicitly set that the data type of computation kernel of cross_entropy
139132
// is determined by its input "X".
140133
framework::OpKernelType GetExpectedKernelType(
141134
const framework::ExecutionContext& ctx) const override {
142-
return framework::OpKernelType(
143-
ctx.Input<Tensor>(framework::GradVarName("Y"))->type(),
144-
ctx.device_context());
145-
}
146-
147-
virtual framework::DDim GetXDim(framework::InferShapeContext* ctx) const {
148-
return ctx->GetInputDim("X");
149-
}
150-
151-
virtual const char* VarNameWithXLoD() const { return "X"; }
152-
153-
virtual bool IsSoftLabel(framework::InferShapeContext* ctx) const {
154-
return ctx->Attrs().Get<bool>("soft_label");
155-
}
156-
};
157-
158-
class CrossEntropyOpInferVarType
159-
: public framework::PassInDtypeAndVarTypeToOutput {
160-
protected:
161-
std::unordered_map<std::string, std::string> GetInputOutputWithSameType()
162-
const override {
163-
return std::unordered_map<std::string, std::string>{{"X", /*->*/ "Y"}};
135+
return framework::OpKernelType(ctx.Input<Tensor>("X")->type(),
136+
ctx.device_context());
164137
}
165138
};
166139

@@ -228,137 +201,26 @@ or not. But the output only shares the LoD information with input X.
228201
}
229202
};
230203

231-
class CrossEntropyGradientOp : public CrossEntropyGradientOpBase {
232-
public:
233-
using CrossEntropyGradientOpBase::CrossEntropyGradientOpBase;
234-
235-
void InferShape(framework::InferShapeContext* ctx) const override {
236-
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) should be not null.");
237-
CrossEntropyGradientOpBase::InferShape(ctx);
238-
}
239-
};
240-
241-
class CrossEntropyOp2 : public CrossEntropyOpBase {
242-
public:
243-
using CrossEntropyOpBase::CrossEntropyOpBase;
244-
245-
void InferShape(framework::InferShapeContext* ctx) const override {
246-
CrossEntropyOpBase::InferShape(ctx);
247-
248-
PADDLE_ENFORCE(ctx->HasOutput("XShape"),
249-
"Output(XShape) should be not null.");
250-
251-
auto x_dims = ctx->GetInputDim("X");
252-
auto x_dims_vec = framework::vectorize(x_dims);
253-
x_dims_vec.push_back(0);
254-
ctx->SetOutputDim("XShape", framework::make_ddim(x_dims_vec));
255-
ctx->ShareLoD("X", /*->*/ "XShape");
256-
}
257-
258-
protected:
259-
bool IsSoftLabel(framework::InferShapeContext* ctx) const override {
260-
return false;
261-
}
262-
};
263-
264-
class CrossEntropyGradientOp2 : public CrossEntropyGradientOpBase {
265-
public:
266-
using CrossEntropyGradientOpBase::CrossEntropyGradientOpBase;
267-
268-
protected:
269-
virtual framework::DDim GetXDim(framework::InferShapeContext* ctx) const {
270-
auto x_shape = ctx->GetInputDim("XShape");
271-
return framework::DDim(x_shape.Get(), x_shape.size() - 1);
272-
}
273-
274-
virtual const char* VarNameWithXLoD() const { return "XShape"; }
275-
276-
virtual bool IsSoftLabel(framework::InferShapeContext* ctx) const {
277-
return false;
278-
}
279-
};
280-
281-
class CrossEntropyOpMaker2 : public framework::OpProtoAndCheckerMaker {
282-
public:
283-
void Make() override {
284-
AddInput("X",
285-
"(Tensor, default Tensor<float>), a tensor whose last dimension "
286-
"size is equal to the number of classes. This input is a "
287-
"probability computed by the previous operator, which is almost "
288-
"always the result of a softmax operator.");
289-
AddInput(
290-
"Label",
291-
"(Tensor), the tensor which represents the ground truth. It has the "
292-
"same shape with 'X' except the last dimension. One hot Tensor.");
293-
AddOutput("Y",
294-
"(Tensor, default Tensor<float>), a tensor whose shape is same "
295-
"with 'X' except that the last dimension size is 1. It "
296-
"represents the cross entropy loss.");
297-
AddOutput("XShape", "Temporaily variable to save shape and LoD of X.");
298-
AddAttr<int>("ignore_index",
299-
"(int, default -100), Specifies a target value that is"
300-
"ignored and does not contribute to the input gradient."
301-
"Only valid if soft_label is set to False")
302-
.SetDefault(-100);
303-
AddComment(R"DOC(
304-
Hard-label CrossEntropy Operator.
305-
306-
The input 'X' and 'Label' will first be logically flattened to 2-D matrixs.
307-
The matrix's second dimension(row length) is as same as the original last
308-
dimension, and the first dimension(column length) is the product of all other
309-
original dimensions. Then the softmax computation will take palce on each raw
310-
of flattened matrixs.
311-
312-
Only support hard label.
313-
314-
Both the input X and Label can carry the LoD (Level of Details) information,
315-
or not. But the output only shares the LoD information with input X.
316-
317-
)DOC");
318-
}
319-
};
320-
321-
class CrossEntropyGradOpDescMaker2 : public framework::SingleGradOpDescMaker {
322-
public:
323-
using framework::SingleGradOpDescMaker::SingleGradOpDescMaker;
324-
204+
class CrossEntropyOpInferVarType
205+
: public framework::PassInDtypeAndVarTypeToOutput {
325206
protected:
326-
std::unique_ptr<framework::OpDesc> Apply() const override {
327-
std::unique_ptr<framework::OpDesc> op(new framework::OpDesc());
328-
op->SetType("cross_entropy_grad2");
329-
op->SetInput("Label", Input("Label"));
330-
op->SetInput("Y", Output("Y"));
331-
op->SetInput("XShape", Output("XShape"));
332-
op->SetInput(framework::GradVarName("Y"), OutputGrad("Y"));
333-
op->SetOutput(framework::GradVarName("X"), InputGrad("X"));
334-
op->SetAttrMap(Attrs());
335-
return op;
207+
std::unordered_map<std::string, std::string> GetInputOutputWithSameType()
208+
const override {
209+
return std::unordered_map<std::string, std::string>{{"X", /*->*/ "Y"}};
336210
}
337211
};
338-
339212
} // namespace operators
340213
} // namespace paddle
341214

342215
namespace ops = paddle::operators;
343216
using CPUCtx = paddle::platform::CPUDeviceContext;
344217

345-
REGISTER_OPERATOR(cross_entropy, ops::CrossEntropyOpBase,
346-
ops::CrossEntropyOpMaker, ops::CrossEntropyOpInferVarType,
218+
REGISTER_OPERATOR(cross_entropy, ops::CrossEntropyOp, ops::CrossEntropyOpMaker,
219+
ops::CrossEntropyOpInferVarType,
347220
paddle::framework::DefaultGradOpDescMaker<true>);
348221
REGISTER_OPERATOR(cross_entropy_grad, ops::CrossEntropyGradientOp);
349222
REGISTER_OP_CPU_KERNEL(cross_entropy, ops::CrossEntropyOpKernel<CPUCtx, float>,
350223
ops::CrossEntropyOpKernel<CPUCtx, double>);
351224
REGISTER_OP_CPU_KERNEL(cross_entropy_grad,
352225
ops::CrossEntropyGradientOpKernel<CPUCtx, float>,
353226
ops::CrossEntropyGradientOpKernel<CPUCtx, double>);
354-
355-
REGISTER_OPERATOR(cross_entropy2, ops::CrossEntropyOp2,
356-
ops::CrossEntropyOpMaker2, ops::CrossEntropyOpInferVarType,
357-
ops::CrossEntropyGradOpDescMaker2);
358-
REGISTER_OPERATOR(cross_entropy_grad2, ops::CrossEntropyGradientOp2);
359-
REGISTER_OP_CPU_KERNEL(cross_entropy2,
360-
ops::CrossEntropyOpKernel2<CPUCtx, float>,
361-
ops::CrossEntropyOpKernel2<CPUCtx, double>);
362-
REGISTER_OP_CPU_KERNEL(cross_entropy_grad2,
363-
ops::CrossEntropyGradientOpKernel2<CPUCtx, float>,
364-
ops::CrossEntropyGradientOpKernel2<CPUCtx, double>);

paddle/fluid/operators/cross_entropy_op.cu

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,3 @@ REGISTER_OP_CUDA_KERNEL(
2727
cross_entropy_grad, ops::CrossEntropyGradientOpKernel<CUDACtx, float>,
2828
ops::CrossEntropyGradientOpKernel<CUDACtx, double>,
2929
ops::CrossEntropyGradientOpKernel<CUDACtx, plat::float16>);
30-
31-
REGISTER_OP_CUDA_KERNEL(cross_entropy2,
32-
ops::CrossEntropyOpKernel2<CUDACtx, float>,
33-
ops::CrossEntropyOpKernel2<CUDACtx, double>,
34-
ops::CrossEntropyOpKernel2<CUDACtx, plat::float16>);
35-
36-
REGISTER_OP_CUDA_KERNEL(
37-
cross_entropy_grad2, ops::CrossEntropyGradientOpKernel2<CUDACtx, float>,
38-
ops::CrossEntropyGradientOpKernel2<CUDACtx, double>,
39-
ops::CrossEntropyGradientOpKernel2<CUDACtx, plat::float16>);

paddle/fluid/operators/cross_entropy_op.h

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ limitations under the License. */
1515
#pragma once
1616
#include "paddle/fluid/framework/eigen.h"
1717
#include "paddle/fluid/framework/op_registry.h"
18-
#include "paddle/fluid/operators/math.h"
1918
#include "paddle/fluid/operators/math/cross_entropy.h"
2019
#include "paddle/fluid/operators/math/math_function.h"
2120
#include "paddle/fluid/platform/for_range.h"
@@ -138,85 +137,5 @@ class CrossEntropyGradientOpKernel : public framework::OpKernel<T> {
138137
}
139138
};
140139

141-
template <typename T>
142-
struct HardLabelCrossEntropyBackwardFunctor {
143-
HardLabelCrossEntropyBackwardFunctor(T* dx, const T* y, const T* dy,
144-
const int64_t* label,
145-
int64_t ignore_index,
146-
int64_t feature_size)
147-
: dx_(dx),
148-
y_(y),
149-
dy_(dy),
150-
label_(label),
151-
ignore_index_(ignore_index),
152-
feature_size_(feature_size) {}
153-
154-
HOSTDEVICE void operator()(int64_t idx) const {
155-
auto row_idx = idx / feature_size_;
156-
auto col_idx = idx % feature_size_;
157-
auto label = label_[row_idx];
158-
if (label == col_idx && label != ignore_index_) {
159-
dx_[idx] = -dy_[row_idx] * real_exp(y_[row_idx]);
160-
} else {
161-
dx_[idx] = 0;
162-
}
163-
}
164-
165-
T* dx_;
166-
const T* y_;
167-
const T* dy_;
168-
const int64_t* label_;
169-
int64_t ignore_index_;
170-
int64_t feature_size_;
171-
};
172-
173-
template <typename DeviceContext, typename T>
174-
class CrossEntropyOpKernel2 : public framework::OpKernel<T> {
175-
public:
176-
void Compute(const framework::ExecutionContext& ctx) const override {
177-
auto* x_original = ctx.Input<Tensor>("X");
178-
int rank = x_original->dims().size();
179-
180-
auto x = framework::ReshapeToMatrix(*x_original, rank - 1);
181-
auto label =
182-
framework::ReshapeToMatrix(*ctx.Input<Tensor>("Label"), rank - 1);
183-
auto* y = ctx.Output<Tensor>("Y");
184-
y->mutable_data<T>(ctx.GetPlace());
185-
186-
auto ignore_index = ctx.Attr<int>("ignore_index");
187-
188-
math::CrossEntropyFunctor<DeviceContext, T>()(
189-
ctx.template device_context<DeviceContext>(), y, &x, &label, false,
190-
ignore_index);
191-
}
192-
};
193-
194-
template <typename DeviceContext, typename T>
195-
class CrossEntropyGradientOpKernel2 : public framework::OpKernel<T> {
196-
public:
197-
void Compute(const framework::ExecutionContext& ctx) const override {
198-
auto* dx = ctx.Output<Tensor>(framework::GradVarName("X"));
199-
auto* y = ctx.Input<Tensor>("Y");
200-
auto* dy = ctx.Input<Tensor>(framework::GradVarName("Y"));
201-
auto* label = ctx.Input<Tensor>("Label");
202-
203-
auto* p_dx = dx->mutable_data<T>(ctx.GetPlace());
204-
auto* p_y = y->data<T>();
205-
auto* p_dy = dy->data<T>();
206-
auto* p_label = label->data<int64_t>();
207-
208-
int64_t ignore_index = ctx.Attr<int>("ignore_index");
209-
int rank = dx->dims().size();
210-
int64_t feature_size = dx->dims()[rank - 1];
211-
int64_t batch_size = framework::product(dx->dims()) / feature_size;
212-
213-
platform::ForRange<DeviceContext> for_range(
214-
ctx.template device_context<DeviceContext>(),
215-
batch_size * feature_size);
216-
for_range(HardLabelCrossEntropyBackwardFunctor<T>(
217-
p_dx, p_y, p_dy, p_label, ignore_index, feature_size));
218-
}
219-
};
220-
221140
} // namespace operators
222141
} // namespace paddle

0 commit comments

Comments
 (0)