您现在的位置是:首页 > 数字电源 > 技术解析

手把手教你在FPGA实例上运行“Hello World”

时间:2017-09-13 来源:

前言

在4月19号的旧金山AWS技术峰会上,亚马逊CTO Werner Vogels宣布了多项AWS新功能,其中就包括众人期待已久的FPGA实例F1。

F1 实例配有最新的 16 nm Xilinx UltraScale Plus FPGA,目前有f1.2xlarge和f1.16xlarge两种类型,其中f1.2xlarge配备有1个FPGA卡, f1.16xlarge配备有8个FPGA卡。

使用 F1 实例部署硬件加速在许多高性能计算 (HPC) 应用程序中非常有用,可解决需要高带宽、增强型联网和较高计算能力的复杂科学、工程和业务问题。F1 实例尤其适用于有时间要求的应用程序,如临床基因组学、实时视频处理和财务风险分析。

因为这段时间都在学习神经网络,所以F1实例最吸引我的是在FPGA上部署神经网络模型,神经网络的前向计算以高频脉冲的方式同时发生在门电路构成的神经网络单元上,想想都让人激动。

不过FPGA这个东西确实太专业了,入门学习曲线不是一般的陡,启动F1实例运行一个简单的Hello World都需要折腾一番。

所以在这里记录一下自己启动F1实例运行Hello World的过程,供各位参考,希望可以让大家开始开始FPGA的旅程。

启动f1实例

f1实例的启动过程和一般的EC2启动过程类似,有关AWS账号的准备,EC2创建过程的细节请大家参考相关技术文档。以下只列出一些需要注意的地方。

测试时我选择了“弗吉尼亚北部”这个区域,也就是us-east-1区域。

启动f1实例时强烈推荐使用 AWS FPGA Developer AMI 镜像, FPGA Developer AMI 包括一个预先打包的工具开发环境,其中含有用于模拟 FPGA 设计、编译代码及构建和注册 AFI 的脚本和工具。

在启动实例的第一步,选择系统镜像的时候选择“AWS Marketplace”,然后搜索“FPGA”就可以找到FPGA Developer AMI, 该镜像在弗吉尼亚北部区域的ID为:ami-3afc6f2c,镜像选择界面截图如下。

 

 

启动过程中注意给你的实例指定一个IAM Role, 后续使用AWS CLI命令行工具的时候就需要配置静态的Access Key和Secret Key了。

还有就是安全组配置,缺省的22号端口保留打开状态,另外建议开3389端口,后续如果你希望使用远程连接的方式使用图形化界面需要用到这个端口。

还有一个不需要再强调的就是你启动的f1实例需要有公有IP。

系统登录

在f1实例启动后在EC2控制台上找到这台实例的公有IP地址,然后通过ssh命令连接该实例,注意使用的用户名是centos, ssh命令样例如下:

ssh -i ~/.ssh/ centos@

登录以后可以看到下面的信息:

___ ___ ___ _ ___ _____ __ _ __ __ ___

| __| _ / __| /_ | | __ / / /_ | / |_ _|

| _|| _/ (_ |/ _ | |) | _| V / / _ | |/| || |

|_| |_| ___/_/ _ |___/|___| _/ /_/ __| |_|___|

AMI Version: 1.2.0

Readme: /home/centos/src/README.md

GUI Setup Steps: /home/centos/src/GUI_README.md

AMI Release Notes: /home/centos/src/RELEASE_NOTES.md

Xilinx Tools: /opt/Xilinx/

Developer Support: https://github.com/aws/aws-fpga/blob/master/README.md#developer-support

注意这里提到的GUI设置说明文档: /home/centos/src/GUI_README.md,如果你后续希望使用图形化界面,请参考这个文档进行操作。

克隆AWS FPGA项目

在远程f1实例上创建一个工作目录,在该工作目录下执行以下命令克隆AWS FPGA 项目:

git clone https://github.com/aws/aws-fpga.git

执行完成以后可以看到一个aws-fpga目录

安装 FPGA SDK

进入aws-fpga目录,然后执行以下命令安装FPGA SDK:

