5. TopsGraphCompiler 用户使用手册

5.1. 专有名词解释

表 5.1.1 缩略语和术语

术语

定义

GCU

General Computing Unit 燧原科技通用计算单元

gcu200

燧原科技面向数据中心的第二代人工智能训练加速卡

gcu210

燧原科技面向数据中心的第二代人工智能推理加速卡

gcu300

燧原科技面向数据中心的第三代人工智能推理加速卡

SIP

Scalable Intelligent Processor,芯片计算核心

Cluster

SIP的集群分组

HLIR

High Level Intermediate Representation 高级别中间(图层)表示和优化

Op

HLIR Operation的简称,燧原科技定义的算子

HLIR Module

由 HLIR Op 组合而成的一个完整的计算图(模型)

Builder

创建算子和计算图的基础设施,可以用于构建 HLIR Module

5.2. 快速入门

TopsGraphCompiler是燧原科技开放给用户的图编译库,能够将hlir module编译成燧原科技人工智能加速卡可执行的二进制文件。

TopsGraphCompiler支持两种格式的hlir输入,一种是用户友好型的字符格式类型,一种是开发者友好型的C++数据结构类型hlir module。

TopsGraphCompiler通过设置编译选项-arch和-recource指定目标硬件(GCU),通过-hlir设置优化的pipeline。

下面是C++图编译示例:

示例1:输入为字符串类型的hlir通过TopsGraphCompiler编译成可执行文件。

#include "gcu/tops_graph_compiler/tops_graph_compiler.h"
int main() {
  const char* module = R"(
    module @hlir_module attributes {dtu_hlir.executable_id = 1 : i64} {
      func @main(%arg0: tensor<10xf64>, %arg1: tensor<10xf64>) -> tensor<1xf64> {
        %0 = "dtu_hlir.dot_general"(%arg0, %arg1) {
            dot_dimension_numbers = {lhs_batching_dimensions = dense<[]> : tensor<0xi64>,
            lhs_contracting_dimensions = dense<0> : tensor<1xi64>,
            rhs_batching_dimensions = dense<[]> : tensor<0xi64>,
            rhs_contracting_dimensions = dense<0> : tensor<1xi64>},
            op_type = "DotInference"} : (tensor<10xf64>, tensor<10xf64>) -> tensor<f64>
        %1 = "dtu_hlir.reshape"(%0) : (tensor<f64>) -> tensor<1xf64>
        return %1 : tensor<1xf64>
      }
    }
  )";

  // 设置编译选项
  const char* options[] = {"-arch=gcu300", "-resource=1c12s",
                           "-hlir=tops-hlir-pipeline"};
  topsgraphProgram program;
  // 创建program
  auto ret = topsgraphCreateProgramFromString(&program, module);
  // 编译program
  ret = topsgraphCompileProgram(program, 3, options);
  // 从编译完成的program中获取binary大小和binary数据
  size_t binary_size = 0;
  ret = topsgraphGetBinSize(program, &binary_size);
  char* binary = new char[binary_size];
  ret = topsgraphGetBin(program, binary);
  // 释放program
  topsgraphDestroyProgram(&program);
  // 释放申请的binary
  delete [] binary;
  return 0;
}

示例2:输入为hlir module通过TopsGraphCompiler编译成可执行文件。

#include "gcu/tops_graph_compiler/tops_graph_compiler.h"
#include "gcu/hlir/builder/hlir_builder.h"
int main() {
  // 使用builder构建hlir module
  auto builder = std::make_shared<builder::Builder>();
  builder->SetShapeInference(/*enable_shape_inference=*/true);
  builder::Type type({2, 3}, builder::PrimitiveType::F32());
  auto in = builder->CreateInput(type);
  // 创建一个relu op
  auto op0 = builder::Relu(in);
  builder->SetOutput({op0});
  auto module = builder->GetModule();

  // 设置编译选项
  const char *options[] = {"-arch=gcu300", "-resource=1c12s",
                           "-hlir=tops-hlir-pipeline"};
  // 创建program
  topsgraphProgram program;
  auto ret = topsgraphCreateProgramFromModule(&program, module.get());
  // 编译program
  ret = topsgraphCompileProgram(program, 3, options);
  // 从编译完成的program中获取binary大小和binary数据
  size_t binary_size = 0;
  ret = topsgraphGetBinSize(program, &binary_size);
  char* binary = new char[binary_size];
  ret = topsgraphGetBin(program, binary);
  // 释放program
  topsgraphDestroyProgram(&program);
  // 释放申请的binary
  delete [] binary;
  return 0;
}

5.3. 用户使用说明

简介

TopsGraphCompiler分为三个阶段:创建程序、编译程序、读取(和存取)程序。 这里的程序指的是topsgraphProgram,它是一个不透明的句柄(void*),用于整个编译阶段。

topsgraphProgram的定义如下所示:

typedef void* topsgraphProgram;

topsgraphResult是一个枚举类型,在编译阶段作为返回值,用户通过返回值可以判断编译的状态。

enum topsgraphResult {
  TOPS_GRAPH_SUCCESS = 0,  // 成功标志
  TOPS_GRAPH_ERROR_INVALID_INPUT,  // 无效输入标志
  TOPS_GRAPH_ERROR_INVALID_PROGRAM,  // 无效的程序
  TOPS_GRAPH_ERROR_INVALID_OPTION,  // 无效的输入参数
  TOPS_GRAPH_ERROR_OUT_OF_MEMORY  // 内存溢出
};

创建程序

在创建程序阶段,通过topsgraphCreateProgramFromString或者topsgraphCreateProgramFromModule接口解析不同格式的hlir并创建topsgraphProgram。

// 解析字符类型hlir
topsgraphResult topsgraphCreateProgramFromString(topsgraphProgram* program, const char* module);
// 解析C++数据结构类型hlir module
topsgraphResult topsgraphCreateProgramFromModule(topsgraphProgram* program, hlir::Module* module);

Warning

当通过上述两个API创建了program之后,请不要忘记在合适的地方将其释放。

// 释放program资源
topsgraphResult topsgraphDestroyProgram(topsgraphProgram* program);

编译程序

在编译阶段,通过options_num设置参数(options)的个数,通过参数指定目标硬件和优化相关的配置。 编译之后的结果将保存到程序中。

// 编译program,options_num是输入参数的个数,options是输入参数
topsgraphResult topsgraphCompileProgram(topsgraphProgram program,
                                        int options_num,
                                        const char** options);

输入的参数需要按照指定的键值对(key-vlaue)进行设置,键和值之间用’=’连接。当前版本支持三种键,分别是-arch、 -recource和-hlir。

-arch表示燧原科技产品型号,-recource为资源配置选项,这两个参数为必须配置的选项,-hlir为可选配置,默认为hlir-training-pipeline。 比如,-arch=gcu200和-recource=4c24s表示配置为gcu200型号的训练加速卡,其中包含了24个sip计算资源,以6个sip为一组,称为一个cluster。 -arch和-recource的所有可选配置如下表所示:

表 5.3.1 架构和硬件配置

架构

硬件配置

描述

gcu200

4c24s

训练卡。

gcu210

1c4s

推理卡。模型大小不超4G,吞吐高,适用于小模型多cluster 并行推理场景,一张gcu210卡最多可以支持6个cluster。

gcu210

1c12s

推理卡。模型大小不超8G,低延迟,适用于大模型推理场景。在 网络中算力计算相对数据搬运占比高时占优势,一张gcu210卡最 多可以支持2个cluster。

gcu300

2c24s

推理卡。

-hlir表示燧原科技AI编译器优化选项,可以配置优化的pipeline。 当前版本提供了训练和推理两个pipeline,用户可以根据实际情况进行配置。

表 5.3.2 图编译pipeline

pipeline

描述

hlir-training-pipeline

训练pipeline

tops-hlir-pipeline

推理pipeline

pipeline是由一系列pass组合而成,通过option设置也可以控制pipeline中pass的行为。 比如,hlir-training-pipeline{disable-passes=constant-folding-pass}表示在pipeline中禁用constant-folding-pass pass。pipeline option也是通过键值对(key-value)进行设置。 下表所示列出了该版本支持的所有key:

表 5.3.3 pipeline option

option键

类型

描述

disable-passes

string

禁止pass

enable-passes

string

enable-passes=all 使能所有pass

enable-passes=none 禁止所有pass

enable-passes=hlir-cse,algebraic-simplify 仅仅使能cse和代数优化pass

dynamic-shape

bool

是否开启动态shape

disable-passes和enable-passes对应的value是hlir注册的pass名字。当前版本支持通过option来控制下表中的pass:

表 5.3.4 pass注册名

pass注册名

描述

constant-folding-pass

常量折叠

algebraic-simplify

代数优化

hlir-cse

公共子表达式消除

hlir-fusion-elementwise

elementwise fusion

读取(和存取)程序

从编译完成的程序中读取燧原科技人工智能加速卡可执行的二进制文件分为三步:1. 通过topsgraphGetBinSize接口获取二进制文件的大小。2. 在堆区申请一块与二进制文件相同大小的内存。3. 通过topsgraphGetBin接口从编译完成的程序中获取二进制文件。

// 从程序中获取进制文件大小
topsgraphResult topsgraphGetBinSize(topsgraphProgram program,
                                    size_t* binary_size);

// 从程序中拷贝二进制文件
topsgraphResult topsgraphGetBin(topsgraphProgram program,
                                char* binary);

如果需要将二进制文件保存成文件,则可以使用topsgraphSaveBinFile接口。

// 将程序中的二进制文件保存到save_file文件中
topsgraphResult topsgraphSaveBinFile(topsgraphProgram program,
                                    const char* save_file);

5.4. Dump hlir

TopsGraphCompiler提供了一个环境变量来保存编译过程中的hlir module,方便使用者debug。

export COMPILE_OPTIONS_MLIR_DBG="-pass-timing -pass-statistics -mlir-elide-elementsattrs-if-larger=100 -print-ir-before-all=true -print-ir-after-all=true -log-output-path=/tmp/irdump/"

下面是这个环境变量可以设置的参数:

表 5.4.1 环境变量提供的option

参数

描述

-log-output-path

log保存路径

-pass-timing

pass执行时间报告

-pass-statistics

pass统计报告

-mlir-elide-elementsattrs-if-larger

属性存储最大值设置

-mlir-elide-elementsattrs-if-larger=100, op的属性如果不超过100个字 节,则全部保存,否则,保存缩减成dense<0xFF800000>

-disable-pass-threading

静止TopsGraphCompiler使用多线程编译

-print-ir-before

打印执行pass之前的ir

-print-ir-before=hlir-cse 打印执行cse pass之前的ir

-print-ir-after

打印执行pass之后的ir

-print-ir-after=hlir-cse 打印执行cse pass之后的ir

-print-ir-before-all

打印所有pass之前的ir

-print-ir-after-all

打印所有pass之后的ir

-print-ir-after-change

只打印执行pass之后有改变的ir

上述参数的前置也可以是’–’,比如-log-output-path也可以用–log-output-path。

5.5. 其他

如需要更为详尽的API参考信息,参见《TopsGraphCompiler C++ API参考》。