目的
先日アメリカなどの国でPixel 2が発売になり、DxOスコアで98点をマークしたカメラ機能などが話題となった。1
また、Pixel 2には、新たに開発されたPixel Visual Coreという画像処理プロセッサが搭載されていることが明らかにされた
上記の記事によるとPixel Visual Coreは画像処理用ドメイン言語としてHalideをサポートし、開発者の負担を軽減しているとのことである。
このような状況から、今後Halideについての注目も大きくなると予想される。
Halideに関しては詳しいチュートリアルも公開されているが、私が手元の環境(Ubuntu16.4 64bit)で実行したところ思いのほか多数のトラブルに出くわしたので、その際に行った環境設定などの作業を公開する。
なお、これらの作業の中には環境設定を正しく行っておけば必要がないものも含まれているのではないかと想像する。もしそういったものがあった場合はコメントなどしていただければ感謝します。
Halideについて
HalideはMITなどによって開発された画像処理用の言語である。特徴として画像処理の定義と、処理の最適化をわけることにより、非常に簡潔な表記のまま高性能を実現することができる。言語としてはC++を拡張したものとなっている。コンパイル済みのパッケージが配布されている実行プラットフォームはARM-Linux、X86-Linux (64-bit/32-bit)、Windows、Mac。最適化の対象としてはマルチコアCPU, NEON, SSE, AVX, GPUなどが挙げられている。
このページはHalideの実行環境設定に関するものなのでHalide自体の解説は他のくわしい記事に譲るものとする。解説などを含んだページとしては以下のようなものがあるようだ。
Halide - a language for image processing and computational photography
本家Halideのホームページ。Halideの解説と詳細なチュートリアル、github上のバイナリーへのリンクなどがある。(なお、本稿でとりあげるチュートリアルはこのページのものである)Qiita: Halide入門とOpenCVとの比較
OpenCVとの比較を中心とした貴重な日本語によるHalideの解説。
(OpenCVとの速度比較なども行われていて、Halideに関する内容は本稿よりはるかに詳しいので、Halide自体を知りたい方はこちらのページを参照される事をおすすめします。Qiita: Halideによる2次元FIRフィルタの実装
先ほどの「OpenCVとの比較」の方の別記事。実際にフィルターをどう書くか解説されている。
環境設定
Halideのインストール
今回はコンパイル済みパッケージを使用した2
コンパイル済みのパッケージはこちらにある。
https://github.com/halide/Halide/releases
パッケージは実行環境とgccのバージョンに合わせて選択する必要がある。今回はX86 Linux 64bitのパッケージのうち、gcc-4.8に対応したものを選択した。(gccのバージョンについては後述する)
halide-linux-64-gcc48-で始まるファイルをダウンロードし、halideディレクトリを実行するディレクトリ(~/workなど)に解凍する。チュートリアルはhalide/tutorialフォルダ内にあり、このフォルダ内でコンパイル及び実行する限りは、特にパスの設定は必要ない。(コンパイル時および実行時に指定する)
なおこれ以降の作業はこの解凍したhalide/tutorialフォルダ内で行うものとする。
アプリケーション用コンパイラの設定
Halideのコンパイル済みバイナリーはgcc5.3以前のバージョンしか対応していない。Ubuntu16.4のgccは5.4のようなので、以前のバージョンのgccとg++をインストールする必要がある。いくつかバージョンを試してみたが、gcc-4.8でアプリケーションのコンパイル、リンク、実行が成功したので、今回はそれを使用する。
sudo apt-get install gcc-4.8 g++-4.8
次にこちらのページを参考に使用するgccのバージョンを設定する
Ask Ubuntu: Choose gcc and g++ version
具体的には以下のようにした。
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 10
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 20
sudo update-alternatives --remove-all cc
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
sudo update-alternatives --set cc /usr/bin/gcc
sudo update-alternatives --remove-all c++
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
sudo update-alternatives --set c++ /usr/bin/g++
sudo update-alternatives --config gcc
sudo update-alternatives --config g++
また、私の環境ではlibjepg-dev, libjpeg9-dev, libpng-devが無かったので追加した。
sudo apt-get install libjpeg-dev libjpeg9-dev libpng-dev
このあたり追加が必要なライブラリーは環境によって異なると思われるので、各自必要なライブラリーを追加していただきたい。
さらにリンク時にtinfoが見つからないというエラーが出たため、以下のようなシンボリックリンクを作成した
sudo ln -s /lib/x86_64-linux-gnu/libtinfo.so.5 /lib/x86_64-linux-gnu/libtinfo.so
Tutorial実行の注意点
Halideのチュートリアルはこちらにある。
http://halide-lang.org/tutorials/tutorial_introduction.html
また同じ内容が先ほどインストールしたHalideパッケージ内のtutorialフォルダーに含まれている。
基本的にチュートリアルで指示されているとおりにコンパイル用のコマンドをと実行用のコマンドを入力するだけなのだが、私の環境では若干の変更を入れないとエラーがでて実行できないケースがあった。
02 Processing Images
コンパイル用のコマンドを元の
g++ lesson_02*.cpp -g -I ../include -I ../tools -L ../bin -lHalide `libpng-config --cflags --ldflags` -o lesson_02 -std=c++11
から、
g++ lesson_02*.cpp -g -I ../include -I ../tools -L ../bin -lHalide `libpng-config --cflags --ldflags` -o lesson_02 -std=c++11 -ljpeg
に変更(-ljpegの追加)
07 Multi-stage pipelines
02 Processing Imagesと同様に-ljpegが必要
g++ lesson_07*.cpp -g -std=c++11 -I ../include -I ../tools -L ../bin -lHalide `libpng-config --cflags --ldflags` -o lesson_07 -ljpeg
DYLD_LIBRARY_PATH=../bin ./lesson_07
09 Multi-pass Funcs, update definitions, and reductions
チュートリアル内ではこのように書かれている。
On linux, you can compile and run it like so:
g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -lpthread -ldl -o lesson_10_generate LD_LIBRARY_PATH=../bin ./lesson_10_generate g++ lesson_10*run.cpp lesson_10_halide.a -lpthread -ldl -o lesson_10_run ./lesson_10_run
しかし、私の環境ではHalideBuffer.hが見つからないというエラーなどが出たので以下のようにした。
g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -lpthread -ldl -o lesson_10_generate
LD_LIBRARY_PATH=../bin ./lesson_10_generate
g++ lesson_10*run.cpp lesson_10_halide.a -std=c++11 -I ../include -lpthread -ldl -o lesson_10_run
./lesson_10_run
二回目のg++の実行時に -I ../include
を追加されている。
12 Using the GPU
まず、-ljpegを入れないと私の環境ではコンパイルされなかったので、追加
g++ lesson_12*.cpp -g -std=c++11 -I ../include -I ../tools -L ../bin -lHalide `libpng-config --cflags --ldflags` -lpthread -ldl -o lesson_12 -ljpeg
こうしてコンパイルしても、GPUに対応するOpenCLがインストールされていない場合はこのような実行結果だった
Testing performance on CPU:
1.0027 milliseconds
Not testing performance on GPU, because I can't find the opencl library
GPUと速度比較する場合はopenclをインストールしておく必要がある。私の環境ではNVIDIAのビデオカードを使用しているので、以下のようにしてインストールした。
sudo apt-get install nvidia-opencl-dev
OpenCLをインストール後は、次のような結果が表示された
Testing performance on CPU:
0.7788 milliseconds
Testing performance on GPU:
0.5871 milliseconds
思ったほど差がでないのは処理が軽いからだろうか。
16 RGB images and memory layouts
以下の部分がチュートリアルの記述のままでは動作しなかった。
g++ lesson_16_rgb_run.cpp brighten_*.o -ldl -lpthread -o lesson_16_run
以下のように変更
g++ lesson_16_rgb_run.cpp brighten_* -ldl -lpthread -o lesson_16_run -I ../include -std=c++11
これですべてのチュートリアルを実行することができた。
なお、Halideのコンパイルが一通り終わった後はコンパイラの設定を元にもどしておくことを強くおすすめする。[^3]
[^3]: 実は最初に実行した後で気が付かずひどい目にあった
sudo update-alternatives --config gcc
sudo update-alternatives --config g++
まとめ
以上、Halideのチュートリアルを、Ubuntu16.04-64bitで実行した際の環境設定とそのほかの変更点を記録しておいた。