cuBLAS argmin - segfault se estiver enviando para a memória do dispositivo?
Em cuBLAS,cublasIsamin()
fornece o argmin para uma matriz de precisão única.
Aqui está a declaração completa da função:cublasStatus_t cublasIsamin(cublasHandle_t handle, int n, const float *x, int incx, int *result)
O guia do programador cuBLAS fornece esta informação sobre ocublasIsamin()
parâmetros:
Se eu usarhospedeiro (CPU) memória pararesult
, entãocublasIsamin
funciona corretamente. Aqui está um exemplo:
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));
}
No entanto, se eu usardispositivo (GPU) pararesult
, entãocublasIsamin
segfaults. Aqui está um exemplo que 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));
}
O guia da Nvidia diz que `cublasIsamin ()` pode enviar para a memória do dispositivo. O que estou fazendo de errado?Motivação: Eu quero calcular o argmin () de vários vetores simultaneamente em múltiplos fluxos. A saída para a memória do host requer a sincronização CPU-GPU e parece matar a simultaneidade multi-kernel. Então, eu quero enviar o argmin para a memória do dispositivo.