0

これは、問題を示す最小限のプログラムです。Windows 7 で 128 個の CUDA コア、CUDA 5.0 を搭載した GTS 250 を使用しています。

void cuda_ops_test(int N, float* R)
{
    //Values of input matrix in CPU
    fprintf(stderr, "\nValues of R: \n");
    for (int i=0; i<N; ++i)
        fprintf(stderr, "%f, ", R[i]);
    fprintf(stderr, "\n");

    //Initialize CUDA/CUBLAS
    cublasHandle_t handle;
    cublasStatus_t status;
    status = cublasCreate(&handle);
    if (status == CUBLAS_STATUS_SUCCESS)
        fprintf(stderr, "CUBLAS initialization succeeded.\n");

    //Allocate device memory
    float *dR = 0;
    cudaError_t alloc_status;
    alloc_status = cudaMalloc((void**)&dR, N*sizeof(dR[0]));
    if(alloc_status == cudaSuccess)
        fprintf (stderr, "\nDevice memory allocation succeeded.\n");

    //Load array into memory
    status = cublasSetMatrix(1, N, sizeof(R[0]), R, N, dR, N);
    if(status == CUBLAS_STATUS_SUCCESS)
        fprintf (stderr, "\nDevice write succeeded.\n");

    //First operation: summation
    float ans;
    status = cublasSasum(handle, N, dR, 1, &ans);
    if (status == CUBLAS_STATUS_SUCCESS)
        fprintf(stderr, "\ncublasSasum produced no error. Sum of dR: %d\n", ans);
    else
        fprintf(stderr, "\ncublasSasum error: %d.\n", status);

    //Second operation: y = ax+y
    const float alpha = 2.0;
    status = cublasSaxpy(handle, N,
                 &alpha,
                 dR, 1,
                 dR, 1);
    if (status == CUBLAS_STATUS_SUCCESS)
        fprintf(stderr, "\ncublasSaxpy produced no error.\n");
    else
        fprintf(stderr, "\ncublasSaxpy error: %d.\n", status);

    // transfer device dR to host R
    status = cublasGetMatrix (1, N, sizeof(dR[0]), dR, N, R, N);
    if(status == CUBLAS_STATUS_SUCCESS)
        fprintf (stderr, "\nDevice read succeded\n");

    //Display post-op values of R
    fprintf(stderr, "\nValues of R, after cublasSaxpy: \n");
    for (int i=0; i<N; ++i)
        fprintf(stderr, "%f, ", R[i]);
    fprintf(stderr, "\n");

    //Attempt to zero with cudaMemset
    cudaError_t stat = cudaMemset(dR, 0, N*sizeof(dR[0]));
    if (stat==cudaSuccess)
        fprintf(stderr, "\nZeroing with cudaMemset on R produced no error.\n");

    //Again transfer device dR to host R, after zeroing
    status = cublasGetMatrix (1, N, sizeof(dR[0]), dR, N, R, N);
    if(status == CUBLAS_STATUS_SUCCESS)
        fprintf (stderr, "\nDevice read succeded.\n");

    //Display values of R again
    fprintf(stderr, "\nValues of R, after zeroing with cudaMemset: \n");
    for (int i=0; i<N; ++i)
        fprintf(stderr, "%f, ", R[i]);
    fprintf(stderr, "\n");

    cudaFree(dR);
}

次の出力は、データが GPU メモリに読み込まれている間、実際には操作が行われなかったことを示しています。

R の値: 0.123020、0.367809、0.834681、0.035096、0.517014、0.662984、0.426221、0.104678、

CUBLAS の初期化に成功しました。

デバイスのメモリ割り当てに成功しました。

cublasSasum はエラーを生成しませんでした。dRの合計: 0

cublasSaxpy はエラーを生成しませんでした。

cublasSaxpy 後の R の値: 0.123020、0.367809、0.834681、0.035096、0.517014、0.662984、0.426221、0.104678、

R で cudaMemset をゼロ設定してもエラーは発生しませんでした。

cudaMemset でゼロにした後の R の値: 0.123020、0.367809、0.834681、0.035096、0.517014、0.662984、0.426221、0.104678、

どうしたの?(そしてハッピー ホリデー。:))

4

1 に答える 1

2

コードにいくつかのエラーがありました。コメントで述べたように、デバイスの読み取りメッセージとデバイスの書き込みメッセージの両方が出力されていないという事実を見逃していました。これは、これらの関数 (cublasSetMatrix、cublasGetMatrix) が実際に失敗していたためです。

cublasSetMatrix と cublasGetMatrix の呼び出しを修正するには 、パラメータldaldbパラメータを 1に変更します。

 status = cublasSetMatrix(1, N, sizeof(R[0]), R, 1, dR, 1);    
 ...     
 status = cublasGetMatrix (1, N, sizeof(dR[0]), dR, 1, R, 1);

これらの関数のドキュメントには、次のように記載されています。

cublasSasum 操作の結果を出力する行で、printf ステートメントが int 形式指定子を誤って使用して float 値を出力しています。これはうまくいきません。を次のように変更%d%fます。

 fprintf(stderr, "\ncublasSasum produced no error. Sum of dR: %f\n", ans);

これらの変更により、賢明な結果を得ることができました。

Values of R:
0.123020, 0.367809, 0.834681, 0.035096, 0.517014, 0.662984, 0.426221, 0.104678,
CUBLAS initialization succeeded.

Device memory allocation succeeded.

Device write succeeded.

cublasSasum produced no error. Sum of dR: 3.071503

cublasSaxpy produced no error.

Device read succeded

Values of R, after cublasSaxpy:
0.369060, 1.103427, 2.504043, 0.105288, 1.551042, 1.988952, 1.278663, 0.314034,

Zeroing with cudaMemset on R produced no error.

Device read succeded.

Values of R, after zeroing with cudaMemset:
0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,

このSOの質問/回答は、便利で便利なcublasエラーパーサー関数のヒントを提供することに注意してください。これを cublas 関数呼び出しのラッパーまたはエラー チェック マクロに組み込むことは難しくありません。

于 2012-12-26T01:46:05.973 に答える