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

Add expand operator #4061

Merged
merged 9 commits into from
Nov 11, 2017
Merged

Add expand operator #4061

merged 9 commits into from
Nov 11, 2017

Conversation

pkuyym
Copy link
Contributor

@pkuyym pkuyym commented Sep 13, 2017

Resolves #4029

@qingqing01 qingqing01 changed the title Add expand tensor Add expand operator Sep 13, 2017
namespace paddle {
namespace operators {

using Tensor = framework::Tensor;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do not using namespace or type alias in the header file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

template <int Rank>
void Expand(const framework::ExecutionContext& context) const {
auto* in0 = context.Input<Tensor>("X");
auto expand_times = context.Attr<std::vector<int>>("expandTimes");
Copy link
Collaborator

Choose a reason for hiding this comment

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

auto -> auto&

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

auto* in0 = context.Input<Tensor>("X");
auto expand_times = context.Attr<std::vector<int>>("expandTimes");
auto* out0 = context.Output<Tensor>("Out");
Eigen::DSizes<int, Rank> bcast_dims;
Copy link
Collaborator

@reyoung reyoung Sep 13, 2017

Choose a reason for hiding this comment

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

Maybe the problem is how to cast vector<int> to Eigen::DSizes<Rank>

@reyoung
Copy link
Collaborator

reyoung commented Sep 13, 2017

Related issue #4091

}
}

int dims = reshape_dims_vec.size() * 6 + reduce_dims_vec.size() - 7;
Copy link
Contributor

Choose a reason for hiding this comment

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

这里不-7的话是否ExpandBackwardDims / 6 + 1Dims % 6 + 1就可以把+1去掉了

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not really, please consider 6*1 + 6 = 12, 12/6=2 (expect 1)

AddComment(R"DOC(
Expand operator tiles the input by given times number. You should set times
number for each dimension by providing attribute 'expandTimes'. Rank of input
tensor should be in [1, 6]. Please draw an attention that size of
Copy link
Member

Choose a reason for hiding this comment

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

why Rank of input tensor should be in [1, 6]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The implementation will specialize the template due to the limitation of Eigen. I think rank 6 is big enough.

void InferShape(const framework::InferShapeContext& ctx) const override {
PADDLE_ENFORCE_NOT_NULL(ctx.InputVar("X"), "X must be initialized.");
std::vector<int> expand_times = Attr<std::vector<int>>("expandTimes");
auto* x = ctx.Input<Tensor>("X");
Copy link
Member

Choose a reason for hiding this comment

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

seems x is not used, can use

auto x_dims = ctx.Input<Tensor>("X")->dims();

instead

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

self.op_type = "expand"
self.inputs = {'X': np.random.random((12, 14)).astype("float32")}
self.attrs = {'expandTimes': [1, 1]}
output = np.tile(self.inputs['X'], (1, 1))
Copy link
Member

Choose a reason for hiding this comment

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

I think use all one as expand time is not good for test ~

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this is a corner case and I will add more robust test cases. Same as bellow.

def setUp(self):
self.op_type = "expand"
self.inputs = {'X': np.random.random((2, 4, 5)).astype("float32")}
self.attrs = {'expandTimes': [1, 1, 1]}
Copy link
Member

Choose a reason for hiding this comment

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

seem as above

@reyoung
Copy link
Collaborator

reyoung commented Sep 20, 2017

Maybe could use this PR #4205, too?

@qingqing01
Copy link
Contributor

Please update this PR and merge it asap.

"dimension size of Input(X) multiplying corresponding value of "
"Attr(expandTimes).");
AddAttr<std::vector<int>>("expandTimes",
"Expand times number for each dimension.");
Copy link
Contributor

Choose a reason for hiding this comment

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

expandTimes -> expand_times

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

}

ctx->SetOutputDim("Out", framework::make_ddim(out_shape));
ctx->ShareLoD("X", "Out");
Copy link
Contributor

Choose a reason for hiding this comment

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

这里应该out_shape[0] == x_dims[0]时,才能SharedLoD

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


protected:
void InferShape(framework::InferShapeContext* ctx) const override {
PADDLE_ENFORCE(ctx->HasInput("X"), "Input(X) must be initialized.");
Copy link
Contributor

Choose a reason for hiding this comment

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

should not be null.

Also needs to check the output.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

auto& expand_times = context.Attr<std::vector<int>>("expandTimes");
auto x_dims = in0->dims();
std::vector<int> reshape_dims_vec;
std::vector<int> reduce_dims_vec;
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add the comments about how to compute gradients.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

const std::vector<int>& reshape_dims_vec,
const std::vector<int>& reduce_dims_vec) const {
size_t reshape_size = Dims / 6 + 1;
size_t reduce_size = Dims % 6 + 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

use a constant variable to represent 6, do not use 6 directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

self.check_grad(['X'], 'Out')


class TestExpandOpRank2_2(OpTest):
Copy link
Contributor

Choose a reason for hiding this comment

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

The name _1 _2 is not clear.

@qingqing01 qingqing01 merged commit 561d634 into PaddlePaddle:develop Nov 11, 2017
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.

5 participants