FPGA F1インスタンス開発用SDKでSDAccel対応がGAになったので試してみた

AWS

EC2のFPGAインスタンス向けに提供されているaws-fpga SDKで、SDAccelというツールが使えるようになりました。少しためしてみたので紹介します。

高位合成とOpenCLとSDAccel

FPGAを動作させるためには回路を作る必要があります。基本的な方法として、VerilogやVHDLという言語を使って論理回路を組み立てるののですが、普通のプログラミングとはかなり考え方が異なるので、プログラマにとっては正直敷居が高いです。

これとは違ったやりかたとして、高位合成という方法があります。簡単にいうと普通のプログラミング言語をつかって回路を記述して、それを回路に変換するという方法です。CやC++を使って記述したプログラムをメモリとCPUを使って走らせるのではなく、ハードウェアに載せられる論理回路として合成してしまうことが可能なのです。これなら普通のプログラマにも手に負えるだろうということで、FPGAを使ったアプリケーション開発では、高位合成が有力な方法と見なされているようです。

ところで並列計算に向けてOpenCLという仕様規格があり、GPUプログラミングなどで良く使われています。実はこのOpenCLはFPGA向けにも使われているのです。FPGAベンダーそれぞれがOpenCL仕様にそったツール群を提供しており、そのうちXilinxが提供しているのがSDAccelなのです。

AWS F1インスタンス開発用に提供されているFPGA Developer AMIにはSDAccelが含まれており、今回のリリースでは(githubで提供されている)aws-fpgaというSDKでの対応がなされたというわけです。

開発用にインスタンスを起動する

AWS-FPGA SDK向けのSDAccel対応は、夏ころからしばらくプレビュー状態だったのですが、先週9/13(日本だと9/14)にGAになりました。さっそくためしてみました。

FPGA開発に使うインスタンスタイプですが、開発作業とビルド(合成)作業を行うためにはFPGAインスタンスは必要ありません。時間単位で使えるとはいえ、普通のインスタンスに比べると高価ですので、普通のインスタンスを使って開発を行い、ハードウェアでの動作確認やデバッグだけです。また、FPGAインスタンスが使えるのは北米のリージョンですが、開発はどのリージョンをつかってもOKです。

というわけで、メモリが>30Gというのが要件ですので、インスタンスタイプには m4.2xlarge 、そしてリージョンはネットワーク的に近いap-northeast-1(東京)で使うことにします。

Amazonマネージメントコンソールから、サービスEC2を選び、[インスタンスの作成]ボタンを押します。AMIの選択で、コミュニティAMIからFPGAと入力して検索すると、FPGA Developer AMIを見つけることができます。バージョンは1.3.0でした。

sdaccel-01-ami

インスタンスタイプは、m4.2xlargeを選びます。図のように32GiBのメモリがあるのでFPGA Developer AMIの要件を満たします。

sdaccel-02-ec2-instance

ハマった点として、作業用のボリュームサイズがデフォルトの5GiBだと、SDAccelのサンプルをいくつかビルドしているだけですぐにディスクフルになってしまうので、十分な量(たとえば20GiB)を確保するようにします。

sdaccel-03-vol

インスタンスが起動したら、sshと鍵ファイルを使って接続します。FPGA Developer AMIはCentOSベースなのでユーザ名がcentosであることに注意です。

$ ssh -i your-key.pem centos@ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com
Last login: Thu Jul 20 16:39:48 2017 from XX-XX-XX-XX.amazon.com
 ___ ___  ___   _     ___  _____   __    _   __  __ ___
| __| _ \/ __| /_\   |   \| __\ \ / /   /_\ |  \/  |_ _|
| _||  _/ (_ |/ _ \  | |) | _| \ V /   / _ \| |\/| || |
|_| |_|  \___/_/ \_\ |___/|___| \_/   /_/ \_\_|  |_|___|
AMI Version:        1.3.0_a
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 Common code: /srv/git/centos-git-common
[centos@ip-XX-XX-XX-XX ~]$

aws-fpgaを用意する

インスタンスに接続したら、githubからSDKをダウンロードします。src/project_data ディレクトリが作業用ボリュームですのでここにcloneします。

$ cd src/project_data
$ git clone https://github.com/aws/aws-fpga

この後の作業は、SDKに含まれている README.md の手順に従って進めます。