source sdk_setup.sh

安装命令执行完以后会有以下输出,表示安装成功:

Done with SDK install.

Done with AWS SDK setup.

这个过程会安装好FPGA管理工具,通过这个管理工具可以查看FPGA卡的情况,列出FPGA卡上的镜像情况,还可以执行加载镜像等操作。

首先我们可以通过fpga-describe-local-image-slots命令查看FPGA卡的情况,这里就是FPGA的“image slot”的情况,具体命令请如下:

sudo fpga-describe-local-image-slots -H

在我的 f1.2xlarge 实例上有如下输出:

$ sudo fpga-describe-local-image-slots -H

Type FpgaImageSlot VendorId DeviceId DBDF

AFIDEVICE 0 0x1d0f 0x1042 0000:00:1d.0

这里列出的就是slot 0的情况,接着你可以使用fpga-describe-local-image-slots命令查看这个slot上的FPGA镜像情况:

sudo fpga-describe-local-image -S 0

其中参数 -S 用于指定希望查看的image slot,参数值就是FPGA image slot的编号。

如果你希望将新的FPGA镜像加载到一个image slot上, 你可以使用命令 fpga-load-local-image, 同时通过参数 -S指定image slot的编号,通过-I参数指定需要加载的FPGA镜像ID,如:

sudo fpga-load-local-image -S 0 -I agfi-0123456789abcdefg

有关FPGA管理工具的更多信息,请参考以下链接:

https://github.com/aws/aws-fpga/blob/master/sdk/userspace/fpga_mgmt_tool...

安装FPGA HDK

安装好FPGA的SDK以后就需要安装FPGA HDK了,具体的安装命令如下:

source hdk_setup.sh

这个过程稍长一点,可能需要5到10分钟,执行的命令的时候输出结果中也有提示:

AWS FPGA-INFO: This could take 5-10 minutes, please be patient!

如果一切正常,安装成功后会有如下信息:

AWS FPGA-INFO: DDR4 model build passed.

AWS FPGA-INFO: ATTENTION: Don't forget to set the CL_DIR variable for the directory of your Custom Logic.

AWS FPGA-INFO: AWS HDK setup PASSED.

如成功信息里提示的,如果你以后要构建自己的FPGA模块,需要将CL_DIR变量指向你的模块目录,我们在后续的步骤中会进行设置。

配置 AWS CLI

因为FPGA镜像创建过程需要使用AWS CLI命令行工具,所以我们需要提前配置好AWS CLI。

在我们使用的这个FPGA Developer AMI中AWS CLI命令行工具已经安装好了,如果你使用其它镜像需要手工安装AWS CLI的话请参考AWS CLI命令行工具的安装文档。

需要注意的时,虽然在FPGA Developer AMI中已经安装好了AWS CLI,但是这个版本不一定是最新的,所以建议通过以下命令先进行升级:

pip install --upgrade --user awscli

然后就通过以下命令启动AWS CLI配置过程:

aws configure

在配置AWS CLI的过程中一般需要提供Access Key和Secret Key,不过我们的f1实例在启动过程中制定了IAM Role, 而且我给这个IAM Role足够的权限,所以我们这里不需要配置静态的Access Key和Secret Key,我们要做的只是指定区域,这里我们指定区域为us-east-1。

$aws configure

AWS Access Key ID [None]:

AWS Secret Access Key [None]:

Default region name [None]: us-east-1

Default output format [None]:

构建DCP

安装好HDK,配置好工具,就可以开始跑样例了,这里我们使用AWS FPGA项目里的hello world样例,该样例在aws-fpga中的以下目录中:

./hdk/cl/examples/cl_hello_world

如之前安装过程中提到的,如果我们使用目录./hdk/cl/examples/cl_hello_world中的样例,我们需要设置CL_DIR变量指向./hdk/cl/examples/cl_hello_world目录,具体命令如下:

cd ./hdk/cl/examples/cl_hello_world

export CL_DIR=$(pwd)

接下来的工作需要使用Xilinx Vivado工具,所以我们需要检查一下vivado工具是否安装正常,具体命令如下:

