我试图以这种方式将结构复制到常量内存:
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 *));
答案 0 :(得分:10)
从CUDA 5开始,不再支持使用字符串作为符号名称。这在CUDA 5发行说明here
中有所介绍•不再支持使用字符串来表示某些API函数可能出现的设备符号。相反,应该直接使用该符号。
其中一个原因与启用真正的设备链接器有关,这是CUDA 5中的新功能。
答案 1 :(得分:2)
由于一次又一次地获得相同的错误,我想分享这个示例代码,该代码几乎显示了这个问题的所有示例案例(所以我稍后会在这里再次提到同样的错误时参考)。
//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;
}
我收到了“无效设备符号”以及许多与 _ 常量 _ _ 设备 _ 强>内存使用率。此代码在运行时不会出现此类错误。