覚え書き: cmdstanr+OpenCLでGPUをうまく使えたり使えなかったり (WSL2-Ubuntu-NVIDEA編)

 cmdstanrパッケージでOpenCLを経由してGPUを使う方法についての試行錯誤の記録、その第三弾。こんどは、Windows上のWSL(Windows Subsystem for Linux)の上でLinuxを動かし、そこでcmdstanからGPUを使ってみようという試みである。
 なんだか遠回りな話だが、一概にばかばかしいとはいえない。下のCase 21でわかるように、GPUを使わない場合、Windows上でcmdstanを使うより、おなじPCのWindows上のWSL上のLinux仮想マシン上でcmdstanを使ったほうが、計算速度が速かったりするのである。

目次

Case 21-22の準備

 本件、ここ数日にわたってあれこれ試しすぎて頭が混乱してきたので、すべてを消して一からやりなおすことにする。

 まずはWSL上で動くUbuntu仮想マシンの準備から。

  • Windows 10 Home (22H2)
  • WSLってなんだかいろいろあるらしいんだけど、ここではMicrosoft StoreからダウンロードしたWSL2を使ってます。
  • 既存のdistroを削除。Windowsのコマンドラインから
    wsl --unregistor

    ついでにWindowsの「機能とアプリ」から、既存のdistroの項目をすべて削除。

  • 念のため、wslそのものの更新を試みておく。
    wsl --update
    wsl --version

    WSLバージョンは 1.2.5.0 であった。

  • どのdistroをいれようか考える。ちょっと楽しいですね。
    wsl --list --online
  • 無難にUtuntuをいれることにして…
    wsl --install Ubuntu

    ここでユーザ名とパスワードの設定を求められるはず。

  • 今後のため、Windows Terminal上にUbuntu用の設定をつくっておく。これ、なんとなく自動で設定されるような気がしていたよ。私これまでどうしていたのだろうか?
    • 名前: Ubuntu
    • コマンドライン: wsl.exe -d Ubuntu
    • 開始ディレクトリ: %USERPROFILE%
    • アイコン: https://assets.ubuntu.com/v1/49a1a858-favicon-32×32.png
    • 外観-テキスト-フォントサイズ: 11
    • 外観-テキスト-見分けがつかないテキストの明るさを自動的に調整する: 常時

    Windows TerminalでUbuntuのターミナル画面を開けることを確認。

  • Ubuntuのリリースを確認する。Ubuntuのターミナルから
    lsb_release -a

    あいたたた、単にUbuntuと指定すると、Ubuntu 22.04.2 LTSとなるようだ。20.04がよかったんだけど… まあいいか…

  • システムを更新しておく。Ubuntuのターミナルから
    sudo apt update
    sudo apt upgrade
  • R 4.3.1をインストール。CRANの指示に従い、
    wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | sudo tee -a /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc
    sudo add-apt-repository "deb https://cloud.r-project.org/bin/linux/ubuntu $(lsb_release -cs)-cran40/"
    sudo apt install --no-install-recommends r-base
  • RStudio Server 2023.06.1 Build 524 のインストール。posit様の指示に従い、
    sudo apt-get install gdebi-core
    wget https://download2.rstudio.org/server/jammy/amd64/rstudio-server-2023.06.1-524-amd64.deb
    sudo gdebi rstudio-server-2023.06.1-524-amd64.deb

    RStudio Serverがスタートしたようなので、Windows上のブラウザから localhost:8787 にアクセスし、ログインできることを確認。

