我试图在启动需要这些值的内核之前在GPU的常量内存上设置常量值。
我的代码(简化):
__constant__ size_t con_N;
int main()
{
size_t N;
size_t* dev_N = NULL;
cudaError_t cudaStatus;
//[...]
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, &con_N);
if (cudaStatus != cudaSuccess) {
cout<<"cudaGetSymbolAddress (dev_N) failed: "<<cudaGetErrorString(cudaStatus)<<endl;
}
之后我计划cudaMemcpy
N
到dev_N
。
但是,我在代码中得到的所有内容都是:
cudaGetSymbolAddress (dev_N) failed: invalid device symbol
我正在使用CUDA 6.5,因此它不是一个带引号的符号问题,因为它在我迄今为止检查过的大部分Q&amp; A中都已经过了。
我尝试将con_N
替换为con_N[1]
(并删除&
参数中con_N
之前的cudaGetSymbolAddress
:同样的结果。
由于这个函数的原型是cudaGetSymbolAddress(void **devPtr , const void* symbol )
,我猜想它想要给我的符号地址。但是,我尝试了cudaStatus = cudaGetSymbolAddress((void **)&dev_N, (const void*) con_N);
并得到了同样的信息。
当我删除cudaGetSymbolAddress((void **)&dev_N, &con_N)
并直接使用cudaMemcpyToSymbol(&con_N, &N, sizeof(size_t))
时,我也收到了相同的错误消息。
我害怕错过了必不可少的东西。任何帮助将不胜感激。
答案 0 :(得分:1)
cudaGetSymbolAddress
的正确用法是
cudaGetSymbolAddress((void **)&dev_N, con_N)
我用下面的简单示例展示了这一点。
正如文档所述,符号应该物理上驻留在设备上。因此,在API调用中使用&con_N
似乎毫无意义,因为作为主机API的cudaGetSymbolAddress
,不应该直接从主机访问驻留在设备上的内容的地址。我不确定出现在CUDA Runtime API文档中的原型是否应该更好地读作`
template<class T>
cudaError_t cudaGetSymbolAddress (void **devPtr, const T symbol)
使用设备符号引用而不是设备符号地址。
#include <stdio.h>
__constant__ int const_symbol;
/********************/
/* CUDA ERROR CHECK */
/********************/
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const 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);
}
}
/***************/
/* TEST KERNEL */
/***************/
__global__ void kernel() {
printf("Address of symbol from device = %p\n", &const_symbol);
}
/********/
/* MAIN */
/********/
int main()
{
const int N = 16;
int *pointer = NULL;
gpuErrchk(cudaGetSymbolAddress((void**)&pointer, const_symbol));
kernel<<<1,1>>>();
printf("Address of symbol from host = %p\n", pointer);
return 0;
}
答案 1 :(得分:0)
在我看来,你的代码的一行应修改如下。
cudaStatus = cudaGetSymbolAddress((void **)&dev_N, con_N);
希望这会对你有所帮助。