AWSのFPGAインスタンス用サンプルカスタムロジックcl_hello_worldのAFIを構築してみました #fpga

AWS

AWSのFPGAを搭載したEC2インスタンスであるF1インスタンス用カスタムロジック(CL)のサンプルをビルドして、AFI(Amazon FPGA Image)の構築手順を試してみましたのでご報告します。

はじめに

先日書きましたFPGAの開発ツールでサンプルをビルドする手順ですは、ごく単純なHDL(Hardware Description Language)のサンプルで、特にAWS F1インスタンス用というわけではありませんでした。F1インスタンスで何か有意な処理をさせようとするには、FPGAとCPUやメモリの間でデータのやりとりを行う必要があり、それなりの中身が必要なはずです。探してみるとちゃんとサンプルがありましたので、今回はこれをビルド(合成)してみました。手順が長くなりましたので、今回はビルドとイメージの作成までを説明します。完成したイメージをロードして動かしてみるのは次の記事にしたいと思います。

今回の手順の概略は以下のとおりです。

  1. EC2インスタンスを起動する
  2. SDKをダウンロードする
  3. ビルドする
  4. AFI(Amazon FPGA Image)を作成する

EC2インスタンスを起動する

FPGA Developer AMIを使うため、インスタンスをLaunchします。前回同様、AMI MarketplaceからFPGAを選びます。インスタンスタイプは、今回はオススメに従ってc4.4xlargeを使うことにします。デフォルトでc4.4xlargeにチェックが入っていますので、素直にこれに従います。あとはデフォルトのままでOKです。

EC2_Management_Console fpga-ami-c4.4xlarge

SDKをダウンロードする

EC2インスタンスが起動してから、SSHでログインします。AWS F1インスタンス用のSDKは、githubで提供されていますのでgithubからcloneします。

$ ssh -i your-private-key.pem centos@ec2-XX-XXX-XX-XXX.compute-1.amazonaws.com
Last login: Thu Apr 20 16:43:01 2017 from 72-21-196-69.amazon.com
 ___ ___  ___   _     ___  _____   __    _   __  __ ___
| __| _ \/ __| /_\   |   \| __\ \ / /   /_\ |  \/  |_ _|
| _||  _/ (_ |/ _ \  | |) | _| \ V /   / _ \| |\/| || |
|_| |_|  \___/_/ \_\ |___/|___| \_/   /_/ \_\_|  |_|___|
AMI Version:        1.2.1
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
[centos@ip-172-31-21-121 ~]$

ディレクトリをsrc/project_dataに移動して、https://github.com/aws/aws-fpga.git からgit cloneします。

$ cd src/project_data/
$ git clone https://github.com/aws/aws-fpga.git
Cloning into 'aws-fpga'...
remote: Counting objects: 3007, done.
remote: Compressing objects: 100% (184/184), done.
remote: Total 3007 (delta 120), reused 73 (delta 73), pack-reused 2750
Receiving objects: 100% (3007/3007), 136.25 MiB | 5.31 MiB/s, done.
Resolving deltas: 100% (1474/1474), done.
Checking out files: 100% (1379/1379), done.

中身を確認してみます。HDKがハードウェアの開発キット、SDKはソフトウェアの開発キットです。今回使うサンプルはHDKに入っています。

$ cd aws-fpga/
$ ls -l
total 96
-rw-rw-r-- 1 centos centos 28471 May  2 03:58 FAQs.md
drwxrwxr-x 5 centos centos  4096 May  2 03:58 hdk
-rw-rw-r-- 1 centos centos  8892 May  2 03:58 hdk_setup.sh
-rw-rw-r-- 1 centos centos 11364 May  2 03:58 LICENSE.txt
-rw-rw-r-- 1 centos centos  6921 May  2 03:58 README.md
-rw-rw-r-- 1 centos centos 20651 May  2 03:58 RELEASE_NOTES.md
drwxrwxr-x 6 centos centos  4096 May  2 03:58 sdk
-rwxrwxr-x 1 centos centos   978 May  2 03:58 sdk_setup.sh

ビルドする

aws-fpgaディレクトリに、環境をセットアップするためのスクリプトが用意されているので、これを読み込みます。予想外に時間がかかります。環境変数だけかと思ったら、ライブラリのビルドを行なっているようです。

