cuBLAS argmin - 如果输出到设备内存,会出现段错误?

时间:2012-12-05 07:24:52

标签: cuda gpu gpgpu blas cublas

在cuBLAS中,cublasIsamin()给出了单精度数组的argmin。

这是完整的函数声明:cublasStatus_t cublasIsamin(cublasHandle_t handle, int n, const float *x, int incx, int *result)

cuBLAS程序员指南提供了有关cublasIsamin()参数的信息: enter image description here

如果我对result使用主机(CPU)内存,则cublasIsamin正常工作。这是一个例子:

void argmin_experiment_hostOutput(){
    float h_A[4] = {1, 2, 3, 4}; int N = 4; 
    float* d_A = 0;
    CHECK_CUDART(cudaMalloc((void**)&d_A, N * sizeof(d_A[0])));
    CHECK_CUBLAS(cublasSetVector(N, sizeof(h_A[0]), h_A, 1, d_A, 1));
    cublasHandle_t handle; CHECK_CUBLAS(cublasCreate(&handle));

    int result; //host memory
    CHECK_CUBLAS(cublasIsamin(handle, N, d_A, 1, &result));
    printf("argmin = %d, min = %f \n", result, h_A[result]);

    CHECK_CUBLAS(cublasDestroy(handle));
}

但是,如果我使用设备(GPU)内存result,那么cublasIsamin段错误。这是segfaults的一个例子:

void argmin_experiment_deviceOutput(){
    float h_A[4] = {1, 2, 3, 4}; int N = 4;
    float* d_A = 0;
    CHECK_CUDART(cudaMalloc((void**)&d_A, N * sizeof(d_A[0])));
    CHECK_CUBLAS(cublasSetVector(N, sizeof(h_A[0]), h_A, 1, d_A, 1));
    cublasHandle_t handle; CHECK_CUBLAS(cublasCreate(&handle));

    int* d_result = 0; 
    CHECK_CUDART(cudaMalloc((void**)&d_result, 1 * sizeof(d_result[0]))); //just enough device memory for 1 result
    CHECK_CUDART(cudaMemset(d_result, 0, 1 * sizeof(d_result[0])));
    CHECK_CUBLAS(cublasIsamin(handle, N, d_A, 1, d_result)); //SEGFAULT!

    CHECK_CUBLAS(cublasDestroy(handle));
}

Nvidia指南说`cublasIsamin()`可以输出到设备内存。我究竟做错了什么?


动机:我想在多个流中同时计算几个向量的argmin()。输出到主机内存需要CPU-GPU同步,并且似乎会破坏多内核并发性。所以,我想把argmin输出到设备内存。

1 个答案:

答案 0 :(得分:7)

CUBLAS V2 API支持将标量结果写入设备内存。但默认情况下它不支持此功能。根据文档的第2.4节“标量参数”,您需要使用cublasSetPointerMode()使API知道标量参数指针将驻留在设备内存中。请注意,这也使这些1级BLAS函数异步,因此在尝试访问结果指针之前必须确保GPU已完成内核。

有关完整的工作示例,请参阅this answer