在CUDA中分配设备变量时遇到问题

时间:2011-07-29 10:36:28

标签: cuda

我在尝试为设备变量赋值,然后将其复制到主变量时遇到问题。

我从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);  

}

4 个答案:

答案 0 :(得分:6)

您的代码存在一些问题。

  1. 正如pezcode正确指出的那样,kernel1的参数d_test会影响您的全局变量,因此当它分配给d_test时,它实际上会更改其参数的值,而不是你想要的全局变量。 kernel1在这个例子中不需要参数。

  2. 从全局cudaMemcpy变量复制时,使用cudaMemcpyFromSymbol代替__device__

  3. 以下是完整的解决方案:

    // -*- 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