Repository: spack/spack

Issue:
make variants in CudaPackage optional
I am not sure if there is a way to make variants optional or conditional but that would be nice to have for the CudaPackage class. That class provides conflicts management for cuda and compilers, which makes it very useful to include. However, it also includes two variants, `cuda` and `cuda_arch` that are not necessarily needed for all cuda enabled packages. For instance, a package that requires CUDA can use CudaPackage to take advantage of the compiler conflicts statements. However, if the package requires CUDA then the `cuda` variant does not make sense. That leads to needing another conflict statement in the package itself. See the `gpu-burn` package for an example.
```
class GpuBurn(MakefilePackage, CudaPackage):
...
    # This package uses CudaPackage to pick up the cuda_arch variant. A side
    # effect is that it also picks up the cuda variant, but cuda is required
    # for gpu-burn so is not really a variant.
    variant('cuda', 'True', description='Use CUDA; must be true')

    conflicts('~cuda', msg='gpu-burn requires cuda')
...
```
In the above case, the compiler conflicts statements and the `cpu_arch` variant are needed but not the `cuda` variant. 


Discussion:
Relates to #9740 (though it's not a perfect duplicate). I think this can be enabled after the new concretizer will be merged.

Resolving patch:
diff --git a/lib/spack/spack/build_systems/cuda.py b/lib/spack/spack/build_systems/cuda.py
--- a/lib/spack/spack/build_systems/cuda.py
+++ b/lib/spack/spack/build_systems/cuda.py
@@ -35,7 +35,8 @@ class CudaPackage(PackageBase):
 
     variant('cuda_arch',
             description='CUDA architecture',
-            values=spack.variant.any_combination_of(*cuda_arch_values))
+            values=spack.variant.any_combination_of(*cuda_arch_values),
+            when='+cuda')
 
     # https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#nvcc-examples
     # https://llvm.org/docs/CompileCudaWithLLVM.html#compiling-cuda-code
diff --git a/lib/spack/spack/build_systems/rocm.py b/lib/spack/spack/build_systems/rocm.py
--- a/lib/spack/spack/build_systems/rocm.py
+++ b/lib/spack/spack/build_systems/rocm.py
@@ -100,7 +100,8 @@ class ROCmPackage(PackageBase):
     # possible amd gpu targets for rocm builds
     variant('amdgpu_target',
             description='AMD GPU architecture',
-            values=spack.variant.any_combination_of(*amdgpu_targets))
+            values=spack.variant.any_combination_of(*amdgpu_targets),
+            when='+rocm')
 
     depends_on('llvm-amdgpu', when='+rocm')
     depends_on('hsa-rocr-dev', when='+rocm')
diff --git a/var/spack/repos/builtin/packages/cp2k/package.py b/var/spack/repos/builtin/packages/cp2k/package.py
--- a/var/spack/repos/builtin/packages/cp2k/package.py
+++ b/var/spack/repos/builtin/packages/cp2k/package.py
@@ -53,14 +53,15 @@ class Cp2k(MakefilePackage, CudaPackage):
                          ' and BQB compression'))
     variant('spglib', default=False, description='Enable support for spglib')
 
-    variant('cuda_arch_35_k20x', default=False,
-            description=('CP2K (resp. DBCSR) has specific parameter sets for'
-                         ' different GPU models. Enable this when building'
-                         ' with cuda_arch=35 for a K20x instead of a K40'))
-    variant('cuda_fft', default=False,
-            description=('Use CUDA also for FFTs in the PW part of CP2K'))
-    variant('cuda_blas', default=False,
-            description=('Use CUBLAS for general matrix operations in DBCSR'))
+    with when('+cuda'):
+        variant('cuda_arch_35_k20x', default=False,
+                description=('CP2K (resp. DBCSR) has specific parameter sets for'
+                             ' different GPU models. Enable this when building'
+                             ' with cuda_arch=35 for a K20x instead of a K40'))
+        variant('cuda_fft', default=False,
+                description=('Use CUDA also for FFTs in the PW part of CP2K'))
+        variant('cuda_blas', default=False,
+                description=('Use CUBLAS for general matrix operations in DBCSR'))
 
     HFX_LMAX_RANGE = range(4, 8)
 
@@ -167,8 +168,6 @@ class Cp2k(MakefilePackage, CudaPackage):
     depends_on('python@3.6:', when='@7:+cuda', type='build')
 
     depends_on('spglib', when='+spglib')
-    conflicts('~cuda', '+cuda_fft')
-    conflicts('~cuda', '+cuda_blas')
 
     # Apparently cp2k@4.1 needs an "experimental" version of libwannier.a
     # which is only available contacting the developer directly. See INSTALL


Test patch: