Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
3cfb2e1a
P
Paddle
项目概览
PaddlePaddle
/
Paddle
大约 2 年 前同步成功
通知
2325
Star
20933
Fork
5424
代码
文件
提交
分支
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看板
未验证
提交
3cfb2e1a
编写于
12月 14, 2022
作者:
H
Hulek
提交者:
GitHub
12月 14, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Deleted mkldnn_inplace_pass code (#47818)
* Deleted mkldnn_inplace_pass code * Fixed error with cmake * Resolve conflicts
上级
f7514772
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
0 addition
and
593 deletion
+0
-593
paddle/fluid/framework/ir/CMakeLists.txt
paddle/fluid/framework/ir/CMakeLists.txt
+0
-17
paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass.cc
paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass.cc
+0
-228
paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass.h
paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass.h
+0
-43
paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass_tester.cc
...e/fluid/framework/ir/mkldnn/mkldnn_inplace_pass_tester.cc
+0
-231
paddle/fluid/inference/api/paddle_pass_builder.cc
paddle/fluid/inference/api/paddle_pass_builder.cc
+0
-6
python/paddle/fluid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py
...luid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py
+0
-7
python/paddle/fluid/tests/unittests/ir/inference/test_mkldnn_inplace_fuse_pass.py
...s/unittests/ir/inference/test_mkldnn_inplace_fuse_pass.py
+0
-56
tools/parallel_UT_rule.py
tools/parallel_UT_rule.py
+0
-4
tools/static_mode_white_list.py
tools/static_mode_white_list.py
+0
-1
未找到文件。
paddle/fluid/framework/ir/CMakeLists.txt
浏览文件 @
3cfb2e1a
...
...
@@ -151,19 +151,6 @@ endif()
if
(
WITH_MKLDNN
)
pass_library
(
mkldnn_placement_pass base DEPS placement_pass_base DIR mkldnn
)
pass_library
(
mkldnn_inplace_pass
inference
DEPS
mkldnn_placement_pass
op_registry
elementwise_add_op
generated_op
activation_op
softmax_op
softmax
DIR
mkldnn
)
pass_library
(
depthwise_conv_mkldnn_pass base DIR mkldnn
)
pass_library
(
conv_affine_channel_mkldnn_fuse_pass inference DIR mkldnn
)
pass_library
(
conv_bias_mkldnn_fuse_pass inference DIR mkldnn
)
...
...
@@ -450,10 +437,6 @@ if(WITH_MKLDNN)
test_mkldnn_placement_pass
SRCS mkldnn/mkldnn_placement_pass_tester.cc
DEPS mkldnn_placement_pass
)
cc_test
(
test_mkldnn_inplace_pass
SRCS mkldnn/mkldnn_inplace_pass_tester.cc
DEPS mkldnn_inplace_pass
)
cc_test
(
test_compute_propagate_scales_mkldnn_pass
SRCS mkldnn/compute_propagate_scales_mkldnn_pass_tester.cc
...
...
paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass.cc
已删除
100644 → 0
浏览文件 @
f7514772
// Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
//
// 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 "paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass.h"
#include <algorithm>
#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "paddle/fluid/framework/eigen.h"
#include "paddle/fluid/framework/lod_tensor.h"
#include "paddle/fluid/framework/op_info.h"
#include "paddle/fluid/framework/op_version_registry.h"
#include "paddle/fluid/platform/enforce.h"
namespace
paddle
{
namespace
framework
{
namespace
ir
{
void
MKLDNNInPlacePass
::
ApplyImpl
(
ir
::
Graph
*
graph
)
const
{
PADDLE_ENFORCE_NOT_NULL
(
graph
,
platform
::
errors
::
InvalidArgument
(
"Pointer to graph argument should not be NULL."
));
std
::
unordered_map
<
std
::
string
,
std
::
string
>
original_output_names
;
std
::
unordered_set
<
std
::
string
>
inplaced_vars
;
GraphPatternDetector
gpd
;
patterns
::
MKLDNNInPlace
mkldnn_inplace
{
gpd
.
mutable_pattern
(),
"mkldnn_inplace"
};
mkldnn_inplace
();
int
found_inplace_count
=
0
;
auto
handler
=
[
&
](
const
GraphPatternDetector
::
subgraph_t
&
subgraph
,
Graph
*
g
)
{
VLOG
(
3
)
<<
"Start to handle MKL-DNN In-Place pass"
;
GET_IR_NODE_FROM_SUBGRAPH
(
current_op
,
inplace_to_be_op
,
mkldnn_inplace
);
GET_IR_NODE_FROM_SUBGRAPH
(
current_op_in
,
inplace_to_be_op_in
,
mkldnn_inplace
);
GET_IR_NODE_FROM_SUBGRAPH
(
current_op_out
,
inplace_to_be_op_out
,
mkldnn_inplace
);
GET_IR_NODE_FROM_SUBGRAPH
(
next_op
,
next_op
,
mkldnn_inplace
);
GET_IR_NODE_FROM_SUBGRAPH
(
next_op_out
,
next_op_out
,
mkldnn_inplace
);
if
((
current_op
->
Op
()
->
HasAttr
(
"use_mkldnn"
)
==
false
)
||
(
PADDLE_GET_CONST
(
bool
,
current_op
->
Op
()
->
GetAttr
(
"use_mkldnn"
))
==
false
))
{
VLOG
(
3
)
<<
"do not perform mkl-dnn inplace: use_mkldnn missing or set to "
"false"
;
return
;
}
auto
&
infer_inplace
=
OpInfoMap
::
Instance
().
Get
(
current_op
->
Op
()
->
Type
()).
infer_inplace_
;
if
(
!
infer_inplace
)
{
VLOG
(
3
)
<<
"do not perform mkl-dnn inplace: missing InplaceInferer"
;
return
;
}
VLOG
(
3
)
<<
"oneDNN Inplace op("
<<
current_op
->
id
()
<<
") "
<<
"Curr Node In: "
<<
current_op_in
->
Name
()
<<
" Curr Node out: "
<<
current_op_out
->
Name
();
VLOG
(
3
)
<<
"oneDNN Inplace next op("
<<
next_op
->
id
()
<<
") "
<<
" next Node out: "
<<
next_op_out
->
Name
();
auto
inputs
=
current_op
->
Op
()
->
Inputs
();
auto
outputs
=
current_op
->
Op
()
->
Outputs
();
auto
in_to_outs
=
infer_inplace
(
false
);
// strictly no CUDA for MKL-DNN
VLOG
(
3
)
<<
"oneDNN InplaceInferer op("
<<
current_op
->
id
()
<<
") "
<<
in_to_outs
.
begin
()
->
first
<<
": "
<<
inputs
[
in_to_outs
.
begin
()
->
first
][
0
]
<<
" "
<<
in_to_outs
.
begin
()
->
second
<<
": "
<<
outputs
[
in_to_outs
.
begin
()
->
second
][
0
];
// If InferInplace pattern does not contain input node then skip
auto
inplace_input_vec
=
inputs
[
in_to_outs
.
begin
()
->
first
];
if
(
std
::
find
(
inplace_input_vec
.
begin
(),
inplace_input_vec
.
end
(),
current_op_in
->
Name
())
==
inplace_input_vec
.
end
())
{
VLOG
(
3
)
<<
"oneDNN in-place pass SKIP pattern "
;
return
;
}
// Checking if this particular node (to be inplaced, overwritten)
// is used anywhere else apart from inplaced op
auto
input_consumers
=
current_op_in
->
outputs
;
if
(
input_consumers
.
size
()
>
1
)
{
VLOG
(
3
)
<<
"oneDNN in-place pass FAIL: in-place var cannot "
"be an input to multiple operators"
;
return
;
}
else
{
// We will prevent in-place when
// input is used in other part of graph, unless it was a result of
// inplacing
// Allow to next op out reuse inpuit var, as this is the same chaing
if
(
inplaced_vars
.
find
(
current_op_in
->
Name
())
==
inplaced_vars
.
end
())
{
for
(
const
Node
*
n
:
graph
->
Nodes
())
{
if
((
n
->
id
()
!=
current_op_in
->
id
())
&&
(
n
->
id
()
!=
next_op_out
->
id
())
&&
(
n
->
Name
()
==
current_op_in
->
Name
()))
{
VLOG
(
3
)
<<
"oneDNN in-place pass FAIL var used in diffrent part of "
"graph "
;
return
;
}
}
}
}
// If this op was alrady inplaced in previous pass placements
// then we need to update input of next op
// but original name to be changed is gone, so we need to remember it
// on first time given op is to be inplaced
if
(
current_op_in
->
Name
()
!=
current_op_out
->
Name
())
{
original_output_names
[
current_op
->
Name
()
+
current_op_in
->
Name
()]
=
current_op_out
->
Name
();
}
else
{
VLOG
(
3
)
<<
"oneDNN Inplace: Current op already inplaced! "
;
}
// It may be that next op is reusing some of vars, we need to
// make sure that unwanted inplace is not created
for
(
auto
&
n
:
current_op_out
->
outputs
)
{
auto
&
n_op_infer_inplace
=
OpInfoMap
::
Instance
().
Get
(
n
->
Op
()
->
Type
()).
infer_inplace_
;
if
((
n_op_infer_inplace
==
nullptr
))
{
for
(
auto
&
m
:
n
->
outputs
)
{
if
(
m
->
Name
()
==
current_op_in
->
Name
())
{
VLOG
(
3
)
<<
"oneDNN in-place pass FAIL: in-place var cannot "
"be an output to non-inplaced next op"
;
return
;
}
}
}
}
auto
original_name
=
original_output_names
[
current_op
->
Name
()
+
current_op_in
->
Name
()];
current_op_out
->
RenameVar
(
current_op_in
->
Name
());
// Get mapping of input to output
auto
out_name
=
in_to_outs
.
begin
()
->
second
;
current_op
->
Op
()
->
SetOutput
(
out_name
,
std
::
vector
<
std
::
string
>
({
current_op_out
->
Name
()}));
// Record var name
inplaced_vars
.
insert
(
current_op_out
->
Name
());
// If next op in a line is doing inplace
// then we need to update its output as well
// Get inferer of next op
// If no inferer then we are done
auto
&
next_op_infer_inplace
=
OpInfoMap
::
Instance
().
Get
(
next_op
->
Op
()
->
Type
()).
infer_inplace_
;
if
(
next_op_infer_inplace
)
{
auto
in_to_outs
=
next_op_infer_inplace
(
false
);
auto
out_name
=
in_to_outs
.
begin
()
->
second
;
auto
*
op
=
next_op
->
Op
();
auto
inputs
=
op
->
Inputs
();
auto
outputs
=
op
->
Outputs
();
// Check if in-place happened
// for variable we changed (original name)
// TODO(jczaja): make recursive propagation of inplace
auto
next_op_inplace_inputs
=
inputs
[
in_to_outs
.
begin
()
->
first
];
if
((
next_op_inplace_inputs
==
outputs
[
in_to_outs
.
begin
()
->
second
])
&&
(
std
::
find
(
next_op_inplace_inputs
.
begin
(),
next_op_inplace_inputs
.
end
(),
original_name
)
!=
next_op_inplace_inputs
.
end
()))
{
VLOG
(
3
)
<<
"oneDNN InPlace: Next Op is in-placed , updating its "
"input "
"and output var!"
;
next_op
->
Op
()
->
SetOutput
(
out_name
,
std
::
vector
<
std
::
string
>
({
current_op_out
->
Name
()}));
next_op_out
->
RenameVar
(
current_op_in
->
Name
());
// Get ops that next_op_out is linked to and update their input
auto
next_op_out_consumers
=
next_op_out
->
outputs
;
// Has to be ops
for
(
auto
&
c
:
next_op_out_consumers
)
{
c
->
Op
()
->
RenameInput
(
original_name
,
current_op_out
->
Name
());
}
}
}
next_op
->
Op
()
->
RenameInput
(
original_name
,
current_op_out
->
Name
());
found_inplace_count
++
;
VLOG
(
3
)
<<
"oneDNN InPlace applied!"
;
};
// TODO(jczaja): inplace pass does not influece ops inside block ops
auto
should_inplace
=
[
&
](
Graph
*
g
)
{
std
::
unordered_set
<
std
::
string
>
unwanted_ops
(
{
"conditional_block"
,
"While"
,
"while_loop"
});
for
(
auto
&
node
:
g
->
Nodes
())
{
if
(
node
->
IsOp
()
&&
unwanted_ops
.
find
(
node
->
Name
())
!=
unwanted_ops
.
end
())
{
VLOG
(
3
)
<<
"oneDNN InPlace FAILED: unsupported op: "
<<
node
->
Name
();
return
false
;
}
}
return
true
;
};
if
(
should_inplace
(
graph
))
gpd
(
graph
,
handler
);
}
}
// namespace ir
}
// namespace framework
}
// namespace paddle
REGISTER_PASS
(
mkldnn_inplace_pass
,
paddle
::
framework
::
ir
::
MKLDNNInPlacePass
);
REGISTER_PASS_CAPABILITY
(
mkldnn_inplace_pass
)
.
AddCombination
(
paddle
::
framework
::
compatible
::
OpVersionComparatorCombination
()
.
EQ
(
"softmax"
,
0
)
.
LE
(
"elementwise_add"
,
1
)
.
EQ
(
"tanh"
,
0
));
paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass.h
已删除
100644 → 0
浏览文件 @
f7514772
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// 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 <memory>
#include "paddle/fluid/framework/ir/graph.h"
#include "paddle/fluid/framework/ir/graph_pattern_detector.h"
#include "paddle/fluid/framework/ir/pass.h"
namespace
paddle
{
namespace
framework
{
namespace
ir
{
/*
* Transpose weights of FC to comply with MKL-DNN interface
*/
class
MKLDNNInPlacePass
:
public
Pass
{
public:
virtual
~
MKLDNNInPlacePass
()
{}
protected:
void
ApplyImpl
(
ir
::
Graph
*
graph
)
const
;
private:
#if PADDLE_WITH_TESTING
friend
class
MKLDNNInPlacePassTest
;
#endif
};
}
// namespace ir
}
// namespace framework
}
// namespace paddle
paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass_tester.cc
已删除
100644 → 0
浏览文件 @
f7514772
// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
//
// 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 <gtest/gtest.h>
#include <unordered_set>
#include "paddle/utils/tribool.h"
#include "paddle/fluid/framework/ir/mkldnn/mkldnn_inplace_pass.h"
#include "paddle/fluid/framework/ir/pass_tester_helper.h"
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/phi/core/kernel_registry.h"
USE_OP_ITSELF
(
softmax
);
PD_DECLARE_KERNEL
(
softmax
,
OneDNN
,
ONEDNN
);
USE_OP_ITSELF
(
elementwise_add
);
PD_DECLARE_KERNEL
(
add_raw
,
OneDNN
,
ONEDNN
);
USE_OP_ITSELF
(
leaky_relu
);
PD_DECLARE_KERNEL
(
leaky_relu
,
OneDNN
,
ONEDNN
);
USE_OP_ITSELF
(
gelu
);
USE_OP_ITSELF
(
relu
);
USE_OP_ITSELF
(
tanh
);
PD_DECLARE_KERNEL
(
tanh
,
OneDNN
,
ONEDNN
);
PD_DECLARE_ARG_MAPPING_FN
(
gelu
);
namespace
paddle
{
namespace
framework
{
namespace
ir
{
class
MKLDNNInplacePassTest
{
private:
void
SetOp
(
ProgramDesc
*
prog
,
const
std
::
string
&
type
,
const
std
::
string
&
name
,
const
std
::
vector
<
std
::
string
>&
inputs
,
const
std
::
vector
<
std
::
string
>&
outputs
,
paddle
::
tribool
use_mkldnn
)
{
auto
*
op
=
prog
->
MutableBlock
(
0
)
->
AppendOp
();
op
->
SetType
(
type
);
if
(
!
paddle
::
indeterminate
(
use_mkldnn
))
op
->
SetAttr
(
"use_mkldnn"
,
use_mkldnn
);
if
(
type
==
"conv2d"
)
{
op
->
SetAttr
(
"name"
,
name
);
op
->
SetInput
(
"Input"
,
{
inputs
[
0
]});
op
->
SetInput
(
"Filter"
,
{
inputs
[
1
]});
op
->
SetInput
(
"Bias"
,
{
inputs
[
2
]});
}
else
if
(
std
::
unordered_set
<
std
::
string
>
{
"gelu"
,
"leaky_relu"
,
"relu"
,
"tanh"
}
.
count
(
type
))
{
op
->
SetInput
(
"X"
,
inputs
);
}
else
if
(
type
==
"softmax"
)
{
op
->
SetAttr
(
"axis"
,
-
1
);
op
->
SetInput
(
"X"
,
inputs
);
}
else
if
(
type
==
"elementwise_add"
)
{
op
->
SetInput
(
"X"
,
{
inputs
[
0
]});
op
->
SetInput
(
"Y"
,
{
inputs
[
1
]});
}
else
{
FAIL
()
<<
"Unexpected operator type."
;
}
op
->
SetOutput
(
"Out"
,
{
outputs
[
0
]});
}
ProgramDesc
BuildProgramDesc
(
const
std
::
string
&
mkldnn_enabled_op
,
bool
branched
)
{
ProgramDesc
prog
;
for
(
auto
&
v
:
std
::
vector
<
std
::
string
>
({
"a"
,
"weights"
,
"bias"
,
"f"
,
"g"
,
"h"
,
"i"
,
"j"
,
"k"
,
"l"
,
"m"
,
"n"
,
"z"
}))
{
auto
*
var
=
prog
.
MutableBlock
(
0
)
->
Var
(
v
);
var
->
SetType
(
proto
::
VarType
::
SELECTED_ROWS
);
if
(
v
==
"weights"
||
v
==
"bias"
)
{
var
->
SetPersistable
(
true
);
}
}
SetOp
(
&
prog
,
"conv2d"
,
"conv1"
,
std
::
vector
<
std
::
string
>
({
"a"
,
"weights"
,
"bias"
}),
std
::
vector
<
std
::
string
>
({
"f"
}),
paddle
::
indeterminate
);
SetOp
(
&
prog
,
"relu"
,
"relu1"
,
std
::
vector
<
std
::
string
>
({
"f"
}),
std
::
vector
<
std
::
string
>
({
"g"
}),
mkldnn_enabled_op
.
compare
(
"relu"
)
==
0
);
SetOp
(
&
prog
,
"softmax"
,
"softmax1"
,
std
::
vector
<
std
::
string
>
({
"g"
}),
std
::
vector
<
std
::
string
>
({
"h"
}),
mkldnn_enabled_op
.
compare
(
"softmax"
)
==
0
);
SetOp
(
&
prog
,
"elementwise_add"
,
"elementwise_add1"
,
std
::
vector
<
std
::
string
>
({
"h"
,
"i"
}),
std
::
vector
<
std
::
string
>
({
"j"
}),
mkldnn_enabled_op
.
compare
(
"elementwise_add"
)
==
0
);
SetOp
(
&
prog
,
"relu"
,
"relu2"
,
std
::
vector
<
std
::
string
>
({
"j"
}),
std
::
vector
<
std
::
string
>
({
"k"
}),
mkldnn_enabled_op
.
compare
(
"relu"
)
==
0
);
SetOp
(
&
prog
,
"tanh"
,
"tanh1"
,
std
::
vector
<
std
::
string
>
({
"k"
}),
std
::
vector
<
std
::
string
>
({
"l"
}),
mkldnn_enabled_op
.
compare
(
"tanh"
)
==
0
);
SetOp
(
&
prog
,
"relu"
,
"relu3"
,
std
::
vector
<
std
::
string
>
({
"l"
}),
std
::
vector
<
std
::
string
>
({
"m"
}),
mkldnn_enabled_op
.
compare
(
"relu"
)
==
0
);
SetOp
(
&
prog
,
"leaky_relu"
,
"leaky_relu1"
,
std
::
vector
<
std
::
string
>
({
"m"
}),
std
::
vector
<
std
::
string
>
({
"n"
}),
mkldnn_enabled_op
.
compare
(
"leaky_relu"
)
==
0
);
SetOp
(
&
prog
,
"gelu"
,
"gelu1"
,
std
::
vector
<
std
::
string
>
({
"n"
}),
std
::
vector
<
std
::
string
>
({
"m"
}),
mkldnn_enabled_op
.
compare
(
"gelu"
)
==
0
);
if
(
branched
==
true
)
{
SetOp
(
&
prog
,
"softmax"
,
"softmax2"
,
std
::
vector
<
std
::
string
>
({
"g"
}),
std
::
vector
<
std
::
string
>
({
"z"
}),
mkldnn_enabled_op
.
compare
(
"softmax"
)
==
0
);
}
return
prog
;
}
public:
void
MainTest
(
const
std
::
string
&
mkldnn_enabled_op
,
bool
branched
,
unsigned
expected_use_mkldnn_true_count
)
{
auto
prog
=
BuildProgramDesc
(
mkldnn_enabled_op
,
branched
);
std
::
unique_ptr
<
ir
::
Graph
>
graph
(
new
ir
::
Graph
(
prog
));
auto
pass
=
PassRegistry
::
Instance
().
Get
(
"mkldnn_inplace_pass"
);
graph
.
reset
(
pass
->
Apply
(
graph
.
release
()));
unsigned
use_mkldnn_true_count
=
0
;
std
::
unordered_map
<
std
::
string
,
std
::
string
>
input_names
;
std
::
unordered_map
<
std
::
string
,
std
::
string
>
output_names
;
VLOG
(
3
)
<<
DebugString
(
graph
);
for
(
auto
*
node
:
graph
->
Nodes
())
{
if
(
node
->
IsOp
())
{
auto
*
op
=
node
->
Op
();
if
(
op
->
Type
()
==
mkldnn_enabled_op
)
{
auto
ins
=
op
->
Inputs
();
auto
outs
=
op
->
Outputs
();
// Input and output are the same var
// All inplace ops are inplacing input named: X
// and output : Out
if
(
ins
[
"X"
]
==
outs
[
"Out"
])
{
++
use_mkldnn_true_count
;
}
}
}
}
EXPECT_EQ
(
use_mkldnn_true_count
,
expected_use_mkldnn_true_count
);
}
};
TEST
(
MKLDNNInplacePass
,
inplace_softmax
)
{
// softmax to be mkl-dnn enabled and made in-place
MKLDNNInplacePassTest
().
MainTest
(
"softmax"
,
false
,
1
);
}
TEST
(
MKLDNNInplacePass
,
inplace_softmax_branched
)
{
// softmax's input is shared by two branches. so no in-place
MKLDNNInplacePassTest
().
MainTest
(
"softmax"
,
true
,
0
);
}
TEST
(
MKLDNNInplacePass
,
inplace_elementwise_add
)
{
// Two elementwise_add mkl-dnn enabled op instances to be made inplace
MKLDNNInplacePassTest
().
MainTest
(
"elementwise_add"
,
false
,
0
);
}
TEST
(
MKLDNNInplacePass
,
inplace_tanh
)
{
MKLDNNInplacePassTest
().
MainTest
(
"tanh"
,
false
,
1
);
}
TEST
(
MKLDNNInplacePass
,
inplace_leaky_relu
)
{
// Input of leaky_relu is used as output of subsequent gelu, so no inplace
// cannot be done
MKLDNNInplacePassTest
().
MainTest
(
"leaky_relu"
,
false
,
0
);
}
}
// namespace ir
}
// namespace framework
}
// namespace paddle
USE_PASS
(
mkldnn_inplace_pass
);
paddle/fluid/inference/api/paddle_pass_builder.cc
浏览文件 @
3cfb2e1a
...
...
@@ -355,11 +355,6 @@ void CpuPassStrategy::EnableMKLDNN() {
"operator_scale_onednn_fuse_pass"
,
//
"operator_unsqueeze2_onednn_fuse_pass"
,
//
"operator_reshape2_onednn_fuse_pass"
,
//
// TODO(intel): Please fix the bug on windows.
// https://github.com/PaddlePaddle/Paddle/issues/29710
// "mkldnn_inplace_pass", // This pass should be activated after
// fuses. Disabled by default due to
// little gain and lots of problems
}))
{
passes_
.
push_back
(
pass
);
}
...
...
@@ -459,7 +454,6 @@ void CpuPassStrategy::EnableMkldnnInt8() {
passes_
.
push_back
(
"cpu_quantize_squash_pass"
);
passes_
.
push_back
(
"int8_scale_calculation_mkldnn_pass"
);
passes_
.
push_back
(
"params_quantization_mkldnn_pass"
);
passes_
.
push_back
(
"mkldnn_inplace_pass"
);
}
use_mkldnn_int8_
=
true
;
#else
...
...
python/paddle/fluid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py
浏览文件 @
3cfb2e1a
...
...
@@ -111,7 +111,6 @@ class Quant2Int8MkldnnPass:
# graph = self._update_relu_output_scales(graph)
graph
=
self
.
_propagate_scales
(
graph
)
graph
=
self
.
_quantize_fp32_graph
(
graph
)
graph
=
self
.
_final_optimizations
(
graph
)
graph
=
self
.
_cleanup
(
graph
)
return
graph
...
...
@@ -122,7 +121,6 @@ class Quant2Int8MkldnnPass:
self
.
_reset_pass_idx_and_group
(
'fp32'
)
graph
=
self
.
_optimize_fp32_graph
(
graph
)
graph
=
self
.
_final_optimizations
(
graph
)
graph
=
self
.
_cleanup
(
graph
)
return
graph
...
...
@@ -521,11 +519,6 @@ class Quant2Int8MkldnnPass:
self
.
_pass_idx
+=
1
return
graph
def
_final_optimizations
(
self
,
graph
):
# make some MKL-DNN ops working inplace
graph
=
self
.
_apply_pass
(
graph
,
'mkldnn_inplace_pass'
)
return
graph
def
_cleanup
(
self
,
graph
):
graph
=
self
.
_remove_unused_var_nodes
(
graph
)
graph
=
self
.
_set_op_role_forward
(
graph
)
...
...
python/paddle/fluid/tests/unittests/ir/inference/test_mkldnn_inplace_fuse_pass.py
已删除
100644 → 0
浏览文件 @
f7514772
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
import
unittest
import
numpy
as
np
from
inference_pass_test
import
InferencePassTest
import
paddle
import
paddle.fluid
as
fluid
import
paddle.nn.functional
as
F
from
paddle.fluid.core
import
PassVersionChecker
class
MkldnnInplacePassTest
(
InferencePassTest
):
def
setUp
(
self
):
with
fluid
.
program_guard
(
self
.
main_program
,
self
.
startup_program
):
paddle
.
enable_static
()
data
=
fluid
.
data
(
name
=
"data"
,
shape
=
[
-
1
,
3
,
100
,
100
],
dtype
=
"float32"
)
conv_out_1
=
fluid
.
layers
.
conv2d
(
data
,
num_filters
=
3
,
filter_size
=
3
,
bias_attr
=
False
)
softmax_out
=
paddle
.
nn
.
functional
.
softmax
(
conv_out_1
)
relu_out
=
F
.
relu
(
conv_out_1
)
eltwise_out
=
paddle
.
add
(
softmax_out
,
relu_out
)
self
.
pass_name
=
'mkldnn_inplace_pass'
self
.
feeds
=
{
"data"
:
np
.
random
.
random
((
1
,
3
,
100
,
100
)).
astype
(
"float32"
)
}
self
.
fetch_list
=
[
softmax_out
,
relu_out
,
eltwise_out
]
self
.
enable_mkldnn
=
True
def
test_check_output
(
self
):
use_gpu
=
False
self
.
check_output_with_option
(
use_gpu
)
def
test_pass_compatible
(
self
):
self
.
assertTrue
(
PassVersionChecker
.
IsCompatible
(
self
.
pass_name
))
if
__name__
==
"__main__"
:
unittest
.
main
()
tools/parallel_UT_rule.py
浏览文件 @
3cfb2e1a
...
...
@@ -112,7 +112,6 @@ HIGH_PARALLEL_JOB_NEW = [
'test_fc_lstm_fuse_pass_cc'
,
'test_version'
,
'gather_test'
,
'test_mkldnn_inplace_fuse_pass'
,
'test_reshape_bf16_op'
,
'test_compat'
,
'test_data_feeder'
,
...
...
@@ -237,7 +236,6 @@ HIGH_PARALLEL_JOB_NEW = [
'test_selected_rows'
,
'test_fleet_sharding_meta_optimizer'
,
'test_inference_api'
,
'test_mkldnn_inplace_pass'
,
'test_data_generator'
,
'test_deprecated_memory_optimize_interfaces'
,
'test_ir_skip_layernorm_pass'
,
...
...
@@ -1819,8 +1817,6 @@ CPU_PARALLEL_JOB = [
'test_mkldnn_op_inplace'
,
'test_mkldnn_matmul_transpose_reshape_fuse_pass'
,
'test_mkldnn_matmul_op_output_fuse_pass'
,
'test_mkldnn_inplace_pass'
,
'test_mkldnn_inplace_fuse_pass'
,
'test_mkldnn_cpu_bfloat16_pass'
,
'test_mkldnn_conv_concat_relu_mkldnn_fuse_pass'
,
'test_mkldnn_conv_bias_fuse_pass'
,
...
...
tools/static_mode_white_list.py
浏览文件 @
3cfb2e1a
...
...
@@ -655,7 +655,6 @@ STATIC_MODE_TESTING_LIST = [
'test_mkldnn_matmul_op_output_fuse_pass'
,
'test_mkldnn_matmul_transpose_reshape_fuse_pass'
,
'test_mkldnn_scale_matmul_fuse_pass'
,
'test_mkldnn_inplace_fuse_pass'
,
'test_mkldnn_conv_affine_channel_fuse_pass'
,
'test_batch_fc_op'
,
'test_c_comm_init_all_op'
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录