2011-03-12 75 views
0

這可能與Linker errors 2005 and 1169 (multiply defined symbols) when using CUDA __device__ functions (should be inline by default)類似,但不完全相同。在VS2010中嘗試構建項目時(使用已顯示在別處工作的代碼),我收到了幾個LNK2005錯誤。我在我的智慧結束。CUDA和鏈接器錯誤

例如,我有以下三個文件:transposeGPU.h,transposeGPU.cutransposeCUDA.cutransposeGPU.h可概括如下:

void transposeGPU(float *d_dst, size_t dst_pitch, 
    float *d_src, size_t src_pitch, 
    unsigned int width, unsigned int height); 

即,沒有任何包括的單個聲明。該函數的定義中transposeGPU.cu被發現,其可以總結如下:

#include <stdio.h> 
#include "../transposeGPU.h" 
#include "../helper_funcs.h" 

#include "transposeCUDA.cu" 

void 
transposeGPU(float *d_dst, size_t dst_pitch, 
    float *d_src, size_t src_pitch, 
    unsigned int width, unsigned int height) 
{ 
    // execution configuration parameters 
    dim3 threads(16, 16); 
    dim3 grid(iDivUp(width, 16), iDivUp(height, 16)); 
    size_t shared_mem_size = 
     (threads.x * threads.y + (threads.y - 1)) * sizeof(float); 

    transposeCUDA<<<grid, threads, shared_mem_size>>>(
     d_dst, dst_pitch/sizeof(float), 
     d_src, src_pitch/sizeof(float), 
     width, height); 
} 

tranposeGPU.cu包括它的頭文件和transposeCUDA.cu,除了限定transposeGPU()並調用transposeCUDA(),後者在transposeCUDA.cu找到。現在,transposeCUDA.cu定義爲預期的功能:

#include "common_kernel.h" 

__global__ void 
transposeCUDA(
    float *g_dst, size_t s_dst_pitch, 
    const float *g_src, size_t s_src_pitch, 
    unsigned int img_width, unsigned int img_height) 
{ 
// several lines of code... 
} 

這一切看起來有序,但是我還是在transposeGPU.objerror LNK2005: "void __cdecl __device_stub__Z13transposeCUDAPfjPKfjjj(float *,unsigned int,float const *,unsigned int,unsigned int,unsigned int)" ([email protected]@[email protected]) already defined in transposeCUDA.obj

這和大約二十個其他類似的鏈接器錯誤。爲什麼?沒有明顯的重新定義發生。任何幫助將不勝感激。

回答

1

如果您正在編譯transposeCUDA.cu和transposeGPU.cu,則會出現重新定義,因爲定義同時出現在兩個翻譯單元中。您不應該#include transposeCUDA.cu並將nvcc應用於該文件。

+0

我不確定我是否理解。我應該爲'transposeCUDA.cu'編寫一個頭文件並將其包含在'transposeGPU.cu'中? 'transposeGPU.cu'至少需要一個'transposeCUDA()'的聲明才能工作。 – 2011-03-12 13:21:39

+0

最簡單的解決方案是在transposeGPU中只提供一個聲明 – 2011-03-12 13:30:35

0

澄清:__device__函數內聯(至少在費米前),但__global__不是 - 畢竟,您不能將GPU代碼內聯到您的CPU可執行函數中。全局函數可以使用它們的地址,唯一的區別是地址指向GPU內存(類似於存儲在GPU上的數據的普通指針看起來就像普通指針)。

正如William Pursell所說,如果你編譯你的全局函數兩次,你會得到兩個具有相同定義的函數,從而導致鏈接器錯誤。