12#include "clang/Config/config.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Option/ArgList.h"
21#include "llvm/Support/FileSystem.h"
22#include "llvm/Support/FormatAdapters.h"
23#include "llvm/Support/FormatVariadic.h"
24#include "llvm/Support/Path.h"
25#include "llvm/Support/Process.h"
26#include "llvm/Support/Program.h"
27#include "llvm/Support/VirtualFileSystem.h"
28#include "llvm/TargetParser/Host.h"
29#include "llvm/TargetParser/TargetParser.h"
30#include <system_error>
41 if (raw_version < 7050)
42 return CudaVersion::CUDA_70;
43 if (raw_version < 8000)
44 return CudaVersion::CUDA_75;
45 if (raw_version < 9000)
46 return CudaVersion::CUDA_80;
47 if (raw_version < 9010)
48 return CudaVersion::CUDA_90;
49 if (raw_version < 9020)
50 return CudaVersion::CUDA_91;
51 if (raw_version < 10000)
52 return CudaVersion::CUDA_92;
53 if (raw_version < 10010)
54 return CudaVersion::CUDA_100;
55 if (raw_version < 10020)
56 return CudaVersion::CUDA_101;
57 if (raw_version < 11000)
58 return CudaVersion::CUDA_102;
59 if (raw_version < 11010)
60 return CudaVersion::CUDA_110;
61 if (raw_version < 11020)
62 return CudaVersion::CUDA_111;
63 if (raw_version < 11030)
64 return CudaVersion::CUDA_112;
65 if (raw_version < 11040)
66 return CudaVersion::CUDA_113;
67 if (raw_version < 11050)
68 return CudaVersion::CUDA_114;
69 if (raw_version < 11060)
70 return CudaVersion::CUDA_115;
71 if (raw_version < 11070)
72 return CudaVersion::CUDA_116;
73 if (raw_version < 11080)
74 return CudaVersion::CUDA_117;
75 if (raw_version < 11090)
76 return CudaVersion::CUDA_118;
77 return CudaVersion::NEW;
83 auto StartsWithWords =
84 [](llvm::StringRef Line,
86 for (StringRef word : words) {
87 if (!Line.consume_front(word))
94 Input = Input.ltrim();
95 while (!Input.empty()) {
97 StartsWithWords(Input.ltrim(), {
"#",
"define",
"CUDA_VERSION"})) {
99 Line->consumeInteger(10, RawVersion);
100 return getCudaVersion(RawVersion);
103 Input = Input.drop_front(Input.find_first_of(
"\n\r")).ltrim();
105 return CudaVersion::UNKNOWN;
112 if (!VersionString.empty())
113 VersionString.insert(0,
" ");
114 D.
Diag(diag::warn_drv_new_cuda_version)
119 D.
Diag(diag::warn_drv_partially_supported_cuda_version)
124 const Driver &D,
const llvm::Triple &HostTriple,
125 const llvm::opt::ArgList &Args)
131 Candidate(std::string Path,
bool StrictChecking =
false)
132 : Path(Path), StrictChecking(StrictChecking) {}
137 std::initializer_list<const char *> Versions = {
"8.0",
"7.5",
"7.0"};
140 if (Args.hasArg(clang::driver::options::OPT_cuda_path_EQ)) {
141 Candidates.emplace_back(
142 Args.getLastArgValue(clang::driver::options::OPT_cuda_path_EQ).str());
143 }
else if (HostTriple.isOSWindows()) {
144 for (
const char *Ver : Versions)
145 Candidates.emplace_back(
146 D.
SysRoot +
"/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" +
149 if (!Args.hasArg(clang::driver::options::OPT_cuda_path_ignore_env)) {
158 if (llvm::ErrorOr<std::string> ptxas =
159 llvm::sys::findProgramByName(
"ptxas")) {
161 llvm::sys::fs::real_path(*ptxas, ptxasAbsolutePath);
163 StringRef ptxasDir = llvm::sys::path::parent_path(ptxasAbsolutePath);
164 if (llvm::sys::path::filename(ptxasDir) ==
"bin")
165 Candidates.emplace_back(
166 std::string(llvm::sys::path::parent_path(ptxasDir)),
171 Candidates.emplace_back(D.
SysRoot +
"/usr/local/cuda");
172 for (
const char *Ver : Versions)
173 Candidates.emplace_back(D.
SysRoot +
"/usr/local/cuda-" + Ver);
175 Distro Dist(FS, llvm::Triple(llvm::sys::getProcessTriple()));
179 Candidates.emplace_back(D.
SysRoot +
"/usr/lib/cuda");
182 bool NoCudaLib = Args.hasArg(options::OPT_nogpulib);
184 for (
const auto &Candidate : Candidates) {
185 InstallPath = Candidate.Path;
186 if (InstallPath.empty() || !FS.exists(InstallPath))
189 BinPath = InstallPath +
"/bin";
190 IncludePath = InstallPath +
"/include";
191 LibDevicePath = InstallPath +
"/nvvm/libdevice";
193 if (!(FS.exists(IncludePath) && FS.exists(BinPath)))
195 bool CheckLibDevice = (!NoCudaLib || Candidate.StrictChecking);
196 if (CheckLibDevice && !FS.exists(LibDevicePath))
200 if (
auto CudaHFile = FS.getBufferForFile(InstallPath +
"/include/cuda.h"))
201 Version = parseCudaHFile((*CudaHFile)->getBuffer());
205 Version = FS.exists(LibDevicePath +
"/libdevice.10.bc")
212 std::string FilePath = LibDevicePath +
"/libdevice.10.bc";
213 if (FS.exists(FilePath)) {
220 LibDeviceMap[GpuArchName] = FilePath;
225 for (llvm::vfs::directory_iterator LI = FS.dir_begin(LibDevicePath, EC),
227 !EC && LI != LE; LI = LI.increment(EC)) {
228 StringRef FilePath = LI->path();
229 StringRef FileName = llvm::sys::path::filename(FilePath);
232 const StringRef LibDeviceName =
"libdevice.";
233 if (!(FileName.startswith(LibDeviceName) && FileName.endswith(
".bc")))
235 StringRef GpuArch = FileName.slice(
236 LibDeviceName.size(), FileName.find(
'.', LibDeviceName.size()));
237 LibDeviceMap[GpuArch] = FilePath.str();
241 if (GpuArch ==
"compute_20") {
242 LibDeviceMap[
"sm_20"] = std::string(FilePath);
243 LibDeviceMap[
"sm_21"] = std::string(FilePath);
244 LibDeviceMap[
"sm_32"] = std::string(FilePath);
245 }
else if (GpuArch ==
"compute_30") {
246 LibDeviceMap[
"sm_30"] = std::string(FilePath);
248 LibDeviceMap[
"sm_50"] = std::string(FilePath);
249 LibDeviceMap[
"sm_52"] = std::string(FilePath);
250 LibDeviceMap[
"sm_53"] = std::string(FilePath);
252 LibDeviceMap[
"sm_60"] = std::string(FilePath);
253 LibDeviceMap[
"sm_61"] = std::string(FilePath);
254 LibDeviceMap[
"sm_62"] = std::string(FilePath);
255 }
else if (GpuArch ==
"compute_35") {
256 LibDeviceMap[
"sm_35"] = std::string(FilePath);
257 LibDeviceMap[
"sm_37"] = std::string(FilePath);
258 }
else if (GpuArch ==
"compute_50") {
260 LibDeviceMap[
"sm_50"] = std::string(FilePath);
261 LibDeviceMap[
"sm_52"] = std::string(FilePath);
262 LibDeviceMap[
"sm_53"] = std::string(FilePath);
270 if (LibDeviceMap.empty() && !NoCudaLib)
279 const ArgList &DriverArgs, ArgStringList &CC1Args)
const {
280 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
284 llvm::sys::path::append(
P,
"include");
285 llvm::sys::path::append(
P,
"cuda_wrappers");
286 CC1Args.push_back(
"-internal-isystem");
287 CC1Args.push_back(DriverArgs.MakeArgString(
P));
290 if (DriverArgs.hasArg(options::OPT_nogpuinc))
294 D.
Diag(diag::err_drv_no_cuda_installation);
298 CC1Args.push_back(
"-include");
299 CC1Args.push_back(
"__clang_cuda_runtime_wrapper.h");
305 ArchsWithBadVersion[(
int)Arch])
310 if (Version < MinVersion || Version > MaxVersion) {
311 ArchsWithBadVersion[(
int)Arch] =
true;
312 D.
Diag(diag::err_drv_cuda_version_unsupported)
321 OS <<
"Found CUDA installation: " << InstallPath <<
", version "
331enum DeviceDebugInfoLevel {
334 EmitSameDebugInfoAsHost,
348 const Arg *A = Args.getLastArg(options::OPT_O_Group);
349 bool IsDebugEnabled = !A || A->getOption().matches(options::OPT_O0) ||
350 Args.hasFlag(options::OPT_cuda_noopt_device_debug,
351 options::OPT_no_cuda_noopt_device_debug,
353 if (
const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
354 const Option &Opt = A->getOption();
355 if (Opt.matches(options::OPT_gN_Group)) {
356 if (Opt.matches(options::OPT_g0) || Opt.matches(options::OPT_ggdb0))
357 return DisableDebugInfo;
358 if (Opt.matches(options::OPT_gline_directives_only))
359 return DebugDirectivesOnly;
361 return IsDebugEnabled ? EmitSameDebugInfoAsHost : DebugDirectivesOnly;
370 const char *LinkingOutput)
const {
373 assert(TC.getTriple().isNVPTX() &&
"Wrong platform");
375 StringRef GPUArchName;
383 GPUArchName = Args.getLastArgValue(options::OPT_march_EQ);
384 assert(!GPUArchName.empty() &&
"Must have an architecture passed in.");
390 "Device action expected to have an architecture.");
393 if (!Args.hasArg(options::OPT_no_cuda_version_check)) {
394 TC.CudaInstallation.CheckCudaVersionSupportsArch(gpu_arch);
397 ArgStringList CmdArgs;
398 CmdArgs.push_back(TC.getTriple().isArch64Bit() ?
"-m64" :
"-m32");
400 if (DIKind == EmitSameDebugInfoAsHost) {
403 CmdArgs.push_back(
"-g");
404 CmdArgs.push_back(
"--dont-merge-basicblocks");
405 CmdArgs.push_back(
"--return-at-end");
406 }
else if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
414 StringRef OOpt =
"3";
415 if (A->getOption().matches(options::OPT_O4) ||
416 A->getOption().matches(options::OPT_Ofast))
418 else if (A->getOption().matches(options::OPT_O0))
420 else if (A->getOption().matches(options::OPT_O)) {
422 OOpt = llvm::StringSwitch<const char *>(A->getValue())
430 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-O") + OOpt));
434 CmdArgs.push_back(
"-O0");
436 if (DIKind == DebugDirectivesOnly)
437 CmdArgs.push_back(
"-lineinfo");
440 if (Args.hasArg(options::OPT_v))
441 CmdArgs.push_back(
"-v");
443 CmdArgs.push_back(
"--gpu-name");
445 CmdArgs.push_back(
"--output-file");
446 std::string OutputFileName = TC.getInputFilename(Output);
450 if (!
C.getInputArgs().getLastArg(options::OPT_c)) {
452 llvm::sys::path::replace_extension(
Filename,
"cubin");
456 C.addTempFile(Args.MakeArgString(OutputFileName));
458 CmdArgs.push_back(Args.MakeArgString(OutputFileName));
459 for (
const auto &II : Inputs)
460 CmdArgs.push_back(Args.MakeArgString(II.getFilename()));
462 for (
const auto &A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
463 CmdArgs.push_back(Args.MakeArgString(A));
468 Relocatable = Args.hasFlag(options::OPT_fopenmp_relocatable_target,
469 options::OPT_fnoopenmp_relocatable_target,
473 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
480 CmdArgs.push_back(
"-c");
483 if (Arg *A = Args.getLastArg(options::OPT_ptxas_path_EQ))
484 Exec = A->getValue();
486 Exec = Args.MakeArgString(TC.GetProgramPath(
"ptxas"));
487 C.addCommand(std::make_unique<Command>(
491 Exec, CmdArgs, Inputs, Output));
495 bool includePTX =
true;
496 for (Arg *A : Args) {
497 if (!(A->getOption().matches(options::OPT_cuda_include_ptx_EQ) ||
498 A->getOption().matches(options::OPT_no_cuda_include_ptx_EQ)))
501 const StringRef ArchStr = A->getValue();
502 if (ArchStr ==
"all" || ArchStr == gpu_arch) {
503 includePTX = A->getOption().matches(options::OPT_cuda_include_ptx_EQ);
517 const char *LinkingOutput)
const {
520 assert(TC.getTriple().isNVPTX() &&
"Wrong platform");
522 ArgStringList CmdArgs;
524 CmdArgs.push_back(
"--cuda");
525 CmdArgs.push_back(TC.getTriple().isArch64Bit() ?
"-64" :
"-32");
526 CmdArgs.push_back(Args.MakeArgString(
"--create"));
527 CmdArgs.push_back(Args.MakeArgString(Output.
getFilename()));
529 CmdArgs.push_back(
"-g");
531 for (
const auto &II : Inputs) {
532 auto *A = II.getAction();
533 assert(A->getInputs().size() == 1 &&
534 "Device offload action is expected to have a single input");
535 const char *gpu_arch_str = A->getOffloadingArch();
536 assert(gpu_arch_str &&
537 "Device action expected to have associated a GPU architecture!");
540 if (II.getType() == types::TY_PP_Asm &&
545 const char *Arch = (II.getType() == types::TY_PP_Asm)
549 Args.MakeArgString(llvm::Twine(
"--image=profile=") + Arch +
550 ",file=" + getToolChain().getInputFilename(II)));
553 for (
const auto &A : Args.getAllArgValues(options::OPT_Xcuda_fatbinary))
554 CmdArgs.push_back(Args.MakeArgString(A));
556 const char *Exec = Args.MakeArgString(TC.GetProgramPath(
"fatbinary"));
557 C.addCommand(std::make_unique<Command>(
561 Exec, CmdArgs, Inputs, Output));
568 const char *LinkingOutput)
const {
571 assert(TC.getTriple().isNVPTX() &&
"Wrong platform");
573 ArgStringList CmdArgs;
575 CmdArgs.push_back(
"-o");
578 assert(Output.
isNothing() &&
"Invalid output.");
582 CmdArgs.push_back(
"-g");
584 if (Args.hasArg(options::OPT_v))
585 CmdArgs.push_back(
"-v");
587 StringRef GPUArch = Args.getLastArgValue(options::OPT_march_EQ);
588 assert(!GPUArch.empty() &&
"At least one GPU Arch required for nvlink.");
590 CmdArgs.push_back(
"-arch");
591 CmdArgs.push_back(Args.MakeArgString(GPUArch));
598 llvm::sys::path::parent_path(TC.getDriver().Dir);
599 llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
600 CmdArgs.push_back(Args.MakeArgString(Twine(
"-L") + DefaultLibPath));
602 for (
const auto &II : Inputs) {
603 if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
604 II.getType() == types::TY_LTO_BC || II.getType() == types::TY_LLVM_BC) {
605 C.getDriver().Diag(diag::err_drv_no_linker_llvm_support)
606 << getToolChain().getTripleString();
612 if (!II.isFilename())
619 auto InputFile = getToolChain().getInputFilename(II);
620 if (llvm::sys::path::extension(InputFile) !=
".cubin") {
624 if (II.getAction() && II.getAction()->getInputs().size() == 0) {
626 Args.MakeArgString(getToolChain().getDriver().GetTemporaryPath(
627 llvm::sys::path::stem(InputFile),
"cubin"));
628 if (std::error_code EC =
629 llvm::sys::fs::copy_file(InputFile,
C.addTempFile(CubinF)))
632 CmdArgs.push_back(CubinF);
635 llvm::sys::path::replace_extension(
Filename,
"cubin");
636 CmdArgs.push_back(Args.MakeArgString(
Filename));
639 CmdArgs.push_back(Args.MakeArgString(InputFile));
643 C.addCommand(std::make_unique<Command>(
647 Args.MakeArgString(getToolChain().GetProgramPath(
"nvlink")), CmdArgs,
652 const llvm::opt::ArgList &Args,
653 std::vector<StringRef> &Features) {
654 if (Args.hasArg(options::OPT_cuda_feature_EQ)) {
655 StringRef PtxFeature =
656 Args.getLastArgValue(options::OPT_cuda_feature_EQ,
"+ptx42");
657 Features.push_back(Args.MakeArgString(PtxFeature));
665 const char *PtxFeature =
nullptr;
666 switch (CudaInstallation.
version()) {
667#define CASE_CUDA_VERSION(CUDA_VER, PTX_VER) \
668 case CudaVersion::CUDA_##CUDA_VER: \
669 PtxFeature = "+ptx" #PTX_VER; \
686#undef CASE_CUDA_VERSION
688 PtxFeature =
"+ptx42";
690 Features.push_back(PtxFeature);
697 const llvm::Triple &HostTriple,
699 :
ToolChain(D, Triple, Args), CudaInstallation(D, HostTriple, Args) {
700 if (CudaInstallation.isValid()) {
701 CudaInstallation.WarnIfUnsupportedVersion();
702 getProgramPaths().push_back(std::string(CudaInstallation.getBinPath()));
706 getProgramPaths().push_back(getDriver().Dir);
714 llvm::Triple(
llvm::sys::getDefaultTargetTriple()), Args) {}
716llvm::opt::DerivedArgList *
720 DerivedArgList *DAL =
723 DAL =
new DerivedArgList(Args.getBaseArgs());
725 const OptTable &Opts = getDriver().getOpts();
728 if (!llvm::is_contained(*DAL, A))
731 if (!DAL->hasArg(options::OPT_march_EQ))
732 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ),
739 const Option &O = A->getOption();
740 return (O.matches(options::OPT_gN_Group) &&
741 !O.matches(options::OPT_gmodules)) ||
742 O.matches(options::OPT_g_Flag) ||
743 O.matches(options::OPT_ggdbN_Group) || O.matches(options::OPT_ggdb) ||
744 O.matches(options::OPT_gdwarf) || O.matches(options::OPT_gdwarf_2) ||
745 O.matches(options::OPT_gdwarf_3) || O.matches(options::OPT_gdwarf_4) ||
746 O.matches(options::OPT_gdwarf_5) ||
747 O.matches(options::OPT_gcolumn_info);
751 llvm::codegenoptions::DebugInfoKind &DebugInfoKind,
752 const ArgList &Args)
const {
754 case DisableDebugInfo:
755 DebugInfoKind = llvm::codegenoptions::NoDebugInfo;
757 case DebugDirectivesOnly:
758 DebugInfoKind = llvm::codegenoptions::DebugDirectivesOnly;
760 case EmitSameDebugInfoAsHost:
771 const ToolChain &HostTC,
const ArgList &Args)
772 :
NVPTXToolChain(D, Triple, HostTC.getTriple(), Args), HostTC(HostTC) {}
775 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
779 StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
780 assert(!GpuArch.empty() &&
"Must have an explicit GPU arch.");
783 "Only OpenMP or CUDA offloading kinds are supported for NVIDIA GPUs.");
787 {
"-fcuda-is-device",
"-mllvm",
"-enable-memcpyopt-without-libcalls"});
789 if (DriverArgs.hasFlag(options::OPT_fcuda_approx_transcendentals,
790 options::OPT_fno_cuda_approx_transcendentals,
false))
791 CC1Args.push_back(
"-fcuda-approx-transcendentals");
794 if (DriverArgs.hasArg(options::OPT_nogpulib))
798 DriverArgs.hasArg(options::OPT_S))
802 if (LibDeviceFile.empty()) {
803 getDriver().
Diag(diag::err_drv_no_cuda_libdevice) << GpuArch;
807 CC1Args.push_back(
"-mlink-builtin-bitcode");
808 CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
812 if (DriverArgs.hasFlag(options::OPT_fcuda_short_ptr,
813 options::OPT_fno_cuda_short_ptr,
false))
814 CC1Args.append({
"-mllvm",
"--nvptx-short-ptr"});
818 DriverArgs.MakeArgString(Twine(
"-target-sdk-version=") +
824 diag::err_drv_omp_offload_target_cuda_version_not_support)
839 const llvm::opt::ArgList &DriverArgs,
const JobAction &JA,
840 const llvm::fltSemantics *FPType)
const {
842 if (FPType && FPType == &llvm::APFloat::IEEEsingle() &&
843 DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero,
844 options::OPT_fno_gpu_flush_denormals_to_zero,
false))
845 return llvm::DenormalMode::getPreserveSign();
849 return llvm::DenormalMode::getIEEE();
853 ArgStringList &CC1Args)
const {
855 if (!DriverArgs.hasArg(options::OPT_nogpuinc) &&
856 !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) {
857 StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
858 assert(!Arch.empty() &&
"Must have an explicit GPU arch.");
873 llvm::sys::path::replace_extension(
Filename,
"cubin");
877llvm::opt::DerivedArgList *
881 DerivedArgList *DAL =
884 DAL =
new DerivedArgList(Args.getBaseArgs());
893 if (!llvm::is_contained(*DAL, A))
896 if (!DAL->hasArg(options::OPT_march_EQ)) {
897 StringRef Arch = BoundArch;
902 llvm::formatv(
"{0}", llvm::fmt_consume(ArchsOrErr.takeError()));
904 << llvm::Triple::getArchTypeName(
getArch()) << ErrMsg <<
"-march";
907 Arch = Args.MakeArgString(ArchsOrErr->front());
910 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ), Arch);
916 for (Arg *A : Args) {
920 if (!BoundArch.empty()) {
921 DAL->eraseArg(options::OPT_march_EQ);
922 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ),
932 if (Arg *A = Args.getLastArg(options::OPT_nvptx_arch_tool_EQ))
933 Program = A->getValue();
939 return StdoutOrErr.takeError();
942 for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
944 GPUArchs.push_back(Arch.str());
946 if (GPUArchs.empty())
947 return llvm::createStringError(std::error_code(),
948 "No NVIDIA GPU detected in the system");
950 return std::move(GPUArchs);
979 ArgStringList &CC1Args)
const {
984 {
"-internal-isystem",
989 ArgStringList &CC1Args)
const {
994 ArgStringList &CC1Args)
const {
1012 const ArgList &Args)
const {
const char * getOffloadingArch() const
OffloadKind getOffloadingDeviceKind() const
bool isDeviceOffloading(OffloadKind OKind) const
bool isOffloading(OffloadKind OKind) const
Compilation - A set of tasks to perform for a single driver invocation.
A class to find a viable CUDA installation.
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args)
void WarnIfUnsupportedVersion()
CudaVersion version() const
Get the detected Cuda install's version.
std::string getLibDeviceFile(StringRef Gpu) const
Get libdevice file for given architecture.
void CheckCudaVersionSupportsArch(CudaArch Arch) const
Emit an error if Version does not support the given Arch.
void print(raw_ostream &OS) const
Print information about the detected CUDA installation.
StringRef getIncludePath() const
Get the detected Cuda Include path.
bool isValid() const
Check whether we detected a valid Cuda install.
Distro - Helper class for detecting and classifying Linux distributions.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
DiagnosticBuilder Diag(unsigned DiagID) const
const llvm::opt::OptTable & getOpts() const
std::string ResourceDir
The path to the compiler resource directory.
llvm::vfs::FileSystem & getVFS() const
bool willEmitRemarks(const llvm::opt::ArgList &Args)
const char * CudaArchToVirtualArchString(CudaArch A)
CudaVersion MaxVersionForCudaArch(CudaArch A)
Get the latest CudaVersion that supports the given CudaArch.
CudaArch StringToCudaArch(llvm::StringRef S)
CudaVersion MinVersionForCudaArch(CudaArch A)
Get the earliest CudaVersion that supports the given CudaArch.
@ C
Languages that the frontend can parse and compile.
static bool IsNVIDIAGpuArch(CudaArch A)
const char * CudaVersionToString(CudaVersion V)
const char * CudaArchToString(CudaArch A)
YAML serialization mapping.