こんどはOpenCLの設定。

  • このPCにはGPUとしてNVIDIA GeForce GTX 660が載っています。ドライババージョンは474.44。
  • まず、OpenCL実行環境について調べるためにclinfoをインストールしておく。Ubuntuのターミナルから
    sudo apt install clinfo

    さっそくclinfoと実行してみると、Number of platforms: 0と表示される。まだOpenCLが設定できていないわけである。

  • ここで肝心なのは、NVIDIAのドライバ類を一切インストールしないこと。単にCUDA ToolkitのWSL-Ubuntu版をインストールすればよいのである。
     CUDA Toolkitのリリースノートを参照し、グラフィック・ドライバと整合する適切なバージョンを選び、CUDA Toolkitの配布ページを参照して、インストール用のコマンドを教えてもらう。
     …というのは簡単だが、正直なところ、バージョンの選び方がわからない。リリースノートの説明が良く理解できないのだ。私の場合は11.7.1を選んでうまくいかず、すべてアンインストールして、11.4.4で再挑戦した。
     dev(local)を選んだ場合のコマンドは以下の通り。

    wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
    sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
    wget https://developer.download.nvidia.com/compute/cuda/11.4.4/local_installers/cuda-repo-wsl-ubuntu-11-4-local_11.4.4-1_amd64.deb
    sudo dpkg -i cuda-repo-wsl-ubuntu-11-4-local_11.4.4-1_amd64.deb
    sudo apt-key add /var/cuda-repo-wsl-ubuntu-11-4-local/7fa2af80.pub
    sudo apt-get update
    sudo apt-get -y install cuda

    最後の行は、liburcu6がないというエラーになった。以下を実行してから改めて実行した。

    sudo add-apt-repository ppa:cloudhan/liburcu6
    sudo apt update
    sudo apt install liburcu6
  • 無事インストールは終わったが、clinfoは依然としてNumber of platforms: 0と返してくる。こちらの投稿によれば、さらにOpenCL開発パッケージとランタイムが必要になる(とChatGPTが教えてくれたのだそうだ。ははは)。
    sudo apt-get install ocl-icd-opencl-dev
    sudo apt-get install pocl-opencl-icd
  • 再度clinfoを動かしてみると… おお!なんか出てきた!
    Number of platforms                               1
      Platform Name                                   Portable Computing Language
      Platform Vendor                                 The pocl project
      Platform Version                                OpenCL 2.0 pocl 1.8  Linux, None+Asserts, RELOC, LLVM 11.1.0, SLEEF, DISTRO, POCL_DEBUG
      Platform Profile                                FULL_PROFILE
      Platform Extensions                             cl_khr_icd cl_pocl_content_size
      Platform Extensions function suffix             POCL
    
      Platform Name                                   Portable Computing Language
    Number of devices                                 1
      Device Name                                     pthread-Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
      Device Vendor                                   GenuineIntel
      Device Vendor ID                                0x6c636f70
      Device Version                                  OpenCL 1.2 pocl HSTR: pthread-x86_64-pc-linux-gnu-ivybridge
      Driver Version                                  1.8
      Device OpenCL C Version                         OpenCL C 1.2 pocl
    (後略)

    しかし、Device NameのところにCPUが出てくるのが不安だなあ…

  • NVIDEAのシステム管理ツールnvidia-smiの出力もおかしい。
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 470.199.01   Driver Version: 474.44       CUDA Version: 11.4     |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |                               |                      |               MIG M. |
    |===============================+======================+======================|
    |   0  NVIDIA GeForce ...  Off  | 00000000:01:00.0 N/A |                  N/A |
    |ERR!    0C    P8    N/A /  N/A |    420MiB /  1536MiB |     N/A      Default |
    |                               |                      |                  N/A |
    +-------------------------------+----------------------+----------------------+
    
    +-----------------------------------------------------------------------------+
    | Processes:                                                                  |
    |  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
    |        ID   ID                                                   Usage      |
    |=============================================================================|
    |  No running processes found                                                 |
    +-----------------------------------------------------------------------------+
  • いっぽう、/usr/local/cuda/extras/demo_suite/deviceQueryというツールによれば、GPUはちゃんと認識されている。
    ./deviceQuery Starting...
    
     CUDA Device Query (Runtime API) version (CUDART static linking)
    
    Detected 1 CUDA Capable device(s)
    
    Device 0: "NVIDIA GeForce GTX 660"
      CUDA Driver Version / Runtime Version          11.4 / 11.4
      CUDA Capability Major/Minor version number:    3.0
    (後略)

    よくわかんないけど、ちゃんとOpenCLに対応しているのだろうか。不安になってきた。

Case 21. Win10, WLS-Ubuntu 22.04, R4.3.1, cmdstan2.32.2, OpenCLなし, 成功

