---
title: 使用改图接口修改Graph
description: "如果用户想要直接优化图的结构，比如将某些特定子图替换成一个融合算子，以减少计算步骤、外存访问、调度时间等，或者在某些算子之间添加一个算子，此时可以通过本节内容将图直接修改成期望的结构。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/programug/graphdevg/atlasag_25_0026.html
sourcePath: /source/zh/canncommercial/900/programug/graphdevg/atlasag_25_0026.html
indexId: 9656a6e7513d859b29e0c39eb63c7a53bbaf7e0e602356f86f6bc777ba40376170
---
# 使用改图接口修改Graph

如果用户想要直接优化图的结构，比如将某些特定子图替换成一个融合算子，以减少计算步骤、外存访问、调度时间等，或者在某些算子之间添加一个算子，此时可以通过本节内容将图直接修改成期望的结构。

#### 功能介绍

本节以在算子A和算子B之间添加算子C为例，说明如何修改Graph，涉及的主要接口如下：


本手册除了通过改图接口修改Graph，还提供了将改图函数封装为自定义Pass来修改Graph的方式，详细介绍请参见基于改图接口实现Pass。


#### 开发示例

1. 包含的头文件。
  1 2 3 4 #include "graph.h" #include "ascend_string.h" #include "ge_ir_build.h" #include "gnode.h"

2. （可选步骤）修改图之前，可以先调用  aclgrphDumpGraph(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0134.html)
把Graph dump到本地，查看Graph信息。
  需要注意的是，aclgrphDumpGraph接口必须在SetInputs接口和SetOutputs接口之后调用，例如： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 string op_name = "tc_ge_openpass_0001"; // 创建Graph对象 Graph graph(op_name); // 创建Data算子实例 auto data = op::Data("data").set_attr_index(0); // 定义数据张量的描述信息 TensorDesc data_desc2(ge::Shape({3, 3, 3, 3}), FORMAT_NHWC, DT_FLOAT); data.update_input_desc_x(data_desc2); data.update_output_desc_y(data_desc2); // 创建MatrixInverse算子实例，并设置其输入为Data的输出 auto matrixinverse = op::MatrixInverse("MatrixInverse").set_input_x(data); // 创建Square算子实例，并设置其输入为MatrixInverse的输出 auto square1 = op::Square("square1").set_input_x(matrixinverse); std::vector<Operator> inputs{data}; std::vector<Operator> outputs{data,square1}; // 调用接口，设置Graph的输入输出算子 graph.SetInputs(inputs).SetOutputs(outputs); std::map<std::string, std::string> init_options = { {ge::ir_option::SOC_VERSION,"xxx"} }; // 模型初始化，申请资源 auto ret = aclgrphBuildInitialize(init_options); EXPECT_EQ(ret, GRAPH_SUCCESS); std::cout << "BuildInitialize before infershape Success." << std::endl; size_t filesize =24; const char* file = "tc_ge_openpass_0001_dump"; // 将输入的Graph导出到文件中 ret = ge::aclgrphDumpGraph(graph,file,filesize); if(ret != GRAPH_SUCCESS) { std::cout<<"dump graph failed."<<std::endl; } // 编译生成离线模型并保存到内存缓冲区 ret = aclgrphBuildModel(graph,op_name); if(ret != GRAPH_SUCCESS) { std::cout<<"aclgrphBuildModel failed."<<std::endl; }

3. 在算子A和算子B之间增加算子C，比如在Const和Add算子之间插入Abs。
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const std::string CONST = "Const"; const std::string ADD = "Add"; GNode src_node; GNode dst_node; std::vector<GNode> nodes = graph.GetAllNodes(); for(auto &node : nodes) { ge::AscendString name; node.GetName(name); std::string node_name(name.GetString()); if(node_name == CONST) { src_node = node;} else if(node_name == ADD) { dst_node = node;} } graph.RemoveEdge(src_node, 0, dst_node, 0); auto abs = op::Abs("input3_abs"); GNode node_abs = graph.AddNodeByOp(abs); TensorDesc output_tensor_desc; src_node.GetOutputDesc(0, output_tensor_desc); abs.UpdateInputDesc(0, output_tensor_desc); abs.UpdateOutputDesc(0, output_tensor_desc); graph.AddDataEdge(src_node, 0, node_abs, 0); graph.AddDataEdge(node_abs, 0, dst_node, 0);

  a. 调用    GetAllNodes(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0027.html)
找到Const算子和Add算子。
  b. 调用    RemoveEdge(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0030.html)
删除Const算子和Add算子的连边（数据边或控制边）。
  c. 参考    使用算子原型衍生接口定义算子
，创建Operator类算子Abs（也可以调用OperatorFactory::CreateOperator创建算子）。
  d. 调用    AddNodeByOp(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0031.html)
创建GNode类算子Abs。
    创建完算子后，可以根据需要更新该算子的input和output TensorDesc，一般根据源节点的Output TensorDesc更新算子abs的Input TensorDesc和Output TensorDesc。如果不更新，系统会设置默认值，在模型编译时对Tensor Shape，type进行推导。

  e. 调用    AddDataEdge(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0032.html)
添加Const算子和Abs算子，Abs算子和Add算子之间的连边。如果有控制边，再调用    AddControlEdge(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0033.html)
添加控制边。


  如果在A与B插入多个算子，比如，A->C->D->B，参考以上步骤，分别执行操作A->C, C->D, D->B。

4. 删除算子A和算子B之间的C算子，比如删除算子Const和Add之间的Abs。
```
graph.RemoveNode(node_abs);
graph.AddDataEdge(src_node, 0, dst_node, 0);
```


  a. 调用    RemoveNode(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0029.html)
删除Abs算子。
  b. 调用    AddDataEdge(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0032.html)
添加Const和Add算子之间的连边。如果有控制边，再调用    AddControlEdge(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0033.html)
添加控制边。
5. 此外，如果需要查询GNode的信息，可以参考  GNode(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0035.html)
提供的方法。
