Wednesday 18 May 2016

CentOS 7 で Waifu2x を動作させるには

自分のポストの翻訳版です。
http://k2-rnd.blogspot.jp/2016/05/how-to-setup-waifu2x-on-centos7.html

!! こちらの Python+OpenCL 版の動作はかなり遅い !!
!! 他に C++, OpenCV+OpenCL 版を試して、良い結果を得た !!
!! 従って、直近にそれ対応の導入ガイドを投稿する予定 !! 
参考したガイド:
https://wiki.tiker.net/OpenCLHowTo

動作させるのにいろんな難関を直面したので、備忘録的にガイドを作成しました。
特に OpenCL あたりのリンク関連がかなり面倒でした・・・
( Intel 版は問題はありません。問題児は AMD 版のみです。)

Waifu2x とは?
簡単に言うと、アニメや二次元向けの画像拡大するものです。

本家 Waifu2x:
https://github.com/nagadomi/waifu2x (@ultraistter)

使用する派生 Waifu2x: cl-waifu2x (Waifu2x OpenCL)
https://github.com/marcan/cl-waifu2x (@marcan42)

cl-waifu2x を使用する理由:
本家の方では CUDA 対応の NVIDIA のグラフィックボードが必須でして、
OpenCL さえ有れば動ける Python-OpenCL の派生版を使用しました。
OpenCL も必要無いのであれば、以下のものを使っても大丈夫、らしいです。
https://marcan.st/transf/waifu2x.py
( cl-waifu2x と同じ作者)

依存物:
- Python >= 2.7
- numpy
- scipy
- PIL (or Pillow) < 3.0.0 ( 3.x 以降は fromstring() 関連のエラーがあります)
- OpenCL ヘッダ
- OpenCL ライブラリ (AMD or Intel)
- Boost(推奨)
- OpenCL Test Tool(推奨)
- PyOpenCL

導入手順:
- Python, numpy, scipy, OpenCL headers, Boost などを入れる
# yum install python numpy scipy opencl-headers boost boost-devel ctags

- Pillow ( 2.9.0 ) を入れる
# easy_install pillow==2.9.0 

- OpenCL を入れる( Intel 版、簡単)
* Intel 版は SSE4.2 以降を対応する CPU が必要です。
** 執筆した時点では v16.1 が最新版でした。 url など変わるかもしれません。
*** v16.1 では redhat-lsb-core が必要です。
**** ダウンロードサイト: https://software.intel.com/en-us/articles/opencl-drivers
# yum install redhat-lsb-core
# wget http://registrationcenter-download.intel.com/akdlm/irc_nas/9019/opencl_runtime_16.1_x64_rh_5.2.0.10002.tgz
# tar xzvf opencl_runtime_16.1_x64_rh_5.2.0.10002.tgz
# ./install.sh

特に問題が発生しないはずです。セットアップを終わらせましょう。

- OpenCL を入れる( AMD 版、問題児)
* AMD 版は SSE3 以降を対応する CPU が必要です。
** セットアップ自体は楽ですが、設定が・・・
*** 最大の難関は OpenCL へのリンクあたり・・・
**** ダウンロードサイト: http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/
# tar xjvf AMD-APP-SDKInstaller-v3.0.130.136-GA-linux64.tar.bz2
# ./AMD-APP-SDK-v3.0.130.136-GA-linux64.sh
# vi /etc/ld.so.conf (add /opt/AMDAPPSDK-3.0/lib/x86_64/sdk )
# ln -s /opt/AMDAPPSDK-3.0/lib/x86_64/sdk/libOpenCL.so.1 /usr/lib/libOpenCL.so.1
# ln -s /opt/AMDAPPSDK-3.0/lib/x86_64/sdk/libOpenCL.so.1 /usr/lib64/libOpenCL.so.1

おめでとう〜これで OpenCL の導入が終わりました!
OpenCL を試すには、以下のツールをセットアップしてくださいませ。
(必須ではありません)
# curl https://codeload.github.com/hpc12/tools/tar.gz/master | tar xvfz -
# cd tools-master

難関その1
Intel 版の場合:
# make

AMD 版の場合:
# make OPENCL_INC=/opt/AMDAPPSDK-3.0/include OPENCL_LIB=/opt/AMDAPPSDK-3.0/lib/x86_64/sdk

OpenCL デバイスの一覧コマンド:
# ./print-devices
OpenCL を実験するには:
# ./cl-demo 1000000 10
セットアップが成功すれば、エラーが出ないでしょう。
Intel 版を導入して、実行時に "Device Not Available" エラーが発生したら、つまり使用している CPU は SSE4.2 対応してません。 AMD 版を使いましょう><

インストールを続行します。
- PyOpenCLを入れる。
* easy_install や pip 経由で入れないように、失敗するオチです。
** 執筆時では 2016.1が最新です。
# wget https://pypi.python.org/packages/cb/4e/fcb45db7d3005f5646f28a3de2a2f8e60a6e4b629f02bbb331320778f3a1/pyopencl-2016.1.tar.gz
# tar xzvf pyopencl-2016.1.tar.gz
# cd pyopencl-2016.1

