Repository: spack/spack

Issue:
zen vs zen2 inconsitency breaks modules() in spack load
After having some problem with the latest release, I was trying the current develop 66b9009a0713f9ce1d63f518ab1528af7587eaa5 branch.

However, on develop, there seems to be an inconsistency with the architecture, that prohibits the use of `modules`. As a consequence, `spack load` does not work anymore. The issue is related to my architecture, Ubuntu 19.04 with kernel 5.3.0-050300rc3-generic, running on a Ryzen 3900X processor. I did not have the issue with a previous commit from the develop branch from one or two months ago. At that time my architecture was recognized as `linux-ubuntu19.04-x86_64`.

### Steps to reproduce the issue

I started with a fresh clone and did the bootstrapping. The first use of `spack load` fails
```console
$ git clone https://github.com/spack/spack.git
$ export SPACK_ROOT=/opt/spack
$ export PATH=$SPACK_ROOT/bin:$PATH
$ source $SPACK_ROOT/share/spack/setup-env.sh
$ export SPACK_SHELL="bash"
$ export EDITOR="vim"
$ spack bootstrap
...
$ spack load tcl
module: command not found
```

### Error Message

`module` should be a bash function, which it isn't here.
```console
$ type module
-bash: type: module: not found
$ spack find
==> 3 installed packages
-- linux-ubuntu19.04-zen / gcc@8.3.0 ----------------------------
environment-modules@4.3.1  tcl@8.6.8  zlib@1.2.11
$ spack --print-shell-vars modules
_sp_sys_type='linux-ubuntu19.04-zen2'
_sp_compatible_sys_types='linux-ubuntu19.04-zen2:linux-ubuntu19.04-zen:linux-ubuntu19.04-x86_64'
_sp_tcl_roots='/opt/spack/share/spack/modules'
_sp_lmod_roots='/opt/spack/share/spack/lmod'
_sp_module_prefix='not_installed'
```
It is notable, that `find` shows the architecture as `zen`, whereas `--print-shell-vars modules` shows the architecture as `zen2`. 'not_installed' is the result of this inconsistency and breaks `spack load`.

Checking the difference in `main.py` reveals:
```python
print('specs=%s' % spack.store.db.query('environment-modules arch=linux-ubuntu19.04-zen'))
>> specs=[environment-modules@4.3.1%gcc@8.3.0~X arch=linux-ubuntu19.04-zen ^tcl@8.6.8%gcc@8.3.0 arch=linux-ubuntu19.04-zen ^zlib@1.2.11%gcc@8.3.0+optimize+pic+shared arch=linux-ubuntu19.04-zen]
```
```python
print('specs=%s' % spack.store.db.query('environment-modules arch=linux-ubuntu19.04-zen2'))
>> specs=[]
```
The latter happens in my case. The architecture is checked since e5b86c5527c458df7434c499842d659dd086b7f8 and microarchitectures are available since 3c4322bf1abb7af691179434652188b64e90e4dc.

I don't know where the decision about the architecture is made but the inconsistency, that I have shown, prevents `spack load` from working.


Discussion:
@bassenj Did you try to source again `setup-env.sh` after having bootstrapped `tcl` and `environment-modules`? Asking because when you source this file the paths in:
```console
${_sp_tcl_roots}/linux-ubuntu19.04-zen2
${_sp_tcl_roots}/linux-ubuntu19.04-zen
${_sp_tcl_roots}/linux-ubuntu19.04-x86_64
```
are checked and all the existing ones are added to `MODULEPATH`. The very first time you clone spack none of them exist yet and that requires sourcing the file again. Just wondering if this is your issue, or something else.
Yes, my regular script sources `setup-env.sh` again after bootstrapping.

Resolving patch:
diff --git a/lib/spack/spack/cmd/bootstrap.py b/lib/spack/spack/cmd/bootstrap.py
--- a/lib/spack/spack/cmd/bootstrap.py
+++ b/lib/spack/spack/cmd/bootstrap.py
@@ -3,6 +3,7 @@
 #
 # SPDX-License-Identifier: (Apache-2.0 OR MIT)
 
+import llnl.util.cpu
 import llnl.util.tty as tty
 
 import spack.repo
@@ -52,7 +53,12 @@ def bootstrap(parser, args, **kwargs):
     # Define requirement dictionary defining general specs which need
     # to be satisfied, and the specs to install when the general spec
     # isn't satisfied.
-    requirement_dict = {'environment-modules': 'environment-modules~X'}
+    requirement_dict = {
+        # Install environment-modules with generic optimizations
+        'environment-modules': 'environment-modules~X target={0}'.format(
+            llnl.util.cpu.host().family
+        )
+    }
 
     for requirement in requirement_dict:
         installed_specs = spack.store.db.query(requirement)
diff --git a/lib/spack/spack/main.py b/lib/spack/spack/main.py
--- a/lib/spack/spack/main.py
+++ b/lib/spack/spack/main.py
@@ -20,6 +20,7 @@
 import warnings
 from six import StringIO
 
+import llnl.util.cpu
 import llnl.util.tty as tty
 import llnl.util.tty.color as color
 from llnl.util.tty.log import log_output
@@ -621,8 +622,9 @@ def shell_set(var, value):
     # print environment module system if available. This can be expensive
     # on clusters, so skip it if not needed.
     if 'modules' in info:
-        specs = spack.store.db.query(
-            'environment-modules arch=%s' % spack.architecture.sys_type())
+        generic_arch = llnl.util.cpu.host().family
+        module_spec = 'environment-modules target={0}'.format(generic_arch)
+        specs = spack.store.db.query(module_spec)
         if specs:
             shell_set('_sp_module_prefix', specs[-1].prefix)
         else:


Test patch: