---
title: Lowering流程示例
description: "本章节以一个简单的Conv+Abs+Exp+Conv的GE IR Graph为例（Conv无Lowering实现），简单介绍Lowering的流程。原始GE IR图如下："
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/programug/graphdevg/autofuse_1_0015.html
sourcePath: /source/zh/canncommercial/900/programug/graphdevg/autofuse_1_0015.html
indexId: 8eb73656b2021c8fdd35d467986165550eea09facf807d155cdecfd23c0cced370
---
# Lowering流程示例

本章节以一个简单的Conv+Abs+Exp+Conv的GE IR Graph为例（Conv无Lowering实现），简单介绍Lowering的流程。原始GE IR图如下：

图1 原始GE IR图

1. 首先会进行Conv的Lowering，由于Conv无注册的Lowering实现，会执行默认的Lowering：所有输出Anchor的KernelBox均为ExternKernel类型，表示执行原始的GE IR Kernel。
  图2 输入Conv的Lowering

2. 然后，Lowering Abs时加载输入数据，伪码如下：
  1 2 3 4 5 6 graphStatus LoweringAbs(const ge::Node &node) { auto x = loop::Load(node.GetInDataAnchor(0)); // 从输入anchor0中加载数据 ... auto result = loop::Abs(x); ... }

  当执行loop::Load(node.GetInDataAnchor(0))时，实际会调用对端输出Anchor关联的KernelBox的Load方法，此时为Conv节点输出，由于Conv的KernelBox为Extern类型，对其Load时，等同于对Conv节点的输出Anchor进行Load，因此Abs节点在Lowering后，其输出Anchor关联的KernelBox如下：

  图3 Abs的Lowering


3. 接着进行Exp节点的Lowering，伪码如下：
  1 2 3 4 5 6 graphStatus LoweringExp(const ge::Node &node) { auto x = loop::Load(node.GetInDataAnchor(0)); // 从输入anchor0中加载数据 ... auto result = loop::Exp(x); ... }

  对其输入Load时，实际执行的是Abs输出Anchor关联的KernelBox的Load，其没有被Realize也非Extern（IsRealize为true，表示可融合；IsExternKernel为true，表示走原始GE IR流程）可继续进行融合，因此会返回其内部的计算过程（load->Abs->Store）。在Exp Lowering后，其输出Anchor关联的KernelBox如下：

  图4 Exp的Lowering


4. 最后，进行Conv节点的Lowering，执行默认的Lowering函数，会将所有的输入Anchor对端的KernelBox进行Realize（因为Conv要回退至原始GE IR Kernel执行，需要有输入）。
  图5 输出Conv的Lowering


完成Graph Lowering后，可以看出，需要Realize的KernelBox是Exp节点输出的KernelBox。此时，会将Exp节点输出Anchor关联的KernelBox转换为AscGraph，并将Exp节点替换为AscBackend类型。需要注意的是，Exp节点关联的KernelBox的输入为Conv:0而非Abs节点，因此在替换后，Abs节点会因输出未被任何节点使用而被删除。然而，为了确保在任意时刻都能方便地回滚到原始节点，无用节点的删除并不会立即执行。
