4

我试图以这种方式将结构复制到常量内存:

struct Foo {
    int a, b, c;
};

__constant__ Foo cData;

int main() {
    Foo hData = {1, 2, 3};
    cudaMemcpyToSymbol(cData, &hData, sizeof(Foo));
    // ...
}

这很好用,在我的内核中我可以直接访问常量数据:

__global__ void kernel() {
    printf("Data is: %d %d %d\n", cData.a, cData.b, cData.c); // 1 2 3
}

但后来我尝试使用const char *符号名称,事情停止了:

cudaMemcpyToSymbol("cData", &hData, sizeof(Foo)); // prints 0 0 0

我认为两个版本相似,但似乎我错了。

怎么了?

编辑:我想用 cudaGetSymbolAddress 报告同样的行为,如果没有const char *使用,这对我有用:

__constant__ int someData[10];
__constant__ int *ptrToData;

int *dataPosition;
cudaGetSymbolAddress((void **)&dataPosition, someData); // Works
// cudaGetSymbolAddress((void **)&dataPosition, "someData"); // Do not work
cudaMemcpyToSymbol(ptrToData, &dataPosition, sizeof(int *));
4

2 回答 2

11

从 CUDA 5 开始,不再支持使用字符串作为符号名称。这在此处的 CUDA 5 发行说明中有所介绍

• 不再支持使用字符串来指示设备符号,这在某些 API 函数中是可能的。相反,应直接使用该符号。

原因之一与启用真正的设备链接器有关,这是 CUDA 5 中的新功能。

于 2013-03-15T15:50:14.223 回答
3

因为一次又一次地遇到同样的错误,我想分享这个示例代码,它显示了这个问题的几乎所有示例案例(所以我以后再次犯同样的错误时可以参考这里)。

//file: main.cu
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>

__constant__ float constData[256];
__device__ float devData;
__device__ float* devPointer;

int main(int argc, char **argv)
{
  cudaFree(0);

  float data[256];
  cudaError_t err = cudaMemcpyToSymbol(constData, data, sizeof(data));
  printf("Err id: %d, str: %s\n", err, cudaGetErrorString(err));

  float value = 3.14f;
  err = cudaMemcpyToSymbol(devData, &value, sizeof(float));
  printf("Err id: %d, str: %s\n", err, cudaGetErrorString(err));

  float* ptr;
  cudaMalloc(&ptr, 256 * sizeof(float));
  err = cudaMemcpyToSymbol(devPointer, &ptr, sizeof(ptr));
  printf("Err id: %d, str: %s\n", err, cudaGetErrorString(err));
  cudaFree(ptr);

  return EXIT_SUCCESS;
}

我得到“无效的设备符号”和许多其他与_常量_设备_内存使用有关的信息。此代码在运行时不会出现此类错误。

于 2013-04-16T19:27:14.200 回答