プログラムのバグを見つけようとしています。それは生産します
[vaio:10404] Signal: Segmentation fault (11)
[vaio:10404] Signal code: Address not mapped (1)
[vaio:10404] Failing at address: 0x210000
[vaio:10405] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0) [0x7fa7857ffcb0]
[vaio:10405] [ 1] /lib/x86_64-linux-gnu/libc.so.6(+0x14fe20) [0x7fa785580e20]
[vaio:10405] [ 2] /usr/lib/libcuda.so.1(+0x1b1f49) [0x7fa78676bf49]
0x210000
GPU メモリに存在するアドレスです。統一されたアドレス空間がありません (カードの制限のため: sm_12)。
を介してプログラムを実行すると、問題が発生しますmpiexec -n 2
。つまり、2 つの CPU プロセスを開始し、どちらも同じ (!) GPU (1 つの GPU がインストールされているだけ) で独自のコンテキストを作成します。このような:
cuInit(0);
cuDeviceGet(&cuDevice, 0); // get device number 0
cuCtxCreate(&cuContext, 0, cuDevice); // create context
cuMemAlloc( &mem , size ); // allocate memory pool (hundreds of MB)
(これはここでは単純化されています - すべての cuda 呼び出しでエラーが返されたかどうかがチェックされます)
私はこのセットアップをかなり長い間うまく使用しています (複数のホスト プロセスが同じ GPU を共有しています)。ただし、それは CUDA ランタイム API を使用する場合でした。現在、ドライバー API に切り替えています。
これを突き止めるためmem
に、上記のコードからダンプします。によって返されるメモリ アドレスcuMemAlloc
は、両方のプロセスで同じであることが判明しました。これは私を驚かせます。ここにダンプします:
process 0: allocate internal buffer: unaligned ptr = 0x210000 aligned ptr = 0x210000
process 1: allocate internal buffer: unaligned ptr = 0x210000 aligned ptr = 0x210000
すぐに、そのような問題のない古いコード (ランタイム API) を確認しました。両方のプロセス(同じデバイスを共有)で同じメモリアドレスも報告することが判明しました。これはこれまで私の注意を引くことはありませんでした。
これは信じがたいことです。これを明確にするために:両方のプロセスがcudaMalloc
(ランタイムAPI)とcuMalloc
(ドライバーAPI)(大きなカードで400MB)でデバイスメモリを要求し、両方のプロセスが同じアドレスを返しますか?最初のプロセスがすでに終了しているため、最初のプロセスが同じメモリを再利用できるように、1 つのプロセスが大幅に進行して既にメモリを解放していないことは確かです。いいえ、このメモリは、後続のメモリ割り当てに対応するためのメモリ プールとして使用され、その間に多くの同期ポイントがあります。プールはプログラムの終了時に解放されます。
同じポインタ値 (メモリ アドレス) を両方のプロセスに報告する方法を知っている人はいますが、GPU ではこれは異なるメモリを参照していますか? (それが実行する計算は正しいため、そうする必要があります。また、メモリ プールが重複している場合はそうではありません)。私の知る限り、これは不可能です。私は何が欠けていますか?