Repository: spack/spack

Issue:
%nvhpc does not respect micro arch target
### Steps to reproduce

nvhpc seems to default to host native compilation :(.

```
$ spack build-env zlib %nvhpc -- cc -v main.c |& grep native
/home/hstoppel/spack/opt/spack/linux-ubuntu21.04-skylake/gcc-10.3.0/nvhpc-22.3-xkgbf2eo655wbnkhwe6wmbfe2vetn6ch/Linux_x86_64/22.3/compilers/share/llvm/bin/llc /tmp/nvcB7WybrdeDNH3i.ll -march=x86-64 -mcpu=native -mattr=+mmx -mattr=+sse -mattr=+sse2 -mattr=+sse3 -mattr=+ssse3 -mattr=+sse4.1 -mattr=+sse4.2 -mattr=+avx -mattr=+avx2 -mattr=+f16c -mattr=+fma -mattr=+xsave -mattr=+xsaveopt -mattr=+xsavec -mattr=+xsaves -mattr=+popcnt -mattr=+aes -mattr=+pclmul -mattr=+clflushopt -mattr=+fsgsbase -mattr=+rdrnd -mattr=+bmi -mattr=+bmi2 -mattr=+lzcnt -mattr=+fxsr -O1 -fast-isel=0 -non-global-value-max-name-size=4294967295 -x86-cmov-converter=0 -dwarf-directory=false --align-all-functions=6 --frame-pointer=none -o /tmp/nvcZ7WybzDe-eS2q.s

$ spack build-env zlib target=x86_64 %nvhpc -- cc -v main.c |& grep native
/home/hstoppel/spack/opt/spack/linux-ubuntu21.04-skylake/gcc-10.3.0/nvhpc-22.3-xkgbf2eo655wbnkhwe6wmbfe2vetn6ch/Linux_x86_64/22.3/compilers/share/llvm/bin/llc /tmp/nvcJQXybPupwVvCi.ll -march=x86-64 -mcpu=native -mattr=+mmx -mattr=+sse -mattr=+sse2 -mattr=+sse3 -mattr=+ssse3 -mattr=+sse4.1 -mattr=+sse4.2 -mattr=+avx -mattr=+avx2 -mattr=+f16c -mattr=+fma -mattr=+xsave -mattr=+xsaveopt -mattr=+xsavec -mattr=+xsaves -mattr=+popcnt -mattr=+aes -mattr=+pclmul -mattr=+clflushopt -mattr=+fsgsbase -mattr=+rdrnd -mattr=+bmi -mattr=+bmi2 -mattr=+lzcnt -mattr=+fxsr -O1 -fast-isel=0 -non-global-value-max-name-size=4294967295 -x86-cmov-converter=0 -dwarf-directory=false --align-all-functions=6 --frame-pointer=none -o /tmp/nvc7QXybX5PfCzSP.s
```

It should respect the `target` from the spec:

```
$ spack spec zlib target=x86_64 %nvhpc 
zlib@1.2.12%nvhpc@22.3+optimize+pic+shared patches=0d38234 arch=linux-ubuntu21.04-x86_64
```

(Reported by @teojgo)

fix mcpu flags for gcc on neoverse-v1
`-mcpu=neoverse-v1` flag is not recognized until GCC 11.1. For GCC 10.2 onward there is an alias `-mcpu=zeus`.
See https://gcc.gnu.org/releases.html for the release timeline.


Discussion:
Correct.  The documented default is host native.  Use `-tp` to select the target processor.

Seems like the resolution would be supporting nvhpc in archspec.
I think @alalazo can best comment on what is necessary to make that work.

```
$ nvc --help | grep tp
-march=<arg>        Select target processor. Alias for -tp
                    Implies -tp
-tp=px|bulldozer|piledriver|zen|zen2|zen3|sandybridge|haswell|skylake|host|native
```

Would be good to get this to work, since we're facing issues where the build system has a different micro arch than the target system.
@samcmill @haampie I'll try to fix this asap. Can you point me to:
1. Which flags need to be used for which architectures (if we can use the same flags as GCC just let me know)
2. Restrictions depending on the versions of `nvhpc` (e.g. `icelake` is supported starting from version X)
```
$ nvc -help -tp
-tp=px|bulldozer|piledriver|zen|zen2|zen3|sandybridge|haswell|skylake|host|native
                    Select target processor
    px              Generic Linux/Windows x86_64 Processor.
    bulldozer       AMD Bulldozer processor
    piledriver      AMD Piledriver processor
    zen             AMD Zen architecture (Epyc, Ryzen)
    zen2            AMD Zen 2 architecture (Ryzen 2)
    zen3            AMD Zen 3 architecture (Ryzen 3)
    sandybridge     Intel SandyBridge processor
    haswell         Intel Haswell processor
    skylake         Intel Skylake Xeon processor
    host            Link native version of HPC SDK cpu math library
    native          Alias for -tp host
```

```
$ nvc -help -tp
-tp=pwr8|pwr9|host|native
                    Select target processor
    pwr8            Power8 Processor
    pwr9            Power9 Processor
    host            Link native version of HPC SDK cpu math library
    native          Alias for -tp host
```

```
$ nvc -help -tp
-tp=host|native|neoverse-n1
                    Select target processor
    host            Link native version of HPC SDK cpu math library
    native          Alias for -tp host
    neoverse-n1     Arm Neoverse N1 architecture
```

The `zen3` architecture was added in version 21.11.  

The `knl` architecture was dropped in 21.9.

`-march` is an alias for `-tp`, but it does not use the same architecture values as gcc.
See https://github.com/archspec/archspec-json/pull/67 (previously https://github.com/archspec/archspec-json/pull/66 and https://github.com/archspec/archspec-json/pull/52)
Thanks! Could you first open a PR here? https://github.com/archspec/archspec it's synced every now and then with Spack.
@haampie Do you mean the `microarchitectures.json` in `archspec/archspec-json` ? I will need to get internal permission to contribute to that project first. 
@annop-w Yes, it's that project. For what is worth, the file you modified is a vendored version of the one in https://github.com/archspec/archspec-json and the licensing is the same as Spack. In fact, the `archspec` project effectively grew out of Spack :slightly_smiling_face: 
@annop-w because you said you will need to get internal permission to contribute to that project first, I've checked your changes:

I've found that -mcpu=neoverse-v1 was already added with gcc-10.3:
https://gcc.gnu.org/onlinedocs/gcc-10.3.0/gcc/AArch64-Options.html#AArch64-Options

So I think that the commit should be like this:

gcc-10.2 added -mcpu=zeus for neoverse-v1 platform
and -mcpu=neoverse-v1 was added with gcc-9.4, gcc-10.3 and gcc-11.0.

I submitted this update to your changes here: https://github.com/archspec/archspec-json/pull/64

I hope you agree, Bernhard
@alalazo Now that https://github.com/archspec/archspec-json/pull/64 is merged. Do we need this PR ? or the file will be automatically synced from archspec-json ? 
I need to submit a new PR to update archspec in Spack. I am waiting to see if we can speed-up a bit https://github.com/archspec/archspec-json/pull/66 and do a single update in Spack with `neoverse-v1` and `nvhpc`

Resolving patch:
diff --git a/lib/spack/external/__init__.py b/lib/spack/external/__init__.py
--- a/lib/spack/external/__init__.py
+++ b/lib/spack/external/__init__.py
@@ -18,7 +18,7 @@
 
 * Homepage: https://pypi.python.org/pypi/archspec
 * Usage: Labeling, comparison and detection of microarchitectures
-* Version: 0.2.0-dev (commit f3667f95030c6573842fb5f6df0d647285597509)
+* Version: 0.2.0-dev (commit d02dadbac4fa8f3a60293c4fbfd59feadaf546dc)
 
 astunparse
 ----------------
diff --git a/lib/spack/external/archspec/__main__.py b/lib/spack/external/archspec/__main__.py
new file mode 100644
--- /dev/null
+++ b/lib/spack/external/archspec/__main__.py
@@ -0,0 +1,8 @@
+"""
+Run the `archspec` CLI as a module.
+"""
+
+import sys
+from .cli import main
+
+sys.exit(main())
diff --git a/lib/spack/external/archspec/cpu/microarchitecture.py b/lib/spack/external/archspec/cpu/microarchitecture.py
--- a/lib/spack/external/archspec/cpu/microarchitecture.py
+++ b/lib/spack/external/archspec/cpu/microarchitecture.py
@@ -268,15 +268,14 @@ def tuplify(ver):
                 return flags
 
         msg = (
-            "cannot produce optimized binary for micro-architecture '{0}'"
-            " with {1}@{2} [supported compiler versions are {3}]"
-        )
-        msg = msg.format(
-            self.name,
-            compiler,
-            version,
-            ", ".join([x["versions"] for x in compiler_info]),
+            "cannot produce optimized binary for micro-architecture '{0}' with {1}@{2}"
         )
+        if compiler_info:
+            versions = [x["versions"] for x in compiler_info]
+            msg += f' [supported compiler versions are {", ".join(versions)}]'
+        else:
+            msg += " [no supported compiler versions]"
+        msg = msg.format(self.name, compiler, version)
         raise UnsupportedMicroarchitecture(msg)
 
 


Test patch: