手把手教你在FPGA實(shí)例上運行“Hello World”
前言
本文引用地址:http://dyxdggzs.com/article/201709/364344.htm在4月19號的舊金山AWS技術(shù)峰會(huì )上,亞馬遜CTO Werner Vogels宣布了多項AWS新功能,其中就包括眾人期待已久的FPGA實(shí)例F1。
F1 實(shí)例配有最新的 16 nm Xilinx UltraScale Plus FPGA,目前有f1.2xlarge和f1.16xlarge兩種類(lèi)型,其中f1.2xlarge配備有1個(gè)FPGA卡, f1.16xlarge配備有8個(gè)FPGA卡。
使用 F1 實(shí)例部署硬件加速在許多高性能計算 (HPC) 應用程序中非常有用,可解決需要高帶寬、增強型聯(lián)網(wǎng)和較高計算能力的復雜科學(xué)、工程和業(yè)務(wù)問(wèn)題。F1 實(shí)例尤其適用于有時(shí)間要求的應用程序,如臨床基因組學(xué)、實(shí)時(shí)視頻處理和財務(wù)風(fēng)險分析。
因為這段時(shí)間都在學(xué)習神經(jīng)網(wǎng)絡(luò ),所以F1實(shí)例最吸引我的是在FPGA上部署神經(jīng)網(wǎng)絡(luò )模型,神經(jīng)網(wǎng)絡(luò )的前向計算以高頻脈沖的方式同時(shí)發(fā)生在門(mén)電路構成的神經(jīng)網(wǎng)絡(luò )單元上,想想都讓人激動(dòng)。
不過(guò)FPGA這個(gè)東西確實(shí)太專(zhuān)業(yè)了,入門(mén)學(xué)習曲線(xiàn)不是一般的陡,啟動(dòng)F1實(shí)例運行一個(gè)簡(jiǎn)單的Hello World都需要折騰一番。
所以在這里記錄一下自己?jiǎn)?dòng)F1實(shí)例運行Hello World的過(guò)程,供各位參考,希望可以讓大家開(kāi)始開(kāi)始FPGA的旅程。
啟動(dòng)f1實(shí)例
f1實(shí)例的啟動(dòng)過(guò)程和一般的EC2啟動(dòng)過(guò)程類(lèi)似,有關(guān)AWS賬號的準備,EC2創(chuàng )建過(guò)程的細節請大家參考相關(guān)技術(shù)文檔。以下只列出一些需要注意的地方。
測試時(shí)我選擇了“弗吉尼亞北部”這個(gè)區域,也就是us-east-1區域。
啟動(dòng)f1實(shí)例時(shí)強烈推薦使用 AWS FPGA Developer AMI 鏡像, FPGA Developer AMI 包括一個(gè)預先打包的工具開(kāi)發(fā)環(huán)境,其中含有用于模擬 FPGA 設計、編譯代碼及構建和注冊 AFI 的腳本和工具。
在啟動(dòng)實(shí)例的第一步,選擇系統鏡像的時(shí)候選擇“AWS Marketplace”,然后搜索“FPGA”就可以找到FPGA Developer AMI, 該鏡像在弗吉尼亞北部區域的ID為:ami-3afc6f2c,鏡像選擇界面截圖如下。

