私はunspecified launch failure
、かなり頻繁に でランダムにクラッシュする CUDA プログラムに取り組んできました。慎重にデバッグすることで、どのカーネルが失敗しているかを突き止め、さらに、特定の超越関数が CUDA カーネル内から呼び出された場合にのみ失敗が発生することを突き止めました (例:sinf()
やatanhf()
)。
これにより、これらの超越関数が実際に問題を引き起こしていることを確認するために、はるかに単純なプログラム (以下を参照) を作成することになりました。以下のコードをコンパイルして実行すると、tanh と atanh を使用するカーネルへの呼び出しが繰り返されるだけで、プログラムが動作することもあれば、Error with Kernel
次のようなドライバーからのメッセージと共に出力されることもあります。
NVRM: XID (0000:01:00): 13, 0002 000000 000050c0 00000368 00000000 0000080
頻度に関しては、実行可能ファイルを実行する時間の 50% でおそらくクラッシュします。
私がオンラインで読んだことXiD 13
から、ホストベースのセグ障害に似ているように思えます。ただし、配列のインデックス付けを考えると、それがどのように当てはまるかわかりません。さらに、カーネル内の超越関数を他の関数 (浮動小数点の減算と加算の繰り返しなど) に置き換えても、プログラムはクラッシュしません。つまり、XiD エラー メッセージは表示されず、プログラムは最終的に atanh(0.7) の正しい値を返します。
Ubuntu 11.10 x64 デスクトップで cuda-5.0 を実行しています。ドライバーのバージョンは 304.54 で、GeForce 9800 GTX を使用しています。
これはハードウェアの問題か、ドライバーのバグだと言いたいところです。奇妙なのは、nvidia のサンプル アプリケーションが正常に動作することです。おそらく、影響を受ける超越関数を使用していないためです。
潜在的に重要な最後の情報は、メイン プロジェクトまたはこのテスト プログラムを cuda-memcheck の下で実行すると、エラーは報告されず、クラッシュすることもないということです。正直なところ、cuda-memcheck の下でプロジェクトを実行するだけで済みますが、パフォーマンスが低下するため、実用的ではありません。
ここでのヘルプ/洞察に感謝します。誰かが 9800 GTX を持っていて、このコードを実行して動作するかどうかを確認したい場合は、大歓迎です。
#include <iostream>
#include <stdlib.h>
using namespace std;
__global__ void test_trans (float *a, int length) {
if ((threadIdx.x + blockDim.x*blockIdx.x) < length) {
float temp=0.7;
for (int i=0;i<100;i++) {
temp=atanh(temp);
temp=tanh(temp);
}
a[threadIdx.x+ blockDim.x*blockIdx.x] = atanh(temp);
}
}
int main () {
float *array_dev;
float *array_host;
unsigned int size=10000000;
if (cudaSuccess != cudaMalloc ((void**)&array_dev, size*sizeof(float)) ) {
cerr << "Error with memory Allocation\n"; exit (-1);}
array_host = new float [size];
for (int i=0;i<10;i++) {
test_trans <<< size/512+1, 512 >>> (array_dev, size);
if (cudaSuccess != cudaDeviceSynchronize()) {
cerr << "Error with kernel\n"; exit (-1);}
}
cudaMemcpy (array_host, array_dev, sizeof(float)*size, cudaMemcpyDeviceToHost);
cout << array_host[size-1] << "\n";
}
編集: このプロジェクトを数か月中断しましたが、昨日ドライバー バージョン 319.23 に更新したところ、この問題は発生しなくなりました。私が説明した問題は、修正されたバグだったに違いないと思います。お役に立てれば。