まずはセットアップ用のスクリプト sdaccel_setup.shが用意されていますので、これをsourceで読み込みます。

$ cd aws-fpga
$ source sdaccel_setup.sh

カーネルモジュールのビルドや、SDAccelのサンプルのダウンロードが行われますので、若干時間がかかります。

ところが実際やってみると、いくつかモジュールが無いとのウォーニングが出ていました。

AWS FPGA-SDK-WARNING:  libstdc++-static not installed - please run: sudo yum install libstdc++-static
AWS FPGA-SDK-WARNING:  gdb not installed - please run: sudo yum install gdb
AWS FPGA-SDK-WARNING:  libstdc++-static not installed - please run: sudo yum install libstdc++-static
AWS FPGA-SDK-WARNING:  opencv not installed - please run: sudo yum install opencv
AWS FPGA-SDK-WARNING:  libjpeg-turbo-devel not installed - please run: sudo yum install libjpeg-turbo-devel
AWS FPGA-SDK-WARNING:  libpng12-devel not installed - please run: sudo yum install libpng12-devel
AWS FPGA-SDK-WARNING:  libtiff-devel not installed - please run: sudo yum install libtiff-devel
AWS FPGA-SDK-WARNING:  compat-libtiff3 not installed - please run: sudo yum install compat-libtiff3

ウォーニングを消すため、これらのモジュールをyumでインストールしておきます。

$ sudo yum install -y libstdc++-static gdb opencv libjpeg-turbo-devel libpng12-devel libtiff-devel compat-libtiff3

モジュールがインストールができたら、改めてSDKをセットアップしておきます。

$ source sdaccel_setup.sh

さらにもう一つセットアップスクリプトを読み込む必要があります。

$ source $XILINX_SDX/settings64.sh

以上で準備完了です。

サンプルをビルドする

helloworld的サンプルが用意されていますので、これを試してみます。

$ cd $SDACCEL_DIR/examples/xilinx/getting_started/host/helloworld_ocl/

makeでコンパイルするターゲットが3種類あります。

  • sw_emu: ソフトウェアエミュレーション
  • hw_emu: ハードウェアエミュレーション
  • hw: ハードウェア

ソフトウェアエミュレーションしてみる

まずはソフトウェアエミュレーションで試します。TARGETS=sw_emuを指定します。そして、F1インスタンスで使用するハードウェアについての情報が環境変数$AWS_PLATFORMに用意されているので、これをDEVICEとして渡し、makeします。そうすると、OpenCLのソースがソフトウェアとしてコンパイル、そして実行されます。

$ make check TARGETS=sw_emu DEVICES=$AWS_PLATFORM all
/opt/Xilinx/SDx/2017.1.op/bin/xcpp -Wall -O0 -g -I./src/ -I/opt/Xilinx/SDx/2017.1.op/runtime/include/1_2 -I../../../libs/xcl2  -std=c++0x -o helloworld ./src/host.cpp  ../../../libs/xcl2/xcl2.cpp -L/opt/Xilinx/SDx/2017.1.op/runtime/lib/x86_64 -L/opt/Xilinx/SDx/2017.1.op/lib/lnx64.o -lOpenCL -pthread
mkdir -p xclbin
/opt/Xilinx/SDx/2017.1.op/bin/xocc -c --xp "param:compiler.preserveHlsOutput=1" --xp "param:compiler.generateExtraRunData=true" -s   -o xclbin/vector_addition.sw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo -t sw_emu --platform /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm ./src/vector_addition.cl

****** xocc v2017.1_sdx (64-bit)
  **** SW Build 1933108 on Fri Jul 14 11:54:19 MDT 2017
    ** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.

Attempting to get a license: ap_opencl
Feature available: ap_opencl
INFO: [XOCC 60-585] Compiling for software emulation target
INFO: [XOCC 60-895]    Target platform: /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm
INFO: [XOCC 60-423]   Target device: xilinx:aws-vu9p-f1:4ddr-xpr-2pr:4.0
INFO: [XOCC 60-242] Creating kernel: 'vector_add'
INFO: [XOCC 60-594] Finished kernel compilation
INFO: [XOCC 60-586] Created xclbin/vector_addition.sw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo
INFO: [XOCC 60-791] Total elapsed time: 0h 0m 52s
mkdir -p xclbin
/opt/Xilinx/SDx/2017.1.op/bin/xocc -l --xp "param:compiler.preserveHlsOutput=1" --xp "param:compiler.generateExtraRunData=true" -s   -o xclbin/vector_addition.sw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin -t sw_emu --platform /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm xclbin/vector_addition.sw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo

