前回の記事
AIアクセラレータ・IMAXの紹介 ~ (1) CGRAとIMAXについて
IMAXの開発環境構築
IMAXを利用するためには、IMAXというハードウェアを利用できるソフトウェア的インターフェースを用いずに使用することはできません。もちろん、極論「設定に必要な情報をメモリの特定番地において特定の信号を出す」にすれば動きはしますが、そのようなプログラミングをしたいと思う方はいないと思います。
IMAXでも、少なくともデータフローに集中してプログラミングができるツールチェーンが存在します。WebのフレームワークとかCUDAとかのそういう凝ったものではありませんが、とりあえずプログラミングが「できなくもない」程度のツールチェーンは存在します。
今回は、そのツールチェーンの使用方法と簡単なサンプルプログラムの作成をしみたいと思います。
IMAXのツールチェーン
IAMXのツールチェーンはここから入手できます。
それぞれ実際IMAXで動かすためのコードを生成するコンパイラ、マークを貼ってくれるプロプロセッサ、そしてIMAXのシミュレータです。実機はこの研究室の人間でもない限り入手は困難だと思うので、ここではシミュレータを使ってやっていくことにします。
ツールチェーンの構成
IMAX関係のツールチェーンは
-
emax6lib.c
.emax6.h
のようなFPGA上のIMAXを動かすのに必要な型定義や関数呼び出しを定義したファイル - どのような部分がIMAXのコードに置換されるかを決める特定様式のコメントアウトからマークを貼り付ける
conv-mark
- 上でマークをつけられたコードにマクロを実行し、置き換える
cpp -P
- 最終的にIMAXの操作ができるコードを生成する
conv-c2c
があります。これらを見ていきましょう。
conv-mark
conv-markは、設定されている部分にわかりやすいマークをつけていく作業だけを行います。conv-mark自体、Perlで作成された正規表現で定義された文字列置き換えプログラムに過ぎないので、いくつかの注意事項がありますがそれは後で解説します。
IMAXで実行させたいループの上に、IMAXで実行させたいという意思を示します。
//EMAX5A begin name mapdist=0
for () {
for () {
for () {
......
}}}
//EMAX5A end
//EMAX5A drain_dirty_lmm
こういうふうにどこから始まってどこで終わるという処理を書く必要があります。これらが後々IMAXをインターフェース的に操作するコードと置き換わっていきます。注意事項としては、あのコメントの先頭に何かしらの空白やTabを入れてはいけないということです。これに関しては、EMAX5Aと/の間も同様で、そう書かないとconv-markがマークをつけてくれません。
この一連の置き換え過程が終わると、/-EMAX5AB-/
,/-EMAX5AE-/
,/-EMAX5AS-/
のようなマークが各行の先頭に付きます。この部分をIMAXで実行していく、という表示です。
mapdist=0
やdrain_dirty_lmm
の意味については追々説明していくことにします。とりあえずおまじないだと考えてください。ループの書き方にも一定の決まった記述をしなければ動きませんが、それも追々説明していきます。
実行すると次のようなコードに変換されます。
#define printf(format,...)
/-EMAX5AB-/ name 0
/-EMAX5AS-/ for () {
/-EMAX5AS-/ for () {
/-EMAX5AS-/ for () {
...
/-EMAX5AS-/ }}}
#undef printf
/-EMAX5AE-/
/-EMAX5AD-/
cpp -P
によるマクロの変換
cpp
自体、IMAXのツールチェーンではありませんが、先程変換したコードをcpp -P
に通すことによりC言語のマクロや#include
の中身を貼り付けます。このプロセスの次で、IMAXのコンパイラであるconv-c2c
を使います。
conv-c2c
conv-c2c
は、IMAX用に書いたC言語のコードの中をIMAXで実行可能な形に変換するコンパイラです。IMAXで実行する命令に変換し、それをメモリに乗せるようなC言語のコードが結果として出力されます。このようなものを「コンパイラ」と呼ぶのは普段Qiitaを読んでいる方からしたら違和感を覚えるかもしれませんが、VueやReactのコードからSPAを生成するようなものも辞書定義上立派な「コンパイラ」なので、ここではconv-c2c
をコンパイラとします。
emax6.h, emax6lib.cなどのコード作成に必要なライブラリ
IMAXのコード作成に必要な関数、構造体などが定義されてあります。普通に使うC言語のファイルの上に#include
でインクルードするだけでいいのですが、最新のコンパイラでは
#include <stdio.h>
#include <stdlib.h>
#include "emax6.h"
#include "emax6lib.c"
のようにインクルードする前にstdio.h
とstdlib.h
をインクルードしないとエラーになる場合があります。これは、生成されたIMAXのコードでも当該ライブラリを使用するためですが、最新のコンパイラだとこれらの明示的なインクルードがないとエラーを出すため、emax6.h
とemax6lib.c
をインクルードする前に標準ライブラリのインクロードが必要になってきます。これらのコードは、コンパイラのconv-c2c
に含まれているため、そこから取ってきてインクルードしてください。
csim
csim
は、IMAXの実機がない状態でIMAXのバイナリーを試せるシミュレータです。
csim binary param1 param2 .....
という風にすればシミュレータでプログラムを走らせることができます。
FPGAで試したい方
残念ながら、IMAXのVerilogファイルは公開されていません。しかし、一部のFPGAで実行可能なバイナリ等がホームページにて提供されています。もちろんそのFPGA一式は最低でもうん百万円するようなものなので、余程の高給取りなエンジニアではない限り家で試すことは不可能など思われますが、一応載せておきます。
共通事項
コンパイルは、Makefile
を使えばできますが、gcc10以降では-fcommon
オプションがないとエラーが出る場合があるので、コンパイルに失敗したらMakefile
のCFLAGS
に-fcommon
を追加してください。複数のMakefile
が存在し、make
だけでは実行できない場合がありますが、その場合はmake -f ファイル名
でファイルを指定してmake
を走らせることができます。複数ある場合、プラットフォームによってさまざまな定義がされているので、自分の環境にあったファイルを選べばいいと思います。基本x86環境のLinux(またはWSL環境)での実行になると思うので、Makefile-cent
を選んでおけば問題ありません。ラズパイならMakefile-zynq
を選んでおけばいいと思います。
あと、macOSをご使用の方、特にARMのMacユーザならDocker上のLinuxで環境構築を行うのをおすすめします。Macはgccを実行してもclangが実行されるし、gccの導入が結構面倒な方なので、Dockerがおすすめです。
おわりに
今回は、ツールチェーンの紹介と環境構築の仕方について紹介しました。次回からは、例題を一つずつ挙げ、それらを解説しながらIMAXの機能について紹介していきたいと思います。
次回の記事
AIアクセラレータ・IMAXの紹介 ~ (3) 基本的なデータの扱い方及び演算