![](https://jhalfmoon.com/dbc/wp-content/uploads/2018/11/JH-2-150x150.png)
このところ、Jetson Nano用のOSイメージに最初から含まれているJetPackの中のツール類をあれこれ当たってみているのですが、ハングしました。デバッグに必須
cuda-gdb
です。これがハングしているのではデバッグもままなりません。いろいろ調べた結果、動くようになったので書き留めておきます。ま、ちゃんと調べずにとりあえず使ってみて、問題起きたらようやく調べるという、泥縄式がまずい、という自覚はあり、しかし、やめられまへん。
※「トホホな疑問」投稿順Indexはこちら
最初にツマラナイことをちょっと書いてしまいます。最近、Jetsonばかりいじっているので、頭の中は
Jetpack といったら Nvidiaの Jetpack
になっていたですが、世間的には「Wordpressの」でしたね。Googleで検索して改めて気付きました。見ている人の数の規模感が違うのでしょうかね。
さて、本題へ戻ります。Jetson nano用のUbuntuをOSイメージからインストールすると、
/usr/local/cuda/bin
に nvcc をはじめとする cudaのツール類がインストールされています。Jetson nanoを使う目的がGPUだとすると、避けては通れぬツールばかりでありましょう。今回、動かそうと思ってちょっとハマったのが
cuda-gdb
であります。gdbのNvidiaによる拡張版で、cudaによるカーネル、GPUによって実行される部分、までデバッグできる優れものです。勿論、CPU部分だけならば、nvcc でコンパイルしたオブジェクトでも結局はホスト側のgccでコンパイルされているので、普通の gdb でデバッグすることが可能です。しかし、GPUに渡されて実行される「カーネル」はこれがないとデバッグできない。ただね、私は、起動すれば直ぐ動くに決まっている、と頭から思い込んでおりましたで。
まず、今回モルモット(調査のビークルと呼ぶべきか)に使わせていただいたのは、cudaのサンプルプログラムの中でももっともシンプルな、vectorAdd です。その名のとおり、長いベクトルの足し算。そんなデバッガがいるようなプログラムじゃありませんが、動作を確かめるには小さくて手頃でしょう。直接、nvccを動かして以下のような感じでビルドしました。
$ nvcc -I../../common/inc -g -G vectorAdd.cu -o vectorAdd_debug
nvcc のマニュアルに書いてあることですが、-gはCPU部分をコンパイルするホストコンパイラ(Jetson nanoではgcc)に渡され、オブジェクトにデバッグ情報が含まれるようにする。また、-GはGPU部分でやはり同様な作用をする、と。勿論、デバッグ用のビルドなので最適化は無し(最適化すると消えてしまうようなルーチンや順序が変わったりして、デバッグ大変だから、だと思います)。
もちろん問題なくコンパイルできて、
$ ./vectorAdd_debug
などとすれば、以下のような感じでちゃんと動作します。
[Vector addition of 50000 elements] Copy input data from the host memory to the CUDA device CUDA kernel launch with 196 blocks of 256 threads Copy output data from the CUDA device to the host memory Test PASSED Done
そこで
$ cuda-gdb ./vectorAdd_debug
などとすると、ちゃんと cuda-gdb 自体は立ち上がり、プロンプト
(cuda-gdb)
を返してきます。CPU部分などは普通にデバッグできます。しかし、恐ろしいことに、run とか continue、あるいは stepでもよいですが、cudaのファンクションに入った瞬間、固まります。このプログラムの場合、cudaMallocのところで戻ってこなくなります(「地」のCPUのところは、普通にブレークでもステップでもできるので、走らせて行けばcudaMallocから返ってこないのは直ぐに分かる)。
待てど暮らせど、戻る気配もなし。。。とりあえず、別なプロセスから kill すれば該当のcuda-gdbのセッションを殺してプロンプトに帰ってきます。しかたが無いので調べました。NVIDIAのマニュアル読んでいて直ぐに分かるのが、単一のGPU上で作業している場合、
- GUIもGPUを使うので、X11動かしてちゃいけない
- でも、CUDA Capability3.5以上だったら、設定すればGUIと共存できるらしい
こちらは、sshでリモートからCUIで動作させているので、未練なくJetson nano上のX11止めました。これで動くか?期待したのですが、
やっぱり戻ってきません。
どうしたんだろうと、いろいろ調べていたらありました。
cuda-gdb CUDA debugging hangs when non-root – NVIDIA Developer Forums
NVIDIAの人がモデレータになっていて回答書いているので引用させていただきましょう。
This is a known issue.
Due to some internal restrictions, you will need to execute all the tool (cuda-gdb, cupti, nvprof…) as root.
そうだったんかい、そういうことは、大きい字でどこかに書いといてくれん?(書いてあるのに私が見過ごしていただけかも。。。)
まあ、実際、nvprof動かすときに sudo やっているし、気が付かなかった私が悪い? 例によってsecure_pathはいじってないので、
$ sudo /usr/local/cuda/bin/cuda-gdb ./vectorAdd_debug
とし、mainの先頭と尻尾にブレーク張って、continueするならば、以下のごとし。
そして、前回まで、no CUDA devices などとつれない反応だった
info cuda devices
コマンドもちゃんと、見えているCUDAデバイスを報告してまいります。こんな感じ。
なんだかな~、分かってしまえば呆気ないのだけれどね、そんなことは「常識」なんでしょうか?