****** xocc v2017.1_sdx (64-bit)
  **** SW Build 1933108 on Fri Jul 14 11:54:19 MDT 2017
    ** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.

INFO: [XOCC 60-899] Reading --xp value from platform: param:compiler.lockFlowCritSlackThreshold=0
Attempting to get a license: ap_opencl
Feature available: ap_opencl
INFO: [XOCC 60-629] Linking for software emulation target
INFO: [XOCC 60-895]    Target platform: /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm
INFO: [XOCC 60-423]   Target device: xilinx:aws-vu9p-f1:4ddr-xpr-2pr:4.0
INFO: [XOCC 60-586] Created xclbin/vector_addition.sw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin
INFO: [XOCC 60-791] Total elapsed time: 0h 0m 13s
/opt/Xilinx/SDx/2017.1.op/bin/emconfigutil --platform /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm --nd 1

****** configutil v2017.1_sdx (64-bit)
  **** SW Build 1933108 on Fri Jul 14 11:54:19 MDT 2017
    ** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.

INFO: [ConfigUtil 60-895]    Target platform: /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm
emulation configuration file `emconfig.json` is created in ./ directory
XCL_EMULATION_MODE=sw_emu ./helloworld
platform Name: Xilinx
Vendor Name : Xilinx
Found Platform
Found Device=xilinx:aws-vu9p-f1:4ddr-xpr-2pr:4.0
XCLBIN File Name: vector_addition
INFO: Importing xclbin/vector_addition.sw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin
Loading: 'xclbin/vector_addition.sw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin'
Result =
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
TEST PASSED
make: Nothing to be done for `all'.

なんだか42がたくさん表示されています。何をやっているのか中身をみてみます。

呼び出し側(host.cpp)で、それぞれ10と32で初期化された二つの配列があります。

    // Creates a vector of DATA_SIZE elements with an initial value of 10 and 32
    vector<int,aligned_allocator<int>> source_a(DATA_SIZE, 10);
    vector<int,aligned_allocator<int>> source_b(DATA_SIZE, 32);
    vector<int,aligned_allocator<int>> source_results(DATA_SIZE);

そして、OpenCLで記述(vector_addition.cl)されたカーネル関数vector_add()が呼び出され、配列の要素同士を加算し、42になっているようです。ここが回路としてハードウェアで実装されることになるわけです。

#define BUFFER_SIZE 256
kernel __attribute__((reqd_work_group_size(1, 1, 1)))
void vector_add(global int* c,
                global const int* a,
                global const int* b,
                       const int n_elements)
{
    int arrayA[BUFFER_SIZE];
    int arrayB[BUFFER_SIZE];
    for (int i = 0 ; i < n_elements ; i += BUFFER_SIZE)
    {
        int size = BUFFER_SIZE;
        if (i + size > n_elements) size = n_elements - i;
        readA: for (int j = 0 ; j < size ; j++) arrayA[j] = a[i+j];
        readB: for (int j = 0 ; j < size ; j++) arrayB[j] = b[i+j];
        vadd_writeC: for (int j = 0 ; j < size ; j++) c[i+j] = arrayA[j] + arrayB[j];
    }
}

ハードウェアエミュレーションしてみる

今度はハードウェアエミュレーションを試してみます。sw_emuの代わりにhw_emuを指定します。

$ make check TARGETS=hw_emu DEVICES=$AWS_PLATFORM all

/opt/Xilinx/SDx/2017.1.op/bin/xcpp -Wall -O0 -g -I./src/ -I/opt/Xilinx/SDx/2017.1.op/runtime/include/1_2 -I../../../libs/xcl2  -std=c++0x -o helloworld ./src/host.cpp  ../../../libs/xcl2/xcl2.cpp -L/opt/Xilinx/SDx/2017.1.op/runtime/lib/x86_64 -L/opt/Xilinx/SDx/2017.1.op/lib/lnx64.o -lOpenCL -pthread
mkdir -p xclbin
/opt/Xilinx/SDx/2017.1.op/bin/xocc -c --xp "param:compiler.preserveHlsOutput=1" --xp "param:compiler.generateExtraRunData=true" -s   -o xclbin/vector_addition.hw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo -t hw_emu --platform /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm ./src/vector_addition.cl

****** xocc v2017.1_sdx (64-bit)
  **** SW Build 1933108 on Fri Jul 14 11:54:19 MDT 2017
    ** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.

Attempting to get a license: ap_opencl
Feature available: ap_opencl
INFO: [XOCC 60-585] Compiling for hardware emulation target
INFO: [XOCC 60-895]    Target platform: /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm
INFO: [XOCC 60-423]   Target device: xilinx:aws-vu9p-f1:4ddr-xpr-2pr:4.0
INFO: [XOCC 60-242] Creating kernel: 'vector_add'

===>The following messages were generated while  performing high-level synthesis for kernel: vector_add Log file:/home/centos/src/project_data/aws-fpga/SDAccel/examples/xilinx/getting_started/host/helloworld_ocl/_xocc_compile_vector_addition_vector_addition.hw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.dir/impl/kernels/vector_add/vivado_hls.log :
INFO: [XOCC 204-61] Option 'relax_ii_for_timing' is enabled, will increase II to preserve clock frequency constraints.
INFO: [XOCC 204-61] Pipelining loop 'readA'.
INFO: [XOCC 204-61] Pipelining result: Target II: 1, Final II: 1, Depth: 3.
INFO: [XOCC 204-61] Pipelining loop 'readB'.
INFO: [XOCC 204-61] Pipelining result: Target II: 1, Final II: 1, Depth: 3.
INFO: [XOCC 204-61] Pipelining loop 'vadd_writeC'.
INFO: [XOCC 204-61] Pipelining result: Target II: 1, Final II: 1, Depth: 3.
INFO: [XOCC 60-594] Finished kernel compilation
INFO: [XOCC 60-586] Created xclbin/vector_addition.hw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo
INFO: [XOCC 60-791] Total elapsed time: 0h 3m 15s
mkdir -p xclbin
/opt/Xilinx/SDx/2017.1.op/bin/xocc -l --xp "param:compiler.preserveHlsOutput=1" --xp "param:compiler.generateExtraRunData=true" -s   -o xclbin/vector_addition.hw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin -t hw_emu --platform /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm xclbin/vector_addition.hw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo

****** xocc v2017.1_sdx (64-bit)
  **** SW Build 1933108 on Fri Jul 14 11:54:19 MDT 2017
    ** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.

INFO: [XOCC 60-899] Reading --xp value from platform: param:compiler.lockFlowCritSlackThreshold=0
Attempting to get a license: ap_opencl
Feature available: ap_opencl
INFO: [XOCC 60-629] Linking for hardware emulation target
INFO: [XOCC 60-895]    Target platform: /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm
INFO: [XOCC 60-423]   Target device: xilinx:aws-vu9p-f1:4ddr-xpr-2pr:4.0
INFO: [XOCC 60-251]   Hardware accelerator integration...
INFO: [XOCC 60-586] Created xclbin/vector_addition.hw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin
INFO: [XOCC 60-791] Total elapsed time: 0h 2m 10s
/opt/Xilinx/SDx/2017.1.op/bin/emconfigutil --platform /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm --nd 1

****** configutil v2017.1_sdx (64-bit)
  **** SW Build 1933108 on Fri Jul 14 11:54:19 MDT 2017
    ** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.

INFO: [ConfigUtil 60-895]    Target platform: /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm
emulation configuration file `emconfig.json` is created in ./ directory
XCL_EMULATION_MODE=hw_emu ./helloworld
platform Name: Xilinx
Vendor Name : Xilinx
Found Platform
Found Device=xilinx:aws-vu9p-f1:4ddr-xpr-2pr:4.0
XCLBIN File Name: vector_addition
INFO: Importing xclbin/vector_addition.hw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin
Loading: 'xclbin/vector_addition.hw_emu.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin'
INFO: [SDx-EM 01] Hardware emulation runs detailed simulation underneath. It may take long time for large data set. Please use a small dataset for faster execution. You can still get performance trend for your kernel with smaller dataset.
Result =
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
TEST PASSED
INFO: [SDx-EM 22] [Wall clock time: 04:24, Emulation time: 0.00791 ms] Data transfer between kernel(s) and global memory(s)
BANK0          RD = 2.000 KB               WR = 1.000 KB
BANK1          RD = 0.000 KB               WR = 0.000 KB
BANK2          RD = 0.000 KB               WR = 0.000 KB
BANK3          RD = 0.000 KB               WR = 0.000 KB

make: Nothing to be done for `all'.