$ vivado -mode batch

正常的输出如下:

****** Vivado v2017.1 (64-bit)

**** SW Build 1846317 on Fri Apr 14 18:54:47 MDT 2017

**** IP Build 1846188 on Fri Apr 14 20:52:08 MDT 2017

** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.

Sourcing tcl script '/opt/Xilinx/Vivado/2017.1/scripts/Vivado_init.tcl'

INFO: [Common 17-206] Exiting Vivado at Fri Apr 21 02:42:35 2017...

现在我们可以开始构建DCP了,构建命令在$CL_DIR/build/scripts中,文件名是aws_build_dcp_from_cl.sh,所以具体命令如下:

cd $CL_DIR/build/scripts

$ ./aws_build_dcp_from_cl.sh

需要注意的是,这个命令的运行时间比较长,需要几个小时的时间才能完成。为了避免ssh会话中断导致构建失败,样例的作者选择在后台运行建构过程。在我们运行aws_build_dcp_from_cl.sh命令之后,会马上获得以下输出,不过构建程序会在后台持续运行:

$ ./aws_build_dcp_from_cl.sh

AWS FPGA: Starting the design checkpoint build process

AWS FPGA: Checking for proper environment variables and build directories

Creating the reports directory

Creating the checkpointss directory

Creating the checkpoints/to_aws directory

AWS FPGA: Environment variables and directories are present. Checking for Vivado installation.

AWS FPGA: Build through Vivado is running as background process, this may take few hours.

AWS FPGA: Output is being redirected to 17_04_21-025018.nohup.out

AWS FPGA: If you have set your EMAIL environment variable and -notify is specified, you will receive a notification when complete.

AWS FPGA: (See $HDK_DIR/cl/examples/README.md for details)

在以上输出中我们可以注意到,构建日志会输出到文件xxxx.nohup.out中,所以我们可以定时查看这个日志文件从而了解构建进程.

当然,时不时跑过来看看日志文件看看是不是构建完成了并不是一个很有效的办法,如果你希望构建程序在结束的时候给你发一封邮件,可以使用-notify参数,使用-notify参数前需要通过以下命令设置SNS:

$ export EMAIL=your.email@example.com

$ ./$HDK_COMMON_DIR/scripts/notify_via_sns.py

有关-notify参数的更多信息请参考对应的READMD.md文件,本例中就不设置了,采用定时查看日志的笨办法。

在构建结束后,我们可以在xxxx.nohup.out文件中看到以下信息:

AWS FPGA: (07:00:53) Finished creating final tar file in to_aws directory.

然后你可以查看一下这个目录:$CL_DIR/build/checkpoints/to_aws,目录中会有打包好的tar文件,执行ls命令的结果如下:

$ ls checkpoints/to_aws

17_04_21-025018.Developer_CL.tar 17_04_21-025018.manifest.txt 17_04_21-025018.SH_CL_routed.dcp

上传文件到S3

在构建的dcp以后,我们需要将tar文件上传到S3上,然后才能通过AWS CLI命令构建FPGA image。

为了上传文件到S3上,我们需要创建对应的S3桶,这个过程可以通过AWS控制台完成,也可以使用AWS CLI命令行工具完成,有关S3的具体操作请参考相关文档。

本例使用AWS CLI来创建S3桶并上传文件,命令参考如下:

$ aws s3 mb s3:// --region us-east-1

$ aws s3 cp $CL_DIR/build/checkpoints/to_aws/*.Developer_CL.tar s3:////

接着我们还需要为日志文件创建一个目录,其实在S3上没有目录的概念,整个文件路径和文件名就是这个文件的key,所以样例中创建目录的方法就是直接上传一个空文件到我们需要的目录中,具体命令如下:

$ touch LOGS_FILES_GO_HERE.txt

$ aws s3 cp LOGS_FILES_GO_HERE.txt s3:////

因为我们上传的tar文件最后会交由AWS对应账号完成构建工作,同时构建日志还需要由AWS对应账号写回到我们的S3桶中,所以我们需要为我们的S3桶设置桶访问策略,让AWS账号可以访问这些文件和目录。具体的访问策略样例如下,我们需要把下面的策略配置拷贝到我们的S3桶的“访问策略”设置中。注意样例中的 和 等内容,要把它们修改成真实的桶名和对应路径。

{

"Version": "2012-10-17",

"Statement": [

{

"Sid": "Bucket level permissions",

"Effect": "Allow",

"Principal": {

"AWS": "arn:aws:iam::365015490807:root"

},

"Action": [

"s3:ListBucket"

],

"Resource": "arn:aws:s3:::"

},

{

"Sid": "Object read permissions",

"Effect": "Allow",

"Principal": {

"AWS": "arn:aws:iam::365015490807:root"

},

"Action": [

"s3:GetObject"

],

"Resource": "arn:aws:s3::://"

},

{

"Sid": "Folder write permissions",

"Effect": "Allow",

"Principal": {

"AWS": "arn:aws:iam::365015490807:root"

},

"Action": [

"s3:PutObject"

],

"Resource": "arn:aws:s3::://*"

}

]

}

设置完S3的桶访问策略以后我们需要验证一下策略写的对不对,不然策略写错了,AWS对应账号拿不到需要的tar文件,就不能成功构建FPGA image了,而且我们分析问题还不知道如何下手。

验证S3桶策略的脚本在下面这个文件里:

`aws-fpga/hdk/common/scripts/check_s3_bucket_policy.py`

如果执行出现INFO: Passed字样就表示策略设置正确。

不过在有些python环境下check_s3_bucket_policy.py运行会报下面这个错误:

AttributeError: PolicyStatement instance has no attribute 'principals_re'

发现这个错误的话需要手工改一下check_s3_bucket_policy.py文件。

用你习惯的编辑器打开文件check_s3_bucket_policy.py,然后找到下面的代码:

class PolicyStatement:

def __init__(self, statement, principal=None):

self.statement = statement

self.process_policy_statement(statement, principal)

self.principals_re = []

self.actions_re = []

self.notactions_re = []

self.resources_re = []

然后把self.process_policy_statement(statement, principal)这句放到其它变量设置之后,像下面这样:

class PolicyStatement:

def __init__(self, statement, principal=None):

self.statement = statement

self.principals_re = []

self.actions_re = []

self.notactions_re = []

self.resources_re = []

self.process_policy_statement(statement, principal)

然后就不会报错了,具体运行check_s3_bucket_policy.py命令的参考和对应输出如下:

$ check_s3_bucket_policy.py --dcp-bucket fpga.use1.damondeng.com --dcp-key fpgajarfile/17_04_21-025018.Developer_CL.tar

--logs-bucket fpga.use1.damondeng.com --logs-key logfile

INFO: Passed

一切准备好就可以开始运行 aws ec2 create-fpga-image 命令构建FPGA image了,命令参考如下:

$ aws ec2 create-fpga-image --name DamonFPGAOne

--description "Testing FPGA Image" --input-storage-location Bucket=fpga.use1.damondeng.com,Key=fpgajarfile/17_04_21-025018.Developer_CL.tar

--logs-storage-location Bucket=fpga.use1.damondeng.com,Key=logfile

如果你发现AWS CLI命令报下面这个错误,则你的AWS CLI版本不够,需要运行pip install --upgrade --user awscli进行升级:

Invalid choice: 'create-fpga-image', maybe you meant:

* create-image

*

运行正常的情况下你会获得类似这样的输出:

{

"FpgaImageId": "afi-046ead8eb3a0e3112",

"FpgaImageGlobalId": "agfi-06fdb0f3cea076195"

}

其中”FpgaImageId”是本区域唯一的image ID,”FpgaImageGlobalId”是全球唯一的image ID,后面我们加载FPGA image时要使用过的是全球唯一的”FpgaImageGlobalId”,以agfi开头。

开始构建FPGA image后需要等待一段时间,你可以查看你指定的保存日志的S3桶以了解进展。

如果你在日志目录里看到有个新目录产生,里面有个叫State的文件中出现{State=available} 字样就表明构建成功了。接着就可以加载你的FPGA image了。

在加载新的FPGA image之前记得先清除现有image:

sudo fpga-clear-local-image -S 0

接着通过以下命令加载FPGA image:

sudo fpga-load-local-image -S 0 -I agfi-06fdb0f3cea076195

如之前描述的,这里-S参数用于指定image slot,-I参数用于指定FPGA image的镜像ID,注意是全球唯一,以agfi开头的镜像ID。

为了检查FPGA image是否加载成功,可以使用fpga-describe-local-image命令,执行输出的样例如下:

$ sudo fpga-describe-local-image -S 0 -R -H

Type FpgaImageSlot FpgaImageId StatusName StatusCode ErrorName ErrorCode ShVersion

AFI 0 agfi-06fdb0f3cea076195 loaded 0 ok 0 0x04151701

Type FpgaImageSlot VendorId DeviceId DBDF

AFIDEVICE 0 0x1d0f 0xf000 0000:00:1d.0

其中可以看到镜像ID为agfi-06fdb0f3cea076195的状态是loaded,就是加载成功了。

最后我们就需要运行宿主机上的软件端来测试了,进入cd $CL_DIR/software/runtime/目录,这里有个写好的c的代码用于测试,运行以下命令编译软件测试端:

$ cd $CL_DIR/software/runtime/

$ make all

编译成功后通过./test_hello_world命令执行,以下是执行结果:

$ sudo ./test_hello_world

AFI PCI Vendor ID: 0x1d0f, Device ID 0xf000

===== Starting with peek_poke_example =====

register: 0xdeadbeef

Resulting value matched expected value 0xdeadbeef. It worked!

Developers are encourged to modify the Virtual DIP Switch by calling the linux shell

command to demonstrate how AWS FPGA Virtual DIP switches can be used to change a CustomLogic functionality:

$ fpga-set-virtual-dip-switch -S (slot-id) -D (16 digit setting)

In this example, setting a virtual DIP switch to zero clears the corresponding LED, even if the peek-poke example would set it to 1.

For instance:

# fpga-set-virtual-dip-switch -S 0 -D 1111111111111111

# fpga-get-virtual-led -S 0

FPGA slot id 0 have the following Virtual LED:

1010-1101-1101-1110

# fpga-set-virtual-dip-switch -S 0 -D 0000000000000000

# fpga-get-virtual-led -S 0

FPGA slot id 0 have the following Virtual LED:

0000-0000-0000-0000

这个样例有两部分,一部分是peek_poke部分,就是寄存器的读写。样例为了说明FPGA寄存器的功能是否起作用,将输入的比特位做了交换。

如./test_hello_world.c中的代码所描述的:

uint32_t value = 0xefbeadde;

uint32_t expected = 0xdeadbeef;

/* read it back and print it out; you should expect the byte order to be

* reversed (That's what this CL does) */

