文档
注册

DSL简介

为了方便开发者进行自定义算子开发,TBE(Tensor Boost Engine)提供了一套计算接口供开发者用于组装算子的计算逻辑,这套计算接口称之为DSL(Domain-Specific Language)。基于DSL开发的算子,可以直接使用TBE提供的Auto Schedule机制,自动完成调度过程,省去最复杂的调度编写过程。

DSL功能框架

TBE DSL算子的功能框架如图1所示。

图1 TBE DSL功能框架
  1. 开发者调用TBE提供的DSL接口进行计算逻辑的描述,指明算子的计算方法和步骤。
  2. 计算逻辑开发完成后,开发者可调用Auto Schedule接口,启动自动调度,自动调度时TBE会根据计算类型自动选择合适的调度模板,完成数据切块和数据流向的划分,确保在硬件执行上达到最优。
  3. Auto Schedule调度完成后,会生成类似于TVM的IR(Intermediate Representation)的中间表示。
  4. 编译优化(Pass)会对算子生成的IR进行编译优化,优化的方式有双缓冲(Double Buffer)、流水线(Pipeline)同步、内存分配管理、指令映射、分块适配矩阵计算单元等。
  5. 算子经Pass处理后,由CodeGen生成类C代码的临时文件,这个临时代码文件可通过编译器生成算子的实现文件,可被网络模型直接加载调用。

代码示例如下所示:

    //初始化输入tensor,为输入tensor进行占位
    data_x = tvm.placeholder(shape_x, name="data_1", dtype=input_data_type)
    data_y = tvm.placeholder(shape_y, name="data_2", dtype=input_data_type)
   //调用计算接口实现data_x + data_y
    res = tbe.dsl.vadd(data_x, data_y)
   //调用auto_schedule接口实现自动调度
    with tvm.target.cce():
        schedule = tbe.dsl.auto_schedule(res)
    //配置编译参数并进行编译
    config = {"name": kernel_name,
              "tensor_list": (data_x, data_y, res)}
    tbe.dsl.build(schedule, config)

DSL计算接口介绍

TBE DSL提供的计算接口主要涵盖向量运算,包括Math、NN、Reduce、卷积、矩阵计算等接口。

详细的接口介绍请参见TBE DSL API

Auto Schedule介绍

算子的计算逻辑实现完后,如果要让计算逻辑在硬件中执行,还需要考虑如下问题:
  • 计算指令在硬件中按照什么顺序执行?
  • 数据如何在硬件内存中存储?

Schedule(调度)就是为了解决如上问题,通过调整计算逻辑、优化计算过程,使得计算更加高效,并保证计算过程中占用的硬件存储空间不会超过上限。

TBE DSL提供了Auto Schedule机制,以上Schedule操作无需用户关注。用户通过组合DSL接口表达算子的计算逻辑后,直接调用Auto Schedule接口即可实现自动调度,完成数据切块和数据流向的划分。Auto Schedule机制是TBE底层的默认Schedule调优机制,开发者无法在算子开发代码过程中进行控制,下面简要介绍Auto Schedule的原理。

如下是基于DSL进行算子开发的示例,实现对x取指数,然后在轴0上进行累加降维,再取倒数的功能。

x = tvm.placeholder((512, 1024), "float16")
exp_x = tbe.dsl.vexp(x)
reduce_exp_x = tbe.dsl.sum(exp_x, axis = 0)
res = tbe.dsl.vrec(reduce_exp_x)

with tvm.target.cce():
    sch = tbe.dsl.auto_schedule(res)

开发者调用tbe.dsl.auto_schedule接口开启TBE的自动调度,自动调度的总体流程如图2所示。

图2 Auto Schedule总体流程
  1. 调用Auto Schedule接口的时候,就是传递了一个compute的语法树,TBE中每一个compute语句在进行编译的时候都会被加上tag_scope标志,如下所示。

    添加tag_scope的操作如下:

    with tvm.tag_scope(op):
        tmp = tvm.compute(shape, lambda_func, name=name)
    图3所示,左侧的compute语法树,也叫抽象语法树(Abstract Syntax Tree: AST),编译过程中,会对每一个compute语句加上tag_scope标志。
    图3 计算语句与tag_scope标志对应示例
  2. 根据scope标识,识别出对应pattern,TBE当前支持的pattern类型有:elewise、reduce、segment、concat、conv、depthwise、pooling2d等。TBE会按照pattern规则对AST进行切分,例如最简单的一条pattern规则是elewise可以和其他的pattern连在一起,reduce、segment、concat不能在一个AST子图内。
  3. 完成AST子图切分后,TBE会创建并初始化Schedule对象。
  4. Schedule执行过程中首先找到AST子图的边界,然后对每一个子图根据其pattern选择一个合适的Schedule模板进行调度。调度过程主要包括数据流管理、tiling以及指令映射等。
搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词