さきほどよりコンパイルに時間が若干かかります(数分程度)。結果は同じになっているようです。さらにおまけの情報としてホストとのデータ転送量が最後に表示されています。ハードウェアをエミュレーションした側とのデータ転送が特別に扱われているようです。

ハードウェア用にmakeする

最後にハードウェア用にコンパイル(合成)を行います。checkを付けず、allだけでmakeします。これはかなり時間がかります。2.5時間ほど要しました。気長に待ちます。SSHのコネクションが不慮に切れてしまうことを考えて、screen等の仮想コンソールを使ったほうが良いかもしれません。

$ make TARGETS=hw DEVICES=$AWS_PLATFORM all
/opt/Xilinx/SDx/2017.1.op/bin/xcpp -Wall -O0 -g -I./src/ -I/opt/Xilinx/SDx/2017.1.op/runtime/include/1_2 -I../../../libs/xcl2  -std=c++0x -o helloworld ./src/host.cpp  ../../../libs/xcl2/xcl2.cpp -L/opt/Xilinx/SDx/2017.1.op/runtime/lib/x86_64 -L/opt/Xilinx/SDx/2017.1.op/lib/lnx64.o -lOpenCL -pthread
mkdir -p xclbin
/opt/Xilinx/SDx/2017.1.op/bin/xocc -c --xp "param:compiler.preserveHlsOutput=1" --xp "param:compiler.generateExtraRunData=true" -s   -o xclbin/vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo -t hw --platform /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm ./src/vector_addition.cl