啟動(dòng)過(guò)程中注意給你的實(shí)例指定一個(gè)IAM Role, 后續使用AWS CLI命令行工具的時(shí)候就需要配置靜態(tài)的Access Key和Secret Key了。
還有就是安全組配置,缺省的22號端口保留打開(kāi)狀態(tài),另外建議開(kāi)3389端口,后續如果你希望使用遠程連接的方式使用圖形化界面需要用到這個(gè)端口。
還有一個(gè)不需要再強調的就是你啟動(dòng)的f1實(shí)例需要有公有IP。
系統登錄
在f1實(shí)例啟動(dòng)后在EC2控制臺上找到這臺實(shí)例的公有IP地址,然后通過(guò)ssh命令連接該實(shí)例,注意使用的用戶(hù)名是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設置說(shuō)明文檔: /home/centos/src/GUI_README.md,如果你后續希望使用圖形化界面,請參考這個(gè)文檔進(jìn)行操作。
克隆AWS FPGA項目
在遠程f1實(shí)例上創(chuàng )建一個(gè)工作目錄,在該工作目錄下執行以下命令克隆AWS FPGA 項目:
git clone https://github.com/aws/aws-fpga.git
執行完成以后可以看到一個(gè)aws-fpga目錄
安裝 FPGA SDK
進(jìn)入aws-fpga目錄,然后執行以下命令安裝FPGA SDK:
source sdk_setup.sh
安裝命令執行完以后會(huì )有以下輸出,表示安裝成功:
Done with SDK install.
Done with AWS SDK setup.
這個(gè)過(guò)程會(huì )安裝好FPGA管理工具,通過(guò)這個(gè)管理工具可以查看FPGA卡的情況,列出FPGA卡上的鏡像情況,還可以執行加載鏡像等操作。
首先我們可以通過(guò)fpga-describe-local-image-slots命令查看FPGA卡的情況,這里就是FPGA的“image slot”的情況,具體命令請如下:
sudo fpga-describe-local-image-slots -H
在我的 f1.2xlarge 實(shí)例上有如下輸出:
$ sudo fpga-describe-local-image-slots -H
Type FpgaImageSlot VendorId DeviceId DBDF
AFIDEVICE 0 0x1d0f 0x1042 0000:00:1d.0
這里列出的就是slot 0的情況,接著(zhù)你可以使用fpga-describe-local-image-slots命令查看這個(gè)slot上的FPGA鏡像情況:
sudo fpga-describe-local-image -S 0
其中參數 -S 用于指定希望查看的image slot,參數值就是FPGA image slot的編號。
如果你希望將新的FPGA鏡像加載到一個(gè)image slot上, 你可以使用命令 fpga-load-local-image, 同時(shí)通過(guò)參數 -S指定image slot的編號,通過(guò)-I參數指定需要加載的FPGA鏡像ID,如:
sudo fpga-load-local-image -S 0 -I agfi-0123456789abcdefg
有關(guān)FPGA管理工具的更多信息,請參考以下鏈接:
https://github.com/aws/aws-fpga/blob/master/sdk/userspace/fpga_mgmt_tool...
安裝FPGA HDK
安裝好FPGA的SDK以后就需要安裝FPGA HDK了,具體的安裝命令如下:
source hdk_setup.sh
這個(gè)過(guò)程稍長(cháng)一點(diǎn),可能需要5到10分鐘,執行的命令的時(shí)候輸出結果中也有提示:
AWS FPGA-INFO: This could take 5-10 minutes, please be patient!
如果一切正常,安裝成功后會(huì )有如下信息:
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變量指向你的模塊目錄,我們在后續的步驟中會(huì )進(jìn)行設置。
配置 AWS CLI
因為FPGA鏡像創(chuàng )建過(guò)程需要使用AWS CLI命令行工具,所以我們需要提前配置好AWS CLI。
在我們使用的這個(gè)FPGA Developer AMI中AWS CLI命令行工具已經(jīng)安裝好了,如果你使用其它鏡像需要手工安裝AWS CLI的話(huà)請參考AWS CLI命令行工具的安裝文檔。
需要注意的時(shí),雖然在FPGA Developer AMI中已經(jīng)安裝好了AWS CLI,但是這個(gè)版本不一定是最新的,所以建議通過(guò)以下命令先進(jìn)行升級:
pip install --upgrade --user awscli
然后就通過(guò)以下命令啟動(dòng)AWS CLI配置過(guò)程:
aws configure
在配置AWS CLI的過(guò)程中一般需要提供Access Key和Secret Key,不過(guò)我們的f1實(shí)例在啟動(dòng)過(guò)程中制定了IAM Role, 而且我給這個(gè)IAM Role足夠的權限,所以我們這里不需要配置靜態(tài)的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,配置好工具,就可以開(kāi)始跑樣例了,這里我們使用AWS FPGA項目里的hello world樣例,該樣例在aws-fpga中的以下目錄中:
./hdk/cl/examples/cl_hello_world
如之前安裝過(guò)程中提到的,如果我們使用目錄./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)
接下來(lái)的工作需要使用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...
現在我們可以開(kāi)始構建DCP了,構建命令在$CL_DIR/build/scripts中,文件名是aws_build_dcp_from_cl.sh,所以具體命令如下:
cd $CL_DIR/build/scripts
$ ./aws_build_dcp_from_cl.sh
需要注意的是,這個(gè)命令的運行時(shí)間比較長(cháng),需要幾個(gè)小時(shí)的時(shí)間才能完成。為了避免ssh會(huì )話(huà)中斷導致構建失敗,樣例的作者選擇在后臺運行建構過(guò)程。在我們運行aws_build_dcp_from_cl.sh命令之后,會(huì )馬上獲得以下輸出,不過(guò)構建程序會(huì )在后臺持續運行:
$ ./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)
在以上輸出中我們可以注意到,構建日志會(huì )輸出到文件xxxx.nohup.out中,所以我們可以定時(shí)查看這個(gè)日志文件從而了解構建進(jìn)程.
當然,時(shí)不時(shí)跑過(guò)來(lái)看看日志文件看看是不是構建完成了并不是一個(gè)很有效的辦法,如果你希望構建程序在結束的時(shí)候給你發(fā)一封郵件,可以使用-notify參數,使用-notify參數前需要通過(guò)以下命令設置SNS:
$ export EMAIL=your.email@example.com
$ ./$HDK_COMMON_DIR/scripts/notify_via_sns.py
有關(guān)-notify參數的更多信息請參考對應的READMD.md文件,本例中就不設置了,采用定時(shí)查看日志的笨辦法。
在構建結束后,我們可以在xxxx.nohup.out文件中看到以下信息:
AWS FPGA: (07:00:53) Finished creating final tar file in to_aws directory.
然后你可以查看一下這個(gè)目錄:$CL_DIR/build/checkpoints/to_aws,目錄中會(huì )有打包好的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上,然后才能通過(guò)AWS CLI命令構建FPGA image。
為了上傳文件到S3上,我們需要創(chuàng )建對應的S3桶,這個(gè)過(guò)程可以通過(guò)AWS控制臺完成,也可以使用AWS CLI命令行工具完成,有關(guān)S3的具體操作請參考相關(guān)文檔。
本例使用AWS CLI來(lái)創(chuàng )建S3桶并上傳文件,命令參考如下:
$ aws s3 mb s3:// --region us-east-1
$ aws s3 cp $CL_DIR/build/checkpoints/to_aws/*.Developer_CL.tar s3:////
接著(zhù)我們還需要為日志文件創(chuàng )建一個(gè)目錄,其實(shí)在S3上沒(méi)有目錄的概念,整個(gè)文件路徑和文件名就是這個(gè)文件的key,所以樣例中創(chuàng )建目錄的方法就是直接上傳一個(gè)空文件到我們需要的目錄中,具體命令如下:
$ touch LOGS_FILES_GO_HERE.txt
$ aws s3 cp LOGS_FILES_GO_HERE.txt s3:////
因為我們上傳的tar文件最后會(huì )交由AWS對應賬號完成構建工作,同時(shí)構建日志還需要由AWS對應賬號寫(xiě)回到我們的S3桶中,所以我們需要為我們的S3桶設置桶訪(fǎng)問(wèn)策略,讓AWS賬號可以訪(fǎng)問(wèn)這些文件和目錄。具體的訪(fǎng)問(wèn)策略樣例如下,我們需要把下面的策略配置拷貝到我們的S3桶的“訪(fǎng)問(wèn)策略”設置中。注意樣例中的 和 等內容,要把它們修改成真實(shí)的桶名和對應路徑。
{
"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的桶訪(fǎng)問(wèn)策略以后我們需要驗證一下策略寫(xiě)的對不對,不然策略寫(xiě)錯了,AWS對應賬號拿不到需要的tar文件,就不能成功構建FPGA image了,而且我們分析問(wèn)題還不知道如何下手。
驗證S3桶策略的腳本在下面這個(gè)文件里:
`aws-fpga/hdk/common/scripts/check_s3_bucket_policy.py`
如果執行出現INFO: Passed字樣就表示策略設置正確。
不過(guò)在有些python環(huán)境下check_s3_bucket_policy.py運行會(huì )報下面這個(gè)錯誤:
AttributeError: PolicyStatement instance has no attribute 'principals_re'
發(fā)現這個(gè)錯誤的話(huà)需要手工改一下check_s3_bucket_policy.py文件。
用你習慣的編輯器打開(kāi)文件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)
然后就不會(huì )報錯了,具體運行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
一切準備好就可以開(kāi)始運行 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
如果你發(fā)現AWS CLI命令報下面這個(gè)錯誤,則你的AWS CLI版本不夠,需要運行pip install --upgrade --user awscli進(jìn)行升級:
Invalid choice: 'create-fpga-image', maybe you meant:
* create-image
*
運行正常的情況下你會(huì )獲得類(lèi)似這樣的輸出:
{
"FpgaImageId": "afi-046ead8eb3a0e3112",
"FpgaImageGlobalId": "agfi-06fdb0f3cea076195"
}
其中”FpgaImageId”是本區域唯一的image ID,”FpgaImageGlobalId”是全球唯一的image ID,后面我們加載FPGA image時(shí)要使用過(guò)的是全球唯一的”FpgaImageGlobalId”,以agfi開(kāi)頭。
開(kāi)始構建FPGA image后需要等待一段時(shí)間,你可以查看你指定的保存日志的S3桶以了解進(jìn)展。
如果你在日志目錄里看到有個(gè)新目錄產(chǎn)生,里面有個(gè)叫State的文件中出現{State=available} 字樣就表明構建成功了。接著(zhù)就可以加載你的FPGA image了。
在加載新的FPGA image之前記得先清除現有image:
sudo fpga-clear-local-image -S 0
接著(zhù)通過(guò)以下命令加載FPGA image:
sudo fpga-load-local-image -S 0 -I agfi-06fdb0f3cea076195
如之前描述的,這里-S參數用于指定image slot,-I參數用于指定FPGA image的鏡像ID,注意是全球唯一,以agfi開(kāi)頭的鏡像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的狀態(tài)是loaded,就是加載成功了。
最后我們就需要運行宿主機上的軟件端來(lái)測試了,進(jìn)入cd $CL_DIR/software/runtime/目錄,這里有個(gè)寫(xiě)好的c的代碼用于測試,運行以下命令編譯軟件測試端:
$ cd $CL_DIR/software/runtime/
$ make all
編譯成功后通過(guò)./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
這個(gè)樣例有兩部分,一部分是peek_poke部分,就是寄存器的讀寫(xiě)。樣例為了說(shuō)明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) */
第二個(gè)部分是虛擬LED的使用,測試者可以通過(guò)FPGA管理工具設置virtual-dip開(kāi)關(guān),以類(lèi)似掩碼的形式影響虛擬LED的顯示,比如,原來(lái)虛擬LED的輸出是1010-1101-1101-1110我通過(guò)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樣例以后可能會(huì )有不少人想了解這個(gè)開(kāi)發(fā)環(huán)境的圖形化訪(fǎng)問(wèn)的問(wèn)題。
如文中提到的,當你通過(guò)SSH登錄到FPGA實(shí)例時(shí),FPGA Developer AMI的歡迎文字中有提到GUI界面的設置。這里提到的方法概括起來(lái)就是在centos上啟動(dòng)xrdp,然后通過(guò)MS的遠程桌面程序進(jìn)行連接。
在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用戶(hù)設置一個(gè)密碼,否則遠程桌面登錄不了:
sudo passwd centos
當你通過(guò)遠程桌面登錄centos后,就可以看到圖形化界面了。更多可以參考Jeff Bar的博客https://aws.amazon.com/blogs/aws/developer-preview-ec2-instances-f1-with-programmable-hardware/
以下是從該博客拷貝的遠程圖形界面截圖:

最后希望大家可以在FPGA的世界里找到自己的方向,開(kāi)始創(chuàng )建自己的芯片系統真是一件讓人興奮的事情。
作者介紹
AWS解決方案架構師;擁有15年IT 領(lǐng)域的工作經(jīng)驗,先后在IBM,RIM,Apple 等企業(yè)擔任工程師、架構師等職位;目前就職于A(yíng)WS,擔任解決方案架構師一職。喜歡編程,喜歡各種編程語(yǔ)言,尤其喜歡Lisp。喜歡新技術(shù),喜歡各種技術(shù)挑戰,目前在集中精力學(xué)習分布式計算環(huán)境下的機器學(xué)習算法。
評論