diff options
author | Robert Maynard <robert.maynard@kitware.com> | 2019-05-09 13:13:39 (GMT) |
---|---|---|
committer | Robert Maynard <robert.maynard@kitware.com> | 2019-05-21 15:40:07 (GMT) |
commit | 81b4d10d8f421242f9989ff0c2d37a12be66f405 (patch) | |
tree | 74ee6499eb43e48f18dd41ff0b0b1bdd809768cc /Source/cmLinkLineDeviceComputer.cxx | |
parent | 3205c7c950d5b90d47ce1c5c58073e511339b78c (diff) | |
download | CMake-81b4d10d8f421242f9989ff0c2d37a12be66f405.zip CMake-81b4d10d8f421242f9989ff0c2d37a12be66f405.tar.gz CMake-81b4d10d8f421242f9989ff0c2d37a12be66f405.tar.bz2 |
CUDA: More exhaustive checks to determine when to do device linking
Previously CMake used fairly naive logic to determine when to do
device linking which caused unnecessary device linking to occur
frequently. We now use a more exhaustive algorithm to determine
when we have a need for device linking.
Fixes: #19238
Diffstat (limited to 'Source/cmLinkLineDeviceComputer.cxx')
-rw-r--r-- | Source/cmLinkLineDeviceComputer.cxx | 97 |
1 files changed, 86 insertions, 11 deletions
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 72edba3..6cfe5bb 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -3,14 +3,20 @@ #include "cmLinkLineDeviceComputer.h" +#include <algorithm> #include <set> #include <sstream> #include <utility> +#include <vector> #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmGeneratorTarget.h" +#include "cmLocalGenerator.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" #include "cmStateTypes.h" +#include "cmSystemTools.h" class cmOutputConverter; @@ -40,6 +46,27 @@ static bool cmLinkItemValidForDevice(std::string const& item) cmHasLiteralPrefix(item, "--library")); } +bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking( + cmComputeLinkInformation& cli) +{ + // Determine if this item might requires device linking. + // For this we only consider targets + typedef cmComputeLinkInformation::ItemVector ItemVector; + ItemVector const& items = cli.GetItems(); + std::string config = cli.GetConfig(); + for (auto const& item : items) { + if (item.Target && + item.Target->GetType() == cmStateEnums::STATIC_LIBRARY) { + if ((!item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS")) && + item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) { + // this dependency requires us to device link it + return true; + } + } + } + return false; +} + std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( cmComputeLinkInformation& cli, std::string const& stdLibString) { @@ -62,17 +89,12 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( } if (item.Target) { - bool skip = false; - switch (item.Target->GetType()) { - case cmStateEnums::MODULE_LIBRARY: - case cmStateEnums::INTERFACE_LIBRARY: - skip = true; - break; - case cmStateEnums::STATIC_LIBRARY: - skip = item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS"); - break; - default: - break; + bool skip = true; + if (item.Target->GetType() == cmStateEnums::STATIC_LIBRARY) { + if ((!item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS")) && + item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) { + skip = false; + } } if (skip) { continue; @@ -116,3 +138,56 @@ std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*, { return "CUDA"; } + +bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, + const std::string& config) +{ + + if (target.GetType() == cmStateEnums::OBJECT_LIBRARY) { + return false; + } + + if (const char* resolveDeviceSymbols = + target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) { + // If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need + // to honor the value no matter what it is. + return cmSystemTools::IsOn(resolveDeviceSymbols); + } + + if (const char* separableCompilation = + target.GetProperty("CUDA_SEPARABLE_COMPILATION")) { + if (cmSystemTools::IsOn(separableCompilation)) { + bool doDeviceLinking = false; + switch (target.GetType()) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::EXECUTABLE: + doDeviceLinking = true; + break; + default: + break; + } + return doDeviceLinking; + } + } + + // Determine if we have any dependencies that require + // us to do a device link step + const std::string cuda_lang("CUDA"); + cmGeneratorTarget::LinkClosure const* closure = + target.GetLinkClosure(config); + + bool closureHasCUDA = + (std::find(closure->Languages.begin(), closure->Languages.end(), + cuda_lang) != closure->Languages.end()); + if (closureHasCUDA) { + cmComputeLinkInformation* pcli = target.GetLinkInformation(config); + if (pcli) { + cmLinkLineDeviceComputer deviceLinkComputer( + &lg, lg.GetStateSnapshot().GetDirectory()); + return deviceLinkComputer.ComputeRequiresDeviceLinking(*pcli); + } + return true; + } + return false; +} |