****** xocc v2017.1_sdx (64-bit)
  **** SW Build 1933108 on Fri Jul 14 11:54:19 MDT 2017
    ** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.

Attempting to get a license: ap_opencl
Feature available: ap_opencl
INFO: [XOCC 60-585] Compiling for hardware target
INFO: [XOCC 60-895]    Target platform: /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm
INFO: [XOCC 60-423]   Target device: xilinx:aws-vu9p-f1:4ddr-xpr-2pr:4.0
INFO: [XOCC 60-242] Creating kernel: 'vector_add'

===>The following messages were generated while  performing high-level synthesis for kernel: vector_add Log file:/home/centos/src/project_data/aws-fpga/SDAccel/examples/xilinx/getting_started/host/helloworld_ocl/_xocc_compile_vector_addition_vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.dir/impl/kernels/vector_add/vivado_hls.log :
INFO: [XOCC 204-61] Option 'relax_ii_for_timing' is enabled, will increase II to preserve clock frequency constraints.
INFO: [XOCC 204-61] Pipelining loop 'readA'.
INFO: [XOCC 204-61] Pipelining result: Target II: 1, Final II: 1, Depth: 3.
INFO: [XOCC 204-61] Pipelining loop 'readB'.
INFO: [XOCC 204-61] Pipelining result: Target II: 1, Final II: 1, Depth: 3.
INFO: [XOCC 204-61] Pipelining loop 'vadd_writeC'.
INFO: [XOCC 204-61] Pipelining result: Target II: 1, Final II: 1, Depth: 3.
INFO: [XOCC 60-594] Finished kernel compilation
INFO: [XOCC 60-586] Created xclbin/vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo
INFO: [XOCC 60-791] Total elapsed time: 0h 0m 45s
mkdir -p xclbin
/opt/Xilinx/SDx/2017.1.op/bin/xocc -l --xp "param:compiler.preserveHlsOutput=1" --xp "param:compiler.generateExtraRunData=true" -s   -o xclbin/vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin -t hw --platform /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm xclbin/vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo

****** xocc v2017.1_sdx (64-bit)
  **** SW Build 1933108 on Fri Jul 14 11:54:19 MDT 2017
    ** Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.

