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

Feature/transform #7111

Merged
merged 10 commits into from
Jan 2, 2018
Merged

Conversation

dzhwinter
Copy link
Contributor

add Datatype, Layout transform.

PADDLE_ENFORCE(in.IsType<Tensor>(), "Only Support Tensor transform!.");
auto src = in.Get<Tensor>();
auto* dst = out->GetMutable<Tensor>();
// TODO(dzhwinter): CPU <-> GPU need a copy here
Copy link
Contributor

Choose a reason for hiding this comment

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

My view is that in TransDataType, the in and out should be in the same device.

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 dst_type = kernel_pair.second.data_type_;
auto src_type = kernel_pair.first.data_type_;

switch (src_type) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You should check whether src_type and dst_type are the same.
If they are the same, we only need copy in to out.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, this check should be done before the function.


namespace f = paddle::framework;
REGISTER_DATA_TRANSFORM_FN(f::kernel_FP32, f::kernel_FP64, f::TransDataType);
REGISTER_DATA_TRANSFORM_FN(f::kernel_Layout0, f::kernel_Layout1,
Copy link
Contributor

Choose a reason for hiding this comment

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

kernel_Layout0 and kernel_Layout1 are not intuitive. I suggest that kernel_Layout0 be written as "kernel_Layout_NHWC", or other better.

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.

@@ -45,6 +48,42 @@ struct KernelTypePairHash {
}
};

template <typename InType, typename OutType>
struct CastDataTypeFunctor {
HOSTDEVICE OutType operator()(InType in) const {
Copy link
Contributor

Choose a reason for hiding this comment

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

Add inline

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.

CastDataTypeFunctor<InType, OutType>());
} else {
// TODO(dzhwinter): enhance CopyFrom CPU<->GPU with different data type?
PADDLE_THROW("Unsupport CPU <-> GPU!");
Copy link
Contributor

Choose a reason for hiding this comment

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

OpKernelType is made up of four members(type, layout, place, library), except for library, the other three members are related to Data. According to the principle of function: a single task, I suggest that CastDataType only handles the data type conversion on the same device.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, we have re-designed the registrars.

Copy link
Contributor Author

@dzhwinter dzhwinter Jan 2, 2018

Choose a reason for hiding this comment

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

In the very beginning, we didn't figure out a method to do the multiple transforms.

For example, if we need to transform 0000 -> 1111, should we done in 4 step or 1 step?

  • For DataType, only test the FP32(float), FP64(double).
  • e.g. 0000 -> FP32, CPUPlace, kNHWC, kPlain
  •   1111 -> FP64, GPUPlace, kNCHW, kMKLDNN
    

So this PR looks ugly when deal with CPU <-> GPU, and transform datatype the same time.

Now we have made the decision, we will do this in 4 step. ONE functor will only do its own duty, then we will only have four kinds of transform functor. We will achieve that in the final state.

Copy link
Contributor

Choose a reason for hiding this comment

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

For LibraryType, Variable does not need a transform functor, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, only 3 kinds of transform functor if you take it seriously.

auto* dst = out->GetMutable<Tensor>();
dst->Resize(src.dims());
auto place = kernel_pair.second.place_;
CopyFrom(src, place, *ctx, dst);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe TransDataLayout is wrong.
e.g. arr's layout is NCHW format, and data is:

    [[[[ 0,  1,  2],
         [ 3,  4,  5]],

        [[ 6,  7,  8],
         [ 9, 10, 11]]]]

Obviously, arr's shape is (1,2,2,3).
If we change NCHW to NHWC, it's shape will be (1,3,2,2), and the data is:

    [[[[ 0,  6],
         [ 3,  9]],

        [[ 1,  7],
         [ 4, 10]],

        [[ 2,  8],
         [ 5, 11]]]]

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 src = in.Get<Tensor>();
auto* dst = out->GetMutable<Tensor>();
PADDLE_ENFORCE(arity(src.dims()) == 4, "Input Arity Only Suppport 4!");
Copy link
Contributor

Choose a reason for hiding this comment

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

arity(src.dims()) can be replaced by src.dims().size(). This is just a small problem.

}

Tensor dst = out.Get<Tensor>();
EXPECT_TRUE(dst.layout() != src->layout());
Copy link
Contributor

Choose a reason for hiding this comment

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

EXPECT_TRUE(dst.dims() == make_ddim({2, 2, 3, 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.

good point, will fix the test in next PR.

@dzhwinter dzhwinter merged commit 899a79c into PaddlePaddle:develop Jan 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants