From 3dbd493de218cbecac056fc133e9147a2246a91d Mon Sep 17 00:00:00 2001 From: Olexa Bilaniuk Date: Fri, 12 Mar 2021 05:51:44 -0500 Subject: [PATCH 1/3] Canonicalize and merge consecutive -Xcompiler flags together. Makes command-line more readable. --- mesonbuild/compilers/cuda.py | 48 +++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index ef6375ab0..1471d8404 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -259,6 +259,52 @@ class CudaCompiler(Compiler): l = [cls._shield_nvcc_list_arg(s, listmode=False) for s in l] return r'\,'.join(l) + @classmethod + def _merge_flags(cls, flags: T.List[str]) -> T.List[str]: + r""" + The flags to NVCC gets exceedingly verbose and unreadable when too many of them + are shielded with -Xcompiler. Merge consecutive -Xcompiler-wrapped arguments + into one. + """ + if len(flags) <= 1: + return flags + flagit = iter(flags) + xflags = [] + + def is_xcompiler_flag_isolated(flag: str) -> bool: + return flag == '-Xcompiler' + def is_xcompiler_flag_glued(flag: str) -> bool: + return flag.startswith('-Xcompiler=') + def is_xcompiler_flag(flag: str) -> bool: + return is_xcompiler_flag_isolated(flag) or is_xcompiler_flag_glued(flag) + def get_xcompiler_val(flag: str, flagit: T.Iterator[str]) -> str: + if is_xcompiler_flag_glued(flag): + return flag[len('-Xcompiler='):] + else: + try: + return next(flagit) + except StopIteration: + return "" + + ingroup = False + for flag in flagit: + if not is_xcompiler_flag(flag): + ingroup = False + xflags.append(flag) + elif ingroup: + xflags[-1] += ',' + xflags[-1] += get_xcompiler_val(flag, flagit) + elif is_xcompiler_flag_isolated(flag): + ingroup = True + xflags.append(flag) + xflags.append(get_xcompiler_val(flag, flagit)) + elif is_xcompiler_flag_glued(flag): + ingroup = True + xflags.append(flag) + else: + raise ValueError("-Xcompiler flag merging failed, unknown argument form!") + return xflags + @classmethod def _to_host_flags(cls, flags: T.List[str], phase: _Phase = _Phase.COMPILER) -> T.List[str]: """ @@ -432,7 +478,7 @@ class CudaCompiler(Compiler): xflags.append(flag) xflags.append(val) - return xflags + return cls._merge_flags(xflags) def needs_static_linker(self) -> bool: return False From 5941e94ff8242591761c634f96efc56e49fedecf Mon Sep 17 00:00:00 2001 From: Olexa Bilaniuk Date: Fri, 12 Mar 2021 18:15:21 -0500 Subject: [PATCH 2/3] Retract "DQSQ" merging in NVCC arguments handling. No coverage, no tests, unreadable, unused, likely premature optimization. --- mesonbuild/compilers/cuda.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 1471d8404..0ef92b55b 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -218,21 +218,6 @@ class CudaCompiler(Compiler): # strings between them. l = [cls._shield_nvcc_list_arg(s) for s in arg.split(SQ)] l = sum([[s, DQSQ] for s in l][:-1], []) # Interleave l with DQSQs - - # The list l now has the structure of shielded strings interleaved - # with double-quoted single-quotes. - # - # Plain concatenation would result in the tripling of the length of - # a string made up only of single quotes. See if we can merge some - # DQSQs together first. - def isdqsq(x:str) -> bool: - return x.startswith(SQ) and x.endswith(SQ) and x[1:-1].strip(SQ) == '' - for i in range(1, len(l)-2, 2): - if isdqsq(l[i]) and l[i+1] == '' and isdqsq(l[i+2]): - l[i+2] = l[i][:-1]+l[i+2][1:] - l[i] = '' - - # With DQSQs merged, simply concatenate everything together and return. return ''.join(l) else: # A comma is present, and list mode was active. From 2579420a72b64c020f9538d8ccbb52fd57c804a1 Mon Sep 17 00:00:00 2001 From: Olexa Bilaniuk Date: Fri, 12 Mar 2021 18:09:22 -0500 Subject: [PATCH 3/3] Strip host-compiler -std flag from NVCC line. Closes #8523. --- mesonbuild/compilers/cuda.py | 13 ++++++++++++- test cases/cuda/16 multistd/main.cu | 20 ++++++++++++++++++++ test cases/cuda/16 multistd/meson.build | 4 ++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 test cases/cuda/16 multistd/main.cu create mode 100644 test cases/cuda/16 multistd/meson.build diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 0ef92b55b..145b7c8aa 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -617,8 +617,19 @@ class CudaCompiler(Compiler): return opts def _to_host_compiler_options(self, options: 'KeyedOptionDictType') -> 'KeyedOptionDictType': + """ + Convert an NVCC Option set to a host compiler's option set. + """ + + # We must strip the -std option from the host compiler option set, as NVCC has + # its own -std flag that may not agree with the host compiler's. overrides = {name: opt.value for name, opt in options.items()} - return OptionOverrideProxy(overrides, self.host_compiler.get_options()) + overrides.pop(OptionKey('std', machine=self.for_machine, + lang=self.host_compiler.language), None) + host_options = self.host_compiler.get_options().copy() + if 'std' in host_options: + del host_options['std'] # type: ignore + return OptionOverrideProxy(overrides, host_options) def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: args = self.get_ccbin_args(options) diff --git a/test cases/cuda/16 multistd/main.cu b/test cases/cuda/16 multistd/main.cu new file mode 100644 index 000000000..a2ffba489 --- /dev/null +++ b/test cases/cuda/16 multistd/main.cu @@ -0,0 +1,20 @@ +#include +#include + +auto cuda_devices(void) { + int result = 0; + cudaGetDeviceCount(&result); + return result; +} + + +int main(void) { + int n = cuda_devices(); + if (n == 0) { + std::cout << "No Cuda hardware found. Exiting.\n"; + return 0; + } + + std::cout << "Found " << n << "Cuda devices.\n"; + return 0; +} diff --git a/test cases/cuda/16 multistd/meson.build b/test cases/cuda/16 multistd/meson.build new file mode 100644 index 000000000..4769a87dd --- /dev/null +++ b/test cases/cuda/16 multistd/meson.build @@ -0,0 +1,4 @@ +project('C++-CUDA multi-std', 'cpp', 'cuda', version : '1.0.0', default_options : ['cpp_std=c++17', 'cuda_std=c++14']) + +exe = executable('prog', 'main.cu') +test('cudatest', exe)