我想從設備運行矩陣反轉。如果從主機調用此邏輯,則工作正常。從設備的cublas矩陣反轉
編譯行如下(Linux的):
nvcc -ccbin g++ -arch=sm_35 -rdc=true simple-inv.cu -o simple-inv -lcublas_device -lcudadevrt
我碰到下面的警告,我似乎無法化解。 (我的GPU是開普勒我不知道爲什麼它正試圖鏈接到麥克斯韋程序我有Cuda的6.5-14。):
handle 0 n = 3
simple-inv.cu:63 Error [an illegal memory access was encountered]
測試:
nvlink warning : SM Arch ('sm_35') not found in '/usr/local/cuda/bin/../targets/x86_64-linux/lib/libcublas_device.a:maxwell_sm50_sgemm.o'
程序與運行程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cuda_runtime.h>
#include <cublas_v2.h>
#define PERR(call) \
if (call) {\
fprintf(stderr, "%s:%d Error [%s] on "#call"\n", __FILE__, __LINE__,\
cudaGetErrorString(cudaGetLastError()));\
exit(1);\
}
#define ERRCHECK \
if (cudaPeekAtLastError()) { \
fprintf(stderr, "%s:%d Error [%s]\n", __FILE__, __LINE__,\
cudaGetErrorString(cudaGetLastError()));\
exit(1);\
}
__global__ void
inv_kernel(float *a_i, float *c_o, int n)
{
int p[3], info[1], batch;
cublasHandle_t hdl;
cublasStatus_t status = cublasCreate_v2(&hdl);
printf("handle %d n = %d\n", status, n);
info[0] = 0;
batch = 1;
float *a[] = {a_i};
const float *aconst[] = {a_i};
float *c[] = {c_o};
// See
// http://docs.nvidia.com/cuda/pdf/CUDA_Dynamic_Parallelism_Programming_Guide.pdf
//http://stackoverflow.com/questions/27094612/cublas-matrix-inversion-from-device
status = cublasSgetrfBatched(hdl, n, a, n, p, info, batch);
__syncthreads();
printf("rf %d info %d\n", status, info[0]);
status = cublasSgetriBatched(hdl, n, aconst, n, p,
c, n, info, batch);
__syncthreads();
printf("ri %d info %d\n", status, info[0]);
cublasDestroy_v2(hdl);
printf("done\n");
}
static void
run_inv(float *in, float *out, int n)
{
float *a_d, *c_d;
PERR(cudaMalloc(&a_d, n*n*sizeof(float)));
PERR(cudaMalloc(&c_d, n*n*sizeof(float)));
PERR(cudaMemcpy(a_d, in, n*n*sizeof(float), cudaMemcpyHostToDevice));
inv_kernel<<<1, 1>>>(a_d, c_d, n);
cudaDeviceSynchronize();
ERRCHECK;
PERR(cudaMemcpy(out, c_d, n*n*sizeof(float), cudaMemcpyDeviceToHost));
PERR(cudaFree(a_d));
PERR(cudaFree(c_d));
}
int
main(int argc, char **argv)
{
float c[9];
float a[] = {
1, 2, 3,
0, 4, 5,
1, 0, 6 };
run_inv(a, c, 3);
return 0;
}
我也跟着指導在http://docs.nvidia.com/cuda/cublas/index.html#device-api第2.1.9節,但我懷疑我忽略了一些東西。
注意:11月24日編輯使用正確的指針輸入。這仍然報告內核中的非法內存訪問。
您發佈的代碼中的第63行是空格。代碼中發生的錯誤究竟在哪裏? – talonmies 2014-11-23 21:42:55
設備同步期間的第64行。我必須發佈和更老的輸出。我懷疑在調用cublasSgetrfBatched期間。 – Bob 2014-11-23 21:47:10
'(float **)a_i'看起來很可疑。當然,你的意思是傳遞'a_i'的地址而不是它的值? – talonmies 2014-11-23 22:03:21