概要
自分はこれまでDebian 8(jessie)に非パッケージのCUDAインストーラでCUDA環境を作っていたのですが、9にアップグレードするにあたりいくつかハマりポイントがあったので、どんな問題が起きたかのかとその解決について示します。
CUDAとDebianの関係
基本的にCUDAは特定のLinux distro向けパッケージしか提供していません。Ubuntuは対応していますが、Debianは未対応です。
そのため自分はjessieの頃に"cuda_8.0.61_375.26_linux-run"というインストーラを使っていたのですが、このスクリプトは実行環境がstretchになるとパッケージの利用を促して、起動してくれません。
Debian NVIDIA Maintainersがnon-freeセクションでCUDAのパッケージ化を行っているので、そちらを使えというのがstretchからの作法となったようです。
CUDAのアンインストール
基本的にはnvidia関連のパッケージをインストールする時にnvidia-uninstallを実行してくれるのですが、私が試した時はスクリプトが無反応になってしまい、強制終了させてアンインストールが不十分な状況になってしまいました。
パッケージのスクリプトでは、非インタラクティブモードでuninstallスクリプトを実行するので、それが良くなかったのかもしれません。このような失敗をしないために、事前に手動でスクリプトを起動し、CUDAを削除するほうが良いと思われます。
アンインストールが不十分だと何が起きるか
非パッケージインストーラでCUDAをインストールすると、/usr/lib/x86_64以下に各種ファイルが直接配置されます。
一方で、Debian non-freeパッケージの方ではファイルの実体を/usr/lib/x86_64/nvidia/currentに置きつつ、必要なシンボリックリンクをupdate-alternative経由で作成します。非パッケージインストーラにより配置されたファイルがあるとシンボリックリンクリンクの作成をあきらめてしまうので、各種パッケージが参照するファイルは非パッケージインストーラによる古いバージョンのライブラリになってしまいます。
しかしながらデバイスドライバはdkms経由で最新のものが入るため、結果としてユーザーランドアプリケーションとデバイスドライバとのバージョンの不整合が発生します。この状態で何かしらのCUDAを利用するコマンドを実行すると、dmesgで以下のような出力がなされます。
[ 4037.658285] NVRM: API mismatch: the client has the version 375.26, but
[ 4037.658285] NVRM: this kernel module has the version 375.66. Please
[ 4037.658285] NVRM: make sure that this kernel module and all NVIDIA driver
dmesgの出力はまだわかりやすいのですが、直接コンソールなどに出力されるわけではありません。この状態でcupyを使うプログラムを起動するとのようなエラーになってしまいます。
cupy.cuda.cudnn.CuDNNError: CUDNN_STATUS_EXECUTION_FAILED: CUDNN_STATUS_EXECUTION_FAILED
内部的にはCUDAのユーザーランドとドライバのバージョンミスマッチを返すエラーコードが出ているのですが、cupyは成功以外の値についてチェックをしていないので、このようなエラーしか得られません。
CUDA付属のサンプル"deviceQuery"を実行するともう少し詳細なメッセージが得られるので、そちらを試す方がよりわかりやすいと思われます。
どう対処したか
自分はfindで"nvidia" "cuda"を含むファイル名を/usr/lib以下からひたすらチェックし、パッケージに所属していないものすべてを消してからnvidia-driver, nvidia-cuda-toolkitをインストールすることで解決しました。
こんなハマり方をする人はそう多くはないでしょうが、cupyでCUDA周りのエラーが出る時ケースの一つとして「ライブラリとデバイスドライバのバージョン不整合」があるということをここに残しておきます。