mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-06 05:40:54 -06:00
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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user