Ich habe eine Geräte Funktion, die in einer Header-Datei definiert ist. Der Grund, warum sie in einer Header-Datei steht, ist, dass sie von einem globalen Kernel verwendet wird, der in einer Header-Datei stehen muss, da es sich um einen Template-Kernel handelt.
Wenn diese Header-Datei in 2 oder mehr .cu-Dateien eingebunden wird, erhalte ich einen LNK2005-Fehler während des Linkens:
FooDevice.cu.obj : Fehler LNK2005: "int __cdecl getCurThreadIdx(void)" (?getCurThreadIdx@@YAHXZ) bereits definiert in Main.cu.obj
Warum wird dieser Fehler verursacht? Wie kann er behoben werden?
Hier ist ein Beispielcode, der den oben genannten Fehler erzeugt:
FooDevice.h:
#ifndef FOO_DEVICE_H
#define FOO_DEVICE_H
__device__ int getCurThreadIdx()
{
return ( ( blockIdx.x * blockDim.x ) + threadIdx.x );
}
template< typename T >
__global__ void fooKernel( const T* inArr, int num, T* outArr )
{
const int threadNum = ( gridDim.x * blockDim.x );
for ( int idx = getCurThreadIdx(); idx < num; idx += threadNum )
outArr[ idx ] = inArr[ idx ];
return;
}
__global__ void fooKernel2( const int* inArr, int num, int* outArr );
#endif // FOO_DEVICE_H
FooDevice.cu:
#include "FooDevice.h"
// Ein weiterer Kernel, der getCurThreadIdx() verwendet
__global__ void fooKernel2( const int* inArr, int num, int* outArr )
{
const int threadNum = ( gridDim.x * blockDim.x );
for ( int idx = getCurThreadIdx(); idx < num; idx += threadNum )
outArr[ idx ] = inArr[ idx ];
return;
}
Main.cu:
#include "FooDevice.h"
int main()
{
int num = 10;
int* dInArr = NULL;
int* dOutArr = NULL;
const int arrSize = num * sizeof( *dInArr );
cudaMalloc( &dInArr, arrSize );
cudaMalloc( &dOutArr, arrSize );
// Verwendung des Template-Kernels
fooKernel<<< 10, 10 >>>( dInArr, num, dOutArr );
return 0;
}