Intel PACのAFUをGitLab CIでテストする

## はじめに

[Intellectual Highway合同会社](https://www.i-highway.com/)のytodaです。
Intellectual HighwayではネットワークアクセラレータIPの提供やFPGA用の回路設計受託を行っています。

この記事では、IntelのPACカード用に開発したAFUをGitLab CIで実機テストする方法を紹介します。
今回はアクセラレーションスタックに含まれる`hello_afu`サンプルをGitLab CIで実機テストする環境を構築してみます。

## 環境

以下の環境で確認しました。

* [Intel Programmable Acceleration Card with Intel Arria 10 GX FPGA](https://www.intel.co.jp/content/www/jp/ja/programmable/products/boards_and_kits/dev-kits/altera/acceleration-card-arria-10-gx/overview.html)
* [Intel Acceleration Stack v1.2 Update 1](https://www.intel.com/content/www/us/en/programmable/solutions/acceleration-hub/archives.html)
    * 古いバージョンですみません
* CentOS 7.4
    * このマシンにPACカードを挿入し、アクセラレーションスタックをインストールします
* [GitLabのSaaS版](https://gitlab.com/)

## アクセラレーションスタックのセットアップ

https://www.intel.com/content/www/us/en/programmable/solutions/acceleration-hub/archives.html からAcceleration Stack for DevelopmentとRequired UpdatesとなっているUpdate 1をダウンロードします。

v1.2のセットアップについては[クイックスタートガイド](https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/archives/ug-qs-ias-v1-2-1-2.pdf)を、Update 1の適用についてダウンロードしたファイル内のreadmeを参照してください。

アクセラレーションスタックは`/home/xxx/inteldevstack`にインストールされたものとします。

## `hello_afu`をGitLabリポジトリに登録

1. GitLabでプロジェクト作成
1. `hello_afu`をGitLabにpush

```shell-session
cd /home/xxx/inteldevstack/a10_gx_pac_ias_1_2_pv/hw/samples/hello_afu
git init
git remote add origin <リポジトリのURL>
git checkout -b main
git add .
git commit
git push origin main
```

## GitLab Runnerのセットアップ

PACカードが挿入されたマシンに、GitLab Runnerをセットアップしていきます。

GitLab Runnerをセットアップすることで、PACカード用マシン上でGitLab CIのジョブを実行できるようになります。

### インストール

https://docs.gitlab.com/runner/install/index.html に従ってインストールします。

```shell-session
# Replace ${arch} with any of the supported architectures, e.g. amd64, arm, arm64
# A full list of architectures can be found here https://gitlab-runner-downloads.s3.amazonaws.com/latest/index.html
curl -LJO "https://gitlab-runner-downloads.s3.amazonaws.com/latest/rpm/gitlab-runner_${arch}.rpm"
rpm -i gitlab-runner_${arch}.rpm
```

### runnerの登録

インストールしたrunnerをGitLab CIに登録します。

```shell-session
sudo gitlab-runner register
```

register時に使用するURL、tokenは`hello_afu`リポジトリのweb画面から確認できます。

* coodinator URL: `hello_afu`リポジトリ -> Settings -> CI/CD -> Runners -> Specific runners
* token: `hello_afu`リポジトリ -> Settings -> CI/CD -> Runners -> Specific runners
* description: マシン名などrunnerの説明を入力
* tags: `shell,pac` (`.gitlab-ci.yml`で指定するtag名)
* executor: `shell`

executorを`shell`とすることで、CIジョブ実行時にPACカードにアクセスできるようになります。

### gitlab-runnerアカウントの設定

GitLab Runnerのジョブはrunnerをインストールしたマシンの`gitlab-runner`アカウントで実行されます。
`gitlab-runner`アカウントでAFUのビルドと実行を行えるように設定していきます。

必要な設定は以下の通りです。

* アクセラレーションスタックの環境変数を設定する
* パスワードなしで`sudo`できるようにする
* アクセラレーションスタックがインストールされたディレクトリにアクセス可能にする

#### アクセラレーションスタックの環境変数を設定する

アクセラレーションスタック環境変数を設定するために`gitlab-runner`アカウントの`.bashrc`に以下を追記します。
本来は`.gitlab-ci.yml`内で指定したいところですが、なぜかジョブがエラーになってしまうので`.bashrc`に直接記述することにします。

```shell:.bashrc
source /home/xxx/inteldevstack/init_env.sh > /dev/null
```

#### パスワード無しで`sudo`できるようにする

`gitlab-runner`アカウントがパスワードなしで`sudo`できるようにします。

```shell-session
sudo visudo
```

で以下を追記します。

```
# visudo
gitlab-runner      ALL=(ALL)       NOPASSWD: ALL
```

上記で`.bashrc`に追加した`init_env.sh`が、内部で`sudo`を使用しているためにこの設定が必要になっています。
`source /home/xxx/inteldevstack/init_env.sh`で設定される環境変数を`.gitlab-ci.yml`で個別に設定してあげれば、この手順は不要になると思います。

#### アクセラレーションスタックのディレクトリにアクセスできるようにする

`gitlab-runner`アカウントからアクセラレーションスタックがインストールされたディレクトリにアクセスできるようにします。

```shell-session
sudo chmod 755 /home/xxx
```

## .gitlab-ci.yml

`hello_afu`リポジトリのトップに以下の内容で`.gitlab-ci.yml`を作成して、push時に実機用のビルドとテストが実行されるようにします。

`build`ジョブでは、実機用にAFUをビルド（合成）を行います。
`test`ジョブでは、PACカードへのバイナリの書き込み、テスト用ホストアプリケーションのビルドと実行を行います。

```yaml:.gitlab-ci.yml
build:
  stage: build
  script:
    - afu_synth_setup -s hw/rtl/filelist.txt build_synth
    - cd build_synth
    - run.sh
  artifacts:
    paths:
      - build_synth/*.gbs
  tags:
    - pac
    - shell

test:
  stage: test
  dependencies:
    - build
  script:
    - fpgaconf build_synth/hello_afu.gbs
    - cd sw
    - make
    - ./hello_afu
  tags:
    - pac
    - shell
```

## おわりに

以上で、`hello_afu`リポジトリへのpush時にビルドとPACカード上でのテストが行われるようになります。

実際の運用ではAFUのビルドに結構な時間がかかるので、以下の設定を行うと良いと思います。

* リポジトリweb画面 -> CI/CD -> Schedulesからジョブの実行を1日1回にする

今回はv1.2と古いアクセラレーションスタックのバージョンを使用しましたが、最新のv1.2.1でも似たような手順でCI環境を構築できると思います。