$ source hdk_setup.sh
INFO: Using Vivado v2017.1 (64-bit)
INFO: Setting up environment variables
INFO: Using HDK shell version shell_v04151701
INFO: HDK shell's checkpoint hasn't been downloaded yet.
INFO: Downloading latest HDK shell checkpoint from aws-fpga-hdk-resources/hdk/shell_v04151701/build/checkpoints/from_aws/SH_CL_BB_routed.dcp
INFO: HDK shell is up-to-date
INFO: DDR4 model files in /home/centos/src/project_data/aws-fpga/hdk/common/verif/models/ddr4_model/ do NOT exist. Running model creation step.
INFO:   Building in /home/centos/src/project_data/aws-fpga/ddr4_model_build
INFO:   This could take 5-10 minutes, please be patient!

****** 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'
source /home/centos/src/project_data/aws-fpga/hdk/common/shell_stable/design/ip/ddr4_core/ddr4_core_ex.tcl -notrace

...省略...

INFO: DDR4 model build passed.
INFO: ATTENTION: Don't forget to set the CL_DIR variable for the directory of your Custom Logic.
INFO: AWS HDK setup PASSED.

つづいて、サンプルプロジェクトですが、hdk/cl/examplesには二つ用意されています。

  • cl_hello_world
  • cl_dram_dma
$ cd hdk/cl/examples/
$ ls -l
total 32
drwxrwxr-x 6 centos centos  4096 May  2 03:58 cl_dram_dma
-rw-rw-r-- 1 centos centos  1406 May  2 03:58 cl_examples_list.md
drwxrwxr-x 6 centos centos  4096 May  2 03:58 cl_hello_world
drwxrwxr-x 3 centos centos  4096 May  2 03:58 common
-rw-rw-r-- 1 centos centos 12512 May  2 03:58 README.md

今回は名前からして易しそうな、cl_hello_worldを試してみます。README.mdに従って手順を進めます。

まずはEC2インスタンスからaws-cliを使うため、クレデンシャルを設定しておきます。AWSコンソールのIAMから必要なキーとクレデンシャルを参照して設定します。

$ aws configure

もうひとつ準備として、環境変数CL_DIRにプロジェクトディレクトリをセットする必要があるようです。それができたら、build/scriptディレクトリにあるビルドスクリプトを実行します。

$ cd cl_hello_world/
$ export CL_DIR=$(pwd)
$ cd build/scripts/
$ ./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.

スクリプトを実行すると「数時間かかるよ」とのメッセージが表示され、すぐにプロンプトに戻ってきます。これで処理が終わったわけではなく、バックグラウンドでビルド作業が進行しています。このまま終わるまでしばらく待ちます。実際に試したところ、3時間程度かかりました。インスタンスを上げておけば、ログアウトしても大丈夫です。

README.mdによると、作業の終了をメールで通知する仕組みが用意されているようです。この通知を受けるには、まずSNS (Simple Notification Service)の設定をする必要があります。

$ export EMAIL=your.email@example.com
$ ./$HDK_COMMON_DIR/scripts/notify_via_sns.py

メールが来るので、その中のURLをクリックして、Subscribeを有効化しておきます。そのうえで、aws_build_dcp_from_cl.shスクリプトに-notifyオプションを付けてると、ビルド完了のときにメールで通知されるとのことです。

ビルドが正常に終わると、build/checkpoint/to_awsというディレクトリにtarファイルが作成されます。

$ ls -l build/checkpoints/to_aws/
total 276140
-rw-rw-r-- 1 centos centos 141381632 Apr 26 18:27 17_04_26-145828.Developer_CL.tar
-rw-rw-r-- 1 centos centos       375 Apr 26 18:27 17_04_26-145828.manifest.txt
-rw-rw-r-- 1 centos centos 141378721 Apr 26 18:27 17_04_26-145828.SH_CL_routed.dcp

AFIの作成

tarファイルができても完成ではありません。今度はこれをS3にアップロードして、AFI(Amazon FPGA Image)の作成を依頼します。実作業はインスタンスの中ではなく、コマンドを実行して作成を依頼、そうするとAWS側で処理を行うという流れになります。

