Ascend Graph构图
GE提供了Ascend Graph相关接口,支持开发者基于算子原型构造可直接在昇腾平台运行的计算图,本节仅描述Ascend Graph构图的总体流程并对每个流程进行简要介绍。
- 基于算子原型构建Graph。
每一个算子都会提供原型定义,规定了其在昇腾AI处理器上可运行的相关约束,包括算子的输入、输出、属性等,CANN内置算子的原型定义可参见《算子清单》,您也可以从“Ascend-cann-toolkit安装目录/ascend-toolkit/latest/opp/built-in/op_proto/inc”算子原型定义的头文件中获取。
例如Add算子的原型定义如下:
REG_OP(Add) .INPUT(x1, TensorType({DT_BOOL, DT_FLOAT, DT_INT32, DT_INT64, DT_FLOAT16, DT_BF16, DT_INT16, DT_INT8, DT_UINT8, DT_DOUBLE, DT_COMPLEX128, DT_COMPLEX64, DT_STRING, DT_COMPLEX32})) .INPUT(x2, TensorType({DT_BOOL, DT_FLOAT, DT_INT32, DT_INT64, DT_FLOAT16, DT_BF16, DT_INT16, DT_INT8, DT_UINT8, DT_DOUBLE, DT_COMPLEX128, DT_COMPLEX64, DT_STRING, DT_COMPLEX32})) .OUTPUT(y, TensorType({DT_BOOL, DT_FLOAT, DT_INT32, DT_INT64, DT_FLOAT16, DT_BF16, DT_INT16, DT_INT8, DT_UINT8, DT_DOUBLE, DT_COMPLEX128, DT_COMPLEX64, DT_STRING, DT_COMPLEX32})) .OP_END_FACTORY_REG(Add)
获取了算子原型定义后,开发者可以通过如下几个步骤完成Graph的创建。- 根据算子原型创建算子实例,并设置其输入、输出与属性。
#include "all_ops.h" auto shape_data = vector<int64_t>({ 1,1,28,28 }); TensorDesc desc_data(ge::Shape(shape_data), FORMAT_ND, DT_FLOAT16); // 创建Data算子的实例data auto data = op::Data("data"); data.update_input_desc_x(desc_data); data.update_output_desc_y(desc_data); // 创建Add算子的实例add auto add = op::Add("add") .set_input_x1(data) .set_input_x2(data);
- 算子连接边表达。
算子之间的连边分为数据边和控制边。其中数据边(set_input_输入名称)用于指定算子的输入,控制边(AddControlInput)用于控制算子的执行顺序。
开发者需要根据图结构使用连接边和控制边完成图拓扑结构的构造。
- 创建Graph实例。
至此,已经完成通过算子原型构造Ascend Graph的全部流程,关于更详细的各类算子的构图表达以及技巧可参见《Ascend Graph开发指南》中的通过算子原型构建Graph。
- 根据算子原型创建算子实例,并设置其输入、输出与属性。
- 编译运行Graph。
构造好Graph后,开发者可通过如下步骤编译执行Graph(如下仅描述关键步骤及其接口)。
- 调用ge::GEInitialize接口进行系统初始化,申请系统资源。
- 创建session,并调用AddGraph接口加载Graph对象。
- 调用aclInit接口进行AscendCL资源初始化。
- 调用BuildGraph接口编译Graph。
- 指定运行的Device(aclrtSetDevice)、创建Stream(aclrtCreateStream)、申请内存(aclrtMallocHost与aclrtMalloc),并将数据从Host传输到Device( aclrtMemcpy),进行图执行前准备。
- 调用RunGraphWithStreamAsync接口执行Graph,输出执行结果。
- 释放相关资源。