2014-01-16 27 views
0

我在嘗試與nvcc建立一個項目。我收到了我見過的最令人煩惱的nvlink error:消息。無法破譯nvlink錯誤

這裏是鏈接聲明:

nvcc -rdc=true -arch=sm_21 -O3 -Xcompiler -fPIC -I"/usr/local/ACE_wrappers" -I"/usr/local/ACE_wrappers/TAO" -I"/usr/local/DDS" -I"/usr/include/Qt" -I"/usr/include/QtCore" -I"/usr/include/QtGui" -I"../../include" -I"../../include/DDS" -I"../../include/CoordinateTransforms" -I"../../include/DDS/IDLBrokerTemplates" -I"../../def/IDL" -I"../../def/CMD" -I"../../def/XSD" -I"../../src/NetAcquire" -I"/usr/local/ACE_wrappers/TAO/orbsvcs" -I"/usr/local/include/lct.7.5.4" -L"." -L"/usr/local/ACE_wrappers/lib" -L"/usr/local/DDS/lib" -L"/usr/lib64" -L"/usr/local/lib64" -L"../../def/IDL/lib" -L"../../def/XSD" -L"/usr/local/lib" .obj/../../src/Component.o .obj/../../src/COM.o .obj/../../src/DDS/EntityManager.o .obj/../../src/IDLBrokerTemplates/CommandManager.o .obj/../../src/IDLBrokerTemplates/OptionManager.o .obj/../../include/ApplicationProcessStateReporter_moc.o .obj/../../src/Application.o .obj/../../src/CoordinateTransforms/Site.o .obj/../../src/CoordinateTransforms/Geodesy.o .obj/../../src/CoordinateTransforms/Earth.o .obj/../../src/CoordinateTransforms/StateVector.o .obj/../../src/CoordinateTransforms/KeplerianImpact.o .obj/../../src/CoordinateTransforms/GeodeticPosition.o .obj/../../src/IDLBrokerTemplates/MeasurandSubscription.o .obj/../../src/NetAcquire/NetAcquire.o .obj/DataLossFlightTimeImpl.o .obj/DataLossFlightTime.o .obj/DftTable.o .obj/OptionListener.o .obj/PrimaryListener.o .obj/MissionTimeListener.o .obj/DeadMan.o .obj/main.o .obj/../../src/XML/spline.o .obj/../../src/XML/FpTable.o -l"naps-x86_64" -l"naio-x86_64" -l"nalct-x86_64" -l"curl" -l"TAO_Messaging" -l"TAO_Valuetype" -l"TAO_PI_Server" -l"TAO_PI" -l"TAO_CodecFactory" -l"TAO_CosNaming" -l"armadillo" -l"boost_filesystem" -l"boost_system" -l"xerces-c" -l"jarssXSD" -l"OpenDDS_Tcp" -l"JARSSRTv10" -l"QtNetwork" -l"fontconfig" -l"QtGui" -l"QtCore" -l"OpenDDS_Rtps_Udp" -l"OpenDDS_Rtps" -l"OpenDDS_Multicast" -l"OpenDDS_Udp" -l"OpenDDS_InfoRepoDiscovery" -l"OpenDDS_Dcps" -l"TAO_PortableServer" -l"TAO_AnyTypeCode" -l"TAO" -l"ACE" -o "DFT" 

而且我越來越

nvlink error : Undefined reference to '_ZN5JARSS15KeplerianImpactC1ERKdS2_S2_S2_S2_S2_' 
nvlink error : Undefined reference to '_ZNK5JARSS15KeplerianImpact9getStatusEv' 
nvlink error : Undefined reference to '_ZNK5JARSS15KeplerianImpact13getImpactTimeEv' 
nvlink error : Undefined reference to '_ZNK5JARSS15KeplerianImpact11getPlhStateEv' 
nvlink error : Undefined reference to '_ZN5JARSS15KeplerianImpactD1Ev' 
nvlink error : Undefined reference to '_ZN5JARSS7Geodesy12EFG2GeodeticERKdS2_S2_PdS3_S3_' 

我敢肯定,這些功能/文件包含在編譯。你可以從編譯中看到KeplerianImpact.cppGeodesy.cpp在那裏。

有什麼辦法讓鏈接輸出更容易閱讀,所以我可以調試嗎?

+1

如果你有設備代碼,nvlink需要在.cpp文件中,這是一個問題。我只能在編譯命令中看到'KeplerianImpact.o'和'Geodesy.o',所以我不知道,只是將它基於你的語句。 –

+0

我有'__constant__'值,需要在大地測量所需的cpp代碼中。儘管所有的大地測量代碼都被編譯爲'__host__ __device__'。常量的位置有所不同嗎? –

+0

是的。默認情況下,nvcc會忽略.cpp文件中的任何代碼,並將整個文件交給主編譯器。但是,我不確定你的情況是怎麼回事,因爲主編譯器應該在'__constant__'結構中阻塞。 (它也應該扼殺'__host__ __device__')。不過,如果這是針對該設備的,並且位於.cpp文件中,則可能會導致鏈接問題。 –

回答

1

我想通了。

我需要在正確的文件中定義我的功能。例如,在Foo.h

class Foo { 
public: 
    __host__ __device__ 
    Foo(); 
} 

Foo.cuFoo.cpp因爲我本來以爲函數定義。

Foo::Foo() {} 

對於常量變量,我需要實現一個稍微不同的策略。

這裏是我開始使用C++類的一個例子:

class Foo { 
public: 
    static double const epsilon; 
    static void functionThatUsesEpsilon(); 
    /**/ 
} 

不得不被轉換爲使用全局命名空間作爲的εdef'n

namespace foo { 
    extern __constant__ double epsilon; 
} 

class Foo { 
public: 
    // same stuff as before with the addition of this function 
    __host__ __device__ 
    static inline double getEpsilon() { 
#ifdef __CUDACC__ 
     return foo::epsilon; 
#else 
     return epsilon; 
#endif 
    } 

    static void functionThatUsesEpsilon() { 
     if (bar < getEpsilon()) { // etc } 
    } 
}; 

ifdef的上面會爲主機或設備代碼返回正確版本的變量。我在任何地方引用了Foo::epsilon我需要用Foo::getEpsilon()來替換,以便返回正確的epsilon。

希望這可以幫助未來的人。感謝@RobertCrovella讓我思考。

5

使用c++filt來取消名稱的縮小。例如:

$ C++ filt的_ZN5JARSS15KeplerianImpactC1ERKdS2_S2_S2_S2_S2_ JARSS :: KeplerianImpact :: KeplerianImpact(雙常量&,雙常量&,雙常量&,雙常量&,雙常量&,雙常量&)

+0

這是一個很棒的竅門,我不知道你可以這樣做。 –

2

更早面對這個問題,我想你還沒有使用設備鏈接器鏈接設備對象。

通過編譯,如下所示生成用於所述設備重定位代碼(-dc是-c裝置等效,請參閱manual獲得更多信息)通過調用nvlink

nvcc –arch=sm_21 –dc a.cu b.cu 

鏈路代碼的裝置部分或最終主機鏈路

nvlink -arch=sm_21 a.o b.o -o link.o (or) 
nvcc –arch=sm_21 –dlink a.o b.o –o link.o 

最後使用主機編譯器形成可執行文件之前的dlink,

g++ a.o b.o link.o –L<path> -lcudart