CUDA on WSL導入時，Docker Desktop for Windowsとケンカしてしまった件

[CUDA on WSL](https://docs.nvidia.com/cuda/wsl-user-guide/index.html)の公開と，[前回紹介したNeural Source Filter](https://qiita.com/mitsu-h/items/261868e245c888ba4e76)の[実装](https://github.com/nii-yamagishilab/project-CURRENNT-scripts/tree/master/waveform-modeling/project-WaveNet)がLinux環境でしか動作しないことを受けて，本格的に環境構築を行うことにした．ところが，

```shell
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "process_linux.go:402: container init caused \"process_linux.go:385: running prestart hook 1 caused \\\"error running hook: exit status 1, stdout: , stderr: exec command: [/usr/bin/nvidia-container-cli --load-kmods configure --ldconfig=@/sbin/ldconfig.real --device=all --compute --utility --require=cuda>=9.0 --pid=8276 /var/lib/docker/overlay2/b956d7f169cca157457e107ee8c99a050c33199ded8f4fa4d68e3ace612c6d0c/merged]\\\\nnvidia-container-cli: initialization error: driver error: failed to process request\\\\n\\\"\"": unknown.
```
と言った感じでWSL側からGPUの認識ができず苦労した．なので，その解決法をメモしておく．

#CUDA on WSLとは
Windows Subsystem for Linux（WSL）でCUDAを利用したPGU計算ができる仕組み．今まではWSL上にCUDAをインストールして行っていたそうだが，CUDA on WSLを使えばWindows側にGPUドライバーをインストールすればOK．[Gigazineの記事](https://gigazine.net/news/20200619-wsl-support-cuda/)がわかりやすかったので詳しく知りたい方はこちらを参照

#環境構築
##はじめに
もしCUDA on WSLの導入のみを考えている方は，必ず公式の手順のみに従って欲しい．以下に記すのは，導入につまずいた状況の整理であるため，上記のエラーが発生している人は，以下を見て同じような構築を行ってないかチェックして欲しい．
##WSL上にAnaconda導入
まず，WSL上でPythonを動かせるようにして，ついでにPyCharmから実行したいなと思いそちらの構築から開始した．以下が参考にしたサイトである．

- [WSL　＋　Ubuntu　＋　Anaconda　＋　VScodeでPythonの環境構築](https://penyoo.hatenablog.com/entry/2019/11/30/002503)
- [SSHを使用してWSLベースのリモートインタープリターを作成する](https://pleiades.io/help/pycharm/using-wsl-as-a-remote-interpreter-1.html)
- [pycharmとwsl(Windows Subsystem for Linux)の連携方法](https://igrrk.hatenablog.com/entry/2018/09/13/010435)

また，WSLのUbuntuにはgcc等がインストールされていないため，そちらのインストールも行った．

- [【Ubuntu 20.04/18.04 LTS】gcc, make などの開発ツールをインストールして使う](https://www.yokoweb.net/2018/05/04/ubuntu-18_04-gcc-makme-install/)
- [g++をUbuntuへインストールする](https://kaworu.jpn.org/cpp/g++%E3%82%92Ubuntu%E3%81%B8%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)

##Docker Desktopの導入
あと，CUDA on WSLでDockerが必要というのを見たことと，Windows10 homeでも利用可能になったので嬉しくなり，Docker Desktop for Windowsをインストール．__これが元凶__

- [公式](https://docs.docker.com/docker-for-windows/wsl/)

##CUDA on WSLの導入
CUDA on WSL構築にあたって参考にしたサイト

- [公式](https://docs.nvidia.com/cuda/wsl-user-guide/index.html)
- [待ってました CUDA on WSL2](https://qiita.com/ksasaki/items/ee864abd74f95fea1efa)

#解決方法
公式で，WSL上のUbuntuにdockerをインストールする項目がある．

```shell
$ curl https://get.docker.com | sh
```
このUbuntu上のDockerと，Docker Desktop for Windowsが別に動作していることに気づき，もしかすると2つのDockerが競合しているのでは？と考えた，そこで，Docker Desktop for Windowsが自動的に起動しないように設定，念の為NVIDIA Container Toolkitのアンインストールを行ってから再起動をして，再びDocumentation通りにインストール，CUDAサンプルの実行を行うと

```shell
Run "nbody -benchmark [-numbodies=<numBodies>]" to measure performance.
-fullscreen       (run n-body simulation in fullscreen mode)
-fp64             (use double precision floating point values for simulation)
-hostmem          (stores simulation data in host memory)
-benchmark        (run benchmark to measure performance)
-numbodies=<N>    (number of bodies (>= 1) to run in simulation)
-device=<d>       (where d=0,1,2.... for the CUDA device to use)
-numdevices=<i>   (where i=(number of CUDA devices > 0) to use for simulation)
compare          (compares simulation results running once on the default GPU and once on the CPU)
-cpu              (run n-body simulation on the CPU)
-tipsy=<file.bin> (load a tipsy model file for simulation)
NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.
> Windowed mode
> Simulation data stored in video memory
> Single precision floating point simulation
> 1 Devices used for simulation
MapSMtoCores for SM 7.5 is undefined.  Default to use 64 Cores/SM
GPU Device 0: "GeForce RTX 2080 Ti" with compute capability 7.5
Compute 7.5 CUDA device: [GeForce RTX 2080 Ti]
69632 bodies, total time for 10 iterations: 119.463 ms
= 405.868 billion interactions per second
= 8117.351 single-precision GFLOP/s at 20 flops per interaction 
```
動いた！！！
そういえば，[待ってました CUDA on WSL2](https://qiita.com/ksasaki/items/ee864abd74f95fea1efa)にも
>この時、
>>WSL DETECTED: We recommend using Docker Desktop for Windows.

>なんて言われますが、無視。

って書かれてたのを考えると，Docker Desktop for Windowsが動いてるとエラー吐くのは当然だなと納得した．
##ちなみに
試しに，CUDAサンプル実行後に，Docker Desktop for Windowsを起動して同じサンプルを実行するとエラーが出る．また，Docker Desktopを終了してもエラーが出てしまい，Windowsを再起動しないとサンプルが動かせなくなった．なので，CUDA on WSLを使用する方は，Docker Desktopのアンインストールをしてしまっても良いのかもしれない（保証はしない）

##Pytorchで計算をした感想
そもそもPytorchがCUDA11に非対応なのだが，面白そうなので動かしてみたところ，GPUでの計算は可能だった．しかし，どこが原因か不明であるが，1iterの計算がけっこう重く実用的ではない．試しにWindows環境で同じプログラムを実行したところCUDA10.1のときと同じ速度で計算が行えるため，Python環境で直接実行するにはまだまだ改善の余地があるのでは，と思った．そもそもDockerの仕組みすら曖昧なペーペーであり，自分の知識不足である可能性が高いので，もっと勉強したい所存．

#まとめ

- まだWSLの構築もしていない人は，CUDA on WSLのDocumentation通りに環境構築すべし
- Docker Desktop for Windowsをインストールしている場合は，自動的に起動しないよう設定またはアンインストール