我试图使用不同的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_CALL
,CURAND_CALL
和CUBLAS_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。欢迎任何进一步的评论。