Help us understand the problem. What is going on with this article?

ROCm pytorch をコンパイルする試み(2018 年 7 月 27 日時点 実行時 seg fault)

More than 1 year has passed since last update.

pytorch を ROCm でコンパイルにチャレンジします.

2018 年 7 月 27 日時点まとめ

乱数ライブラリ(hcrng)の対応が過渡期のためか, いろいろ頑張ってコンパイルはできても, strace で確認すると乱数ライブラリを呼ぶところで seg fault することがわかりました.
しばらく様子見ですね.

https://github.com/ROCmSoftwarePlatform/pytorch/pull/41
https://github.com/ROCmSoftwarePlatform/pytorch/pull/80

以下, メモ...

Ubuntu 16.04 + ROCm 1.8.2 で環境を整えているものとします.

途中まではうまく行きますが, caffe2/proto/caffe2.pb.h ヘッダが見つからないというエラーがでて, うんうんと悩んで原因調べてみたところ, CMake generator expression の挙動でうまくコンパイルできないことがわかりました.

pytorch repo の cmake/Dependency.cmake

    set(Caffe2_HIP_INCLUDES
      ${hip_INCLUDE_DIRS} ${hcc_INCLUDE_DIRS} ${hsa_INCLUDE_DIRS} ${rocrand_INCLUDE_DIRS} ${hiprand_INCLUDE_DIRS} ${rocblas_INCLUDE_DIRS} ${miopen_INCLUDE_DIRS} ${thrust_INCLUDE_DIRS} $<INSTALL_INTERFACE:include> ${Caffe2_HIP_INCLUDES})

というのがあります.

ここの $<INSTALL_INTERFACE:include> は CMake generator expression であり,

https://cmake.org/cmake/help/v3.2/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.html

基本的には特定の cmake コマンド(e.g. target_include_directories)でしか値が展開できないようになっています(他の環境では値が展開されません(要検証))

pytorch rocm ポートでは, HIP でコンパイルするために, hip_include_directories() に include path を渡し, それを外部コマンドへの引数に渡しているため, ここで問題があります.

apt で入る HIP(/opt/rocm/hip) はいくらか古いため, opt/rocm/hip/cmake/FindHIP.cmake において, hip_include_directories の定義は以下のようになっています.

macro(HIP_INCLUDE_DIRECTORIES)
    foreach(dir ${ARGN})
        list(APPEND HIP_HIPCC_INCLUDE_ARGS_USER -I${dir})
    endforeach()
endmacro()

generator script は展開されると空文字になるため(要検証), これだと

-I$<INSTALL_INTERFACE:include> -I/path/to/protobuf/src

となり, これが展開されて HIP コンパイラには以下が渡ります.

-I -I/path/to/protobuf/src

ここで, gcc/clang では, 空の -I があると, 後続の -I/path/to/protobuf/src をサーチパスとして認識する挙動になっているため, これにより /path/to/protobuf/src にパスが通らずにコンパイルが失敗します.

では, Caffe2_HIP_INCLUDES から $<INSTALL_INTERFACE:include> を除けばいいのかといういうと, 実際には gloo や gtest などの submodule でも include path に $<INSTALL_INTERFACE:include> を使うような cmake 記述があり, pytorch/caffe2 ではこれらの変数も参照していますから, FindHIP をやはり修正しないとダメです.

最新の FindHIP.cmake をみますと

https://github.com/ROCm-Developer-Tools/HIP/blob/master/cmake/FindHIP.cmake#L290

list(APPEND HIP_HIPCC_INCLUDE_ARGS_USER $<$<BOOL:${dir}>:-I${dir}>)

となり, この generator expression による空の -I 問題が解決されています.

pytorch の Docker + Jenkins ビルドスクリプトでは, そのための work around の記述があります.

https://github.com/pytorch/pytorch/blob/master/docker/caffe2/jenkins/common/install_rocm.sh#L39

build cofiguration についても修正がありますね.

https://github.com/pytorch/pytorch/blob/master/docker/caffe2/jenkins/common/install_rocm.sh#L45

(2018 年 7 月 27 日時点, ここまで)

以下, 作業メモ...

環境

  • (mini)conda
  • その他, で apt や pip パッケージを入れているとします

Docker 用のビルドスクリプト

https://github.com/pytorch/pytorch/blob/master/docker/caffe2/jenkins/common/install_rocm.sh

を参考にします.

