【问题标题】:How to return a single variable from a CUDA kernel function?如何从 CUDA 内核函数返回单个变量?
【发布时间】:2011-02-06 20:06:57
【问题描述】:

我有一个计算单个变量的 CUDA 搜索功能。怎么退货。

__global__ 
void G_SearchByNameID(node* Node, long nodeCount, long start,char* dest, long answer){
    answer = 2;
}

cudaMemcpy(h_answer, d_answer, sizeof(long), cudaMemcpyDeviceToHost);
cudaFree(d_answer);

对于这两行我得到这个错误: 错误:“long”类型的参数与“const void *”类型的参数不兼容

【问题讨论】:

    标签: c cuda


    【解决方案1】:

    我一直在为此使用__device__ 变量,这样您就不必为cudaMalloccudaFree 烦恼,也不必将指针作为内核参数传递,这样可以节省你在你的内核中注册一个启动。

    __device__ long d_answer;
    
    __global__ void G_SearchByNameID() {
      d_answer = 2;
    }
    
    int main() {
      SearchByNameID<<<1,1>>>();
      typeof(d_answer) answer;
      cudaMemcpyFromSymbol(&answer, "d_answer", sizeof(answer), 0, cudaMemcpyDeviceToHost);
      printf("answer: %d\n", answer);
      return 0;
    }
    

    【讨论】:

    • @Erogol 内核和主机代码都知道 __device__ 声明中的类型
    • 出于某种原因,这仅适用于我 (Toolkit 6.5) 如果我将 "d_answer" 替换为 d_answer,即删除引号。除此之外,这很好用。
    • 我的值总是为零。
    • __device__ 变量可以是线程本地的吗?像这样的全局变量不适用于多线程应用程序。
    • 这种方法不是“可重入”的,即不支持从多个流启动同一个内核。
    【解决方案2】:

    要获得单个结果,您必须对其进行 Memcpy,即:

    #include <assert.h>
    
    __global__ void g_singleAnswer(long* answer){ *answer = 2; }
    
    int main(){
    
      long h_answer;
      long* d_answer;
      cudaMalloc(&d_answer, sizeof(long));
      g_singleAnswer<<<1,1>>>(d_answer);
      cudaMemcpy(&h_answer, d_answer, sizeof(long), cudaMemcpyDeviceToHost); 
      cudaFree(d_answer);
      assert(h_answer == 2);
      return 0;
    }
    

    我猜这个错误是因为你传递的是一个 long 值,而不是一个指向 long 值的指针。

    【讨论】:

    • 你没有memcpy() - 还有其他选项,例如@wich 的答案。 -1 除非你认为复制是最好/唯一现实的选择。
    • 请注意,另一个选项确实执行memcpy(名称为cudaMemcpyFromSymbol)。这个答案使用动态分配,这对于多线程应用程序比另一个使用全局变量的应用程序更可取。
    猜你喜欢
    • 2014-03-14
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 2010-09-07
    相关资源
    最近更新 更多