CUDA: Add support for disabling CUDA_ARCHITECTURES

The ability to disable adding architectures completely for packaging purposes
and cases requiring passing the architectures flags explicitly has been
requested.
Support a false value for CUDA_ARCHITECTURES and CMAKE_CUDA_ARCHITECTURES
for this purpose.

Implements #20821.
This commit is contained in:
Raul Tambre
2020-06-12 19:59:32 +03:00
committed by Brad King
parent 594fda9c23
commit 877a92e968
7 changed files with 81 additions and 25 deletions

View File

@@ -23,9 +23,34 @@ The ``NEW`` behavior of this policy is to initialize
:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``
and raise an error if :prop_tgt:`CUDA_ARCHITECTURES` is empty during generation.
If :prop_tgt:`CUDA_ARCHITECTURES` is set to a false value no architectures
flags are passed to the compiler. This is intended to support packagers and
the rare cases where full control over the passed flags is required.
This policy was introduced in CMake version 3.18. CMake version
|release| warns when the policy is not set and uses ``OLD`` behavior.
Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
explicitly.
.. include:: DEPRECATED.txt
Examples
^^^^^^^^
.. code-block:: cmake
set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 35 50 72)
Generates code for real and virtual architectures ``30``, ``50`` and ``72``.
.. code-block:: cmake
set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 70-real 72-virtual)
Generates code for real architecture ``70`` and virtual architecture ``72``.
.. code-block:: cmake
set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES OFF)
CMake will not pass any architecture flags to the compiler.

View File

@@ -8,6 +8,10 @@ the kind of architecture to generate code for.
If no suffix is given then code is generated for both real and virtual
architectures.
A non-empty false value (e.g. ``OFF``) disables adding architectures.
This is intended to support packagers and rare cases where full control
over the passed flags is required.
This property is initialized by the value of the :variable:`CMAKE_CUDA_ARCHITECTURES`
variable if it is set when a target is created.
@@ -28,3 +32,9 @@ Generates code for real and virtual architectures ``30``, ``50`` and ``72``.
set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 70-real 72-virtual)
Generates code for real architecture ``70`` and virtual architecture ``72``.
.. code-block:: cmake
set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES OFF)
CMake will not pass any architecture flags to the compiler.

View File

@@ -352,7 +352,7 @@ endif()
# If the user didn't set the architectures, then set them to a default.
# If the user did, then make sure those architectures worked.
if(DEFINED detected_architecture)
if(DEFINED detected_architecture AND "${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "")
set(CMAKE_CUDA_ARCHITECTURES "${detected_architecture}" CACHE STRING "CUDA architectures")
if(NOT CMAKE_CUDA_ARCHITECTURES)

View File

@@ -3044,6 +3044,34 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
{
const std::string& property = this->GetSafeProperty("CUDA_ARCHITECTURES");
if (property.empty()) {
switch (this->GetPolicyStatusCMP0104()) {
case cmPolicies::WARN:
if (!this->LocalGenerator->GetCMakeInstance()->GetIsInTryCompile()) {
this->Makefile->IssueMessage(
MessageType::AUTHOR_WARNING,
cmPolicies::GetPolicyWarning(cmPolicies::CMP0104) +
"\nCUDA_ARCHITECTURES is empty for target \"" + this->GetName() +
"\".");
}
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
default:
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"CUDA_ARCHITECTURES is empty for target \"" + this->GetName() +
"\".");
}
}
// If CUDA_ARCHITECTURES is false we don't add any architectures.
if (cmIsOff(property)) {
return;
}
struct CudaArchitecture
{
std::string name;
@@ -3054,28 +3082,7 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
{
std::vector<std::string> options;
cmExpandList(this->GetSafeProperty("CUDA_ARCHITECTURES"), options);
if (options.empty()) {
switch (this->GetPolicyStatusCMP0104()) {
case cmPolicies::WARN:
if (!this->LocalGenerator->GetCMakeInstance()->GetIsInTryCompile()) {
this->Makefile->IssueMessage(
MessageType::AUTHOR_WARNING,
cmPolicies::GetPolicyWarning(cmPolicies::CMP0104) +
"\nCUDA_ARCHITECTURES is empty for target \"" +
this->GetName() + "\".");
}
CM_FALLTHROUGH;
case cmPolicies::OLD:
break;
default:
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"CUDA_ARCHITECTURES is empty for target \"" + this->GetName() +
"\".");
}
}
cmExpandList(property, options);
for (std::string& option : options) {
CudaArchitecture architecture;

View File

@@ -1,5 +1,15 @@
cmake_minimum_required(VERSION 3.17)
cmake_minimum_required(VERSION 3.18)
project(Architecture CUDA)
set(CMAKE_CUDA_ARCHITECTURES 52)
add_executable(Architecture main.cu)
set_property(TARGET Architecture PROPERTY CUDA_ARCHITECTURES 52)
# Make sure CMake doesn't pass architectures if CUDA_ARCHITECTURES is OFF.
if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -arch=sm_52")
elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --cuda-gpu-arch=sm_52")
endif()
add_executable(ArchitectureOff main.cu)
set_property(TARGET ArchitectureOff PROPERTY CUDA_ARCHITECTURES OFF)

View File

@@ -0,0 +1,3 @@
include(CMP0104-Common.cmake)
set_property(TARGET cuda PROPERTY CUDA_ARCHITECTURES OFF)

View File

@@ -2,4 +2,5 @@ include(RunCMake)
run_cmake(CMP0104-OLD)
run_cmake(CMP0104-NEW)
run_cmake(CMP0104-OFF)
run_cmake(CMP0104-WARN)