2013-06-06 43 views
0

我有下面显示的代码片段。这两个对“cudaMemcpyToSymbol”的调用基本相同(对dev_a,dev_b的所有操作也是相同的),但是当我运行代码时,仅在第二次调用“cudaMemcpyToSymbol”时报告了“无效设备符号”错误。如果我删除它,那么代码运行没有任何问题。有谁知道可能是什么原因?谢谢。针对结构字段指针的“无效设备符号”

struct aStruct { 
    double *a; 
    double *b; 
}; 

__device__ struct aStruct as; 

int main(void) { 

double *dev_a, *dev_b; 
HANDLE_ERROR(cudaMalloc((void**)&dev_a, N * sizeof(double))); 
HANDLE_ERROR(cudaMalloc((void**)&dev_b, N * sizeof(double))); 
... 
HANDLE_ERROR(cudaMemcpyToSymbol(as.a, &dev_a, sizeof(double *))); 
HANDLE_ERROR(cudaMemcpyToSymbol(as.b, &dev_b, sizeof(double *))); 
.... 
} 

回答

2

完全一样的错误说,as.aas.b无效设备的符号。 as设备符号,但结构本身的成员没有符号表条目,您不能直接在其上应用cudaMemcpyToSymbol

为了解决这个问题,这样做如下:

struct aStruct _as; 

HANDLE_ERROR(cudaMalloc((void**)&_as.a, N * sizeof(double))); 
HANDLE_ERROR(cudaMalloc((void**)&_as.b, N * sizeof(double))); 

HANDLE_ERROR(cudaMemcpyToSymbol(as, &_as, sizeof(struct aStruct))); 

[免责声明写在浏览器中,没有编译或测试,使用风险自担]

即。只复制一个完全初始化的struct aStruct符号,而不是试图通过成员复制成员。

+0

太棒了,它的工作原理!非常感谢。只是有一个后续问题,如果我稍后想要将as.a传递给内核启动,该怎么办?我是否必须使用“cudaMemcpyFromSymbol”整个结构来主持并传递第一个字段?如果“as”也是另一个结构中的字段呢?我必须一个接一个地做这个吗?我从以前的帖子中读到,不建议使用多级间接寻址,但我需要为我的应用程序。有没有简单的方法来解决这个问题?谢谢。 – roger

+0

如果'as'在编译单元范围内被声明为'__device__'变量,则不需要将其作为内核传递,它可以直接从内部代码中访问。如果您确实需要将主机中的结构传递给内核,请按照我的示例代码中所示的'_as'值。另外,如果此答案解决了您的问题,则可以考虑接受该问题,将其从未答复的队列中移除。 – talonmies

+0

感谢您的快速响应。我是新来的stackoverflow,并不知道“规则”。我已经接受了答案。关于后续问题,我想我现在找到了解决方法,这要感谢你的建议。 – roger