У меня есть очень простой строковый класс, объявленный и определенный в 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". Тем не менее, я не вижу никаких дополнительных параметров командной строки. Пока это работает для меня, но, конечно, я не решил исходную проблему.