CGRA调研

CGRA调研

OpenCGRA

image-20230910221721815

OpenCGRA是一个用于建模、测试和评估CGRA的统一框架。上图显示了OpenCGRA框架的概述,并说明了它与编译支持和PyMTL的紧密集成。它提供了一个标准库,其中包含在不同抽象级别用于构建CGRA。为了加速使用CGRA的应用程序,需要有效的编译器支持来生成有效的操作映射和调度。在OpenCGRA中,映射算法在LLVM基础设施中实现。此外,OpenCGRA还提供了基于单元测试、集成测试和基于属性的随机测试的综合测试方法,以测试每个组件和整个CGRA模型。为了快速评估不同的CGRA设计,OpenCGRA可以模拟目标CGRA设计,通过PyMTL的生成通道生成可综合的Verilog,并通过一组电子设计自动化(EDA)脚本驱动ASIC工具流以获得面积、能量和时序分析.

OpenCGRA能够在不同的抽象级别(即,FL、CL、RTL和PL)。这使得用户能够快速地将CGRA设计从概念变为实现,从而简化设计空间探索。

def CGRA_FL( DFG, DataType, mem_size ):
	# Order the DFG nodes in ALAP
    DFG = order_ALAP( DFG )
    sram = [ DataType( 0 ) ] ∗ mem_size
    # Execute the CDFG nodes until a `branch`
    # node breaks the computation
    while( True ):
        for node in DFG:
            complete = execute(node, sram)
            if node.opt is OPT_BRH and complete:
            	break
	return sram

CGRA模拟

模拟CGRA对于周期级或周期精确的性能分析以及验证编译器实现的正确性至关重要。现有的CGRA框架在ADL或基于XML的描述中对目标CGRA进行建模。然而,这需要额外的工程努力来进行模拟。至少,所有这些框架都需要用Verilog或VHDL编写测试台来驱动其他工具(例如,VCS)用于模拟。相反,OpenCGRA通过在框架内利用PyMTL的模拟通道来实现模拟。PyMTL允许编写测试平台和代码来驱动Python中的模拟,而没有任何语义间隙。具体地,OpenCGRA通过执行目标DFG来执行CGRA的FL模拟(如图3所示)。为了在CL或RTL上模拟CGRA,OpenCGRA模拟器读取由的编译器根据目标DFG生成的控制信号(JSON格式),并在每个周期调用静态调度的块。

CGRA生成

- OpenCGRA利用PyMTL的翻译传递从RTL CGRA模型生成可合成的Verilog。有效地建模一个异构CGRA和翻译成Verilog需要一个全面的参数化系统。现有的CGRA框架使得能够在声明性CGRA规范中进行参数化。对特定模块中的任何参数的更改都需要仔细并正确地传递到整个层次结构。举例来说,初始化同一图块模块中的具有不同FU的图块以建模异构CGRA。相比之下,OpenCGRA集成了中提出的参数化系统,以促进CGRA组件的配置过程。开发人员可以参数化层次结构中间的任何特定模块,而无需繁琐地修改配置/参数文件。参数化系统将在细化期间向每个模块通知更新的参数。

CGRA参数化

除了性能之外,面积、功耗和时序等特性对于构建CGRA也很重要。OpenCGRA利用一组EDA脚本来实现特性化。EDA脚本可以驱动不同的工具(例如,Synopsys Design Compiler、Cadence Innovus和Synopsys PrimeTime PX)来合成、放置和路由目标CGRA。面积、功率和定时可以由脚本自动获取和绘制。此外,PL CGRA模型可以生成显式的几何信息,并指导每个元件的放置为最终的芯片布局。

CGRAOmp

image-20230910222800916

CGRAOmp所提出的框架被实现为LLVM的扩展。LLVM由几个子项目组成,包括C/C++前端Clang,Fortran前端和OpenMP。因此,可以用最小的努力来构建框架。

上图描述了建议的编译流程的概述。它是自动处理的编译器驱动程序。前端将用C或Fortran编写的应用程序代码编译成LLVM中间表示(IR)。LLVM-IR具有由主机CPU执行的代码和要卸载的代码两者。LLVM工具链包含clang-offload-bundler,这是一个用于异构单源编程的实用工具,并为主机CPU和加速器分离代码对象。由此,编译器驱动器从捆绑的代码中提取在CGRA上执行的内核。

CGRA内核的提取代码通过预先以CGRA为中心的过程的内置通道进行优化。例如,应用与目标硬件无关的可用代码优化,诸如死代码消除、常数折叠和冗余消除。

image-20230910234302386

