문제

I'm attempting to build a project with nvcc. I am getting the most vexing nvlink error: messages I've ever seen.

Here is the link statement:

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"

And I'm getting

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_'

I'm certain that these functions/files are included in the compile. You can see from the compile that KeplerianImpact.cpp and Geodesy.cpp are in there.

Is there any way to make the link output easier to read so I can debug this?

도움이 되었습니까?

해결책 3

I figured this out.

I needed to define my functions in the correct files. For example, in Foo.h:

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

and the function definition in Foo.cu not Foo.cpp as I originally thought.

 Foo::Foo() {}

For the constant variables, I needed to implement a slightly different strategy.

Here is an example of the C++ class that I started with:

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

Had to be converted to use the global namespace as the epsilon 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 }
    }
};

The ifdef above will return the correct version of the variable for either the host or the device code. Everywhere I had referenced Foo::epsilon I needed to replace with Foo::getEpsilon() so the correct epsilon was returned.

Hope this helps someone in the future. Thanks to @RobertCrovella for getting me thinking.

다른 팁

Use c++filt to demangle the names. For instance:

$ c++filt _ZN5JARSS15KeplerianImpactC1ERKdS2_S2_S2_S2_S2_ JARSS::KeplerianImpact::KeplerianImpact(double const&, double const&, double const&, double const&, double const&, double const&)

Faced this problem earlier, I guess you haven't linked the device object using device linker.

Generate relocatable code for the device by compiling as shown below (-dc is the device equivalent of -c, see the manual for more information)

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

Link the device parts of the code by calling nvlink or dlink before the final host link

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

Finally form a executable using host compiler,

g++ a.o b.o link.o –L<path> -lcudart
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top