第二个部分是虚拟LED的使用,测试者可以通过FPGA管理工具设置virtual-dip开关,以类似掩码的形式影响虚拟LED的显示,比如,原来虚拟LED的输出是1010-1101-1101-1110我通过fpga-set-virtual-dip-switch 设置了 1111111100000000值, 虚拟LED的输出就是1010-1101-0000-0000:

[centos@ip-172-31-8-87 runtime]$ sudo fpga-set-virtual-dip-switch -S 0 -D 1111111100000000

[centos@ip-172-31-8-87 runtime]$ sudo fpga-get-virtual-led -S 0

FPGA slot id 0 have the following Virtual LED:

1010-1101-0000-0000

到这里我们的Hello World就成功啦,虽然比一搬的软件Hello World麻烦好多,但是要知道这里可是直接操控硬件喔。

后续工作

在跑完Hello World样例以后可能会有不少人想了解这个开发环境的图形化访问的问题。

如文中提到的,当你通过SSH登录到FPGA实例时,FPGA Developer AMI的欢迎文字中有提到GUI界面的设置。这里提到的方法概括起来就是在centos上启动xrdp,然后通过MS的远程桌面程序进行连接。

在centos端的命令拷贝如下:

sudo yum install -y kernel-devel # Needed to re-build ENA driver

