在将CUDA函数分离为声明和定义的同时链接错误

时间:2019-01-18 01:49:02

标签: c++ cuda linker

我正在关注instructions provided on NVidia blog post,该如何将从内核调用的函数分离为声明和定义。使用CUDA 10版本和Visual Studio编译器会产生链接错误。按照引用的文章中的说明,在 nvcc 编译器的选项中添加了 -dc 。这些文件都位于同一项目下的同一文件夹中。

test.cuh

__host__ __device__ float test(float, float);

test.cu

#include "test.cuh"    
__host__ __device__ float test(float a, float b)
{
    return a + b;
}

kernel.cu

#include <stdio.h>
#include "test.cuh"
__global__ void addKernel(int *c, const int *a, const int *b)
{
    int i = threadIdx.x;
    c[i] =  test(a[i], b[i]);
}

链接错误

1>kernel.cu.obj : error LNK2019: unresolved external symbol __cudaRegisterLinkedBinary_41_tmpxft_0000796c_00000000_7_kernel_cpp1_ii_f853efa9 referenced in function "void __cdecl __nv_cudaEntityRegisterCallback(void * *)" (?__nv_cudaEntityRegisterCallback@@YAXPEAPEAX@Z)
1>test.cuh.obj : error LNK2019: unresolved external symbol __cudaRegisterLinkedBinary_39_tmpxft_00006d84_00000000_7_test_cpp1_ii_f2c23be0 referenced in function "void __cdecl __nv_cudaEntityRegisterCallback(void * *)" (?__nv_cudaEntityRegisterCallback@@YAXPEAPEAX@Z)
1>test.cu.obj : error LNK2019: unresolved external symbol __cudaRegisterLinkedBinary_39_tmpxft_00008044_00000000_7_test_cpp1_ii_f2c23be0 referenced in function "void __cdecl __nv_cudaEntityRegisterCallback(void * *)" (?__nv_cudaEntityRegisterCallback@@YAXPEAPEAX@Z)
1>D:\Workspaces\src\sandbox\cuda_dc\x64\Debug\cuda_dc.exe : fatal error LNK1120: 3 unresolved externals

如果将文件扩展名更改为“ .c”,“。cpp”或“ .cuh”,则没有任何作用

1 个答案:

答案 0 :(得分:1)

这些是我遵循的步骤,使用您显示的代码,并添加一个简单的main()函数,以便我们可以拥有一个完整的项目。

(在Visual Studio中)

  1. 文件..新建..项目
  2. 在左侧,向下滚动到NVIDIA并选择它
  3. 选择CUDA X.Y运行时项目,为项目命名,然后单击“确定”
  4. 在顶部菜单栏的“调试”旁边,将x86更改为x64
  5. 项目中应该有一个默认文件kernel.cu。将其内容替换为(修改您的kernel.cu以添加主要功能):

    #include <stdio.h>
    #include "test.cuh"
    __global__ void addKernel(int *c, const int *a, const int *b)
    {
        int i = threadIdx.x;
        c[i] = test(a[i], b[i]);
    }
    int main() {
        int *c = NULL;
        int *a = NULL;
        int *b = NULL;
        addKernel << <1, 1 >> > (c, a, b);
    }
    

(在Windows中,例如使用文件管理器)

  1. 在kernel.cu所在的项目文件夹中,放置文件test.cuh和test.cu(您发布的未使用C链接的更新版本)

(在Visual Studio中)

  1. 在解决方案资源管理器窗口中转到项目,右键单击项目名称,然后选择“属性”
  2. 在对话框的左侧,选择“ CUDA C / C ++”
  3. 在右侧,将“生成可重定位设备代码”旁边的下拉菜单从“否”更改为“是”。
  4. 在左侧,选择“ CUDA链接器”并确认“执行设备链接”已设置为“是”。
  5. 选择“确定”以关闭对话框

  6. 同样,在解决方案资源管理器窗口中,右键单击项目名称,然后选择添加...现有项

  7. 应打开一个文件选择对话框。您应该会看到kernel.cu文件以及添加到该文件夹​​中的test.cu和test.cuh文件
  8. 选择并添加test.cu文件
  9. 现在选择“构建...重建解决方案”

