Skip to content

Commit d697b6a

Browse files
committed
Modified code using LoDTensor
1 parent 00ad751 commit d697b6a

File tree

6 files changed

+65
-46
lines changed

6 files changed

+65
-46
lines changed

paddle/framework/lod_tensor.cc

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,25 +103,19 @@ void LoDTensor::ShrinkInLevel(size_t level, size_t elem_begin,
103103
lod_ = new_lod;
104104
}
105105

106-
Vector<size_t> expand_lod(Vector<size_t> level, Vector<size_t> starts,
106+
Vector<size_t> expand_lod(Vector<size_t> level, Vector<size_t> indexes,
107107
Vector<size_t> scales, bool repeat) {
108108
Vector<size_t> result;
109109
result.push_back(level[0]);
110-
size_t p = 0, start = 0, end = 0;
110+
size_t start = 0, end = 0;
111111
if (!repeat) {
112112
for (size_t i = 0; i < scales.size(); ++i) {
113113
result.push_back(result.back() + scales[i] * (level[i + 1] - level[i]));
114114
}
115115
} else {
116116
for (size_t i = 0; i < scales.size(); ++i) {
117-
while (starts[i] != level[p] && p < level.size()) {
118-
++p;
119-
}
120-
start = p;
121-
while (starts[i + 1] != level[p] && p < level.size()) {
122-
++p;
123-
}
124-
end = p + 1;
117+
start = indexes[i];
118+
end = indexes[i + 1];
125119
for (size_t j = 0; j < scales[i]; ++j) {
126120
for (size_t index = start; index < end - 1; ++index) {
127121
result.push_back(result.back() + level[index + 1] - level[index]);

paddle/framework/lod_tensor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class LoDTensor : public Tensor {
123123
LoD lod_;
124124
};
125125

126-
Vector<size_t> expand_lod(Vector<size_t> level, Vector<size_t> starts,
126+
Vector<size_t> expand_lod(Vector<size_t> level, Vector<size_t> indexes,
127127
Vector<size_t> scales, bool repeat);
128128

129129
} // namespace framework

paddle/operators/seq_expand_op.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,15 @@ by lod of input(Y) or 'repeat' attribute.
7777
Case 1:
7878
7979
Given a 2-level LoDTensor X:
80-
X.data = [1, 2 , 3, 4]
80+
X.data = [a, b , c, d]
8181
X.lod = [[0, 3, 4], [0, 1, 3, 4]]
8282
and
8383
repeat = 2
8484
then we get 3-level LoDTensor
85-
Out.data = [1, 2, 3, 1, 2, 3, 4, 4]
86-
Out.lod = [[0, 6, 8],
87-
[0, 3, 6, 7, 8],
88-
[0, 1, 3, 4, 6, 7, 8]]
85+
Out.lod = [[0, 6, 8],
86+
[0, 3, 6, 7, 8],
87+
[0, 1, 3, 4, 6, 7, 8]]
88+
Out.data = [a, b, c, a, b, c, d, d]
8989
9090
Case 2:
9191

paddle/operators/seq_expand_op.h

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,12 @@ class SeqExpandKernel : public framework::OpKernel<T> {
3333
auto x_dims = x->dims();
3434
auto x_lod = x->lod();
3535

36-
if (x_lod.size() == 0) {
37-
framework::Vector<size_t> level;
38-
for (int i = 0; i < x->dims()[0] + 1; ++i) {
39-
level.push_back(i);
40-
}
41-
x_lod.push_back(level);
42-
} else {
43-
x_lod.insert(x_lod.begin(), x_lod[0]);
36+
framework::Vector<size_t> level;
37+
size_t num = (x_lod.size() == 0) ? (x->dims()[0] + 1) : x_lod[0].size();
38+
for (int i = 0; i < num; ++i) {
39+
level.push_back(i);
4440
}
41+
x_lod.push_back(level);
4542

4643
size_t repeat = static_cast<size_t>(context.Attr<int>("repeat"));
4744
framework::Vector<size_t> scales;
@@ -56,19 +53,27 @@ class SeqExpandKernel : public framework::OpKernel<T> {
5653
} else {
5754
auto* y = context.Input<LoDTensor>("Y");
5855
auto y_lod = y->lod();
59-
for (int i = 0; i < y_lod[0].size() - 1; ++i) {
60-
scales.push_back((y_lod[0][i + 1] - y_lod[0][i]) /
61-
(x_lod[0][i + 1] - x_lod[0][i]));
56+
auto y_abs_lod = y_lod.ToAbsOffset();
57+
auto x_abs_lod = x_lod.ToAbsOffset();
58+
for (int i = 0; i < y_abs_lod[0].size() - 1; ++i) {
59+
scales.push_back((y_abs_lod[0][i + 1] - y_abs_lod[0][i]) /
60+
(x_abs_lod[0][i + 1] - x_abs_lod[0][i]));
6261
}
6362
out->Resize(y->dims());
6463
}
6564

65+
framework::Vector<size_t> indexes;
66+
for (int size_t i = 0; i < x_lod[0]; ++i) {
67+
indexes[i] = x_lod[0];
68+
}
6669
framework::LoD out_lod;
67-
auto level0 = framework::expand_lod(x_lod[0], x_lod[0], scales, false);
70+
auto level0 = framework::expand_lod(indexes, x_lod[0], scales, false);
6871
out_lod.push_back(level0);
6972
for (int i = 1; i < x_lod.size(); ++i) {
70-
out_lod.push_back(
71-
framework::expand_lod(x_lod[i], x_lod[0], scales, true));
73+
for (int j = 0; j < indexes.size(); ++j) {
74+
indexes[j] = x_lod[i - 1][indexes[j]];
75+
}
76+
out_lod.push_back(framework::expand_lod(x_lod[i], indexes, scales, true));
7277
}
7378

7479
size_t element_len = framework::product(x_dims) / x_dims[0];
@@ -80,7 +85,7 @@ class SeqExpandKernel : public framework::OpKernel<T> {
8085
if (platform::is_cpu_place(place)) {
8186
auto& cpu_place = boost::get<platform::CPUPlace>(place);
8287
for (size_t i = 0; i < scales.size(); ++i) {
83-
count = element_len * (x_lod[0][i + 1] - x_lod[0][i]);
88+
count = element_len * (x_abs_lod[0][i + 1] - x_abs_lod[0][i]);
8489
for (size_t j = 0; j < scales[i]; ++j) {
8590
memory::Copy(cpu_place, out_data, cpu_place, x_data,
8691
sizeof(T) * count);
@@ -95,7 +100,7 @@ class SeqExpandKernel : public framework::OpKernel<T> {
95100
context.device_context())
96101
.stream();
97102
for (size_t i = 0; i < scales.size(); ++i) {
98-
count = element_len * (x_lod[0][i + 1] - x_lod[0][i]);
103+
count = element_len * (x_abs_lod[0][i + 1] - x_abs_lod[0][i]);
99104
for (size_t j = 0; j < scales[i]; ++j) {
100105
memory::Copy(gpu_place, out_data, gpu_place, x_data,
101106
sizeof(T) * count, stream);
@@ -109,6 +114,11 @@ class SeqExpandKernel : public framework::OpKernel<T> {
109114
}
110115

111116
out->set_lod(out_lod);
117+
for (size_t i = 0; i < lod.size; i++) {
118+
for (size_t j = 0; j < lod[i].size(); j++) {
119+
LOG(INFO) << "lod[" << i << "][" << j "] = " << lod[i][j];
120+
}
121+
}
112122
}
113123
};
114124

@@ -121,13 +131,14 @@ class SeqExpandGradKernel : public framework::OpKernel<T> {
121131
auto* out = context.Input<LoDTensor>("Out");
122132
auto* d_x = context.Output<LoDTensor>(framework::GradVarName("X"));
123133
auto out_lod = out->lod();
134+
auto out_abs_lod = out_lod.ToAbsOffset();
124135
d_x->set_lod(x->lod());
125136
const T* d_out_data = d_out->data<T>();
126137
auto d_out_dims = d_out->dims();
127138
T* d_x_data = d_x->mutable_data<T>(context.GetPlace());
128139
size_t element_len = framework::product(d_out_dims) / d_out_dims[0];
129140
for (size_t i = 0; i < out->NumElements(); ++i) {
130-
size_t ele_count = out_lod[0][i + 1] - out_lod[0][i];
141+
size_t ele_count = out_abs_lod[0][i + 1] - out_abs_lod[0][i];
131142
size_t repeat = out->NumElements(0, i);
132143
Eigen::TensorMap<Eigen::Tensor<const T, 2>> d_out_t(
133144
d_out_data, static_cast<int>(repeat),

python/paddle/v2/framework/tests/op_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ def check_output_with_place(self, place, atol):
246246
else:
247247
actual = np.array(self.scope.find_var(out_name).get_tensor())
248248
expect = self.outputs[out_name]
249+
print "actual= %s" % actual
250+
print "expect = %s" % expect
249251
self.assertTrue(
250252
np.allclose(
251253
actual, expect, atol=atol),

python/paddle/v2/framework/tests/test_seq_expand.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,42 @@ def repeat_array(array, starts, times):
2727
return newlist
2828

2929

30+
def toAbsOffset(lod):
31+
for i in range(len(lod) - 2, -1, -1):
32+
for j in range(len(lod[i])):
33+
lod[i][j] = lod[i + 1][lod[i][j]]
34+
return lod
35+
36+
3037
class TestSeqExpand(OpTest):
38+
#class TestSeqExpand():
3139
def set_data(self):
3240
x_data = np.random.uniform(0.1, 1, [4, 1]).astype('float32')
3341
self.inputs = {'X': x_data}
3442
self.repeat = 2
3543

3644
def compute(self):
3745
x = self.inputs['X']
46+
print "x= %s" % x
3847
x_data, x_lod = x if type(x) == tuple else (x, None)
39-
if not x_lod:
40-
x_lod = [[i for i in range(1 + x_data.shape[0])]]
41-
else:
42-
x_lod = [x_lod[0]] + x_lod
48+
n = 1 + x_data.shape[0] if not x_lod else len(x_lod[0])
49+
x_lod = [[i for i in range(n)]] + x_lod
50+
x_abs_lod = toAbsOffset(x_lod)
4351
if self.repeat:
52+
print "repeat= %s" % self.repeat
4453
self.attrs = {'repeat': self.repeat}
4554
repeats = (len(x_lod[0]) - 1) * [self.repeat]
4655
else:
4756
y_data, y_lod = self.inputs['Y']
48-
repeats = [((y_lod[0][i + 1] - y_lod[0][i]) /
49-
(x_lod[0][i + 1] - x_lod[0][i]))
50-
for i in range(len(y_lod[0]) - 1)]
51-
out_lod = [repeat(x_lod[0], x_lod[0], repeats, True)] + [
52-
repeat(lod, x_lod[0], repeats, False) for lod in x_lod[1:]
53-
]
54-
out = repeat_array(x_data.tolist(), x_lod[0], repeats)
57+
print "y_lod: %s" % y_lod
58+
y_abs_lod = toAbsOffset(y_lod)
59+
repeats = [((y_abs_lod[0][i + 1] - y_abs_lod[0][i]) /
60+
(x_abs_lod[0][i + 1] - x_abs_lod[0][i]))
61+
for i in range(len(y_abs_lod[0]) - 1)]
62+
#out_lod = [repeat(x_lod[0], x_lod[0], repeats, True)] + [
63+
# repeat(lod, x_lod[0], repeats, False) for lod in x_lod[1:]
64+
#]
65+
out = repeat_array(x_data.tolist(), x_abs_lod[0], repeats)
5566
self.outputs = {'Out': out}
5667

5768
def setUp(self):
@@ -69,7 +80,7 @@ def test_check_grad(self):
6980
class TestSeqExpandCase1(TestSeqExpand):
7081
def set_data(self):
7182
x_data = np.random.uniform(0.1, 1, [7, 1]).astype('float32')
72-
x_lod = [[0, 5, 7], [0, 2, 5, 7]]
83+
x_lod = [[0, 2, 3], [0, 2, 5, 7]]
7384
self.inputs = {'X': (x_data, x_lod)}
7485
self.repeat = 2
7586

@@ -95,10 +106,11 @@ def set_data(self):
95106
x_data = np.random.uniform(0.1, 1, [5, 1]).astype('float32')
96107
x_lod = [[0, 2, 5]]
97108
y_data = np.random.uniform(0.1, 1, [13, 1]).astype('float32')
98-
y_lod = [[0, 4, 13], [0, 2, 4, 7, 10, 13]]
109+
y_lod = [[0, 2, 5], [0, 2, 4, 7, 10, 13]]
99110
self.inputs = {'X': (x_data, x_lod), 'Y': (y_data, y_lod)}
100111
self.repeat = None
101112

102113

103114
if __name__ == '__main__':
104115
unittest.main()
116+
# TestSeqExpandCase4().setUp()

0 commit comments

Comments
 (0)