在CUDA中分配设备变量时出现问题
尝试为设备变量赋值,然后将其复制到主机变量时遇到问题 我从d_检验开始,h_检验=0.0。我有一个简单的内核将设备变量d_test设置为1.0。然后将其复制到宿主变量h_test并打印。问题是当我打印时,我得到h_test=0.0。我做错了什么?代码如下:在CUDA中分配设备变量时出现问题,cuda,Cuda,尝试为设备变量赋值,然后将其复制到主机变量时遇到问题 我从d_检验开始,h_检验=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
// -*- 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);
}
/-*-模式:C-*-
#包括
#包括
#包括
//设备变量与内核
__装置浮球试验;
__全局无效内核1(浮点d_测试){d_测试=1.0;}
int main(){
//初始化变量
浮球h_试验=0.0;
cudaMemset(&d_测试,0,sizeof(float));
//调用内核
核1(d_检验);
//将设备变量复制到主机并打印
cudaMemcpy(h_测试、d_测试、sizeof(float)、cudamemcpydevicetoost);
printf(“%f\n”,h_测试);
}
我猜kernel1会更改其参数d_test,因为它隐藏了全局设备变量。
重命名其中一个,或者如果这适用于CUDA,则通过设置::d_test显式使用全局范围。您的代码有几个问题
kernel1
的参数d_test
隐藏了全局变量,因此当它赋值给d_test
时,它实际上是在更改其参数的值,而不是您想要的全局变量<在本例中,code>kernel1不需要使用参数\uuu设备\uuu
变量复制时,请使用cudaMemcpyFromSymbol
而不是cudaMemcpy
// -*- 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);
// or cudaMemcpyFromSymbol(&h_test, "d_test", sizeof(float), 0, cudaMemcpyDeviceToHost);
// until CUDA 5.0
printf("%f\n",h_test);
}
2019年11月更新
声明“CUDA 4.1中不推荐使用将变量命名为符号参数的字符串,CUDA 5.0中删除了该字符串。”cudaMemcpyFromSymbol在与cudaMemcpy抗争了很长一段时间并取回了错误的值后对我起到了作用。我不得不删除“d_test”周围的引号,并在cudaMemset中得到了一个无效的参数错误,所以只使用了代码中以前的cudamaloc。这段代码对我来说很好。钥匙在那儿 第二个变量应该是这样的\n cudaMemcpyFromSymbol(&h_测试、d_测试、sizeof(float)、0、cudaMemcpyDeviceToHost) 然后用
nvcc-Xcompiler-arch=sm_30 sample.cu-o sample.exe我已将d_test的名称更改为内核中的test,但这没有任何区别。全局范围是什么:dxTestTygy?出于某种原因,我认为您正在使用C++,在这里您可以使用范围:var访问特定范围内的变量。仅仅使用::就意味着全局作用域,从而访问由同名函数参数隐藏的全局变量。抱歉造成混淆:在cudaMemcpyFromSymbol中使用quote会在复制操作后导致0.0,因此只需删除quote符号即可。您使用的CUDA版本是什么?此时,
cudaMemset
返回错误消息:“cudaMemset”;和cudaMemcpyFromSymbol
返回错误消息:“返回错误消息”(API已更改,请参阅:)不确定确切原因,但一旦删除引号(例如cudaMemcpyFromSymbol(&h_测试,“d_测试”,sizeof(float),0,cudaMemcpyDeviceToHost);)
$ nvcc test.cu -run
1.000000