ソースコードの構成

本ウェブサイトで公開している、 Halide DSL で記述されたソースコードは、一般的に以下のようなファイルで構成されています。

  • xxx_generator.cc: IP のアルゴリズムおよびスケジューリングを Halide DSL によって記述したジェネレータ定義
  • xxx_test.cc: CPU 上で IP の機能テストプログラム
  • xxx_run.cc: FPGA 上で IP の動作テストプログラム
  • Makefile: 各種バイナリ生成用Makefile

以下では、ジェネレータ定義とテストプログラムを使用して、x86 CPU上でHalide DSLの動作を確認するための手順について説明します。

ビルド・テスト方法

事前に Halide の導入を行っておいてください。

ソースコードを GitHub から取得します。

$ git clone https://github.com/fixstars/Halide-elements.git

各プロジェクトのソースコードディレクトリに移動し、make してください。以下では、例として convolution を使用します。

$ cd Halide-elements/src/convolution;
$ make

以下のファイルができていれば、ビルドに成功しています。

  • convolution_gen
  • convolution_test

最後に、convolution_test を実行して機能テストを行うことができます。

$./convolution_test
Success!

Halide DSL のコンパイルフロー

先ほど、ソースコードのディレクトリ以下でmakeコマンドを実行した時、何が起こっていたのでしょうか?  make clean && make -n すると、以下のような結果が得られます。

g++ -fno-rtti -O0 -g -std=c++11 -I <...snip...> GenGen.cpp -o convolution_gen -ldl -lpthread -lz -lHalide
LD_LIBRARY_PATH=<...snip...> ./convolution_gen -o . -e h,static_library target=host-no_asserts
touch convolution_gen.exec
g++ -I . -O0 -g -std=c++11 -I <...snip...> convolution_test.cc -o convolution_test convolution.a -ldl -lpthread

2回の g++ の呼び出しと、ファイルの実行、touch コマンドを行うようです。ここで本質的に重要なのは、g++ の呼び出しとファイルの実行です。 convolution_generator.cc と convolution_test.cc からテストバイナリがどのように生成されるか、図として表してみましょう。

 

GenGen.cpp はジェネレータ定義からターゲットコードを素早く生成するためのスタブファイルで、Halide のソースコードの一部として提供されています。 main エントリポイントを内包しており、C++コードとしてコンパイルされたジェネレータ定義とリンクされ、Halideライブラリに内包されたコンパイラを呼び出してターゲットコードを生成する機能を持っています。この第一段階のコンパイルの結果、convolution_gen という実行ファイルが生成されました。

convolution_gen に適切な引数を与えて実行すると、ターゲットコード(ここではホストCPU上で動作するコード)の静的ライブラリおよびヘッダファイルが生成されます。この、convolution_genの実行が、DSL定義からターゲットコードへのDSL としてののコンパイルフェーズになります。

生成された静的ライブラリ convolution.a は Halideが規定するモジュールインタフェースに準じたABIの関数をエクスポートしています。convolution.h にはそのシグネチャが記載されています。

int convolution(struct halide_buffer_t *_in_buffer, struct halide_buffer_t *_kernel_buffer, int32_t _kernel_size, struct halide_buffer_t *_out_buffer) HALIDE_FUNCTION_ATTRS;

この関数を呼び出すと、Halide DSL で記述したアルゴリズムをターゲットハードウェア上で呼び出すことができます。

以上のように、Halide DSL は C++ の言語内 DSL であるため、通常のプログラミング言語やスクリプト言語に比べ、少し複雑なコンパイル手順が必要になっています。 オリジナルのプロジェクトを実装してみたい方は、既存のプロジェクトをコピーして、テンプレートとして使用するのがよいでしょう。