nvlink error : Undefined reference to * in 'Debug/*.cu.obj' (CUDA Separate Compilation, Visual Studio 2013)

nvlink error : Undefined reference to * in 'Debug/*.cu.obj' (CUDA Separate Compilation, Visual Studio 2013)

我有一个非常简单的字符串 class 分别在 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] = '[=11=]';
}

StringT::~StringT()
{
   free(str);
}

char* StringT::Get()
{
   return str;
}

我想简单调用 kernel.cu 中的 class。

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 error : Undefined reference to '_ZN7StringTC1EPKc' in 'Debug/kernel.cu.obj'

1>CUDALINK : nvlink error : Undefined reference to '_ZN7StringT3GetEv' in 'Debug/kernel.cu.obj'

1>CUDALINK : nvlink error : Undefined reference to '_ZN7StringTD1Ev' in 'Debug/kernel.cu.obj'

如您所见,所有方法都已定义。我还尝试按照 this post. I should add that I enabled relocatable device code as I am planning to use dynamic parallelism. Meanwhile, I did come across this 文档的指示更改运行时库,并在“在 CUDA 中使用单独编译”部分找到了一些说明。但是,我正在为该项目使用 visual studio,但不确定如何更改编译器设置。我尝试将各种东西添加到

C/C++ -> Command Line -> Additional Options

CUDA C/C++ -> Command Line -> Additional Options

Linker -> Command Line -> Additional Options

CUDA Linker -> Command Line -> Additional Options

但还是没有成功。有人知道吗?

已编辑 我重命名了包含字符串声明和定义的文件 class:

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] = '[=14=]';
}

__host__ __device__ StringT::~StringT()
{
   free(str);
}

__host__ __device__ char* StringT::Get()
{
   return str;
}

我使用 CUDA 8.0 安装的 vs 集成选项附带的模板创建了项目,将可重定位代码更改为 true 并将 arch 更改为 sm_61、compute_61(我有 GTX 1080 Ti) .

在我将输出详细程度更改为详细之后,错误消息是:

1>CUDALINK : nvlink error : Undefined reference to '_ZN7StringTC1EPKc' in 'Debug/kernel.cu.obj'

1>CUDALINK : nvlink error : Undefined reference to '_ZN7StringT3GetEv' in 'Debug/kernel.cu.obj'

1>CUDALINK : nvlink error : Undefined reference to '_ZN7StringTD1Ev' in 'Debug/kernel.cu.obj'

另一方面,我确实设法通过扩展其中一个示例项目“simpleSeparateCompilation”来编译和 运行 代码。但是,我看不到任何额外的命令行选项。这暂时对我有用,但当然我还没有解决原来的问题。

如果使用 visual studio,从 .cpp 重命名为 .cu and/or .h 重命名为 .cuh do/does 无效。

为了生成设备代码,除了启用

之外,还必须添加"CUDA C/C++ File"或"CUDA C/C++ Header"以反对"C++ File"和"Header File" ]
  1. 可重定位设备代码(属性 -> 配置属性 -> CUDA C/C++ -> 通用 -> 生成可重定位设备代码)
  2. 设备链接(属性 -> 配置属性 -> CUDA Linker -> 通用 -> 执行设备 Link)