Раздельная компиляция CUDA с CMake, недопустимая функция устройства - PullRequest
1 голос
/ 26 апреля 2020

Я занимаюсь разработкой приложения на C ++ с использованием cmake в качестве системы сборки. Каждый компонент в приложении встроен в библиотеку stati c, на которую ссылается исполняемый файл.

Я пытаюсь связать некоторый код cuda, который создается как отдельная библиотека stati c, также с помощью cmake , Когда я пытаюсь вызвать точку входа глобальной функции в библиотеке cuda stati c из основного приложения, кажется, что все работает нормально - cudaDeviceSynchronize, который следует за моим вызовом глобальной функции, возвращает 0. Однако вывод ядра не установлен и звонок немедленно возвращается.

Я запустил cuda-gdb. Несмотря на то, что код был скомпилирован с помощью -g и -G, я не смог разбить функцию устройства, вызываемую ядром. Итак, я запустил cuda-memcheck. Когда ядро ​​запускается, появляется это сообщение: ========= Program hit cudaErrorInvalidDeviceFunction (error 8) due to "invalid device function" on CUDA API call to cudaLaunchKernel.

Я посмотрел это, и прочитанные мной посты и документы NVIDIA предположили, что это обычно происходит из-за неправильной вычислительной способности. Тем не менее, я использую Titan V, и CC правильно установлен на 7.0 при компиляции.

Я установил CUDA_SEPARABLE_COMPILATION как для библиотеки cuda, так и для компонента в основном приложении, с которым связан код cuda за https://devblogs.nvidia.com/building-cuda-applications-cmake/. Я также попытался установить CUDA_RESOLVE_DEVICE_SYMBOLS.

Вот соответствующая часть cmake для основного приложения:

(kronmult_cuda - это компонент в основном приложении, который ссылается на библиотеку cuda ${KRONLIB}. Другой компонент, kronmult, ссылается на kronmult_cuda. В конце концов, то, что ссылается на kronmult, связано с основным приложением).

  find_package(CUDA 9.0 REQUIRED)
  include_directories(${CUDA_INCLUDE_DIRS})
  enable_language(CUDA)
  set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -arch sm_70 -g --ptxas-options=-O3")
  set_source_files_properties( src/kronmult_cuda.cpp PROPERTIES LANGUAGE CUDA ) # no .cu extension

...

target_include_directories(kronmult_cuda PRIVATE ${KRON_PATH})
target_link_libraries(kronmult_cuda PRIVATE OpenMP::OpenMP_CXX PUBLIC ${KRON_LIB})