sudo yum groupinstall -y "Server with GUI"

sudo systemctl set-default graphical.target

sudo yum -y install epel-release

sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.e...

sudo yum install -y xrdp tigervnc-server

sudo systemctl start xrdp

sudo systemctl enable xrdp

sudo systemctl disable firewalld

sudo systemctl stop firewalld

设置完记得给centos用户设置一个密码,否则远程桌面登录不了:

sudo passwd centos

当你通过远程桌面登录centos后,就可以看到图形化界面了。更多可以参考Jeff Bar的博客https://aws.amazon.com/blogs/aws/developer-preview-ec2-instances-f1-with-programmable-hardware/

以下是从该博客拷贝的远程图形界面截图:

 

 

最后希望大家可以在FPGA的世界里找到自己的方向,开始创建自己的芯片系统真是一件让人兴奋的事情。

作者介绍

AWS解决方案架构师;拥有15年IT 领域的工作经验,先后在IBM,RIM,Apple 等企业担任工程师、架构师等职位;目前就职于AWS,担任解决方案架构师一职。喜欢编程,喜欢各种编程语言,尤其喜欢Lisp。喜欢新技术,喜欢各种技术挑战,目前在集中精力学习分布式计算环境下的机器学习算法。

换一批

延伸阅读

[新鲜事] Ryzen运行部分FMA3测试会崩溃,AMD承诺固件修复

Ryzen运行部分FMA3测试会崩溃,AMD承诺固件修复

现在Ryzen处理器还真的被爆出一个bug——运行部分FMA3测试会导致系统锁定,AMD也确认了这个问题,已经承诺通过主板固件升级解决。......

关键字:Ryzen FMA3测试

[新鲜事] 国产厂商弯道超车AMOLED面板?京东方研发出5寸AMQLED显示屏

国产厂商弯道超车AMOLED面板?京东方研发出5寸AMQLED显示屏

中国厂商在LCD面板领域一度是烧钱运营,京东方(BOE)就过了很多年亏损的日子,不过现在京东方等国产LCD面板厂商算是熬出头了,去年Q4季度京东方出货的大尺寸LCD面板一跃成为世界第一,中国大陆公司的LCD产能已经超过台湾地区,逐渐赶超韩国......

关键字:京东方 AMQLED显示屏

[新鲜事] 惊呆了!黑客通过硬盘LED灯闪烁盗取信息隐私!

惊呆了!黑客通过硬盘LED灯闪烁盗取信息隐私!

黑客们通常都神通广大,但它们攻破严密的防御多数还是靠代码这一武器,不过现在有一批大牛要上天了,他们居然能从台式机上闪烁的LED灯搜集到敏感信息。......

关键字:硬盘LED灯 无人机 黑客

[新鲜事] 产能被苹果三星瓜分 今年华为仅8%设备能用上OLED

产能被苹果三星瓜分 今年华为仅8%设备能用上OLED

据外媒报道,近些年来OLED屏幕逐渐流行,厂商们都希望将其当作自家机器的新卖点,不过由于产能有限,想用上OLED屏幕必须靠“抢”。......

关键字:OLED屏幕 华为

[图酷] 无用发明之:LED火柴

无用发明之:LED火柴

我们今天来谈一谈什么是创新,在手机上加入摄像头是创新,声控手机少掉一些操作步骤也是创新,这些都是成功的创新,然而还有一些创新却让我们的生活变得更加麻烦。比如,不用点火的火柴。 Matchbox ......

关键字:
发表评论 共有条评论
用户名: 验证码:

双音发生器

双音发生器

两个555振荡器或定时器都可以配置成音频振荡器,分别用于单独的扬声器。一个双100kQ电……

音频动态噪音消除系统

音频动态噪音消除系统

U1是一种美国国家半导体公司生产的专用集成电路,用于自动适配宽带方案和听觉掩蔽技术……

RC电路波形全面分析汇总

RC电路波形全面分析汇总

RC电路在模拟电路、脉冲数字电路中得到广泛的应用,由于电路的形式以及信号源和R,C元……

项目外包