[CMake] Passing -x=cu to FindCUDA, and specifying libraries to nvcc

James Bigler jamesbigler at gmail.com
Fri Jan 16 12:35:35 EST 2015


On Fri, Jan 16, 2015 at 10:15 AM, Irwin Zaid <irwin.zaid at physics.ox.ac.uk>
wrote:

> Hi James,
>
> Thanks for the quick reply. Some thoughts...
>
>  FindCUDA only looks for .cu files. In CUDA_WRAP_SRCS:
>>
>> get_source_file_property(_is_header ${file} HEADER_FILE_ONLY)
>> if(${file} MATCHES "\\.cu$" AND NOT _is_header)
>>
>> What benefit is there in keeping cuda code in .cpp files?
>>
>
> It allows us to write code that supports both a host library when there is
> no GPU and a CUDA library. We've gotten very good at this, and keep all our
> code in .cpp files.
>
> Would it be possible to add a flag or option that disables that checking?
> I'd even be happy with it as a global "everything is CUDA" flag. NVCC does
> support this with '-x=cu'.
>
>
I would feel better about a flag that changes the the match string.  If you
want to cook up a patch, I'll take a look at it (I don't have much time to
devote to this).

It should be something along the lines of.

1. Add a new CUDA variable called CUDA_FILE_MATCH_REGEX that defaults to
"\\.cu$".
2. Add documentation for it at the beginning along with the other things.
3. Replace the before mentioned if statement to use the new variable.

I think this will allow you get precisely what you want, but also allow for
somewhat arbitrary matches for anyone else who might have slightly
different needs.



>  You can't use nvcc to link. CMake makes this difficult, and in VS it is
>> impossible. Instead what I've done for device linking is to create an
>> intermediate object file that is the product of linking. FindCUDA
>> supports separable compilation for a single executable module, but not
>> for multiple ones. I had an example laying around for doing this, but
>> I'm not sure where it ended up. Basically you add a prelink custom
>> command that takes the objects and libraries that contain device code
>> for your target executable module and link them using nvcc producing
>> another object file that is then linked into the final executable module
>> using the host linker.
>>
>
> I follow you here. I do this as well in a different part. I agree it's
> hard, so things may be as good as they can be.
>
>  I'm not sure what is going wrong. If you do this:
>>
>> set(CUDA_NVCC_FLAGS -arch sm_20)
>> add_subdirectory(tests)
>>
>> then CUDA_NVCC_FLAGS should have "-arch;sm_20" defined in
>> tests/CMakeLists.txt.
>>
>
> Ah, I meant that the subproject itself can't modify CUDA_NVCC_FLAGS. The
> flags itself are passed from the superproject fine. I think this isn't
> really an issue though, the device linking is probably good enough.
>
> Irwin
>

You can set the value in the parent scope.

set(CUDA_NVCC_FLAGS -arch sm_20)
message("CUDA_NVCC_FLAGS = ${CUDA_NVCC_FLAGS}")
add_subdirectory(tests)
message("CUDA_NVCC_FLAGS = ${CUDA_NVCC_FLAGS}")

if in tests/CMakeLists.txt you do
set(CUDA_NVCC_FLAGS -arch sm_35 PARENT_SCOPE)

your output would be
CUDA_NVCC_FLAGS = -arch;sm_20
CUDA_NVCC_FLAGS = -arch;sm_35
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20150116/3a2f4a2b/attachment.html>


More information about the CMake mailing list