INFO: [XOCC 60-899] Reading --xp value from platform: param:compiler.lockFlowCritSlackThreshold=0
Attempting to get a license: ap_opencl
Feature available: ap_opencl
INFO: [XOCC 60-629] Linking for hardware target
INFO: [XOCC 60-895]    Target platform: /home/centos/src/project_data/aws-fpga/SDAccel/aws_platform/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0/xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xpfm
INFO: [XOCC 60-423]   Target device: xilinx:aws-vu9p-f1:4ddr-xpr-2pr:4.0
INFO: [XOCC 60-251]   Hardware accelerator integration...
Creating Vivado project and starting FPGA synthesis.
................................................................................................................................
Finished 1st of 5 tasks (FPGA synthesis). Elapsed time: 00h 36m 04s.
.....
Finished 2nd of 5 tasks (FPGA logic optimization). Elapsed time: 00h 06m 03s.
...............................
Finished 3rd of 5 tasks (FPGA logic placement). Elapsed time: 00h 48m 08s.
................................
Finished 4th of 5 tasks (FPGA routing). Elapsed time: 00h 58m 45s.

INFO: [XOCC 60-586] Created xclbin/vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin
INFO: [XOCC 60-791] Total elapsed time: 2h 40m 6s
./helloworld
platform Name: Xilinx
Vendor Name : Xilinx
Found Platform
Found Device=xilinx:pcie-hw-em:7v3:1.0
XCLBIN File Name: vector_addition

xclbinというディレクトリの中にビルドされたファイルができています。

$ ls -l xclbin
total 287540
-rw-rw-r-- 1 centos centos 292349526 Sep 20 11:00 vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin
-rw-rw-r-- 1 centos centos    218160 Sep 20 08:20 vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xo

無事ビルドに成功したら、つづいてAFIイメージの作成を行います。

この手順には、クレデンシャルとS3バケットを用意しておく必要があります。IAMキーを用意してaws configureで設定しておきます。リージョンはus-east-1を使いましたが、ap-northeast-1でも大丈夫かもしれません。

$ aws configure
AWS Access Key ID []:XXXXXXXXXXXXXXXXXXXXXXXXXXX
AWS Secret Access Key []:XXXXXXXXXXXXXXXXXXXXXXXXXXXX
Default region name []: us-east-1
Default output format 1:

S3バケットは前に使ったcl_heelo_world_01というバケットをそのまま再利用しました。バケットの中には、dcpとlogというキーを用意しておいて、それぞれDCP(Design Check Point)ファイルとログを入れるよう指定します。xclbinという引数で、さきほどビルドしたxclbinファイルを指定します。-oオプションで出力ファイル名を指定しますが、拡張子を取り除いたものを指定しました。

$ $SDACCEL_DIR/tools/create_sdaccel_afi.sh -xclbin=xclbin/vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin -o=vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0 -s3_bucket=cl_hello_world_01 -s3_dcp_key=dcp -s3_logs_key=log
Found xclbin 'xclbin/vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin'
vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0
Split DCP from xclbin: 17_09_20-110840-primary.bit
Split Metadata from xclbin: 17_09_20-110840-primary.bit
Generated manifest file '17_09_20-110840_manifest.txt'
upload: ./17_09_20-110840_Developer_SDAccel_Kernel.tar to s3://cl_hello_world_01/dcp/17_09_20-110840_Developer_SDAccel_Kernel.tar
17_09_20-110840_agfi_id.txt
INFO: Adding section using: '17_09_20-110840' (22 Bytes)
INFO: Adding section using: '17_09_20-110840' (3126 Bytes)

このコマンドはS3へのコピーが終わるとすぐに帰ってきます。AFIとAGFIのIDがJSONで記されたファイルができています。 作業が終わったわけではなくリクエストが発行され処理待ちになっています。

$ cat 17_09_20-110840_afi_id.txt
{
    "FpgaImageId": "afi-085c2ad238d06e898",
    "FpgaImageGlobalId": "agfi-0cae0943c817e2265"
}

describe-fpga-imagesサブコマンドを使って進捗を確認可能です。30分程度で作業が終了するようです。"State""Code""available"になっていれば無事完了です。

