CUDA常量内存问题:使用cudaGetSymbolAddress的设备符号无效

时间:2014-11-04 13:01:34

标签: memory-management cuda

我试图在启动需要这些值的内核之前在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 Ndev_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))时,我也收到了相同的错误消息。

我害怕错过了必不可少的东西。任何帮助将不胜感激。

2 个答案:

答案 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);

希望这会对你有所帮助。