お待たせしました、cmdstanrの登場です。まずはOpenCLを使わないベンチマーク。

  • cmdstanr 0.5.3開発版をインストール。
    install.packages("remotes")
    remotes::install_github("stan-dev/cmdstanr")
  • cmdstan2.32.2をインストール。
    cmdstanr::install_cmdstan(cores = 4, overwrite = TRUE)
  • コンパイル。前々回記事で作ったstantest.stanを使います。
    mod <- cmdstan_model("./stantest.stan", force_recompile = TRUE)
  • サンプリング。
    n <- 250000
    k <- 20
    X <- matrix(rnorm(n * k), ncol = k)
    y <- rbinom(n, size = 1, prob = plogis(3 * X[,1] - 2 * X[,2] + 1))
    mdata <- list(k = k, n = n, y = y, X = X)
    fit <- mod$sample(data = mdata, chains = 4, parallel_chains = 4, refresh = 100)

    無事終了。所要時間は504秒であった。同じマシンのWindows上の所要時間が584秒だから、こっちのほうが少し早いわけだ。

Case 22. Win10, WLS-Ubuntu22.04, R4.3.1, cmdstan2.32.2, OpenCL(NVIDIA CUDA11.4.4), 失敗

いよいよOpenCLの登場。

  • cmdstanr 0.5.3開発版をインストール。
  • cmdstan2.32.2をインストール。
    cmdstanr::install_cmdstan(cores = 4, overwrite = TRUE, cpp_options = list(STAN_OPENCL=TRUE))
  • コンパイル。
    mod <- cmdstan_model(
      "./stantest.stan", 
      force_recompile = TRUE, 
      cpp_options = list(stan_opencl = TRUE)
    )
  • サンプリング。
    n <- 250000
    k <- 20
    X <- matrix(rnorm(n * k), ncol = k)
    y <- rbinom(n, size = 1, prob = plogis(3 * X[,1] - 2 * X[,2] + 1))
    mdata <- list(k = k, n = n, y = y, X = X)
    fit <- mod$sample(data = mdata, chains = 4, parallel_chains = 4, opencl_ids = c(0, 0), refresh = 100)

    無事終了したが、所要時間はなんと970秒。それもそのはず、タスクマネージャを確認すると、GPUを全然使っていないのである。やっぱり、OpenCLが設定できていないようだ。

 NVIDIAのCUDA on WSL User Guideによれば、公式にサポートしているGPUはPascal世代以降。その前のMaxwell世代のGPUはサポート外だがたぶん動く、とのこと。わがマシーンのGTX 660はさらにその前、Kepler世代ってやつだもんな。ダメか... がっくり。

Case 23-24の準備

[2023/10/11 追記] 新PCをお迎えしたので再挑戦。以下はその記録です。

 まずはWSL2-Ubuntu環境の用意。

  • Windows 11 Pro (22H2)
  • Microsoft StoreからWSL2をインストール。
  • 念のため、wslそのものの更新を試みたが(上述)、更新不要だった模様。WSLバージョンは 1.2.5.0。
  • Utuntuのインストール。
    wsl --install Ubuntu-22.04

    ここでユーザ名とパスワードの設定を求められた。

  • 今回は、Windows Terminal上にUbuntu用の設定が勝手に作られた。
  • システムを更新しておく。上述。
  • R 4.3.1をインストール。上述。
  • RStudio Server 2023.09.0 Build 463 のインストール。posit様の指示に従い、
    sudo apt-get install gdebi-core
    wget https://download2.rstudio.org/server/jammy/amd64/rstudio-server-2023.09.0-463-amd64.deb
    sudo gdebi rstudio-server-2023.09.0-463-amd64.deb

    Windows上のブラウザから localhost:8787 にアクセスし、ログインできることを確認。