難関その2
Intel 版の場合:
# python configure.py

AMD 版の場合:
# python configure.py --cl-inc-dir=/opt/AMDAPPSDK-3.0/include --cl-lib-dir=/opt/AMDAPPSDK-3.0/lib/x86_64/sdkintel/opencl/lib64 --cl-libname=OpenCL

ビルドを実行:
# make

難関その3( AMD 版のみ)
ビルド途中、 OpenCL が見つからないエラーで失敗する可能性があります。
理由はパラメーターが正しく渡されてないだけです。
以下のコードを実行して再ビルドすればいいです。
# g++ -pthread -shared -Wl,-z,relro build/temp.linux-x86_64-2.7/build/temp.linux-x86_64-2.7/pyopencl._cffi.o build/temp.linux-x86_64-2.7/src/c_wrapper/wrap_cl.o build/temp.linux-x86_64-2.7/src/c_wrapper/wrap_constants.o build/temp.linux-x86_64-2.7/src/c_wrapper/bitlog.o build/temp.linux-x86_64-2.7/src/c_wrapper/pyhelper.o build/temp.linux-x86_64-2.7/src/c_wrapper/platform.o build/temp.linux-x86_64-2.7/src/c_wrapper/device.o build/temp.linux-x86_64-2.7/src/c_wrapper/context.o build/temp.linux-x86_64-2.7/src/c_wrapper/command_queue.o build/temp.linux-x86_64-2.7/src/c_wrapper/event.o build/temp.linux-x86_64-2.7/src/c_wrapper/memory_object.o build/temp.linux-x86_64-2.7/src/c_wrapper/image.o build/temp.linux-x86_64-2.7/src/c_wrapper/gl_obj.o build/temp.linux-x86_64-2.7/src/c_wrapper/memory_map.o build/temp.linux-x86_64-2.7/src/c_wrapper/buffer.o build/temp.linux-x86_64-2.7/src/c_wrapper/sampler.o build/temp.linux-x86_64-2.7/src/c_wrapper/program.o build/temp.linux-x86_64-2.7/src/c_wrapper/kernel.o build/temp.linux-x86_64-2.7/src/c_wrapper/debug.o -L/opt/AMDAPPSDK-3.0/lib/x86_64/sdk -L. -lOpenCL -lpython2.7 -o build/lib.linux-x86_64-2.7/pyopencl/_cffi.so

インストールを完了します。
# make install

cl-waifu2x を clone する
# git clone https://github.com/marcan/cl-waifu2x.git
# cd cl-waifu2x

Waifu2x を動作する
# python cl-waifu2x.py image-source.png image-waifu2x.png models/scale2.0x_model.json

以上です!
Waifu2x を楽しんでくださいませ〜

How to setup Waifu2x on CentOS7

!! The Python+OpenCL variant used is very slow !!
!! I tested C++, OpenCV+OpenCL variant and it's pretty fast !!
!! Will write the installation guide soon on another post !!

Based on this guide:
https://wiki.tiker.net/OpenCLHowTo

I was having a struggle to get it to work. Especially linking OpenCL.
(No problem with Intel counterpart, but the AMD ones...)

What is Waifu2x?
To sum it simple, it's basically an up-scaller for anime-style image.

Original Waifu2x:
https://github.com/nagadomi/waifu2x (@ultraistter)

Waifu2x I'm using: cl-waifu2x (Waifu2x OpenCL)
https://github.com/marcan/cl-waifu2x (@marcan42)

Reason of using cl-waifu2x:
The original counterpart dependencies requires NVIDIA GPU with CUDA support,
therefore I chose the Python-OpenCL version as it can be done as long as OpenCL is available.

If you do not need OpenCL, you can use this:
https://marcan.st/transf/waifu2x.py
(Same author as cl-waifu2x)

Required:
- Python >= 2.7
- numpy
- scipy
- PIL (or Pillow) < 3.0.0 (3.x above will trigger fromstring() exception)
- OpenCL headers
- OpenCL library (AMD or Intel)
- Boost (Optional)
- OpenCL Test Tool (Optional)
- PyOpenCL

Installation steps:
- Install Python, numpy, scipy, OpenCL headers, Boost
# yum install python numpy scipy opencl-headers boost boost-devel ctags

- Install Pillow (Uses 2.9.0)
# easy_install pillow==2.9.0 

- Install OpenCL Library (Intel OpenCL. the simple way)
* Intel OpenCL requires CPU that supports SSE4.2 and onwards
** Using v16.1 when writing this guide, url might changes.
*** You need redhat-lsb-core for v16.1
**** You can download it here: https://software.intel.com/en-us/articles/opencl-drivers
# yum install redhat-lsb-core
# wget http://registrationcenter-download.intel.com/akdlm/irc_nas/9019/opencl_runtime_16.1_x64_rh_5.2.0.10002.tgz
# tar xzvf opencl_runtime_16.1_x64_rh_5.2.0.10002.tgz
# ./install.sh