if (ASGARD_USE_CUDA)
   set_target_properties(kronmult_cuda
                PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
endif()
if(APPLE AND ASGARD_USE_GPU)
   set_target_properties(kronmult_cuda
                PROPERTIES
                BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
endif ()       

target_link_libraries(kronmult PRIVATE kronmult_cuda)

...

Полный CMakeLists: https://github.com/bmcdanie/ASGarD/blob/feature/kronmult/CMakeLists.txt.

соответствующая часть CMakeLists для библиотеки cuda:

project(kronmult LANGUAGES CXX CUDA) 
set(KRONSRC 
    [list of all sources]
      )

    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -arch sm_70 -g --ptxas-options=-O3")
    set_source_files_properties( ${KRONSRC} PROPERTIES LANGUAGE CUDA )
    add_library(kron STATIC ${KRONSRC})

    target_compile_features(kron PUBLIC cxx_std_11)

    set_target_properties( kron
                               PROPERTIES CUDA_SEPARABLE_COMPILATION ON)

Полные списки CmakeLists: https://github.com/project-asgard/kronmult/blob/master/CMakeLists.txt.

Что я здесь отсутствует?

РЕДАКТИРОВАТЬ:

Вывод cuda-gdb при попытке вызвать ядро:

Thread 1 "asgard" hit Breakpoint 1, kronmult2_xbatched<double> (n=2, Aarray_=0x15551fa24800, lda=8, pX_=0x15551fa23c00, pY_=0x15551fa24400, pW_=0x15551fa24000, batchCount=128)
    at /home/3bm/asgard/contrib/kronmult/src/kronmult-ext/kronmult2_xbatched.hpp:36
36  {
(cuda-gdb) step
__wrapper__device_stub_kronmult2_xbatched<double> (__cuda_0=@0x7fffffff9e1c: 2, __cuda_1=0x15551fa24800, __cuda_2=@0x7fffffff9e18: 8, __cuda_3=0x15551fa23c00, 
    __cuda_4=0x15551fa24400, __cuda_5=0x15551fa24000, __cuda_6=@0x7fffffff9e30: 128) at /tmp/tmpxft_0000ac33_00000000-5_kronmult_cuda.cudafe1.stub.c:40
40  /tmp/tmpxft_0000ac33_00000000-5_kronmult_cuda.cudafe1.stub.c: No such file or directory.
(cuda-gdb) step
__device_stub__Z18kronmult2_xbatchedIdEviPKPKT_iPPS0_S6_S6_i (__par0=2, __par1=0x15551fa24800, __par2=8, __par3=0x15551fa23c00, __par4=0x15551fa24400, __par5=0x15551fa24000, 
    __par6=128) at /tmp/tmpxft_0000ac33_00000000-5_kronmult_cuda.cudafe1.stub.c:39
39  in /tmp/tmpxft_0000ac33_00000000-5_kronmult_cuda.cudafe1.stub.c
(cuda-gdb) step
dim3::dim3 (this=0x7fffffff9d28, vx=1, vy=1, vz=1)
    at /home/dg6/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.3.0/cuda-10.0.130-s6ervywpchxmerrju62il7xkeeamlfcv/include/vector_types.h:420
420     __host__ __device__ dim3(unsigned int vx = 1, unsigned int vy = 1, unsigned int vz = 1) : x(vx), y(vy), z(vz) {}
(cuda-gdb) step
dim3::dim3 (this=0x7fffffff9d34, vx=1, vy=1, vz=1)
    at /home/dg6/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.3.0/cuda-10.0.130-s6ervywpchxmerrju62il7xkeeamlfcv/include/vector_types.h:420
420     __host__ __device__ dim3(unsigned int vx = 1, unsigned int vy = 1, unsigned int vz = 1) : x(vx), y(vy), z(vz) {}
(cuda-gdb) step
cudaLaunchKernel<char> (
    func=0x5555555f94c0 <kronmult2_xbatched<double>(int, double const* const*, int, double**, double**, double**, int)> "UH\211\345H\203\354\060\211}\374H\211u\360\211U\370H\211M\350L\211E\340L\211M\330L\213E\330H\213}\340H\213M\350H\215U\370H\213u\360H\215E\374H\203\354\bL\215M\020AQM\211\301I\211\370H\211\307\350\355\343\377\377H\203\304\020\220\311\303UH\211\345H\203\354\060\211}\374H\211u\360\211U\370H\211M\350L\211E\340L\211M\330L\213E\330H\213}\340H\213M\350H\215U\370H\213u\360H\215E\374H\203\354\bL\215M\020AQM\211\301I\211\370H\211\307\350\267\345\377\377H\203\304\020\220\311\303UH\211\345H\203\354\060\211}\374H\211u\360\211U\370H\211M\350L\211E\340L\211", <incomplete sequence \330>..., gridDim=..., blockDim=..., 
    args=0x7fffffff9d40, sharedMem=0, stream=0x0)
    at /home/dg6/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.3.0/cuda-10.0.130-s6ervywpchxmerrju62il7xkeeamlfcv/bin/..//include/cuda_runtime.h:202
202     return ::cudaLaunchKernel((const void *)func, gridDim, blockDim, args, sharedMem, stream);
(cuda-gdb) step
warning: Cuda API error detected: cudaLaunchKernel returned (0x8)

1 Ответ

1 голос
/ 26 апреля 2020

После полезной подсказки от @talonmies я подозревал, что это проблема с подключением устройства. Я упростил процесс сборки, включил все файлы CUDA в один модуль перевода и выключил SEPARABLE COMPILATION.

Тем не менее, я не видел cmake_device_link.o ни в двоичном файле моего основного приложения, ни в компоненте, который вызывал в моя cuda библиотека И все равно была такая же ошибка. Попытка установить CUDA_RESOLVE_DEVICE_SYMBOLS безрезультатно.

Наконец, я попытался встроить компонент, который вызывает мою библиотеку cuda, как SHARED. Я видел шаг связывания устройства при сборке .so в моем выводе cmake, и программа работает нормально. Я не знаю, почему сборка SHARED исправляет, как я подозреваю, проблему с подключением устройства - примет любой ответ, который расшифровывает это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...