おつぎはOpenCLの設定。

  • このPCにはGPUとしてNVIDIA GeForce GTX 4070が載っています(貧乏性の私としては結構張り込みました)。ドライババージョンは537.58。
  • clinfoのインストール。上述。
  • CUDA ToolkitのWSL-Ubuntu版をインストール。おそらく最新版で大丈夫だろうと踏んで、こちらで [Linux] - [x86_64] - [WSL-Ubuntu] - [2.0] - [dev(network)] を選んだところ、以下の神託がくだされた。
    wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1-1_all.deb
    sudo dpkg -i cuda-keyring_1.1-1_all.deb
    sudo apt-get update
    sudo apt-get -y install cuda

    最後までエラーなしで実行できました。なお、後述するnvidia-smiの出力によれば、インストールされたのはCUDA 12.2らしい。

  • clinfoは依然としてNumber of platforms: 0と返してくる。
  • OpenCL開発パッケージとランタイムをインストール。
    sudo apt-get install ocl-icd-opencl-dev
    sudo apt-get install pocl-opencl-icd
  • 再度clinfoを動かしてみると...
    Number of platforms                               1
      Platform Name                                   Portable Computing Language
      Platform Vendor                                 The pocl project
      Platform Version                                OpenCL 2.0 pocl 1.8  Linux, None+Asserts, RELOC, LLVM 11.1.0, SLEEF, DISTRO, POCL_DEBUG
      Platform Profile                                FULL_PROFILE
      Platform Extensions                             cl_khr_icd cl_pocl_content_size
      Platform Extensions function suffix             POCL
    
      Platform Name                                   Portable Computing Language
    Number of devices                                 1
      Device Name                                     pthread-13th Gen Intel(R) Core(TM) i5-13400F
      Device Vendor                                   GenuineIntel
      Device Vendor ID                                0x6c636f70
      Device Version                                  OpenCL 1.2 pocl HSTR: pthread-x86_64-pc-linux-gnu-goldmont
      Driver Version                                  1.8
      Device OpenCL C Version                         OpenCL C 1.2 pocl
    (後略)

    今回も、Device NameのところにCPUが出てきている... 不安だ...

  • NVIDEAのシステム管理ツールnvidia-smiの出力は以下のとおり。こちらはGPUが表示されている。
    +---------------------------------------------------------------------------------------+
    | NVIDIA-SMI 535.112                Driver Version: 537.42       CUDA Version: 12.2     |
    |-----------------------------------------+----------------------+----------------------+
    | GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
    |                                         |                      |               MIG M. |
    |=========================================+======================+======================|
    |   0  NVIDIA GeForce RTX 4070        On  | 00000000:01:00.0  On |                  N/A |
    |  0%   52C    P8              12W / 200W |    908MiB / 12282MiB |      2%      Default |
    |                                         |                      |                  N/A |
    +-----------------------------------------+----------------------+----------------------+
    
    +---------------------------------------------------------------------------------------+
    | Processes:                                                                            |
    |  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
    |        ID   ID                                                             Usage      |
    |=======================================================================================|
    |    0   N/A  N/A        26      G   /Xwayland                                 N/A      |
    +---------------------------------------------------------------------------------------+
  • /usr/local/cuda/extras/demo_suite/deviceQueryというツールによれば、GPUはちゃんと認識されている。
    /usr/local/cuda/extras/demo_suite/deviceQuery Starting...
    
     CUDA Device Query (Runtime API) version (CUDART static linking)
    
    Detected 1 CUDA Capable device(s)
    
    Device 0: "NVIDIA GeForce RTX 4070"
      CUDA Driver Version / Runtime Version          12.2 / 12.2
      CUDA Capability Major/Minor version number:    8.9
    (後略)

では、準備はできたということにして、いよいよテストです。

Case 23. Win11, WLS-Ubuntu22.04, R4.3.1, cmdstan2.33.1, OpenCLなし, 成功

まずはOpenCLを使わないベンチマーク。

  • cmdstanr 0.6.1をインストール。
    install.packages("cmdstanr", repos = c("https://mc-stan.org/r-packages/", getOption ("repos")))
  • cmdstan2.33.1をインストール。
    cmdstanr::install_cmdstan(cores = 4, overwrite = TRUE)
  • コンパイル。前々回記事で作ったstantest2.stanを使います。
    mod <- cmdstan_model("./stantest.stan", force_recompile = TRUE)
  • サンプリング。
    n <- 250000
    k <- 20
    X <- matrix(rnorm(n * k), ncol = k)
    y <- rbinom(n, size = 1, prob = plogis(3 * X[,1] - 2 * X[,2] + 1))
    mdata <- list(k = k, n = n, y = y, X = X)
    fit <- mod$sample(data = mdata, chains = 4, parallel_chains = 4, refresh = 100)

    無事終了。所要時間は203秒であった。

Case 24. Win11, WLS-Ubuntu 22.04, R4.3.1, cmdstan2.33.1, OpenCL(NVIDIA CUDA12.2), 失敗

