Ошибка связывания при разделении функции CUDA на объявление и определение - PullRequest
0 голосов
/ 18 января 2019

Я следую инструкциям в блоге NVidia о том, как разделить функции, вызываемые из ядра, на объявление и определение. Использование версии 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 голосов
/ 18 января 2019

Это шаги, которые я выполнил, используя код, который вы показали, плюс добавление простой функции main(), чтобы у нас был полный проект.

(в Visual Studio)

  1. File..New..Project
  2. слева, прокрутите вниз до NVIDIA и выберите его
  3. выберите CUDA X.Y исполняемый проект, дайте имя проекту, нажмите OK
  4. в верхней строке меню, рядом с Debug, измените 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)

(в визуальной студии)

  1. Перейдите к проекту в окнах обозревателя решений, щелкните правой кнопкой мыши имя проекта и выберите Свойства
  2. В левой части диалогового окна выберите «CUDA C / C ++»
  3. В правой части окна выберите «Создать код перемещаемого устройства» с Нет на Да
  4. С левой стороны выберите «CUDA linker» и подтвердите, что «Perform device link» уже установлен в «yes»
  5. Выберите ОК, чтобы закрыть диалоговое окно

  6. Опять же, в окне обозревателя решений, щелкните правой кнопкой мыши на имени проекта и выберите Добавить ... существующий элемент

  7. Должен открыться диалог выбора файла. Вы должны увидеть файл kernel.cu плюс файлы test.cu и test.cuh, которые вы добавили в папку
  8. Выберите и добавьте файл test.cu
  9. Теперь выберите Build ... Rebuild Solution

Когда я делаю эти шаги, я получаю чистую компиляцию без ошибок:

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.

...