2021年12月26日日曜日

Fedora 35でOpen3D(CUDA+TensorFlow)をビルドする

目的


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が起動する。



OK!!!!!!!!!

0 件のコメント:

コメントを投稿