目的
Fedora 35 + CUDAの環境でOpen3Dをビルドできるようにしたい。
環境
2021.12.25時点の環境は以下。
- Fedora 35 x86_64
- gcc version 11.2.1 20211203 (Red Hat 11.2.1-7) (GCC)
- CUDA 11.5 + cuDNN v8.3.1
Fedora 35で発生するビルドエラー
Open3DはLinuxディストリビューションではUbuntuが公式の環境となっている。
このため、Fedora 35だと様々なエラーが発生する。
- サポートするPythonバージョンが一致しない。
- GCCバージョンによる(CUDA、C++14 vs C++17)ビルド、リンク時にエラーが発生。
- 不足しているモジュールのインストールが必要。
今回はそれらを解決・回避しながら、v0.14.0で追加されたOpen3D for TensorBoardが動作するところまでやってみる。
事前の準備
- Python3.9のインストール
Fedora 35のPythonは3.10が標準である。
Open3DはPython 3.9までをサポートのため、ビルド時にエラーが発生する。
このため、Open3Dではなく、Fedoraに3.9をインストールし、仮想環境で対応することとする。
Python3.9のパッケージをインストール後、virtualenvwrapperで仮想環境を作成する。
sudo dnf install python3.9 mkvirtualenv --python=python3.9 open3d_p39
以降、仮想環境で作業する。
GCC 11.1のビルド
Fedora
35の場合、Open3DとTensorFlowをCUDAを有効でビルドする場合、GCCのバージョンが問題となる。
前回のブログを参照。
CUDAのコンパイラーのために、GCC11.1をソースビルドしておく。
ビルドについては上記のブログを参照。
TensorFlow 2.5のビルド
Open3D v0.14.0では、TensorFlow v2.5を期待している。
おそらく、TensorFlow v2.7でもOKな気がするが、
v2.5.2をビルドして、インストールする。
ビルド方法は前回のブログと同様なので詳細は割愛。
ただし、v2.5.2の場合、ビルド中にRuyでビルドエラーが発生してしまう。
external/ruy/ruy/block_map.cc: In function ‘void ruy::MakeBlockMap(int, int, int, int, int, int, int, int, const ruy::CpuCacheParams&, ruy::BlockMap*)’: external/ruy/ruy/block_map.cc:395:25: error: ‘numeric_limits’ is not a member of ‘std’ 395 | int best_score = std::numeric_limits<int>::min(); | ^~~~~~~~~~~~~~ external/ruy/ruy/block_map.cc:395:40: error: expected primary-expression before ‘int’ 395 | int best_score = std::numeric_limits<int>::min(); | ^~~ Target //tensorflow/tools/pip_package:build_pip_package failed to build
ビルドエラーが発生した後、該当のモジュール(bazelのキャッシュにある)のソースを修正して、再度ビルドする。
<Bazelのキャッシュディレクトリ>external/ruy/ruy/block_map.cc
にヘッダのインクルードを追加する。
詳細は以下を参照。
ビルド後、pipパッケージを作成し、インストールする。
Open3Dのビルド
さて、ここまできたので後はOpen3Dのビルド。
必要なパッケージのインストール(思いつくもの)
Open3D for TensorBoardを動作させるために必要なモジュールをインストールする。
- yapfはpipパッケージの作成の際にないとエラーとなる。
- nodejs、jupyter関連のモジュールはTensorBoard起動時にないとエラーとなる。
sudo dnf install nodejs sudo npm install -g yarn pip install yapf pip install jupyter_packaging ipywidgets jupyterlab
ソースコードのCloneと修正
現時点(2021.12.26)のOpen3Dのコードのままだとビルドできない。
一番の問題は、CUDAのコンパイラーを指定するCMAKE_CUDA_HOST_COMPILERフラグが3rdpartyモジュールで指定されないことと、3rdpartyモジュールのfaissはCMAKE_CUDA_HOST_COMPILERフラグにCMAKE_CXX_COMPILERフラグを指定していることである。
このため、3rdpartyモジュールのビルド時にビルドエラーが発生する。
3rdpartyモジュールにもCMAKE_CUDA_HOST_COMPILERフラグを指定することと、faissのCMakeLists.txtにパッチを当てる。
forkリポジトリに上記を対応したブランチを用意した。
これをつかってビルドを行う。
git clone https://github.com/NobuoTsukamoto/Open3D.git cd Open3D git ckeckout fedora_cuda_build cd .. git clone https://github.com/isl-org/Open3D-ML.git mkdir build cd build
CMAKE
BUILD_TENSORFLOW_OPSを有効としてビルドするのだが、そのままビルドすると、pipパッケージの作成でエラーが発生してしまう。
- https://zenn.dev/link/comments/50c45f4523bb90
これは、TensorFlowはC++14でビルド(std=gun++14)だが、Open3DはC++17(GCC11.2のデフォルト)でビルドしているため。
tf.load_op_libraryでopen3d_tf_ops.soをロードする際にundefined
symbolが発生してしまう。
詳細は以下のissueも参照。
このため、CMAKE_CXX_STANDARD=14を指定することで解決する。
上記の2つのポイントは、
- CMAKE_CUDA_HOST_COMPILERでCUDAのコンパイラー(GCC 11.1)を指定
- CMAKE_CXX_STANDARDでC++14を指定
である。
cmake ../Open3D \ -DBUILD_TENSORFLOW_OPS=ON \ -DBUILD_BENCHMARKS=ON \ -DBUILD_CUDA_MODULE=ON \ -DBUNDLE_OPEN3D_ML=ON \ -DBUILD_JUPYTER_EXTENSION=ON \ -DBUILD_WEBRTC=ON \ -DOPEN3D_ML_ROOT=/home/xxxxx/WorkSpace/open3d/Open3D-ML/ \ -DCMAKE_CXX_STANDARD=14 \ -DCMAKE_CUDA_HOST_COMPILER=/home/xxxxx/gcc/11.1/bin/gcc
ビルド
あとは、ビルドしてpipパッケージを作成、インストールする。
make -j$(nproc) sudo make install make pip-package pip install lib/python_package/pip_package/open3d-0.14.1+3d75e332f-cp39-cp39-manylinux_2_34_x86_64.whl
ビルド後の確認
Open3D for TensorBoardのサンプルの通りやってみる。
cd ../Open3D python examples/python/gui/tensorboard_tensorflow.py small_scale tensorboard --logdir demo_logs/tf
リンクを開くとTensorBoardが起動する。
Open3D for TensorBoard
— nb.o (@Nextremer_nb_o) December 25, 2021
Fedora 35 + TensorFlow + CUDAでできたよ🎉 pic.twitter.com/rlrYycPD8n
OK!!!!!!!!!