Я использовал CMake 3.13 для создания решения Visual Studio (VS 2017) с одним проектом «cudatest».Проект содержит два файла:
main.cpp
kernel.cu
Чтобы включить поддержку CUDA, я использовал скрипт, предоставленный Nvidia, то есть FindCUDA.cmake
, в отличие от использования последней поддержки CMake для приложений на основе CUDA (яне пользуюсь этой последней поддержкой, потому что она не позволяет мне делать определенные вещи, поэтому мне нужно прибегнуть к FindCUDA).
CMake успешно генерирует проект, который содержит два вышеупомянутых файла.Не вдаваясь в подробности, файл main.cpp
содержит объявление функции:
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);
Вы можете распознать его как функцию, которая создается по умолчанию при создании нового проекта в Visual Studio с использованием типа среды выполнения CUDA.проекта (интеграция NVIDIA CUDA для Visual Studio).
Принимая во внимание, что файл kernel.cu
содержит определение указанной функции:
__global__ void addKernel(int *c, const int *a, const int *b)
{
int i = threadIdx.x;
c[i] = a[i] + b[i];
}
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size)
{
int *dev_a = 0;
int *dev_b = 0;
int *dev_c = 0;
...
addKernel<<<1, size>>>(dev_c, dev_a, dev_b);
...
}
Оба файла успешно скомпилированы, и компоновщик выдает ошибку:
Error LNK2019 unresolved external symbol "enum cudaError __cdecl addWithCuda(int *,int const *,int const *,unsigned int)" ...
Следует отметить, что файл * .obj для kernel.cu успешно создан NVCC.
Однако файлы * .obj помещаются в разные каталоги, что заставляет меня думать, что это может быть проблемой, а также обнаруживает, что я не понимаю, где компоновщик Visual Studio ищет файлы * .obj вдля разрешения символов. Файл
main.obj
заканчивается в build\cudatest.dir\Debug
, где build
- папка, содержащая созданное решение. Файл
cudatest_generated_kernel.cu.obj
заканчивается в build\CMakeFiles\cudatest.dir\Debug
Конфигурация путей к выходным файлам настраивается скриптом FindCUDA.cmake
.
Я пытался поместить cudatest_generated_kernel.cu.obj
в ту же папку, что и main.obj
, но ничего не сделал.
Установка свойства компоновщика 'Show Progress' на /VERBOSE
показала, что компоновщик даже не ищет cudatest_generated_kernel.cu.obj
, чтобы попытаться найти соответствующие символы.
=====================
Вопрос:
Учитывая, что я собираю ядро CUDA в файл * .obj, используя NVCC, ифайл * .cpp в свой собственный файл * .obj, используя CL.exe, как я могу сказать компоновщику проверить ядро cuda * .obj file?
Пожалуйста, дайте мне знать, если мне нужно расширить вопрос, чтобы сделать его более понятным, то есть указать параметры компилятора NVCC, которые я использовал, предоставить полный список кода и т. д. Любые подсказки и указатели в правильном направлении будутс благодарностью!
РЕДАКТИРОВАТЬ: По предложению @talonmies для каждого пользователя (__cdecl addWithCuda
может указывать, что компоновщик ищет связь C), я явно пометил функцию addWithCuda
с extern "C"
в main.cpp
и kernel.cu
:
extern "C" cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size)
Теперь ошибка выглядит следующим образом:
Error LNK2019 unresolved external symbol addWithCuda referenced in function main cudatest D:\projects\vs2017\TestCUDA_CMake\build\main.obj