不支持外部呼叫 - CUDA

Ita*_*chi 4 c++ cuda gpgpu nvidia

目标是在另一个文件中调用一个设备函数,当我编译全局内核时,它显示以下错误*不支持外部调用(找到非内联调用_Z6GoldenSectionCUDA)*.

有问题的代码(不是完整的代码,但问题出现的地方),cat norm.h

# ifndef NORM_H_
# define NORM_H_
# include<stdio.h>

__device__ double invcdf(double prob, double mean, double stddev);

#endif
Run Code Online (Sandbox Code Playgroud)

猫norm.cu

# include <norm.h>

__device__ double invcdf(double prob, double mean, double stddev) {
    return (mean + stddev*normcdfinv(prob));
       }
Run Code Online (Sandbox Code Playgroud)

猫test.cu

# include <norm.h>
# include <curand.h>
# include <curand_kernel.h>

__global__ void phase2Kernel(double* out_profit, struct strategyHolder* strategy) {
       curandState seedValue;
       curand_init(threadIdx.x, 0, 0, &seedValue);
       double randomD = invcdf(curand_uniform_double( &seedValue ), 300, 80);
    }
Run Code Online (Sandbox Code Playgroud)

nvcc -c norm.cu -o norm.o -I"."
nvcc -c test.cu -o test.o -I"."

Tom*_*Tom 5

您正在尝试单独编译,这需要一些特殊的命令行选项.有关详细信息,请参阅NVCC手册,但这里是如何编写示例的.我的目标是sm_20,但你可以根据你拥有的GPU来定位sm_20或更高版本.旧设备上无法进行单独编译(sm_1x).

  • 您不需要在头文件中声明该__device__函数extern,但如果您有任何静态设备变量,则需要将它们声明为extern
  • 通过编译生成设备的可重定位代码,如下所示(-dc与设备等效-c,请参阅手册以获取更多信息)

    nvcc -arch=sm_20 -dc norm.cu -o norm.o -I.
    nvcc -arch=sm_20 -dc test.cu -o test.o -I.
    
    Run Code Online (Sandbox Code Playgroud)
  • 在最终主机链接之前通过调用nvlink链接代码的设备部分

    nvlink -arch=sm_20 norm.o test.o -o final.o
    
    Run Code Online (Sandbox Code Playgroud)

  • 静态定义符号肯定需要`extern`以防止链接期间出现重复错误,但前向声明应该足以用于函数. (2认同)