我在设备变量上使用cudaMemset
时遇到问题。是否可以使用cudaMemset
的设备变量的引用,或者只是缺少编译器标志或库..我正在使用cuda 4.1和
NVRM版本:NVIDIA UNIX x86_64内核模块285.05.33 1月19日星期四 太平洋标准时间2012年14:07:02
这是我的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
// device variable and kernel
__device__ float d_test;
int main() {
if (cudaMemset(&d_test,0,sizeof(float)) !=cudaSuccess)
printf("Error!\n");
}
输出:
Error!
答案 0 :(得分:5)
您的问题是d_test
(因为它出现在主机符号表中)不是有效的设备地址,运行时无法直接访问它。解决方案是使用cudaGetSymbolAddress
API函数在运行时从上下文中读取设备符号的地址。以下是您的演示案例的略微扩展版本,它应该可以正常工作:
#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
// device variable and kernel
__device__ float d_test;
inline void gpuAssert(cudaError_t code, 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);
}
}
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
int main()
{
float * _d_test;
gpuErrchk( cudaFree(0) );
gpuErrchk( cudaGetSymbolAddress((void **)&_d_test, "d_test") );
gpuErrchk( cudaMemset(_d_test,0,sizeof(float)) );
gpuErrchk( cudaThreadExit() );
return 0;
}
在这里,我们从上下文中读取设备符号d_test
的地址到主机指针_d_test
。然后,可以将其传递给主机端API函数,如cudaMemset
,cudaMemcpy
等
编辑注意,此答案中显示的cudaGetSymbolAddress
形式已被弃用,并已从CUDA运行时API中删除。对于现代CUDA,呼叫将是:
gpuErrchk( cudaGetSymbolAddress((void **)&_d_test, d_test) );
答案 1 :(得分:0)
我相信你也可以使用cudaMemcpyFromSymbol: 函数(例如以下内核)可以更改在全局内存中声明的变量的值(在main函数之外)
__global__ void kernel1() { d_test = 1.0; }
在main中,您可以使用cudaMemcpyFromSymbol
获取值cudaMemcpyFromSymbol(&h_test,"d_test",sizeof(float),0,cudaMemcpyDeviceToHost);
当然,还有cudaMemcpyToSymbol来改变全局变量的值。