3

これが私のコードです:

struct S {
    int a, b;
    float c, d;
};
class A {
private:
    S* d;
    S h[3];
public:
    A() {
        cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3));
    }
void Init();
};

void A::Init() {
    for (int i=0;i<3;i++) {
        h[i].a = 0;
        h[i].b = 1;
        h[i].c = 2;
        h[i].d = 3;
    }
    cutilSafeCall(cudaMemcpy(d, h, 3*sizeof(S), cudaMemcpyHostToDevice));
}

A a;

実際、これは CUDA と OpenGL を含む複雑なプログラムです。このプログラムをデバッグすると、cudaMemcpy で実行すると失敗し、エラー情報が表示されます

cudaSafeCall() ランタイム API エラー 11: 引数が無効です。

実際、このプログラムは、正しく実行できる別のプログラムから変換されています。しかし、その例では、クラスではなくメイン関数で 2 つの変数 S* d と S h[3] を使用しました。さらに奇妙なのは、このクラス A を小さなプログラムに実装したことです。問題なく動作します。そして、ドライバーを更新しましたが、エラーがまだ存在します。

なぜこれが起こるのか、そしてそれを解決する方法について誰かが私にヒントを与えることができますか. ありがとう。

4

1 に答える 1

4

CUDA のメモリ操作はブロックしているため、同期ポイントが作成されます。そのため、cudaThreadSynchonize でチェックしない場合、他のエラーはメモリ呼び出しのエラーのように見えます。

そのため、メモリ操作でエラーが発生した場合は、その前に cudaThreadSynchronize を配置して、結果を確認してください。


最初の malloc ステートメントが実行されていることを確認してください。@Harrismが示すように、CUDAの初期化に関する問題である場合、このステートメントでは失敗しますか?? printf ステートメントを配置して、適切な初期化が実行されることを確認してください。初期化されていないメモリ領域を使用しているため、一般的に無効な引数エラーが生成されると思います。

  1. cudaMalloc されたメモリ領域のアドレスを示す printf をコンストラクタに書き込みます。

    A()
    {
        d = NULL;
        cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3));
        printf("D: %p\n", d);
    }
    
  2. ローカルに割り当てられた領域のメモリ コピーを作成してみてください。つまり、cudaMalloc を cudaMemcopy の上に移動します (テスト用)。

    void A::Init()
    {
        for (int i=0;i<3;i++)
        {
            h[i].a = 0;
            h[i].b = 1;
            h[i].c = 2;
            h[i].d = 3;
        }
        cutilSafeCall(cudaMalloc((void**)&d, sizeof(S)*3)); // here!..
        cutilSafeCall(cudaMemcpy(d, h, 3*sizeof(S), cudaMemcpyHostToDevice));
    }
    

幸運を。

于 2012-08-28T10:54:28.213 に答える