Just proceed the installation, nothing much to setting.

- Install OpenCL Library (AMD OpenCL, the hard way)
* AMD OpenCL requires CPU that supports SSE3 and onwards
** The installation is not that hard, but faulty...
*** The real pain lies on linking to AMD OpenCL
**** You can download it here: http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/
# tar xjvf AMD-APP-SDKInstaller-v3.0.130.136-GA-linux64.tar.bz2
# ./AMD-APP-SDK-v3.0.130.136-GA-linux64.sh
# vi /etc/ld.so.conf (add /opt/AMDAPPSDK-3.0/lib/x86_64/sdk )
# ln -s /opt/AMDAPPSDK-3.0/lib/x86_64/sdk/libOpenCL.so.1 /usr/lib/libOpenCL.so.1
# ln -s /opt/AMDAPPSDK-3.0/lib/x86_64/sdk/libOpenCL.so.1 /usr/lib64/libOpenCL.so.1

Congrats! You have complete installing OpenCL!
You can test OpenCL by installing the Test Tool.
(You can skip this)
# curl https://codeload.github.com/hpc12/tools/tar.gz/master | tar xvfz -
# cd tools-master

Treaky part-1
Using Intel OpenCL:
# make
Using AMD OpenCL:
# make OPENCL_INC=/opt/AMDAPPSDK-3.0/include OPENCL_LIB=/opt/AMDAPPSDK-3.0/lib/x86_64/sdk

List of Possible OpenCL Device:
# ./print-devices
OpenCL Demo:
# ./cl-demo 1000000 10
If your installation is successful, you should not get no error.
If you installed Intel OpenCL but you get Device Not Available error, it means that your CPU do not support SSE4.2. Use AMD OpenCL instead.

Continue installation.
- Install PyOpenCL.
* Do not install using easy_install or pip, it won't build properly
** 2016.1 was the latest version when writing this guide.
# wget https://pypi.python.org/packages/cb/4e/fcb45db7d3005f5646f28a3de2a2f8e60a6e4b629f02bbb331320778f3a1/pyopencl-2016.1.tar.gz
# tar xzvf pyopencl-2016.1.tar.gz
# cd pyopencl-2016.1

Treaky part-2
Using Intel OpenCL:
# python configure.py

Using AMD OpenCL:
# python configure.py --cl-inc-dir=/opt/AMDAPPSDK-3.0/include --cl-lib-dir=/opt/AMDAPPSDK-3.0/lib/x86_64/sdkintel/opencl/lib64 --cl-libname=OpenCL

Proceed to build:
# make

Treaky part-3 (AMD OpenCL Only)
You might break the make for the last sentence as you get the OpenCL not found error.
It just that the parameter was passed wrongly, you just need to run this once and rerun # make
# g++ -pthread -shared -Wl,-z,relro build/temp.linux-x86_64-2.7/build/temp.linux-x86_64-2.7/pyopencl._cffi.o build/temp.linux-x86_64-2.7/src/c_wrapper/wrap_cl.o build/temp.linux-x86_64-2.7/src/c_wrapper/wrap_constants.o build/temp.linux-x86_64-2.7/src/c_wrapper/bitlog.o build/temp.linux-x86_64-2.7/src/c_wrapper/pyhelper.o build/temp.linux-x86_64-2.7/src/c_wrapper/platform.o build/temp.linux-x86_64-2.7/src/c_wrapper/device.o build/temp.linux-x86_64-2.7/src/c_wrapper/context.o build/temp.linux-x86_64-2.7/src/c_wrapper/command_queue.o build/temp.linux-x86_64-2.7/src/c_wrapper/event.o build/temp.linux-x86_64-2.7/src/c_wrapper/memory_object.o build/temp.linux-x86_64-2.7/src/c_wrapper/image.o build/temp.linux-x86_64-2.7/src/c_wrapper/gl_obj.o build/temp.linux-x86_64-2.7/src/c_wrapper/memory_map.o build/temp.linux-x86_64-2.7/src/c_wrapper/buffer.o build/temp.linux-x86_64-2.7/src/c_wrapper/sampler.o build/temp.linux-x86_64-2.7/src/c_wrapper/program.o build/temp.linux-x86_64-2.7/src/c_wrapper/kernel.o build/temp.linux-x86_64-2.7/src/c_wrapper/debug.o -L/opt/AMDAPPSDK-3.0/lib/x86_64/sdk -L. -lOpenCL -lpython2.7 -o build/lib.linux-x86_64-2.7/pyopencl/_cffi.so

Complete the installation.
# make install

Getting cl-waifu2x
# git clone https://github.com/marcan/cl-waifu2x.git
# cd cl-waifu2x

Test Waifu2x.
# python cl-waifu2x.py image-source.png image-waifu2x.png models/scale2.0x_model.json

That's all!
Have fun with Waifu2x!