手把手教你在FPGA實例上運(yùn)行“Hello World”
前言
本文引用地址:http://m.butianyuan.cn/article/201709/364344.htm在4月19號的舊金山AWS技術(shù)峰會上,亞馬遜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) 應(yīng)用程序中非常有用,可解決需要高帶寬、增強(qiáng)型聯(lián)網(wǎng)和較高計算能力的復(fù)雜科學(xué)、工程和業(yè)務(wù)問題。F1 實例尤其適用于有時間要求的應(yīng)用程序,如臨床基因組學(xué)、實時視頻處理和財務(wù)風(fēng)險分析。
因為這段時間都在學(xué)習(xí)神經(jīng)網(wǎng)絡(luò),所以F1實例最吸引我的是在FPGA上部署神經(jīng)網(wǎng)絡(luò)模型,神經(jīng)網(wǎng)絡(luò)的前向計算以高頻脈沖的方式同時發(fā)生在門電路構(gòu)成的神經(jīng)網(wǎng)絡(luò)單元上,想想都讓人激動。
不過FPGA這個東西確實太專業(yè)了,入門學(xué)習(xí)曲線不是一般的陡,啟動F1實例運(yùn)行一個簡單的Hello World都需要折騰一番。
所以在這里記錄一下自己啟動F1實例運(yùn)行Hello World的過程,供各位參考,希望可以讓大家開始開始FPGA的旅程。
啟動f1實例
f1實例的啟動過程和一般的EC2啟動過程類似,有關(guān)AWS賬號的準(zhǔn)備,EC2創(chuàng)建過程的細(xì)節(jié)請大家參考相關(guān)技術(shù)文檔。以下只列出一些需要注意的地方。
測試時我選擇了“弗吉尼亞北部”這個區(qū)域,也就是us-east-1區(qū)域。
啟動f1實例時強(qiáng)烈推薦使用 AWS FPGA Developer AMI 鏡像, FPGA Developer AMI 包括一個預(yù)先打包的工具開發(fā)環(huán)境,其中含有用于模擬 FPGA 設(shè)計、編譯代碼及構(gòu)建和注冊 AFI 的腳本和工具。
在啟動實例的第一步,選擇系統(tǒng)鏡像的時候選擇“AWS Marketplace”,然后搜索“FPGA”就可以找到FPGA Developer AMI, 該鏡像在弗吉尼亞北部區(qū)域的ID為:ami-3afc6f2c,鏡像選擇界面截圖如下。
啟動過程中注意給你的實例指定一個IAM Role, 后續(xù)使用AWS CLI命令行工具的時候就需要配置靜態(tài)的Access Key和Secret Key了。
還有就是安全組配置,缺省的22號端口保留打開狀態(tài),另外建議開3389端口,后續(xù)如果你希望使用遠(yuǎn)程連接的方式使用圖形化界面需要用到這個端口。
還有一個不需要再強(qiáng)調(diào)的就是你啟動的f1實例需要有公有IP。
系統(tǒng)登錄
在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設(shè)置說明文檔: /home/centos/src/GUI_README.md,如果你后續(xù)希望使用圖形化界面,請參考這個文檔進(jìn)行操作。
克隆AWS FPGA項目
在遠(yuǎn)程f1實例上創(chuàng)建一個工作目錄,在該工作目錄下執(zhí)行以下命令克隆AWS FPGA 項目:
git clone https://github.com/aws/aws-fpga.git
執(zhí)行完成以后可以看到一個aws-fpga目錄
安裝 FPGA SDK
進(jìn)入aws-fpga目錄,然后執(zhí)行以下命令安裝FPGA SDK:
source sdk_setup.sh
安裝命令執(zhí)行完以后會有以下輸出,表示安裝成功:
Done with SDK install.
Done with AWS SDK setup.
這個過程會安裝好FPGA管理工具,通過這個管理工具可以查看FPGA卡的情況,列出FPGA卡上的鏡像情況,還可以執(zhí)行加載鏡像等操作。
首先我們可以通過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
其中參數(shù) -S 用于指定希望查看的image slot,參數(shù)值就是FPGA image slot的編號。
如果你希望將新的FPGA鏡像加載到一個image slot上, 你可以使用命令 fpga-load-local-image, 同時通過參數(shù) -S指定image slot的編號,通過-I參數(shù)指定需要加載的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
這個過程稍長一點,可能需要5到10分鐘,執(zhí)行的命令的時候輸出結(jié)果中也有提示:
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.
如成功信息里提示的,如果你以后要構(gòu)建自己的FPGA模塊,需要將CL_DIR變量指向你的模塊目錄,我們在后續(xù)的步驟中會進(jìn)行設(shè)置。
配置 AWS CLI
因為FPGA鏡像創(chuàng)建過程需要使用AWS CLI命令行工具,所以我們需要提前配置好AWS CLI。
在我們使用的這個FPGA Developer AMI中AWS CLI命令行工具已經(jīng)安裝好了,如果你使用其它鏡像需要手工安裝AWS CLI的話請參考AWS CLI命令行工具的安裝文檔。
需要注意的時,雖然在FPGA Developer AMI中已經(jīng)安裝好了AWS CLI,但是這個版本不一定是最新的,所以建議通過以下命令先進(jìn)行升級:
pip install --upgrade --user awscli
然后就通過以下命令啟動AWS CLI配置過程:
aws configure
在配置AWS CLI的過程中一般需要提供Access Key和Secret Key,不過我們的f1實例在啟動過程中制定了IAM Role, 而且我給這個IAM Role足夠的權(quán)限,所以我們這里不需要配置靜態(tài)的Access Key和Secret Key,我們要做的只是指定區(qū)域,這里我們指定區(qū)域為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]:
構(gòu)建DCP
安裝好HDK,配置好工具,就可以開始跑樣例了,這里我們使用AWS FPGA項目里的hello world樣例,該樣例在aws-fpga中的以下目錄中:
./hdk/cl/examples/cl_hello_world
如之前安裝過程中提到的,如果我們使用目錄./hdk/cl/examples/cl_hello_world中的樣例,我們需要設(shè)置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...
現(xiàn)在我們可以開始構(gòu)建DCP了,構(gòu)建命令在$CL_DIR/build/scripts中,文件名是aws_build_dcp_from_cl.sh,所以具體命令如下:
cd $CL_DIR/build/scripts
$ ./aws_build_dcp_from_cl.sh
需要注意的是,這個命令的運(yùn)行時間比較長,需要幾個小時的時間才能完成。為了避免ssh會話中斷導(dǎo)致構(gòu)建失敗,樣例的作者選擇在后臺運(yùn)行建構(gòu)過程。在我們運(yùn)行aws_build_dcp_from_cl.sh命令之后,會馬上獲得以下輸出,不過構(gòu)建程序會在后臺持續(xù)運(yùn)行:
$ ./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)
在以上輸出中我們可以注意到,構(gòu)建日志會輸出到文件xxxx.nohup.out中,所以我們可以定時查看這個日志文件從而了解構(gòu)建進(jìn)程.
當(dāng)然,時不時跑過來看看日志文件看看是不是構(gòu)建完成了并不是一個很有效的辦法,如果你希望構(gòu)建程序在結(jié)束的時候給你發(fā)一封郵件,可以使用-notify參數(shù),使用-notify參數(shù)前需要通過以下命令設(shè)置SNS:
$ export EMAIL=your.email@example.com
$ ./$HDK_COMMON_DIR/scripts/notify_via_sns.py
有關(guān)-notify參數(shù)的更多信息請參考對應(yīng)的READMD.md文件,本例中就不設(shè)置了,采用定時查看日志的笨辦法。
在構(gòu)建結(jié)束后,我們可以在xxxx.nohup.out文件中看到以下信息:
AWS FPGA: (07:00:53) Finished creating final tar file in to_aws directory.
然后你可以查看一下這個目錄:$CL_DIR/build/checkpoints/to_aws,目錄中會有打包好的tar文件,執(zhí)行l(wèi)s命令的結(jié)果如下:
$ 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
在構(gòu)建的dcp以后,我們需要將tar文件上傳到S3上,然后才能通過AWS CLI命令構(gòu)建FPGA image。
為了上傳文件到S3上,我們需要創(chuàng)建對應(yīng)的S3桶,這個過程可以通過AWS控制臺完成,也可以使用AWS CLI命令行工具完成,有關(guān)S3的具體操作請參考相關(guān)文檔。
本例使用AWS CLI來創(chuàng)建S3桶并上傳文件,命令參考如下:
$ aws s3 mb s3:// --region us-east-1
$ aws s3 cp $CL_DIR/build/checkpoints/to_aws/*.Developer_CL.tar s3:////
接著我們還需要為日志文件創(chuàng)建一個目錄,其實在S3上沒有目錄的概念,整個文件路徑和文件名就是這個文件的key,所以樣例中創(chuàng)建目錄的方法就是直接上傳一個空文件到我們需要的目錄中,具體命令如下:
$ touch LOGS_FILES_GO_HERE.txt
$ aws s3 cp LOGS_FILES_GO_HERE.txt s3:////
因為我們上傳的tar文件最后會交由AWS對應(yīng)賬號完成構(gòu)建工作,同時構(gòu)建日志還需要由AWS對應(yīng)賬號寫回到我們的S3桶中,所以我們需要為我們的S3桶設(shè)置桶訪問策略,讓AWS賬號可以訪問這些文件和目錄。具體的訪問策略樣例如下,我們需要把下面的策略配置拷貝到我們的S3桶的“訪問策略”設(shè)置中。注意樣例中的 和 等內(nèi)容,要把它們修改成真實的桶名和對應(yīng)路徑。
{
"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::://*"
}
]
}
設(shè)置完S3的桶訪問策略以后我們需要驗證一下策略寫的對不對,不然策略寫錯了,AWS對應(yīng)賬號拿不到需要的tar文件,就不能成功構(gòu)建FPGA image了,而且我們分析問題還不知道如何下手。
驗證S3桶策略的腳本在下面這個文件里:
`aws-fpga/hdk/common/scripts/check_s3_bucket_policy.py`
如果執(zhí)行出現(xiàn)INFO: Passed字樣就表示策略設(shè)置正確。
不過在有些python環(huán)境下check_s3_bucket_policy.py運(yùn)行會報下面這個錯誤:
AttributeError: PolicyStatement instance has no attribute 'principals_re'
發(fā)現(xiàn)這個錯誤的話需要手工改一下check_s3_bucket_policy.py文件。
用你習(xí)慣的編輯器打開文件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)這句放到其它變量設(shè)置之后,像下面這樣:
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)
然后就不會報錯了,具體運(yùn)行check_s3_bucket_policy.py命令的參考和對應(yīng)輸出如下:
$ 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
一切準(zhǔn)備好就可以開始運(yùn)行 aws ec2 create-fpga-image 命令構(gòu)建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ā)現(xiàn)AWS CLI命令報下面這個錯誤,則你的AWS CLI版本不夠,需要運(yùn)行pip install --upgrade --user awscli進(jìn)行升級:
Invalid choice: 'create-fpga-image', maybe you meant:
* create-image
*
運(yùn)行正常的情況下你會獲得類似這樣的輸出:
{
"FpgaImageId": "afi-046ead8eb3a0e3112",
"FpgaImageGlobalId": "agfi-06fdb0f3cea076195"
}
其中”FpgaImageId”是本區(qū)域唯一的image ID,”FpgaImageGlobalId”是全球唯一的image ID,后面我們加載FPGA image時要使用過的是全球唯一的”FpgaImageGlobalId”,以agfi開頭。
開始構(gòu)建FPGA image后需要等待一段時間,你可以查看你指定的保存日志的S3桶以了解進(jìn)展。
如果你在日志目錄里看到有個新目錄產(chǎn)生,里面有個叫State的文件中出現(xiàn){State=available} 字樣就表明構(gòu)建成功了。接著就可以加載你的FPGA image了。
在加載新的FPGA image之前記得先清除現(xiàn)有image:
sudo fpga-clear-local-image -S 0
接著通過以下命令加載FPGA image:
sudo fpga-load-local-image -S 0 -I agfi-06fdb0f3cea076195
如之前描述的,這里-S參數(shù)用于指定image slot,-I參數(shù)用于指定FPGA image的鏡像ID,注意是全球唯一,以agfi開頭的鏡像ID。
為了檢查FPGA image是否加載成功,可以使用fpga-describe-local-image命令,執(zhí)行輸出的樣例如下:
$ 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,就是加載成功了。
最后我們就需要運(yùn)行宿主機(jī)上的軟件端來測試了,進(jìn)入cd $CL_DIR/software/runtime/目錄,這里有個寫好的c的代碼用于測試,運(yùn)行以下命令編譯軟件測試端:
$ cd $CL_DIR/software/runtime/
$ make all
編譯成功后通過./test_hello_world命令執(zhí)行,以下是執(zhí)行結(jié)果:
$ 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管理工具設(shè)置virtual-dip開關(guān),以類似掩碼的形式影響虛擬LED的顯示,比如,原來虛擬LED的輸出是1010-1101-1101-1110我通過fpga-set-virtual-dip-switch 設(shè)置了 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麻煩好多,但是要知道這里可是直接操控硬件喔。
后續(xù)工作
在跑完Hello World樣例以后可能會有不少人想了解這個開發(fā)環(huán)境的圖形化訪問的問題。
如文中提到的,當(dāng)你通過SSH登錄到FPGA實例時,F(xiàn)PGA Developer AMI的歡迎文字中有提到GUI界面的設(shè)置。這里提到的方法概括起來就是在centos上啟動xrdp,然后通過MS的遠(yuǎn)程桌面程序進(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
設(shè)置完記得給centos用戶設(shè)置一個密碼,否則遠(yuǎn)程桌面登錄不了:
sudo passwd centos
當(dāng)你通過遠(yuǎn)程桌面登錄centos后,就可以看到圖形化界面了。更多可以參考Jeff Bar的博客https://aws.amazon.com/blogs/aws/developer-preview-ec2-instances-f1-with-programmable-hardware/
以下是從該博客拷貝的遠(yuǎn)程圖形界面截圖:
最后希望大家可以在FPGA的世界里找到自己的方向,開始創(chuàng)建自己的芯片系統(tǒng)真是一件讓人興奮的事情。
作者介紹
AWS解決方案架構(gòu)師;擁有15年IT 領(lǐng)域的工作經(jīng)驗,先后在IBM,RIM,Apple 等企業(yè)擔(dān)任工程師、架構(gòu)師等職位;目前就職于AWS,擔(dān)任解決方案架構(gòu)師一職。喜歡編程,喜歡各種編程語言,尤其喜歡Lisp。喜歡新技術(shù),喜歡各種技術(shù)挑戰(zhàn),目前在集中精力學(xué)習(xí)分布式計算環(huán)境下的機(jī)器學(xué)習(xí)算法。
評論