nvlink错误:“调试/*.cu.obj”(CUDA单独编译,Visual Studio 2013)中对*的未定义引用

时间:2019-01-26 01:01:55

标签: visual-studio visual-studio-2013 cuda nvlink

我有一个非常简单的字符串类,分别在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错误:在“ Debug / kernel.cu.obj”中未定义对“ _ZN7StringTC1EPKc”的引用

     

1> CUDALINK:nvlink错误:在“ Debug / kernel.cu.obj”中未定义对“ _ZN7StringT3GetEv”的引用

     

1> CUDALINK:nvlink错误:在“ Debug / kernel.cu.obj”中未定义对“ _ZN7StringTD1Ev”的引用

如您所见,所有方法都已定义。我还尝试按照this帖子中的说明更改运行时库。我应该补充一点,因为我打算使用动态并行性,所以启用了可重定位设备代码。同时,我确实查阅了this文档,并在“在CUDA中使用单独的编译”部分中找到了一些说明。但是,我将Visual Studio用于此项目,并且不确定如何准确地更改编译器设置。我尝试将各种东西添加到

  

C / C ++->命令行->其他选项

     

CUDA C / C ++->命令行->其他选项

     

链接器->命令行->其他选项

     

CUDA链接器->命令行->其他选项

但是仍然无法正常工作。有人有任何线索吗?

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

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;
}

我使用CUDA 8.0安装中的vs集成选项随附的模板创建了项目,将可重定位代码更改为true,并分别注册为sm_61,compute_61(我拥有GTX 1080 Ti)。

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

  

1> CUDALINK:nvlink错误:在“ Debug / kernel.cu.obj”中未定义对“ _ZN7StringTC1EPKc”的引用

     

1> CUDALINK:nvlink错误:在“ Debug / kernel.cu.obj”中未定义对“ _ZN7StringT3GetEv”的引用

     

1> CUDALINK:nvlink错误:在“ Debug / kernel.cu.obj”中未定义对“ _ZN7StringTD1Ev”的引用

另一方面,我确实通过扩展示例项目之一“ simpleSeparateCompilation”来编译和运行代码。但是,我看不到任何其他命令行选项。目前这对我有效,但是我当然还没有解决原始问题。

1 个答案:

答案 0 :(得分:0)

如果使用Visual Studio,则无法将.cpp重命名为.cu和/或将.h重命名为.cuh。

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

之外,还必须向“ C ++ File”和“ Header File”添加“ CUDA C / C ++ File”或“ CUDA C / C ++ Header”。
  1. 可重定位的设备代码(属性->配置属性-> CUDA C / C ++->通用->生成可重定位的设备代码)
  2. 设备链接(属性->配置属性-> CUDA链接器->通用->执行设备链接)