执行这些步骤时,我得到的是干净的编译文件,没有错误:

1>------ Rebuild All started: Project: test37, Configuration: Debug x64 ------
1>
1>  c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\test37>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64"  -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include"  -G   --keep-dir x64\Debug -maxrregcount=0  --machine 64 --compile   -g   -DWIN32 -DWIN64 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /FS /Zi /RTC1 /MDd " -o x64\Debug\kernel.cu.obj "c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\test37\kernel.cu" -clean
1>CUDACOMPILE : nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
1>  kernel.cu
1>
1>  c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\test37>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64"  -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include"  -G   --keep-dir x64\Debug -maxrregcount=0  --machine 64 --compile   -g   -DWIN32 -DWIN64 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /FS /Zi /RTC1 /MDd " -o x64\Debug\test.cu.obj "c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\test37\test.cu" -clean
1>CUDACOMPILE : nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
1>  test.cu
1>  Compiling CUDA source file kernel.cu...
1>  Compiling CUDA source file test.cu...
1>
1>  c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\test37>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -gencode=arch=compute_20,code=\"sm_20,compute_20\" --use-local-env --cl-version 2015 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64" -rdc=true -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include"  -G   --keep-dir x64\Debug -maxrregcount=0  --machine 64 --compile -cudart static  -g   -DWIN32 -DWIN64 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /FS /Zi /RTC1 /MDd " -o x64\Debug\kernel.cu.obj "c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\test37\kernel.cu"
1>
1>  c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\test37>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -gencode=arch=compute_20,code=\"sm_20,compute_20\" --use-local-env --cl-version 2015 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64" -rdc=true -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include"  -G   --keep-dir x64\Debug -maxrregcount=0  --machine 64 --compile -cudart static  -g   -DWIN32 -DWIN64 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /FS /Zi /RTC1 /MDd " -o x64\Debug\test.cu.obj "c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\test37\test.cu"
1>CUDACOMPILE : nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
1>  kernel.cu
1>CUDACOMPILE : nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
1>  test.cu
1>
1>  c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\test37>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\nvcc.exe" -dlink -o x64\Debug\test37.device-link.obj -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd " -L"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64" cudart.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  -gencode=arch=compute_20,code=sm_20 -G --machine 64 x64\Debug\kernel.cu.obj x64\Debug\test.cu.obj
1>CUDALINK : nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
1>  cudart.lib
1>  kernel32.lib
1>  user32.lib
1>  gdi32.lib
1>  winspool.lib
1>  comdlg32.lib
1>  advapi32.lib
1>  shell32.lib
1>  ole32.lib
1>  oleaut32.lib
1>  uuid.lib
1>  odbc32.lib
1>  odbccp32.lib
1>  kernel.cu.obj
1>  test.cu.obj
1>  test37.vcxproj -> c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\x64\Debug\test37.exe
1>  test37.vcxproj -> c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\x64\Debug\test37.pdb (Full PDB)
1>  copy "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\cudart*.dll" "c:\Users\bob-tosh\documents\visual studio 2015\Projects\test37\x64\Debug\"
1>  C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\cudart32_80.dll
1>  C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin\cudart64_80.dll
1>          2 file(s) copied.
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

我的观点是,如果您可以完全按照上述步骤操作,从一个新项目开始并使用我指示的文件,并且获得与我相同的结果,那么您在问题中描述的问题与您所要解决的问题有关尚未显示或未描述。然后,您应该提供一个MCVE,并确保提供与我在回答中所提供的相同级别的详细信息。用于创建,构建和编译项目的每个步骤,以及控制台构建输出和所有使用的文件。

我已经使用了CUDA 8和Visual Studio 2015,但是我认为这里所描述的更新的VS和更新的CUDA版本应该没有实质性的区别。