いよいよOpenCLの登場。

  • cmdstanr 0.6.1をインストール。
  • cmdstan2.33.1をインストール。
    cmdstanr::install_cmdstan(cores = 4, overwrite = TRUE, cpp_options = list(STAN_OPENCL=TRUE))
  • コンパイル。
    mod <- cmdstan_model(
      "./stantest2.stan", 
      force_recompile = TRUE, 
      cpp_options = list(stan_opencl = TRUE)
    )
  • サンプリング。
    n <- 250000
    k <- 20
    X <- matrix(rnorm(n * k), ncol = k)
    y <- rbinom(n, size = 1, prob = plogis(3 * X[,1] - 2 * X[,2] + 1))
    mdata <- list(k = k, n = n, y = y, X = X)
    fit <- mod$sample(data = mdata, chains = 4, parallel_chains = 4, opencl_ids = c(0, 0), refresh = 100)

    固唾をのんでタスクマネージャを見守ったが、期待に反し、GPUではなくCPUが猛烈に動き出した。無事終了したが、所要時間は400秒。

  • opencl_idsの設定がいかんのかなと思い、試しにc(0,1), c(1,0), c(1,1)を試したが、いずれもエラーになった。
  • ためしに
    sudo apt-get purge ocl-icd-opencl-dev
    sudo apt-get purge pocl-opencl-icd

    として再挑戦したが、事態は改善しないどころか、Stanのコンパイルがエラーとなった。

  • 巷の情報をみるに、WSL2上でNVIDIAのGPUを使うことはできる、しかしOpenCLを経由して使えるわけではない... ということなのかもしれない。話が複雑すぎてよくわからないんだけど。
Case 25-26の準備

[2025/05/16 追記] あれから1年近くたったので、なにか状況が変わったりしたかな、と思って再挑戦。

 まずはWSL2-Ubuntu環境の用意。Ubuntuごと入れなおします。

  • Windows 11 Pro (24H2)
  • 念のため、wslそのものの更新を試みたが(上述)、更新不要だった模様。WSLバージョンは2.4.13.0。
  • 既存のdistroを削除。
    wsl --unregister Ubuntu
  • Utuntuのインストール。バージョンは板さんのおまかせで。
    wsl --install Ubuntu
  • 他にdistroは入っていないので、
    wsl

    でいきなり起動できる。ちょっと待たされ、ユーザ名とパスワードの設定を求められた。インストールされたバージョンは24.04.2 LTSであった。

  • システムを更新。
    sudo apt update
    sudo apt upgrade
  • 待っているあいだ暇なので、Windows Terminal上にUbuntu用の設定をつくった。これ、distroを入れると自動的に設定が作られる時と、そうでないときがあるんですよね。今回は後者であった。ところが、よくわからんなりに適当な設定をつくり、ふとみると、設定のリストの中に、自分が作った設定とは別にUbuntuという設定ができているではないか。そっちを使うことにしました。ひょっとして、distroをいれてからWindows Terminal上にどのdistroの設定ができるまで、タイムラグがあるのだろうか?
  • R 4.5.0をインストール。CRANの指示に従い、
    sudo apt install --no-install-recommends software-properties-common dirmngr
    wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | sudo tee -a /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc
    sudo add-apt-repository "deb https://cloud.r-project.org/bin/linux/ubuntu $(lsb_release -cs)-cran40/"
    sudo apt install --no-install-recommends r-base
  • RStudio Server v2025.05.0+496 のインストール。posit様の指示に従い、
    sudo apt-get install gdebi-core
    wget https://download2.rstudio.org/server/jammy/amd64/rstudio-server-2025.05.0-496-amd64.deb
    sudo gdebi rstudio-server-2025.05.0-496-amd64.deb

    RStudio Serverがスタートしたようなので、Windows上のブラウザから localhost:8787 にアクセスし、ログインできることを確認。

