paper:Yi-HsiangLai1,YuzeChi,YuweiHu,JieWang,CodyHaoYu,YuanZhou,JasonCong,ZhiruZhang.HeteroCL:AMulti-ParadigmProgrammingInfrastructureforSoftware-DefinedReconfigurableComputing.InFPGA,201code:cornell-zhang/heterocl:HeteroCL:AMulti-ParadigmProgrammingInfrastructureforSoftware-DefinedHeterogeneousComputing
HeteroCLisaprogramminginfrastructurecomposedofaPython-baseddomain-specificlanguageandacompilationflow.TheHeteroCLDSLprovidesacleanabstractionthatdecouplesalgorithmspecificationfromthreeimportanttypesofhardwarecustomizationincompute,datatypes,andmemoryarchitectures.HeteroCLfurthercapturestheinterdependenceamongthesetechniques,allowingprogrammerstoexplorevarioustrade-offsinasystematicandproductivemanner.Inaddition,ourframeworkproduceshighlyefficienthardwareimplementationsforavarietyofpopularworkloadsbytargetingspatialarchitecturetemplatessuchassystolicarraysandstencilwithdataflowarchitectures.**HeteroCL是一个编程基础设施,由基于python的领域特定语言和编译流程组成。HeteroCLDSL提供了一种干净的抽象,将算法规范与计算、数据类型和内存架构中三种重要的硬件定制类型解耦。**HeteroCL进一步捕捉了这些技术之间的相互依赖关系,允许程序员以系统和高效的方式探索各种权衡。通过将systolic阵列和stencil等空间架构模板与数据流架构相结合,该框架为各种流行的工作负载产生高效的硬件实现。
前端用pytorch,keras等框架写神经网络模型,HeteroCL对其中的计算方式,数据类型,内存访问进行定制,生成HLS代码,HLS编译器综合成FPGA能够读懂的RTL级别的语言。
ShaojieXiang,Yi-HsiangLai,YuanZhou,HongzhengChen,NiansongZhang,DebjitPal,ZhiruZhang.HeteroFlow:AnAcceleratorProgrammingModelwithDecoupledDataPlacementforSoftware-DefinedFPGAs.InFPGA,202
要解决的问题
HeteroCL将算法规范和计算定制技术解耦了,或者说分开了。这种将算法规范和计算定制技术分开的解耦编程模型最初是在Halide中提出的,然后才被TVM和HeteroCL等一些框架采用了,不同的是,HeteroCL还进一步将内存架构和量化方案也同算法解耦了。
但是HeteroCL没有提供明确的抽象去对数据放置建模,也就是说定制的存储策略和计算单元之间还是互相依赖的。程序员还是需要将数据放置策略嵌入到算法代码中,或者依靠编译器生成默认的放置策略。
算法和数据放置策略耦合的例子
需要用#pragmaHLS的语法去定义接口完成主机和加速器之间的通信如以数据流的方式实现任务级并行,需要定义两个计算内核的FIFO,还要配置深度。
对于循环中的数据流,如下实现一个脉冲阵列的空间架构,需要定义PE的行为,PE之间的连接方式,数据的广播和输出等数据排布方案。
上面给出的代码都是CPP的,对于HeteroCL来说,没有找到可以定制数据放置策略的API,可能是之前提到的第二种情况,由编译器生成默认方案。
解决的方案
为了解决上面提到的问题,提出了基于HeteroCL扩展出来的HeteroFlow,**HeteroFlow通过使用一个统一的编程接口.to语句,**使得编程人员可以在不同的设计层级和数据粒度去明确数据放置方案。
通过.to语句,可以对主机-加速器,kernel之间,kernel内部的数据放置方案进行设置,而不会影响到上面的算法描述代码,如
对各个设计层级之间放置方案设置的具体API在下面的内容
Host:主机CPU,有处理器,有cache,有hostDRAM,像是一台外设,一个硬宏?
Accelerator:加速器,包含FPGA,可能有缓存cache,有DRAM设备
kernel:计算核,产生或使用数据的一个函数/模块
使用to语句将主机-加速器之间的数据放置和算法描述解耦。提供了三种数据的放置方法:
计算内核之间实现高效的数据流,通常是用FIFO或者双缓冲区,但是在HLS里实现是很复杂的,需要用pragma的指令,stream流对数据访问的替换等等。
使用.to就很简单,不使用就是默认的单缓冲区。通过下面的语句可以设置核间数据传输的方式:
核内细粒度数据的放置方案设置:
然后可以用上面的API写一个脉冲阵列的计算核的架构:
如何解析定义的to语句来生成FPGA可以理解的RTL级语言呢?下面是to语句的编译流
输入程序lower成IR,根据用户的数据放置策略建立数据流DFG被用户明确指出放置策略的数据是所有数据的一部分,所有其他未指明策略的数据得到推理结果,就知道每个数据放置的位置,根据位置将其分为FPGA的DFG和HOST的DFG的两个子,针对FPGA的子,还可以应用硬件定制来进一步提高加速器的性能。编译器也可能会为片外内存访问应用自动的I/O优化,以提高带宽利用率。最后生成优化的HLSC/C++代码
HeteroFlow自动推断出没有显式地用.To注释的那部分数据和计算的位置方案。将放置推理表述为一个整数线性规划问题:
目标是最小化数据的访问延迟,被约束的调节和DFG中计算阶段表示的节点之间的关系有关。
通过解决ILP问题,得到没有to语句指明数据的放置方案。
给FPGA和host子边界的IO自动优化的方法:
MemoryCoalescing:片外访问,窄内存访问合并为一个宽的内存,读一次地址,得到更多的数据AXIControllerConfiguration:AXI是控制片内外数据访问的总线,对它进行配置,可以微小的影响带宽I/OScheduling:每个片外存储器只能同时响应有限个来自不同AXI的访问请求,如果加速器里面的并行访问太多,编译器就会插入一个静态调度器,根据优先级将请求分配给AXI控制器FIFOInference:对于内核间顺序通信推测出使用FIFO,根据用户指定数据流、收缩阵列、pe通信使用FIFO
HeteroFlow编译器后端根据使特定供应商的库和编译指令生成C++代码。
因为HeteroFlow是由HeteroCL扩展来的,其他一些优化也有HeteroCL编译器完成一部分。
opticalflow程序:
性能与HLSc++中手动优化的性能相当,同时所需代码量减少了6倍
KNN:
文章为作者独立观点,不代表观点