Ver Fonte

VS: Select CUDA code generation architectures

Parse the `-gencode=`, `-arch`, and `-code` flags and generate a
`CodeGeneration` field in the project file.
Brad King há 8 anos atrás
pai
commit
94255511a6

+ 22 - 0
Source/cmVS10CudaFlagTable.h

@@ -14,5 +14,27 @@ static cmVS7FlagTable cmVS10CudaFlagTable[] = {
   { "CudaRuntime", "cudart", "CUDA runtime library", "",
     cmVS7FlagTable::UserFollowing },
 
+  // Capture arch/code arguments into temporaries for post-processing.
+  { "cmake-temp-gencode", "gencode=", "", "",
+    cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable },
+  { "cmake-temp-gencode", "gencode", "", "",
+    cmVS7FlagTable::UserFollowing | cmVS7FlagTable::SemicolonAppendable },
+  { "cmake-temp-gencode", "-generate-code=", "", "",
+    cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable },
+  { "cmake-temp-gencode", "-generate-code", "", "",
+    cmVS7FlagTable::UserFollowing | cmVS7FlagTable::SemicolonAppendable },
+
+  { "cmake-temp-code", "code=", "", "", cmVS7FlagTable::UserValue },
+  { "cmake-temp-code", "code", "", "", cmVS7FlagTable::UserFollowing },
+  { "cmake-temp-code", "-gpu-code=", "", "", cmVS7FlagTable::UserValue },
+  { "cmake-temp-code", "-gpu-code", "", "", cmVS7FlagTable::UserFollowing },
+
+  { "cmake-temp-arch", "arch=", "", "", cmVS7FlagTable::UserValue },
+  { "cmake-temp-arch", "arch", "", "", cmVS7FlagTable::UserFollowing },
+  { "cmake-temp-arch", "-gpu-architecture=", "", "",
+    cmVS7FlagTable::UserValue },
+  { "cmake-temp-arch", "-gpu-architecture", "", "",
+    cmVS7FlagTable::UserFollowing },
+
   { 0, 0, 0, 0, 0 }
 };

+ 2 - 0
Source/cmVisualStudio10TargetGenerator.cxx

@@ -2480,6 +2480,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
   // did not parse and hope it works.
   cudaOptions.RemoveFlag("AdditionalCompilerOptions");
 
+  cudaOptions.FixCudaCodeGeneration();
+
   std::vector<std::string> targetDefines;
   this->GeneratorTarget->GetCompileDefinitions(targetDefines,
                                                configName.c_str(), "CUDA");

+ 51 - 0
Source/cmVisualStudioGeneratorOptions.cxx

@@ -208,6 +208,57 @@ cmVisualStudioGeneratorOptions::GetCudaRuntime() const
   return CudaRuntimeStatic;
 }
 
+void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
+{
+  // Extract temporary values stored by our flag table.
+  FlagValue arch = this->TakeFlag("cmake-temp-arch");
+  FlagValue code = this->TakeFlag("cmake-temp-code");
+  FlagValue gencode = this->TakeFlag("cmake-temp-gencode");
+
+  // No -code allowed without -arch.
+  if (arch.empty()) {
+    code.clear();
+  }
+
+  if (arch.empty() && gencode.empty()) {
+    return;
+  }
+
+  // Create a CodeGeneration field with [arch],[code] syntax in each entry.
+  // CUDA will convert it to `-gencode=arch=[arch],code="[code],[arch]"`.
+  FlagValue& result = this->FlagMap["CodeGeneration"];
+
+  // First entries for the -arch=<arch> [-code=<code>,...] pair.
+  if (!arch.empty()) {
+    std::string arch_name = arch[0];
+    std::vector<std::string> codes;
+    if (!code.empty()) {
+      codes = cmSystemTools::tokenize(code[0], ",");
+    }
+    if (codes.empty()) {
+      codes.push_back(arch_name);
+      // nvcc -arch=<arch> has a special case that allows a real
+      // architecture to be specified instead of a virtual arch.
+      // It translates to -arch=<virtual> -code=<real>.
+      cmSystemTools::ReplaceString(arch_name, "sm_", "compute_");
+    }
+    for (std::vector<std::string>::iterator ci = codes.begin();
+         ci != codes.end(); ++ci) {
+      std::string entry = arch_name + "," + *ci;
+      result.push_back(entry);
+    }
+  }
+
+  // Now add entries for the -gencode=<arch>,<code> pairs.
+  for (std::vector<std::string>::iterator ei = gencode.begin();
+       ei != gencode.end(); ++ei) {
+    std::string entry = *ei;
+    cmSystemTools::ReplaceString(entry, "arch=", "");
+    cmSystemTools::ReplaceString(entry, "code=", "");
+    result.push_back(entry);
+  }
+}
+
 void cmVisualStudioGeneratorOptions::Parse(const char* flags)
 {
   // Parse the input string as a windows command line since the string

+ 2 - 0
Source/cmVisualStudioGeneratorOptions.h

@@ -75,6 +75,8 @@ public:
   };
   CudaRuntime GetCudaRuntime() const;
 
+  void FixCudaCodeGeneration();
+
   bool IsDebug() const;
   bool IsWinRt() const;
   bool IsManaged() const;