[CMake] CUDA, CMAKE, and an attempt to build nbody

Brian Davis bitminer at gmail.com
Thu Jan 7 19:08:32 EST 2010


>
>
> What kind of errors were you getting?
>
>
I would point to a URL on GMane for the thread titled "Build only what you
need in third party libs" , but it looks as though Gmane does not have all
the postings.  I was getting bounces back from CMake mailing list due to
size of email.

Here is an excerpt from my local copy of the email:

I have the following line in one of my CMakeLists.txt files which I have
traced the issue down to.

add_subdirectory( ${THIRD_PARTY_SRC_DIR}/dcmtk-3.5.4 ./dcmtk-3.5.4  )

When I include this line the nbody app fails to build.  When I remove it the
NBody app compiles.

The link error created when dcmtk is included in the project is:

1>Linking...
1>bodysystemcuda.obj : error LNK2019: unresolved external symbol
allocateNBodyArrays referenced in function "protected: virtual void __cdecl
BodySystemCUDA::_initialize(
int)" (?_initialize at BodySystemCUDA@@MEAAXH at Z)
1>bodysystemcuda.obj : error LNK2019: unresolved external symbol
registerGLBufferObject referenced in function "protected: virtual void
__cdecl BodySystemCUDA::_initialize(int)" (?_initialize at BodySystemCUDA
@@MEAAXH at Z)
1>bodysystemcuda.obj : error LNK2019: unresolved external symbol
unregisterGLBufferObject referenced in function "protected: virtual void
__cdecl BodySystemCUDA::_finalize(void)" (?_finalize at BodySystemCUDA
@@MEAAXXZ)
1>bodysystemcuda.obj : error LNK2019: unresolved external symbol
deleteNBodyArrays referenced in function "protected: virtual void __cdecl
BodySystemCUDA::_finalize(void)" (?_finalize at BodySystemCUDA@@MEAAXXZ)
1>bodysystemcuda.obj : error LNK2019: unresolved external symbol
setDeviceSoftening referenced in function "public: virtual void __cdecl
BodySystemCUDA::setSoftening(float)" (?setSoftening at BodySystemCUDA@@UEAAXM at Z
)
1>bodysystemcuda.obj : error LNK2019: unresolved external symbol
integrateNbodySystem referenced in function "public: virtual void __cdecl
BodySystemCUDA::update(float)" (?update at BodySystemCUDA@@UEAAXM at Z)
1>bodysystemcuda.obj : error LNK2019: unresolved external symbol
copyArrayFromDevice referenced in function "public: virtual float * __cdecl
BodySystemCUDA::getArray(enum BodySystem::BodyArray)"
(?getArray at BodySystemCUDA@@UEAAPEAMW4BodyArray at BodySystem@@@Z)
1>bodysystemcuda.obj : error LNK2019: unresolved external symbol
copyArrayToDevice referenced in function "public: virtual void __cdecl
BodySystemCUDA::setArray(enum BodySystem::BodyArray,float const *)"
(?setArray at BodySystemCUDA@@UEAAXW4BodyArray at BodySystem@@PEBM at Z)
1>bodysystemcuda.obj : error LNK2019: unresolved external symbol threadSync
referenced in function "public: virtual void __cdecl
BodySystemCUDA::synchronizeThreads(void)const "
(?synchronizeThreads at BodySystemCUDA@@UEBAXXZ)
1>C:\projects\NIH2009\source\branches\brian\build\Windows-6.1\ouput\bin\Debug\nbody.exe
: fatal error LNK1120: 9 unresolved externals
1>Build log was saved at "file://c:\projects\NIH2009\source\branches\brian
\build\dvip4-Win64-broken\cpp_source\app\nbody\nbody.dir\Debug\BuildLog.htm"
1>nbody - 10 error(s), 0 warning(s)

Which is a linker error where extern "C" files cannot be found.  The
inclusion of a third party lib affects the project globally.  Now
conversations above imply that CMake was never designed for this type of use
case.  I have already had to change boost cmake build and will be submitting
my patch to that mailing list.  It appears as though now dcmtk does not play
nice either.  There are differences in the files... some I expect and others
I did not.

... it continues on and shows a diff of the project files that cmake
generates, which I will not post here for fear of the 40kb limit:


I notice a change from:

