Repository: spack/spack

Issue:
Abinit: invalid spec on concretization
Reproducible on a fresh clone of spack:
```console
$ git branch -v
* develop 7e9777f Add latest version of pkg-config (#3672)

$ spack spec abinit+scalapack
Input spec
--------------------------------
abinit+scalapack

Normalized
--------------------------------
abinit+scalapack
    ^blas
    ^lapack
    ^libxc@2.2.1

Concretized
--------------------------------
==> Error: Invalid spec: 'netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config'. Package netlib-scalapack requires dependency netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config, but spec asked for netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config
```
I may be seeing that wrong, but the specs in the error message seem all equal to me.

Abinit: invalid spec on concretization
Reproducible on a fresh clone of spack:
```console
$ git branch -v
* develop 7e9777f Add latest version of pkg-config (#3672)

$ spack spec abinit+scalapack
Input spec
--------------------------------
abinit+scalapack

Normalized
--------------------------------
abinit+scalapack
    ^blas
    ^lapack
    ^libxc@2.2.1

Concretized
--------------------------------
==> Error: Invalid spec: 'netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config'. Package netlib-scalapack requires dependency netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config, but spec asked for netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config
```
I may be seeing that wrong, but the specs in the error message seem all equal to me.



Discussion:
They definitely are the same, I just ran `diff` on the output. I'm not sure what the cause is, but this may have been introduced when I set `netlib-scalapack` as the default `scalapack` provider in #3634.
Whatever it is, #3634 may have uncovered a bug but is definitely not the cause of it.
Reproducible with every package that depends on `scalapack`.
Possible cause? If I comment out all of the virtual dependencies from `netlib-scalapack`, things work again. Are we testing to see if virtual dependencies are allowed to depend on other virtual dependencies?
> Reproducible with every package that depends on scalapack.

Wow, that's unfortunate.


@adamjstewart Nice catch! I think we are not, and given the current state of things `scalapack` is the only virtual dependency which has this requirement. This may be worth an `xfail` test. I'll see if I can code something tomorrow. Of course you are welcome to take advantage of your time zone and beat me to it :smile: 
More insight. Current stack-frame
```console
satisfies, spec.py:2184
satisfies_dependency, spec.py:2281
...
```
it seems we are comparing an `openmpi` that is not concrete (`self`) with one that is instead concrete (`other`). Apart from that the dependencies match.

In `satisfy_dependency, spec.py` we have an inconsistency:
```python
In[1]: self
Out[2]: netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config
In[2]: self.concrete
Out[3]: True
In[3]: self['openmpi'].concrete
Out[4]: False
```
which brings me closer to the solution:
```python
In[5]: other
Out[6]: netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config
In[6]: other['openmpi'].concrete
Out[7]: True
In[7]: a = other.copy()
In[8]: a['openmpi'].concrete
Out[9]: False
```
@adamjstewart After further testing it seems it's the `mpi` that causes the problem here. Specifying the package you want is a workaround to help the concretizer do its job:
```console
$ spack  spec abinit+scalapack+mpi ^ openmpi
Input spec
--------------------------------
abinit+mpi+scalapack
    ^openmpi

Normalized
--------------------------------
abinit+mpi+scalapack
    ^blas
    ^lapack
    ^libxc@2.2.2
    ^openmpi
        ^hwloc
            ^pkg-config
    ^scalapack

Concretized
--------------------------------
abinit@8.0.8b%gcc@4.8~hdf5+mpi~openmp+scalapack arch=linux-ubuntu14-x86_64 
    ^fftw@3.3.6-pl2%gcc@4.8+double+float+long_double+mpi~openmp~pfft_patches~quad arch=linux-ubuntu14-x86_64 
        ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 
            ^hwloc@1.11.6%gcc@4.8~cuda+libxml2+pci arch=linux-ubuntu14-x86_64 
                ^libpciaccess@0.13.4%gcc@4.8 arch=linux-ubuntu14-x86_64 
                    ^libtool@2.4.6%gcc@4.8 arch=linux-ubuntu14-x86_64 
                        ^m4@1.4.18%gcc@4.8+sigsegv arch=linux-ubuntu14-x86_64 
                            ^libsigsegv@2.11%gcc@4.8 arch=linux-ubuntu14-x86_64 
                    ^pkg-config@0.29.1%gcc@4.8+internal_glib arch=linux-ubuntu14-x86_64 
                    ^util-macros@1.19.1%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^libxml2@2.9.4%gcc@4.8~python arch=linux-ubuntu14-x86_64 
                    ^xz@5.2.3%gcc@4.8 arch=linux-ubuntu14-x86_64 
                    ^zlib@1.2.11%gcc@4.8+pic+shared arch=linux-ubuntu14-x86_64 
    ^libxc@2.2.2%gcc@4.8 arch=linux-ubuntu14-x86_64 
    ^netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 
        ^cmake@3.7.2%gcc@4.8~doc+ncurses+openssl+ownlibs~qt arch=linux-ubuntu14-x86_64 
            ^ncurses@6.0%gcc@4.8~symlinks arch=linux-ubuntu14-x86_64 
                ^mawk@1.3.4%gcc@4.8 arch=linux-ubuntu14-x86_64 
            ^openssl@1.0.2k%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^perl@5.24.1%gcc@4.8+cpanm arch=linux-ubuntu14-x86_64 
        ^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 

$ spack  spec abinit+scalapack+mpi 
Input spec
--------------------------------
abinit+mpi+scalapack

Normalized
--------------------------------
abinit+mpi+scalapack
    ^blas
    ^lapack
    ^libxc@2.2.2
    ^mpi@2:
    ^scalapack

Concretized
--------------------------------
==> Error: Invalid spec: 'netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config'. Package netlib-scalapack requires dependency netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config, but spec asked for netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config
```


