ROCm TensorFlow をデバッグするメモ

ROCm TensorFlow でなんだかよくわからないエラーメッセージがでるときに, デバッグするときのメモです.

だいたい MIOpen のレイヤーでおかしいかったので, MIOpen 成分おおめです.

## 環境

* Ubuntu 18.04
* ROCm 2.0
* ROCm 対応 GPU(VEGA, Polaris(e.g. RX470/570)) 

## MIOpen でログを出す

`MIOPEN_ENABLE_LOGGING=1` and `MIOPEN_LOG_LEVEL=6` 環境変数を定義するとログがでます.

### MIOpen をデバッグビルドする.

libMIOpen.so でエラーが起きている場合, デバッグビルドをして gdb で場所の特定ができると github に issue report しやすくなります.

https://github.com/ROCmSoftwarePlatform/MIOpen

Docker ビルドはなぜかうまくいかないので, non-docker build をします.

MIOpen が依存する rocBlas が依存する Tensile のビルドで python2.7(+ pip) が必須になります.
Ubuntu 18.04 などのように python3 が標準の環境では, conda で python2.7 環境をセットアップしてから, `install_deps.cmake` を実行します.
(ドキュメントには記載されていません. issue レポート済み https://github.com/ROCmSoftwarePlatform/MIOpen/issues/71)

```
# assume py27 environment is created using (mini)conda

$ source activate py27

$ cmake -P install_deps.cmake --prefix $HOME/local/miopen-dbg 

$ rm -rf build

$ CXX=/opt/rocm/bin/hcc cmake -DCMAKE_BUILD_TYPE=Debug -Bbuild -H. \
  -DCMAKE_INSTALL_PREFIX=$HOME/local/miopen-dbg \
  -DCMAKE_PREFIX_PATH=$HOME/local/miopen-dbg
```

既存の `/opt/rocm/miopen` をリネームなりして退避し, `$HOME/local/miopen-dbg` にシンボリックリンクを貼ります.

あとは python スクリプトを gdb で実行すれば, だいたいどこで落ちているかわかります.
たとえば..

```
$ gdb python
(gdb) set args main.py
(dbg) r
...
0x00007fffb4ad4aad in miopen::solver::ConvOclBwdWrW2::GetSolution (this=0x7fff3eff9808, params=...)
    at /home/syoyo/work/MIOpen/src/solver/conv_ocl_dir2D_bwdWrW_2.cpp:263
263	            out_wei_scan_loop = (out_width + n_wei_blk - 1) / n_wei_blk;
(gdb) p n_wei_blk
$1 = 0
```

## Resource exhausted

GPU のメモリ確保に失敗しています. メモリのたくさんある GPU を調達するか, ネットワークのサイズを小さくします.

## out-of-memory ...

同じく GPU のメモリ確保に失敗しています. メモリのたくさんある GPU を調達するか, ネットワークのサイズを小さくします.



## Floating point segmentation(core dumped)

とりあえず lldb/gdb でデバッガー経由でプログラムを動かして, どこで落ちているか確認します.
MIOpen 内部の場合は, 前述のように MIOpen をデバッグビルドしてどの行で落ちているか確認できるようにしましょう.

## auto-tune を無効にする.

https://stackoverflow.com/questions/45063489/first-tf-session-run-performs-dramatically-different-from-later-runs-why

`TF_CUDNN_USE_AUTOTUNE=0` を定義します.

## GPU の指定

特定の GPU だけ使うようにする場合, `CUDA_VISIBLE_DEVICES` 環境変数が ROCm でも使えます.

https://stackoverflow.com/questions/39649102/how-do-i-select-which-gpu-to-run-a-job-on


## プロセスの削除

python コードの書き方にもよるのかもしれませんが, MIOpen などのレイヤで segfault などで実行が失敗すると, python プロセスがシステムに残った状態になります. multiprocess で python プロセスがたくさん作られるので, 一度に消す方法が必要になります.

```
$ ps aux | grep "python main.py" | awk '{print $2}' | xargs kill -9
```

などで消します(.py を他の python スクリプトと区別できるような名前にしておくとよい)

## Failed to get function: miog_betac_alphaab

```
2019-01-17 07:18:28.223217: I tensorflow/core/kernels/conv_grad_input_ops.cc:1023] running auto-tune for Backward-Data
MIOpen Error: /home/syoyo/work/MIOpen/src/include/miopen/hipoc_kernel.hpp:200: Failed to get function: miog_betac_alphaab from /home/syoyo/.cache/miopen/1.7.0/983a562b2b2b3b53f1e5e010399bdb74/eb453bcd69413cd24d2a93d8938bab9f.o hipErrorNotFound
2019-01-17 07:18:28.445963: F tensorflow/stream_executor/rocm/rocm_dnn.cc:3201] Check failed: status == miopenStatusSuccess (7 vs. 0)Unable to find a suitable algorithm for doing backward filter convolution
Aborted (core dumped)
```

https://github.com/ROCmSoftwarePlatform/MIOpen/blob/master/src/include/miopen/hipoc_kernel.hpp#L196

MIOpen では, convolution の OpenCL カーネルを動的にコンパイルして高速化(?)を図っているようですが, そのコンパイル済みキャッシュファイルが壊れているのかも?

cache を消すか, cache 機能を disable すると解決しやすいです.

https://github.com/ROCmSoftwarePlatform/MIOpen/blob/master/doc/src/cache.md