如何正确链接cuda头文件与设备功能?

Den*_* S. 3 c++ linker cuda gpgpu nvidia

我试图将我的代码解耦一些,但是有些东西失败了.编译错误:

error: calling a __host__ function("DecoupledCallGpu") from a __global__ function("kernel") is not allowed
Run Code Online (Sandbox Code Playgroud)

代码摘录:

main.c(调用cuda主机函数):

#include "cuda_compuations.h"
...
ComputeSomething(&var1,&var2);
...
Run Code Online (Sandbox Code Playgroud)

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
...
}
Run Code Online (Sandbox Code Playgroud)

decoupled_functions.cuh:

#ifndef _DECOUPLEDFUNCTIONS_H_
#define _DECOUPLEDFUNCTIONS_H_

void DecoupledCallGpu(int *var);

#endif
Run Code Online (Sandbox Code Playgroud)

decoupled_functions.cu:

#include "decoupled_functions.cuh"

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

#endif
Run Code Online (Sandbox Code Playgroud)

汇编:

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

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

PS:如果你需要,我可以分享它背后的实际代码.

Rob*_*lla 8

__device__装饰器添加到原型中decoupled_functions.cuh.这应该照顾你看到的错误信息.

然后,您需要在模块之间使用单独的编译和链接.因此,而不是使用编译进行-c编译-dc.您的链接命令将需要修改.这里有一个基本的例子.

你的问题有点令人困惑:

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

我不知道你是不是在tri english or or or or or or or or or or or or or or or or 实际的错误消息指出:

错误:不允许__host____global__函数("内核")调用函数("DecoupledCallGpu")

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

void DecoupledCallGpu(int *var);
Run Code Online (Sandbox Code Playgroud)

这个原型在CUDA C中表示一个未修饰的函数,这些函数等同于 __host__(仅)修饰函数:

__host__ void DecoupledCallGpu(int *var);
Run Code Online (Sandbox Code Playgroud)

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

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

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

编译器认为你试图__host__从一个__global__函数调用一个函数,这是非法的.

  • 对于 Visual Studio 用户,此选项转换为将 CUDA C++ 选项选项卡中的“生成可重定位设备代码”更改为“是”。参见:/sf/answers/3168080471/ (2认同)