$ aws ec2 describe-fpga-images --fpga-image-ids afi-0bb9c242b597779ea
{
    "FpgaImages": [
        {
            "UpdateTime": "2017-09-20T11:52:15.000Z",
            "Name": "xclbin/vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin",
            "PciId": {
                "SubsystemVendorId": "0xfedd",
                "VendorId": "0x1d0f",
                "DeviceId": "0xf000",
                "SubsystemId": "0x1d51"
            },
            "FpgaImageGlobalId": "agfi-047f45806c5502319",
            "State": {
                "Code": "available"
            },
            "ShellVersion": "0x071417d3",
            "OwnerId": "706644052815",
            "FpgaImageId": "afi-0bb9c242b597779ea",
            "CreateTime": "2017-09-20T11:08:52.000Z",
            "Description": "xclbin/vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.xclbin"
        }
    ]
}

ようやっとFPGA用のイメージができました。つぎはF1インスタンスで動作させたいのですが、リージョンをus-east-1で準備する必要があります。動作させるために、イメージだけではなく、ビルドに使ったファイルが必要になりますので、ボリュームのスナップショットを取って、N.Virginia(us-east-1)にリージョンコピーしておき、F1インスタンスの作業ボリュームとしてマウントすることにします。

sdaccel-05-snapshot

sdaccel-07

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

リージョンをN.Virginiaに切り替えて、F1インスタンス f1.2xlargeを起動します。AMIは、先ほどと同じFPGA Developer AMIを使います。また作業ボリュームとして、リージョンコピーしたスナップショットを指定します(さきほど付けた名前を入れると候補として出てくるはずです)。また実験ということでスポットインスタンスを使うと$0.4/H程度の価格でF1インスタンスを使うことができるようです。ちなみにオンデマンドですと$1.65/Hです。

sdaccel-08-

sdaccel-09-vol

インスタンスが起動したら、SSHで接続します。接続が成功したら、まずは先ほど指定したスナップショットがボリュームとしてマウントされていることを確認します。開発用インスタンスで見えていたのと同じ内容が見えていればOKです。

$ ls src/project_data/aws-fpga/
ERRATA.md  FAQs.md  hdk  hdk_setup.sh  LICENSE.txt  README.md  RELEASE_NOTES.md  SDAccel  sdaccel_setup.sh  sdk  sdk_setup.sh

サンプルディレクトリhelloworld_oclに移動します。まずはsudoでrootになっておきます。ハードウェアにロードするために必要なようです。そしてhelloworld_oclバイナリを実行します。そうすると、自動的にAFIイメージがロードされて、ホスト側コードが走り、FPGA側回路が動作します。ロードには少し時間がかかります。

$ cd src/project_data/aws-fpga/SDAccel/examples/xilinx/getting_started/host/helloworld_ocl/
$ sudo sh
sh-4.2# source /opt/Xilinx/SDx/2017.1.rte/setup.sh
sh-4.2# ./helloworld
Device/Slot[0] (/dev/xdma0, 0:0:1d.0)
xclProbe found 1 FPGA slots with XDMA driver running
platform Name: Xilinx
Vendor Name : Xilinx
Found Platform
Found Device=xilinx:aws-vu9p-f1:4ddr-xpr-2pr:4.0
XCLBIN File Name: vector_addition
INFO: Importing ./vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.awsxclbin
Loading: './vector_addition.hw.xilinx_aws-vu9p-f1_4ddr-xpr-2pr_4_0.awsxclbin'
Result =
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42
TEST PASSED
sh-4.2#

無事エミュレーションと同じ結果が得られました。

SDAccelには、他にも多くのサンプルが提供されています。ほぼ同じように動作させることができるようです。片っ端から試していると、あっというまにディスクを消費してしまいます。合成にかかる時間と、実行の手間を考慮すると、いくつかビルドしておいて、まとめて試すのが良いかもしれません。

まとめ

FPGAの開発環境SDAccelを試してみました。OpenCLのコードから、ソフトウェアエミュレーション、ハードウェアエミュレーションの動作を確認。ハードウェア向けFPGAで動作させることができました。

  • ソフトウェアエミュレーション: makeと実行は速い。
  • ハードウェアエミュレーション: makeと実行は速い(ソフトウェアエミュレーションよりちょっと遅い)。
  • ハードウェア: makeに(数時間レベルで)非常に時間がかかる。AFIイメージを作成する必要がある。

実際のハードウェアで動作させるための合成は時間がかかりますが、エミュレーションでは短時間で済み、効率的に開発と検証を行うことができます。VerilogやVHDLを使った開発にくらべて馴染みやすいスタイルでの開発が可能なようです。ご興味があればぜひお試しください。

参考