Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
c15ac202
P
Paddle
项目概览
PaddlePaddle
/
Paddle
1 年多 前同步成功
通知
2302
Star
20931
Fork
5422
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
c15ac202
编写于
9月 20, 2017
作者:
T
Tao Luo
提交者:
GitHub
9月 20, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4199 from tensor-tang/mkldnn_act
add MKLDNN relu and tanh
上级
5b42d2b2
9d692e3b
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
361 addition
and
23 deletion
+361
-23
paddle/gserver/activations/ActivationFunction.cpp
paddle/gserver/activations/ActivationFunction.cpp
+10
-1
paddle/gserver/activations/MKLDNNActivation.cpp
paddle/gserver/activations/MKLDNNActivation.cpp
+87
-0
paddle/gserver/activations/MKLDNNActivation.h
paddle/gserver/activations/MKLDNNActivation.h
+182
-0
paddle/gserver/layers/MKLDNNConvLayer.cpp
paddle/gserver/layers/MKLDNNConvLayer.cpp
+1
-4
paddle/gserver/layers/MKLDNNFcLayer.cpp
paddle/gserver/layers/MKLDNNFcLayer.cpp
+1
-3
paddle/gserver/layers/MKLDNNLayer.h
paddle/gserver/layers/MKLDNNLayer.h
+4
-0
paddle/gserver/layers/MKLDNNPoolLayer.cpp
paddle/gserver/layers/MKLDNNPoolLayer.cpp
+0
-1
paddle/gserver/tests/MKLDNNTester.cpp
paddle/gserver/tests/MKLDNNTester.cpp
+30
-10
paddle/gserver/tests/MKLDNNTester.h
paddle/gserver/tests/MKLDNNTester.h
+1
-2
paddle/gserver/tests/test_MKLDNN.cpp
paddle/gserver/tests/test_MKLDNN.cpp
+45
-2
未找到文件。
paddle/gserver/activations/ActivationFunction.cpp
浏览文件 @
c15ac202
...
@@ -22,9 +22,12 @@ limitations under the License. */
...
@@ -22,9 +22,12 @@ limitations under the License. */
#include <type_traits>
#include <type_traits>
#include "paddle/parameter/Argument.h"
#include "paddle/parameter/Argument.h"
#include "paddle/utils/ClassRegistrar.h"
#include "paddle/utils/ClassRegistrar.h"
#include "paddle/utils/Logging.h"
#include "paddle/utils/Logging.h"
#ifdef PADDLE_USE_MKLDNN
#include "MKLDNNActivation.h"
#endif
namespace
paddle
{
namespace
paddle
{
static
ClassRegistrar
<
ActivationFunction
>
gActivationRegistrar
;
static
ClassRegistrar
<
ActivationFunction
>
gActivationRegistrar
;
...
@@ -456,6 +459,12 @@ Error __must_check backward(Argument& act) {
...
@@ -456,6 +459,12 @@ Error __must_check backward(Argument& act) {
END_DEFINE_ACTIVATION
(
log
)
END_DEFINE_ACTIVATION
(
log
)
ActivationFunction
*
ActivationFunction
::
create
(
const
std
::
string
&
type
)
{
ActivationFunction
*
ActivationFunction
::
create
(
const
std
::
string
&
type
)
{
#ifdef PADDLE_USE_MKLDNN
if
(
!
type
.
empty
()
&&
type
.
compare
(
0
,
7
,
"mkldnn_"
)
==
0
)
{
return
MKLDNNActivation
::
create
(
type
);
}
#endif
return
gActivationRegistrar
.
createByType
(
type
);
return
gActivationRegistrar
.
createByType
(
type
);
}
}
...
...
paddle/gserver/activations/MKLDNNActivation.cpp
0 → 100644
浏览文件 @
c15ac202
/* Copyright (c) 2017 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "MKLDNNActivation.h"
#include "mkldnn.hpp"
#include "paddle/utils/ClassRegistrar.h"
namespace
paddle
{
static
ClassRegistrar
<
ActivationFunction
>
gMKLDNNActivationRegistrar
;
/**
* @def MKLDNN_ACTIVATION_CLASS_NAME
* @note MKLDNN_ACTIVATION_CLASS_NAME(relu) relu_;
* means mkldnn_reluActivation relu_;
*/
#define MKLDNN_ACTIVATION_CLASS_NAME(ACT_TYPE) mkldnn_##ACT_TYPE##Activation
/**
* @def DEFINE_MKLDNN_ELTWISE_ACTIVATION
*/
#define DEFINE_MKLDNN_ELTWISE_ACTIVATION(ACT_TYPE, ALPHA, BWD_ALPHA) \
class MKLDNN_ACTIVATION_CLASS_NAME(ACT_TYPE) \
: public MKLDNNEltwiseActivation { \
private: \
static const std::string name; \
static const float alpha; \
static const float bwdAlpha; \
\
public: \
const std::string& getName() const { return name; } \
float getAlpha() const { return alpha; } \
float getBwdAlpha() const { return bwdAlpha; } \
}; \
const std::string MKLDNN_ACTIVATION_CLASS_NAME(ACT_TYPE)::name = \
"mkldnn_" #ACT_TYPE; \
const float MKLDNN_ACTIVATION_CLASS_NAME(ACT_TYPE)::alpha = ALPHA; \
const float MKLDNN_ACTIVATION_CLASS_NAME(ACT_TYPE)::bwdAlpha = BWD_ALPHA; \
static InitFunction __reg_activation__mkldnn_##ACT_TYPE([] { \
gMKLDNNActivationRegistrar \
.registerClass<MKLDNN_ACTIVATION_CLASS_NAME(ACT_TYPE)>( \
"mkldnn_" #ACT_TYPE); \
});
/**
* @brief MKLDNN Relu Activation.
* Actually mkldnn_relu is Leaky Relu.
* f(x) = x (x >= 0)
* f(x) = negative_slope * x (x < 0)
* @note the negative_slope should be -0.f in forward
*/
DEFINE_MKLDNN_ELTWISE_ACTIVATION
(
relu
,
-
0.
f
,
0.
f
)
/**
* @brief MKLDNN Tanh Activation.
*/
DEFINE_MKLDNN_ELTWISE_ACTIVATION
(
tanh
,
0.
f
,
0.
f
)
/**
* @brief MKLDNN ELU(Exponential Linear Unit) Activation.
* f(x) = x (x >= 0)
* f(x) = negative_slope * (exp(x) - 1) (x < 0)
*/
DEFINE_MKLDNN_ELTWISE_ACTIVATION
(
elu
,
0.
f
,
0.
f
)
ActivationFunction
*
MKLDNNActivation
::
create
(
const
std
::
string
&
type
)
{
return
gMKLDNNActivationRegistrar
.
createByType
(
type
);
}
std
::
vector
<
std
::
string
>
MKLDNNActivation
::
getAllRegisteredTypes
()
{
std
::
vector
<
std
::
string
>
types
;
gMKLDNNActivationRegistrar
.
forEachType
(
[
&
](
const
std
::
string
&
type
)
{
types
.
push_back
(
type
);
});
return
types
;
}
}
// namespace paddle
paddle/gserver/activations/MKLDNNActivation.h
0 → 100644
浏览文件 @
c15ac202
/* Copyright (c) 2017 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include "ActivationFunction.h"
#include "mkldnn.hpp"
#include "paddle/gserver/layers/MKLDNNBase.h"
#include "paddle/math/MKLDNNMatrix.h"
#include "paddle/parameter/Argument.h"
namespace
paddle
{
/**
* @brief Base class of MKLDNN Activation.
* Common activation function are provieded,
* including mkldnn_relu, mkldnn_elu, mkldnn_tanh, mkldnn_softmax
*/
class
MKLDNNActivation
:
public
ActivationFunction
{
protected:
// input value element count
size_t
cnt_
;
// should not merge the resetBwd into resetFwd,
// because the grad data would be changing before backward.
bool
needResetBwd_
;
// mkldnn matrix, primitive, stream and pipeline
MKLDNNMatrixPtr
val_
;
MKLDNNMatrixPtr
grad_
;
std
::
shared_ptr
<
MKLDNNStream
>
stream_
;
std
::
shared_ptr
<
mkldnn
::
primitive
>
fwd_
;
std
::
shared_ptr
<
mkldnn
::
primitive
>
bwd_
;
std
::
vector
<
mkldnn
::
primitive
>
pipelineFwd_
;
std
::
vector
<
mkldnn
::
primitive
>
pipelineBwd_
;
public:
MKLDNNActivation
()
:
cnt_
(
0
),
needResetBwd_
(
true
)
{}
~
MKLDNNActivation
()
{}
static
ActivationFunction
*
create
(
const
std
::
string
&
type
);
static
std
::
vector
<
std
::
string
>
getAllRegisteredTypes
();
virtual
const
std
::
string
&
getName
()
const
=
0
;
virtual
Error
__must_check
forward
(
Argument
&
act
)
=
0
;
virtual
Error
__must_check
backward
(
Argument
&
act
)
=
0
;
};
/**
* @brief Base class of MKLDNN Eltwise Activation,
* includes mkldnn_relu, mkldnn_elu and mkldnn_tanh.
*/
class
MKLDNNEltwiseActivation
:
public
MKLDNNActivation
{
typedef
mkldnn
::
eltwise_forward
eltwise_fwd
;
typedef
mkldnn
::
eltwise_backward
eltwise_bwd
;
protected:
// save the forward primitive desc, which can be used backward
std
::
shared_ptr
<
eltwise_fwd
::
primitive_desc
>
fwdPD_
;
// eltwise_bwd need src input value
MKLDNNMatrixPtr
inVal_
;
// use for copy data
std
::
shared_ptr
<
mkldnn
::
reorder
>
copyInVal_
;
public:
MKLDNNEltwiseActivation
()
{}
~
MKLDNNEltwiseActivation
()
{}
virtual
const
std
::
string
&
getName
()
const
=
0
;
// in common, the alpha of forward and backward should be equal.
// but for relu, to avoid negative value, they should be opposite
virtual
float
getAlpha
()
const
=
0
;
virtual
float
getBwdAlpha
()
const
=
0
;
virtual
float
getBeta
()
const
{
return
0.
f
;
}
virtual
mkldnn
::
algorithm
getAlgo
(
const
std
::
string
&
type
)
const
{
if
(
type
==
"mkldnn_relu"
)
{
return
mkldnn
::
algorithm
::
eltwise_relu
;
}
else
if
(
type
==
"mkldnn_tanh"
)
{
return
mkldnn
::
algorithm
::
eltwise_tanh
;
}
else
if
(
type
==
"mkldnn_elu"
)
{
return
mkldnn
::
algorithm
::
eltwise_elu
;
}
else
{
LOG
(
FATAL
)
<<
"Unkown eltwise activation type: "
<<
type
;
}
return
(
mkldnn
::
algorithm
)
0
;
}
/**
* reshape and reset the forward primitives
*/
void
resetFwd
(
Argument
&
act
)
{
if
(
cnt_
==
act
.
value
->
getElementCnt
())
{
return
;
}
cnt_
=
act
.
value
->
getElementCnt
();
stream_
.
reset
(
new
MKLDNNStream
());
auto
eng
=
CPUEngine
::
Instance
().
getEngine
();
// get algo setting
mkldnn
::
algorithm
algo
=
getAlgo
(
this
->
getName
());
// note: alpha represents the NegativeSlope when used in relu.
float
alpha
=
getAlpha
();
float
beta
=
getBeta
();
/// forward
pipelineFwd_
.
clear
();
val_
=
std
::
dynamic_pointer_cast
<
MKLDNNMatrix
>
(
act
.
value
);
if
(
val_
==
nullptr
)
{
int
bs
=
act
.
getBatchSize
();
int
ih
=
act
.
getFrameHeight
()
>
0
?
act
.
getFrameHeight
()
:
1
;
int
iw
=
act
.
getFrameWidth
()
>
0
?
act
.
getFrameWidth
()
:
1
;
int
ic
=
cnt_
/
bs
/
ih
/
iw
;
CHECK_EQ
(
cnt_
,
(
size_t
)
bs
*
ic
*
ih
*
iw
);
val_
=
MKLDNNMatrix
::
create
(
act
.
value
,
{
bs
,
ic
,
ih
,
iw
},
mkldnn
::
memory
::
format
::
nchw
,
eng
);
CHECK
(
val_
);
}
auto
fwdDesc
=
eltwise_fwd
::
desc
(
mkldnn
::
prop_kind
::
forward_training
,
algo
,
val_
->
getMemoryDesc
(),
alpha
,
beta
);
fwdPD_
.
reset
(
new
eltwise_fwd
::
primitive_desc
(
fwdDesc
,
eng
));
// use inplace for forward but save input value before submit
inVal_
=
val_
;
if
(
act
.
grad
)
{
// only copy when need do backward
inVal_
=
MKLDNNMatrix
::
create
(
nullptr
,
val_
->
getPrimitiveDesc
());
copyInVal_
=
std
::
make_shared
<
mkldnn
::
reorder
>
(
*
val_
,
*
inVal_
);
CHECK
(
copyInVal_
)
<<
"should not be emptry"
;
pipelineFwd_
.
push_back
(
*
copyInVal_
);
}
fwd_
.
reset
(
new
eltwise_fwd
(
*
fwdPD_
,
*
val_
,
*
val_
));
pipelineFwd_
.
push_back
(
*
fwd_
);
needResetBwd_
=
true
;
}
/**
* reset the backward primitives, can not merge into resetFwd as the grad data
* would be changing before backward.
*/
void
resetBwd
(
Argument
&
act
)
{
if
(
!
needResetBwd_
)
{
return
;
}
needResetBwd_
=
false
;
mkldnn
::
algorithm
algo
=
getAlgo
(
this
->
getName
());
float
alpha
=
getBwdAlpha
();
float
beta
=
getBeta
();
grad_
=
MKLDNNMatrix
::
create
(
act
.
grad
,
val_
->
getPrimitiveDesc
());
auto
eng
=
CPUEngine
::
Instance
().
getEngine
();
auto
bwdDesc
=
eltwise_bwd
::
desc
(
algo
,
grad_
->
getMemoryDesc
(),
val_
->
getMemoryDesc
(),
alpha
,
beta
);
auto
bwdPD
=
eltwise_bwd
::
primitive_desc
(
bwdDesc
,
eng
,
*
fwdPD_
);
CHECK
(
inVal_
);
bwd_
.
reset
(
new
eltwise_bwd
(
bwdPD
,
*
inVal_
,
*
grad_
,
*
grad_
));
pipelineBwd_
.
clear
();
pipelineBwd_
.
push_back
(
*
bwd_
);
}
Error
__must_check
forward
(
Argument
&
act
)
{
resetFwd
(
act
);
stream_
->
submit
(
pipelineFwd_
);
return
Error
();
}
Error
__must_check
backward
(
Argument
&
act
)
{
resetBwd
(
act
);
stream_
->
submit
(
pipelineBwd_
);
return
Error
();
}
};
}
// namespace paddle
paddle/gserver/layers/MKLDNNConvLayer.cpp
浏览文件 @
c15ac202
...
@@ -294,12 +294,9 @@ void MKLDNNConvLayer::resetOutValue(
...
@@ -294,12 +294,9 @@ void MKLDNNConvLayer::resetOutValue(
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
out
)
{
std
::
shared_ptr
<
conv_fwd
::
primitive_desc
>&
pd
,
MKLDNNMatrixPtr
&
out
)
{
out
=
MKLDNNMatrix
::
create
(
output_
.
value
,
pd
->
dst_primitive_desc
());
out
=
MKLDNNMatrix
::
create
(
output_
.
value
,
pd
->
dst_primitive_desc
());
// change original output value from cpu matrix to mkldnn matrix
output_
.
value
=
std
::
dynamic_pointer_cast
<
Matrix
>
(
out
);
// create reorder if output value has cpu device and pd do not match
// create reorder if output value has cpu device and pd do not match
cpuOutVal_
=
nullptr
;
cpuOutVal_
=
nullptr
;
c
pu
OutVal_
=
nullptr
;
c
vt
OutVal_
=
nullptr
;
if
(
!
outputIsOnlyMKLDNN
())
{
if
(
!
outputIsOnlyMKLDNN
())
{
const
MatrixPtr
&
cpuOut
=
getOutput
(
CPU_DEVICE
).
value
;
const
MatrixPtr
&
cpuOut
=
getOutput
(
CPU_DEVICE
).
value
;
memory
::
dims
outDims
=
memory
::
dims
{
bs_
,
oc_
,
oh_
,
ow_
};
memory
::
dims
outDims
=
memory
::
dims
{
bs_
,
oc_
,
oh_
,
ow_
};
...
...
paddle/gserver/layers/MKLDNNFcLayer.cpp
浏览文件 @
c15ac202
...
@@ -172,12 +172,10 @@ void MKLDNNFcLayer::resetWgtBiasValue(MKLDNNMatrixPtr& wgt,
...
@@ -172,12 +172,10 @@ void MKLDNNFcLayer::resetWgtBiasValue(MKLDNNMatrixPtr& wgt,
void
MKLDNNFcLayer
::
resetOutValue
(
MKLDNNMatrixPtr
&
out
)
{
void
MKLDNNFcLayer
::
resetOutValue
(
MKLDNNMatrixPtr
&
out
)
{
out
=
MKLDNNMatrix
::
create
(
output_
.
value
,
{
bs_
,
oc_
},
format
::
nc
,
engine_
);
out
=
MKLDNNMatrix
::
create
(
output_
.
value
,
{
bs_
,
oc_
},
format
::
nc
,
engine_
);
// change original output value to mkldnn output value
output_
.
value
=
std
::
dynamic_pointer_cast
<
Matrix
>
(
out
);
if
(
!
outputIsOnlyMKLDNN
())
{
if
(
!
outputIsOnlyMKLDNN
())
{
// fc cpu output value do not need create convert
// fc cpu output value do not need create convert
// just share point
// just share point
getOutput
(
CPU_DEVICE
).
value
->
setData
(
out
put_
.
value
->
getData
());
getOutput
(
CPU_DEVICE
).
value
->
setData
(
out
->
getData
());
}
}
}
}
...
...
paddle/gserver/layers/MKLDNNLayer.h
浏览文件 @
c15ac202
...
@@ -119,6 +119,10 @@ public:
...
@@ -119,6 +119,10 @@ public:
inputElemenCnt_
=
elemenCnt
;
inputElemenCnt_
=
elemenCnt
;
reshape
(
bs_
,
ic_
,
ih_
,
iw_
,
oc_
,
oh_
,
ow_
);
reshape
(
bs_
,
ic_
,
ih_
,
iw_
,
oc_
,
oh_
,
ow_
);
resetFwd
(
pipelineFwd_
,
inVal_
,
wgtVal_
,
biasVal_
,
outVal_
);
resetFwd
(
pipelineFwd_
,
inVal_
,
wgtVal_
,
biasVal_
,
outVal_
);
if
(
outVal_
)
{
// change original output value to mkldnn output value
output_
.
value
=
std
::
dynamic_pointer_cast
<
Matrix
>
(
outVal_
);
}
convertWeightsFromPaddle
();
convertWeightsFromPaddle
();
needResetBwd_
=
true
;
needResetBwd_
=
true
;
}
}
...
...
paddle/gserver/layers/MKLDNNPoolLayer.cpp
浏览文件 @
c15ac202
...
@@ -134,7 +134,6 @@ void MKLDNNPoolLayer::resetOutValue(MKLDNNMatrixPtr& out) {
...
@@ -134,7 +134,6 @@ void MKLDNNPoolLayer::resetOutValue(MKLDNNMatrixPtr& out) {
memory
::
dims
outDims
=
memory
::
dims
{
bs_
,
oc_
,
oh_
,
ow_
};
memory
::
dims
outDims
=
memory
::
dims
{
bs_
,
oc_
,
oh_
,
ow_
};
out
=
MKLDNNMatrix
::
create
(
out
=
MKLDNNMatrix
::
create
(
output_
.
value
,
outDims
,
inVal_
->
getFormat
(),
engine_
);
output_
.
value
,
outDims
,
inVal_
->
getFormat
(),
engine_
);
output_
.
value
=
std
::
dynamic_pointer_cast
<
Matrix
>
(
out
);
// create reorder if output value has cpu device and pd do not match
// create reorder if output value has cpu device and pd do not match
cpuOutVal_
=
nullptr
;
cpuOutVal_
=
nullptr
;
...
...
paddle/gserver/tests/MKLDNNTester.cpp
浏览文件 @
c15ac202
...
@@ -64,15 +64,17 @@ void MKLDNNTester::reset(const TestConfig& dnn,
...
@@ -64,15 +64,17 @@ void MKLDNNTester::reset(const TestConfig& dnn,
configs_
[
i
],
&
(
layerMaps_
[
i
]),
&
(
parameters_
[
i
]),
&
(
testLayers_
[
i
]));
configs_
[
i
],
&
(
layerMaps_
[
i
]),
&
(
parameters_
[
i
]),
&
(
testLayers_
[
i
]));
}
}
refLayer_
=
testLayers_
[
REF
];
refLayer_
=
testLayers_
[
REF
];
dnnLayer_
=
std
::
dynamic_pointer_cast
<
MKLDNNLayer
>
(
testLayers_
[
DNN
]);
dnnLayer_
=
testLayers_
[
DNN
];
CHECK
(
dnnLayer_
);
// for comparison with Paddle reference results,
// need manually add cpu device output for test
dnnLayer_
->
addOutputArgument
(
CPU_DEVICE
);
EXPECT_EQ
(
dataLayers_
[
DNN
].
size
(),
dataLayers_
[
REF
].
size
());
EXPECT_EQ
(
dataLayers_
[
DNN
].
size
(),
dataLayers_
[
REF
].
size
());
EXPECT_EQ
(
parameters_
[
DNN
].
size
(),
parameters_
[
REF
].
size
());
EXPECT_EQ
(
parameters_
[
DNN
].
size
(),
parameters_
[
REF
].
size
());
setInputImgSize
();
setInputImgSize
();
// for comparison with Paddle reference results,
// need manually add cpu device output for test
MKLDNNLayerPtr
dnnLayer
=
std
::
dynamic_pointer_cast
<
MKLDNNLayer
>
(
dnnLayer_
);
if
(
dnnLayer
)
{
dnnLayer
->
addOutputArgument
(
CPU_DEVICE
);
}
}
}
void
MKLDNNTester
::
setInputImgSize
()
{
void
MKLDNNTester
::
setInputImgSize
()
{
...
@@ -122,7 +124,7 @@ void MKLDNNTester::randomTopDiffs() {
...
@@ -122,7 +124,7 @@ void MKLDNNTester::randomTopDiffs() {
void
MKLDNNTester
::
checkForward
()
{
void
MKLDNNTester
::
checkForward
()
{
VLOG
(
MKLDNN_ALL
)
<<
"Check Forward"
;
VLOG
(
MKLDNN_ALL
)
<<
"Check Forward"
;
printTopDatas
();
printTopDatas
();
double
delta
=
compareMatrix
(
dnnLayer_
->
getOutput
(
-
1
).
value
,
double
delta
=
compareMatrix
(
dnnLayer_
->
getOutput
(
CPU_DEVICE
).
value
,
refLayer_
->
getOutputValue
());
refLayer_
->
getOutputValue
());
EXPECT_LE
(
fabs
(
delta
),
eps_
);
EXPECT_LE
(
fabs
(
delta
),
eps_
);
}
}
...
@@ -155,7 +157,10 @@ void MKLDNNTester::checkBackwardWgts() {
...
@@ -155,7 +157,10 @@ void MKLDNNTester::checkBackwardWgts() {
vector
<
VectorPtr
>
dnnWgts
;
// used to temply save mkldnn weights
vector
<
VectorPtr
>
dnnWgts
;
// used to temply save mkldnn weights
saveWgt
(
parameters_
[
DNN
],
dnnWgts
);
saveWgt
(
parameters_
[
DNN
],
dnnWgts
);
dnnLayer_
->
convertWeightsToPaddle
();
MKLDNNLayerPtr
dnnLayer
=
std
::
dynamic_pointer_cast
<
MKLDNNLayer
>
(
dnnLayer_
);
if
(
dnnLayer
)
{
dnnLayer
->
convertWeightsToPaddle
();
}
for
(
size_t
i
=
0
;
i
<
parameters_
[
DNN
].
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
parameters_
[
DNN
].
size
();
++
i
)
{
const
VectorPtr
&
dnn
=
parameters_
[
DNN
][
i
]
->
getBuf
(
PARAMETER_VALUE
);
const
VectorPtr
&
dnn
=
parameters_
[
DNN
][
i
]
->
getBuf
(
PARAMETER_VALUE
);
const
VectorPtr
&
ref
=
parameters_
[
REF
][
i
]
->
getBuf
(
PARAMETER_VALUE
);
const
VectorPtr
&
ref
=
parameters_
[
REF
][
i
]
->
getBuf
(
PARAMETER_VALUE
);
...
@@ -322,6 +327,10 @@ void MKLDNNTester::runOnce() {
...
@@ -322,6 +327,10 @@ void MKLDNNTester::runOnce() {
// and clearTopDatas(REF) should be coverd by ref layers
// and clearTopDatas(REF) should be coverd by ref layers
clearBotDiffs
(
REF
);
clearBotDiffs
(
REF
);
clearWgtDiffs
(
REF
);
clearWgtDiffs
(
REF
);
// it is necessary to clear bottom diffs when only activation is dnn type
if
(
configs_
[
DNN
].
layerConfig
.
active_type
().
compare
(
0
,
7
,
"mkldnn_"
)
==
0
)
{
clearBotDiffs
(
DNN
);
}
}
}
void
MKLDNNTester
::
run
(
const
TestConfig
&
dnn
,
void
MKLDNNTester
::
run
(
const
TestConfig
&
dnn
,
...
@@ -333,8 +342,19 @@ void MKLDNNTester::run(const TestConfig& dnn,
...
@@ -333,8 +342,19 @@ void MKLDNNTester::run(const TestConfig& dnn,
float
epsilon
,
float
epsilon
,
bool
log
,
bool
log
,
int
level
)
{
int
level
)
{
VLOG
(
MKLDNN_TESTS
)
<<
"Test MKLDNN functionality: "
<<
dnn
.
layerConfig
.
type
()
CHECK
(
dnn
.
layerConfig
.
type
().
compare
(
0
,
7
,
"mkldnn_"
)
==
0
||
<<
" vs "
<<
ref
.
layerConfig
.
type
();
dnn
.
layerConfig
.
active_type
().
compare
(
0
,
7
,
"mkldnn_"
)
==
0
)
<<
"should be MKLDNN layer or MKLDNN activation"
;
if
(
dnn
.
layerConfig
.
type
()
==
ref
.
layerConfig
.
type
())
{
VLOG
(
MKLDNN_TESTS
)
<<
"Test MKLDNN functionality: "
<<
dnn
.
layerConfig
.
active_type
()
<<
" vs "
<<
ref
.
layerConfig
.
active_type
();
}
else
{
VLOG
(
MKLDNN_TESTS
)
<<
"Test MKLDNN functionality: "
<<
dnn
.
layerConfig
.
type
()
<<
" vs "
<<
ref
.
layerConfig
.
type
();
}
ih_
=
inputImgH
;
ih_
=
inputImgH
;
iw_
=
inputImgW
;
iw_
=
inputImgW
;
iter_
=
iter
;
iter_
=
iter
;
...
...
paddle/gserver/tests/MKLDNNTester.h
浏览文件 @
c15ac202
...
@@ -41,8 +41,7 @@ protected:
...
@@ -41,8 +41,7 @@ protected:
vector
<
LayerMap
>
layerMaps_
;
vector
<
LayerMap
>
layerMaps_
;
vector
<
vector
<
ParameterPtr
>>
parameters_
;
vector
<
vector
<
ParameterPtr
>>
parameters_
;
vector
<
LayerPtr
>
testLayers_
;
vector
<
LayerPtr
>
testLayers_
;
LayerPtr
refLayer_
;
LayerPtr
refLayer_
,
dnnLayer_
;
MKLDNNLayerPtr
dnnLayer_
;
/// run some iterations, all the result should pass
/// run some iterations, all the result should pass
size_t
iter_
;
size_t
iter_
;
...
...
paddle/gserver/tests/test_MKLDNN.cpp
浏览文件 @
c15ac202
...
@@ -17,6 +17,7 @@ limitations under the License. */
...
@@ -17,6 +17,7 @@ limitations under the License. */
#include <vector>
#include <vector>
#include "MKLDNNTester.h"
#include "MKLDNNTester.h"
#include "ModelConfig.pb.h"
#include "ModelConfig.pb.h"
#include "paddle/gserver/activations/MKLDNNActivation.h"
#include "paddle/math/MathUtils.h"
#include "paddle/math/MathUtils.h"
using
namespace
paddle
;
// NOLINT
using
namespace
paddle
;
// NOLINT
...
@@ -162,7 +163,6 @@ void testPoolLayer(const testPoolDesc& pm) {
...
@@ -162,7 +163,6 @@ void testPoolLayer(const testPoolDesc& pm) {
0
});
0
});
LayerInputConfig
*
input
=
cfg
.
layerConfig
.
add_inputs
();
LayerInputConfig
*
input
=
cfg
.
layerConfig
.
add_inputs
();
PoolConfig
*
pool
=
input
->
mutable_pool_conf
();
PoolConfig
*
pool
=
input
->
mutable_pool_conf
();
// pool->set_pool_type(poolType);
pool
->
set_channels
(
pm
.
ch
);
pool
->
set_channels
(
pm
.
ch
);
pool
->
set_img_size
(
pm
.
iw
);
pool
->
set_img_size
(
pm
.
iw
);
pool
->
set_img_size_y
(
pm
.
ih
);
pool
->
set_img_size_y
(
pm
.
ih
);
...
@@ -191,7 +191,7 @@ void testPoolLayer(const testPoolDesc& pm) {
...
@@ -191,7 +191,7 @@ void testPoolLayer(const testPoolDesc& pm) {
}
}
}
}
TEST
(
M
kldnn
Layer
,
PoolLayer
)
{
TEST
(
M
KLDNN
Layer
,
PoolLayer
)
{
/* bs, ch, ih, iw, oh, ow, fh, fw, ph, pw, sh, sw*/
/* bs, ch, ih, iw, oh, ow, fh, fw, ph, pw, sh, sw*/
testPoolLayer
({
2
,
1
,
4
,
4
,
2
,
2
,
3
,
3
,
0
,
0
,
2
,
2
});
testPoolLayer
({
2
,
1
,
4
,
4
,
2
,
2
,
3
,
3
,
0
,
0
,
2
,
2
});
testPoolLayer
({
10
,
8
,
16
,
16
,
8
,
8
,
2
,
2
,
0
,
0
,
2
,
2
});
testPoolLayer
({
10
,
8
,
16
,
16
,
8
,
8
,
2
,
2
,
0
,
0
,
2
,
2
});
...
@@ -203,6 +203,49 @@ TEST(MkldnnLayer, PoolLayer) {
...
@@ -203,6 +203,49 @@ TEST(MkldnnLayer, PoolLayer) {
testPoolLayer
({
2
,
8
,
56
,
56
,
29
,
29
,
3
,
3
,
1
,
1
,
2
,
2
});
testPoolLayer
({
2
,
8
,
56
,
56
,
29
,
29
,
3
,
3
,
1
,
1
,
2
,
2
});
}
}
struct
testActDesc
{
int
bs
,
ch
;
int
ih
,
iw
;
};
static
void
getAddtoConfig
(
TestConfig
&
cfg
,
const
testActDesc
&
pm
)
{
cfg
.
biasSize
=
0
;
cfg
.
layerConfig
.
set_type
(
"addto"
);
cfg
.
layerConfig
.
set_size
(
pm
.
ch
*
pm
.
ih
*
pm
.
iw
);
cfg
.
inputDefs
.
push_back
(
{
INPUT_DATA
,
"layer_0"
,
/* size of input layer= */
size_t
(
pm
.
ch
*
pm
.
ih
*
pm
.
iw
),
0
});
cfg
.
layerConfig
.
add_inputs
();
}
void
testActivation
(
std
::
string
&
type
,
const
testActDesc
&
pm
)
{
const
std
::
string
compareTypes
[]
=
{
type
,
type
.
erase
(
0
,
7
)};
TestConfig
cfg
;
getAddtoConfig
(
cfg
,
pm
);
TestConfig
ref
=
cfg
;
cfg
.
layerConfig
.
set_active_type
(
compareTypes
[
0
]);
ref
.
layerConfig
.
set_active_type
(
compareTypes
[
1
]);
MKLDNNTester
tester
;
for
(
auto
bs
:
{
pm
.
bs
,
1
})
{
tester
.
run
(
cfg
,
ref
,
bs
,
pm
.
ih
,
pm
.
iw
);
}
}
TEST
(
MKLDNNActivation
,
Activations
)
{
auto
types
=
MKLDNNActivation
::
getAllRegisteredTypes
();
// TODO(TJ): mkldnn_softmax not implemented, paddle do not have elu activation
std
::
set
<
string
>
excluded
{
"mkldnn_softmax"
,
"mkldnn_elu"
};
for
(
auto
type
:
types
)
{
if
(
excluded
.
count
(
type
))
{
continue
;
}
testActivation
(
type
,
{
16
,
64
,
32
,
32
});
}
}
// TODO(TJ): add branch test
// TODO(TJ): add branch test
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录