From e2ebdf8b53a135b80b95d85acf4e2eae45d42a61 Mon Sep 17 00:00:00 2001 From: SunAhong1993 Date: Thu, 27 Aug 2020 11:06:25 +0800 Subject: [PATCH] add optimizer and aten for shufflenet --- x2paddle/core/program.py | 5 - x2paddle/decoder/pytorch_decoder.py | 3 +- x2paddle/op_mapper/pytorch2paddle/aten.py | 297 +++++++++++++++++- x2paddle/op_mapper/pytorch2paddle/prim.py | 153 ++++++--- .../op_mapper/pytorch2paddle/prim2code.py | 26 ++ x2paddle/optimizer/fusion/__init__.py | 6 +- .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 615 bytes .../adaptive_pool2d_fuse_pass.cpython-37.pyc | Bin 0 -> 925 bytes .../adaptive_pool2d_fuser.cpython-37.pyc | Bin 0 -> 4305 bytes .../batchnorm2d_fuse_pass.cpython-37.pyc | Bin 0 -> 905 bytes .../batchnorm2d_fuser.cpython-37.pyc | Bin 0 -> 5440 bytes .../constant_fuse_pass.cpython-37.pyc | Bin 0 -> 887 bytes .../__pycache__/constant_fuser.cpython-37.pyc | Bin 0 -> 2136 bytes .../__pycache__/fc_fuse_pass.cpython-37.pyc | Bin 0 -> 851 bytes .../__pycache__/fc_fuser.cpython-37.pyc | Bin 0 -> 4421 bytes ...l_adaptive_pool2d_fuse_pass.cpython-37.pyc | Bin 0 -> 987 bytes ...ional_adaptive_pool2d_fuser.cpython-37.pyc | Bin 0 -> 4553 bytes ...n_adaptive_pool2d_fuse_pass.cpython-37.pyc | Bin 0 -> 939 bytes .../nn_adaptive_pool2d_fuser.cpython-37.pyc | Bin 0 -> 4320 bytes .../fusion/adaptive_pool2d_fuse_pass.py | 33 ++ .../optimizer/fusion/adaptive_pool2d_fuser.py | 168 ++++++++++ .../optimizer/fusion/batchnorm2d_fuse_pass.py | 33 ++ .../optimizer/fusion/batchnorm2d_fuser.py | 236 ++++++++++++++ .../optimizer/fusion/constant_fuse_pass.py | 31 ++ x2paddle/optimizer/fusion/constant_fuser.py | 63 ++++ x2paddle/optimizer/fusion/fc_fuser.py | 60 ++-- x2paddle/optimizer/optimizer.py | 7 +- 27 files changed, 1002 insertions(+), 119 deletions(-) create mode 100644 x2paddle/optimizer/fusion/__pycache__/__init__.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/adaptive_pool2d_fuse_pass.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/adaptive_pool2d_fuser.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/batchnorm2d_fuse_pass.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/batchnorm2d_fuser.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/constant_fuse_pass.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/constant_fuser.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/fc_fuse_pass.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/fc_fuser.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/functional_adaptive_pool2d_fuse_pass.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/functional_adaptive_pool2d_fuser.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/nn_adaptive_pool2d_fuse_pass.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/__pycache__/nn_adaptive_pool2d_fuser.cpython-37.pyc create mode 100644 x2paddle/optimizer/fusion/adaptive_pool2d_fuse_pass.py create mode 100644 x2paddle/optimizer/fusion/adaptive_pool2d_fuser.py create mode 100644 x2paddle/optimizer/fusion/batchnorm2d_fuse_pass.py create mode 100644 x2paddle/optimizer/fusion/batchnorm2d_fuser.py create mode 100644 x2paddle/optimizer/fusion/constant_fuse_pass.py create mode 100644 x2paddle/optimizer/fusion/constant_fuser.py diff --git a/x2paddle/core/program.py b/x2paddle/core/program.py index ab76c91..75c4be5 100644 --- a/x2paddle/core/program.py +++ b/x2paddle/core/program.py @@ -101,11 +101,6 @@ class PaddleGraph(object): self.clear_edges() outputs_from_nodes = dict() for layer_id, layer in self.layers.items(): - # if "x5109" in layer.outputs or "x5110" in layer.outputs: - # print(layer.kernel) - # print(layer.inputs) - # print(layer.outputs) - # print(layer.attrs) for input_key, input_var in layer.inputs.items(): vs = input_var if not isinstance(vs, list): diff --git a/x2paddle/decoder/pytorch_decoder.py b/x2paddle/decoder/pytorch_decoder.py index 76a2238..9befec3 100644 --- a/x2paddle/decoder/pytorch_decoder.py +++ b/x2paddle/decoder/pytorch_decoder.py @@ -28,6 +28,7 @@ class PyTorchDecoder(object): torch._C._jit_pass_lint(graph) torch._C._jit_pass_dce(graph) torch._C._jit_pass_lint(graph) - graph = torch._C._jit_pass_canonicalize(graph) + torch._C._jit_pass_canonicalize(graph) torch._C._jit_pass_lint(graph) + torch._C._jit_pass_constant_propagation(graph) return graph diff --git a/x2paddle/op_mapper/pytorch2paddle/aten.py b/x2paddle/op_mapper/pytorch2paddle/aten.py index 26be7f2..f4c4a21 100644 --- a/x2paddle/op_mapper/pytorch2paddle/aten.py +++ b/x2paddle/op_mapper/pytorch2paddle/aten.py @@ -43,7 +43,7 @@ def aten_adaptive_avg_pool2d(mapper, graph, node): else: mapper._check_input(graph, inputs_node[1], inputs_name[1], current_outputs) - layer_attrs["pool_size"] = inputs_name[1] + layer_inputs["pool_size"] = inputs_name[1] current_inputs.append(inputs_name[1]) layer_attrs["pool_type"] = string("avg") @@ -93,7 +93,7 @@ def aten_addmm(mapper, graph, node): else: mapper._check_input(graph, inputs_node[3], inputs_name[3], current_outputs) - layer_attrs["beta"] = inputs_name[3] + layer_inputs["beta"] = inputs_name[3] current_inputs.append(inputs_name[3]) # 处理输入4,即%151 if inputs_name[4] in mapper.attrs: @@ -101,7 +101,7 @@ def aten_addmm(mapper, graph, node): else: mapper._check_input(graph, inputs_node[4], inputs_name[4], current_outputs) - layer_attrs["alpha"] = inputs_name[4] + layer_inputs["alpha"] = inputs_name[4] current_inputs.append(inputs_name[4]) graph.add_layer( @@ -175,7 +175,7 @@ def aten_add_(mapper, graph, node): else: mapper._check_input(graph, inputs_node[2], inputs_name[2], current_outputs) - layer_attrs["alpha"] = inputs_name[2] + layer_inputs["alpha"] = inputs_name[2] current_inputs.append(inputs_name[2]) graph.add_layer( @@ -203,8 +203,7 @@ def aten___and__(mapper, graph, node): mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs) layer_inputs["x"] = inputs_name[0] # 处理输入1,即%288 - mapper._check_input( - graph, inputs_node[1], inputs_name[1], current_outputs, add_dim=True) + 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()) @@ -395,7 +394,7 @@ def aten_cat(mapper, graph, node): else: mapper._check_input(graph, inputs_node[1], inputs_name[1], current_outputs) - layer_attrs["axis"] = inputs_name[1] + layer_inputs["axis"] = inputs_name[1] current_inputs.append(inputs_name[1]) graph.add_layer( "fluid.layers.concat", @@ -405,6 +404,82 @@ def aten_cat(mapper, graph, node): return current_inputs, current_outputs +def aten_chunk(mapper, graph, node): + """构造分割Tensor的PaddleLayer。 + + TorchScript示例: + %724 : Tensor[] = aten::chunk(%input.170, %720, %719) + 参数含义: + %724 (Tensor): 输出,分割后的结果。 + %input.170 (Tensor): 需要进行分割的Tensor。 + %720 (int): 分割的块数。 + %719 (int): 分割的维度。 + """ + 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,即%input.170 + 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,即%720 + if inputs_name[1] in mapper.attrs: + layer_attrs["num_or_sections"] = mapper.attrs[inputs_name[1]] + else: + mapper._check_input(graph, inputs_node[1], inputs_name[1], + current_outputs) + layer_inputs["num_or_sections"] = inputs_name[1] + current_inputs.append(inputs_name[1]) + # 处理输入2,即%719 + if inputs_name[2] in mapper.attrs: + layer_attrs["dim"] = mapper.attrs[inputs_name[2]] + else: + mapper._check_input(graph, inputs_node[2], inputs_name[2], + current_outputs) + layer_inputs["dim"] = inputs_name[2] + current_inputs.append(inputs_name[2]) + graph.add_layer( + "fluid.layers.split", + inputs=layer_inputs, + outputs=layer_outputs, + **layer_attrs) + return current_inputs, current_outputs + + +def aten_contiguous(mapper, graph, node): + """ 构造在内存中连续存储的PaddleLayer。 + + TorchScript示例: + %x.7 : Tensor = aten::contiguous(%4058, %4046) + 参数含义: + %x.7 (Tensor): 输出,在内存中连续存储的Tensor。 + %4058 (Tensor): 原始Tensor。 + %4046 (int): 存储的形式。 + + 【注意】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,即%4058 + 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 aten_conv2d(mapper, graph, node): """ 构造conv2d的PaddleLayer。 @@ -645,6 +720,35 @@ def aten_flatten(mapper, graph, node): return current_inputs, current_outputs +def aten_floordiv(mapper, graph, node): + """ 构造向上取整除法的PaddleLayer。 + + TorchScript示例: + %channels_per_group.2 : int = aten::floordiv(%num_channels.2, %3690) + 参数含义: + %channels_per_group.2 (-): 除后的结果。 + %%num_channels.2 (-): 被除数。 + %2 (int): 除数。 + """ + 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,即%124 + mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs) + layer_inputs["x"] = inputs_name[0] + # 处理输入1,即%123 + 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.floordiv", inputs=layer_inputs, outputs=layer_outputs) + return current_inputs, current_outputs + + def aten___getitem__(mapper, graph, node): """ 构造获取list中元素的PaddleLayer。 @@ -920,6 +1024,54 @@ def aten_matmul(mapper, graph, node): return current_inputs, current_outputs +def aten_mean(mapper, graph, node): + """ 构造求均值的PaddleLayer。 + + TorchScript示例: + %x.28 : Tensor = aten::mean(%result.1, %4967, %3, %2) + 参数含义: + %x.28 (Tensor): 输出,求均值后的结果。 + %result.1 (Tensor): 输入,需要求均值的Tensor。 + %4967 (int/list): 求平均值运算的维度。 + %3 (bool): 是否在输出Tensor中保留减小的维度。 + %2 (Tensor): 结果Tensor。 + """ + 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,即%result.1 + mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs) + layer_inputs["input"] = inputs_name[0] + current_inputs = list(layer_inputs.values()) + # 处理输入1,即%4967 + if inputs_name[1] in mapper.attrs: + layer_attrs["dim"] = mapper.attrs[inputs_name[1]] + else: + mapper._check_input(graph, inputs_node[1], inputs_name[1], + current_outputs) + layer_inputs["dim"] = inputs_name[1] + current_inputs.append(inputs_name[1]) + # 处理输入2,即%3 + if inputs_name[1] in mapper.attrs: + layer_attrs["keep_dim"] = mapper.attrs[inputs_name[2]] + else: + mapper._check_input(graph, inputs_node[2], inputs_name[2], + current_outputs) + layer_inputs["keep_dim"] = inputs_name[2] + current_inputs.append(inputs_name[2]) + + graph.add_layer( + "fluid.layers.reduce_mean", + inputs=layer_inputs, + outputs=layer_outputs, + **layer_attrs) + return current_inputs, current_outputs + + def aten_mul(mapper, graph, node): """ 构造数值相乘的PaddleLayer。 @@ -1136,14 +1288,22 @@ def aten_reshape(mapper, graph, node): # 处理输入0,即%4700 mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs) layer_inputs["x"] = inputs_name[0] - # 处理输入1,即%4703 - mapper._check_input(graph, inputs_node[1], inputs_name[1], current_outputs) - layer_inputs["shape"] = inputs_name[1] # 获取当前节点输入、输出的list current_inputs = list(layer_inputs.values()) + # 处理输入1,即%4703 + if inputs_name[1] in mapper.attrs: + layer_attrs["shape"] = mapper.attrs[inputs_name[1]] + else: + mapper._check_input(graph, inputs_node[1], inputs_name[1], + current_outputs) + layer_inputs["shape"] = inputs_name[1] + current_inputs.append(inputs_name[1]) graph.add_layer( - "fluid.layers.reshape", inputs=layer_inputs, outputs=layer_outputs) + "fluid.layers.reshape", + inputs=layer_inputs, + outputs=layer_outputs, + **layer_attrs) return current_inputs, current_outputs @@ -1305,6 +1465,72 @@ def aten_t(mapper, graph, node): return current_inputs, current_outputs +def aten_transpose(mapper, graph, node): + """ 构造矩阵转置的PaddleLayer。 + + TorchScript示例: + %715 : Tensor = aten::transpose(%x.21, %704, %705) + 参数含义: + %715 (Tensor): 输出,转置后的矩阵。 + %x.21 (Tensor): 需要转置的Tensor。 + %704 (int): 转置的维度1。 + %705 (int): 转置的维度2。 + """ + 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.21 + mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs) + layer_inputs["x"] = inputs_name[0] + # 处理输入1,即%704 + mapper._check_input(graph, inputs_node[1], inputs_name[1], current_outputs) + dim1 = inputs_name[1] + # 处理输入2,即%705 + mapper._check_input(graph, inputs_node[2], inputs_name[2], current_outputs) + dim2 = inputs_name[2] + # 获取当前节点输入的list + current_inputs = list(layer_inputs.values()) + graph.add_layer( + "prim.shape", + inputs={"input": inputs_name[0]}, + outputs=[output_name + "_shape"]) + current_outputs.append(output_name + "_shape") + graph.add_layer( + "prim.len", + inputs={"input": output_name + "_shape"}, + outputs=[output_name + "_len"]) + current_outputs.append(output_name + "_len") + current_inputs.append(output_name + "_shape") + graph.add_layer( + "prim.len2list", + inputs={"len": output_name + "_len"}, + outputs=[output_name + "_list"]) + current_outputs.append(output_name + "_list") + current_inputs.append(output_name + "_len") + graph.add_layer( + "prim.replaceitem", + inputs={"list": output_name + "_list", + "index": dim1, + "item": dim2}, + outputs=[]) + graph.add_layer( + "prim.replaceitem", + inputs={"list": output_name + "_list", + "index": dim2, + "item": dim1}, + outputs=[]) + graph.add_layer( + "fluid.layers.transpose", + inputs=layer_inputs, + outputs=layer_outputs, + perm=output_name + "_list") + return current_inputs, current_outputs + + def aten_unsqueeze(mapper, graph, node): """ 构造插入维度的PaddleLayer。 @@ -1333,7 +1559,7 @@ def aten_unsqueeze(mapper, graph, node): else: mapper._check_input(graph, inputs_node[1], inputs_name[1], current_outputs) - layer_attrs["axes"] = inputs_name[1] + layer_inputs["axes"] = inputs_name[1] current_inputs.append(inputs_name[1]) graph.add_layer( "fluid.layers.unsqueeze", @@ -1343,6 +1569,51 @@ def aten_unsqueeze(mapper, graph, node): return current_inputs, current_outputs +def aten_view(mapper, graph, node): + """ 构造调整大小的PaddleLayer。 + + TorchScript示例: + %input.152 : Tensor = aten::view(%x.20, %430) + 参数含义: + %input.152 (Tensor): 输出,view后的Tensor。 + %x.20 (Tensor): 需要view的Tensor。 + %430 (list): 形状大小组成的list。 + + 【注意】view 函数只能用于contiguous后的Tensor上, + 也就是只能用于内存中连续存储的Tensor。 + 如果对Tensor调用过transpose,permute等操作的话会使该Tensor在内存中变得不再连续, + 此时就不能再调用view函数。因此,需要先使用contiguous来返回一个contiguous copy。 + reshape则不需要依赖目标Tensor是否在内存中是连续的。 + """ + 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.20 + mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs) + layer_inputs["x"] = inputs_name[0] + # 获取当前节点输入、输出的list + current_inputs = list(layer_inputs.values()) + # 处理输入1,即%430 + if inputs_name[1] in mapper.attrs: + layer_attrs["shape"] = mapper.attrs[inputs_name[1]] + else: + mapper._check_input(graph, inputs_node[1], inputs_name[1], + current_outputs) + layer_inputs["shape"] = inputs_name[1] + current_inputs.append(inputs_name[1]) + + graph.add_layer( + "fluid.layers.reshape", + inputs=layer_inputs, + outputs=layer_outputs, + **layer_attrs) + return current_inputs, current_outputs + + def aten_warn(mapper, graph, node): """ 构造warning的PaddleLayer。 @@ -1370,7 +1641,7 @@ def aten_warn(mapper, graph, node): else: mapper._check_input(graph, inputs_node[1], inputs_name[1], current_outputs) - layer_attrs["stacklevel"] = inputs_name[1] + layer_inputs["stacklevel"] = inputs_name[1] current_inputs.append(inputs_name[1]) graph.add_layer( diff --git a/x2paddle/op_mapper/pytorch2paddle/prim.py b/x2paddle/op_mapper/pytorch2paddle/prim.py index 60dba68..6d1ef46 100644 --- a/x2paddle/op_mapper/pytorch2paddle/prim.py +++ b/x2paddle/op_mapper/pytorch2paddle/prim.py @@ -35,6 +35,34 @@ def prim_Constant(mapper, graph, node): return [], [output_name] +def prim_data(mapper, graph, node): + """ 构造Tensor的PaddleLayer。 + + TorchScript示例: + %4336 : Tensor = prim::data(%out.6) + 参数含义: + %4336 (Tensor): 输出Tensor。 + %out.6 (Tensor): 原始Tensor。 + + 【注意】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,即%4336 + 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_GetAttr(mapper, graph, node): """ 获取attribute信息。 @@ -66,6 +94,46 @@ def prim_GetAttr(mapper, graph, node): return [], [output_name] +def prim_If(mapper, graph, node): + """ 构造if控制流的PaddleLayer。 + + TorchScript示例: + %input.5 : Tensor = prim::If(%107) + block0(): + %109 : Tensor = aten::t(%102) + %ret.2 : Tensor = aten::addmm(%103, %101, %109, %104, %104) + -> (%ret.2) + block1(): + %111 : Tensor = aten::t(%102) + ... + -> (%output.4) + 参数含义: + %107 (bool): if判断条件。 + %input.5 (Tensor): if控制流的输出,与%output.4对应。 + """ + output_name = mapper._get_outputs_name(node)[0] + node_outputs = [output_name] + input_node = list(node.inputs())[0].node() + script_input_unique_id = list(node.inputs())[0].unique() + input_node_name = mapper.outputs_info[script_input_unique_id] + mapper._check_input(graph, input_node, input_node_name, node_outputs) + graph.add_layer("prim.if", {'input': input_node_name}, [output_name]) + current_layer = list(graph.layers.values())[-1] + block0 = list(node.blocks())[0] + block0_graph, graph_inputs0 = mapper.traverse(block0, current_layer) + len0 = 0 + for i, input_name in enumerate(graph_inputs0): + current_layer.inputs['input-{}'.format(i)] = input_name + len0 = i + current_layer.add_block(block0_graph) + block1 = list(node.blocks())[1] + block1_graph, graph_inputs1 = mapper.traverse(block1, current_layer) + for i, input_name in enumerate(graph_inputs1): + current_layer.inputs['input-{}'.format(len0 + 1 + i)] = input_name + current_layer.add_block(block1_graph) + return list(current_layer.inputs.values()), node_outputs + + def prim_ListConstruct(mapper, graph, node): """ 构造list的PaddleLayer。 @@ -92,28 +160,30 @@ def prim_ListConstruct(mapper, graph, node): return current_inputs, current_outputs -def prim_RaiseException(mapper, graph, node): - """ 构造抛出异常的PaddleLayer。 +def prim_ListUnpack(mapper, graph, node): + """ 构造获取list中元素的PaddleLayer。 TorchScript示例: - = prim::RaiseException(%76) + %x1.4 : Tensor, %x2.4 : Tensor = prim::ListUnpack(%4354) 参数含义: - %76 (str): 异常信息。 + %x1.4 (Tensor): 输出,list的第一个元素。 + %x2.4 (Tensor): 输出,list的第二个元素。 + %4354 (list): 列表。 """ - output_name = mapper._get_outputs_name(node)[0] - layer_outputs = [output_name] + outputs_name = mapper._get_outputs_name(node) + layer_outputs = outputs_name.copy() layer_inputs = {} inputs_name, inputs_node = mapper._get_inputs_name(node) # 获取当前节点输出的list - current_outputs = [output_name] - # 处理输入0,即%76 + current_outputs = layer_outputs.copy() + # 处理输入0,即%4354 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.exception", inputs=layer_inputs, outputs=layer_outputs) + "prim.list_unpack", inputs=layer_inputs, outputs=layer_outputs) return current_inputs, current_outputs @@ -180,46 +250,6 @@ def prim_Loop(mapper, graph, node): return list(current_layer.inputs.values()), node_outputs -def prim_If(mapper, graph, node): - """ 构造if控制流的PaddleLayer。 - - TorchScript示例: - %input.5 : Tensor = prim::If(%107) - block0(): - %109 : Tensor = aten::t(%102) - %ret.2 : Tensor = aten::addmm(%103, %101, %109, %104, %104) - -> (%ret.2) - block1(): - %111 : Tensor = aten::t(%102) - ... - -> (%output.4) - 参数含义: - %107 (bool): if判断条件。 - %input.5 (Tensor): if控制流的输出,与%output.4对应。 - """ - output_name = mapper._get_outputs_name(node)[0] - node_outputs = [output_name] - input_node = list(node.inputs())[0].node() - script_input_unique_id = list(node.inputs())[0].unique() - input_node_name = mapper.outputs_info[script_input_unique_id] - mapper._check_input(graph, input_node, input_node_name, node_outputs) - graph.add_layer("prim.if", {'input': input_node_name}, [output_name]) - current_layer = list(graph.layers.values())[-1] - block0 = list(node.blocks())[0] - block0_graph, graph_inputs0 = mapper.traverse(block0, current_layer) - len0 = 0 - for i, input_name in enumerate(graph_inputs0): - current_layer.inputs['input-{}'.format(i)] = input_name - len0 = i - current_layer.add_block(block0_graph) - block1 = list(node.blocks())[1] - block1_graph, graph_inputs1 = mapper.traverse(block1, current_layer) - for i, input_name in enumerate(graph_inputs1): - current_layer.inputs['input-{}'.format(len0 + 1 + i)] = input_name - current_layer.add_block(block1_graph) - return list(current_layer.inputs.values()), node_outputs - - def prim_min(mapper, graph, node): """ 构造min的PaddleLayer。 @@ -245,6 +275,31 @@ def prim_min(mapper, graph, node): return current_inputs, current_outputs +def prim_RaiseException(mapper, graph, node): + """ 构造抛出异常的PaddleLayer。 + + TorchScript示例: + = prim::RaiseException(%76) + 参数含义: + %76 (str): 异常信息。 + """ + 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,即%76 + 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.exception", inputs=layer_inputs, outputs=layer_outputs) + return current_inputs, current_outputs + + def prim_requires_grad(mapper, graph, node): """ 构造是否计算梯度的PaddleLayer。 diff --git a/x2paddle/op_mapper/pytorch2paddle/prim2code.py b/x2paddle/op_mapper/pytorch2paddle/prim2code.py index d30c3ee..f178fa0 100644 --- a/x2paddle/op_mapper/pytorch2paddle/prim2code.py +++ b/x2paddle/op_mapper/pytorch2paddle/prim2code.py @@ -100,6 +100,12 @@ def prim_exception(layer, indent=1, init_func=[], forward_func=[]): forward_func.extend(gen_codes([line], indent=indent)) +def prim_floordiv(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=[]): line = "if {} :".format(get_value(layer, "input")) forward_func.extend(gen_codes([line], indent=indent)) @@ -141,6 +147,14 @@ def prim_len(layer, indent=1, init_func=[], forward_func=[]): forward_func.extend(gen_codes([line], indent=indent)) +def prim_len2list(layer, indent=1, init_func=[], forward_func=[]): + lines = [] + lines.append("{} = []".format(layer.outputs[0])) + lines.append("for i in range({}):".format(get_value(layer, "len"))) + lines.append(" {}.append(i)".format(layer.outputs[0])) + forward_func.extend(gen_codes(lines, indent=indent)) + + def prim_lt(layer, indent=1, init_func=[], forward_func=[]): line = "{} = {} < {}".format(layer.outputs[0], get_value(layer, "x"), get_value(layer, "y")) @@ -157,6 +171,11 @@ def prim_list(layer, indent=1, init_func=[], forward_func=[]): forward_func.extend(gen_codes([line], indent=indent)) +def prim_list_unpack(layer, indent=1, init_func=[], forward_func=[]): + line = "{} = {}".format(", ".join(layer.outputs), get_value(layer, "input")) + forward_func.extend(gen_codes([line], indent=indent)) + + def prim_loop(layer, indent=1, init_func=[], forward_func=[]): loop_range = get_value(layer, "input") line = "for {} in range({}):".format(layer.outputs[1], loop_range) @@ -194,6 +213,13 @@ def prim_not(layer, indent=1, init_func=[], forward_func=[]): forward_func.extend(gen_codes([line], indent=indent)) +def prim_replaceitem(layer, indent=1, init_func=[], forward_func=[]): + line = "{}[{}] = {}".format( + get_value(layer, "list"), + get_value(layer, "index"), get_value(layer, "item")) + forward_func.extend(gen_codes([line], indent=indent)) + + def prim_requires_grad(layer, indent=1, init_func=[], forward_func=[]): line = "{} = not {}.stop_gradient".format(layer.outputs[0], get_value(layer, "input")) diff --git a/x2paddle/optimizer/fusion/__init__.py b/x2paddle/optimizer/fusion/__init__.py index 543afeb..13ef304 100644 --- a/x2paddle/optimizer/fusion/__init__.py +++ b/x2paddle/optimizer/fusion/__init__.py @@ -14,10 +14,8 @@ from .fc_fuser import FcFuser from .fc_fuse_pass import FcFusePass -from .nn_adaptive_pool2d_fuser import NnAdaptivePool2dFuser -from .nn_adaptive_pool2d_fuse_pass import NnAdaptivePool2dFusePass -from .functional_adaptive_pool2d_fuser import FunctionalAdaptivePool2dFuser -from .functional_adaptive_pool2d_fuse_pass import FunctionalAdaptivePool2dFusePass +from .adaptive_pool2d_fuser import AdaptivePool2dFuser +from .adaptive_pool2d_fuse_pass import AdaptivePool2dFusePass from .constant_fuser import ConstantFuser from .constant_fuse_pass import ConstantFusePass from .batchnorm2d_fuser import BatchNorm2dFuser diff --git a/x2paddle/optimizer/fusion/__pycache__/__init__.cpython-37.pyc b/x2paddle/optimizer/fusion/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4df0dc093c7c17e4a2dc9a5736138bb789f5a271 GIT binary patch literal 615 zcmZutyH3L}6m^=Wd9-N@RgsvOyO0tV285tUWveQ&ATO4QQ;1|cQJhwkui!WMr4B4i z`~nlUXjuw3XoK0% z*4U;^=0Hc|CT%enx*9vwV?OjXZqb0XVOwLDc322QjXm0BJ=l}jzXhYELhL2*T@}iwg5fCRq{B?OZMGz z@GGaNvr!* zBx|;-*n9WNH`l(6z*BYx15cS9IW{DC&0-;tQwb#95OSo`As1%7_P!x#+XfKu(JL$rH)!tMj3a9kS ze}E%@$yZMN1y0O(8-zsa)r`j;@4R`>J{u1E1V(avF5U)&{KUm>gbVm1X7Ul=9 zlx*7kN>A&$7^^o+s|{=q8%PVI7rAYDSl0|po7oC z4$wXN9|5u5p}avBjfWOpV0Nueww3QV>5pajv^tr=8hCrXvvm*VH@_5Zm6P)ePwv1 zK#xyc(AG^2ocg6~XBXmAUMZlAC0ws=w2`e&xQTHcE{tq0T!=CnPrh^bxLhckrdU0O z&>}XW5nVsIrDK0|l0+zKB}*-Y>kCoVYFS`B5aMzvizy*+=ghkMf9?Q|j>?aBM!OIgVU=zwfJm_hJ;?Ya0x S$L-}k>=8R2Q26+O#)Cg(+~*Jg literal 0 HcmV?d00001 diff --git a/x2paddle/optimizer/fusion/__pycache__/adaptive_pool2d_fuser.cpython-37.pyc b/x2paddle/optimizer/fusion/__pycache__/adaptive_pool2d_fuser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b586006ee41096590420ad2d5164e2b2e89076ae GIT binary patch literal 4305 zcmai1-EZ6073a4o*-q1ZC(BYb%a*81WLt_YIkStkU6&2(f@0~zpkN>vUD}~bQQRe! z$(oF{v4H{`+&px^fHf$bZ5Xzfp?h72_W$5(o22{~`mpYIE-5*by+r~K?>%4l+}}O- z-osaCW=ax%M)|t+)6Ef9>)a0Rj5=@F z8xDt_{8F1tMn5%cgjdmUL?|ugJ!w^DGE=tAmdaG7ZA&dJ9lWKp0yEJ!-jg(`RX_;E z_~oExx?P0Mn9H?k~fX`$n-;$5_?wr7W-W&K_H>gH_6k7mQ3zhV2U zw!bzvKl}4q3dme@u70;R+ph%zpV=;=?zjVo&#v}Dx9iW^*+i^B%)|oQ;niS+(|S_y zp#mbwgR=)rxjKq$Ja-ei1w60e3AcfO09D$={MV&*nW?Tcl$o|AugQQ{UsIT|qsdYx z1<0g@v^Qp!n=GBX`t#Gwm~{c#)< z{OO$Kao9m06jFBLfr8e_y#21sP6_|u3;(A{{%|x)B~ry~m0j(j1RrNkOQ)qxCDMlq z`vyC^qim`}6)1jF_`ri~hX2`xE)})+| zbi7tC3jX=rOuv;P1PUoA5C#RB?7{;Lt#AJiU*8e@JZdT4un=>(xXOs#|Db=OkRjiqgH8W^+*g|BoMT&T{kge1*E2f@VQ;fTm`b4|% z2j%_IiWb>9+C}V|IBC9zlV+tyhf(?Q{rg{j_HpvyoiG3T?&A+Xd%W|fCx6@?9RTI@ z0C@D_r%yil;PFS>pTBdjRL*{rI{&=)_-_v%{ri5f5#8zfkN)w|llMRV;*&o=*?srP zU;g#Qr@y;4wj>ArMyRu>)s9wgB11*ZXY;M^@LrI3Znx zbg5RW*BiCD`eJk8YNN5xoNG*IHJ~*=!E1u&IsT=7qh6U1EkRVv^O|$u^&8FdGQE~^ zLU*;?hde)9nlZQC&?*0n=y(DcZ((A*CQbj=1SZX^U|yMwg1|t)xBAVi*U(rb(wMX) zOePHp0WsU=zR?K?IK;a2oBMnb6de~RHJkaUSG&Ay^_S+$u8(>8YYtSFD*G|$FVU)F z?QfBGK2(tv&3e@i0>@{Upqd|}zeLEadOep_J-Wri>L>-Xd+L(w2fb(oxpP@0t`*`^ zTj@9JS(mQSm5cV>wTpY6$CuRTg1$+Y)HDc_BOHcX@=3aul^e0##}%uF5mgV0%lHg* zQgR5b*j#gb%eOmDog8HMWBrx=B|-Ie&-IuU*iqzgzq;&o+qM_JTpigDW&-YZs_m{H zMz$Yu3M`>J9~FQhW*EkWZZE=A!&tv-dp&1R5+-89#JbQKOw-oABHCBx5^_>e_%Xcr zadJojzLiil5*Nqmm{3*b=^$VKCjA$rgt`M$41kU{sZ&T%sjX4R5X4Pe3U_v&7)XF zmZ0>BoFJj)N@zV2T8fI&N^zRY@S0C3$ZQVC-{dfLvoX8fAbFllj}UWO1hVEtZsc@O zLTVmjB1oCjPmYqtl+Z|%G$A}kv#7;If?O19v5GAF>g@kZRzN3alNwQ`CbTesikza9 z!^!cO@ZMELg(jmu(}$>e z*0rII+gsg5y&!Jy^e7Qqx?;qoz~(qGa14a;jM)CpuTq@F!txai#Fs&0HRuKvL#$q` zi*Ew{1L7AtcGSM(gmKXyna0!OrnUc+I_&x=B`89Zypj?d3ZVQ-0IJ>39fVXQH?9dSyS%2c}LXtnr{K;mM$b+I5B>FF*yX>f0l`HzX@Zyo+Rc=zyx7eFMD+v!fB-9r1t#Gm$xmbDMg z`dso=O!~T{tIV?El4W(etmjdC+OmGxv%ORzz6CigI{yg~iX@)NzChcK=ULWXusF@= zjOKJai|O#5`upd?PwpkEdd_?PhuM=#a_G uc9%QVfOoM)I_Zf>ix3~lEA%4Q6XWd#n6}c3d^w%)%XDdsV#LNU)&Bx9$}s-` literal 0 HcmV?d00001 diff --git a/x2paddle/optimizer/fusion/__pycache__/batchnorm2d_fuse_pass.cpython-37.pyc b/x2paddle/optimizer/fusion/__pycache__/batchnorm2d_fuse_pass.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ecb0ce0f73ed60571192436f4e4980a674ca6db GIT binary patch literal 905 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 IHl)$uFSumdK>z>% literal 0 HcmV?d00001 diff --git a/x2paddle/optimizer/fusion/__pycache__/constant_fuser.cpython-37.pyc b/x2paddle/optimizer/fusion/__pycache__/constant_fuser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3085d8580717b3faa728d822f9e931a74315f7d GIT binary patch literal 2136 zcmaJ?&5smC6tC*9=^18lK|m2hMxzNs%*-zM6@zGihzGJEYOq^u6kt*^CFPQ`N6N-mCZVd#}#a zY83+QFYyjbfqICOQ8R#e7kYw&M?4x3hr(YAw65;x6xZ~?=$ek%wH!;$jiB@qIZr&( zv(|}caeYm9Y>$3O8l@eOLS`FO+V5ovKjS96p~*cLUC#^ndEv&3qsaxg&jp;L$J@v< zYWk2!UIBtDRUGXanWrB0v~}CjJ>4_biDML(JLWZF5XZu+W$kPfCaD{yc(rKLp(y;L zSnSCm7*dkboUCa}8VbEm(Iya}&&rb5UqB^6uZkjA+K+idmu8a1TnG!erOlWh`YB^@ z%1C%H5C1Y_?Z8bE#(p7xUubp1w3TFG-wo&8aAA6;_3??q1=DX%pS*mc)jJU@kF=sV z^}GIni`IOW_)*wu4^3b&=b{<+1%~b*s;XVekPjkAJ@r_tV8FeEjR}?XT}Vy7$BO#+B_Ke|vQQ ztGC81$k{ttf4e?2J+U?)i8|}OFeTmYQ32q z^cV!s^20bw6IqI~R1xN7H^}&G!;q!eO;avHS%!G905K`eOPL>dVm~rdu?K#lHXil@ zC2Q&g8}dF2ONk8wDOq%iR_Nf!WQZnCw=vVg zLGp5L<)t-9@a50uiUcrc+o%jSGzUTSH1y<87<#WGL{KFVb?g&uMPD&;Bc~lrRMn1_ z>zfo{rNK|LA=Hvb{_ngv@h6+;?JPzD8 zXNsjjB!W@A3{_4)25MN}EI_i#P)NvRpU;Qccv6=_oQ)R2oTB)l^xDT>(CT zyn~!ne&FD|!dJd0O+`8TiiIL)hfXV&)SXUs#K7>b7w|4jQ%G6#hERz*^4@<5jQfx2&3y8F5I)j0&%6t%T~0lyeX A(f|Me literal 0 HcmV?d00001 diff --git a/x2paddle/optimizer/fusion/__pycache__/fc_fuse_pass.cpython-37.pyc b/x2paddle/optimizer/fusion/__pycache__/fc_fuse_pass.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bcf71b57bbb851e2f9d1379ee33fd0cd2bf4f25 GIT binary patch literal 851 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 INC~#_FD*AylK=n! literal 0 HcmV?d00001 diff --git a/x2paddle/optimizer/fusion/__pycache__/functional_adaptive_pool2d_fuse_pass.cpython-37.pyc b/x2paddle/optimizer/fusion/__pycache__/functional_adaptive_pool2d_fuse_pass.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8d6069ec998da8a7ee4146f964783cb40e87f3e GIT binary patch literal 987 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 literal 0 HcmV?d00001 diff --git a/x2paddle/optimizer/fusion/__pycache__/nn_adaptive_pool2d_fuse_pass.cpython-37.pyc b/x2paddle/optimizer/fusion/__pycache__/nn_adaptive_pool2d_fuse_pass.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9807e24311c0fb00d850aba05b240a8f5416d97 GIT binary patch literal 939 zcmaJS0&3K&g&UoF<$q!kMBxP)r3Egohmg z9(9oI=nw|txA%+@@)BOu9$zegfI#p$h4Q#?55Qi7x$EE>@{MlEci#pOMW-pVNUBYQ z$W7h|feM{27C(r+28rK1D@~KRm03%(kY;&woV}mSq*8@GdUo{We3E^h)c%-N(2O$Q zXqy3(yfWGUIF9SJ?E%0D%pnCrH;=B8JKnRK`3m- X(QA|EowgS@kRvi4Q1}G{nhgE`gWv3! literal 0 HcmV?d00001 diff --git a/x2paddle/optimizer/fusion/__pycache__/nn_adaptive_pool2d_fuser.cpython-37.pyc b/x2paddle/optimizer/fusion/__pycache__/nn_adaptive_pool2d_fuser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03f0a9f14eef754324b9fbbc0d5e08b6ad8a125c GIT binary patch literal 4320 zcma)9+i%;}8RuP;Y^SN4`_fcPyE^I;*_JPoGrQQ@b=k1O=+_bg%2s{vUj8W0(IzAJ+Z8LrMwdbR7wPJm|K*IV(w@Qf2sPD0~-RNQ6mD_N1nazv3xvwW-R)Q$4M%H}$sBG(=tV z3U5f)B&IWCPhy6n?y60b$*)V5LIN++dPR=SA9O?KB|CH~N<8tJ&6ww0<92X!Sb5dn zb~yCp7g}U8eAKKEE~4OwP@2j+(uT}rrtFzbm8neIlbTxEcvEKuW}sPNQ&fvw5x0>)W{u~`UpqrdR$=Jn-nzS zEQx{@Z3j+8jrFh_IGh`>j!nyQeK)c!XlbG2ZQx(Dtd?hop=JGD`r>D^Z9kd~yZ*NA zZ`l6k-2Cj%Ybhjijk$$ewb@=R5D3k75Ov$_JA8Jd8@e5T*7q$t>x&hL&RCE*yc%qC z8dQouR6r!Tf8nwHt`5T+0boMAfbV5|;T~WR*h)J9VN2SQnd(XdnQ6Q7rVNzzO@$eE zG+D}|z?&6a85$*_F>wb;lCzu?{HdH(>hqY8Jnz`e12{G6Q#@Y#Hprsx(mc3j_5&lI{@?n&4{0&5(UY zj7d2k>1eFJDfkz2J$*Js2ozFKAPfpL*>m?al)m*9zMdESJZdT4un>KjIb!(?{J{aa`uet{PXs~-|j#7_uXJSy4mp`{NsbecR&2>qdy<+ zzkT?Ze|`4x@2-w4$w9APE3cKWFJCS%|6)wA070)lUkz{Cfiossf^6oMUdzF{)$wP> zq|1=5)M^V0_1fIRa${++USDd=)yK5z(3&6PHNf*6|5C5MP#F`gKvc`~8gtW%U$ z{Z?{9cca{cJl|XDF}K~&DgTt{r~_zkX{@~lb^rPpCXGcfuZ%}QU?AY@y~g5I6qbq9 z$1MqyaYI5t^tN%NbpiqoF)qEv5nlvF+XYIEMn39|4li51mHD#kqo4k!1C^D^Q4D%3 zH0l`p>!h6zRb)kDp=t+#qkJo9vrFMpH11u3Cw-xLiXYZBVZ`-Q9umrtM`%i9TU^BLdW zNQ$T>U*h4UUy->G9}{NIa02%WS$O?o>dy_MgpL`>1d;#1eAqM3Z8;T^5k)~-vcn*6}i;D!gIJ3nn^6ZQA|0`Vqo#;(!M7f&KzyK<8 ziZd;*Q?(QqvP_AKIJ8+J_hTcS0(>4SvG%639da5l zu$+3@G~JEN*|DqvOW4fC`TBgb2pw>g#5ZI(ojk;yz9pAl2JG{-$a3V#bCoikNK zJ|i3QDSRi!zH?cI9lW|7V z2RQd^X#*WQxVn!sgV@2-Frn`64^hIS@(YcRE{W#?YKG@zQ+J zvhr7Del7tkCS5gYOS7!FWLfPF>v~k4w5(rtZ7-FGTOp@m=RYPwvBXo^b+qMpo@G4@ z7i$`=)SMP+ahatBFQlCTvr;v0m<7Sbom%(1?O;1r{2;zKyscJ8x7F%!5lVBPbK1