cudaMemcpyToSymbol()的invalid device symbol问题
来源:互联网 发布:探索性数据分析 pdf 编辑:程序博客网 时间:2024/05/20 13:17
这个问题调试了好久,也从网上查了不少资料,但一直没找到解决方法,直到最近修改完成。因为查找解决方案花费很大功夫,为了方便,特此记录。
下面是问题描述。
我写一个cuda程序需要用到__constant__常量,而在host端给__constant__常量赋值的函数是cudaMemcpyToSymbol()函数。我在文件中声明了2个__constant__常量和3个__constant__二维数组,在host函数中把数据从host端传递到device端。为了更好说明,下面附上关键代码:
// ...// 声明__constant__ double cd;__constant__ int ci;__constant__ double ca1[4][4];__constant__ double ca2[4][4];__constant__ double ca3[4][4];void init(){ // 声明host端与__constant__对应变量并赋值 // 数据传递 size_t sized = sizeof(double); sizei = sizeof(int); cudaMemcpyToSymbol(&cd, &hd, sized, 0, cudaMemcpyHostToDevice); cudaMemcpyToSymbol(&ci, &hi, sizei, 0, cudaMemcpyHostToDevice); cudaMemcpyToSymbol(ca1, ha1, sized*4*4, 0, cudaMemcpyHostToDevice); // ca2和ca3的数据传递...}之后在kernel函数中使用ca1,ca2,ca3(二维数组)的时候都没问题,但等到使用cd和ci的时候,取值都是0。经过检查,是使用cudaMemcpyToSymbol函数的时候出了问题。
// ...cudaError_t err;err = cudaMemcpyToSymbol(&cd, &hd, sized, 0, cudaMemcpyHostToDevice);printf("%d: %s.\n", err, cudaGetErrorString(err));err = cudaMemcpyToSymbol(&ci, &hi, sizei, 0, cudaMemcpyHostToDevice);printf("%d: %s.\n", err, cudaGetErrorString(err));// ...打印结果:
13: invalid device symbol(无效的device symbol)
13: invalid device symbol
对于cudaMemcpyToSymbol函数,这种错误一般出现的原因是函数的第一个参数(设备端)数据类型有问题。我试过了更改计算能力,把&改成"",都失败了。直到把cd和ci改成指针类型:
// 声明__constant__ double *cd;__constant__ int *ci;// 赋值void init(){ // ... // 分配空间 cudaMalloc((void**)&cd, sized); cudaMalloc((void**)&ci, sizei); // ... // 数据传输 cudaError_t err; err = cudaMemcpyToSymbol(cd, &hd, sized, 0, cudaMemcpyHostToDevice); printf("%d: %s.\n", err, cudaGetErrorString(err)); err = cudaMemcpyToSymbol(ci, &hi, sizei, 0, cudaMemcpyHostToDevice); printf("%d: %s.\n", err, cudaGetErrorString(err)); // ...}// kernel函数__global__ void kernel(...){ // ... if(tid == 0 && bid == 0) printf("cd:%lf, ci:%d.\n", cd, ci); // ...}打印结果:
0: no error
0: no error
cd:cd的值, ci:ci的值
看起来没毛病,但实际上使用的时候会在调试过程中报错:
error: expression must have arithmetic or enum type(表达式必须是算数或枚举类型)
在之后才查到原来__constant__类型可以是变量、数组,但不能是指针。
所以最后还是要从cudaMemcpyToSymbol这个函数本身入手。CUDA Runtime API中关于此函数是这么说的:
__host__ cudaError_t cudaMemcpyToSymbol ( const void* symbol, const void* src, size_t count, size_t offset = 0, cudaMemcpyKind kind = cudaMemcpyHostToDevice )
Copies data to the given symbol on the device.
Parameters
symbol
- Device symbol address
src
- Source memory address
count
- Size in bytes to copy
offset
- Offset from start of symbol in bytes
kind
- Type of transfer
单看这个看不出什么来。然而我在cuda手册的3.2.2 Device Memory部分找到了如下三个例子:
__constant__ float constData[256];float data[256];cudaMemcpyToSymbol(constData, data, sizeof(data));cudaMemcpyFromSymbol(data, constData, sizeof(data));__device__ float devData; float value = 3.14f; cudaMemcpyToSymbol(devData, &value, sizeof(float));__device__ float* devPointer; float* ptr;cudaMalloc(&ptr, 256 * sizeof(float));cudaMemcpyToSymbol(devPointer, &ptr, sizeof(ptr));发现cudaMemcpyToSymbol函数的第一个参数都没有用&。
于是我抱着尝试的心态修改了代码:
// 声明__constant__ double cd;__constant__ int ci;// 赋值void init(){ // ... // 分配空间 cudaMalloc((void**)&cd, sized); cudaMalloc((void**)&ci, sizei); // ... // 数据传输 cudaError_t err; err = cudaMemcpyToSymbol(cd, &hd, sized, 0, cudaMemcpyHostToDevice); printf("%d: %s.\n", err, cudaGetErrorString(err)); err = cudaMemcpyToSymbol(ci, &hi, sizei, 0, cudaMemcpyHostToDevice); printf("%d: %s.\n", err, cudaGetErrorString(err)); // ...}
打印结果:
0: no error
0: no error
关于问题的出现以及这样解决的原因,到现在我也没有弄明白,如果找到了原因,再进行补充。
- cudaMemcpyToSymbol()的invalid device symbol问题
- "invalid device symbol"问题解决
- cudaMemcpyToSymbol
- cuda调用cudaMemcpyToSymbol出现cudaErrorInvalidSymbol (13)问题
- CUDA6.5调试向量求程序时出现invalid device function这一问题的解决方案
- CUDA程序的”invalid device funciton"错误信息
- error: invalid symbol:
- error: invalid symbol: 'switch'
- 基于WG2005的PCB设计-DEVICE值和symbol、Cell
- Android开发中关于“invalid symbol”的错误
- Altium Designer 中Device Sheet Symbol 与 Sheet Symbol 的使用
- uboot-Invalid boot device
- Cuda:invalid device pointer
- 关于Device tree的问题
- caffe-windows10 安装问题 Check failed: error == cudaSuccess (8 vs.0) invalid device function
- symbol 扫描枪开发遇到的问题
- 关于windbg的symbol设置问题
- 关于windbg的symbol设置问题
- OpenCV学习笔记之二值图像的边缘光滑处理
- 学习Linux系统的方法有很多,适合自己的才是最好。
- angularjs 一个数组 两层循环显示 例如一行三个,多行
- 快速提升游戏开发技术
- slice
- cudaMemcpyToSymbol()的invalid device symbol问题
- SimpleDraweeView低配置手机显示svg矢量图问题
- java工厂模式(设计模式)
- HDU 4474:Yet Another Multiple Problem
- Spring获取bean工厂的两种方法
- 增强For
- Spring Boot系列之十 日志配置
- 程序员该如何定位?看这四大方向
- 分分钟推导神经网络