目的
Tensorflowの2.9rc2 + CUDAをFedora 36でソースビルドする。
環境
- SW
- Fedora 35 x86_64
- Python 3.10.4
- GCC 12.0.1 20220308
- CUDA 11.6 + cuDNN v8.4.0
- HW
- CPU AMD Ryzen 7 1700
- GPU GeForce GTX 1070
事前の準備
CUDA、cuDNNのインストール
これは、以前のブログと同様。
RPM Fusionを参考にCUDAを、NVIDIAよりcuDNNをそれぞれインストールする。
Bazelのソースビルド
TensorFlow v2.9はBazel 5.0.0以上でのビルドが必要。
FedoraのCOPR repositoryからインストール(公式の手順にもある)できるバージョンは4系でビルドできない。
このため、v5.1.1をソースビルドする。
$ sudo dnf install java-11-openjdk-devel $ wget https://github.com/bazelbuild/bazel/releases/download/5.1.1/bazel-5.1.1-dist.zip $ unzip -qq bazel-5.1.1-dist.zip $ env EXTRA_BAZEL_ARGS="--host_javabase=@local_jdk//:jdk" bash ./compile.sh $ sudo cp output/bazel /usr/local/bin/
GCC11.2のビルド
CUDA 11.6がサポートするGCCのバージョンは11.2で、Fedora 36のGCC12は対象外。
このため、GCC 11.2をソースビルドする。
ビルドについては、以前のブログを参照。
ソースダウンロード&ビルド
$ wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-11.2.0/gcc-11.2.0.tar.gz $ tar xf gcc-11.2.0.tar.gz $ gcc-11.2.0/ $ ./contrib/download_prerequisites $ mkdir build && cd build $ ../configure \ --enable-bootstrap \ --enable-languages=c,c++ \ --prefix=/home/USER/gcc/11.2 \ --enable-shared \ --enable-threads=posix \ --enable-checking=release \ --disable-multilib \ --with-system-zlib \ --enable-__cxa_atexit \ --disable-libunwind-exceptions \ --enable-gnu-unique-object \ --enable-linker-build-id \ --with-gcc-major-version-only \ --with-linker-hash-style=gnu \ --enable-plugin \ --enable-initfini-array \ --with-isl \ --enable-libmpx \ --enable-gnu-indirect-function \ --build=x86_64-redhat-linux $ make -j$(nproc) $ make install
specsファイルの作成&設定
コンパイルしたGCC11でビルドした際に、適切な動的リンクライブラリ(libstdc++.so)がリンクされるようにSPECEファイルを修正する。
$ /home/USER/gcc/11.2/bin/gcc -dumpspecs > specs $ vi specs # before *link_libgcc: %D # after *link_libgcc: %{!static:%{!static-libgcc:-rpath /home/USER/gcc/11.2/lib64/}} %D $ mv specs /home/USER/gcc/11.2/lib/gcc/x86_64-redhat-linux/11/
Tensorflowのビルド
さて、本題。TensorFlow 2.9-rc2をビルドする。
virtualenvの設定
まずはvirtualenv(virtualenvwapper)でTensorflow用の仮想Python環境を作成し、必要なモジュールをインストールする。
$ mkvirtualenv tf2.9rc2 $ pip install pip numpy wheel $ pip install keras_preprocessing --no-deps $ pip install packaging
今回、packagingモジュールも追加でインストールが必要だった。
(ビルド時にModuleNotFoundError: No module named 'packaging'エラーとなった)
ビルド
今までどおりconfigure&buildなのだが、今回は追加の手順が必要。
CUDA_HOST_COMPILERに使用するGCC11とGCC12でGLIBCXXのABIが異なってしまう。
ビルドは成功するが、import時に以下のエラーが発生してしまう。
$ python Python 3.10.4 (main, Mar 25 2022, 00:00:00) [GCC 12.0.1 20220308 (Red Hat 12.0.1-0)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tensorflow as tf Traceback (most recent call last): File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/pywrap_tensorflow.py", line 62, in <module> from tensorflow.python._pywrap_tensorflow_internal import * ImportError: /home/USER/gcc/11.2/lib64/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/__init__.py", line 37, in <module> from tensorflow.python.tools import module_util as _module_util File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/__init__.py", line 36, in <module> from tensorflow.python import pywrap_tensorflow as _pywrap_tensorflow File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/pywrap_tensorflow.py", line 77, in <module> raise ImportError( ImportError: Traceback (most recent call last): File "/home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/pywrap_tensorflow.py", line 62, in <module> from tensorflow.python._pywrap_tensorflow_internal import * ImportError: /home/USER/gcc/11.2/lib64/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so) Failed to load the native TensorFlow runtime. See https://www.tensorflow.org/install/errors for some common causes and solutions. If you need help, create an issue at https://github.com/tensorflow/tensorflow/issues and include the entire stack trace above this error message.
Fedora36のGCC12 libstdc++とビルドしたGCC11 libstdc++のGLIBCXXのABIの不一致。
これを回避するために、ビルド時のオプションに"-std=gnu++14"を付与する。
あとは、Githubからソースを取得し、configureスクリプト実行し、ビルドを行う。
- CUDAのサポートを有効とする。
- Host compilerにGCC11.2のgccのパスを指定してあげる。
- ビルドオプションには"--config=v2"、"-std=gnu++14"、"--config=nonccl "を指定。
$ ./configure You have bazel 5.1.1- (@non-git) installed. Please specify the location of python. [Default is /home/USER/.virtualenvs/tf2.9rc2/bin/python3]: Found possible Python library paths: /home/USER/.virtualenvs/tf2.9rc2/lib/python3.10/site-packages /home/USER/.virtualenvs/tf2.9rc2/lib64/python3.10/site-packages Please input the desired Python library path to use. Default is [/home/USER/.virtualenvs/tf2.9rc2/lib/python3.10/site-packages] Do you wish to build TensorFlow with ROCm support? [y/N]: No ROCm support will be enabled for TensorFlow. Do you wish to build TensorFlow with CUDA support? [y/N]: y CUDA support will be enabled for TensorFlow. Do you wish to build TensorFlow with TensorRT support? [y/N]: No TensorRT support will be enabled for TensorFlow. Found CUDA 11.6 in: /usr/local/cuda-11.6/targets/x86_64-linux/lib /usr/local/cuda-11.6/targets/x86_64-linux/include Found cuDNN 8 in: /usr/local/cuda-11.6/targets/x86_64-linux/lib /usr/local/cuda-11.6/targets/x86_64-linux/include Please specify a list of comma-separated CUDA compute capabilities you want to build with. You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus. Each capability can be specified as "x.y" or "compute_xy" to include both virtual and binary GPU code, or as "sm_xy" to only include the binary code. Please note that each additional compute capability significantly increases your build time and binary size, and that TensorFlow only supports compute capabilities >= 3.5 [Default is: 6.1]: Do you want to use clang as CUDA compiler? [y/N]: nvcc will be used as CUDA compiler. Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/bin/gcc]: /home/USER/gcc/11.2/bin/gcc Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -Wno-sign-compare]: Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]: Not configuring the WORKSPACE for Android builds. Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See .bazelrc for more details. --config=mkl # Build with MKL support. --config=mkl_aarch64 # Build with oneDNN and Compute Library for the Arm Architecture (ACL). --config=monolithic # Config for mostly static monolithic build. --config=numa # Build with NUMA support. --config=dynamic_kernels # (Experimental) Build kernels into separate shared objects. --config=v1 # Build with TensorFlow 1 API instead of TF 2 API. Preconfigured Bazel build configs to DISABLE default on features: --config=nogcp # Disable GCP support. --config=nonccl # Disable NVIDIA NCCL support. Configuration finished $ bazel build \ --config=cuda \ --config=v2 \ --config=nonccl \ --config=opt \ --cxxopt="-std=gnu++14" \ //tensorflow/tools/pip_package:build_pip_package $ ./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg $ cp /tmp/tensorflow_pkg/tensorflow-2.9.0rc2-cp310-cp310-linux_x86_64.whl ./ $ pip3 install tensorflow-2.9.0rc2-cp310-cp310-linux_x86_64.whl
インストールの確認
- tf.__version__が2.9-rc2であること。
- GPUデバイスを認識していること。
Fedora 36でTensorFlow 2.9-rc2、CUDA11.6でビルドできたよ。
— nb.o (@Nextremer_nb_o) May 14, 2022
これでFedora 36の環境はまずまずかなぁ pic.twitter.com/o8YByJiv5B