Windows10、GeForce1080Ti/1650でTensorFlow2.10.0をソースからコンパイル

# 概要
Tensorflow2.3でXLAを有効にしたのち、pipで入るパッケージが色々と不整合を起こす様になったので、
Tensorflowをバージョンアップしてpipで入れるパッケージのバージョンが上がっても対応できる様にしたい。
環境はWindows10、Geforce 1650が1台と1080Tiが1台。
動けばよいというノリなので、不要な工程もありそうな気がする。

ここでは、TensorFlow r2.10.0、都合によりPython3.9.19、CUDA11.2、cuDNN8.1、Visual Studio 2019 の Microsoft Visual C++ 再頒布可能パッケージ、Build Tools for Visual Studio 2019を入れる。
何故か？後で書く。

# tensorflowのアンインストール。

多用するので最初に書く。
トラブルの元になるので、既存のtensorflow環境を壊しても良ければだがアンインストールする。
なお、アンインストールしなくても、バージョンの不整合が発生すると思われる。

```
python -m pip uninstall -y tensorflow tensorflow-cpu tensorflow-gpu tf-models-official tensorflow_datasets tensorflow-hub keras tensorflow-text tensorboard
```

# 調査

## TensorFlowのバージョンを調べる

早々に見つけていた先達のページなんですが(バージョンアップはしてるかも)、ちゃんと読んでなかった。
https://qiita.com/kHz/items/6af115d04628ecc82c43

所持しているグラフィックカードで、入るCUDA及びTensorFlowのバージョンが異なります。

グラフィックカードのアーキテクチャについては下記がよくまとまっていると思います。
https://qiita.com/k_ikasumipowder/items/1142dadba01b42ac6012

適切なページが見つけられないのだけれども、
https://itips.krsw.biz/tensorflow-gpu-version/
https://tecsingularity.com/cuda/version-2/
https://create-it-myself.com/research/survey-about-cuda-version-for-geforce/

GeForce1080はPascalアーキテクチャ。
GeFoce1650はTuringアーキテクチャ。
アーキテクチャでCUDAバージョンが違うのかと思いましたけれども、その記載が見つけられず。
ドライバのバージョン(コンパネのアプリに出てくる方)による模様です。
https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-12-0-release-notes
自分の所のバージョンは「536.23」。

一応、元のGoogleさんのページを信じて、Tensorflow2.10.0にして、CUDA11.2、cuDNN8.1、で始める事にします。
https://www.tensorflow.org/install/source_windows?hl=ja
正確には、WindowsでサポートされてるのはTensorFlow2.10.0までの模様です。
ネットではそれでも入らない、の話があり、その場合は2.9に落とすと良いかもしれません。

## Pythonのバージョン

3.9.10にしたのは、自己都合です。

## CUDAとcuDNNのバージョン
一応、下記ページの確認済みバージョンによる。
https://www.tensorflow.org/install/source_windows?hl=ja

## Visual Studio

Googleさんと自己都合で2019。
https://www.tensorflow.org/install/source_windows?hl=ja

Visual Studio 2015、2017、2019、および 2022のVisual C++ 再頒布可能パッケージ
Microsoft Build Tools 2019

# インストール

## pythonのインストール

「python-3.9.10-amd64.exe」を「管理者モードで実行」しました。

インストールする時は、初期画面で全てのチェックボックスをチェックしないとはまります。

Pathに、下記があればOK。

```C:\Program Files\Python39\Scripts\```
```C:\Program Files\Python39\```

もしかすると、「Program Files」は「Progra~1」に書き換えた方がいいかもしれません。

なお、もっと新しいPythonを使う事もあるという人の為に、
Pathにおいて、使いたいバージョンのPythonを先に持ってきた上で、
IDEなりプロンプトなりを再起動すれば解決します。

バージョン確認。

```
python --version
```

## 番外編、プロキシ環境でのセットアップ

プロキシ認証のせいでこのままだと動かない。どこかファイルに設定する解決法がある筈だが(実際、１台のPCは何もしていない)。
これを打っても出てこなかった。

```
pip config -v list
```

結局わからなかった為に、同じコマンドプロンプトで下記実施。

```
set HTTP_PROXY=http://アカウント:パスワード@プロキシURL:ポート
set HTTPS_PROXY=http://アカウント:パスワード@プロキシURL:ポート
```

mysys2だとこちら
```
export HTTP_PROXY=http://アカウント:パスワード@プロキシURL:ポート
export HTTPS_PROXY=http://アカウント:パスワード@プロキシURL:ポート
```

ちなみに、set HTTPS_PROXY=http://、についてはhttpsの打ち間違いでは無くてhttpです。

なお、パスワードで記号を使っている場合は、例えば@なら%40などの回避が必要。昨今、パスワードの強度から記号が必須な事が多いが、こういう場合は極めて面倒臭い…。

## Visual Studio系ツールのインストール
Visual Studioのダウンロードサイトから以下をダウンロード&インストールする
注意: 2024/04/16現在、何故かBuild Tools for Visual Studio2019がダウンロードできなくなってます。
2024/09/12追記: MSDNの有償アカウントを持っていないと、過去バージョンはダウンロードできない模様です。最新はダウンロードできます。

Visual Studio 2015、2017、2019、および 2022のVisual C++ 再頒布可能パッケージのダウンロード
Build Tools for Visual Studio 2019

下記先達によると、
https://qiita.com/TrashBoxx/items/2e884998cd1193f73e2f
「インストールする場合、「C++によるデスクトップ開発」にチェックオプションに「MSVC v142 - VS 2019 C++ x64/x86 ビルドツール」にチェックが入っていることを確認してください。」となってはいますが -> 自分用のメモ。
他、自分の過去メモによると「MSVC v141及びv140も入れた方がいい様です。

2024/09/12追記: MSVCの各バージョンが不足していると、ビルド時にエラーを出力し、失敗する事が有ります。

## JIT有効化 (たぶんいらない)

要らない気はするのですが、JIT有効化です(XLAでJIT使うので)。英語の場合どうするんだろうか。

次のレジストリ キーに [無効] の [DWORD 値] を [値のデータ] を 1 として追加します。

```HKEY_LOCAL_MACHINE\Software\WOW6432Node\Microsoft\Windows\Windows Error Reporting```

そして、次のレジストリ キーに [自動] の [DWORD 値] を [値のデータ] を 1 として追加します。

```HKEY_LOCAL_MACHINE\Software\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug```

Visual Studioをインストールしている場合は下記を実施します。
[ツール] > [オプション] > [デバッグ] > [Just-In-Time] で、Just-In-Time デバッグが 有効になっていることを確認します。

## MSYS2インストール

Windowsで基本的なLinuxコマンドを使えるようになる、らしい。
MSYS2の公式サイトからダウンロード&インストールする。

### MSYS2の動作環境を整える。

上手くいかないのでWindowsメニューから「管理者権限」でMSYS2を起動、もしくは「ファイルがあるフォルダ開く」して「管理者権限で起動」した。

### MSYS2のアップデート

MSYS2を管理者権限で起動し、pacmanのパッケージを一括アップグレードする
(-Sy: 最新のパッケージデータベースをダウンロードする）
-Su: インストールしたパッケージをアップグレードする）
以下、全てMSYS2で実行。

```
pacman -Syu
```

MSYS2を再起動して以下のコマンドを実行する （[Y]でインストールを完了）

```
pacman -Su
pacman -Sy git patch unzip zip ed rsync
```

上記をやらないと、最後の方でビルドファイルを作成する時にこける。
特にPythonを再インストールすると顕著。

### MSYS2文字コード設置

MYSYS2の文字コードを変更しておかないと、後でエラーメッセージに苦しむことになる。
端末上で「右クリック」→「Options...」→「Text」の「locale」を「ja_JP」、「Character set」を「SJIS」

### MSYS2パス設定
Windows側のPATHを読み込めるようにする
Windowsの システムのプロパティ＞詳細設定＞環境変数 にて、以下を[新規]で追加する。
変数 

```MSYS2_PATH_TYPE```

値 

```inherit```

同時に下記を実施。

ファイル名を指定して実行（Windowsキー+R）でgpedit.mscを実行して、ローカルグループポリシーエディターを起動。
コンピューターの構成> 管理者用テンプレート> システム> ファイルシステム を選択し、その中にある「Win32の長いパスを有効にする」を「有効」に変更。

Pathに、下記を追加しておく。
C:\msys64にインストールされている場合は、 

```C:\msys64\usr\bin```

## Bazelインストール

tensorflow_gpu-2.10.0にはバゼル5.1.1とのことで、それを入れる。
https://www.tensorflow.org/install/source_windows?hl=ja

bazel.exeをダウンロードするディレクトリを作成し、wgetで取得する。
Bazel 実行可能ファイルの場所を%PATH%環境変数に追加します。
最後の--no-check-certificateは、カスペルスキー入れてるが故に必要だった。

```
cd /c/
mkdir bazel
cd bazel/
wget https://github.com/bazelbuild/bazel/releases/download/5.1.1/bazel-5.1.1-windows-x86_64.exe -O bazel.exe --no-check-certificate
```

あとで、Cannot find bazel. Please install bazel/bazelisk.言われるのでbazeliskを入れて置く。私はここから落としました。
https://github.com/bazelbuild/bazelisk/releases

## CUDA(NVIDIAグラフィックスドライバ)のインストール -> 要るか要らないかわからない

下記悪影響を及ぼしそうな気もするが、別に何も起きなかった。
NVIDIAグラフィックスドライバ
最新の NVIDIA 公式ドライバーをダウンロード
https://www.nvidia.co.jp
から、セットアップするPCに該当するドライバをダウンロード、インストール。
おそらく再起動を要求される。

## CUDAインストール

前述の通り、自分のグラフィックカードに合わせたバージョンを入れて下さい。
ここでは11.2を入れる。

下記より、CUDAを入手します。
CUDA Toolkit Archive
https://developer.nvidia.com/cuda-toolkit-archive

「Windows」「x86_64」「10」(おそらくWindows10)「exe(local)」選択。

これで、「cuda_11.2.0_460.89_win10.exe」をダウンロードしてきます。

PATH、CUDA_PATHにインストールしたCUDAのフォルダが含まれている事を確認。
PATHにおける場所ですが、どうも先頭の方に有った方が確実な模様(最後に書いていたら失敗した)。
私の場合、最初にPythonのPathを書いて、次にCUDAのPATHを書いている。
2024/09/12追記: 最初にPythonScriptのPathを書き、次にPythonを書き、直後にCUDAのPathを書かないと失敗する公算が大きい。 

```C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\bin```
```C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\libnvvp```

ここも、もしかすると、「Program Files\NVIDIA GPU Computing Toolkit」の代わりに「Progra~1\NVIDIA~2」の方が良いかもしれません。

一応、CUDAのインストール確認。

```
export PATH=/c/bazel:$PATH
nvcc -V
```

## cuDNNのインストール

CUDAのバージョンに対応するcuDNNを落として入れる。
cuDNN Archive
https://developer.nvidia.com/rdp/cudnn-archive

GoogleのTensorflowページより8.1.1を選択します。

これで、「cudnn-11.2-windows-x64-v8.1.1.33.zip」をダウンロードしてきます。

ダウンロードした .zip ファイルを解凍し、「cuda」フォルダ下に展開された全フォルダとファイルを、先ほどCUDA ツールキットをインストールしたディレクトリ(C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2)にコピーする。

こちらを見ると時に記載はないが、
https://docs.nvidia.com/deeplearning/cudnn/installation/windows.html

念のため、これを入れておく。
```CUDNN_PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2```


これは入れない方が良い、入れなくても入った環境がある上に、環境によっては間のバックスラッシュを無視してエラーになる。
```CUDNN_INSTALL_PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2```



またやはり記載がないが、以前は実行したのと下記により、
https://www.kkaneko.jp/tools/win/cuda.html

```
cd "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\bin"
curl -O http://www.winimage.com/zLibDll/zlib123dllx64.zip
powershell -command "Expand-Archive -Path zlib123dllx64.zip" -Force
copy zlib123dllx64\dll_x64\zlibwapi.dll .
```
なお最後の記載についてはcmdにおける書き方で、msys2においてはcopyでなくてcpですし、ディレクトリの区切り文字もバックスラッシュからスラッシュに変わります。

下記の結果くらいは確認した方がいいかもしれない。

cuDNNのインストール確認

```
export PATH=/c/bazel:$PATH
where cudnn64_8.dll
```

## Graphviz
pydotというかplot_modelするの必要。
Graphvizの公式サイトからダウンロードしてインストールする。
https://graphviz.org/download/


## LLVMのインストール
いつのまにか加わってたので入れる。
LLVM ダウンロードに移動し、
Windows 互換の LLVM を C:/Program Files/LLVM にダウンロードしてインストールします。
https://github.com/tensorflow/tensorflow/issues/60264
より
LLVM 9.0
にする。

## Pythonの各種パッケージインストール

トラブルの元になるので、既存のtensorflow環境を壊しても良ければだがアンインストールする。
なお、アンインストールしなくても、バージョンの不整合が発生すると思われる。

```
python -m pip uninstall -y tensorflow tensorflow-cpu tensorflow-gpu tf-models-official tensorflow_datasets tensorflow-hub keras tensorflow-text tensorboard
```

pipでインストールする、ただしpipのアップデートの必要性は不明。

```
pip install -U pip
```

```
pip install -U six
```

なおwheelは入れておかないと、最後にビルドしたtensorflowをpipで入れられなくなる。

```
pip install -U numpy wheel packaging
```


```
pip install mock setuptools pandas  seaborn scikit-learn scikit-learn-intelex
```

Keras

```
pip install keras
```

keras_applicationsとkeras_preprocessingもバージョン指定する必要性があったと思われるが失念。

```
pip install keras_applications --no-deps
pip install -U keras_preprocessing --no-deps
```

他に、過去に下記を実施している。

```
python -m pip install -U matlablib
python -m pip install scipy
python -m pip install -U opencv-python opencv-contrib-python
python -m pip install opencv-python

