はじめに
Halideはgeneratorという中間ファイルを用いることで、作成したプログラムを再利用可能な部品にカプセル化することができます。
ここではgeneratorの概要とgeneratorの作成手順(スクリプト含め)について紹介します。
generatorとは
概要
Halideで実装したプログラムとGit上にあるGenGen.cppとコンパイル・リンクして、generatorと呼ばれる実行可能な中間ファイルを作成することができます。
generatorを実行すると以下のファイルを自動生成することができます。
- 静的ライブラリ(.a)
- オブジェクトファイル(.o)
- ヘッダファイル(.h)
- アセンブリファイルなど
ファイルを自動生成する中間ファイルなので「generator」と呼んでいるみたいです。
generatorを利用する理由
generatorを作成しておくことで、後から目的(環境)に合ったファイルを作成することが出来ます。
generatorを作成するときに生成するファイルの種類だけではなく、どの環境(target)で使用するかを指定することが出来ます。
Halideはマルチプラットフォームに対応しており、作成したアルゴリズムを当初とは別の環境で使用したいときもgeneratorを活用することですぐに対応できます。
対応している環境 | |
CPU | X86, ARM, MIPSなど |
OS | Linux, Windows, macOSなど |
GPU | CUDA, OpenCLなど |
generatorの作成手順
generatorを作成する手順例
- Halideでスクリプト(halide_program.cpp)を作成する
- halide_program.cppとGenGen.cppをコンパイル、リンクをすることでgeneratorを作成
- generatorを実行する(実行時に、生成するファイルの種類を指定する)
- 自動生成されたファイル(オブジェクトファイルなど)を他のソースファイル(main.cpp)で使用する
フォルダ構成
1 2 3 4 5 6 7 8 |
Program/ |-Halide-10.0.0/ |-test_program/ |-generator_sample/ |-halide_program.cpp |-main.cpp |-GenGen.cpp |-Makefile |
スクリプト例
generatorを作成するscript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <Halide.h> using namespace Halide; // 入力に1を足す関数 class halide_program :public Halide::Generator<halide_program>{ public : Input<Buffer<int>> input{"input", 1}; Output<Buffer<int>> output{"output", 1}; Var x; void generate(){ output(x) = input(x) + 1; } void schedule(){ } }; HALIDE_REGISTER_GENERATOR(halide_program, Halide_Program); |
自動生成したファイルを利用するscript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <stdio.h> #include "Halide.h" #include "Halide_Program.h" // generatorで自動生成したヘッダファイル using namespace std; using namespace Halide; int main() { int data[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; int data_size = 12; int result[12]; Runtime::Buffer<int> input_data(data, data_size); Runtime::Buffer<int> output_data(result); printf("input data: "); // 入力を表示 for(int i = 0; i < data_size; i++) { printf("%d ", data[i]); } printf("\n"); Halide_Program(input_data, output_data); // 入力に1を足す printf("output_data: "); // 出力を表示 for(int i = 0; i < data_size; i++) { printf("%d ", result[i]); } printf("\n"); return 0; } |
Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
INCLUDES := -I ../../Halide-10.0.0/include -I ../../Halide-10.0.0/share/Halide/tools LIBRARIES := -lHalide -lpthread -ldl # generatorで自動生成されたオブジェクトファイルをリンクしている main: main.cpp Halide_Program.o g++ main.cpp Halide_Program.o -g -std=c++11 $(INCLUDES) $(LIBRARIES) -o main # generatorを実行し、オブジェクトファイルとヘッダファイルを自動生成する Halide_Program.o: halide_program ./halide_program -g Halide_Program -e o,h -o . target=host # generatorを作成する halide_program: halide_program.cpp g++ halide_program.cpp GenGen.cpp -g -std=c++11 -fno-rtti $(INCLUDES) $(LIBRARIES) -o halide_program |
result
1 2 |
input data: 1 2 3 4 5 6 7 8 9 10 11 12 output data: 2 3 4 5 6 7 8 9 10 11 12 13 |
コメント