Repository: spack/spack

Issue:
Mystery MPI implementations due to conflict resolution
### Steps to reproduce

Add an external CUDA 11.6, and default all package variants to `+cuda`:
```yaml
packages:
  cuda:
    buildable: false
    externals:
    - spec: cuda@11.6
      prefix: /usr/local/cuda-11.6
  all:
    variants: +cuda
```

Then try installing `superlu-dist`, which currently conflicts with CUDA 11.5+.

### Error message

```console
$ spack spec -I superlu-dist
Input spec
--------------------------------
 -   superlu-dist

Concretized
--------------------------------
 -   superlu-dist@7.1.1%gcc@8.4.1~cuda~int64~ipo~openmp~rocm+shared build_type=RelWithDebInfo arch=linux-rhel8-haswell
# <snip>
 -           ^spectrum-mpi@10.4%gcc@8.4.1 arch=linux-rhel8-haswell
```

`spectrum-mpi` showed up this time, and `mpt` showed up a previous iteration. Setting `providers: [openmpi]` does nothing.

Neither `mpt` nor `spectrum-mpi` are in the list of providers in the etc/spack file. Should they be? Should they be deleted? Should they `conflict` with systems that don't support them?

### Information on your system

* **Spack:** 0.17.1-970-b700335be7
* **Python:** 3.6.8
* **Platform:** linux-rhel8-haswell
* **Concretizer:** clingo

### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have searched the issues of this repo and believe this is not a duplicate
- [X] I have run the failing commands in debug mode and reported the output
Mystery MPI implementations due to conflict resolution
### Steps to reproduce

Add an external CUDA 11.6, and default all package variants to `+cuda`:
```yaml
packages:
  cuda:
    buildable: false
    externals:
    - spec: cuda@11.6
      prefix: /usr/local/cuda-11.6
  all:
    variants: +cuda
```

Then try installing `superlu-dist`, which currently conflicts with CUDA 11.5+.

### Error message

```console
$ spack spec -I superlu-dist
Input spec
--------------------------------
 -   superlu-dist

Concretized
--------------------------------
 -   superlu-dist@7.1.1%gcc@8.4.1~cuda~int64~ipo~openmp~rocm+shared build_type=RelWithDebInfo arch=linux-rhel8-haswell
# <snip>
 -           ^spectrum-mpi@10.4%gcc@8.4.1 arch=linux-rhel8-haswell
```

`spectrum-mpi` showed up this time, and `mpt` showed up a previous iteration. Setting `providers: [openmpi]` does nothing.

Neither `mpt` nor `spectrum-mpi` are in the list of providers in the etc/spack file. Should they be? Should they be deleted? Should they `conflict` with systems that don't support them?

### Information on your system

* **Spack:** 0.17.1-970-b700335be7
* **Python:** 3.6.8
* **Platform:** linux-rhel8-haswell
* **Concretizer:** clingo

### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have searched the issues of this repo and believe this is not a duplicate
- [X] I have run the failing commands in debug mode and reported the output


Discussion:

Resolving patch:
diff --git a/var/spack/repos/builtin/packages/superlu-dist/package.py b/var/spack/repos/builtin/packages/superlu-dist/package.py
--- a/var/spack/repos/builtin/packages/superlu-dist/package.py
+++ b/var/spack/repos/builtin/packages/superlu-dist/package.py
@@ -53,7 +53,8 @@ class SuperluDist(CMakePackage, CudaPackage, ROCmPackage):
 
     conflicts('+rocm', when='+cuda')
     conflicts('+cuda', when='@:6.3')
-    conflicts('^cuda@11.5.0:', when='@7.1.0:')
+    # See https://github.com/xiaoyeli/superlu_dist/issues/87
+    conflicts('^cuda@11.5.0:', when='@7.1.0:7.1 +cuda')
 
     patch('xl-611.patch', when='@:6.1.1 %xl')
     patch('xl-611.patch', when='@:6.1.1 %xl_r')
@@ -61,59 +62,60 @@ class SuperluDist(CMakePackage, CudaPackage, ROCmPackage):
 
     def cmake_args(self):
         spec = self.spec
