2014-01-16 2 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

Geodesy가 필요로하는 cpp 코드에 필요한 '__constant__' 값이 있습니다. 모든 측지 코드는'__host__ __device__' 컴파일됩니다. 상수의 위치가 차이를 만드나요? –

+0

예. 기본적으로 nvcc는 .cpp 파일의 모든 코드를 무시하고 전체 파일을 호스트 컴파일러로 전달합니다. 그러나, 호스트 컴파일러가'__constant__' 구조체에 숨 막히지 않아야했기 때문에 어떤 일이 벌어지고 있는지 잘 모르겠습니다. ('__host__ __device__'를 질식시켜야합니다). 그럼에도 불구하고 장치를위한 것이고 .cpp 파일에있는 경우 링크 문제가 발생할 수 있습니다. –

답변

1

나는 이것을 알아 냈다.

내 기능을 올바른 파일에 정의해야했습니다.

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

내가 원래 생각했던 Foo.cu하지Foo.cpp에서 함수 정의 : Foo.h에서 예를 들어.

Foo::Foo() {} 

상수 변수의 경우 약간 다른 전략을 구현해야했습니다.

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을 글로벌 네임 스페이스를 사용하도록 변환 할 수 있었다 : 여기

내가 시작했던 C++ 클래스의 예입니다 호스트 또는 장치 코드에 대한 올바른 버전의 변수를 반환하십시오. 어디에서나 참조한 Foo::epsilon Foo::getEpsilon()으로 바꿔야하므로 올바른 엡실론이 반환되었습니다.

앞으로 도움이되기를 바랍니다. 나를 생각하게 해주신 @RobertCrovella에게 감사드립니다.

5

c++filt을 사용하여 이름을 디 앵글링하십시오.

$ C++ filt을 _ZN5JARSS15KeplerianImpactC1ERKdS2_S2_S2_S2_S2_ JARSS :: KeplerianImpact :: KeplerianImpact (더블 const를 & 두 번 const를 & 두 번 const를 & 두 번 const를 & 두 번 const를 & 두 번 const를 &)

: 예를 들어
+0

위대한 트릭입니다. 그럴 수 있다는 것을 몰랐습니다. –

2

앞서이 문제에 직면했기 때문에 장치 링커를 사용하여 장치 개체를 연결하지 않았을 것입니다.

아래와 같이 컴파일 장치의 재배치 코드 생성 nvlink를 호출

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

링크 코드의 기기 부품 (-dc은 -c의 장치 동등한 자세한 내용 manual 표시이다) 또는, 최종 호스트 링크 마지막

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 
관련 문제