diff options
-rw-r--r-- | .clang-tidy | 4 | ||||
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/cmGeneratedFileStream.cxx | 3 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 6 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 12 | ||||
-rw-r--r-- | Source/cmLinkLineDeviceComputer.cxx | 4 | ||||
-rw-r--r-- | Source/cmListFileCache.cxx | 1 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 14 | ||||
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.cxx | 23 | ||||
-rw-r--r-- | Source/cmVariableWatchCommand.cxx | 1 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 76 | ||||
-rw-r--r-- | Tests/CMakeLib/testUVProcessChainHelper.cxx | 3 | ||||
-rw-r--r-- | Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt | 23 | ||||
-rw-r--r-- | Tests/CudaOnly/ResolveDeviceSymbols/file1.h | 3 | ||||
-rw-r--r-- | Tests/CudaOnly/ResolveDeviceSymbols/file2.cu | 16 | ||||
-rw-r--r-- | Tests/CudaOnly/ResolveDeviceSymbols/file2.h | 2 | ||||
-rw-r--r-- | Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu | 18 | ||||
-rw-r--r-- | Tests/CudaOnly/ResolveDeviceSymbols/main.cu | 24 |
18 files changed, 157 insertions, 78 deletions
diff --git a/.clang-tidy b/.clang-tidy index 2d17145..a6378e0 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -7,9 +7,6 @@ bugprone-*,\ -bugprone-too-small-loop-variable,\ google-readability-casting,\ misc-*,\ --misc-incorrect-roundings,\ --misc-macro-parentheses,\ --misc-misplaced-widening-cast,\ -misc-non-private-member-variables-in-classes,\ -misc-static-assert,\ modernize-*,\ @@ -23,7 +20,6 @@ performance-*,\ readability-*,\ -readability-function-size,\ -readability-identifier-naming,\ --readability-implicit-bool-cast,\ -readability-implicit-bool-conversion,\ -readability-inconsistent-declaration-parameter-name,\ -readability-magic-numbers,\ diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b54dbd1..45dd11e 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 15) -set(CMake_VERSION_PATCH 20190906) +set(CMake_VERSION_PATCH 20190910) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index 7475e9f..491d96f 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -4,6 +4,7 @@ #include <stdio.h> +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" #if !defined(CMAKE_BOOTSTRAP) @@ -149,7 +150,7 @@ bool cmGeneratedFileStreamBase::Close() // The destination is to be replaced. Rename the temporary to the // destination atomically. if (this->Compress) { - std::string gzname = this->TempName + ".temp.gz"; + std::string gzname = cmStrCat(this->TempName, ".temp.gz"); if (this->CompressFile(this->TempName, gzname)) { this->RenameFile(gzname, resname); } diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 10f822f..3dae824 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1254,7 +1254,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget( bundleFiles[tsFlags.MacFolder].push_back(sourceFile); } } - for (auto keySources : bundleFiles) { + for (auto const& keySources : bundleFiles) { cmXCodeObject* copyFilesBuildPhase = this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); copyFilesBuildPhase->SetComment("Copy files"); @@ -1302,7 +1302,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget( bundleFiles[tsFlags.MacFolder].push_back(sourceFile); } } - for (auto keySources : bundleFiles) { + for (auto const& keySources : bundleFiles) { cmXCodeObject* copyFilesBuildPhase = this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); copyFilesBuildPhase->SetComment("Copy files"); @@ -1433,7 +1433,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase( void cmGlobalXCodeGenerator::CreateCustomCommands( cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase, cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase, - std::vector<cmXCodeObject*> contentBuildPhases, + std::vector<cmXCodeObject*> const& contentBuildPhases, cmXCodeObject* frameworkBuildPhase, cmGeneratorTarget* gtgt) { std::vector<cmCustomCommand> const& prebuild = gtgt->GetPreBuildCommands(); diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 71446f9..af905d0 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -122,13 +122,11 @@ private: std::string RelativeToSource(const std::string& p); std::string RelativeToBinary(const std::string& p); std::string ConvertToRelativeForMake(std::string const& p); - void CreateCustomCommands(cmXCodeObject* buildPhases, - cmXCodeObject* sourceBuildPhase, - cmXCodeObject* headerBuildPhase, - cmXCodeObject* resourceBuildPhase, - std::vector<cmXCodeObject*> contentBuildPhases, - cmXCodeObject* frameworkBuildPhase, - cmGeneratorTarget* gtgt); + void CreateCustomCommands( + cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase, + cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase, + std::vector<cmXCodeObject*> const& contentBuildPhases, + cmXCodeObject* frameworkBuildPhase, cmGeneratorTarget* gtgt); std::string ComputeInfoPListLocation(cmGeneratorTarget* target); diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index 9c0e20f..1a602ca 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -82,6 +82,9 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( ItemVector const& items = cli.GetItems(); std::string config = cli.GetConfig(); bool skipItemAfterFramework = false; + // Note: + // Any modification of this algorithm should be reflected also in + // cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions for (auto const& item : items) { if (skipItemAfterFramework) { skipItemAfterFramework = false; @@ -91,6 +94,7 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries( if (item.Target) { bool skip = false; switch (item.Target->GetType()) { + case cmStateEnums::SHARED_LIBRARY: case cmStateEnums::MODULE_LIBRARY: case cmStateEnums::INTERFACE_LIBRARY: skip = true; diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index ff3ecd9..349d5e9 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -326,6 +326,7 @@ cmListFileBacktrace::cmListFileBacktrace(cmStateSnapshot const& snapshot) { } +/* NOLINTNEXTLINE(performance-unnecessary-value-param) */ cmListFileBacktrace::cmListFileBacktrace(std::shared_ptr<Entry const> parent, cmListFileContext const& lfc) : TopEntry(std::make_shared<Entry const>(std::move(parent), lfc)) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 9152e94..5d831c9 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -14,6 +14,7 @@ #include "cmInstallScriptGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmLinkLineComputer.h" +#include "cmLinkLineDeviceComputer.h" #include "cmMakefile.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" @@ -1153,6 +1154,12 @@ void cmLocalGenerator::GetTargetFlags( switch (target->GetType()) { case cmStateEnums::STATIC_LIBRARY: this->GetStaticLibraryFlags(linkFlags, buildType, linkLanguage, target); + if (pcli && dynamic_cast<cmLinkLineDeviceComputer*>(linkLineComputer)) { + // Compute the required cuda device link libraries when + // resolving cuda device symbols + this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, + frameworkPath, linkPath); + } break; case cmStateEnums::MODULE_LIBRARY: libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS"; @@ -2089,12 +2096,11 @@ void cmLocalGenerator::AddConfigVariableFlags(std::string& flags, const std::string& config) { // Add the flags from the variable itself. - std::string flagsVar = var; - this->AppendFlags(flags, this->Makefile->GetSafeDefinition(flagsVar)); + this->AppendFlags(flags, this->Makefile->GetSafeDefinition(var)); // Add the flags from the build-type specific variable. if (!config.empty()) { - flagsVar += "_"; - flagsVar += cmSystemTools::UpperCase(config); + const std::string flagsVar = + cmStrCat(var, '_', cmSystemTools::UpperCase(config)); this->AppendFlags(flags, this->Makefile->GetSafeDefinition(flagsVar)); } } diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index d603dac..36f6809 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -301,19 +301,16 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( // Collect up flags to link in needed libraries. std::string linkLibs; - if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) { - - std::unique_ptr<cmLinkLineComputer> linkLineComputer( - new cmLinkLineDeviceComputer( - this->LocalGenerator, - this->LocalGenerator->GetStateSnapshot().GetDirectory())); - linkLineComputer->SetForResponse(useResponseFileForLibs); - linkLineComputer->SetUseWatcomQuote(useWatcomQuote); - linkLineComputer->SetRelink(relink); - - this->CreateLinkLibs(linkLineComputer.get(), linkLibs, - useResponseFileForLibs, depends); - } + std::unique_ptr<cmLinkLineComputer> linkLineComputer( + new cmLinkLineDeviceComputer( + this->LocalGenerator, + this->LocalGenerator->GetStateSnapshot().GetDirectory())); + linkLineComputer->SetForResponse(useResponseFileForLibs); + linkLineComputer->SetUseWatcomQuote(useWatcomQuote); + linkLineComputer->SetRelink(relink); + + this->CreateLinkLibs(linkLineComputer.get(), linkLibs, + useResponseFileForLibs, depends); // Construct object file lists that may be needed to expand the // rule. diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index db23efd..f9f7d66 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -91,6 +91,7 @@ static void deleteVariableWatchCallbackData(void* client_data) class FinalAction { public: + /* NOLINTNEXTLINE(performance-unnecessary-value-param) */ FinalAction(cmMakefile* makefile, std::string variable) : Action(std::make_shared<Impl>(makefile, std::move(variable))) { diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 5e92622..ba72294 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3152,6 +3152,82 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( "-Wno-deprecated-gpu-targets"); } + // For static libraries that have device linking enabled compute + // the libraries + if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY && + doDeviceLinking) { + cmComputeLinkInformation* pcli = + this->GeneratorTarget->GetLinkInformation(configName); + if (!pcli) { + cmSystemTools::Error( + "CMake can not compute cmComputeLinkInformation for target: " + + this->Name); + return false; + } + + // Would like to use: + // cmLinkLineDeviceComputer computer(this->LocalGenerator, + // this->LocalGenerator->GetStateSnapshot().GetDirectory()); + // std::string computed_libs = computer.ComputeLinkLibraries(cli, + // std::string{}); but it outputs in "<libA> <libB>" format instead of + // "<libA>;<libB>" + // Note: + // Any modification of this algorithm should be reflected also in + // cmLinkLineDeviceComputer + cmComputeLinkInformation& cli = *pcli; + std::vector<std::string> libVec; + const std::string currentBinDir = + this->LocalGenerator->GetCurrentBinaryDirectory(); + const auto& libs = cli.GetItems(); + for (cmComputeLinkInformation::Item const& l : libs) { + + if (l.Target) { + auto managedType = l.Target->GetManagedType(configName); + // Do not allow C# targets to be added to the LIB listing. LIB files + // are used for linking C++ dependencies. C# libraries do not have lib + // files. Instead, they compile down to C# reference libraries (DLL + // files). The + // `<ProjectReference>` elements added to the vcxproj are enough for + // the IDE to deduce the DLL file required by other C# projects that + // need its reference library. + if (managedType == cmGeneratorTarget::ManagedType::Managed) { + continue; + } + const auto type = l.Target->GetType(); + + bool skip = false; + switch (type) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::INTERFACE_LIBRARY: + skip = true; + break; + case cmStateEnums::STATIC_LIBRARY: + skip = l.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS"); + break; + default: + break; + } + if (skip) { + continue; + } + } + + if (l.IsPath) { + std::string path = this->LocalGenerator->MaybeConvertToRelativePath( + currentBinDir, l.Value); + ConvertToWindowsSlash(path); + if (!cmVS10IsTargetsFile(l.Value)) { + libVec.push_back(path); + } + } else { + libVec.push_back(l.Value); + } + } + + cudaLinkOptions.AddFlag("AdditionalDependencies", libVec); + } + this->CudaLinkOptions[configName] = std::move(pOptions); return true; } diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx index 263665d..a77ec90 100644 --- a/Tests/CMakeLib/testUVProcessChainHelper.cxx +++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx @@ -44,7 +44,7 @@ int main(int argc, char** argv) } if (command == "dedup") { // Use a nested scope to free all resources before aborting below. - { + try { std::string input = getStdin(); std::set<char> seen; std::string output; @@ -56,6 +56,7 @@ int main(int argc, char** argv) } std::cout << output << std::flush; std::cerr << "3" << std::flush; + } catch (...) { } // On Windows, the exit code of abort() is different between debug and diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt index 796e133..64845c5 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt +++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt @@ -16,21 +16,29 @@ else() endif() #Goal for this example: -# Build a static library that defines multiple methods and kernels that -# use each other. -# Resolve the device symbols into that static library -# Verify that we can't use those device symbols from anything that links +# 1. Build two static libraries that defines multiple methods and kernels +# 2. Resolve the device symbols into the second static library, therefore +# confirming that the first static library is on the device link line +# 3. Verify that we can't use those device symbols from anything that links # to the static library -string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30] -gencode arch=compute_50,code=\\\"compute_50\\\"") +string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[sm_30] -gencode arch=compute_50,code=\\\"compute_50\\\"") set(CMAKE_CXX_STANDARD 11) set(CMAKE_CUDA_STANDARD 11) -add_library(CUDAResolveDeviceLib STATIC file1.cu file2.cu) +add_library(CUDAResolveDeviceDepsA STATIC file1.cu) +add_library(CUDAResolveDeviceDepsB STATIC file2.cu) +set_target_properties(CUDAResolveDeviceDepsA CUDAResolveDeviceDepsB + PROPERTIES + CUDA_SEPARABLE_COMPILATION ON + POSITION_INDEPENDENT_CODE ON) + +add_library(CUDAResolveDeviceLib STATIC file2_launch.cu) set_target_properties(CUDAResolveDeviceLib PROPERTIES CUDA_SEPARABLE_COMPILATION ON CUDA_RESOLVE_DEVICE_SYMBOLS ON POSITION_INDEPENDENT_CODE ON) +target_link_libraries(CUDAResolveDeviceLib PRIVATE CUDAResolveDeviceDepsA CUDAResolveDeviceDepsB) if(dump_command) add_custom_command(TARGET CUDAResolveDeviceLib POST_BUILD @@ -45,7 +53,8 @@ endif() add_executable(CudaOnlyResolveDeviceSymbols main.cu) set_target_properties(CudaOnlyResolveDeviceSymbols PROPERTIES - CUDA_SEPARABLE_COMPILATION ON) + CUDA_SEPARABLE_COMPILATION OFF + CUDA_RESOLVE_DEVICE_SYMBOLS OFF) target_link_libraries(CudaOnlyResolveDeviceSymbols PRIVATE CUDAResolveDeviceLib) diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file1.h b/Tests/CudaOnly/ResolveDeviceSymbols/file1.h index ff1945c..b33bcae 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/file1.h +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file1.h @@ -1,7 +1,10 @@ #pragma once + struct result_type { int input; int sum; }; + +result_type __device__ file1_func(int x); diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu b/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu index 278fd6c..0e5e7aa 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2.cu @@ -1,25 +1,9 @@ #include "file2.h" -result_type __device__ file1_func(int x); - result_type_dynamic __device__ file2_func(int x) { const result_type r = file1_func(x); const result_type_dynamic rd{ r.input, r.sum, true }; return rd; } - -static __global__ void file2_kernel(result_type_dynamic& r, int x) -{ - // call static_func which is a method that is defined in the - // static library that is always out of date - r = file2_func(x); -} - -int file2_launch_kernel(int x) -{ - result_type_dynamic r; - file2_kernel<<<1, 1>>>(r, x); - return r.sum; -} diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2.h b/Tests/CudaOnly/ResolveDeviceSymbols/file2.h index d2dbaa4..c6e2875 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/file2.h +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2.h @@ -8,3 +8,5 @@ struct result_type_dynamic int sum; bool from_static; }; + +result_type_dynamic __device__ file2_func(int x); diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu b/Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu new file mode 100644 index 0000000..4e8da13 --- /dev/null +++ b/Tests/CudaOnly/ResolveDeviceSymbols/file2_launch.cu @@ -0,0 +1,18 @@ + +#include "file2.h" + +static __global__ void file2_kernel(result_type_dynamic& r, int x) +{ + // call static_func which is a method that is defined in the + // static library that is always out of date + r = file2_func(x); +} + +static __global__ void file2_kernel(result_type_dynamic& r, int x); + +int file2_launch_kernel(int x) +{ + result_type_dynamic r; + file2_kernel<<<1, 1>>>(r, x); + return r.sum; +} diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/main.cu b/Tests/CudaOnly/ResolveDeviceSymbols/main.cu index d464f96..ea842cc 100644 --- a/Tests/CudaOnly/ResolveDeviceSymbols/main.cu +++ b/Tests/CudaOnly/ResolveDeviceSymbols/main.cu @@ -1,26 +1,10 @@ #include <iostream> -#include "file1.h" #include "file2.h" int file2_launch_kernel(int x); -result_type_dynamic __device__ file2_func(int x); -static __global__ void main_kernel(result_type_dynamic& r, int x) -{ - // call function that was not device linked to us, this will cause - // a runtime failure of "invalid device function" - r = file2_func(x); -} - -int main_launch_kernel(int x) -{ - result_type_dynamic r; - main_kernel<<<1, 1>>>(r, x); - return r.sum; -} - int choose_cuda_device() { int nDevices = 0; @@ -62,12 +46,10 @@ int main(int argc, char** argv) return 0; } - main_launch_kernel(1); + file2_launch_kernel(1); cudaError_t err = cudaGetLastError(); - if (err == cudaSuccess) { - // This kernel launch should fail as the file2_func was device linked - // into the static library and is not usable by the executable - std::cerr << "main_launch_kernel: kernel launch should have failed" + if (err != cudaSuccess) { + std::cerr << "file2_launch_kernel: kernel launch should have passed" << std::endl; return 1; } |