我在尝试为设备变量赋值,然后将其复制到主变量时遇到问题。
我从d_test和h_test = 0.0开始。我有一个简单的内核将设备变量d_test设置为1.0。然后我将其复制到主变量h_test并打印。问题是,当我打印时,我得到h_test = 0.0。我究竟做错了什么?这是代码:
// -*- mode: C -*-
#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
// device variable and kernel
__device__ float d_test;
__global__ void kernel1(float d_test) { d_test = 1.0; }
int main() {
// initialise variables
float h_test = 0.0;
cudaMemset(&d_test,0,sizeof(float));
// invoke kernel
kernel1 <<<1,1>>> (d_test);
// Copy device variable to host and print
cudaMemcpy(&h_test,&d_test,sizeof(float),cudaMemcpyDeviceToHost);
printf("%f\n",h_test);
}
答案 0 :(得分:6)
您的代码存在一些问题。
正如pezcode正确指出的那样,kernel1
的参数d_test
会影响您的全局变量,因此当它分配给d_test
时,它实际上会更改其参数的值,而不是你想要的全局变量。 kernel1
在这个例子中不需要参数。
从全局cudaMemcpy
变量复制时,使用cudaMemcpyFromSymbol
代替__device__
。
以下是完整的解决方案:
// -*- mode: C -*-
#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
// device variable and kernel
__device__ float d_test;
__global__ void kernel1() { d_test = 1.0; }
int main() {
// initialise variables
float h_test = 0.0;
cudaMemset(&d_test,0,sizeof(float));
// invoke kernel
kernel1 <<<1,1>>> ();
// Copy device variable to host and print
cudaMemcpyFromSymbol(&h_test, "d_test", sizeof(float), 0, cudaMemcpyDeviceToHost);
printf("%f\n",h_test);
}
输出:
$ nvcc test.cu -run
1.000000
答案 1 :(得分:4)
cudaMemcpyFromSymbol在与cudaMemcpy挣扎了很长一段时间之后为我工作,并且回到了错误的值。我不得不删除“d_test”周围的引号,并使用cudaMemset获得了无效的参数错误,所以只使用了之前代码中的cudaMalloc。
答案 2 :(得分:1)
我的猜测是kernel1更改了参数d_test,因为它隐藏了全局设备变量。 重命名其中一个或者如果它适用于CUDA,请通过设置:: d_test。
显式使用全局范围答案 3 :(得分:0)
这段代码对我很好。关键在那里。
第二个变量应该是这样的\ n
cudaMemcpyFromSymbol(&amp; h_test,d_test,sizeof(float),0,cudaMemcpyDeviceToHost);
然后用
编译你的代码
nvcc -Xcompiler -arch = sm_30 sample.cu -o sample.exe