まずはaws-cliを使って、S3のバケットを作成します。ここでは"cl_hello_world_01"というバケット名にしました。

$ aws s3 mb s3://cl_hello_world_01 --region us-east-1
make_bucket: cl_hello_world_01
$ aws s3 mb s3://cl_hello_world_01/dcp
make_bucket: cl_hello_world_01
$ aws s3 mb s3://cl_hello_world_01/log
make_bucket: cl_hello_world_01

そしてこのバケットの中に、先ほどのtarファイルをコピーしておきます。

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

イメージを作成してもらうために、このS3バケットに、ポリシーを設定します。この作業にはAWSコンソールを使います。AWSコンソールから、S3を開き、目的のバケットを選び、Properties、そしてPermissionをクリックします。

fpga-image-create-s3-bucket-policy

そしてEdit Bucket Policyをクリックして、下記のJSONを貼り付け、Saveを押します。バケット名やファイル名は適切に合わせます。

{
	"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:::cl_hello_world_01"
		},
		{
			"Sid": "Object read permissions",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::365015490807:root"
			},
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::cl_hello_world_01/dcp/17_04_26-145828.Developer_CL.tar"
		},
		{
			"Sid": "Folder write permissions",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::365015490807:root"
			},
			"Action": "s3:PutObject",
			"Resource": "arn:aws:s3:::cl_hello_world_01/log/*"
		}
	]
}

fpga-create-image-s3-policy

チェック用のスクリプトがありますので、これにバケット名やキー名を与えてチェックします。

$ cd ../../../common/scripts/
$ ./check_s3_bucket_policy.py --dcp-bucket cl_hello_world_01 --dcp-key dcp/17_04_26-145828.Developer_CL.tar --logs-bucket cl_hello_world_01 --logs-key log
INFO: Passed

Passedと表示されました。準備OKですので、awsコマンドのcreate-fpga-imageというサブコマンドを使ってイメージ作成を開始します。作成するイメージ名、S3バケット名やキー名を適切に与えます。すぐに、作成されるAFIのIDが返されてきます。コマンドは終了しますが、AFIはまだできていません。

$ aws ec2 create-fpga-image --name cl_hello_world_test1 --description cl_hello_world_test1 --input-storage-location Bucket=cl_hello_world_01,Key=dcp/17_04_26-145828.Developer_CL.tar --logs-storage-location Bucket=cl_hello_world_01,Key=log
{
    "FpgaImageId": "afi-087de794473334559",
    "FpgaImageGlobalId": "agfi-0c023fead7942c8e0"
}

処理が完了するまでしばらく待ちます。この過程ではインスタンスは使わないようです(インスタンスを落としても大丈夫だと思います)。このフェーズも結構な時間がかかりました。1.5H程度待つと、S3に以下のようなログファイルが生成されていました。

$ aws s3 ls s3://cl_hello_world_01/log/ --recursive
2017-04-26 20:50:05          0 log/LOGS_FILES_GO_HERE.txt
2017-04-26 22:17:33      87787 log/afi-087de794473334559/17_04_26-221726_debug_probes.ltx
2017-04-26 22:17:33     667249 log/afi-087de794473334559/17_04_26-221726_io_summary.rpt
2017-04-26 22:17:33    1766478 log/afi-087de794473334559/17_04_26-221726_timing_summary.rpt
2017-04-26 22:17:33      20182 log/afi-087de794473334559/17_04_26-221726_vivado.log
2017-04-26 22:25:39         17 log/afi-087de794473334559/State

確認はAWSコンソールでも行うことができます。

fpga-create-image-log

Stateというファイルの中に結果が格納されているとのことなので、確認してみます。

$ aws s3 cp s3://cl_hello_world_01/log/afi-087de794473334559/State -
{State=available}

availableとのことなので、無事にAFIが準備できたようです。AFIは実際のファイルとしては見えていませんが、AWS側で管理されているようです。FPGAへのロードも、AFIのIDを指定して行います。

まとめ

aws-fpgaのHDKのサンプルCL_HELLO_WORLDから、FPGA Developer AMIを使って、AFIを作成することができました。

次の記事では、実際にAWS F1インスタンスを上げて、作成したAFIをロードしてみたいと思います。うまく行けば、何か操作ができるはずです。

参考