提交 a94b3dd9 编写于 作者: W wanghaoshuang

Refine comments and function name

1. Add more comments and exmples
2. Rename repeat_lod to expand_lod
3. Remove unused head file
上级 a5adffd0
...@@ -103,28 +103,28 @@ void LoDTensor::ShrinkInLevel(size_t level, size_t elem_begin, ...@@ -103,28 +103,28 @@ 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> expand_lod(Vector<size_t> level, Vector<size_t> starts,
Vector<size_t> times, bool is_first) { Vector<size_t> scales, bool repeat) {
Vector<size_t> result; Vector<size_t> result;
result.push_back(data[0]); result.push_back(level[0]);
size_t p = 0, start = 0, end = 0; size_t p = 0, start = 0, end = 0;
if (is_first == true) { if (!repeat) {
for (size_t i = 0; i < times.size(); ++i) { for (size_t i = 0; i < scales.size(); ++i) {
result.push_back(result.back() + times[i] * (data[i + 1] - data[i])); result.push_back(result.back() + scales[i] * (level[i + 1] - level[i]));
} }
} else { } else {
for (size_t i = 0; i < times.size(); ++i) { for (size_t i = 0; i < scales.size(); ++i) {
while (starts[i] != data[p] && p < data.size()) { while (starts[i] != level[p] && p < level.size()) {
++p; ++p;
} }
start = p; start = p;
while (starts[i + 1] != data[p] && p < data.size()) { while (starts[i + 1] != level[p] && p < level.size()) {
++p; ++p;
} }
end = p + 1; end = p + 1;
for (size_t j = 0; j < times[i]; ++j) { for (size_t j = 0; j < scales[i]; ++j) {
for (size_t index = start; index < end - 1; ++index) { for (size_t index = start; index < end - 1; ++index) {
result.push_back(result.back() + data[index + 1] - data[index]); result.push_back(result.back() + level[index + 1] - level[index]);
} }
} }
} }
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
#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>
...@@ -126,8 +123,8 @@ class LoDTensor : public Tensor { ...@@ -126,8 +123,8 @@ class LoDTensor : public Tensor {
LoD lod_; LoD lod_;
}; };
Vector<size_t> repeat_lod(Vector<size_t> data, Vector<size_t> starts, Vector<size_t> expand_lod(Vector<size_t> level, Vector<size_t> starts,
Vector<size_t> times, bool is_first); Vector<size_t> scales, bool repeat);
} // namespace framework } // namespace framework
} // namespace paddle } // namespace paddle
...@@ -50,28 +50,68 @@ class SeqExpandOpMaker : public framework::OpProtoAndCheckerMaker { ...@@ -50,28 +50,68 @@ class SeqExpandOpMaker : public framework::OpProtoAndCheckerMaker {
SeqExpandOpMaker(framework::OpProto* proto, SeqExpandOpMaker(framework::OpProto* proto,
framework::OpAttrChecker* op_checker) framework::OpAttrChecker* op_checker)
: OpProtoAndCheckerMaker(proto, op_checker) { : OpProtoAndCheckerMaker(proto, op_checker) {
// TODO(wanghaoshuang): Add more comments AddInput(
AddInput("X", "The input('X') of seq_expand op."); "X",
AddInput("Y", "The reference input('Y') of seq_expand op."); "The input('X') of seq_expand op. It can be LoDTensor or base Tensor.");
AddOutput("Out", "The output of seq_expand op."); AddInput(
AddAttr<int>("repeat", "repeat times").SetDefault(0); "Y",
"The reference input('Y') of seq_expand op."
"It must be a LoDTensor with k-level(k>0)."
"This reference input is essential if 'repeat' attribute is not "
"configured."
"Input(X) will be expanded by LoD of input(Y) while repeat == 0.");
AddOutput("Out",
"The output of seq_expand op."
"The output is a (k+1)-level LoDTensor"
"while input(X) being k-level LoDTensor."
"(Given base tensor is 0-level LoDTensor.)");
AddAttr<int>("repeat",
"(type:int; default value: 0)"
"Repeatting times of each element while expanding input(X)."
"It works while input(Y) is not configured.")
.SetDefault(0);
AddComment(R"DOC( AddComment(R"DOC(
As an example: Expand k-level LoDTensor to (k+1)-level LoDTensor
by lod of input(Y) or 'repeat' attribute.
Given: Case 1:
X.data = [1, 2 , 3, 4]
X.lod = [[0, 3, 4], [0, 1, 3, 4]]
Given a 2-level LoDTensor X:
X.data = [1, 2 , 3, 4]
X.lod = [[0, 3, 4], [0, 1, 3, 4]]
and and
repeat = 2
repeat = 2 then we get 3-level LoDTensor
Out.data = [1, 2, 3, 1, 2, 3, 4, 4]
Out.lod = [[0, 6, 8],
then we get [0, 3, 6, 7, 8],
[0, 1, 3, 4, 6, 7, 8]]
Out.data = [1, 2, 3, 1, 2, 3, 4, 4]
Out.lod = [[0, 6, 8], [0, 3, 6, 7, 8], [0, 1, 3, 4, 6, 7, 8]] Case 2:
Given 2-level a LoDTensor X
X.data = [1, 2, 3, 4]
X.lod = [[0, 3, 4], [0, 1, 3, 4]]
and
Y.lod = [[0, 6, 8],
[0, 3, 6, 7, 8],
[0,1,3,4,6,7,8]]
then we get 3-level LoDTensor
Out.data = [1, 2, 3, 1, 2, 3, 4, 4]
Out.lod = [[0, 6, 8],
[0, 3, 6, 7, 8],
[0, 1, 3, 4, 6, 7, 8]]
Case 3:
Given a 0-level LoDTensor X
X.data = [1, 2, 3, 4]
X.lod = NULL
and
repeat = 2
then we get 1-level LoDTensor
Out.data = [1, 1, 2, 2, 3, 3, 4, 4]
Out.lod = [[0, 2, 4, 6, 8]]
)DOC"); )DOC");
} }
......
...@@ -44,10 +44,10 @@ class SeqExpandKernel : public framework::OpKernel<T> { ...@@ -44,10 +44,10 @@ 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"));
framework::Vector<size_t> repeats; framework::Vector<size_t> scales;
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); scales.push_back(repeat);
} }
std::vector<int64_t> dims = framework::vectorize(x->dims()); std::vector<int64_t> dims = framework::vectorize(x->dims());
dims[0] = dims[0] * repeat; dims[0] = dims[0] * repeat;
...@@ -57,18 +57,18 @@ class SeqExpandKernel : public framework::OpKernel<T> { ...@@ -57,18 +57,18 @@ class SeqExpandKernel : public framework::OpKernel<T> {
auto* y = context.Input<LoDTensor>("Y"); auto* y = context.Input<LoDTensor>("Y");
auto y_lod = y->lod(); auto y_lod = y->lod();
for (int i = 0; i < y_lod[0].size() - 1; ++i) { for (int i = 0; i < y_lod[0].size() - 1; ++i) {
repeats.push_back((y_lod[0][i + 1] - y_lod[0][i]) / scales.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(y->dims()); out->Resize(y->dims());
} }
framework::LoD out_lod; framework::LoD out_lod;
auto level0 = framework::repeat_lod(x_lod[0], x_lod[0], repeats, true); auto level0 = framework::expand_lod(x_lod[0], x_lod[0], scales, false);
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( out_lod.push_back(
framework::repeat_lod(x_lod[i], x_lod[0], repeats, false)); framework::expand_lod(x_lod[i], x_lod[0], scales, true));
} }
size_t element_len = framework::product(x_dims) / x_dims[0]; size_t element_len = framework::product(x_dims) / x_dims[0];
...@@ -77,9 +77,9 @@ class SeqExpandKernel : public framework::OpKernel<T> { ...@@ -77,9 +77,9 @@ class SeqExpandKernel : public framework::OpKernel<T> {
// copy data // copy data
Place place = boost::get<Place>(context.GetPlace()); Place place = boost::get<Place>(context.GetPlace());
size_t count = 0; size_t count = 0;
for (size_t i = 0; i < repeats.size(); ++i) { for (size_t i = 0; i < scales.size(); ++i) {
count = element_len * (x_lod[0][i + 1] - x_lod[0][i]); count = element_len * (x_lod[0][i + 1] - x_lod[0][i]);
for (size_t j = 0; j < repeats[i]; ++j) { for (size_t j = 0; j < scales[i]; ++j) {
memory::Copy(place, out_data, place, x_data, sizeof(T) * count); memory::Copy(place, out_data, place, x_data, sizeof(T) * count);
out_data += count; out_data += count;
} }
...@@ -95,9 +95,9 @@ class SeqExpandGradKernel : public framework::OpKernel<T> { ...@@ -95,9 +95,9 @@ 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<LoDTensor>(framework::GradVarName("Out")); auto* d_out = context.Input<LoDTensor>(framework::GradVarName("Out"));
auto* d_x = context.Output<LoDTensor>(framework::GradVarName("X"));
auto* x = context.Input<LoDTensor>("X"); auto* x = context.Input<LoDTensor>("X");
auto* out = context.Input<LoDTensor>("Out"); auto* out = context.Input<LoDTensor>("Out");
auto* d_x = context.Output<LoDTensor>(framework::GradVarName("X"));
auto out_lod = out->lod(); auto out_lod = out->lod();
d_x->set_lod(x->lod()); d_x->set_lod(x->lod());
const T* d_out_data = d_out->data<T>(); const T* d_out_data = d_out->data<T>();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册