Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seq expand op #4740

Merged
merged 20 commits into from
Oct 30, 2017
Merged

Seq expand op #4740

merged 20 commits into from
Oct 30, 2017

Conversation

wanghaoshuang
Copy link
Contributor

@wanghaoshuang wanghaoshuang commented Oct 12, 2017

fix #5000

out_dim[0] = out_dim[0] * repeat;
}
PADDLE_ENFORCE(ctx->HasOutput("Out"),
"Output(Out) of PadOp should not be null.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PadOp --> SeqExpandOp

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

for (size_t i = 0; i < scales.size(); ++i) {
count = element_len * (x_lod[0][i + 1] - x_lod[0][i]);
for (size_t j = 0; j < scales[i]; ++j) {
memory::Copy(place, out_data, place, x_data, sizeof(T) * count);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In GPU, we should set a CUDA stream for copy.

#ifdef PADDLE_WITH_CUDA
  auto stream = reinterpret_cast<const platform::CUDADeviceContext&>(
                      context.device_context())
                      .stream();
 memory::Copy(...... stream);
#else
 memory::Copy(......);
#endif

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Eigen::TensorMap<Eigen::Tensor<T, 1>> d_x_t(
d_x_data, static_cast<int>((ele_count * element_len) / repeat));
auto place = context.GetEigenDevice<Place>();
d_x_t.device(place) = d_out_t.sum(Eigen::array<int, 1>({0}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Contributor

@qingqing01 qingqing01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the code is not read yet. Just part comments.

: OpProtoAndCheckerMaker(proto, op_checker) {
AddInput(
"X",
"The input('X') of seq_expand op. It can be LoDTensor or base Tensor.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"(Tensor or LoDTensor) The input('X') of this operator can be a LoDTensor or a base Tensor."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

"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.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by - > according to the

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

"The input('X') of seq_expand op. It can be LoDTensor or base Tensor.");
AddInput(
"Y",
"The reference input('Y') of seq_expand op."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

" (LoDTensor) The ... "

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -103,5 +103,34 @@ void LoDTensor::ShrinkInLevel(size_t level, size_t elem_begin,
lod_ = new_lod;
}

Vector<size_t> expand_lod(Vector<size_t> level, Vector<size_t> starts,
Vector<size_t> scales, bool repeat) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functions names: "CamelCase"

https://google.github.io/styleguide/cppguide.html#Function_Names

Now, only the seq_expand needs this function, it may be removed to seq_expand_op.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}
PADDLE_ENFORCE(ctx->HasOutput("Out"),
"Output(Out) of SeqExpandOp should not be null.");
ctx->SetOutputDim("Out", out_dim);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whether the InferShape should set the LoD for output LoDTensor? Here, the LoD will be computed in the forward according the attr and input LoDs. I'm not sure wether the InferShape needs to infer all the shape info (dimension, LoD). @reyoung @jacquesqiao @QiJune

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]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples are good, but still hard to understand. Need some more details, since this the changes for LoD are a bit complex. For example, explain the Repeatting, it takes one instance (maybe other words) as a unit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

protected:
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"),
"Input(X) of SeqExpandOp should not be null.");
Copy link
Contributor

@Superjomn Superjomn Oct 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just PADDLE_ENFORCE_NOT_NULL(Input(X) ?
and this comment lack information, tells nothing more than the enforce code itself.

So enforce without comment is ok, or with a comment that really helps to find out the reason for its failure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


Case 1:

Given 2-level a LoDTensor input(X)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure this op support empty sequence, if it supports, add a case because this scenario is special.

for example, Y's LoD is 1 2 2 2, that means there are 2 empty sequences.

Some instance in X should be dropped when a corresponding LoD element is empty.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by adding unitest case and comments.

};

template <typename Place, typename T>
class SeqExpandGradKernel : public framework::OpKernel<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add more comments to describe the process because the code is long and hard to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIxed.

"The element numbers of last level in input('Y') "
"must be equal to dims[0] of input('X').");
AddOutput("Out",
"The output of seq_expand op."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add type for the output: (LoDTensor) The ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

X.dims = [4, 1]
and input(Y)
Y.lod = [[0, 2, 4],
[0, 3, 6, 7, 8]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the necessary condition? Y.lod[0][-1] == X.dims[0]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

X.lod = NULL
X.dims = [3, 1]
and input(Y)
Y.lod = [[0, 2, 3, 6]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add the necessary condition: len(Y.lod[0]) -1 == X.dims[0]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

X.lod = NULL
X.dims = [3, 1]
and input(Y)
Y.lod = [[0, 2, 3, 6]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add the necessary condition: len(Y.lod[0]) == X.dims[0]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

X.lod = NULL
X.dims = [3, 2]
and input(Y)
Y.lod = [[0, 2, 3, 6]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

"The size of last lod level in Input(Y)"
"must be equal to dims[0] of Input(X).");
out->set_lod(y->lod());
out->Resize(y->dims());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dimension has been set in the InferShape, so this line can be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIxed.

"The size of last lod level in Input(Y)"
"must be equal to dims[0] of Input(X).");
out->set_lod(y->lod());
out->Resize(y->dims());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dimension has been set in the InferShape.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIxed.

const T* d_out_data = d_out->data<T>();
auto d_out_dims = d_out->dims();
T* d_x_data = d_x->mutable_data<T>(context.GetPlace());
size_t element_len = framework::product(d_out_dims) / d_out_dims[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove line 71:

size_t element_len = d_out->numel()  / d_out->dims()[0];

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

qingqing01
qingqing01 previously approved these changes Oct 30, 2017
Copy link
Contributor

@qingqing01 qingqing01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

"It must be a LoDTensor with k-level(k>0)."
"Input(X) will be expanded according to LOD of input(Y)."
"The element numbers of last level in input('Y') "
"must be equal to dims[0] of input('X').");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有的地方用input('X'),用的地方用Input(X),是不是要统一下
下面的注释里也是一样。

PADDLE_ENFORCE(ctx->HasOutput("Out"));
PADDLE_ENFORCE(
ctx->HasInput("Y"),
"Input(Y) of SeqExpandOp should not be null while repeat == 0.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while -> when?
repeat是从哪儿来呢?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Contributor

@Superjomn Superjomn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wanghaoshuang wanghaoshuang merged commit 03136f6 into PaddlePaddle:develop Oct 30, 2017
@wanghaoshuang wanghaoshuang deleted the seq_expand_op branch June 1, 2018 05:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

LodExtend Operator
5 participants