さあ、OpenCLの準備だ。

  • 前回同様、GPUはNVIDIA GeForce GTX 4070。ドライババージョンは576.02。
  • clinfoのインストール。
    sudo apt install clinfo
  • CUDA ToolkitのWSL-Ubuntu版をインストール。こちらで [Linux] - [x86_64] - [WSL-Ubuntu] - [2.0] - [dev(network)] を選んだところ、以下の神託がくだされた。
    wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1-1_all.deb
    sudo dpkg -i cuda-keyring_1.1-1_all.deb
    sudo apt-get update
    sudo apt-get -y install cuda-toolkit-12-9

    最後までエラーなしで実行できました。

  • clinfoは依然としてNumber of platforms: 0と返してくる。
  • OpenCL開発パッケージとランタイムをインストール。
    sudo apt-get install ocl-icd-opencl-dev
    sudo apt-get install pocl-opencl-icd
  • 再度clinfoを動かしてみると...
    Number of platforms                               1
      Platform Name                                   Portable Computing Language
      Platform Vendor                                 The pocl project
      Platform Version                                OpenCL 3.0 PoCL 5.0+debian  Linux, None+Asserts, RELOC, SPIR, LLVM 16.0.6, SLEEF, DISTRO, POCL_DEBUG
      Platform Profile                                FULL_PROFILE
      Platform Extensions                             cl_khr_icd cl_pocl_content_size
      Platform Extensions with Version                cl_khr_icd                                                       0x400000 (1.0.0)
                                                      cl_pocl_content_size                                             0x400000 (1.0.0)
      Platform Numeric Version                        0xc00000 (3.0.0)
      Platform Extensions function suffix             POCL
      Platform Host timer resolution                  0ns
    
      Platform Name                                   Portable Computing Language
    Number of devices                                 1
      Device Name                                     cpu-haswell-13th Gen Intel(R) Core(TM) i5-13400F
      Device Vendor                                   GenuineIntel
      Device Vendor ID                                0x6c636f70
      Device Version                                  OpenCL 3.0 PoCL HSTR: cpu-x86_64-pc-linux-gnu-haswell
      Device Numeric Version                          0xc00000 (3.0.0)
      Driver Version                                  5.0+debian
      Device OpenCL C Version                         OpenCL C 1.2 PoCL
    (後略)

    今回も、Device NameのところにCPUが出てきている。

  • NVIDEAのシステム管理ツールnvidia-smiの出力は以下のとおり。
    +-----------------------------------------------------------------------------------------+
    | NVIDIA-SMI 575.51.02              Driver Version: 576.02         CUDA Version: 12.9     |
    |-----------------------------------------+------------------------+----------------------+
    | GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
    |                                         |                        |               MIG M. |
    |=========================================+========================+======================|
    |   0  NVIDIA GeForce RTX 4070        On  |   00000000:01:00.0  On |                  N/A |
    |  0%   52C    P8              9W /  200W |     693MiB /  12282MiB |      0%      Default |
    |                                         |                        |                  N/A |
    +-----------------------------------------+------------------------+----------------------+
    
    +-----------------------------------------------------------------------------------------+
    | Processes:                                                                              |
    |  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
    |        ID   ID                                                               Usage      |
    |=========================================================================================|
    |    0   N/A  N/A              25      G   /Xwayland                             N/A      |
    +-----------------------------------------------------------------------------------------+
Case 25. Win11, WLS-Ubuntu24.02, R4.5.0, cmdstan2.36.0, OpenCLなし, 成功

OpenCLを使わないベンチマーク。

  • cmdstanr 0.8.0をインストール。
    install.packages("cmdstanr", repos = c("https://mc-stan.org/r-packages/", getOption ("repos")))
  • cmdstan2.36.0をインストール。
    cmdstanr::install_cmdstan(cores = 4, overwrite = TRUE)
  • テスト用に、以前に作ったstantest2.stanを使いたいので、軽い気持ちでRStudioでstanファイルのエディタを開こうとしたら、大変面倒なことになった。rstanパッケージを入れろと言われ、入れようとしたらエラーとなり、それより先にinstall.packages(c('StanHeaders', 'RcppEigen'))をやれと叱られ、入れようとしたらエラーとなり、それより先にinstall.packages('RcppEigen')をやれよと怒られ、入れようとしたらエラーとなり、どうやらlapackが入っていないようなのでubuntuのコマンドラインで
    sudo apt update
    sudo apt -y install libatlas3-base libatlas-base-dev

    としてからRで再度install.packages('RcppEigen')としたらいやまだgfortranが足らんと突き放され、またubuntuに戻って

    sudo apt update
    sudo apt-get install gfortran 

    としてからRで再度install.packages('RcppEigen')としたら今度は通り、install.packages(c('StanHeaders', 'RcppEigen'))も通り、install.packages('rstan'))も通り、晴れてエディタ画面を開けるようになった。うぜええええええええ!

  • コンパイル。
    library(cmdstanr)
    mod <- cmdstan_model("./stantest2.stan", force_recompile = TRUE)
  • サンプリング。
    n <- 250000
    k <- 20
    X <- matrix(rnorm(n * k), ncol = k)
    y <- rbinom(n, size = 1, prob = plogis(3 * X[,1] - 2 * X[,2] + 1))
    mdata <- list(k = k, n = n, y = y, X = X)
    fit <- mod$sample(data = mdata, chains = 4, parallel_chains = 4, refresh = 100)

    無事終了。所要時間は216秒であった。