-        args = [
-            '-DCMAKE_C_COMPILER=%s' % spec['mpi'].mpicc,
-            '-DCMAKE_CXX_COMPILER=%s' % spec['mpi'].mpicxx,
-            '-DCMAKE_INSTALL_LIBDIR:STRING=%s' % self.prefix.lib,
-            '-DCMAKE_INSTALL_BINDIR:STRING=%s' % self.prefix.bin,
-            '-DTPL_BLAS_LIBRARIES=%s' % spec['blas'].libs.joined(";"),
-            '-DTPL_LAPACK_LIBRARIES=%s' % spec['lapack'].libs.joined(";"),
-            '-DUSE_XSDK_DEFAULTS=YES',
-            '-DTPL_PARMETIS_LIBRARIES=%s' % spec['parmetis'].libs.ld_flags +
-            ';' + spec['metis'].libs.ld_flags,
-            '-DTPL_PARMETIS_INCLUDE_DIRS=%s' %
-            spec['parmetis'].prefix.include +
-            ';' + spec['metis'].prefix.include
-        ]
-
-        if (spec.satisfies('%xl') or spec.satisfies('%xl_r')) and \
-           spec.satisfies('@:6.1.1'):
-            args.append('-DCMAKE_C_FLAGS=-DNoChange')
-
-        if '+int64' in spec:
-            args.append('-DXSDK_INDEX_SIZE=64')
-        else:
-            args.append('-DXSDK_INDEX_SIZE=32')
-
-        if '+openmp' in spec:
-            args.append('-Denable_openmp=ON')
-        else:
-            args.append('-Denable_openmp=OFF')
-            args.append('-DCMAKE_DISABLE_FIND_PACKAGE_OpenMP=ON')
+        cmake_args = []
+
+        def append_define(*args):
+            cmake_args.append(CMakePackage.define(*args))
+
+        def append_from_variant(*args):
+            cmake_args.append(self.define_from_variant(*args))
+
+        append_define('CMAKE_C_COMPILER', spec['mpi'].mpicc)
+        append_define('CMAKE_CXX_COMPILER', spec['mpi'].mpicxx)
+        append_define('CMAKE_INSTALL_LIBDIR:STRING', self.prefix.lib)
+        append_define('CMAKE_INSTALL_BINDIR:STRING', self.prefix.bin)
+        append_define('TPL_BLAS_LIBRARIES', spec['blas'].libs)
+        append_define('TPL_LAPACK_LIBRARIES', spec['lapack'].libs)
+        append_define('USE_XSDK_DEFAULTS', True)
+        append_define('TPL_PARMETIS_LIBRARIES', [
+            spec['parmetis'].libs.ld_flags,
+            spec['metis'].libs.ld_flags
+        ])
+        append_define('TPL_PARMETIS_INCLUDE_DIRS', [
+            spec['parmetis'].prefix.include,
+            spec['metis'].prefix.include
+        ])
+
+        if ((spec.satisfies('%xl') or spec.satisfies('%xl_r'))
+                and spec.satisfies('@:6.1.1')):
+            append_define('CMAKE_C_FLAGS', '-DNoChange')
+
+        append_define('XSDK_INDEX_SIZE', '64' if '+int64' in spec else '32')
+
+        append_from_variant('enable_openmp', 'openmp')
+        if '~openmp' in spec:
+            append_define('CMAKE_DISABLE_FIND_PACKAGE_OpenMP', True)
 
         if '+cuda' in spec:
-            args.append('-DTPL_ENABLE_CUDALIB=TRUE')
-            args.append('-DTPL_CUDA_LIBRARIES=-L%s -lcublas -lcudart'
-                        % spec['cuda'].libs.directories[0])
+            append_define('TPL_ENABLE_CUDALIB', True)
+            append_define(
+                'TPL_CUDA_LIBRARIES',
+                '-L%s -lcublas -lcudart' % spec['cuda'].libs.directories[0]
+            )
             cuda_arch = spec.variants['cuda_arch'].value
             if cuda_arch[0] != 'none':
-                args.append(
-                    '-DCMAKE_CUDA_FLAGS=-arch=sm_{0}'.format(cuda_arch[0]))
+                append_define('CMAKE_CUDA_FLAGS', '-arch=sm_' + cuda_arch[0])
 
         if '+rocm' in spec and spec.satisfies('@amd'):
-            args.append('-DTPL_ENABLE_HIPLIB=TRUE')
-            args.append(
-                '-DHIP_ROOT_DIR={0}'.format(spec['hip'].prefix))
+            append_define('TPL_ENABLE_HIPLIB', True)
+            append_define('HIP_ROOT_DIR', spec['hip'].prefix)
             rocm_archs = spec.variants['amdgpu_target'].value
             if 'none' not in rocm_archs:
-                args.append('-DHIP_HIPCC_FLAGS=--amdgpu-target={0}'.
-                            format(",".join(rocm_archs)))
-
-        if '+shared' in spec:
-            args.append('-DBUILD_SHARED_LIBS:BOOL=ON')
-        else:
-            args.append('-DBUILD_SHARED_LIBS:BOOL=OFF')
-        return args
+                append_define('HIP_HIPCC_FLAGS',
+                              '--amdgpu-target=' + ",".join(rocm_archs))
+
+        append_from_variant('BUILD_SHARED_LIBS', 'shared')
+        return cmake_args
 
     def flag_handler(self, name, flags):
         flags = list(flags)


Test patch: