Skip to content

Commit 823a3f0

Browse files
authored
Merge pull request #1224 from tianbingsz/context_projection
rewrite unit test for Context Projection
2 parents d9ea333 + 02c5ecc commit 823a3f0

File tree

5 files changed

+185
-175
lines changed

5 files changed

+185
-175
lines changed

paddle/function/BufferArg.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ class SequenceIdArg : public BufferArg {
190190
: BufferArg(VALUE_TYPE_INT32, shape, argType) {
191191
bufferType_ = TENSOR_SEQUENCE_ID;
192192
CHECK_EQ(shape_.ndims(), 1UL);
193-
CHECK_GT(shape_[0], 1UL);
193+
CHECK_GE(shape_[0], 1UL);
194194
numSeqs_ = shape_[0] - 1;
195195
}
196196

@@ -226,7 +226,8 @@ class SequenceArg : public BufferArg {
226226
SequenceArg(ValueType valueType,
227227
const TensorShape& shape,
228228
ArgType argType = UNSPECIFIED)
229-
: BufferArg(valueType, shape, argType), startPositions_(TensorShape()) {
229+
: BufferArg(valueType, shape, argType),
230+
startPositions_(TensorShape({shape[0]})) {
230231
bufferType_ = TENSOR_SEQUENCE_DATA;
231232
}
232233

paddle/function/ContextProjectionOp.cpp

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -108,37 +108,35 @@ class ContextProjectionForwardFunc : public FunctionBase {
108108
}
109109

110110
void calc(const BufferArgs& inputs, const BufferArgs& outputs) override {
111-
CHECK(1 == inputs.size() || 2 == inputs.size());
112-
CHECK_EQ((size_t)1, outputs.size());
111+
CHECK(1UL == inputs.size() || 2UL == inputs.size());
112+
CHECK_EQ(1UL, outputs.size());
113113
CHECK(inputs[0].isSequenceArg() && outputs[0].isSequenceArg())
114114
<< "SequenceArg required here";
115115
const auto val_seqs = dynamic_cast<const SequenceArg&>(inputs[0]);
116116
auto out_seq = dynamic_cast<const SequenceArg&>(outputs[0]);
117117

118118
CHECK(out_seq.data() && val_seqs.data() && val_seqs.getSequenceId().data());
119-
CHECK_EQ(out_seq.shape().ndims(), (size_t)2);
120-
CHECK_EQ(val_seqs.shape().ndims(), (size_t)2);
121-
CHECK_EQ(val_seqs.getSequenceId().shape().ndims(), (size_t)1);
122-
if (2 == inputs.size()) {
123-
CHECK_EQ(inputs[1].shape().ndims(), (size_t)2);
124-
}
119+
CHECK_EQ(out_seq.shape().ndims(), 2UL);
120+
CHECK_EQ(val_seqs.shape().ndims(), 2UL);
125121
/// dim of output = dim of input * context_length
126122
CHECK_EQ(out_seq.shape()[1], val_seqs.shape()[1] * context_length_);
127123
/// input and output has the same batch_size
128124
CHECK_EQ(val_seqs.shape()[0], out_seq.shape()[0]);
129-
/// dim of input == dim of weight
130-
if (2 == inputs.size()) {
125+
if (2UL == inputs.size()) {
126+
CHECK_EQ(inputs[1].shape().ndims(), 2UL);
127+
/// dim of input == dim of weight
131128
CHECK_EQ(val_seqs.shape()[1], inputs[1].shape()[1]);
132129
}
133130

134131
CHECK_EQ(out_seq.getArgType(), ADD_TO);
135132
auto out_mat = out_seq.matrix<Device>();
136133
const auto in_mat = val_seqs.matrix<Device>();
137134
const auto w_mat =
138-
(2 == inputs.size())
135+
(2UL == inputs.size() && inputs[1].data())
139136
? inputs[1].matrix<Device>()
140137
: typename Tensor<real, Device>::Matrix(nullptr, 0, 0);
141138
const auto seq_vec = val_seqs.getSequenceId().vector<int, Device>();
139+
142140
ContextProjectionForward<Device>(out_mat,
143141
in_mat,
144142
w_mat,
@@ -235,36 +233,40 @@ class ContextProjectionBackwardFunc : public FunctionBase {
235233
}
236234

237235
void calc(const BufferArgs& inputs, const BufferArgs& outputs) override {
238-
CHECK_EQ((size_t)1, inputs.size());
239-
CHECK_EQ((size_t)2, outputs.size());
236+
CHECK_EQ(1UL, inputs.size());
237+
CHECK(1UL == outputs.size() || 2UL == outputs.size());
240238
CHECK(inputs[0].isSequenceArg() && outputs[0].isSequenceArg())
241239
<< "SequenceArg required here";
242240
const auto in_seq = dynamic_cast<const SequenceArg&>(inputs[0]);
243241
auto out_seq = dynamic_cast<const SequenceArg&>(outputs[0]);
244242
CHECK(in_seq.data() && in_seq.getSequenceId().data());
245-
CHECK_EQ(in_seq.shape().ndims(), (size_t)2);
246-
CHECK_EQ(in_seq.getSequenceId().shape().ndims(), (size_t)1);
247-
CHECK_EQ(out_seq.shape().ndims(), (size_t)2);
248-
CHECK_EQ(out_seq.getSequenceId().shape().ndims(), (size_t)1);
249-
CHECK_EQ(outputs[1].shape().ndims(), (size_t)2);
243+
CHECK_EQ(in_seq.shape().ndims(), 2UL);
244+
CHECK_EQ(out_seq.shape().ndims(), 2UL);
245+
CHECK_EQ(out_seq.getSequenceId().shape().ndims(), 1UL);
250246

251-
/// dim of input grad == dim of weight
252-
CHECK_EQ(out_seq.shape()[1], outputs[1].shape()[1]);
253247
/// input and output grad has the same batch_size
254248
CHECK_EQ(out_seq.shape()[0], in_seq.shape()[0]);
255249
/// dim of output grad = dim of input grad * context_length
256250
CHECK_EQ(in_seq.shape()[1], out_seq.shape()[1] * context_length_);
257251
CHECK_EQ(out_seq.getArgType(), ADD_TO);
258-
CHECK_EQ(outputs[1].getArgType(), ADD_TO);
252+
253+
if (2UL == outputs.size()) {
254+
CHECK_EQ(outputs[1].shape().ndims(), 2UL);
255+
/// dim of input grad == dim of weight
256+
CHECK_EQ(out_seq.shape()[1], outputs[1].shape()[1]);
257+
CHECK_EQ(outputs[1].getArgType(), ADD_TO);
258+
}
259259

260260
const auto seq_vec = in_seq.getSequenceId().vector<int, Device>();
261261
const auto out_grad_mat = in_seq.matrix<Device>();
262262
auto in_grad_mat =
263263
!out_seq.data() ? typename Tensor<real, Device>::Matrix(nullptr, 0, 0)
264264
: out_seq.matrix<Device>();
265-
auto w_grad_mat = !outputs[1].data()
266-
? typename Tensor<real, Device>::Matrix(nullptr, 0, 0)
267-
: outputs[1].matrix<Device>();
265+
auto w_grad_mat =
266+
(2UL == outputs.size() && outputs[1].data())
267+
? outputs[1].matrix<Device>()
268+
: typename Tensor<real, Device>::Matrix(nullptr, 0, 0);
269+
268270
ContextProjectionBackward<Device>(out_grad_mat,
269271
in_grad_mat,
270272
w_grad_mat,
@@ -304,17 +306,17 @@ class ContextProjectionBackwardDataFunc : public FunctionBase {
304306
}
305307

306308
void calc(const BufferArgs& inputs, const BufferArgs& outputs) override {
307-
CHECK_EQ(1, static_cast<int>(inputs.size()));
308-
CHECK_EQ(1, static_cast<int>(outputs.size()));
309+
CHECK_EQ(1UL, inputs.size());
310+
CHECK_EQ(1UL, outputs.size());
309311
CHECK(inputs[0].isSequenceArg() && outputs[0].isSequenceArg())
310312
<< "SequenceArg required here";
311313
const auto in_seq = dynamic_cast<const SequenceArg&>(inputs[0]);
312314
const auto out_seq = dynamic_cast<const SequenceArg&>(outputs[0]);
313315

314316
CHECK(in_seq.data() && out_seq.data() && in_seq.getSequenceId().data());
315-
CHECK_EQ(static_cast<int>(out_seq.shape().ndims()), 2);
316-
CHECK_EQ(static_cast<int>(in_seq.shape().ndims()), 2);
317-
CHECK_EQ(static_cast<int>(in_seq.getSequenceId().shape().ndims()), 1);
317+
CHECK_EQ(out_seq.shape().ndims(), 2UL);
318+
CHECK_EQ(in_seq.shape().ndims(), 2UL);
319+
CHECK_EQ(in_seq.getSequenceId().shape().ndims(), 1UL);
318320
/// output layer grad dim == input layer grad dim * context_length_
319321
CHECK_EQ(in_seq.shape().ndims(), out_seq.shape().ndims() * context_length_);
320322
/// input and output has the same batch_size
@@ -355,14 +357,14 @@ class ContextProjectionBackwardWeightFunc : public FunctionBase {
355357
}
356358

357359
void calc(const BufferArgs& inputs, const BufferArgs& outputs) override {
358-
CHECK_EQ(1, static_cast<int>(inputs.size()));
359-
CHECK_EQ(1, static_cast<int>(outputs.size()));
360+
CHECK_EQ(1UL, inputs.size());
361+
CHECK_EQ(1UL, outputs.size());
360362
CHECK(inputs[0].isSequenceArg()) << "SequenceArg required here";
361363
const auto in_seq = dynamic_cast<const SequenceArg&>(inputs[0]);
362364
CHECK(in_seq.data() && in_seq.getSequenceId().data() && outputs[0].data());
363-
CHECK_EQ(static_cast<int>(outputs[0].shape().ndims()), 2);
364-
CHECK_EQ(static_cast<int>(in_seq.shape().ndims()), 2);
365-
CHECK_EQ(static_cast<int>(in_seq.getSequenceId().shape().ndims()), 1);
365+
CHECK_EQ(outputs[0].shape().ndims(), 2UL);
366+
CHECK_EQ(in_seq.shape().ndims(), 2UL);
367+
CHECK_EQ(in_seq.getSequenceId().shape().ndims(), 1UL);
366368
CHECK_EQ(in_seq.shape()[0], outputs[0].shape()[0]);
367369
/// output layer grad dim == weight dim * context_length_
368370
CHECK_EQ(in_seq.shape()[1], outputs[0].shape()[1] * context_length_);

paddle/function/ContextProjectionOp.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ See the License for the specific language governing permissions and
1313
limitations under the License. */
1414

1515
#pragma once
16-
1716
#include "Function.h"
1817

1918
namespace paddle {

paddle/function/ContextProjectionOpTest.cpp

Lines changed: 39 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -28,55 +28,26 @@ void testMatrixProjectionForward(int context_start,
2828
std::max(0, (int)(context_start + context_length - 1));
2929
if (pad == 0) is_padding = false;
3030

31-
FunctionCompare compare("ContextProjectionForward",
32-
FuncConfig()
33-
.set("context_length", context_length)
34-
.set("context_start", context_start)
35-
.set("begin_pad", std::max(0, -context_start)));
36-
37-
CpuMatrix cpu_in(batch_size, input_dim);
38-
cpu_in.randomizeUniform();
39-
GpuMatrix gpu_in(batch_size, input_dim);
40-
gpu_in.copyFrom(cpu_in);
41-
auto cpu_weight =
42-
is_padding ? std::make_shared<CpuMatrix>(pad, input_dim) : nullptr;
43-
auto gpu_weight =
44-
is_padding ? std::make_shared<GpuMatrix>(pad, input_dim) : nullptr;
45-
if (is_padding) {
46-
cpu_weight->randomizeUniform();
47-
gpu_weight->copyFrom(*cpu_weight);
31+
FunctionCompare test("ContextProjectionForward",
32+
FuncConfig()
33+
.set("context_length", context_length)
34+
.set("context_start", context_start)
35+
.set("begin_pad", std::max(0, -context_start)));
36+
37+
// prepare input arguments
38+
test.addSequence(SequenceIdArg(TensorShape{batch_size}));
39+
test.addInputs(
40+
SequenceArg(VALUE_TYPE_FLOAT, TensorShape{batch_size, input_dim}));
41+
if (is_padding) { // weight
42+
test.addInputs(SequenceArg(VALUE_TYPE_FLOAT, TensorShape{pad, input_dim}));
4843
}
49-
IVectorPtr cpu_seq;
50-
generateSequenceStartPositions(batch_size, cpu_seq);
51-
IVectorPtr gpu_seq = IVector::create(cpu_seq->getSize(), true);
52-
gpu_seq->copyFrom(*cpu_seq);
53-
54-
CpuMatrix cpu_out(batch_size, input_dim * context_length);
55-
GpuMatrix gpu_out(batch_size, input_dim * context_length);
56-
cpu_out.randomizeUniform();
57-
gpu_out.copyFrom(cpu_out);
58-
59-
BufferArgs cpu_inputs;
60-
BufferArgs cpu_outputs;
61-
cpu_inputs.addArg(cpu_in, *cpu_seq);
62-
if (cpu_weight) {
63-
cpu_inputs.addArg(*cpu_weight, *cpu_seq);
64-
}
65-
cpu_outputs.addArg(cpu_out, *cpu_seq, ADD_TO);
66-
67-
compare.getCpuFunction()->calc(cpu_inputs, cpu_outputs);
44+
test.addOutputs(
45+
SequenceArg(VALUE_TYPE_FLOAT,
46+
TensorShape{batch_size, input_dim * context_length}),
47+
ADD_TO);
6848

69-
BufferArgs gpu_inputs;
70-
BufferArgs gpu_outputs;
71-
gpu_inputs.addArg(gpu_in, *gpu_seq);
72-
if (gpu_weight) {
73-
gpu_inputs.addArg(*gpu_weight, *gpu_seq);
74-
}
75-
gpu_outputs.addArg(gpu_out, *gpu_seq, ADD_TO);
76-
77-
compare.getGpuFunction()->calc(gpu_inputs, gpu_outputs);
78-
79-
autotest::TensorCheckEqual(cpu_out, gpu_out);
49+
// run Function
50+
test.run();
8051
}
8152

8253
void testMatrixProjectionBackward(int context_start,
@@ -88,63 +59,31 @@ void testMatrixProjectionBackward(int context_start,
8859
std::max(0, (int)(context_start + context_length - 1));
8960
if (pad == 0) is_padding = false;
9061

91-
FunctionCompare compare("ContextProjectionBackward",
92-
FuncConfig()
93-
.set("context_length", context_length)
94-
.set("context_start", context_start)
95-
.set("begin_pad", std::max(0, -context_start))
96-
.set("is_padding", is_padding)
97-
.set("total_pad", pad));
98-
99-
CpuMatrix cpu_in_grad(batch_size, input_dim);
100-
cpu_in_grad.randomizeUniform();
101-
GpuMatrix gpu_in_grad(batch_size, input_dim);
102-
gpu_in_grad.copyFrom(cpu_in_grad);
103-
104-
CpuMatrix cpu_out_grad(batch_size, input_dim * context_length);
105-
cpu_out_grad.randomizeUniform();
106-
GpuMatrix gpu_out_grad(batch_size, input_dim * context_length);
107-
gpu_out_grad.copyFrom(cpu_out_grad);
108-
109-
IVectorPtr cpu_seq;
110-
generateSequenceStartPositions(batch_size, cpu_seq);
111-
IVectorPtr gpu_seq = IVector::create(cpu_seq->getSize(), true);
112-
gpu_seq->copyFrom(*cpu_seq);
113-
114-
auto cpu_w_grad =
115-
is_padding ? std::make_shared<CpuMatrix>(pad, input_dim) : nullptr;
116-
auto gpu_w_grad =
117-
is_padding ? std::make_shared<GpuMatrix>(pad, input_dim) : nullptr;
118-
if (is_padding) {
119-
cpu_w_grad->randomizeUniform();
120-
gpu_w_grad->copyFrom(*cpu_w_grad);
62+
FunctionCompare test("ContextProjectionBackward",
63+
FuncConfig()
64+
.set("context_length", context_length)
65+
.set("context_start", context_start)
66+
.set("begin_pad", std::max(0, -context_start))
67+
.set("is_padding", is_padding)
68+
.set("total_pad", pad));
69+
70+
// prepare input arguments
71+
test.addSequence(SequenceIdArg(TensorShape{batch_size}));
72+
test.addInputs(SequenceArg(
73+
VALUE_TYPE_FLOAT, TensorShape{batch_size, input_dim * context_length}));
74+
test.addOutputs(
75+
SequenceArg(VALUE_TYPE_FLOAT, TensorShape{batch_size, input_dim}),
76+
ADD_TO);
77+
if (is_padding) { // weight
78+
test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{pad, input_dim}),
79+
ADD_TO);
12180
}
12281

123-
BufferArgs cpu_inputs;
124-
BufferArgs cpu_outputs;
125-
cpu_inputs.addArg(cpu_out_grad, *cpu_seq);
126-
cpu_outputs.addArg(cpu_in_grad, *cpu_seq, ADD_TO);
127-
cpu_outputs.addArg(
128-
cpu_w_grad ? *cpu_w_grad : CpuMatrix(nullptr, 0, input_dim), ADD_TO);
129-
130-
compare.getCpuFunction()->calc(cpu_inputs, cpu_outputs);
131-
132-
BufferArgs gpu_inputs;
133-
BufferArgs gpu_outputs;
134-
gpu_inputs.addArg(gpu_out_grad, *gpu_seq);
135-
gpu_outputs.addArg(gpu_in_grad, *gpu_seq, ADD_TO);
136-
gpu_outputs.addArg(
137-
gpu_w_grad ? *gpu_w_grad : GpuMatrix(nullptr, 0, input_dim), ADD_TO);
138-
139-
compare.getGpuFunction()->calc(gpu_inputs, gpu_outputs);
140-
141-
autotest::TensorCheckErr(cpu_in_grad, gpu_in_grad);
142-
if (is_padding) {
143-
autotest::TensorCheckErr(*cpu_w_grad, *gpu_w_grad);
144-
}
82+
// run Function
83+
test.run();
14584
}
14685

147-
TEST(ContextProjection, projection) {
86+
TEST(ContextProjection, Projection) {
14887
for (auto context_start : {-5, -3, -1, 0, 3}) {
14988
for (auto context_length : {1, 2, 5, 7}) {
15089
for (auto trainable_padding : {false, true}) {

0 commit comments

Comments
 (0)