Case 26. Win11, WLS-Ubuntu 24.02, R4.5.0, cmdstan2.36.0, OpenCL(NVIDIA CUDA12.9), 失敗

いよいよOpenCLの登場。

  • cmdstan2.36.0を再インストール。
    cmdstanr::install_cmdstan(cores = 4, overwrite = TRUE, cpp_options = list(STAN_OPENCL=TRUE))
  • コンパイル。
    mod <- cmdstan_model(
      "./stantest2.stan", 
      force_recompile = TRUE, 
      cpp_options = list(stan_opencl = TRUE)
    )
  • サンプリング。
    n <- 250000
    k <- 20
    X <- matrix(rnorm(n * k), ncol = k)
    y <- rbinom(n, size = 1, prob = plogis(3 * X[,1] - 2 * X[,2] + 1))
    mdata <- list(k = k, n = n, y = y, X = X)
    fit <- mod$sample(data = mdata, chains = 4, parallel_chains = 4, opencl_ids = c(0, 0), refresh = 100)

    あーあ、やっぱりGPUではなくCPUが動き出した。所要時間は451秒。

  • RのOpenCLパッケージというのをインストールして、oclPlatforms()というのを試したんだけど、プラットフォームがないと怒られた。

やっぱし、ubuntu側の設定がおかしいのだろうと思い...

  • Stanの掲示板の投稿を参考に、ubuntu側で
    sudo apt install libopenblas-dev
    sudo apt install libpocl-dev
    sudo apt install nvidia-opencl-dev

    とし、/etc/R/Renviron.siteに

    POCL_BUILDING=1
    OCL_ICD_VENDORS=/etc/OpenCL/venders

    と付け加え、cmdsranのインストールからやり直してみたが、やはりだめだった。

  • 上記記事を読み直し、PoCLというのがちゃんとインストールされていないんじゃなかろうか(sudo apt-get install pocl-opencl-icdというのだけではダメなんじゃなかろうか)と思い至り、ubuntu側で
    export LLVM_VERSION=18
    sudo apt install -y python3-dev libpython3-dev build-essential ocl-icd-libopencl1 \
        cmake git pkg-config libclang-${LLVM_VERSION}-dev clang-${LLVM_VERSION} \
        llvm-${LLVM_VERSION} make ninja-build ocl-icd-libopencl1 ocl-icd-dev \
        ocl-icd-opencl-dev libhwloc-dev zlib1g zlib1g-dev clinfo dialog apt-utils \
        libxml2-dev libclang-cpp${LLVM_VERSION}-dev libclang-cpp${LLVM_VERSION} \
        llvm-${LLVM_VERSION}-dev
    wget https://github.com/pocl/pocl/archive/refs/tags/v6.0.tar.gz
    cd pocl-6.0
    mkdir build
    sudo apt install cmake
    cmake -B build \
        -DCMAKE_C_FLAGS=-L/usr/lib/wsl/lib \
        -DCMAKE_CXX_FLAGS=-L/usr/lib/wsl/lib \
        -DENABLE_HOST_CPU_DEVICES=ON \
        -DENABLE_CUDA=ON

    とやってみたが、cmake いわく、 Could not find Clang library clang-cpp, perhaps wrong setting of STATIC_LLVM? とのことで、行き詰った。

  • だんだんやけくそになってきて、なにがなんだかわからないが
    sudo apt install clang llvm lld lldb

    としてから、もう一度上述のcmakeを試してみたが、やはりだめ。もう少しだという気もするのだが。

  • ひょっとしたらLLVMというのをインストールすべきなの? と思い、こちらの指示に従って
    sudo apt-get install clang-format clang-tidy clang-tools clang clangd libc++-dev libc++1 libc++abi-dev libc++abi1 libclang-dev libclang1 liblldb-dev libllvm-ocaml-dev libomp-dev libomp5 lld lldb llvm-dev llvm-runtime llvm python3-clang

    としてから上述のcmakeを試してみたが、やはりだめ。

  • 待て待て、落ち着け。LLVMというのがインストールされているどうかを調べるのが先決だろう。と考え、
    sudo apt install llvm-17
    llvm-config-17 version

    とやったら、17.0.6とのこと。

    llvm-config-16 version

    とやったら、16.0.6とのこと。なんだかわからんがLLVMというのは入っているんじゃないか? というわけで、再度行き詰った。

  • 外に出かけて商店街で昼飯を食い、机の前に戻ってきてふと思ったんだけど、LLVMってのにはバージョンがあるわけね。さきほどはexport LLVM_VERSION=18としてからたくさんのライブラリをインストールしたけど、これを17に変えてインストールしたら、cmakeは動くようになる? ならなかった。では16に変えてインストールしたら? おおお、cmakeが動くようになった! すばらしい!
  • 続きまして...
    cmake --build build -j34
    echo 'export POCL_BUILDING=1' >> ~/.bashrc
    echo 'export OCL_ICD_VENDORS=/home/(私のユーザ名)/pocl-6.0/build/ocl-vendors/' >> ~/.bashrc
    sudo cmake --install build
  • ubuntuからいったんログアウトし、Windowsでwsl --shutdownし、再びubuntuにログインして clinfo --listを試したら、なんと!
    Platform #0: Portable Computing Language
     +-- Device #0: cpu-goldmont-13th Gen Intel(R) Core(TM) i5-13400F
     `-- Device #1: NVIDIA GeForce RTX 4070

    いいぞ! イイ感じだ!

  • /etc/R/Renviron.siteにさきほど追加した行を、
    POCL_BUILDING=1
    OCL_ICD_VENDORS=/home/(私のユーザ名)/pocl-6.0/build/ocl-vendors

    に書き換えた。で、localhost:8787からRStudio Serverにログインし、ためしにSys.getenv()してみたら... あれ? OCL_ICD_VENDORSが変わってないじゃん。ubuntuでsudo rstudio-server restartしてから再度Rstudio Serverにログインしたら、今度はちゃんと変わっていた。

  • Rに対してOpenCL::oclPlatforms()と尋ねたら、"OpenCL platform 'Portable Computing Language'"だってさ!イイネ! ところが、OpenCL::oclDevices()と尋ねたら、"OpenCL device 'cpu-goldmont-13th Gen Intel(R) Core(TM) i5-13400F'"だって... 再び不安の影が...
  • 試してみましょう。
    cmdstanr::install_cmdstan(cores = 4, overwrite = TRUE, cpp_options = list(STAN_OPENCL=TRUE))
    library(cmdstanr)
    mod <- cmdstan_model(
      "./stantest2.stan", 
      force_recompile = TRUE, 
      cpp_options = list(stan_opencl = TRUE)
    )
    n <- 250000
    k <- 20
    X <- matrix(rnorm(n * k), ncol = k)
    y <- rbinom(n, size = 1, prob = plogis(3 * X[,1] - 2 * X[,2] + 1))
    mdata <- list(k = k, n = n, y = y, X = X)
    fit <- mod$sample(data = mdata, chains = 4, parallel_chains = 4, opencl_ids = c(0, 0), refresh = 100)

    これは動くんだけど、CPUが爆走する。opencl_ids = c(0, 0)はCPUを指しているからだろうな。

  • opencl_ids = c(0, 1)とすると、
    Chain 1 OpenCL Initialization: [Device] CL_INVALID_DEVICE: Unknown error -1
    Chain 2 OpenCL Initialization: [Device] CL_INVALID_DEVICE: Unknown error -1
    Chain 3 OpenCL Initialization: [Device] CL_INVALID_DEVICE: Unknown error -1
    Chain 4 OpenCL Initialization: [Device] CL_INVALID_DEVICE: Unknown error -1

    えええええ...

というわけで、WSL上のcmdstanからGPUを使う計画はいまだ実現していない。疲れる...