Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
18a5d307
P
Paddle
项目概览
Crayon鑫
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
18a5d307
编写于
12月 03, 2019
作者:
J
Jacek Czaja
提交者:
Tao Luo
12月 03, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[MKL-DNN] Conv2d and Conv2d transpose MKL-DNN NHWC support (#21466)
上级
96a446f6
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
125 addition
and
43 deletion
+125
-43
paddle/fluid/framework/data_layout_transform.cc
paddle/fluid/framework/data_layout_transform.cc
+0
-4
paddle/fluid/framework/data_layout_transform.h
paddle/fluid/framework/data_layout_transform.h
+1
-1
paddle/fluid/framework/data_transform.cc
paddle/fluid/framework/data_transform.cc
+5
-2
paddle/fluid/operators/conv_op.cc
paddle/fluid/operators/conv_op.cc
+31
-10
paddle/fluid/operators/conv_op.h
paddle/fluid/operators/conv_op.h
+4
-0
paddle/fluid/operators/conv_transpose_op.cc
paddle/fluid/operators/conv_transpose_op.cc
+29
-7
paddle/fluid/operators/conv_transpose_op.h
paddle/fluid/operators/conv_transpose_op.h
+4
-0
paddle/fluid/operators/mkldnn/conv_mkldnn_op.cc
paddle/fluid/operators/mkldnn/conv_mkldnn_op.cc
+8
-15
paddle/fluid/operators/mkldnn/conv_transpose_mkldnn_op.cc
paddle/fluid/operators/mkldnn/conv_transpose_mkldnn_op.cc
+1
-3
python/paddle/fluid/tests/unittests/mkldnn/test_conv2d_int8_mkldnn_op.py
...luid/tests/unittests/mkldnn/test_conv2d_int8_mkldnn_op.py
+1
-1
python/paddle/fluid/tests/unittests/mkldnn/test_conv2d_mkldnn_op.py
...dle/fluid/tests/unittests/mkldnn/test_conv2d_mkldnn_op.py
+33
-0
python/paddle/fluid/tests/unittests/mkldnn/test_conv2d_transpose_mkldnn_op.py
...tests/unittests/mkldnn/test_conv2d_transpose_mkldnn_op.py
+8
-0
未找到文件。
paddle/fluid/framework/data_layout_transform.cc
浏览文件 @
18a5d307
...
...
@@ -113,7 +113,6 @@ void* GetDataFromTensor(const Tensor& tensor, mkldnn::memory::data_type type) {
PADDLE_THROW
(
"wrong mkldnn type provided"
);
}
}
#endif
void
TransDataLayoutFromMKLDNN
(
const
OpKernelType
&
kernel_type_for_var
,
const
OpKernelType
&
expected_kernel_type
,
...
...
@@ -127,14 +126,11 @@ void TransDataLayoutFromMKLDNN(const OpKernelType& kernel_type_for_var,
"TransDataLayoutFromMKLDNN only supports transform from MKLDNN to "
"non-MKLDNN"
);
#ifdef PADDLE_WITH_MKLDNN
innerTransDataLayoutFromMKLDNN
(
in_layout
,
paddle
::
platform
::
get_cur_paddle_data_layout
(),
in
,
out
,
place
);
#endif
}
#ifdef PADDLE_WITH_MKLDNN
void
innerTransDataLayoutFromMKLDNN
(
DataLayout
in_layout
,
DataLayout
out_layout
,
const
Tensor
&
in
,
Tensor
*
out
,
platform
::
Place
place
)
{
...
...
paddle/fluid/framework/data_layout_transform.h
浏览文件 @
18a5d307
...
...
@@ -69,11 +69,11 @@ inline MKLDNNDataType ToMKLDNNDataType(proto::VarType::Type type) {
void
innerTransDataLayoutFromMKLDNN
(
DataLayout
in_layout
,
DataLayout
out_layout
,
const
Tensor
&
in
,
Tensor
*
out
,
platform
::
Place
place
);
#endif
void
TransDataLayoutFromMKLDNN
(
const
OpKernelType
&
kernel_type_for_var
,
const
OpKernelType
&
expected_kernel_type
,
const
Tensor
&
in
,
Tensor
*
out
);
#endif
std
::
vector
<
int
>
GetAxis
(
const
DataLayout
&
from
,
const
DataLayout
&
to
);
...
...
paddle/fluid/framework/data_transform.cc
浏览文件 @
18a5d307
...
...
@@ -43,13 +43,13 @@ void TransformData(const OpKernelType &expected_kernel_type,
// do layout transform
if
(
NeedTransformLayout
(
lout
,
lin
))
{
#ifdef PADDLE_WITH_MKLDNN
if
(
lin
==
DataLayout
::
kMKLDNN
||
lout
==
DataLayout
::
kMKLDNN
)
{
PADDLE_ENFORCE
(
!
(
lin
==
DataLayout
::
kMKLDNN
&&
lout
==
DataLayout
::
kMKLDNN
),
"No layout transform needed between two MKLDNN OPKernels"
);
if
(
lin
!=
DataLayout
::
kMKLDNN
&&
lout
==
DataLayout
::
kMKLDNN
)
{
#ifdef PADDLE_WITH_MKLDNN
// Case1 - transform from Non-MKLDNN OPKernel to MKLDNN OPKernel
// Just set layout/format. No real transform occur
...
...
@@ -67,7 +67,6 @@ void TransformData(const OpKernelType &expected_kernel_type,
}
out
.
set_layout
(
DataLayout
::
kMKLDNN
);
out
.
set_format
(
out_format
);
#endif
}
else
{
// Case2 - transfrom from MKLDNN OPKernel to Non-MKLDNN OPKernel
// Do transform via MKLDNN lib
...
...
@@ -78,6 +77,10 @@ void TransformData(const OpKernelType &expected_kernel_type,
// Case3 - transfrom between Non-MKLDNN OPKernels
TransDataLayout
(
kernel_type_for_var
,
expected_kernel_type
,
in
,
&
out
);
}
#else
// Case3 - transfrom between Non-MKLDNN OPKernels
TransDataLayout
(
kernel_type_for_var
,
expected_kernel_type
,
in
,
&
out
);
#endif
transformed
=
true
;
PassTensorData
(
&
out
,
&
in
);
}
...
...
paddle/fluid/operators/conv_op.cc
浏览文件 @
18a5d307
...
...
@@ -48,7 +48,11 @@ void ConvOp::InferShape(framework::InferShapeContext* ctx) const {
int
groups
=
ctx
->
Attrs
().
Get
<
int
>
(
"groups"
);
std
::
vector
<
int
>
dilations
=
ctx
->
Attrs
().
Get
<
std
::
vector
<
int
>>
(
"dilations"
);
const
std
::
string
data_format
=
ctx
->
Attrs
().
Get
<
std
::
string
>
(
"data_format"
);
const
bool
channel_last
=
(
data_format
==
"NHWC"
||
data_format
==
"NDHWC"
);
// MKL-DNN Kernels are using NCHW order of dims description
// so we ignore data_format consideration for MKL-DNN kernel
const
bool
channel_last
=
(
this
->
IsMKLDNNType
()
==
false
)
&&
(
data_format
==
"NHWC"
||
data_format
==
"NDHWC"
);
PADDLE_ENFORCE_EQ
(
in_dims
.
size
()
==
4
||
in_dims
.
size
()
==
5
,
true
,
...
...
@@ -151,15 +155,6 @@ framework::OpKernelType ConvOp::GetExpectedKernelType(
#ifdef PADDLE_WITH_MKLDNN
if
(
library
==
framework
::
LibraryType
::
kPlain
&&
platform
::
CanMKLDNNBeUsed
(
ctx
))
{
// TODO(jczaja): Add support for NHWC
const
std
::
string
data_format
=
ctx
.
Attr
<
std
::
string
>
(
"data_format"
);
PADDLE_ENFORCE_NE
(
data_format
,
"NHWC"
,
platform
::
errors
::
Unimplemented
(
"Conv MKLDNN does not support NHWC data format yet"
));
PADDLE_ENFORCE_NE
(
data_format
,
"NDHWC"
,
platform
::
errors
::
Unimplemented
(
"Conv MKLDNN does not support NDHWC data format yet"
));
library
=
framework
::
LibraryType
::
kMKLDNN
;
layout
=
framework
::
DataLayout
::
kMKLDNN
;
customized_type_value
=
...
...
@@ -197,6 +192,32 @@ framework::OpKernelType ConvOp::GetExpectedKernelType(
return
type
;
}
framework
::
OpKernelType
ConvOp
::
GetKernelTypeForVar
(
const
std
::
string
&
var_name
,
const
Tensor
&
tensor
,
const
framework
::
OpKernelType
&
expected_kernel_type
)
const
{
#ifdef PADDLE_WITH_MKLDNN
// Only input require reshaping, weights and
// bias are having shape in NCHW order
if
((
var_name
==
"Input"
)
&&
(
expected_kernel_type
.
data_layout_
==
framework
::
DataLayout
::
kMKLDNN
)
&&
(
tensor
.
layout
()
!=
framework
::
DataLayout
::
kMKLDNN
))
{
auto
attrs
=
Attrs
();
auto
ar
=
paddle
::
framework
::
AttrReader
(
attrs
);
const
std
::
string
data_format
=
ar
.
Get
<
std
::
string
>
(
"data_format"
);
auto
dl
=
framework
::
StringToDataLayout
(
data_format
);
// Some models may have intentionally set "AnyLayout" for pool
// op. Treat this as NCHW (default data_format value)
if
(
dl
!=
framework
::
DataLayout
::
kAnyLayout
)
{
return
framework
::
OpKernelType
(
expected_kernel_type
.
data_type_
,
tensor
.
place
(),
framework
::
StringToDataLayout
(
data_format
));
}
}
#endif
return
framework
::
OpKernelType
(
expected_kernel_type
.
data_type_
,
tensor
.
place
(),
tensor
.
layout
());
}
void
Conv2DOpMaker
::
Make
()
{
AddAttr
<
bool
>
(
"is_test"
,
"(bool, default false) Set to true for inference only, false "
...
...
paddle/fluid/operators/conv_op.h
浏览文件 @
18a5d307
...
...
@@ -258,6 +258,10 @@ class ConvOp : public framework::OperatorWithKernel {
protected:
framework
::
OpKernelType
GetExpectedKernelType
(
const
framework
::
ExecutionContext
&
ctx
)
const
override
;
framework
::
OpKernelType
GetKernelTypeForVar
(
const
std
::
string
&
var_name
,
const
Tensor
&
tensor
,
const
framework
::
OpKernelType
&
expected_kernel_type
)
const
override
;
};
class
ConvOpGrad
:
public
framework
::
OperatorWithKernel
{
...
...
paddle/fluid/operators/conv_transpose_op.cc
浏览文件 @
18a5d307
...
...
@@ -48,8 +48,9 @@ void ConvTransposeOp::InferShape(framework::InferShapeContext* ctx) const {
ctx
->
Attrs
().
Get
<
std
::
string
>
(
"padding_algorithm"
);
const
std
::
string
data_layout_str
=
ctx
->
Attrs
().
Get
<
std
::
string
>
(
"data_format"
);
const
framework
::
DataLayout
data_layout
=
framework
::
StringToDataLayout
(
data_layout_str
);
const
DataLayout
data_layout
=
this
->
IsMKLDNNType
()
?
DataLayout
::
kNCHW
:
framework
::
StringToDataLayout
(
data_layout_str
);
PADDLE_ENFORCE_EQ
(
in_dims
.
size
()
==
4
||
in_dims
.
size
()
==
5
,
true
,
"ShapeError: input of Op(conv_transpose) should be 4-D or "
...
...
@@ -145,11 +146,6 @@ framework::OpKernelType ConvTransposeOp::GetExpectedKernelType(
#ifdef PADDLE_WITH_MKLDNN
if
(
library_
==
framework
::
LibraryType
::
kPlain
&&
platform
::
CanMKLDNNBeUsed
(
ctx
))
{
// TODO(jczaja): Add support for NHWC
const
std
::
string
data_format
=
ctx
.
Attr
<
std
::
string
>
(
"data_format"
);
PADDLE_ENFORCE_NE
(
data_format
,
"NHWC"
,
"Conv Transpose MKLDNN does not support NHWC data format yet"
);
library_
=
framework
::
LibraryType
::
kMKLDNN
;
layout_
=
framework
::
DataLayout
::
kMKLDNN
;
}
...
...
@@ -160,6 +156,32 @@ framework::OpKernelType ConvTransposeOp::GetExpectedKernelType(
layout_
,
library_
);
}
framework
::
OpKernelType
ConvTransposeOp
::
GetKernelTypeForVar
(
const
std
::
string
&
var_name
,
const
Tensor
&
tensor
,
const
framework
::
OpKernelType
&
expected_kernel_type
)
const
{
#ifdef PADDLE_WITH_MKLDNN
// Only input require reshaping, weights and
// bias are having shape in NCHW order
if
((
var_name
==
"Input"
)
&&
(
expected_kernel_type
.
data_layout_
==
framework
::
DataLayout
::
kMKLDNN
)
&&
(
tensor
.
layout
()
!=
framework
::
DataLayout
::
kMKLDNN
))
{
auto
attrs
=
Attrs
();
auto
ar
=
paddle
::
framework
::
AttrReader
(
attrs
);
const
std
::
string
data_format
=
ar
.
Get
<
std
::
string
>
(
"data_format"
);
auto
dl
=
framework
::
StringToDataLayout
(
data_format
);
// Some models may have intentionally set "AnyLayout" for pool
// op. Treat this as NCHW (default data_format value)
if
(
dl
!=
framework
::
DataLayout
::
kAnyLayout
)
{
return
framework
::
OpKernelType
(
expected_kernel_type
.
data_type_
,
tensor
.
place
(),
framework
::
StringToDataLayout
(
data_format
));
}
}
#endif
return
framework
::
OpKernelType
(
expected_kernel_type
.
data_type_
,
tensor
.
place
(),
tensor
.
layout
());
}
void
Conv2DTransposeOpMaker
::
Make
()
{
AddAttr
<
bool
>
(
"is_test"
,
"(bool, default false) Set to true for inference only, false "
...
...
paddle/fluid/operators/conv_transpose_op.h
浏览文件 @
18a5d307
...
...
@@ -98,6 +98,10 @@ class ConvTransposeOp : public framework::OperatorWithKernel {
protected:
framework
::
OpKernelType
GetExpectedKernelType
(
const
framework
::
ExecutionContext
&
ctx
)
const
override
;
framework
::
OpKernelType
GetKernelTypeForVar
(
const
std
::
string
&
var_name
,
const
Tensor
&
tensor
,
const
framework
::
OpKernelType
&
expected_kernel_type
)
const
override
;
};
class
ConvTransposeOpGrad
:
public
framework
::
OperatorWithKernel
{
...
...
paddle/fluid/operators/mkldnn/conv_mkldnn_op.cc
浏览文件 @
18a5d307
...
...
@@ -220,9 +220,14 @@ class ConvMKLDNNOpKernel : public paddle::framework::OpKernel<T> {
* ('any') which lets a primitive (convolution in this case) choose
* the memory format preferred for best performance
*/
// TODO(jczaja): This is workaround to make grad op UT's numerical
// gradient computation proper as this op is called directly without
// fetch op following it , so numercial grad is computed (in python)
// using block formats which will give wrong results
std
::
string
data_format
=
ctx
.
Attr
<
std
::
string
>
(
"data_format"
);
auto
chosen_memory_format
=
platform
::
data_format_to_memory_format
(
data_format
);
is_test
?
MKLDNNMemoryFormat
::
any
:
platform
::
data_format_to_memory_format
(
data_format
);
weights_format
=
MKLDNNMemoryFormat
::
any
;
// Check the format for user's special output
...
...
@@ -519,9 +524,7 @@ class ConvMKLDNNOpKernel : public paddle::framework::OpKernel<T> {
* ('any') which lets a primitive (convolution in this case) choose
* the memory format preferred for best performance
*/
std
::
string
data_format
=
ctx
.
Attr
<
std
::
string
>
(
"data_format"
);
auto
chosen_memory_format
=
platform
::
data_format_to_memory_format
(
data_format
);
auto
chosen_memory_format
=
MKLDNNMemoryFormat
::
any
;
std
::
vector
<
int
>
bias_tz
;
...
...
@@ -772,18 +775,8 @@ class ConvMKLDNNGradOpKernel : public paddle::framework::OpKernel<T> {
* ('any') which lets a primitive (conv backward in this case) choose
* the memory format preferred for best performance
*/
std
::
string
data_format
=
ctx
.
Attr
<
std
::
string
>
(
"data_format"
);
auto
chosen_memory_format
=
platform
::
data_format_to_memory_format
(
data_format
);
auto
chosen_memory_format
=
MKLDNNMemoryFormat
::
any
;
weights_format
=
MKLDNNMemoryFormat
::
any
;
// Check the format for user's special output
if
(
chosen_memory_format
!=
MKLDNNMemoryFormat
::
any
)
{
if
(
is_conv3d
)
{
chosen_memory_format
=
platform
::
MKLDNNFormatForSize
(
src_tz
.
size
(),
chosen_memory_format
);
}
}
auto
src_md
=
platform
::
MKLDNNMemDesc
(
src_tz
,
platform
::
MKLDNNGetDataType
<
T
>
(),
chosen_memory_format
);
...
...
paddle/fluid/operators/mkldnn/conv_transpose_mkldnn_op.cc
浏览文件 @
18a5d307
...
...
@@ -156,9 +156,7 @@ class ConvTransposeMKLDNNOpKernel : public paddle::framework::OpKernel<T> {
* ('any') which lets a primitive (convolution in this case) choose
* the memory format preferred for best performance
*/
std
::
string
data_format
=
ctx
.
Attr
<
std
::
string
>
(
"data_format"
);
auto
chosen_memory_format
=
platform
::
data_format_to_memory_format
(
data_format
);
auto
chosen_memory_format
=
MKLDNNMemoryFormat
::
any
;
std
::
string
fuse_activation
=
ctx
.
Attr
<
std
::
string
>
(
"fuse_activation"
);
float
fuse_alpha
=
ctx
.
Attr
<
float
>
(
"fuse_alpha"
);
float
fuse_beta
=
ctx
.
Attr
<
float
>
(
"fuse_beta"
);
...
...
python/paddle/fluid/tests/unittests/mkldnn/test_conv2d_int8_mkldnn_op.py
浏览文件 @
18a5d307
...
...
@@ -35,7 +35,7 @@ class TestConv2dInt8Op(TestConv2dOp):
self
.
exhaustive_search
=
False
self
.
use_cuda
=
False
self
.
use_mkldnn
=
False
self
.
data_format
=
"
AnyLayout
"
self
.
data_format
=
"
NCHW
"
self
.
weighttype
=
np
.
float32
self
.
use_mkldnn
=
True
self
.
init_group
()
...
...
python/paddle/fluid/tests/unittests/mkldnn/test_conv2d_mkldnn_op.py
浏览文件 @
18a5d307
...
...
@@ -197,5 +197,38 @@ class TestConv2dOp_Valid_MKLDNN(TestConv2dOp_AsyPadding_MKLDNN):
self
.
padding_algorithm
=
"VALID"
class
TestConv2dOp_Valid_NHWC_MKLDNN
(
TestConv2dOp_Valid_MKLDNN
):
def
init_data_format
(
self
):
self
.
data_format
=
"NHWC"
def
init_test_case_2
(
self
):
N
,
C
,
H
,
W
=
self
.
input_size
self
.
input_size
=
[
N
,
H
,
W
,
C
]
#TODO(jczaja): Enable once GRAD op is adjusted
def
test_check_grad
(
self
):
pass
#TODO(jczaja): Enable once GRAD op is adjusted
def
test_check_grad_no_filter
(
self
):
pass
#TODO(jczaja): Enable once GRAD op is adjusted
def
test_check_grad_no_input
(
self
):
pass
class
TestConv2dOp_Same_NHWC_MKLDNN
(
TestConv2dOp_Valid_NHWC_MKLDNN
):
def
init_paddings
(
self
):
self
.
pad
=
[
0
,
0
]
self
.
padding_algorithm
=
"SAME"
class
TestConv2dOp_AsyPadding_NHWC_MKLDNN
(
TestConv2dOp_Valid_NHWC_MKLDNN
):
def
init_paddings
(
self
):
self
.
pad
=
[
0
,
0
,
1
,
2
]
self
.
padding_algorithm
=
"EXPLICIT"
if
__name__
==
'__main__'
:
unittest
.
main
()
python/paddle/fluid/tests/unittests/mkldnn/test_conv2d_transpose_mkldnn_op.py
浏览文件 @
18a5d307
...
...
@@ -126,3 +126,11 @@ class TestMKLDNNWithValidPad(TestConv2dTransposeMKLDNNOp):
TestConv2dTransposeMKLDNNOp
.
init_test_case
(
self
)
self
.
pad
=
[
1
,
1
]
self
.
padding_algorithm
=
"VALID"
class
TestMKLDNNWithValidPad_NHWC
(
TestMKLDNNWithValidPad
):
def
init_test_case
(
self
):
super
(
TestMKLDNNWithValidPad
,
self
).
init_test_case
()
self
.
data_format
=
"NHWC"
N
,
C
,
H
,
W
=
self
.
input_size
self
.
input_size
=
[
N
,
H
,
W
,
C
]
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录