【问题标题】:How to properly link cuda header file with device functions?如何正确链接 cuda 头文件与设备功能?
【发布时间】:2014-08-19 00:23:52
【问题描述】:

我正在尝试将我的代码解耦,但有些失败。编译错误:

error: calling a __host__ function("DecoupledCallGpu") from a __global__ function("kernel") is not allowed

代码摘录:

ma​​in.c(调用了 cuda 主机函数):

#include "cuda_compuations.h"
...
ComputeSomething(&var1,&var2);
...

cuda_computations.cu(具有内核、主机主控功能并包括具有设备功能的标头):

#include "cuda_computations.h"
#include "decoupled_functions.cuh"
...
__global__ void kernel(){
...
DecoupledCallGpu(&var_kernel);
}

void ComputeSomething(int *var1, int *var2){
//allocate memory and etc..
...
kernel<<<20,512>>>();
//cleanup
...
}

decoupled_functions.cuh

#ifndef _DECOUPLEDFUNCTIONS_H_
#define _DECOUPLEDFUNCTIONS_H_

void DecoupledCallGpu(int *var);

#endif

decoupled_functions.cu:

#include "decoupled_functions.cuh"

__device__ void DecoupledCallGpu(int *var){
  *var=0;
}

#endif

编译:

nvcc -g --ptxas-options=-v -arch=sm_30 -c cuda_computations.cu -o cuda_computations.o -lcudart

问题:为什么DecoupledCallGpu 是从主机函数调用而不是内核调用的?

P.S.:如果您需要,我可以分享它背后的实际代码。

【问题讨论】:

  • 好吧,在所有这些代码 sn-ps 中,您既没有显示“ComputeDensityGpu”也没有显示“DoColision”,它们是错误消息中列出的实际函数。所以你让我们猜测。但在我看来,decoupled_functions.cuh 中的 DecoupledCallGpu 原型缺少 __device__ 装饰器。并且将设备函数的编译与调用它的编译单元分开可能意味着您必须使用separate compilation and linking

标签: c++ cuda linker gpgpu nvidia


【解决方案1】:

__device__ 装饰器添加到decoupled_functions.cuh 中的原型。这应该可以解决您看到的错误消息。

然后你需要在你的模块中使用separate compilation and linking。因此,不要使用-c 编译,而是使用-dc 编译。并且您的链接命令将需要修改。一个基本的例子是here

你的问题有点混乱:

问题:为什么 DecoupledCallGpu 是从主机函数而不是内核调用的?

我不知道你是在说英语,还是这里有误会。实际的错误消息指出:

错误:不允许从 __global__ 函数(“内核”)调用 __host__ 函数(“DecoupledCallGpu”)

这是由于在编译单元内(即在模块内,在正在编译的文件内,即cuda_computations.cu),函数的唯一描述DecoupledCallGpu() 是原型中标题中提供的:

void DecoupledCallGpu(int *var);

这个原型表示CUDA C中的一个未修饰函数,这些函数是equivalent to__host__(仅)修饰函数:

__host__ void DecoupledCallGpu(int *var);

该编译单元不知道 decoupled_functions.cu 中的实际内容。

因此,当你有这样的内核代码时:

__global__ void kernel(){       //<- __global__ function
...
DecoupledCallGpu(&var_kernel);  //<- appears as a __host__ function to compiler
}

编译器认为您试图从 __global__ 函数调用 __host__ 函数,这是非法的。

【讨论】:

  • 对于 Visual Studio 用户,此选项转换为在 CUDA C++ 选项选项卡中将“生成可重定位设备代码”更改为“是”。见:stackoverflow.com/a/45258292/6734314
猜你喜欢
  • 1970-01-01
  • 2020-01-14
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多