2013-03-22 162 views
0

我对CUDA完全陌生。我想在设备上创建一个对象,并从不同的线程访问其成员。我使用nvcc -arch = sm_20(在Tesla M2090上),如果我运行我的代码,我会得到'未指定的启动失败'。这里是我的代码:线程之间的CUDA共享对象

#include <stdio.h> 
#include <string> 

using namespace std; 

#ifdef __CUDACC__ 
#define CUDA_CALLABLE __host__ __device__ 
#else 
#define CUDA_CALLABLE 
#endif 

class SimpleClass { 
public: 
    int i; 
    CUDA_CALLABLE SimpleClass(){i=1;}; 
    CUDA_CALLABLE ~SimpleClass(){}; 
}; 

__global__ void initkernel(SimpleClass *a){ 
    a = new SimpleClass(); 
} 
__global__ void delkernel(SimpleClass *a){ 
    delete a; 
} 
__global__ void kernel(SimpleClass *a){ 
printf("%d\n", a->i); 
} 

int main() { 
    SimpleClass *a; 
    initkernel<<<1,1>>>(a); 
    cudaThreadSynchronize(); 
    kernel<<<1,10>>>(a); 
    cudaThreadSynchronize(); 
    delkernel<<<1,1>>>(a); 
    cudaThreadSynchronize(); 

    cudaError_t error = cudaGetLastError(); 
    string lastError = cudaGetErrorString(error); 
    printf("%s\n",lastError.c_str()); 
    return 0; 
} 
+0

您应该检查每个内核调用后发生的错误,而不是在最后。这也适用于任何CUDA API调用。 – pQB 2013-03-22 15:51:30

+0

你可以试着用cuda-memcheck运行你的应用程序并发布结果吗? – Vyas 2013-03-22 22:23:58

回答

0

你的第一个内核代码中得到“未指定发射失败”,因为“A”是存储在主机的指针,但你想给它从一个设备功能的价值。如果你想在设备上分配对象,比你首先必须在设备上分配一个指针,并且你可以读写设备(内核)代码,但要小心,因为它需要双重间接。

您的代码应该看起来像这样的事情(的其余功能应同样修改):

__global__ void initkernel(SimpleClass** a){ 
    *a = new SimpleClass(); 
} 

int main() { 
    SimpleClass** a; 
    cudaMalloc((void**)&a, sizeof(SimpleClass**)); 
    initkernel<<<1,1>>>(a); 
    cudaThreadSynchronize(); 
} 

PS:PQB是绝对正确的是,你应该做的每个内核之后的错误检查代码尽快检测错误(并且目前用于查找代码中错误的确切位置)

+0

谢谢SqrtPi,你的建议解决了这个问题。 – robogos 2013-03-23 05:56:00