Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
cb65439d
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看板
提交
cb65439d
编写于
9月 21, 2019
作者:
A
Adam
提交者:
Tao Luo
9月 21, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for other axes in MKLDNN softmax op (#19907)
* Initial, functional commit * Clean commit related files test=develop
上级
45425411
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
50 addition
and
40 deletion
+50
-40
paddle/fluid/operators/mkldnn/softmax_mkldnn_op.cc
paddle/fluid/operators/mkldnn/softmax_mkldnn_op.cc
+25
-33
paddle/fluid/operators/softmax_op.cc
paddle/fluid/operators/softmax_op.cc
+0
-2
python/paddle/fluid/tests/unittests/mkldnn/test_softmax_mkldnn_op.py
...le/fluid/tests/unittests/mkldnn/test_softmax_mkldnn_op.py
+24
-4
python/paddle/fluid/tests/unittests/test_softmax_op.py
python/paddle/fluid/tests/unittests/test_softmax_op.py
+1
-1
未找到文件。
paddle/fluid/operators/mkldnn/softmax_mkldnn_op.cc
浏览文件 @
cb65439d
...
...
@@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. */
#include <iostream>
#include <numeric>
#include "mkldnn.hpp"
#include "paddle/fluid/operators/softmax_op.h"
#include "paddle/fluid/platform/mkldnn_reuse.h"
...
...
@@ -38,37 +39,37 @@ class SoftmaxMKLDNNHandler
mkldnn
::
softmax_backward
>
{
public:
SoftmaxMKLDNNHandler
(
const
std
::
vector
<
int
>&
dims
,
const
MKLDNNMemoryFormat
fmt
,
const
MKLDNNMemoryFormat
fmt
,
const
int
&
axis
,
const
platform
::
MKLDNNDeviceContext
&
dev_ctx
,
platform
::
Place
cpu_place
,
const
std
::
string
&
uniq_name
)
:
platform
::
MKLDNNHandlerT
<
T
,
mkldnn
::
softmax_forward
,
mkldnn
::
softmax_backward
>
(
dev_ctx
,
dev_ctx
.
GetEngine
(),
cpu_place
,
platform
::
CreateKey
(
dims
,
uniq_name
))
{
platform
::
CreateKey
(
dims
,
axis
,
uniq_name
))
{
auto
md
=
mkldnn
::
memory
::
desc
(
dims
,
platform
::
MKLDNNGetDataType
<
T
>
(),
fmt
);
this
->
AcquireForwardPrimitiveDescriptor
(
prop_kind
::
forward_scoring
,
md
,
1
/*dim: C*/
);
axis
);
}
SoftmaxMKLDNNHandler
(
const
std
::
vector
<
int
>&
dims
,
const
MKLDNNMemoryFormat
fmt
,
const
MKLDNNMemoryFormat
diff_fmt
,
const
MKLDNNMemoryFormat
diff_fmt
,
const
int
&
axis
,
const
platform
::
MKLDNNDeviceContext
&
dev_ctx
,
platform
::
Place
cpu_place
,
const
std
::
string
&
uniq_name
)
:
platform
::
MKLDNNHandlerT
<
T
,
mkldnn
::
softmax_forward
,
mkldnn
::
softmax_backward
>
(
dev_ctx
,
dev_ctx
.
GetEngine
(),
cpu_place
,
platform
::
CreateKey
(
dims
,
uniq_name
))
{
platform
::
CreateKey
(
dims
,
axis
,
uniq_name
))
{
auto
data_softmax_md
=
mkldnn
::
memory
::
desc
(
dims
,
platform
::
MKLDNNGetDataType
<
T
>
(),
fmt
);
auto
diff_softmax_md
=
mkldnn
::
memory
::
desc
(
dims
,
platform
::
MKLDNNGetDataType
<
T
>
(),
diff_fmt
);
this
->
AcquireForwardPrimitiveDescriptor
(
prop_kind
::
forward_scoring
,
data_softmax_md
,
1
/*dim: C*/
);
data_softmax_md
,
axis
);
this
->
AcquireBackwardPrimitiveDescriptor
(
diff_softmax_md
,
data_softmax_md
,
1
/* dim: C*/
);
axis
);
}
};
...
...
@@ -85,18 +86,14 @@ class SoftmaxMKLDNNKernel : public paddle::framework::OpKernel<T> {
input
->
dims
(),
output
->
dims
(),
"The shape of softmax's input and output must be identical."
);
// flatten input and output to 2-D matrixs
auto
dims
=
input
->
dims
();
// input and output share the same shape
auto
flattened_dims
=
framework
::
flatten_to_2d
(
dims
,
dims
.
size
()
-
1
);
const
int
axis
=
CanonicalAxis
(
ctx
.
Attr
<
int
>
(
"axis"
),
dims
.
size
()
);
auto
src_tz
=
paddle
::
framework
::
vectorize
<
int
>
(
flattened_dims
);
auto
dst_tz
=
src_tz
;
// Same memory descriptor to be used for input and output
memory
::
dims
softmax_tz
=
{
src_tz
[
0
],
src_tz
[
1
]};
auto
softmax_tz
=
paddle
::
framework
::
vectorize
<
int
>
(
dims
);
SoftmaxMKLDNNHandler
<
T
>
handler
(
softmax_tz
,
MKLDNNMemoryFormat
::
nc
,
dev_ctx
,
SoftmaxMKLDNNHandler
<
T
>
handler
(
softmax_tz
,
input
->
format
(),
axis
,
dev_ctx
,
ctx
.
GetPlace
(),
ctx
.
op
().
Output
(
"Out"
));
// Currently only NC data format is supported
auto
softmax_src_memory_p
=
handler
.
AcquireSrcMemory
(
input
);
auto
softmax_dst_memory_p
=
handler
.
AcquireDstMemory
(
output
);
auto
softmax_p
=
handler
.
AcquireForwardPrimitive
(
*
softmax_src_memory_p
,
...
...
@@ -105,14 +102,14 @@ class SoftmaxMKLDNNKernel : public paddle::framework::OpKernel<T> {
std
::
vector
<
primitive
>
pipeline
{
*
softmax_p
};
stream
(
stream
::
kind
::
eager
).
submit
(
pipeline
).
wait
();
T
*
output_data
=
output
->
mutable_data
<
T
>
(
ctx
.
GetPlace
());
const
bool
is_test
=
ctx
.
Attr
<
bool
>
(
"is_test"
);
if
(
!
is_test
)
{
T
threshold
=
exp
(
-
64
);
for
(
int
i
=
0
;
i
<
dst_tz
[
0
]
*
dst_tz
[
1
];
++
i
)
{
output_data
[
i
]
=
output_data
[
i
]
<
threshold
?
threshold
:
output_data
[
i
];
}
T
*
output_data
=
output
->
mutable_data
<
T
>
(
ctx
.
GetPlace
());
int
size
=
std
::
accumulate
(
begin
(
softmax_tz
),
end
(
softmax_tz
),
1
,
std
::
multiplies
<
int
>
());
std
::
for_each
(
output_data
,
&
output_data
[
size
],
[](
T
&
val
)
{
val
=
std
::
max
(
val
,
static_cast
<
T
>
(
exp
(
-
64
)));
});
}
output
->
set_layout
(
framework
::
DataLayout
::
kMKLDNN
);
...
...
@@ -139,31 +136,26 @@ class SoftmaxMKLDNNGradKernel : public paddle::framework::OpKernel<T> {
"The shape of softmax_grad's input and output must be identical."
);
auto
dims
=
dout
->
dims
();
// input and output share the same shape
auto
flattened_dims
=
framework
::
flatten_to_2d
(
dims
,
dims
.
size
()
-
1
);
std
::
vector
<
int
>
dst_tz
=
paddle
::
framework
::
vectorize
<
int
>
(
flattened_dims
);
std
::
vector
<
int
>
src_tz
(
dst_tz
);
const
int
axis
=
CanonicalAxis
(
ctx
.
Attr
<
int
>
(
"axis"
),
dims
.
size
());
// Same memory descriptor to be used for input and output
memory
::
dims
softmax_tz
=
{
src_tz
[
0
],
src_tz
[
1
]};
std
::
vector
<
int
>
softmax_tz
=
paddle
::
framework
::
vectorize
<
int
>
(
dims
);
// TODO(jczaja): Add layouts support when there is a need to do so
// Two dimensional softmax does support NC format
// Normalization is made after innermost dimension eg. C out of NC
SoftmaxMKLDNNHandler
<
T
>
handler
(
softmax_tz
,
MKLDNNMemoryFormat
::
nc
,
MKLDNNMemoryFormat
::
nc
,
dev_ctx
,
SoftmaxMKLDNNHandler
<
T
>
handler
(
softmax_tz
,
output
->
format
(),
dout
->
format
(),
axis
,
dev_ctx
,
ctx
.
GetPlace
(),
ctx
.
op
().
Input
(
"Out"
));
auto
dst_memory_p
=
handler
.
AcquireDstMemory
(
output
);
auto
diff_dst_memory_p
=
handler
.
AcquireDiffDstMemory
(
dout
);
auto
diff_src_memory_p
=
handler
.
AcquireDiffSrcMemory
(
dx
);
// Get primitve from device context
auto
softmax_bwd_p
=
handler
.
AcquireBackwardPrimitive
(
*
dst_memory_p
,
*
diff_dst_memory_p
,
*
diff_src_memory_p
);
std
::
vector
<
primitive
>
pipeline
{
*
softmax_bwd_p
};
stream
(
stream
::
kind
::
eager
).
submit
(
pipeline
).
wait
();
dx
->
set_layout
(
framework
::
DataLayout
::
kMKLDNN
);
dx
->
set_format
(
dout
->
format
());
}
};
}
// namespace operators
...
...
paddle/fluid/operators/softmax_op.cc
浏览文件 @
cb65439d
...
...
@@ -47,10 +47,8 @@ class SoftmaxOp : public framework::OperatorWithKernel {
"R is the rank of Input(X)."
);
auto
use_cudnn
=
ctx
->
Attrs
().
Get
<
bool
>
(
"use_cudnn"
);
auto
use_mkldnn
=
ctx
->
Attrs
().
Get
<
bool
>
(
"use_mkldnn"
);
if
(
axis
!=
rank_x
-
1
&&
axis
!=
-
1
)
{
PADDLE_ENFORCE
(
!
use_cudnn
,
"CUDNN kernel only support axis as -1."
);
PADDLE_ENFORCE
(
!
use_mkldnn
,
"MKLDNN kernel only support axis as -1."
);
}
ctx
->
SetOutputDim
(
"Out"
,
ctx
->
GetInputDim
(
"X"
));
...
...
python/paddle/fluid/tests/unittests/mkldnn/test_softmax_mkldnn_op.py
浏览文件 @
cb65439d
...
...
@@ -18,7 +18,7 @@ import unittest
import
numpy
as
np
from
paddle.fluid.tests.unittests.op_test
import
OpTest
import
paddle.fluid.core
as
core
from
paddle.fluid.tests.unittests.test_softmax_op
import
TestSoftmaxOp
,
stable_softmax
from
paddle.fluid.tests.unittests.test_softmax_op
import
*
from
mkldnn_op_test
import
check_if_mkldnn_primitives_exist_in_bwd
...
...
@@ -27,9 +27,29 @@ class TestSoftmaxMKLDNNOp(TestSoftmaxOp):
self
.
use_mkldnn
=
True
class
TestSoftmaxMKLDNNOp2
(
TestSoftmaxMKLDNNOp
):
def
get_x_shape
(
self
):
return
[
2
,
3
,
4
,
5
]
class
TestSoftmaxMKLDNNOp2
(
TestSoftmaxOp2
):
def
init_kernel_type
(
self
):
self
.
use_mkldnn
=
True
class
TestSoftmaxMKLDNNOp3
(
TestSoftmaxOp3
):
def
init_kernel_type
(
self
):
self
.
use_mkldnn
=
True
class
TestSoftmaxMKLDNNOp4
(
TestSoftmaxOp4
):
def
init_kernel_type
(
self
):
self
.
use_mkldnn
=
True
class
TestSoftmaxMKLDNNOp5
(
TestSoftmaxOp5
):
def
init_kernel_type
(
self
):
self
.
use_mkldnn
=
True
class
TestSoftmaxMKLDNNOp6
(
TestSoftmaxOp6
):
def
init_kernel_type
(
self
):
self
.
use_mkldnn
=
True
# Check if primitives already exist in backward
...
...
python/paddle/fluid/tests/unittests/test_softmax_op.py
浏览文件 @
cb65439d
...
...
@@ -103,7 +103,7 @@ class TestSoftmaxOp5(TestSoftmaxOp):
return
2
class
TestSoftmaxOp
5
(
TestSoftmaxOp
):
class
TestSoftmaxOp
6
(
TestSoftmaxOp
):
def
get_x_shape
(
self
):
return
[
2
,
3
,
4
,
5
]
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录