HeteroFlow: An Accelerator Programming Model with Decoupled Data Placement for Software-Defined FPGAs

HeteroCL

OVERVIEW

HeteroCL is a programming infrastructure composed of a Python-based domain-specific language (DSL) and a compilation flow. The HeteroCL DSL provides a clean abstraction that decouples algorithm specification from three important types of hardware customization in compute, data types, and memory architectures. HeteroCL further captures the interdependence among these techniques, allowing programmers to explore various trade-offs in a systematic and productive manner. In addition, our framework produces highly efficient hardware implementations for a variety of popular workloads by targeting spatial architecture templates such as systolic arrays and stencil with dataflow architectures.

HeteroCL是一个编程基础设施,由基于python的领域特定语言(DSL)和编译流程组成。HeteroCL DSL提供了一种干净的抽象,将算法规范与计算、数据类型和存储架构中三种重要的硬件定制类型解耦。HeteroCL进一步捕捉了这些技术之间的相互依赖关系,允许程序员以系统和高效的方式探索各种权衡。通过将systolic阵列和stencil等空间架构模板与数据流架构相结合,该框架为各种流行的工作负载产生高效的硬件实现。

img

前端用pytorch,keras等框架写神经网络模型,HeteroCL对其中的计算方式,数据类型,存储访问进行定制,生成HLS代码(C++代码),HLS编译器综合成FPGA能够读懂的RTL级别的语言。

Language Overview

lang_overview

compile flow

compile_flow

HeteroFlow

要解决的问题

HeteroCL将算法规范和计算定制技术解耦了,或者说分开了。这种将算法规范和计算定制技术分开的解耦编程模型最初是在Halide中提出的,然后才被TVM和HeteroCL等一些框架采用了,不同的是,HeteroCL还进一步将存储架构和量化方案也同算法解耦了。

但是HeteroCL没有提供明确的抽象去对数据放置建模,也就是说定制的存储策略和计算单元之间还是互相依赖的。程序员还是需要将数据放置策略嵌入到算法代码中,或者依靠编译器生成默认的放置策略。

image-20221011115514344

算法和数据放置策略耦合的例子

image-20221011193004938

image-20221011193014862

需要用#pragma HLS 的语法去定义接口完成主机和加速器之间的通信如图1,以数据流的方式实现任务级并行,需要定义两个计算内核的FIFO,还要配置深度。

对于循环中的数据流,如下图3,实现一个脉冲阵列的空间架构,需要定义PE的行为,PE之间的连接方式,数据的广播和输出等数据排布方案。

image-20221011193617245

上面给出的代码都是CPP的,对于HeteroCL来说,没有找到可以定制数据放置策略的API,可能是之前提到的第二种情况,由编译器生成默认方案。

解决的方案(创新点)

为了解决上面提到的问题,提出了基于HeteroCL扩展出来的HeteroFlow,HeteroFlow通过使用一个统一的编程接口.to() 语句,使得编程人员可以在不同的设计层级和数据粒度去明确数据放置方案。

通过.to语句,可以对主机-加速器,kernel之间,kernel内部的数据放置方案进行设置,而不会影响到上面的算法描述代码,如图5:

image-20221011200038835

对各个设计层级之间放置方案设置的具体API在下面的内容

PROGRAMMING MODEL

Host:主机CPU,有处理器,有cache,有host DRAM,像是一台外设,一个硬宏?

Accelerator:加速器,包含FPGA,可能有缓存cache,有DRAM设备

kernel:计算核,产生或使用数据的一个函数/模块(eg,conv1,conv2,PE....)

Host-Accelerator Data Placement

使用to语句将主机-加速器之间的数据放置和算法描述解耦。提供了三种数据的放置方法:

image-20221011105631689

  1. DMA
  2. DRAM
  3. cache-coherent

Inter-Kernel Data Placement

计算内核之间(也就是两个大的循环嵌套,或者说两个卷积核之间)实现高效的数据流,通常是用FIFO或者双缓冲区,但是在HLS里实现是很复杂的,需要用pragma的指令,stream流对数据访问的替换等等。

使用.to()就很简单,不使用就是默认的单缓冲区。通过下面的语句可以设置核间数据传输的方式:

image-20221011201323031

Intra-Kernel Data Placement

核内细粒度数据的放置方案设置:

image-20221011201600141

然后可以用上面的API写一个脉冲阵列的计算核的架构:

image-20221011201901445

如何解析定义的to()语句来生成FPGA可以理解的RTL级语言呢?下面是to语句的编译流

Comipilation Flow

  1. 输入程序lower成IR,根据用户的数据放置策略建立数据流图DFG
  2. 被用户明确指出放置策略的数据是所有数据的一部分,所有其他未指明策略的数据(灰色节点)由编译器自动推断。(自动推断的算法?)
  3. 得到推理结果,就知道每个数据放置的位置,根据位置将其分为FPGA的DFG和HOST的DFG的两个子图,针对FPGA的子图,还可以应用硬件定制来进一步提高加速器的性能。
  4. 编译器也可能会为片外存储访问应用自动的I/O优化(就是给加速器和host之间的io进行优化),以提高带宽利用率。(具体的优化方法?)
  5. 最后生成优化的HLS C/C++代码

Inference of Compute/Data Placement

HeteroFlow自动推断出没有显式地用. To()注释的那部分数据和计算的位置方案。将放置推理表述为一个整数线性规划(ILP)问题:

image-20221012124345627

目标是最小化数据的访问延迟,被约束的调节和DFG中计算阶段表示的节点之间的关系有关。

通过解决ILP问题,得到没有to语句指明数据的放置方案。

Automatic I/O Optimizations

给FPGA和host子图边界的IO自动优化的方法:

  • Memory Coalescing(存储合并):片外访问,窄存储访问合并为一个宽的存储,读一次地址,得到更多的数据
  • AXI Controller Configuration(AXI控制器配置):AXI是控制片内外数据访问的总线,对它进行配置,可以微小的影响带宽
  • I/O Scheduling(I/O调度):每个片外存储器只能同时响应有限个来自不同AXI的访问请求,如果加速器里面的并行访问太多,编译器就会插入一个静态调度器,根据优先级将请求分配给AXI控制器
  • FIFO Inference(推测是否用FIFO):对于内核间顺序通信推测出使用FIFO,根据用户指定数据流、收缩阵列、pe通信使用FIFO

Code Generation

HeteroFlow编译器后端根据使特定供应商的库和编译指令(比如xilinx的vivado,pragma语法)生成C++代码。

因为HeteroFlow是由HeteroCL扩展来的,其他一些优化也有HeteroCL编译器完成一部分。

image-20221012134458130

EVALUATION

optical flow 程序

image-20221012135416543

性能与HLS c++中手动优化的性能相当,同时所需代码量(LoC)减少了3.6倍

KNN

image-20221012140053018

I/O自动优化的效果:不断加上存储合并,AXI接口控制,IO调度等策略,运行速度不断提升

related work

image-20221012140444473

posted @ 2022-10-31 11:11  xiongyuqing  阅读(36)  评论(0编辑  收藏  举报