600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Vivado HLS加速卷积层运算

Vivado HLS加速卷积层运算

时间:2022-07-29 00:05:01

相关推荐

Vivado HLS加速卷积层运算

源代码链接:/happyday22/HLS_accelerator

1.Introduction

卷积神经网络(CNN)主要由卷积层、池化层、全连接层和激活层等网络层顺序连接而成。本文主要针对计算密集型的卷积层,利用Vivado HLS工具对其在FPGA上的实现进行加速。

2.Basic knowledge

一个基本的卷积运算由6层for循环实现。如下面代码所示,从外向里的循环依次是K*K大小的卷积核,输出特征图的行列(Tr,Tc),输出通道数(Tout),输入通道数(Tin)

Kernel_Row:for(int kr=0;kr<K;kr++){Kernel_Col:for(int kc=0;kc<K;kc++){Row:for(int r=0;r<Tr;r++){Column:for(int c=0;c<Tc;c++){Out_channel:for(int out=0;out<Tout;out++){in_channel:for(int in=0;in<Tin;in++){Out[out][r][c]+=In[in][S*r+kr][S*c+kc]*W[out][in][kr][kc];}}}}}}

用C++语言实现上述卷积运算后,Vivado HLS能够将其综合为RTL硬件代码。除上述的C++代码,Vivado HLS还需要输入时钟周期,芯片类型以及编译制导语句(Directives)等。本文的芯片类型以及时钟周期选定如下

set_part {xc7k160tfbg484-1} -tool vivadocreate_clock -period 10 -name default

到此,我们总结一下Vivado HLS会做哪些工作:

1.将高级语言C/C++代码转换成等价的RTL代码,并根据设定的时钟周期和芯片延迟信息,调度RTL的执行,并尽可能的将多个操作放在同一个时钟周期内执行;

2.根据Directive语句进行特定的优化;

3.使用接口综合语句指定数据传输所使用的总线协议。

3.Convolution design with Vivado HLS

下面,开始说卷积层加速的具体实现过程。主要涉及到以下几方面

3.1 片上资源

Vivado HLS最终综合形成的RTL代码需要在FPGA上执行。但FPGA片上缓存BRAM数量有限,而卷积层的参数量又是非常大的。一种解决方法是将大量的参数存储在DRAM上,循环分片计算输出特征图。下面是循环分片的代码,我们对输出特征图的行、列,输入通道数,输出通道数四个维度进行循环分片,从而保证FPGA片上资源能够满足使用。

r_channel_tiling:for(int r=0;r<R;r+=Tr){c_channel_tiling:for(int c=0;c<C;c+=Tc){out_channel_tiling:for(int cho=0;cho<CHout;cho+=Tout){in_channel_tiling:for(int chi=0;chi<CHin;chi+=Tin) {// compute}}}}

3.2 并行计算

FPGA相比于通过处理器CPU来说,它有着优秀的并行处理能力。因此我们对卷积运算过程并行化,相比于其它维度,输入通道和输出通道更容易实现并行化。如下所示,利用一条PIPELINE语句即可实现。

Kernel_Row:for(int kr=0;kr<K;kr++){Kernel_Col:for(int kc=0;kc<K;kc++){Row:for(int r=0;r<Tr;r++){Column:for(int c=0;c<Tc;c++){#pragma HLS PIPELINEOut_channel:for(int out=0;out<Tout;out++){in_channel:for(int in=0;in<Tin;in++){Out[out][r][c]+=In[in][S*r+kr][S*c+kc]*W[out][in][kr][kc];}}}}}}

我们希望PIPELINE下面的代码可以在一个周期内执行完成,但目前还达不到这样的效果。因为并行化后,一个周期内需要对同一数组进行多次读写,数组默认的端口数是不能满足该条件的。我们继续对数组进行优化。如下所示,在指定维度对数组展开,从而提供多端口读写能力

data_t In[Tin][S*Tr+K-S][S*Tc+K-S];#pragma HLS ARRAY_PARTITION variable=In complete dim=1data_t W[Tout][Tin][K][K];#pragma HLS ARRAY_PARTITION variable=W complete dim=1#pragma HLS ARRAY_PARTITION variable=W complete dim=2static data_t Out[Tout][Tr][Tc];#pragma HLS ARRAY_PARTITION variable=Out complete dim=1

到此,我们成功在FPGA上实现了卷积层的并行计算过程。但还不能说在FPGA上实现了卷积加速。计算能力有了,我们还缺少用来计算的数据。

3.3 数据传输

前面说过FPGA片上缓存资源有限,大量的参数是存储在DRAM上的。FPGA需要时,参数再通过总线从DRAM上传输到FPGA上。这里我们采用AXI4总线协议传输数据,Vivado HLS中是利用INTERFACE语句指定数据传输所使用的总线协议。

#pragma HLS INTERFACE m_axi depth=10800 port=In_addr bundle=BUS0#pragma HLS INTERFACE m_axi depth=55296 port=W_addr bundle=BUS2#pragma HLS INTERFACE m_axi depth=21632 port=Out_addr bundle=BUS3

并行计算需要大量的数据。可以利用DATAPACK语句提高总线带宽。

#pragma HLS DATA_PACK variable=In_addr#pragma HLS DATA_PACK variable=W_addr

3.4 任务级并行

数据读取,卷积计算,写回数据是在FPGA上执行卷积运算的三个过程。上面三个函数能否在一定程度上并行执行呢?答案是可以的。Vivado HLS提供了DATAFLOW语句实现任务级并行。至于任务级并行是什么呢,可以参考这里。我们实现时并没有直接使用DATAFLOW语句,而是用了(pingpong标记+if-else语句)实现的。综合后的效果与DATAFLOW语句基本等价。具体的实现过程可以参考源码,这里就不列出了。

4.Result

最后看一下综合后结果

4.1 卷积参数和分片大小

4.2 综合报告

4.3 资源使用

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
相关阅读
vivado hls 笔记

vivado hls 笔记

2019-05-03

Vivado HLS教程

Vivado HLS教程

2023-12-11

Vivado HLS基本应用

Vivado HLS基本应用

2021-07-15

一文了解Vivado HLS

一文了解Vivado HLS

2019-09-24