Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cherry-pick]Verify the correctness of graph rewrited by GeneratePass #36453

Merged

Conversation

Avin0323
Copy link
Contributor

PR types

Others

PR changes

Others

Describe

(cherry picked from PR #36116)

验证GeneratePass在计算子图替换后计算结果正确性,并对相关问题进行修复。

验证场景

  • 1. 完整的Python注册Pass到完成获取Pass实例对Graph进行子图替换;
  • 2. 简单的fusion场景:
    • 2.1 Paddle Python API开发时无需指定:input_specs、算子属性;
    • 2.2 辅助类型开发时无需指定:匹配/替换子图中的属性限制;
    • 2.3 替换子图可以为仅有输入输出情况,意味着该Pass将删除匹配子图;
    • 2.4 匹配图与替换图可任意使用一种方式开发;
  • 3. 较为复杂的fusion场景:
    • 3.1 Paddle Python API开发时指定且参与匹配替换限制:input_specs、算子属性;
    • 3.2 辅助类型开发时指定:匹配子图中属性限制、替换子图算子在匹配子图中的属性映射;
    • 3.3 匹配/替换子图中存在需要推导的算子属性,如concat、slice等;

本PR中验证其中1、2、3.1场景,对于3.2、3.3于后续PR支持及验证

PR涉及功能验证及问题修复

1. 完整的Python注册Pass到完成获取Pass实例对Graph进行子图替换

功能验证点RegisterPass注册的Pass,通过core.get_pass可以获取到实例且能对Graph进行操作。

存在问题及解决方案

  • 问题:获取Pass实例存在异常,无法正确在C++中调用Python侧函数;
  • 解决方案:RegisterPassHelper类成员中保存每个实例,用以确保Python侧对象的生命周期。

2. 简单的fusion场景

2.1 Paddle Python API开发时无需指定:input_specs、算子属性

以融合两个add算子为例,简单的示意图如下:

image

使用Paddle API创建该Pass代码如下:

@ir.RegisterPass
def multi_add_to_sum():
    pattern = lambda x, y, z: paddle.add(paddle.add(x, y), z)
    replace = lambda x, y, z: paddle.add_n([x, y, z])
    return pattern, replace

为验证该Pass可以正确替换子图并得到相同的计算结果,使用如下图中的计算图来验证:

image

对于上面的计算图验证点如下:

  • 仅匹配到一个子图;
  • 替换子图之后,计算图中的节点数目减少2;
  • 替换前后计算结果相同;

2.2 辅助类型开发时无需指定:匹配/替换子图中的属性限制

仍使用2.1中示例的Pass及测试方式,不同的是使用辅助类型注册Pass,代码如下:

@ir.RegisterPass
def multi_add_to_sum():
    def pattern(x, y, z):
        ewadd1 = ir.PassDesc.OP.elementwise_add(X=x, Y=y)
        ewadd2 = ir.PassDesc.OP.elementwise_add(X=ewadd1, Y=z)
        return ewadd2
    replace = lambda x, y, z: ir.PassDesc.OP.sum(X=[x, y, z])
    return pattern, replace

2.3 替换子图可以为仅有输入输出情况,意味着该Pass将删除匹配子图

以删除连续两个transpose算子为例,简单的示意图如下:

image

使用辅助类型注册该Pass代码如下:

@ir.RegisterPass
def simplify_inference():
    def pattern(x):
        transpose = ir.PassDesc.OP.transpose2(X=x)
        return ir.PassDesc.OP.transpose2(X=transpose)
    replace = lambda x: x
    return pattern, replace

为验证该Pass可以正确替换子图并得到相同的计算结果,使用如下图中的计算图来验证:

image

对于上面的计算图验证点如下:

  • 仅匹配到一个子图;
  • 替换子图之后,计算图中的节点数目减少6;
  • 替换前后计算结果相同;

2.4 匹配图与替换图可任意使用一种方式开发

仍使用2.1中示例的Pass及测试方式,不同的是使用辅助类型注册Pass,代码如下:

@ir.RegitserPass
def multi_add_to_sum():
    pattern = lambda x, y, z: paddle.add(paddle.add(x, y), z)
    replace = lambda x, y, z: ir.PassDesc.OP.sum(X=[x, y, z])
    return pattern, replace

3.1 Paddle Python API开发时指定且参与匹配替换限制:input_specs、算子属性

3.1.1 示例1:融合多个matmul算子

该示例Pass的简单示意图如下:

image

@ir.RegisterPass(input_specs={
    'x': InputSpec([16, 32]),
    'y1': InputSpec([32, 12]),
    'y2': InputSpec([32, 48])
})
def combine_multi_matmul():
    def pattern(x, y1, y2):
        mul1 = paddle.matmul(x, y1)
        mul2 = paddle.matmul(x, y2)
        return mul1, mul2
    def replace(x, y1, y2):
        concat_out = paddle.concat([y1, y2], axis=-1)
        mul_out = paddle.matmul(x, concat_out)
        out1 = paddle.slice(mul_out, axes=[1], starts=[0], ends=[12])
        out2 = paddle.slice(mul_out, axes=[1], starts=[12], ends=[60])
        return out1, out2
    return pattern, replace

3.1.2 示例2:融合连续的transpose算子

与2.3中示例类似,改用Paddle Python API定义子图,并且指定输入的shape及transpose算子的参数设置。

@ir.RegisterPass(input_specs={'x': InputSpec([10, 16, 16])})
def generate_simplify_inference_v1():
    def pattern(x):
        transpose = paddle.transpose(x, [0, 2, 1])
        return paddle.transpose(transpose, [0, 2, 1])
    return pattern, lambda x: x

@paddle-bot-old
Copy link

Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

Copy link
Member

@zhhsplendid zhhsplendid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lanxianghit lanxianghit merged commit cc44965 into PaddlePaddle:release/2.2 Oct 15, 2021
@Avin0323 Avin0323 deleted the cherry-pick-check-generate-pass branch October 16, 2021 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants