昇腾社区首页
中文
注册
开发者
下载

融合条件判断

判断两个节点是否能融合,需要综合CanFuse框架和Backend的判断结果,两个结果都能融合才能融合,本章节分别给出两者的判断条件。

CanFuse框架判断融合条件

  • 能够减少内存读写

    可融合的节点间必须有共用的内存,比如下图所示,Node1的输出1是Node3的输入可以融合,Node3和Node4输入都来自Node1的输出1可以融合,融合后都可以节省内存搬运。Node2和Node3虽然输入都来自Node1,但不是Node1的同一个输出,融合后还是要搬入两次,不能减少内存搬运,因此不能融合。

  • 不会导致成环

    如下图所示:Node1和Node3融合后会导致成环,因此不能融合。

  • 不超过最大融合个数限制(默认最大融合个数为64)

    融合规模控制主要是防止后端资源超限,节点数按照Lowering生成的AscGraph里的节点数进行控制,比如下图中的Node1和Node2融合后认为节点总数是9,可以融合;如果两个节点融合后总数超出阈值就不能融合。

  • 不会导致内存峰值增加

    过度的融合可能会导致内存峰值的增加,需要在执行性能和内存之间进行平衡,完备的内存峰值评估是一个比较复杂的过程,先按照简单策略进行评估,对于节点跨度(拓扑排序的ID差值)超过设定阈值的不再进行融合,当节点可以水平融合的时候,会先计算融合后节点的输出内存是否超过13G,如果超过13G则不融合。

    比如下图所示:Node2-NodeN之间在融合前是有机会进行内存复用的,融合后会导致内存峰值增加,因此不能融合。

Backend判断融合条件

  • 两个AscGraph的loop轴要能映射

    能够融合的第一个条件是两个AscBackend的loop轴是否可以映射,如果不是一套loop轴,则判断融合是没有意义的。由于每个AscBackend是独立进行Lowering的,各自的循环轴ID也是独立编号,因此可能会存在轴ID不一致的问题,典型场景如下图所示:AscBackend1做了reduce后少了一个循环轴,AscBackend2中z1等同AscBackend1中的z2,AscBackend2中z2等同AscBackend1中的z3,如果要融合,则需要把AscBackend2中的loop轴刷成跟AscBackend1相同。

  • 两个AscGraph要能满足Schedule的group merge规则
    假设对轴做一个抽象分组,分为三个group:xgroup、ygroup、rgroup,其中:
    • xgroup: 为Concat view类算子引入的一个单独group,Concat轴之前的轴是xgroup,之后的是ygroup。
    • ygroup:Elementwise、Broadcast类型的算子循环轴。
    • rgroup:Reduce轴的集合。

    每个AscGraph都会有一个基于循环轴的(xgroup, ygroup, rgroup),根据算子融合规则推导,可以判断两个AscGraph是否能融合成一个新的group;然后CanFuse依据此规则,判断后端Schedule是否支持融合。详细group merge规则请参见生成TilingCase