-
Notifications
You must be signed in to change notification settings - Fork 26.3k
Add aten mkldnn ops: relu, max_pool2d and avg_pool2d #19205
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
Changes from all commits
e028e18
d92a03a
b2dd846
2e35227
852490f
89621b2
96f8ece
4d3f3f7
8b80ed8
3da3fcb
49ce657
fd9690c
8b4c8f0
53651c8
8103ad0
03dd40c
2bed92f
3bf9ad0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| #include <ATen/ATen.h> | ||
| #include <ATen/Config.h> | ||
| #include <ATen/NativeFunctions.h> | ||
| #include <ATen/native/utils/ParamUtils.h> | ||
| #include <tuple> | ||
|
|
||
|
|
||
| #if !AT_MKLDNN_ENABLED() | ||
|
|
||
| namespace at { | ||
| namespace native { | ||
|
|
||
| Tensor mkldnn_max_pool2d( | ||
| const Tensor& self, | ||
| IntArrayRef kernel_size, | ||
| IntArrayRef stride, | ||
| IntArrayRef padding, | ||
| IntArrayRef dilation, | ||
| bool ceil_mode) { | ||
| AT_ERROR( | ||
| "mkldnn_max_pool2d: ATen not compiled with MKLDNN support"); | ||
| } | ||
|
|
||
| Tensor mkldnn_avg_pool2d( | ||
| const Tensor& self, | ||
| IntArrayRef kernel_size, | ||
| IntArrayRef stride, | ||
| IntArrayRef padding, | ||
| bool ceil_mode, | ||
| bool count_include_pad) { | ||
| AT_ERROR("mkldnn_avg_pool2d: ATen not compiled with MKLDNN support"); | ||
| } | ||
|
|
||
| Tensor& mkldnn_avg_pool2d_out( | ||
| Tensor& output, | ||
| const Tensor& self, | ||
| IntArrayRef kernel_size, | ||
| IntArrayRef stride, | ||
| IntArrayRef padding, | ||
| bool ceil_mode, | ||
| bool count_include_pad) { | ||
| AT_ERROR("mkldnn_avg_pool2d_out: ATen not compiled with MKLDNN support"); | ||
| } | ||
| } // namespace native | ||
| } // namespace at | ||
|
|
||
| #else // AT_MKLDNN_ENABLED | ||
|
|
||
| #include <ATen/native/mkldnn/MKLDNNCommon.h> | ||
| #include <ATen/native/mkldnn/Utils.h> | ||
|
|
||
| namespace at { | ||
| namespace native { | ||
|
|
||
| static Tensor _mkldnn_pool2d( | ||
| const Tensor& input, | ||
| IntArrayRef kernel_size, | ||
| IntArrayRef stride, | ||
| IntArrayRef padding, | ||
| IntArrayRef dilation, | ||
| bool ceil_mode, | ||
| ideep::algorithm algo) { | ||
| AT_CHECK(!ceil_mode, "Currently Mkldnn Pooling operators do not support ceil_mode."); | ||
| auto kernel_size_vec = expand_param_if_needed(kernel_size, "kernel_size", 2); | ||
| auto stride_vec = expand_param_if_needed(stride, "stride", 2); | ||
| auto padding_vec = expand_param_if_needed(padding, "padding", 2); | ||
| auto dilation_vec = expand_param_if_needed(dilation, "dilation", 2); | ||
|
|
||
| const ideep::tensor& x = itensor_from_mkldnn(input); | ||
| const std::vector<int64_t> output_sizes = pool_output_sizes( | ||
| input.sizes(), | ||
| kernel_size_vec, | ||
| stride_vec, | ||
| padding_vec, | ||
| dilation_vec, | ||
| ceil_mode); | ||
| ideep::tensor y; | ||
| ideep::pooling_forward::compute<AllocForMKLDNN>( | ||
| x, | ||
| {output_sizes.cbegin(), output_sizes.cend()}, | ||
| y, | ||
| {stride_vec.cbegin(), stride_vec.cend()}, | ||
| {kernel_size_vec.cbegin(), kernel_size_vec.cend()}, | ||
| {padding_vec.cbegin(), padding_vec.cend()}, | ||
| {padding_vec.cbegin(), padding_vec.cend()}, | ||
| algo, | ||
| ideep::prop_kind::forward); | ||
|
|
||
| return new_with_itensor_mkldnn(std::move(y), input.options()); | ||
| } | ||
|
|
||
| Tensor mkldnn_max_pool2d( | ||
| const Tensor& input, | ||
| IntArrayRef kernel_size, | ||
| IntArrayRef stride, | ||
| IntArrayRef padding, | ||
| IntArrayRef dilation, | ||
| bool ceil_mode) { | ||
| return _mkldnn_pool2d( | ||
| input, | ||
| kernel_size, | ||
| stride, | ||
| padding, | ||
| dilation, | ||
| ceil_mode, | ||
| ideep::algorithm::pooling_max); | ||
| } | ||
|
|
||
| Tensor mkldnn_avg_pool2d( | ||
| const Tensor& input, | ||
| IntArrayRef kernel_size, | ||
| IntArrayRef stride, | ||
| IntArrayRef padding, | ||
| bool ceil_mode, | ||
| bool count_include_pad) { | ||
| return _mkldnn_pool2d( | ||
| input, | ||
| kernel_size, | ||
| stride, | ||
| padding, | ||
| std::vector<int64_t>{1, 1}, | ||
| ceil_mode, | ||
| count_include_pad ? ideep::algorithm::pooling_avg_include_padding | ||
| : ideep::algorithm::pooling_avg_exclude_padding); | ||
| } | ||
|
|
||
| Tensor& mkldnn_avg_pool2d_out( | ||
| Tensor& output, | ||
| const Tensor& input, | ||
| IntArrayRef kernel_size, | ||
| IntArrayRef stride, | ||
| IntArrayRef padding, | ||
| bool ceil_mode, | ||
| bool count_include_pad) { | ||
| AT_ERROR( | ||
| "mkldnn_avg_pool2d_out: in-place mkldnn operations are not supported yet"); | ||
| } | ||
|
|
||
| } // namespace native | ||
| } // namespace at | ||
|
|
||
| #endif // AT_MKLDNN_ENABLED |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| #include <ATen/ATen.h> | ||
| #include <ATen/NativeFunctions.h> | ||
| #include <ATen/Config.h> | ||
|
|
||
|
|
||
| #if !AT_MKLDNN_ENABLED() | ||
|
|
||
| namespace at { namespace native { | ||
|
|
||
| Tensor mkldnn_relu(const Tensor& input) { | ||
| AT_ERROR("mkldnn_relu: ATen not compiled with MKLDNN support"); | ||
| } | ||
|
|
||
| Tensor& mkldnn_relu_(Tensor& input) { | ||
| AT_ERROR("mkldnn_relu_: ATen not compiled with MKLDNN support"); | ||
| } | ||
|
|
||
| }} | ||
|
|
||
| #else // AT_MKLDNN_EBABLED | ||
|
|
||
| #include <ATen/native/mkldnn/MKLDNNCommon.h> | ||
|
|
||
| namespace at { namespace native { | ||
|
|
||
| Tensor mkldnn_relu(const Tensor& input) { | ||
| const ideep::tensor& x = itensor_from_mkldnn(input); | ||
| ideep::tensor y; | ||
| ideep::eltwise_forward::compute<AllocForMKLDNN>( | ||
| x, y, ideep::algorithm::eltwise_relu, ideep::prop_kind::forward_training, /*alpha*/ 0.0); | ||
| return new_with_itensor_mkldnn(std::move(y), input.options()); | ||
| } | ||
|
|
||
| Tensor& mkldnn_relu_(Tensor& input) { | ||
| ideep::tensor& x = itensor_from_mkldnn(input); | ||
| ideep::eltwise_forward::compute<AllocForMKLDNN>( | ||
| x, x, ideep::algorithm::eltwise_relu, ideep::prop_kind::forward_training, /*alpha*/ 0.0); | ||
| return input; | ||
| } | ||
|
|
||
| }} | ||
|
|
||
| #endif // AT_MKLDNN_EBABLED |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| #include <ATen/native/mkldnn/Utils.h> | ||
| #include <THNN/generic/pooling_shape.h> | ||
|
|
||
| namespace at { namespace native { | ||
|
|
||
|
|
@@ -20,4 +21,30 @@ std::vector<int64_t> conv_output_size( | |
| return output_size; | ||
| } | ||
|
|
||
| std::vector<int64_t> pool_output_sizes( | ||
| IntArrayRef input_size, | ||
| IntArrayRef kernel_size, | ||
| IntArrayRef stride, | ||
| IntArrayRef padding, | ||
| IntArrayRef dilation, | ||
| bool ceil_mode) { | ||
| std::vector<int64_t> output_size(input_size.size()); | ||
| // copy N and C | ||
| output_size[0] = input_size[0]; | ||
| output_size[1] = input_size[1]; | ||
|
|
||
| for (int i = 2; i < input_size.size(); ++i) { | ||
| output_size[i] = pooling_output_shape<int64_t>( | ||
| input_size[i], | ||
| kernel_size[i - 2], | ||
| padding[i - 2], | ||
| stride[i - 2], | ||
| dilation[i - 2], | ||
| ceil_mode | ||
| ); | ||
| } | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MKLDNN treats padding differently with ceil mode. import torch
x = torch.randn(1, 1, 10, 10, dtype=torch.float32) * 10
max_pool2d = torch.nn.MaxPool2d(kernel_size=(4,5),stride=(3,4),padding=(1,2), ceil_mode=True)
# max_pool2d = torch.nn.AvgPool2d(kernel_size=(4,5),stride=(3,4),padding=(1,2), ceil_mode=True)
output = max_pool2d(x.to_mkldnn()).to_dense()please refer caffe code of computing pooling output size for detail. @XiaobingSuper
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. has this comment been addressed? (sorry I didn't follow the point)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This problem can be solved by change the mkldnn padding as caffe's doing: https://github.com/intel/caffe/blob/362a3b375e8f5bc64f5338d18f1742448cfb8fb7/src/caffe/layers/mkldnn_pooling_layer.cpp#L148
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please note that mkldnn is to get given output size by changing padding size.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added an assert to only support non ceil_mode for now. Let's do the padding trick in a follow up PR. |
||
| return output_size; | ||
| } | ||
|
|
||
| }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1141,6 +1141,11 @@ | |
|
|
||
| - func: max_pool2d(Tensor self, int[2] kernel_size, int[2] stride=[], int[2] padding=0, int[2] dilation=1, bool ceil_mode=False) -> Tensor | ||
|
|
||
| - func: mkldnn_max_pool2d(Tensor self, int[2] kernel_size, int[2] stride=[], int[2] padding=0, int[2] dilation=1, bool ceil_mode=False) -> Tensor | ||
| requires_tensor: True | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. requires_tensor is probably not required here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep just for documentation purpose |
||
| dispatch: | ||
| MkldnnCPU: mkldnn_max_pool2d | ||
|
|
||
| - func: max_pool3d(Tensor self, int[3] kernel_size, int[3] stride=[], int[3] padding=0, int[3] dilation=1, bool ceil_mode=False) -> Tensor | ||
|
|
||
| # FIXME: These could be combined as optional<ScalarType> but for https://github.com/pytorch/pytorch/issues/6593. | ||
|
|
@@ -1522,9 +1527,17 @@ | |
|
|
||
| - func: relu(Tensor self) -> Tensor | ||
| variants: function, method | ||
| dispatch: | ||
| CPU: relu | ||
| CUDA: relu | ||
| MkldnnCPU: mkldnn_relu | ||
|
|
||
| - func: relu_(Tensor(a!) self) -> Tensor(a!) | ||
| variants: function, method | ||
| dispatch: | ||
| CPU: relu_ | ||
| CUDA: relu_ | ||
| MkldnnCPU: mkldnn_relu_ | ||
|
|
||
| - func: prelu(Tensor self, Tensor weight) -> Tensor | ||
| variants: function, method | ||
|
|
@@ -3670,9 +3683,17 @@ | |
|
|
||
| - func: avg_pool2d(Tensor self, int[2] kernel_size, int[2] stride=[], int[2] padding=0, bool ceil_mode=False, bool count_include_pad=True, *, Tensor(a!) out) -> Tensor(a!) | ||
| python_module: nn | ||
| dispatch: | ||
| CPU: avg_pool2d_out | ||
| CUDA: avg_pool2d_out | ||
| MkldnnCPU: mkldnn_avg_pool2d_out | ||
|
|
||
| - func: avg_pool2d(Tensor self, int[2] kernel_size, int[2] stride=[], int[2] padding=0, bool ceil_mode=False, bool count_include_pad=True) -> Tensor | ||
| python_module: nn | ||
| dispatch: | ||
| CPU: avg_pool2d | ||
| CUDA: avg_pool2d | ||
| MkldnnCPU: mkldnn_avg_pool2d | ||
|
|
||
| - func: avg_pool2d_backward(Tensor grad_output, Tensor self, int[2] kernel_size, int[2] stride, int[2] padding, bool ceil_mode, bool count_include_pad, *, Tensor(a!) grad_input) -> Tensor(a!) | ||
| python_module: nn | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did we originally have it here?