cudaMemcpy上的奇怪分段错误

时间:2014-04-08 16:33:11

标签: c cuda cublas

我试图使用不同的cuBLAS句柄并行地执行许多cuBLAS操作(例如,矩阵 - 矩阵乘法),并将不同的流与每个句柄相关联,但是我得到了一个非常奇怪的分段错误。假设我们需要执行矩阵 - 矩阵运算C = A*A,其中A是M-by-M矩阵(M = 1024)并假设我们需要并行执行N_STREAM这样的计算。矩阵A的数据打包在大量维M*M*N_STREAM中。这是我编写的用于执行并行乘法的代码:

#define M 1024
#define N_STREAMS 1
int main(void) {
    /* Declarations */
    cublasHandle_t handles[N_STREAMS];
    curandGenerator_t cuda_rng;
    ptrdiff_t i;
    double *d_data = NULL, *d_C = NULL; // device data
    double alpha = 1.0, beta = 0.0, h_C[M * M * N_STREAMS]; //host data

    for (i = 0; i < M * M * N_STREAMS; i++) {
        h_C[i] = 0.0;
    }

    /* Allocate space on the device for the random data `d_data` : */
    CUDA_CALL(cudaMalloc((void**) &d_data, sizeof(double) * M * M * N_STREAMS));
    CUDA_CALL(cudaMalloc((void**) &d_C, sizeof(double) * M * M * N_STREAMS));
    CUDA_CALL( cudaMemcpy(d_C, h_C, M*M*N_STREAMS*sizeof(double), cudaMemcpyHostToDevice));

    /* Start N_STREAMS streams */
    for (i = 0; i < N_STREAMS; i++) { CUBLAS_CALL( cublasCreate( &handles[i])); }

    /* Start the RNG */
    /* Construct the RNG */
    CURAND_CALL( curandCreateGenerator(&cuda_rng, CURAND_RNG_PSEUDO_DEFAULT));
    CURAND_CALL( curandGenerateUniformDouble(cuda_rng,d_data, M*M*N_STREAMS));

    /* Load the random data */
    printf("Generating data. Size = %d\n", M * M * N_STREAMS);
    CURAND_CALL(
            curandGenerateUniformDouble(cuda_rng, d_data, M * M * N_STREAMS));
    for (i = 0; i < N_STREAMS; i++) {
        CUBLAS_CALL(
                cublasDgemm(handles[i], CUBLAS_OP_N, CUBLAS_OP_N, M, M, M,
                        &alpha, d_data + i*M*M, M, d_data+i*M*M, M, &beta, d_C+i*M*M, M));
    }

    CUDA_CALL( cudaMemcpy(h_C, d_C, M * M * N_STREAMS * sizeof(double), cudaMemcpyDeviceToHost));
    printf("%g\n\n", h_C[1]);

    for (i = 0; i < N_STREAMS; i++) {
        CUBLAS_CALL( cublasDestroy( handles[i]));
    }
    CURAND_CALL( curandDestroyGenerator(cuda_rng));
    CUDA_CALL( cudaFree(d_data));
    CUDA_CALL( cudaFree(d_C));
}

函数CUDA_CALLCURAND_CALLCUBLAS_CALL仅用于在出现问题时通知我并中断执行(找到代码here)。我将M设置为1024,但即使N_STREAMS等于1,它也会失败(它会给Segmentation fault (core dumped)提供更多信息)!

我不认为尺寸是这样的问题(请注意,我已将N_STREAMS设置为1,因此它 就像使用单个流/句柄一样)。我已成功尝试使用cuBLAS进行矩阵 - 矩阵乘法,尺寸为5000×5000和更高。在上面的例子中,如果我们减少M(例如#define M 50),它就可以......

更新 在我收到的评论之后,我将堆栈分配更改为h_C的动态分配,现在它可以正常工作。可以找到整个来源on github。欢迎任何进一步的评论。

0 个答案:

没有答案