简体   繁体   English

在CUDA标头(.cuh)文件中使用常量内存时出现LNK2005错误

[英]LNK2005 Error when using Constant Memory in CUDA Header (.cuh) File

I have a CUDA Header (.cuh) file that contains two constant float arrays. 我有一个CUDA标头(.cuh)文件,其中包含两个常量浮点数组。 There are two files that include this header, one is a CPP file that tries to copy to this constant memory and one is a CUDA file that tries to use this constant memory. 包含此头的文件有两个,一个是试图复制到此常量内存的CPP文件,另一个是试图使用此常量内存的CUDA文件。 All three files are in a project that should compile to make a DLL. 所有这三个文件都在一个应编译为DLL的项目中。

I've tried to simplify things with the following code: 我尝试使用以下代码简化操作:

obj1.cuh obj1.cuh

#pragma once

__constant__ float d_array1[5];
__constant__ float d_array2[5];

obj1.cu obj1.cu

#include "obj1.cuh"

//do random stuff
__global__ void kernel(float * d_array1, float * d_array2) {
  int id = threadIdx.x;
  float sum = d_array1[i] + d_array2[i];
}

ext.cpp ext.cpp

#include "obj1.cuh"

void function(float * array1, float * array2) {
  cudaMemcpyToSymbol(d_array1, array1, sizeof(float)*5);
  cudaMemcpyToSymbol(d_array2, array2, sizeof(float)*5);

  kernel<<<1,5>>>(d_array1,d_array2);
}

The build fails and outputs the following errors: 生成失败,并输出以下错误:

1>ext.obj : error LNK2005: "float * d_array1" (?d_array1@@3PAMA) already defined in obj1.cu.obj
1>ext.obj : error LNK2005: "float * d_array2" (?d_array2@@3PAMA) already defined in obj1.cu.obj

Before you ask, yes I have tried using include guards instead of the pragma once and it still outputs the same error. 在您问之前,是的,我曾经尝试使用include防护而不是pragma,它仍然会输出相同的错误。

Include guard version of obj1.cuh 包括obj1.cuh的防护版本

#ifndef CONSTANTARRAYS
#define CONSTANTARRAYS
__constant__ float d_array1[5];
__constant__ float d_array2[5];
#endif

The problem is exactly what the linker tells you: The variables are defined in multiple translation units . 问题恰恰是链接程序告诉您的:变量是在多个翻译单元定义的

When the preprocessor includes a header files, it quite literally pastes the text in the header into the place where the #include directive was, which means both generated objects files will have the definitions of the variables. 当预处理器包含头文件时,它实际上将头文件中的文本粘贴到#include指令所在的位置,这意味着两个生成的对象文件都将具有变量的定义。

What you should do is to only declare the variables in the header file, then in a single source file you define them. 您应该做的只是在头文件中声明变量,然后在单个源文件中定义它们。 To change the definition to a declaration, the simplest way is to prepend the extern keyword: 要将定义更改为声明,最简单的方法是在extern关键字前添加:

#pragma once

extern __constant__ float d_array1[5];
extern __constant__ float d_array2[5];

Then in a single source file you have the old definitions: 然后,在单个源文件中,您具有旧的定义:

__constant__ float d_array1[5];
__constant__ float d_array2[5];

The #pragma once or header include guards prevents a header file to be included multiple times in the same translation unit. #pragma once或标头包含防护可防止将标头文件多次包含在同一翻译单元中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM