Ошибка nvlink: неопределенная ссылка на * в 'Debug/*.cu.obj' (Отдельная компиляция CUDA, Visual Studio 2013)
У меня есть очень простой строковый класс, объявленный и определенный в StringT.cu и StringT.cpp соответственно.
StringT.cu
#ifndef STRING_T_CU
#define STRING_T_CU
#include "cuda_runtime.h"
class StringT
{
public:
static const int MAX_LEN = 15;
__host__ __device__ StringT(char const * s);
__host__ __device__ ~StringT();
__host__ __device__ char* Get();
private:
char* str;
};
#endif
StringT.cpp
#include "StringT.cu"
#include <stdlib.h>
#include <malloc.h>
StringT::StringT(char const * s)
{
str = (char*)malloc(MAX_LEN + 1);
int k;
for (k = 0; *s != NULL; ++s, ++k) {
if (k > MAX_LEN) {
break;
}
str[k] = *s;
}
str[k] = '\0';
}
StringT::~StringT()
{
free(str);
}
char* StringT::Get()
{
return str;
}
Я хочу сделать простой вызов класса в kernel.cu.
kernel.cu
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include "StringT.cu"
#include "CudaUtil.h"
__global__ void kernel()
{
StringT s("aa");
printf("%s", s.Get());
}
int main()
{
kernel <<< 1, 1 >>> ();
checkCudaErrors(cudaDeviceSynchronize());
checkCudaErrors(cudaGetLastError());
return 0;
}
Однако этот код не компилируется, выдавая такие ошибки, как:
1> CUDALINK: ошибка nvlink: неопределенная ссылка на '_ZN7StringTC1EPKc' в 'Debug/kernel.cu.obj'
1> CUDALINK: ошибка nvlink: неопределенная ссылка на '_ZN7StringT3GetEv' в 'Debug/kernel.cu.obj'
1> CUDALINK: ошибка nvlink: неопределенная ссылка на '_ZN7StringTD1Ev' в 'Debug/kernel.cu.obj'
Как видите, все методы определены. Я также попытался изменить библиотеку времени выполнения, как указано в этом сообщении. Я должен добавить, что я включил перемещаемый код устройства, так как я планирую использовать динамический параллелизм. Тем временем я наткнулся на этот документ и нашел некоторые инструкции в разделе "Использование отдельной компиляции в CUDA". Тем не менее, я использую Visual Studio для этого проекта и не уверен, как именно изменить настройки компилятора. Я пытался добавить все виды вещей в
C/C++ -> Командная строка -> Дополнительные параметры
CUDA C/C++ -> Командная строка -> Дополнительные параметры
Компоновщик -> Командная строка -> Дополнительные параметры
CUDA Linker -> Командная строка -> Дополнительные параметры
Но все еще не заставил это работать. У кого-нибудь есть подсказка?
Отредактировано Я переименовал файлы, содержащие объявление и определение класса строки:
StringT.cuh
#ifndef STRING_T_CUH
#define STRING_T_CUH
#include "cuda_runtime.h"
class StringT
{
public:
static const int MAX_LEN = 15;
__host__ __device__ StringT(char const * s);
__host__ __device__ ~StringT();
__host__ __device__ char* Get();
private:
char* str;
};
#endif
StringT.cu
#include "StringT.cuh"
#include <stdlib.h>
#include <malloc.h>
__host__ __device__ StringT::StringT(char const * s)
{
str = (char*)malloc(MAX_LEN + 1);
int k;
for (k = 0; *s != NULL; ++s, ++k) {
if (k > MAX_LEN) {
break;
}
str[k] = *s;
}
str[k] = '\0';
}
__host__ __device__ StringT::~StringT()
{
free(str);
}
__host__ __device__ char* StringT::Get()
{
return str;
}
Я создал проект с шаблоном, который поставляется с опцией интеграции vs из установки CUDA 8.0, изменил перемещаемый код на true и arch на sm_61, compute_61 (у меня GTX 1080 Ti).
Сообщения об ошибках, после того как я изменил детализацию вывода на подробные, были:
1> CUDALINK: ошибка nvlink: неопределенная ссылка на '_ZN7StringTC1EPKc' в 'Debug/kernel.cu.obj'
1> CUDALINK: ошибка nvlink: неопределенная ссылка на '_ZN7StringT3GetEv' в 'Debug/kernel.cu.obj'
1> CUDALINK: ошибка nvlink: неопределенная ссылка на '_ZN7StringTD1Ev' в 'Debug/kernel.cu.obj'
С другой стороны, мне удалось скомпилировать и запустить код, расширив один из примеров проектов, "simpleSeparateCompilation". Тем не менее, я не вижу никаких дополнительных параметров командной строки. Это работает для меня на данный момент, но, конечно, я не решил исходную проблему.
1 ответ
При использовании visual studio переименование из.cpp в.cu и / или.h в.cuh не работает / не работает.
Чтобы сгенерировать код устройства, необходимо добавить "Файл CUDA C/C++" или "Заголовок CUDA C/C++" вместо "Файл C++" и "Файл заголовка", в дополнение к включению
- код перемещаемого устройства (Свойства -> Свойства конфигурации -> CUDA C/C++ -> Общий -> Создать код перемещаемого устройства)
- привязка устройства (Свойства -> Свойства конфигурации -> CUDA Linker -> Общие -> Выполнить привязку устройства)