pip install pillow
pip install lxml
pip install Cython
pip install jupyter
pip install matplotlib
pip install pandas
pip install opencv-python
```

# コンパイル及びビルド

## 事前準備

ここらで一度再起動しておいた方が安全な気がする。私は引っかかったので再起動した。

### Bazelのパスを通す。

今回ややこしいのだが、mysys2とcmdを併用している。ここまではmysys2で実施している。

mysys2

```
export PATH=/c/bazel:$PATH
```

cmd

```
set PATH=C:\bazel;%PATH%
```

### MSYS2またはコマンドプロンプトの環境変数設定について。

下記は過去の経緯を残す為にだけ記載。
---------------
Progra~2にした理由は、どうもProgram Files (x86)の記載が悪さしている疑いがあったから。MIB055~1はMicrosoft Visual Studioの略です。NVIDIA~2はNVIDIA GPU Computing Toolkitの略です。

下記コマンドで、8.3形式のフォルダ名は調査可能。
dir /x

Windows SDKのバージョンを調べる方法。
https://oneuro.net/where-is-windows-sdk-version

ここまで過去のメモ。

-------
### Windowsの設定。
設定 - 更新とセキュリティ - 開発者モード をオンにする

### 現在のコマンドプロンプトの環境変数設定について
面倒な問題が起きてる模様…
cmdで下記を設定しておく。パスが変ですがオリジナルからそのまま転記しました。
mysys2だとどうなるかはすみません、試してませんが、後にパス設定だけ書いておきます。

Python パス設定の問題tensorflow:issue#59943 、 tensorflow:issue#9436 、 tensorflow:issue#60083

```
set PATH=C:\Progra~1\Python39\python.exe;%PATH%
set PATH=C:\Progra~1\Python39\lib\site-packages;%PATH%
```

Bazel/MSVC/CLANG パスのセットアップの問題tensorflow:issue#54578


```
set BAZEL_SH=C:/msys64/usr/bin/bash.exe 
set BAZEL_VS=C:\Progra~2\\Microsoft Visual Studio\2019\BuildTools
set BAZEL_VC=C:\Progra~2\\Microsoft Visual Studio\2019\BuildTools\VC
set Bazel_LLVM=C:Progra~1s\LLVM
set PATH=C:/Progra~1/LLVM/bin;%PATH%

```

mysys2の場合
```
export PATH="/C/bazel:$PATH"
export PATH="/c/Progra~1/Python39:$PATH"


export PATH="/c/Progra~1/NVIDIA~2/CUDA/v11.2/bin:$PATH"
export PATH="/c/Progra~1/NVIDIA~2/CUDA/v11.2/extras/CUPTI/libx64:$PATH"
export PATH="/c//c/Progra~1/NVIDIA~2/CUDA/v11.2/bin:$PATH"
```

## Tensorflowのソース準備

### TensorFlowのGitリポジトリを取得する

今回はcmdで実行する(パスの都合)。

```
cd c:
git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow/
```

### チェックアウト

チェックアウト。なお、r2.10の「r」をつけ忘れると見つからない。

```
git checkout r2.10
```

## コンフィグ

### 入力コマンドと、少し解説。

```
python configure.py
```

特にエラーが出なかった場合は、いくつか質問されるのでYやNなどを入力していく。
なのだが、ここで注意ではないが特記事項。
私の場合、XLAを有効化したくて実行しているのだが、何故か質問でその項目が出てこない。
何故か悩んだのだが、Tensorflow1系の場合はその項目は出てくるのだが、TensorFlow2系ではその項目は出てこない、らしい。

### 各項目について

Please specify the location of python. [Default is C:\Program Files\Python39\python.exe]:

どうも「Program Files」の指定が悪さするので、「Progra~1」にして下記入力。

```C:\Progra~1\Python39\python.exe```

Found possible Python library paths: C:\Program Files\Python37\lib\site-packages
Please input the desired Python library path to use. Default is [C:\Program Files\Python39\lib\site-packages\

同上。

```C:\Progra~1\Python39\lib\site-packages```

Do you wissh to build TensorFlow with ROCm support？

CUDAをYにするならここは絶対にN。

```N```

Do you wieh to build TensorFlow with CUDA support？
CUDA使いたいのでY。

```Y```

Do you wish to build TensorFlow with TensorRT support?
何か増えてた。DeepLearningが早くなるとか書いてるのでYとしたかったのだが、トラブルが増えたのでNとする。
```N```

Please specify the CUDA SDK version you want to use. [Leave empty to default to CUDA 11]:
「Do you wish to build TensorFlow with TensorRT support?」をYにすると出てくる。

Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 2]:
「Do you wish to build TensorFlow with TensorRT support?」をYにすると出て来るが、Enterでは無くて応じたバージョンを。この場合は(やらなかったが)8.1。

Please specify the TensorRT version you want to use. [Leave empty to default to TensorRT 6]:
「Do you wish to build TensorFlow with TensorRT support?」をYにすると出てくる。

Please specify the comma-separated list of base paths to look for CUDA libraries and headers. 
「Do you wish to build TensorFlow with TensorRT support?」をYにすると出てくる。

Please note that each additioinal compute capability signigficantly increases your buid time and binari size, and that TensoFlow only supports compute capabilities >= 3.5
下記を見て決める。
CUDA GPUs
https://developer.nvidia.com/cuda-gpus

GeForce 1080Tiなら6.1。1650なら7.5。ただし自動判別されてる模様で何故この項目があるのかわからない。

GeForce1650

```3.5,7.5```

GeForce1080Ti

```3.5,6.1```

Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is /arch:AVX]:
ここでおそらくtensorflow v2を指定するのだと思う。

```/arch:AVX```

Woud you like to override eigen storong inline for some C++ compilatoin to reduce the complaton time？
よくわからないがY

```Y```

Would you like to nteractively configure ./WORKSPACE for Android builds？
Android使わないのでN

```N```

## ビルドファイル生成

BazelでTensorFlowビルドファイルを生成する

### ディレクトリ移動

whlファイルを生成するディレクトリを作成した後、ビルドするディレクトリに移動する。
今回はcmdで実施(パスの都合)。

```
cd c:\
mkdir tmp
cd c:\tensorflow
```

### ビルドファイル生成前のビルド

今回は基本通りに実施する。５時間かかるなんて聞いてない…

Windowsでのソースからのビルド | TensorFlow
https://tensorflow.google.cn/install/source_windows?hl=ja

```
bazel clean --expunge  
bazel build --config=opt --config=cuda --define=no_tensorflow_py_deps=true //tensorflow/tools/pip_package:build_pip_package
```

llvmでインストールする様になり、cygwinが入っていると妨害する模様。
私が取った手段はかなりの力業。
一時的に、「c:\cygwin2#1」「c:\cygwin」「c:\cygwin2」を「ごみ箱」に入れてビルドした。インストールが完了したら元に戻す予定。

なお、私は2.10.0で入ったが、

こちらに2.10.0はWindows上で動かない事になっていると書いてあったり、
https://github.com/tensorflow/tensorflow/issues/61226

こちらに2.10.0で入らず2.9にしたら入ったの記載もあるので、
https://gugu-ran.hatenablog.com/entry/2023/06/28/010146

うまく行かなかったら2.9に落とすのも選択肢かも知れません。

## パッケージ作成

ビルドを実行する。

長時間かかると聞いていたがそんなに掛からなかった。20分程度。何か間違えたか？

```
bash bazel-bin/tensorflow/tools/pip_package/build_pip_package /c/tmp/tensorflow_pkg
```

## ビルドファイル、すなわちtensorflowインストール

```
cd /c/tmp/tensorflow_pkg
pip install tensorflow-2.10.1-cp39-cp39-win_amd64.whl
```

## 確認

ディレクトリ変えないとエラーが出る。

```
python -c "import tensorflow as tf; print( tf.__version__ )"
python -c "from tensorflow.python.client import device_lib; print(device_lib.list_local_devices())"
```

無事、ここでXLA_GPUとXLA_CPUが表示されました。