pytorch 本家での CI サーバのビルド状態も確認しておきましょう.

py2-clang3.8-rocmnightly-ubuntu16.04-test など, rocmnightly の文字があるターゲットになります.

https://ezyang.github.io/pytorch-ci-hud/build/pytorch-master

hipblas https://github.com/ROCmSoftwarePlatform/hipBLAS を入れます.

$ sudo apt-get install hipblas

ROCm(HIP)版 Thrust をインストールします.

https://github.com/ROCmSoftwarePlatform/Thrust

apt package は無いので git clone. /opt/rocm/Thrust にインストールするものとします. Thrust はヘッダファイル集なのでビルドは不要です.
cub-hip が submodule になっているので, 忘れずに submodule も checkout しておきます.

$ git clone --recursive https://github.com/ROCmSoftwarePlatform/Thrust
$ sudo mv Thrust /opt/rocm/ 

https://github.com/ROCmSoftwarePlatform/pytorch

を clone します.

$ git clone --recursive https://github.com/ROCmSoftwarePlatform/pytorch pytorch-rocm

(pytorch オフィシャルの repo だと, hcrnd, hcsparse が見つからないとエラーがでま)

python の環境を作ります. 今回は 3.6 にしました.

$ conda create -n py36 python=3.6
$ source activate py36

前処理として, hippify(CUDA コードの HIP 化?)をします.

(py27) $ cd pytorch-rocm
(py27) $ python tools/amd_build/build_pytorch_amd.py

1 分くらいかかりますのでしばらく待ちます(プログレスが出ないので少し不安になります)

一度実行していると, すでに patch が当たっていて fail するなどのエラーが出ます(変換自体には影響無い模様) 再実行するときは一度 git checkout しておくとよいかもしれません.

ROCm を on にしてビルドします.

USE_ROCM=1 を指定しないと, caffe2 自体は ROCm(HIP) 環境が見つかれば ROCm(HIP) 有効でビルドされますが, python binding のほうが ROCm 有効にならず, torch.cuda.is_available() が false になってしまうので注意ください.

$ USE_ROCM=1 python setup.py install

libcaffe2_hip.so のリンクにめちゃめちゃ時間がかかります. Ryzen2700X で 10~20 分くらい.
(ROCm clang opt で最適化しているようですが, その最適化処理に時間がかかっています)

再ビルドでもなぜか hip カーネル周り再コンパイルになってつらい(hipcc を外部コマンドで呼び出すところはキャッシュされないから?)

setup_caffe2.py もありますが, これは少なくとも ROCm ビルドでは setup.py から呼ばれるのを想定するようで, setup_caffe2.py で caffe2 だけビルドしようとしてもうまくいきませんでした.

実行時セットアップ

libcaffe2_hip.so は HIP clang でコンパイルされていますが, libcxx がデフォルトになっているようで, import torch とすると,

ImportError: libc++.so.1: cannot open shared object file: No such file or directory

と出ます...

libc++.so は rocm パッケージ(prebult HIP パッケージ)に含まれていないので, 自前ビルドします...
(もしかしたら llvm.org で配布している prebuilt package でも動くかもしれません)

ROCm 1.8.2 の hcc では clang 7(ToT, top of trunk) ですが, 6.0.1 release でも大丈夫のようです.

http://releases.llvm.org/download.html#6.0.1

libcxx, libcxxabi をインストールしておきます.
(default の /usr/local に install すると仮定. clang++/clang は hcc の clang++(e.g. /opt/rocm/hcc/clang++) を仮定)

$ cd libcxx
$ mkdir build
$ cd build
$ CXX=clang++ CC=clang cmake ..
$ make
$ (sudo) make install
$ cd libcxxabi
$ mkdir build
$ cd build
$ CXX=clang++ CC=clang cmake -DLIBCXXABI_LIBCXX_INCLUDES=/usr/local/include/c++/v1 ..
$ make
$ (sudo) make install

インストールした先の lib ディレクトリを LD_LIBRARY_PATH に設定しておきます.

import torch
torch.cuda.is_available()

で True が返れば成功です!

TODO

pytorch の ROCm ビルド手順ドキュメントが無くてかなしい.
(web とか Jenkins CI のスクリプトを見るしかない)

https://github.com/RadeonOpenCompute/hcc/tree/roc-1.8.x

の ThinLTO でリンクが早くなるかしら?

export KMTHINLTO=1
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away