---
title: 融合条件判断
description: "判断两个节点是否能融合，需要综合CanFuse框架和Backend的判断结果，两个结果都必须能融合才能融合，本章节分别给出两者的判断条件。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/programug/graphdevg/autofuse_1_0019.html
sourcePath: /source/zh/canncommercial/900/programug/graphdevg/autofuse_1_0019.html
indexId: 3e5dc8fc64f304d5a31cbb165aaaf8a8a77e56d1955fd1dd27d033e0c095b8ce70
---
# 融合条件判断

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

#### CanFuse框架判断融合条件

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

  图1 CanFuse判断融合条件1

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

  图2 CanFuse判断融合条件2

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

  图3 CanFuse判断融合条件3

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

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

  图4 CanFuse判断融合条件4


#### Backend判断融合条件

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

  图5 Backend判断融合条件

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


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