将良好优化的LLVM-IR馈送到CGRAOmpPass中。根据目标CGRA模型来改变通道的行为。验证内核代码是否可以被执行,提取经验证的内核作为DFG,并且用适当的运行时函数替换内核代码以用于重新配置、数据传输和同步。但是,运行时部分目前正在开发中。导出的DFG被馈送到目标CGRA的任何后端映射器中。最后,为每个内核创建配置文件。它被静态加载到执行二进制文件中,或者在运行时动态加载。替换之后的剩余LLVM-IR仅包含控制部分,使得其再次通过clang-offload-bundler合并到主机LLVMIR中。该框架旨在为运行时库提供模板。因此,CGRA设计人员只需实现一个从模板派生的库来适应他的系统。以这种方式,预期甚至用于一些没有主机处理器的独立CGRA。

CCF

image-20230911093456512

CCF 20.04编译器的前端(通过修改clang 13.0实现)从C/C++代码中识别并标记带注释的循环。然后,它生成源代码的中间表示(IR).该中间表示是在SelectionDAG阶段之前通过LLVM获得的。CCF在LLVM 中实现,包括一组转换和分析通道。其中一个重要的过程基于使用定义链对循环变量的IR执行活性分析。它确保CPU和CGRA之间循环的活入/活出变量的自动通信。这些实时变量作为CPU和CGRA之间的共享数据进行通信,或者可替代地,可以经由memcpy风格的函数向CGRA存储器传输/从CGRA存储器传输。在该模型中,CGRA是紧密耦合的CPU核心在L2缓存的接口或通过一个暂存器与处理器相连。

在IR文件中,注释循环包含元数据(例如,使能),这样编译器就知道哪个循环将进行分析和转换。然后编译器分析循环是否将在CGRA上加速。如果循环可以,编译器将生成该循环的数据流图(DFG)。

int fibonacci(int count){
	if(count == 0 || count == 1) return 0;
    int ret =1;
    int prev =1;
    #pragma CGRA
    for(int i=1; i<count -1; i++){
        int temp = ret+prev;
        prev = ret;
        ret = temp;
    }
    return ret;
}

LLVM Pass CondDDGGen生成循环的DDG,可以使用点工具可视化。

然后,为DDG生成迭代模调度,并且以软件流水的方式将操作映射到PE上。一旦实现映射,基于CGRA微架构生成用于CGRA PE的机器指令。最后插入与CGRA上的循环执行有关的库调用,并且通过LLVM Pass 的InvokeCGRA和CGRAGen来清除与循环体相对应的IR,然后将该修改的IR用于CPU的机器代码生成。

在系统仿真模式下,在流行的周期精确模拟器gem 5上评估生成的二进制;将CGRA建模为耦合到具有ARMv 7a简档的ARMCortex类处理器核心的单独核心。

Pilars

image-20230911101306929

框架的输入是基于Scala的ADL中的模型,用于描述CGRA架构1,以及用于描述应用7的普遍接受的数据流图(DFG)。CGRA的ADL由架构解释器2解析,产生所描绘的CGRA架构的分层抽象模型3。为了获得高质量的映射表示并降低RTL生成的复杂度,层次抽象模型将被平坦化4 。设备中的层次化抽象模型将产生对应的基本Chisel模块5和模路由资源图(6;MRRG)以对CGRA 建模。

映射器接收用于特定应用的DFG作为输入,以及CGRA架构的MRRG模型,以将DFG映射到CGRA上,并且调度器将重构映射结果的调度8。结合层次抽象模型,映射器和调度器的输出可以被转换成上下文,将应用于仿真。根据基本模块在层次抽象模型中的区域自动生成辅助模块9,支持周期精确仿真和互连。结果,将获得Chisel顶层设计10,从而可以进行Verilog RTL 11的自动生成。

它实现了一个组件,辅助模拟器代码生成12。在Chisel I/O测试和Verilator (RocketChip 使用的功率RTL模拟器)的帮助下,可以获得用于功能验证13的周期精确模拟结果。ADRES CGRA架构14变体的FPGA覆盖实现。将FPGA覆盖层15的性能、面积和消耗与来自映射器的可映射性、吞吐量和运行时间相结合,可以在16中的一组应用上评估CGRA的所描绘设计的性能、功率和面积。

image-20230910223648678

OpenCL 由一组headers和一个在运行时加载的共享对象组成。必须在平台上为运行时需要支持的每个供应商类安装可安装的客户端驱动程序 (ICD)。也就是说,例如,为了在Linux平台上支持Nvidia设备,需要安装Nvidia ICD,以便OpenCL Runtime(ICD加载器)能够找到供应商的ICD并适当地重定向呼叫。标准 OpenCL 标头由使用者应用程序使用;然后,OpenCL 运行时使用 ICD 将调用每个函数代理到相应的驱动程序。每个供应商都必须在其驱动程序中实现每个 OpenCL 调用。

Apple,Nvidia,ROCm,RapidMind和Gallium3DOpenCL的实现都基于LLVM编译器技术,并使用Clang编译器作为前端。

posted @ 2023-09-12 09:43  lishangli  阅读(327)  评论(0)    收藏  举报