6
votes

My project uses CMake-GUI with visual studio. There is no gpu card installed on my system. The visual studio solution generated sets the nvcc flags to compute_30 and sm_30 but I need to set it to compute_50 and sm_50.

I use CMake 3.10.1 and Visual studio 14 2015 with 64 bit compilation.

I wish to supersede the default setting from CMake. I am not using the Find CUDA method to search and add CUDA. I am adding CUDA as a language support in CMAKE and VS enables the CUDA Build customization based on that.

4
It didnt work out for me. It is not gettting set.C0D3R
I am not using the Find CUDA method to search and add CUDA. I am adding CUDA as a language support in CMAKE and VS enables the CUDA Build customization based on that.C0D3R
Your question is not really abouy CMake; the CUDA architecture is just a compiler flag. Once you have it, setting it is not much of an issue.einpoklum

4 Answers

8
votes

The correct way is:

target_compile_options(myTarget PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:-gencode arch=compute_50,code=sm_50>)

Select PRIVATE/PUBLIC as needed. This is the correct way to set per target flags.

5
votes

So I was able to figure it out myself. The following way we can set it -

string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_50,code=sm_50")
5
votes

With CMake 3.18 there is the new target property CUDA_ARCHITECTURES. From the documentation here:

set_property(TARGET myTarget PROPERTY CUDA_ARCHITECTURES 35 50 72)

Generates code for real and virtual architectures 30, 50 and 72.

set_property(TARGET myTarget PROPERTY CUDA_ARCHITECTURES 70-real 72-virtual)

Generates code for real architecture 70 and virtual architecture 72.

0
votes

I've written a module which defaults to obtaining (and using) the computer capability settings for the first installed phyiscal device, but which can be overriden by setting the CUDA_SM environment variable. Here's the module (put the contents in a .cmake file and place that in an included folder):

# This module determines which compute capability / SM version
# we should be compiling our CUDA code for, and adds the appropriate
# switch to the NVCC compiler flags - so that you don't have to worry
# about it.
#
# TODO: Be willing to take CUDA_CC, CUDA_TARGET_COMPUTE_CAPABILITY, 
# CUDA_TARGET_COMPUTE or CUDA_TARGET_COMPUTE_CAP and maybe even 
# those without the CUDA_ prefix

if (NOT CUDA_TARGET_COMPUTE_CAPABILITY)
        if("$ENV{CUDA_SM}" STREQUAL "")
                set(ENV{CUDA_INCLUDE_DIRS} "${CUDA_INCLUDE_DIRS}")
                set(ENV{CUDA_CUDART_LIBRARY} "${CUDA_CUDART_LIBRARY}")
                set(ENV{CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER}")
                execute_process(COMMAND bash -c "${CMAKE_CURRENT_SOURCE_DIR}/scripts/get_cuda_sm.sh"  OUTPUT_VARIABLE CUDA_TARGET_COMPUTE_CAPABILITY_) 
        else()
                set(CUDA_TARGET_COMPUTE_CAPABILITY_ $ENV{CUDA_SM})
        endif()

        set(CUDA_TARGET_COMPUTE_CAPABILITY "${CUDA_TARGET_COMPUTE_CAPABILITY_}" CACHE STRING "CUDA compute capability of the (first) CUDA device on the system, in XY format (like the X.Y format but no dot); see table of features and capabilities by capability X.Y value at https://en.wikipedia.org/wiki/CUDA#Version_features_and_specifications")

        execute_process(COMMAND bash -c "echo -n $(echo ${CUDA_TARGET_COMPUTE_CAPABILITY})" OUTPUT_VARIABLE CUDA_TARGET_COMPUTE_CAPABILITY) 
        execute_process(COMMAND bash -c "echo ${CUDA_TARGET_COMPUTE_CAPABILITY} | sed 's/^\\([0-9]\\)\\([0-9]\\)/\\1.\\2/;' | xargs echo -n" OUTPUT_VARIABLE FORMATTED_COMPUTE_CAPABILITY) 

        message(STATUS "CUDA device-side code will assume compute capability ${FORMATTED_COMPUTE_CAPABILITY}")
endif()

set(CUDA_GENCODE "arch=compute_${CUDA_TARGET_COMPUTE_CAPABILITY},code=compu