< set(source_file "C:/projects/NIH2009/source/
branches/brian/source/cpp/app/testing/cudaTests/nbody/src/bodysystemcuda.cu
")

To:

> set(source_file "C:/projects/NIH2009/source/branches/brian
/source/cpp/app/testing/cudaTests/nbody/src/nbody_kernel.cu")

involving bodysystemcuda.cu (bodysystemcuda.cpp declares ...
bodysystemcuda.cu defines) one of the very files which contain the
unresolved functions (allocateNBodyArrays and friends).

I then ask the question:

Can anyone point me on a path which would help me figure out what (global
project settings) in dcmtk could be causing these kinds of changes in my
unrelated nbody project?

Which I then end up answering my own question:

I removed (i.e. the force to use earlier version):


# check required version of CMake
CMAKE_MINIMUM_REQUIRED(VERSION 2.0)
#IF(CMAKE_BACKWARDS_COMPATIBILITY GREATER 2.0.6)
#  SET(CMAKE_BACKWARDS_COMPATIBILITY 2.0.6 CACHE STRING "Latest version of
CMake when this project was released." FORCE)
#ENDIF(CMAKE_BACKWARDS_COMPATIBILITY GREATER 2.0.6)



>
>>
> Again these are the the user supplied flags that will be applied to
> *everyone*.  They don't take into consideration flags that were added on a
> per configuration basis.  This is why I added the CUDA_VERBOSE_BUILD flag,
> since each target can have their own unique set of flags.
>
>
>>
Yes and I quickly learned not to touch them. I got burned.




>
>>
>>>
>>>> 2) There is a CUDA_TOOLKIT_INCLUDE, but no CUDA_SDK_INCLUDE (or _LIB)...
>>>> why? (this would prevent ${CUDA_SDK_ROOT_DIR}/common/inc - see below)
>>>>
>>>>
>>> As you found out the include directories for the CUDA SDK are not
>>> supported by FindCUDA.  Those libraries and headers are designed to be used
>>> by the SDK, and not particularly by external packages.  That doesn't prevent
>>> you from doing so, but it was decided that because the CUDA SDK won't
>>> maintain backward compatibility and is only designed for the SDK that
>>> external use would not be supported by FindCUDA.  As a compromise I chose to
>>> have as a bare minimum a path to the SDK be supported for those who wished
>>> to poke in the SDK to find things such as libraries or header files.  There
>>> is documentation in the help files and in the FindCUDA.cmake file as well as
>>> examples of what to do with the CUDA_SDK_ROOT_DIR variable.
>>>
>>>
>>
>> Yes it looks as though from 2.2 to 2.3 and 3.0_Beta_1 they (NVIDIA) added
>> a /C/ directory in the sdk and moved  bin, common, etc there.  If I could
>> only create a ClairVoyantFindCUDA to know of future changes such as these.
>>
>>
> Yes, it's hard to keep up with those guys, though there are some registry
> keys and environment variables that I believe will persist (which is what I
> try to make use of).
>

but if they would make a NVIDIASDK.cmake or CMakeLists.txt file in a known
location that would not change it might not be so bad.  One could only
hope.  Registry Key use sadens me.  The very concept (the registry) is an
attack on my sensibilities. I must now cleanse my thoughts with a couple of
pages of Linux kernel code and thoughts of apple pie :-)



>
> So I was also experiencing, just today, that I am unable to get FindCUDA
>> working with PATHS specified or HINTS (if I am using it correctly):
>>
>> find_package(<package> PATHS paths... NO_DEFAULT_PATH)
>>
>>
> First off, to be truthful, this is the first time I've become aware of
> these extra options to find_package.  I'm not sure what they would do at the
> moment, so setting CUDA_TOOLKIT_ROOT_DIR and CUDA_SDK_ROOT_DIR is the right
> way to do this for now.
>
>
Yes I tend to run into this kind of thing.  Usually with the desire to keep
my build system checkout and compile with little to no deps on host system.
When I feel the need to start moving things around into my build tree is
when I find out how brittle the software is.



> From FindCuda (with cmake now in my build tree so I can patch it):
>>
>>   # Search in the CUDA_BIN_PATH first.
>>   find_path(CUDA_TOOLKIT_ROOT_DIR
>>     NAMES nvcc nvcc.exe
>>     PATHS ENV CUDA_BIN_PATH
>>     DOC "Toolkit location."
>>     NO_DEFAULT_PATH
>>     )
>>   # Now search default paths
>>   find_path(CUDA_TOOLKIT_ROOT_DIR
>>     NAMES nvcc nvcc.exe
>>     PATHS /usr/local/bin
>>           /usr/local/cuda/bin
>>     DOC "Toolkit location."
>>     )
>>
>>
> I think the reason that the find_path(CUDA_TOOLKIT_ROOT_DIR doesn't work
> with the paths supplied by find_package is that your paths don't include the
> bin directory, and thus misses the executable.  I'll have to look into that
> more, but for now you should just specify the locations with
> CUDA_TOOLKIT_ROOT_DIR (as per the documentation in FindCUDA.cmake).
>
>
I gave this a try:

#    set( CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_DIR} CACHE STRING "" FORCE )
#    set( CUDA_SDK_ROOT_DIR ${NVIDIA_SDK_DIR} CACHE STRING "" FORCE )

    find_package( cuda PATHS ${CUDA_TOOLKIT_DIR} ${NVIDIA_SDK_DIR}

C:/projects/NIH2009/source/branches/trunk/source/cpp/lib/3rdParty/Win/CUDA_Toolkit_2.2/bin

C:/projects/NIH2009/source/branches/trunk/source/cpp/lib/3rdParty/Win/NVIDIA_GPU_Computing_SDK_2.2/bin
        NO_DEFAULT_PATH)

and it did not work.  I can get it to work by commenting out the set's
above.



>
>
>> Following the advice from
>> http://www.cmake.org/cmake/help/cmake-2-8-docs.html:
>>
>> The default search order is designed to be most-specific to least-specific
>> for common use cases. Projects may override the order by simply calling the
>> command multiple times and using the NO_* options:
>>
>>    find_package(<package> PATHS paths... NO_DEFAULT_PATH)
>>    find_package(<package>)
>>
>> This is urrr... umm... hokey (calling multiple times).  And I cannot seem
>> to get it to work.
>>
>
> I use this construct, because CMake will favor default paths before
> supplied paths, and I want to make sure that the stuff in my path is found
> first.
>
>

This is an general internal CMake construct which is not FindCUDA specific
yes/no?


-- 
Brian J. Davis
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20100107/8e37343a/attachment-0001.htm>


More information about the CMake mailing list