cuda 和 cublas 分段错误
cuda and cublas segmentation fault
在我的 main.cpp 中,我在主机上创建了一些向量,然后将它们复制到设备上。我还创建了一个 cublas 句柄,因为我想使用 cublas :
#define N 3
int main() {
float a[N], b[N], c[N];
float *dev_a, *dev_b, *dev_c;
// allocate the memory on the GPU
cudaMalloc( &dev_a, N * sizeof(float) ) ;
cudaMalloc( &dev_b, N * sizeof(float) );
cudaMalloc( &dev_c, N * sizeof(float) );
// fill the arrays 'a' and 'b' on the CPU
for (int i=0; i<N; i++) {
a[i] = i+0.1;
b[i] = i*i+0.5;
printf( "%f + %f \n", a[i], b[i]);
}
cudaMemcpy( dev_a, a, N * sizeof(float), cudaMemcpyHostToDevice );
cudaMemcpy( dev_b, b, N * sizeof(float), cudaMemcpyHostToDevice );
cublasHandle_t handle;
cublasCreate(&handle);
gpu_blas_sum(handle, dev_a, dev_b, dev_c, N) ;
// copy the array 'c' back from the GPU to the CPU
cudaMemcpy( c, dev_c, N * sizeof(float),cudaMemcpyDeviceToHost );
// ... Free cublas memory
}
然后我有一个 cuda.cu 和 cuda.h 文件,以便在设备
上面的代码中调用 gpu_blas_sum
cuda.h
void gpu_blas_sum(cublasHandle_t &handle, float *A, float *B, float *C, int n) ;
cuda.cu
void gpu_blas_sum(cublasHandle_t &handle, float *A, float *B, float *C, int n) {
const float alf = 1;
A[0] = 3;
cublasScopy(handle,n,A,1,C,1);//C = A
cublasSaxpy(handle,n,&alf,B,1,C,1);
}
cublas.cu 中的行 A[0] = 3
导致分段错误。我想我的函数 gpu_blas_sum 被认为是宿主函数。
如何让它在设备上执行,以便我可以取消引用设备指针,并在我使用 cublas 函数时利用 GPU 速度?
感谢帮助
这是非法的:
A[0] = 3;
这是主机代码,但是A
是一个设备指针。基本的 cuda 规则是不允许主机代码取消引用设备指针,并且不允许设备代码取消引用主机指针。如果您在主机代码中取消引用设备指针,则可能会出现段错误(就像您在主机代码中取消引用任何其他无意义的指针一样,例如 NULL 指针)。
如果你真的想做这个特定的操作,就像你写的那样,那么一个乏味但可行的解决方案是:
float my_val = 3;
cudaMemcpy(A, &my_val, sizeof(float), cudaMemcpyHostToDevice);
如果你想把所有东西都搬到设备上,我建议你研究一个从设备调用cublas函数的cuda示例代码,比如simpleDevLibCUBLAS
在我的 main.cpp 中,我在主机上创建了一些向量,然后将它们复制到设备上。我还创建了一个 cublas 句柄,因为我想使用 cublas :
#define N 3
int main() {
float a[N], b[N], c[N];
float *dev_a, *dev_b, *dev_c;
// allocate the memory on the GPU
cudaMalloc( &dev_a, N * sizeof(float) ) ;
cudaMalloc( &dev_b, N * sizeof(float) );
cudaMalloc( &dev_c, N * sizeof(float) );
// fill the arrays 'a' and 'b' on the CPU
for (int i=0; i<N; i++) {
a[i] = i+0.1;
b[i] = i*i+0.5;
printf( "%f + %f \n", a[i], b[i]);
}
cudaMemcpy( dev_a, a, N * sizeof(float), cudaMemcpyHostToDevice );
cudaMemcpy( dev_b, b, N * sizeof(float), cudaMemcpyHostToDevice );
cublasHandle_t handle;
cublasCreate(&handle);
gpu_blas_sum(handle, dev_a, dev_b, dev_c, N) ;
// copy the array 'c' back from the GPU to the CPU
cudaMemcpy( c, dev_c, N * sizeof(float),cudaMemcpyDeviceToHost );
// ... Free cublas memory
}
然后我有一个 cuda.cu 和 cuda.h 文件,以便在设备
上面的代码中调用gpu_blas_sum
cuda.h
void gpu_blas_sum(cublasHandle_t &handle, float *A, float *B, float *C, int n) ;
cuda.cu
void gpu_blas_sum(cublasHandle_t &handle, float *A, float *B, float *C, int n) {
const float alf = 1;
A[0] = 3;
cublasScopy(handle,n,A,1,C,1);//C = A
cublasSaxpy(handle,n,&alf,B,1,C,1);
}
cublas.cu 中的行 A[0] = 3
导致分段错误。我想我的函数 gpu_blas_sum 被认为是宿主函数。
如何让它在设备上执行,以便我可以取消引用设备指针,并在我使用 cublas 函数时利用 GPU 速度?
感谢帮助
这是非法的:
A[0] = 3;
这是主机代码,但是A
是一个设备指针。基本的 cuda 规则是不允许主机代码取消引用设备指针,并且不允许设备代码取消引用主机指针。如果您在主机代码中取消引用设备指针,则可能会出现段错误(就像您在主机代码中取消引用任何其他无意义的指针一样,例如 NULL 指针)。
如果你真的想做这个特定的操作,就像你写的那样,那么一个乏味但可行的解决方案是:
float my_val = 3;
cudaMemcpy(A, &my_val, sizeof(float), cudaMemcpyHostToDevice);
如果你想把所有东西都搬到设备上,我建议你研究一个从设备调用cublas函数的cuda示例代码,比如simpleDevLibCUBLAS