2012-04-03 92 views
1

我在设备变量上使用cudaMemset时遇到问题。是否有可能使用参考设备变量cudaMemset,或者是它只是一个缺少编译器标志,或库..我使用CUDA 4.1的事情,cudaMemset在__device__变量上失败

NVRM版本:NVIDIA UNIX x86_64的内核模块285.05.33周四年01月19 14时07分02秒PST 2012

这是我的示例代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <cuda_runtime.h> 

// device variable and kernel 
__device__ float d_test; 

int main() { 

    if (cudaMemset(&d_test,0,sizeof(float)) !=cudaSuccess) 
     printf("Error!\n"); 
} 

,其输出:

Error! 
+0

cudaGetSymbolAddress不会为我工作。 我需要添加一些编译器标志吗? 我复制上面的代码,但它说GPUassert:无效的设备符号XXXX.cu 24 – worldterminator 2012-08-29 16:48:18

回答

4

您的问题是d_test(因为它出现在主机符号表中)不是有效的设备地址,运行时无法直接访问它。解决方案是使用API​​函数cudaGetSymbolAddress在运行时从上下文中读取设备符号的地址。这是你的演示情况略有扩大版本,它应能正常工作:

#include <stdio.h> 
#include <stdlib.h> 
#include <cuda_runtime.h> 

// device variable and kernel 
__device__ float d_test; 

inline void gpuAssert(cudaError_t code, char * file, int line, bool Abort=true) 
{ 
    if (code != cudaSuccess) { 
     fprintf(stderr, "GPUassert: %s %s %d\n", cudaGetErrorString(code),file,line); 
     if (Abort) exit(code); 
    }  
} 

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } 

int main() 
{ 

    float * _d_test; 

    gpuErrchk(cudaFree(0)); 
    gpuErrchk(cudaGetSymbolAddress((void **)&_d_test, "d_test")); 
    gpuErrchk(cudaMemset(_d_test,0,sizeof(float))); 

    gpuErrchk(cudaThreadExit()); 

    return 0; 
} 

在这里,我们看到从上下文设备符号d_test的地址转换为主机指针_d_test。这可以被传递到主机像cudaMemsetcudaMemcpy端API函数等

+0

谢谢!这工作..很好的了解'cudaGetSymbolAddress'函数从上下文中提取符号地址。 – nganesan 2012-04-17 02:00:26

0

我相信你也可以使用cudaMemcpyFromSymbol: 的函数,如下面的内核,可以改变变量的全局内存公布值(主要功能之外)

__global__ void kernel1() { d_test = 1.0; } 

里面你的主,你能获得使用cudaMemcpyFromSymbol

cudaMemcpyFromSymbol(&h_test,"d_test",sizeof(float),0,cudaMemcpyDeviceToHost); 

当然的价值,也有cudaMe mcpyToSymbol来更改全局变量的值。

的想法来自这里:Having problem assigning a device variable in CUDA

+0

请注意,此答案中显示的'cudaMemcpyFromSymbol'调用形式已过时,并且在CUDA 5或CUDA 6中都不受支持 – talonmies 2014-05-18 13:17:12