They definitely are the same, I just ran `diff` on the output. I'm not sure what the cause is, but this may have been introduced when I set `netlib-scalapack` as the default `scalapack` provider in #3634.
Whatever it is, #3634 may have uncovered a bug but is definitely not the cause of it.
Reproducible with every package that depends on `scalapack`.
Possible cause? If I comment out all of the virtual dependencies from `netlib-scalapack`, things work again. Are we testing to see if virtual dependencies are allowed to depend on other virtual dependencies?
> Reproducible with every package that depends on scalapack.

Wow, that's unfortunate.


@adamjstewart Nice catch! I think we are not, and given the current state of things `scalapack` is the only virtual dependency which has this requirement. This may be worth an `xfail` test. I'll see if I can code something tomorrow. Of course you are welcome to take advantage of your time zone and beat me to it :smile: 
More insight. Current stack-frame
```console
satisfies, spec.py:2184
satisfies_dependency, spec.py:2281
...
```
it seems we are comparing an `openmpi` that is not concrete (`self`) with one that is instead concrete (`other`). Apart from that the dependencies match.

In `satisfy_dependency, spec.py` we have an inconsistency:
```python
In[1]: self
Out[2]: netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config
In[2]: self.concrete
Out[3]: True
In[3]: self['openmpi'].concrete
Out[4]: False
```
which brings me closer to the solution:
```python
In[5]: other
Out[6]: netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config
In[6]: other['openmpi'].concrete
Out[7]: True
In[7]: a = other.copy()
In[8]: a['openmpi'].concrete
Out[9]: False
```
@adamjstewart After further testing it seems it's the `mpi` that causes the problem here. Specifying the package you want is a workaround to help the concretizer do its job:
```console
$ spack  spec abinit+scalapack+mpi ^ openmpi
Input spec
--------------------------------
abinit+mpi+scalapack
    ^openmpi

Normalized
--------------------------------
abinit+mpi+scalapack
    ^blas
    ^lapack
    ^libxc@2.2.2
    ^openmpi
        ^hwloc
            ^pkg-config
    ^scalapack

Concretized
--------------------------------
abinit@8.0.8b%gcc@4.8~hdf5+mpi~openmp+scalapack arch=linux-ubuntu14-x86_64 
    ^fftw@3.3.6-pl2%gcc@4.8+double+float+long_double+mpi~openmp~pfft_patches~quad arch=linux-ubuntu14-x86_64 
        ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 
            ^hwloc@1.11.6%gcc@4.8~cuda+libxml2+pci arch=linux-ubuntu14-x86_64 
                ^libpciaccess@0.13.4%gcc@4.8 arch=linux-ubuntu14-x86_64 
                    ^libtool@2.4.6%gcc@4.8 arch=linux-ubuntu14-x86_64 
                        ^m4@1.4.18%gcc@4.8+sigsegv arch=linux-ubuntu14-x86_64 
                            ^libsigsegv@2.11%gcc@4.8 arch=linux-ubuntu14-x86_64 
                    ^pkg-config@0.29.1%gcc@4.8+internal_glib arch=linux-ubuntu14-x86_64 
                    ^util-macros@1.19.1%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^libxml2@2.9.4%gcc@4.8~python arch=linux-ubuntu14-x86_64 
                    ^xz@5.2.3%gcc@4.8 arch=linux-ubuntu14-x86_64 
                    ^zlib@1.2.11%gcc@4.8+pic+shared arch=linux-ubuntu14-x86_64 
    ^libxc@2.2.2%gcc@4.8 arch=linux-ubuntu14-x86_64 
    ^netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 
        ^cmake@3.7.2%gcc@4.8~doc+ncurses+openssl+ownlibs~qt arch=linux-ubuntu14-x86_64 
            ^ncurses@6.0%gcc@4.8~symlinks arch=linux-ubuntu14-x86_64 
                ^mawk@1.3.4%gcc@4.8 arch=linux-ubuntu14-x86_64 
            ^openssl@1.0.2k%gcc@4.8 arch=linux-ubuntu14-x86_64 
                ^perl@5.24.1%gcc@4.8+cpanm arch=linux-ubuntu14-x86_64 
        ^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 

$ spack  spec abinit+scalapack+mpi 
Input spec
--------------------------------
abinit+mpi+scalapack

Normalized
--------------------------------
abinit+mpi+scalapack
    ^blas
    ^lapack
    ^libxc@2.2.2
    ^mpi@2:
    ^scalapack

Concretized
--------------------------------
==> Error: Invalid spec: 'netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config'. Package netlib-scalapack requires dependency netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config, but spec asked for netlib-scalapack@2.0.2%gcc@4.8~fpic+shared arch=linux-ubuntu14-x86_64 ^cmake^hwloc^openblas@0.2.19%gcc@4.8~openmp+pic+shared arch=linux-ubuntu14-x86_64 ^openmpi@2.1.0%gcc@4.8~java~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm~verbs+vt arch=linux-ubuntu14-x86_64 ^pkg-config
```



Resolving patch:
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -2248,7 +2248,7 @@ def satisfies(self, other, deps=True, strict=False, strict_deps=False):
         # If we need to descend into dependencies, do it, otherwise we're done.
         if deps:
             deps_strict = strict
-            if self.concrete and not other.name:
+            if self._concrete and not other.name:
                 # We're dealing with existing specs
                 deps_strict = True
             return self.satisfies_dependencies(other, strict=deps_strict)


Test patch: