提交 8de04be7 编写于 作者: W wanghaoshuang

Fix unitest

上级 555ab3f5
...@@ -103,5 +103,34 @@ void LoDTensor::ShrinkInLevel(size_t level, size_t elem_begin, ...@@ -103,5 +103,34 @@ void LoDTensor::ShrinkInLevel(size_t level, size_t elem_begin,
lod_ = new_lod; lod_ = new_lod;
} }
Vector<size_t> repeat_lod(Vector<size_t> data, Vector<size_t> starts,
Vector<size_t> times, bool is_first) {
Vector<size_t> result;
result.push_back(data[0]);
size_t p = 0, start = 0, end = 0;
if (is_first == true) {
for (size_t i = 0; i < times.size(); ++i) {
result.push_back(data.back() + times[i] * (data[i + 1] - data[i]));
}
} else {
for (size_t i = 0; i < times.size(); ++i) {
while (starts[i] != data[p] && p < data.size()) {
++p;
}
start = p;
while (starts[i + 1] != data[p] && p < data.size()) {
++p;
}
end = p + 1;
for (size_t j = 0; j < times[i]; ++j) {
for (size_t index = start; index < end - 1; ++index) {
result.push_back(result.back() + data[index + 1] - data[index]);
}
}
}
}
return result;
}
} // namespace framework } // namespace framework
} // namespace paddle } // namespace paddle
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "paddle/memory/memcpy.h"
#include "paddle/platform/device_context.h"
#include "paddle/platform/place.h"
#ifdef PADDLE_WITH_CUDA #ifdef PADDLE_WITH_CUDA
#include <thrust/device_vector.h> #include <thrust/device_vector.h>
#include <thrust/host_vector.h> #include <thrust/host_vector.h>
...@@ -122,5 +125,9 @@ class LoDTensor : public Tensor { ...@@ -122,5 +125,9 @@ class LoDTensor : public Tensor {
private: private:
LoD lod_; LoD lod_;
}; };
Vector<size_t> repeat_lod(Vector<size_t> data, Vector<size_t> starts,
Vector<size_t> times, bool is_first);
} // namespace framework } // namespace framework
} // namespace paddle } // namespace paddle
...@@ -22,54 +22,6 @@ namespace operators { ...@@ -22,54 +22,6 @@ namespace operators {
using LoDTensor = framework::LoDTensor; using LoDTensor = framework::LoDTensor;
template <typename T>
using vector = framework::Vector<T>;
vector<size_t> repeat_lod(vector<size_t> data, vector<size_t> starts,
vector<size_t> times, bool is_first) {
vector<size_t> result;
result.push_back(data[0]);
size_t p = 0, start = 0, end = 0;
if (is_first == true) {
for (size_t i = 0; i < times.size(); ++i) {
result.push_back(data.back() + times[i] * (data[i + 1] - data[i]));
}
} else {
for (size_t i = 0; i < times.size(); ++i) {
while (starts[i] != data[p] && p < data.size()) {
++p;
}
start = p;
while (starts[i + 1] != data[p] && p < data.size()) {
++p;
}
end = p + 1;
for (size_t j = 0; j < times[i]; ++j) {
for (size_t index = start; index < end - 1; ++index) {
result.push_back(result.back() + data[index + 1] - data[index]);
}
}
}
}
return result;
}
template <typename Place, typename T>
void repeat_data(const T* src, T* dst, size_t size, vector<size_t> starts,
vector<size_t> times, Place place) {
const T* src_p = src;
T* dst_p = dst;
size_t count = 0;
for (size_t i = 0; i < times.size(); ++i) {
count = size * (starts[i + 1] - starts[i]);
for (size_t j = 0; j < times[i]; ++j) {
memory::Copy(place, dst_p, place, src_p, sizeof(T) * count);
dst_p += count;
}
src_p += count;
}
}
template <typename Place, typename T> template <typename Place, typename T>
class SeqExpandKernel : public framework::OpKernel<T> { class SeqExpandKernel : public framework::OpKernel<T> {
public: public:
...@@ -81,7 +33,7 @@ class SeqExpandKernel : public framework::OpKernel<T> { ...@@ -81,7 +33,7 @@ class SeqExpandKernel : public framework::OpKernel<T> {
auto x_lod = x->lod(); auto x_lod = x->lod();
if (x_lod.size() == 0) { if (x_lod.size() == 0) {
vector<size_t> level; framework::Vector<size_t> level;
for (int i = 0; i < x->dims()[0] + 1; ++i) { for (int i = 0; i < x->dims()[0] + 1; ++i) {
level.push_back(i); level.push_back(i);
} }
...@@ -91,7 +43,7 @@ class SeqExpandKernel : public framework::OpKernel<T> { ...@@ -91,7 +43,7 @@ class SeqExpandKernel : public framework::OpKernel<T> {
} }
size_t repeat = static_cast<size_t>(context.Attr<int>("repeat")); size_t repeat = static_cast<size_t>(context.Attr<int>("repeat"));
vector<size_t> repeats; framework::Vector<size_t> repeats;
if (repeat != 0) { if (repeat != 0) {
for (int i = 0; i < x_lod[0].size() - 1; ++i) { for (int i = 0; i < x_lod[0].size() - 1; ++i) {
repeats.push_back(repeat); repeats.push_back(repeat);
...@@ -107,21 +59,32 @@ class SeqExpandKernel : public framework::OpKernel<T> { ...@@ -107,21 +59,32 @@ class SeqExpandKernel : public framework::OpKernel<T> {
repeats.push_back((y_lod[0][i + 1] - y_lod[0][i]) / repeats.push_back((y_lod[0][i + 1] - y_lod[0][i]) /
(x_lod[0][i + 1] - x_lod[0][i])); (x_lod[0][i + 1] - x_lod[0][i]));
} }
out->Resize(x_dims); out->Resize(y->dims());
} }
framework::LoD out_lod; framework::LoD out_lod;
auto level0 = repeat_lod(x_lod[0], x_lod[0], repeats, true); auto level0 = framework::repeat_lod(x_lod[0], x_lod[0], repeats, true);
out_lod.push_back(level0); out_lod.push_back(level0);
for (int i = 1; i < x_lod.size(); ++i) { for (int i = 1; i < x_lod.size(); ++i) {
out_lod.push_back(repeat_lod(x_lod[i], x_lod[0], repeats, false)); out_lod.push_back(
framework::repeat_lod(x_lod[i], x_lod[0], repeats, false));
} }
size_t element_len = framework::product(x_dims) / x_dims[0]; size_t element_len = framework::product(x_dims) / x_dims[0];
T* out_data = out->mutable_data<T>(context.GetPlace()); T* out_data = out->mutable_data<T>(context.GetPlace());
// copy data
Place place = boost::get<Place>(context.GetPlace()); Place place = boost::get<Place>(context.GetPlace());
repeat_data<Place, T>(x_data, out_data, element_len, x_lod[0], repeats, size_t count = 0;
place); for (size_t i = 0; i < repeats.size(); ++i) {
count = element_len * (x_lod[0][i + 1] - x_lod[0][i]);
for (size_t j = 0; j < repeats[i]; ++j) {
memory::Copy(place, out_data, place, x_data, sizeof(T) * count);
out_data += count;
}
x_data += count;
}
out->set_lod(out_lod); out->set_lod(out_lod);
} }
}; };
...@@ -130,9 +93,9 @@ template <typename Place, typename T> ...@@ -130,9 +93,9 @@ template <typename Place, typename T>
class SeqExpandGradKernel : public framework::OpKernel<T> { class SeqExpandGradKernel : public framework::OpKernel<T> {
public: public:
void Compute(const framework::ExecutionContext& context) const override { void Compute(const framework::ExecutionContext& context) const override {
// auto* d_out = context.Input<Tensor>(framework::GradVarName("Out")); auto* d_out = context.Input<Tensor>(framework::GradVarName("Out"));
// auto* d_x = context.Output<Tensor>(framework::GradVarName("X")); auto* d_x = context.Output<Tensor>(framework::GradVarName("X"));
// d_x->mutable_data<T>(context.GetPlace()); d_x->mutable_data<T>(context.GetPlace());
} }
}; };
......
...@@ -29,17 +29,13 @@ def repeat_array(array, starts, times): ...@@ -29,17 +29,13 @@ def repeat_array(array, starts, times):
class TestSeqExpand(OpTest): class TestSeqExpand(OpTest):
def set_data(self): def set_data(self):
self.op_type = 'seq_expand' x_data = np.random.uniform(0.1, 1, [4, 1]).astype('float32')
x = np.random.uniform(0.1, 1, [3, 2, 2]).astype('float32') self.inputs = {'X': x_data}
y = np.zeros((6, 2, 2)).astype('float32')
y_lod = [[0, 2, 3, 6]]
self.inputs = {'X': (x, None), 'Y': (y, y_lod)}
self.repeat = 2 self.repeat = 2
def compute(self): def compute(self):
x_data, x_lod = self.inputs['X'] x = self.inputs['X']
print "x_data: %s" % x_data x_data, x_lod = x if type(x) == tuple else (x, None)
print "x_lod: %s" % x_lod
if not x_lod: if not x_lod:
x_lod = [[i for i in range(1 + x_data.shape[0])]] x_lod = [[i for i in range(1 + x_data.shape[0])]]
else: else:
...@@ -47,28 +43,16 @@ class TestSeqExpand(OpTest): ...@@ -47,28 +43,16 @@ class TestSeqExpand(OpTest):
if self.repeat: if self.repeat:
self.attrs = {'repeat': self.repeat} self.attrs = {'repeat': self.repeat}
repeats = (len(x_lod[0]) - 1) * [self.repeat] repeats = (len(x_lod[0]) - 1) * [self.repeat]
# get out shape
# out_shape = np.copy(x_data.shape)
# out_shape[0] = out_shape[0] * self.repeat
else: else:
y_data, y_lod = self.inputs['Y'] y_data, y_lod = self.inputs['Y']
print "y_lod: %s" % y_lod
#print "y_lod: %s" % y_lod
# get repeats
repeats = [((y_lod[0][i + 1] - y_lod[0][i]) / repeats = [((y_lod[0][i + 1] - y_lod[0][i]) /
(x_lod[0][i + 1] - x_lod[0][i])) (x_lod[0][i + 1] - x_lod[0][i]))
for i in range(len(y_lod[0]) - 1)] for i in range(len(y_lod[0]) - 1)]
# get out shape
# out_shape = y_data.shape
# get out lod
out_lod = [repeat(x_lod[0], x_lod[0], repeats, True)] + [ out_lod = [repeat(x_lod[0], x_lod[0], repeats, True)] + [
repeat(lod, x_lod[0], repeats, False) for lod in x_lod[1:] repeat(lod, x_lod[0], repeats, False) for lod in x_lod[1:]
] ]
# copy data
out = repeat_array(x_data.tolist(), x_lod[0], repeats) out = repeat_array(x_data.tolist(), x_lod[0], repeats)
self.outputs = {'Out': (out, out_lod)} self.outputs = {'Out': out}
print "outputs: %s" % self.outputs
def setUp(self): def setUp(self):
self.op_type = 'seq_expand' self.op_type = 'seq_expand'
...@@ -94,7 +78,7 @@ class TestSeqExpandCase1(TestSeqExpand): ...@@ -94,7 +78,7 @@ class TestSeqExpandCase1(TestSeqExpand):
class TestSeqExpandCase2(TestSeqExpand): class TestSeqExpandCase2(TestSeqExpand):
def set_data(self): def set_data(self):
x_data = np.random.uniform(0.1, 1, [4, 1]).astype('float32') x_data = np.random.uniform(0.1, 1, [4, 1]).astype('float32')
self.inputs = {'X': (x_data, None)} self.inputs = {'X': x_data}
self.repeat = 2 self.repeat = 2
...@@ -103,7 +87,7 @@ class TestSeqExpandCase3(TestSeqExpand): ...@@ -103,7 +87,7 @@ class TestSeqExpandCase3(TestSeqExpand):
x_data = np.random.uniform(0.1, 1, [3, 1]).astype('float32') x_data = np.random.uniform(0.1, 1, [3, 1]).astype('float32')
y_data = np.random.uniform(0.1, 1, [8, 1]).astype('float32') y_data = np.random.uniform(0.1, 1, [8, 1]).astype('float32')
y_lod = [[0, 1, 4, 8]] y_lod = [[0, 1, 4, 8]]
self.inputs = {'X': (x_data, None), 'Y': (y_data, y_lod)} self.inputs = {'X': x_data, 'Y': (y_data, y_lod)}
self.repeat = None self.repeat = None
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册