Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
X2Paddle
提交
841bfa0b
X
X2Paddle
项目概览
PaddlePaddle
/
X2Paddle
大约 1 年 前同步成功
通知
328
Star
698
Fork
167
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
26
列表
看板
标记
里程碑
合并请求
4
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
X2Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
26
Issue
26
列表
看板
标记
里程碑
合并请求
4
合并请求
4
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
841bfa0b
编写于
8月 29, 2020
作者:
S
SunAhong1993
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add optimizer
上级
ab446bfd
变更
10
展开全部
显示空白变更内容
内联
并排
Showing
10 changed file
with
1410 addition
and
29 deletion
+1410
-29
x2paddle/convert.py
x2paddle/convert.py
+33
-0
x2paddle/core/program.py
x2paddle/core/program.py
+6
-3
x2paddle/op_mapper/pytorch2paddle/aten.py
x2paddle/op_mapper/pytorch2paddle/aten.py
+251
-1
x2paddle/op_mapper/pytorch2paddle/prim.py
x2paddle/op_mapper/pytorch2paddle/prim.py
+34
-5
x2paddle/op_mapper/pytorch2paddle/prim2code.py
x2paddle/op_mapper/pytorch2paddle/prim2code.py
+60
-13
x2paddle/op_mapper/pytorch2paddle/pytorch_op_mapper.py
x2paddle/op_mapper/pytorch2paddle/pytorch_op_mapper.py
+6
-1
x2paddle/optimizer/fusion/__init__.py
x2paddle/optimizer/fusion/__init__.py
+6
-4
x2paddle/optimizer/fusion/interpolate_bilinear_fuse_pass.py
x2paddle/optimizer/fusion/interpolate_bilinear_fuse_pass.py
+33
-0
x2paddle/optimizer/fusion/interpolate_bilinear_fuser.py
x2paddle/optimizer/fusion/interpolate_bilinear_fuser.py
+978
-0
x2paddle/optimizer/optimizer.py
x2paddle/optimizer/optimizer.py
+3
-2
未找到文件。
x2paddle/convert.py
浏览文件 @
841bfa0b
...
@@ -174,6 +174,36 @@ def onnx2paddle(model_path, save_dir, params_merge=False):
...
@@ -174,6 +174,36 @@ def onnx2paddle(model_path, save_dir, params_merge=False):
print
(
"Paddle model and code generated."
)
print
(
"Paddle model and code generated."
)
def
pytorch2paddle
(
model_path
,
save_dir
):
# check pytorch installation and version
try
:
import
torch
version
=
torch
.
__version__
ver_part
=
version
.
split
(
'.'
)
print
(
ver_part
)
if
int
(
ver_part
[
1
])
<
5
:
print
(
"[ERROR] pytorch>=1.5.0 is required"
)
return
except
:
print
(
"[ERROR] Pytorch is not installed, use
\"
pip install torch==1.5.0 torchvision
\"
."
)
return
print
(
"Now translating model from pytorch to paddle."
)
from
x2paddle.decoder.pytorch_decoder
import
PyTorchDecoder
from
x2paddle.op_mapper.pytorch2paddle
import
pytorch_op_mapper
model
=
PyTorchDecoder
(
model_path
)
mapper
=
pytorch_op_mapper
.
PyTorchOpMapper
(
model
)
mapper
.
graph
.
build
()
print
(
"Model optimizing ..."
)
from
x2paddle.optimizer.optimizer
import
GraphOptimizer
graph_opt
=
GraphOptimizer
()
graph_opt
.
optimize
(
mapper
.
graph
)
print
(
"Model optimized."
)
mapper
.
graph
.
gen_model
(
save_dir
)
def
paddle2onnx
(
model_path
,
save_dir
,
opset_version
=
10
):
def
paddle2onnx
(
model_path
,
save_dir
,
opset_version
=
10
):
from
x2paddle.decoder.paddle_decoder
import
PaddleDecoder
from
x2paddle.decoder.paddle_decoder
import
PaddleDecoder
from
x2paddle.op_mapper.paddle2onnx.paddle_op_mapper
import
PaddleOpMapper
from
x2paddle.op_mapper.paddle2onnx.paddle_op_mapper
import
PaddleOpMapper
...
@@ -243,6 +273,9 @@ def main():
...
@@ -243,6 +273,9 @@ def main():
if
args
.
params_merge
:
if
args
.
params_merge
:
params_merge
=
True
params_merge
=
True
onnx2paddle
(
args
.
model
,
args
.
save_dir
,
params_merge
)
onnx2paddle
(
args
.
model
,
args
.
save_dir
,
params_merge
)
elif
args
.
framework
==
"pytorch"
:
assert
args
.
model
is
not
None
,
"--model should be defined while translating pytorch model"
pytorch2paddle
(
args
.
model
,
args
.
save_dir
)
elif
args
.
framework
==
"paddle2onnx"
:
elif
args
.
framework
==
"paddle2onnx"
:
assert
args
.
model
is
not
None
,
"--model should be defined while translating paddle model to onnx"
assert
args
.
model
is
not
None
,
"--model should be defined while translating paddle model to onnx"
...
...
x2paddle/core/program.py
浏览文件 @
841bfa0b
...
@@ -132,6 +132,7 @@ class PaddleGraph(object):
...
@@ -132,6 +132,7 @@ class PaddleGraph(object):
if
self
.
graph_type
==
"dygraph"
:
if
self
.
graph_type
==
"dygraph"
:
self
.
get_dygraph_inputs
()
self
.
get_dygraph_inputs
()
if
len
(
self
.
outputs
)
==
0
:
self
.
get_dygraph_outputs
()
self
.
get_dygraph_outputs
()
def
get_global_layers
(
self
):
def
get_global_layers
(
self
):
...
@@ -164,8 +165,8 @@ class PaddleGraph(object):
...
@@ -164,8 +165,8 @@ class PaddleGraph(object):
f
,
[
f
,
[
"from paddle.fluid.initializer import Constant"
,
"from paddle.fluid.initializer import Constant"
,
"from paddle.fluid.param_attr import ParamAttr"
,
"from paddle.fluid.param_attr import ParamAttr"
,
"import paddle.fluid as fluid"
"import paddle.fluid as fluid"
,
"import math"
,
""
,
"
"
,
"
def x2paddle_net():"
"def x2paddle_net():"
],
],
indent
=
0
)
indent
=
0
)
for
layer_id
,
layer
in
self
.
layers
.
items
():
for
layer_id
,
layer
in
self
.
layers
.
items
():
...
@@ -204,6 +205,8 @@ class PaddleGraph(object):
...
@@ -204,6 +205,8 @@ class PaddleGraph(object):
f
.
close
()
f
.
close
()
def
gen_model
(
self
,
save_dir
):
def
gen_model
(
self
,
save_dir
):
if
not
os
.
path
.
exists
(
save_dir
):
os
.
makedirs
(
save_dir
)
if
self
.
graph_type
==
"static"
:
if
self
.
graph_type
==
"static"
:
code_dir
=
os
.
path
.
join
(
save_dir
,
'model_with_code'
)
code_dir
=
os
.
path
.
join
(
save_dir
,
'model_with_code'
)
infer_dir
=
os
.
path
.
join
(
save_dir
,
'inference_model'
)
infer_dir
=
os
.
path
.
join
(
save_dir
,
'inference_model'
)
...
...
x2paddle/op_mapper/pytorch2paddle/aten.py
浏览文件 @
841bfa0b
...
@@ -451,6 +451,35 @@ def aten_chunk(mapper, graph, node):
...
@@ -451,6 +451,35 @@ def aten_chunk(mapper, graph, node):
return
current_inputs
,
current_outputs
return
current_inputs
,
current_outputs
def
aten___contains__
(
mapper
,
graph
,
node
):
""" 构造in的PaddleLayer。
TorchScript示例:
%51 : bool = aten::__contains__(%50, %name.1)
参数含义:
%51 (bool): 输出,第一个元素是否包含第二个元素。
%50 (-): 需对比的输入1。
%name.1 (-): 需对比的输入2。
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
layer_outputs
=
[
output_name
]
layer_inputs
=
{}
inputs_name
,
inputs_node
=
mapper
.
_get_inputs_name
(
node
)
# 获取当前节点输出的list
current_outputs
=
[
output_name
]
# 处理输入0,即%50
mapper
.
_check_input
(
graph
,
inputs_node
[
0
],
inputs_name
[
0
],
current_outputs
)
layer_inputs
[
"input"
]
=
inputs_name
[
0
]
# 处理输入1,即%name.1
mapper
.
_check_input
(
graph
,
inputs_node
[
1
],
inputs_name
[
1
],
current_outputs
)
layer_inputs
[
"element"
]
=
inputs_name
[
1
]
# 获取当前节点输入的list
current_inputs
=
list
(
layer_inputs
.
values
())
graph
.
add_layer
(
"prim.contain"
,
inputs
=
layer_inputs
,
outputs
=
layer_outputs
)
return
current_inputs
,
current_outputs
def
aten_contiguous
(
mapper
,
graph
,
node
):
def
aten_contiguous
(
mapper
,
graph
,
node
):
""" 构造在内存中连续存储的PaddleLayer。
""" 构造在内存中连续存储的PaddleLayer。
...
@@ -545,6 +574,25 @@ def aten_conv2d(mapper, graph, node):
...
@@ -545,6 +574,25 @@ def aten_conv2d(mapper, graph, node):
return
current_inputs
,
current_outputs
return
current_inputs
,
current_outputs
def
aten_dict
(
mapper
,
graph
,
node
):
""" 构造初始化dict的PaddleLayer。
TorchScript示例:
%features.1 : Dict(str, Tensor) = aten::dict()
参数含义:
%features.1: 输出,初始化的dict。
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
layer_outputs
=
[
output_name
]
layer_inputs
=
{}
current_inputs
=
{}
# 获取当前节点输出的list
current_outputs
=
[
output_name
]
graph
.
add_layer
(
"prim.dict"
,
inputs
=
layer_inputs
,
outputs
=
layer_outputs
)
return
current_inputs
,
current_outputs
def
aten_dim
(
mapper
,
graph
,
node
):
def
aten_dim
(
mapper
,
graph
,
node
):
""" 构造获取维度的PaddleLayer。
""" 构造获取维度的PaddleLayer。
...
@@ -720,6 +768,56 @@ def aten_flatten(mapper, graph, node):
...
@@ -720,6 +768,56 @@ def aten_flatten(mapper, graph, node):
return
current_inputs
,
current_outputs
return
current_inputs
,
current_outputs
def
aten_Float
(
mapper
,
graph
,
node
):
""" 构造取浮点型的PaddleLayer。
TorchScript示例:
%3992 : float = aten::Float(%3991)
参数含义:
%3992 (int): 向上取整后的整数。
%3991 (float): 需要取整的浮点数。
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
layer_outputs
=
[
output_name
]
layer_inputs
=
{}
inputs_name
,
inputs_node
=
mapper
.
_get_inputs_name
(
node
)
# 获取当前节点输出的list
current_outputs
=
[
output_name
]
# 处理输入0,即%3991
mapper
.
_check_input
(
graph
,
inputs_node
[
0
],
inputs_name
[
0
],
current_outputs
)
layer_inputs
[
"input"
]
=
inputs_name
[
0
]
# 获取当前节点输入的list
current_inputs
=
list
(
layer_inputs
.
values
())
graph
.
add_layer
(
"prim.float"
,
inputs
=
layer_inputs
,
outputs
=
layer_outputs
)
return
current_inputs
,
current_outputs
def
aten_floor
(
mapper
,
graph
,
node
):
""" 构造向上取整的PaddleLayer。
TorchScript示例:
%3978 : int = aten::floor(%scale.18)
参数含义:
%3978 (int): 向上取整后的整数。
%scale.18 (float): 需要取整的浮点数。
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
layer_outputs
=
[
output_name
]
layer_inputs
=
{}
inputs_name
,
inputs_node
=
mapper
.
_get_inputs_name
(
node
)
# 获取当前节点输出的list
current_outputs
=
[
output_name
]
# 处理输入0,即%scale.18
mapper
.
_check_input
(
graph
,
inputs_node
[
0
],
inputs_name
[
0
],
current_outputs
)
layer_inputs
[
"input"
]
=
inputs_name
[
0
]
# 获取当前节点输入的list
current_inputs
=
list
(
layer_inputs
.
values
())
graph
.
add_layer
(
"prim.floor"
,
inputs
=
layer_inputs
,
outputs
=
layer_outputs
)
return
current_inputs
,
current_outputs
def
aten_floordiv
(
mapper
,
graph
,
node
):
def
aten_floordiv
(
mapper
,
graph
,
node
):
""" 构造向上取整除法的PaddleLayer。
""" 构造向上取整除法的PaddleLayer。
...
@@ -727,7 +825,7 @@ def aten_floordiv(mapper, graph, node):
...
@@ -727,7 +825,7 @@ def aten_floordiv(mapper, graph, node):
%channels_per_group.2 : int = aten::floordiv(%num_channels.2, %3690)
%channels_per_group.2 : int = aten::floordiv(%num_channels.2, %3690)
参数含义:
参数含义:
%channels_per_group.2 (-): 除后的结果。
%channels_per_group.2 (-): 除后的结果。
%
%
num_channels.2 (-): 被除数。
%num_channels.2 (-): 被除数。
%2 (int): 除数。
%2 (int): 除数。
"""
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
...
@@ -854,6 +952,64 @@ def aten_hardtanh_(mapper, graph, node):
...
@@ -854,6 +952,64 @@ def aten_hardtanh_(mapper, graph, node):
return
current_inputs
,
current_outputs
return
current_inputs
,
current_outputs
def
aten___is__
(
mapper
,
graph
,
node
):
""" 构造is not的PaddleLayer。
TorchScript示例:
%3949 : bool = aten::__isnot__(%size.122, %3931)
参数含义:
%3949 (bool): 输出,第一个元素是否不是第二个元素。
%size.122 (-): 需对比的输入1。
%3931 (-): 需对比的输入2。
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
layer_outputs
=
[
output_name
]
layer_inputs
=
{}
inputs_name
,
inputs_node
=
mapper
.
_get_inputs_name
(
node
)
# 获取当前节点输出的list
current_outputs
=
[
output_name
]
# 处理输入0,即%size.122
mapper
.
_check_input
(
graph
,
inputs_node
[
0
],
inputs_name
[
0
],
current_outputs
)
layer_inputs
[
"x"
]
=
inputs_name
[
0
]
# 处理输入1,即%3931
mapper
.
_check_input
(
graph
,
inputs_node
[
1
],
inputs_name
[
1
],
current_outputs
)
layer_inputs
[
"y"
]
=
inputs_name
[
1
]
# 获取当前节点输入的list
current_inputs
=
list
(
layer_inputs
.
values
())
graph
.
add_layer
(
"prim.is"
,
inputs
=
layer_inputs
,
outputs
=
layer_outputs
)
return
current_inputs
,
current_outputs
def
aten___isnot__
(
mapper
,
graph
,
node
):
""" 构造is not的PaddleLayer。
TorchScript示例:
%3949 : bool = aten::__isnot__(%size.122, %3931)
参数含义:
%3949 (bool): 输出,第一个元素是否不是第二个元素。
%size.122 (-): 需对比的输入1。
%3931 (-): 需对比的输入2。
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
layer_outputs
=
[
output_name
]
layer_inputs
=
{}
inputs_name
,
inputs_node
=
mapper
.
_get_inputs_name
(
node
)
# 获取当前节点输出的list
current_outputs
=
[
output_name
]
# 处理输入0,即%size.122
mapper
.
_check_input
(
graph
,
inputs_node
[
0
],
inputs_name
[
0
],
current_outputs
)
layer_inputs
[
"x"
]
=
inputs_name
[
0
]
# 处理输入1,即%3931
mapper
.
_check_input
(
graph
,
inputs_node
[
1
],
inputs_name
[
1
],
current_outputs
)
layer_inputs
[
"y"
]
=
inputs_name
[
1
]
# 获取当前节点输入的list
current_inputs
=
list
(
layer_inputs
.
values
())
graph
.
add_layer
(
"prim.isnot"
,
inputs
=
layer_inputs
,
outputs
=
layer_outputs
)
return
current_inputs
,
current_outputs
def
aten_le
(
mapper
,
graph
,
node
):
def
aten_le
(
mapper
,
graph
,
node
):
""" 构造对比大小的PaddleLayer。
""" 构造对比大小的PaddleLayer。
...
@@ -1344,6 +1500,36 @@ def aten_select(mapper, graph, node):
...
@@ -1344,6 +1500,36 @@ def aten_select(mapper, graph, node):
return
current_inputs
,
current_outputs
return
current_inputs
,
current_outputs
def
aten__set_item
(
mapper
,
graph
,
node
):
""" 构造对dict加入元素的PaddleLayer。
TorchScript示例:
= aten::_set_item(%features.1, %out_name.1, %x.3)
参数含义:
%features.1 (list): dict。
%out_name.1 (-): dict的key。
%x.3 (-): dict的value。
"""
layer_inputs
=
{}
inputs_name
,
inputs_node
=
mapper
.
_get_inputs_name
(
node
)
# 获取当前节点输出的list
current_outputs
=
[]
# 处理输入0,即%features.1
mapper
.
_check_input
(
graph
,
inputs_node
[
0
],
inputs_name
[
0
],
current_outputs
)
layer_inputs
[
"dict"
]
=
inputs_name
[
0
]
# 处理输入1,即%out_name.1
mapper
.
_check_input
(
graph
,
inputs_node
[
1
],
inputs_name
[
1
],
current_outputs
)
layer_inputs
[
"key"
]
=
inputs_name
[
1
]
# 处理输入2,即%x.3
mapper
.
_check_input
(
graph
,
inputs_node
[
2
],
inputs_name
[
2
],
current_outputs
)
layer_inputs
[
"value"
]
=
inputs_name
[
2
]
# 获取当前节点输入的list
current_inputs
=
list
(
layer_inputs
.
values
())
graph
.
add_layer
(
"prim.set_item"
,
inputs
=
layer_inputs
,
outputs
=
[])
return
current_inputs
,
current_outputs
def
aten_size
(
mapper
,
graph
,
node
):
def
aten_size
(
mapper
,
graph
,
node
):
""" 构造获取shape的PaddleLayer。
""" 构造获取shape的PaddleLayer。
...
@@ -1569,6 +1755,70 @@ def aten_unsqueeze(mapper, graph, node):
...
@@ -1569,6 +1755,70 @@ def aten_unsqueeze(mapper, graph, node):
return
current_inputs
,
current_outputs
return
current_inputs
,
current_outputs
def
aten_upsample_bilinear2d
(
mapper
,
graph
,
node
):
""" 构造使用bilinear上采样的PaddleLayer。
TorchScript示例:
%4997 : Tensor = aten::upsample_bilinear2d(%x.13, %4963, %5421, %4995, %4996)
参数含义:
%4997 (Tensor): 输出,上采样后的Tensor。
%x.13 (Tensor): 需要上采样的Tensor。
%4963 (list): 上采样后的大小。
%5421 (bool): 若为True,则将输入和输出张量的4个角落像素的中心对齐,并保留角点像素的值。
%4995 (float): 高度的乘数因子。
%4995 (float): 宽度的乘数因子。
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
layer_outputs
=
[
output_name
]
layer_inputs
=
{}
layer_attrs
=
{}
inputs_name
,
inputs_node
=
mapper
.
_get_inputs_name
(
node
)
# 获取当前节点输出的list
current_outputs
=
[
output_name
]
# 处理输入0,即%x.13
mapper
.
_check_input
(
graph
,
inputs_node
[
0
],
inputs_name
[
0
],
current_outputs
)
layer_inputs
[
"input"
]
=
inputs_name
[
0
]
# 获取当前节点输入的list
current_inputs
=
list
(
layer_inputs
.
values
())
# 处理输入1,即%4963
if
inputs_name
[
1
]
in
mapper
.
attrs
:
layer_attrs
[
"out_shape"
]
=
mapper
.
attrs
[
inputs_name
[
1
]]
else
:
mapper
.
_check_input
(
graph
,
inputs_node
[
1
],
inputs_name
[
1
],
current_outputs
)
layer_inputs
[
"out_shape"
]
=
inputs_name
[
1
]
current_inputs
.
append
(
inputs_name
[
1
])
# 处理输入2,即%5421
if
inputs_name
[
2
]
in
mapper
.
attrs
:
layer_attrs
[
"align_corners"
]
=
mapper
.
attrs
[
inputs_name
[
2
]]
else
:
mapper
.
_check_input
(
graph
,
inputs_node
[
2
],
inputs_name
[
2
],
current_outputs
)
layer_inputs
[
"align_corners"
]
=
inputs_name
[
2
]
current_inputs
.
append
(
inputs_name
[
2
])
# 处理输入3和4,构造assert
list_layer_inputs
=
{}
mapper
.
_check_input
(
graph
,
inputs_node
[
3
],
inputs_name
[
3
],
current_outputs
)
list_layer_inputs
[
"key"
]
=
inputs_name
[
3
]
current_inputs
.
append
(
inputs_name
[
3
])
mapper
.
_check_input
(
graph
,
inputs_node
[
4
],
inputs_name
[
4
],
current_outputs
)
list_layer_inputs
[
"value"
]
=
inputs_name
[
4
]
current_inputs
.
append
(
inputs_name
[
4
])
graph
.
add_layer
(
"prim.assert"
,
inputs
=
list_layer_inputs
,
outputs
=
[
output_name
+
"_assert"
],
type
=
"eq"
)
layer_inputs
[
"scale"
]
=
inputs_name
[
3
]
layer_attrs
[
"align_mode"
]
=
0
graph
.
add_layer
(
"fluid.layers.interpolate"
,
inputs
=
layer_inputs
,
outputs
=
layer_outputs
,
**
layer_attrs
)
return
current_inputs
,
current_outputs
def
aten_view
(
mapper
,
graph
,
node
):
def
aten_view
(
mapper
,
graph
,
node
):
""" 构造调整大小的PaddleLayer。
""" 构造调整大小的PaddleLayer。
...
...
x2paddle/op_mapper/pytorch2paddle/prim.py
浏览文件 @
841bfa0b
...
@@ -111,13 +111,14 @@ def prim_If(mapper, graph, node):
...
@@ -111,13 +111,14 @@ def prim_If(mapper, graph, node):
%107 (bool): if判断条件。
%107 (bool): if判断条件。
%input.5 (Tensor): if控制流的输出,与%output.4对应。
%input.5 (Tensor): if控制流的输出,与%output.4对应。
"""
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
outputs_name
=
mapper
.
_get_outputs_name
(
node
)
node_outputs
=
[
output_name
]
node_outputs
=
outputs_name
.
copy
()
current_outputs
=
outputs_name
.
copy
()
input_node
=
list
(
node
.
inputs
())[
0
].
node
()
input_node
=
list
(
node
.
inputs
())[
0
].
node
()
script_input_unique_id
=
list
(
node
.
inputs
())[
0
].
unique
()
script_input_unique_id
=
list
(
node
.
inputs
())[
0
].
unique
()
input_node_name
=
mapper
.
outputs_info
[
script_input_unique_id
]
input_node_name
=
mapper
.
outputs_info
[
script_input_unique_id
]
mapper
.
_check_input
(
graph
,
input_node
,
input_node_name
,
node
_outputs
)
mapper
.
_check_input
(
graph
,
input_node
,
input_node_name
,
current
_outputs
)
graph
.
add_layer
(
"prim.if"
,
{
'input'
:
input_node_name
},
[
output_name
]
)
graph
.
add_layer
(
"prim.if"
,
{
'input'
:
input_node_name
},
node_outputs
)
current_layer
=
list
(
graph
.
layers
.
values
())[
-
1
]
current_layer
=
list
(
graph
.
layers
.
values
())[
-
1
]
block0
=
list
(
node
.
blocks
())[
0
]
block0
=
list
(
node
.
blocks
())[
0
]
block0_graph
,
graph_inputs0
=
mapper
.
traverse
(
block0
,
current_layer
)
block0_graph
,
graph_inputs0
=
mapper
.
traverse
(
block0
,
current_layer
)
...
@@ -131,7 +132,7 @@ def prim_If(mapper, graph, node):
...
@@ -131,7 +132,7 @@ def prim_If(mapper, graph, node):
for
i
,
input_name
in
enumerate
(
graph_inputs1
):
for
i
,
input_name
in
enumerate
(
graph_inputs1
):
current_layer
.
inputs
[
'input-{}'
.
format
(
len0
+
1
+
i
)]
=
input_name
current_layer
.
inputs
[
'input-{}'
.
format
(
len0
+
1
+
i
)]
=
input_name
current_layer
.
add_block
(
block1_graph
)
current_layer
.
add_block
(
block1_graph
)
return
list
(
current_layer
.
inputs
.
values
()),
node
_outputs
return
list
(
current_layer
.
inputs
.
values
()),
current
_outputs
def
prim_ListConstruct
(
mapper
,
graph
,
node
):
def
prim_ListConstruct
(
mapper
,
graph
,
node
):
...
@@ -436,6 +437,34 @@ def prim_TupleUnpack(mapper, graph, node):
...
@@ -436,6 +437,34 @@ def prim_TupleUnpack(mapper, graph, node):
return
current_inputs
,
current_outputs
return
current_inputs
,
current_outputs
def
prim_unchecked_cast
(
mapper
,
graph
,
node
):
""" 构造确认类型的PaddleLayer。
TorchScript示例:
%size.64 : int[] = prim::unchecked_cast(%size.63)
参数含义:
%size.64 (-): 输出。
%size.63 (-): 输入。
【注意】Paddle中无此用法,所以此处翻译成赋值。
"""
output_name
=
mapper
.
_get_outputs_name
(
node
)[
0
]
layer_outputs
=
[
output_name
]
layer_inputs
=
{}
layer_attrs
=
{}
inputs_name
,
inputs_node
=
mapper
.
_get_inputs_name
(
node
)
# 获取当前节点输出的list
current_outputs
=
[
output_name
]
# 处理输入0,即%size.63
mapper
.
_check_input
(
graph
,
inputs_node
[
0
],
inputs_name
[
0
],
current_outputs
)
layer_inputs
[
"input"
]
=
inputs_name
[
0
]
# 获取当前节点输入的list
current_inputs
=
list
(
layer_inputs
.
values
())
graph
.
add_layer
(
"prim.equal"
,
inputs
=
layer_inputs
,
outputs
=
layer_outputs
)
return
current_inputs
,
current_outputs
def
prim_Uninitialized
(
mapper
,
graph
,
node
):
def
prim_Uninitialized
(
mapper
,
graph
,
node
):
""" 构造表示编译器永远不会使用的值的PaddleLayer,该节点转换为None。
""" 构造表示编译器永远不会使用的值的PaddleLayer,该节点转换为None。
...
...
x2paddle/op_mapper/pytorch2paddle/prim2code.py
浏览文件 @
841bfa0b
...
@@ -62,18 +62,22 @@ def prim_append(layer, indent=1, init_func=[], forward_func=[]):
...
@@ -62,18 +62,22 @@ def prim_append(layer, indent=1, init_func=[], forward_func=[]):
def
prim_assert
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
def
prim_assert
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
if
layer
.
attrs
[
"type"
]
==
"eq"
:
if
layer
.
attrs
[
"type"
]
==
"eq"
:
if
isinstance
(
layer
.
attrs
[
"value"
],
list
):
values
=
get_value
(
layer
,
"key"
)
if
"value"
in
layer
.
attrs
:
values
=
layer
.
attrs
[
"value"
]
if
isinstance
(
values
,
list
):
s
=
""
s
=
""
for
v
in
layer
.
attrs
[
"value"
]
:
for
v
in
values
:
s
+=
"{} == {} or "
.
format
(
layer
.
attrs
[
"key"
]
,
v
)
s
+=
"{} == {} or "
.
format
(
get_value
(
layer
,
"key"
)
,
v
)
if
len
(
s
)
>
0
:
if
len
(
s
)
>
0
:
s
=
s
[:
-
4
]
s
=
s
[:
-
4
]
line
=
"assert {},
\'
The {} must be {}!
\'
"
.
format
(
line
=
"assert {},
\'
The {} must be {}!
\'
"
.
format
(
s
,
layer
.
attrs
[
"key"
],
layer
.
attrs
[
"value"
]
)
s
,
get_value
(
layer
,
"key"
),
get_value
(
layer
,
"value"
)
)
else
:
else
:
line
=
"assert {} == {},
\'
The {} must be {}!
\'
"
.
format
(
line
=
"assert {} == {},
\'
The {} must be {}!
\'
"
.
format
(
layer
.
attrs
[
"key"
],
layer
.
attrs
[
"value"
],
layer
.
attrs
[
"key"
],
get_value
(
layer
,
"key"
),
layer
.
attrs
[
"value"
])
get_value
(
layer
,
"value"
),
get_value
(
layer
,
"key"
),
get_value
(
layer
,
"value"
))
else
:
else
:
raise
Exception
(
"Not implement yet!"
)
raise
Exception
(
"Not implement yet!"
)
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
...
@@ -84,6 +88,18 @@ def prim_constant(layer, indent=1, init_func=[], forward_func=[]):
...
@@ -84,6 +88,18 @@ def prim_constant(layer, indent=1, init_func=[], forward_func=[]):
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_contain
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = {} in {}"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"element"
),
get_value
(
layer
,
"input"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_dict
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = dict()"
.
format
(
layer
.
outputs
[
0
])
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_eq
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
def
prim_eq
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = {} == {}"
.
format
(
layer
.
outputs
[
0
],
line
=
"{} = {} == {}"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"x"
),
get_value
(
layer
,
"y"
))
get_value
(
layer
,
"x"
),
get_value
(
layer
,
"y"
))
...
@@ -100,12 +116,36 @@ def prim_exception(layer, indent=1, init_func=[], forward_func=[]):
...
@@ -100,12 +116,36 @@ def prim_exception(layer, indent=1, init_func=[], forward_func=[]):
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_float
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = float({})"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"input"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_floor
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = math.floor({})"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"input"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_floordiv
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
def
prim_floordiv
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = {} // {}"
.
format
(
layer
.
outputs
[
0
],
line
=
"{} = {} // {}"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"x"
),
get_value
(
layer
,
"y"
))
get_value
(
layer
,
"x"
),
get_value
(
layer
,
"y"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_getitem
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = {}[{}]"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"list"
),
get_value
(
layer
,
"index"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_gt
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = {} > {}"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"x"
),
get_value
(
layer
,
"y"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_if
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
def
prim_if
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"if {} :"
.
format
(
get_value
(
layer
,
"input"
))
line
=
"if {} :"
.
format
(
get_value
(
layer
,
"input"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
...
@@ -123,16 +163,16 @@ def prim_if(layer, indent=1, init_func=[], forward_func=[]):
...
@@ -123,16 +163,16 @@ def prim_if(layer, indent=1, init_func=[], forward_func=[]):
forward_func
.
extend
(
b_forward_lines
)
forward_func
.
extend
(
b_forward_lines
)
def
prim_getitem
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
def
prim_is
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = {}[{}]"
.
format
(
layer
.
outputs
[
0
],
line
=
"{} = {} is {}"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"list"
),
get_value
(
layer
,
"x"
),
get_value
(
layer
,
"y"
))
get_value
(
layer
,
"index"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_gt
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
def
prim_isnot
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = {} > {}"
.
format
(
layer
.
outputs
[
0
],
line
=
"{} = {} is not {}"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"x"
),
get_value
(
layer
,
"y"
))
get_value
(
layer
,
"x"
),
get_value
(
layer
,
"y"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
...
@@ -239,6 +279,13 @@ def prim_set_attr(layer, indent=1, init_func=[], forward_func=[]):
...
@@ -239,6 +279,13 @@ def prim_set_attr(layer, indent=1, init_func=[], forward_func=[]):
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_set_item
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{}[{}] = {}"
.
format
(
get_value
(
layer
,
"dict"
),
get_value
(
layer
,
"key"
),
get_value
(
layer
,
"value"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
def
prim_shape
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
def
prim_shape
(
layer
,
indent
=
1
,
init_func
=
[],
forward_func
=
[]):
line
=
"{} = {}.shape"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"input"
))
line
=
"{} = {}.shape"
.
format
(
layer
.
outputs
[
0
],
get_value
(
layer
,
"input"
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
forward_func
.
extend
(
gen_codes
([
line
],
indent
=
indent
))
...
...
x2paddle/op_mapper/pytorch2paddle/pytorch_op_mapper.py
浏览文件 @
841bfa0b
...
@@ -108,9 +108,14 @@ class PyTorchOpMapper(OpMapper):
...
@@ -108,9 +108,14 @@ class PyTorchOpMapper(OpMapper):
parent_layer
=
parent_layer
,
parent_layer
=
parent_layer
,
index
=
i
)
index
=
i
)
_update_graph_inputs
(
"equal"
,
inputs
,
outputs
)
_update_graph_inputs
(
"equal"
,
inputs
,
outputs
)
# 设置graph的参数
# 设置graph的参数和输出节点
if
isinstance
(
script_graph
,
torch
.
_C
.
Graph
):
if
isinstance
(
script_graph
,
torch
.
_C
.
Graph
):
graph
.
set_parameters
(
self
.
paddle_params
)
graph
.
set_parameters
(
self
.
paddle_params
)
if
hasattr
(
script_graph
,
'return_node'
):
inputs_name
,
inputs_node
=
self
.
_get_inputs_name
(
script_graph
.
return_node
())
graph
.
outputs
=
inputs_name
return
graph
,
graph_inputs
return
graph
,
graph_inputs
def
_get_outputs_name
(
self
,
node
,
attr_name
=
None
):
def
_get_outputs_name
(
self
,
node
,
attr_name
=
None
):
...
...
x2paddle/optimizer/fusion/__init__.py
浏览文件 @
841bfa0b
...
@@ -12,11 +12,13 @@
...
@@ -12,11 +12,13 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
from
.fc_fuser
import
FcFuser
from
.fc_fuse_pass
import
FcFusePass
from
.adaptive_pool2d_fuser
import
AdaptivePool2dFuser
from
.adaptive_pool2d_fuser
import
AdaptivePool2dFuser
from
.adaptive_pool2d_fuse_pass
import
AdaptivePool2dFusePass
from
.adaptive_pool2d_fuse_pass
import
AdaptivePool2dFusePass
from
.constant_fuser
import
ConstantFuser
from
.constant_fuse_pass
import
ConstantFusePass
from
.batchnorm2d_fuser
import
BatchNorm2dFuser
from
.batchnorm2d_fuser
import
BatchNorm2dFuser
from
.batchnorm2d_fuse_pass
import
BatchNorm2dFusePass
from
.batchnorm2d_fuse_pass
import
BatchNorm2dFusePass
from
.constant_fuser
import
ConstantFuser
from
.constant_fuse_pass
import
ConstantFusePass
from
.fc_fuser
import
FcFuser
from
.fc_fuse_pass
import
FcFusePass
from
.interpolate_bilinear_fuser
import
InterpolateBilinearFuser
from
.interpolate_bilinear_fuse_pass
import
InterpolateBilinearFusePass
x2paddle/optimizer/fusion/interpolate_bilinear_fuse_pass.py
0 → 100644
浏览文件 @
841bfa0b
# 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.
from
x2paddle.optimizer.pass_
import
Pass
from
x2paddle.optimizer.fusion
import
InterpolateBilinearFuser
from
x2paddle.optimizer.pass_manager
import
pass_register
@
pass_register
class
InterpolateBilinearFusePass
(
Pass
):
name
=
"interpolate_bilinear_fuse_pass"
def
__init__
(
self
):
Pass
.
__init__
(
self
)
def
apply
(
self
,
graph
):
fuser
=
InterpolateBilinearFuser
()
fuser
.
operate
(
graph
,
match_kind
=
"topo"
)
# 用于注册
interpolate_bilinear_fuse_pass
=
InterpolateBilinearFusePass
()
x2paddle/optimizer/fusion/interpolate_bilinear_fuser.py
0 → 100644
浏览文件 @
841bfa0b
此差异已折叠。
点击以展开。
x2paddle/optimizer/optimizer.py
浏览文件 @
841bfa0b
...
@@ -19,8 +19,9 @@ from x2paddle.optimizer.pass_manager import PassManager
...
@@ -19,8 +19,9 @@ from x2paddle.optimizer.pass_manager import PassManager
class
GraphOptimizer
(
object
):
class
GraphOptimizer
(
object
):
def
__init__
(
self
):
def
__init__
(
self
):
self
.
passes
=
[
self
.
passes
=
[
"fc_fuse_pass"
,
"adaptive_pool2d_fuse_pass"
,
"interpolate_bilinear_fuse_pass"
,
"fc_fuse_pass"
,
"batchnorm2d_fuse_pass"
,
"constant_fuse_pass"
"adaptive_pool2d_fuse_pass"
,
"batchnorm2d_fuse_pass"
,
"constant_fuse_pass"
]
]
def
optimize
(
self
,
graph
):
def
optimize
(
self
,
graph
):
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录