snl-atdm-issue
While trying to use spack install on a rhel6 machine with haswell processors, spack correctly identifies the -march option as core-avx2 but the default gcc version on rhel6 (gcc-4.4.7) does not recognize that as a valid -march option
$ cat /etc/redhat-release
Red Hat Enterprise Linux Workstation release 6.9 (Santiago)
$ which g++
/usr/bin/g++
$ g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -o hello hello.cpp -march=core-avx2
hello.cpp:1: error: bad value (core-avx2) for -march= switch
hello.cpp:1: error: bad value (core-avx2) for -mtune= switch
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... /home/rabartl/Spack.base3/atdm-spack/spack/lib/spack/env/gcc/gcc
checking whether the C compiler works... no
configure: error: in `/tmp/rabartl/spack-stage/spack-stage-libsigsegv-2.12-4wg47p4nrbuzpsovsxhbypwtbcu25k4t/spack-src':
configure: error: C compiler cannot create executables
See `config.log' for more details
...
config.log shows:
configure:3283: checking whether the C compiler works
configure:3305: /home/rabartl/Spack.base3/atdm-spack/spack/lib/spack/env/gcc/gcc conftest.c >&5
conftest.c:1: error: bad value (core-avx2) for -march= switch
conftest.c:1: error: bad value (core-avx2) for -mtune= switch
@fryeguy52 Can you please check if #13362 fixes your issue? I particular can you post the result of:
$ spack arch
$ spack spec zlib %[email protected]
?
Just merged in v0.13.0 to our local branch. The updated code gives:
$ ./atdm-spack/spack/bin/spack arch
linux-rhel6-broadwell
but when installing using:
# Spack env file to build a compiler using Spack
#
# NOTE: Spack will not only read this file but will also write to it so make
# sure you create a copy before spack uses it!
#
spack:
# Packages to build (ordered mostly by dependencies)
specs: [
[email protected] arch=linux-rhel6-broadwell,
]
modules:
tcl:
hash_length: 0
naming_scheme: spack-${PACKAGE}/${VERSION}
whitelist:
- gcc
blacklist:
- '%[email protected]'
all:
conflict:
- '{name}'
filter:
environment_blacklist: [CPATH, LIBRARY_PATH]
environment:
set:
${PACKAGE}_ROOT: ${PREFIX}
verbose: false
packages:
all:
compiler: [[email protected]]
include:
- packages_tools_for_compiler_build.yaml
- common_options.yaml
with:
./atdm-spack/spack/bin/spack install
it shows:
==> Concretized [email protected]
- bq3tfou [email protected]%[email protected]~binutils languages=c,c++,fortran ~nvptx patches=51aebe82afc9a0433ca3503a36592edf5ca769b1433986919cfb9ae2ddf3e343 ~piclibs~strip arch=linux-rhel6-haswell
- gbuqqio ^[email protected]%[email protected] arch=linux-rhel6-haswell
- yw3nhqg ^[email protected]%[email protected] arch=linux-rhel6-haswell
- vfy645g ^[email protected]%[email protected] patches=3877ab548f88597ab2327a2230ee048d2d07ace1062efe81fc92e91b7f39cd00,fc9b61654a3ba1a8d6cd78ce087e7c96366c290bc8d2c299f09828d793b853c8 +sigsegv arch=linux-rhel6-haswell
[+] 5cjvint ^[email protected]%[email protected] arch=linux-rhel6-haswell
- svdyfxm ^[email protected]%[email protected]+cpanm+shared+threads arch=linux-rhel6-haswell
- 5oybdwq ^[email protected]%[email protected] arch=linux-rhel6-haswell
- qbng4dd ^[email protected]%[email protected] arch=linux-rhel6-haswell
- y42pycm ^[email protected]%[email protected]~symlinks~termlib arch=linux-rhel6-haswell
- jwyexez ^[email protected]%[email protected] arch=linux-rhel6-haswell
- xdsocq2 ^[email protected]%[email protected] arch=linux-rhel6-haswell
- xglf55w ^[email protected]%[email protected] arch=linux-rhel6-haswell
- afketd2 ^[email protected]%[email protected] arch=linux-rhel6-haswell
- 5bnd3rv ^[email protected]%[email protected] arch=linux-rhel6-haswell
- j7g53wx ^[email protected]%[email protected] arch=linux-rhel6-haswell
- ldddpk3 ^[email protected]%[email protected] patches=66a5d58364113a21405fc53f4a48f4e8 arch=linux-rhel6-haswell
- cjsj4t2 ^[email protected]%[email protected]+optimize+pic+shared arch=linux-rhel6-haswell
See, the arch is different! The command spack arch returns linux-rhel6-broadwell but running spack install uses the arch of linux-rhel6-haswell. Show is that?
That completely breaks the logic in out driver tool that requires that spack arch gives the same arch that is used by spack install.
Can we get a fix for this on the 0.13 branch?
Re-opening this issue.
@alalazo: just FYI, I added this to 0.13.1
@becker33: FYI
@bartlettroscoe I would close this again as this is expected and documented here on the same exact case.
You are using [email protected] which does not support building software that is optimized for broadwell (support starts from v 4.9). Therefore Spack chooses the next best fit to your broadwell microarchitecture that is also known to [email protected]. This happens to be haswell.
@bartlettroscoe Wondering if you think this should be a case entering into #13482
You are using [email protected] which does not support building software that is optimized for broadwell (support starts from v 4.9).
@alalazo, sorry that was a mistake on my part. I forgot to wiping the env before running raw spack.
Here is the error again ...
On a RHEL6 machine with the raw system compiler:
$ which gcc
/usr/bin/gcc
$ gcc --version
gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
using the files:
# Spack env file to build a compiler using Spack
#
# NOTE: Spack will not only read this file but will also write to it so make
# sure you create a copy before spack uses it!
#
spack:
# Packages to build (ordered mostly by dependencies)
specs: [
[email protected],
]
modules:
tcl:
hash_length: 0
naming_scheme: spack-${PACKAGE}/${VERSION}
whitelist:
- gcc
blacklist:
- '%[email protected]'
all:
conflict:
- '{name}'
filter:
environment_blacklist: [CPATH, LIBRARY_PATH]
environment:
set:
${PACKAGE}_ROOT: ${PREFIX}
verbose: false
packages:
all:
compiler: [[email protected]]
include:
- packages_tools_for_compiler_build.yaml
- common_options.yaml
mirrors:
local_filesystem: file:///ascldap/users/rabartl/Spack.base4/atdm-spack/atdm-spack-tarball-mirror
config:
misc_cache: .spack/cache
???
compilers:
- compiler:
paths:
cc: /usr/bin/gcc
cxx: /usr/bin/g++
f77: /usr/bin/gfortran
fc: /usr/bin/gfortran
operating_system: rhel6
target: x86_64
modules: []
environment: {}
extra_rpaths: []
flags: {}
spec: [email protected]
Running:
$ rm spack.lock
$ ./atdm-spack/spack/bin/spack install
==> Concretized [email protected]
- zzfkclh [email protected]%[email protected]~binutils languages=c,c++,fortran ~nvptx patches=51aebe82afc9a0433ca3503a36592edf5ca769b1433986919cfb9ae2ddf3e343 ~piclibs~strip arch=linux-rhel6-core2
- pbouq4g ^[email protected]%[email protected] arch=linux-rhel6-core2
- 7s5w76y ^[email protected]%[email protected] arch=linux-rhel6-core2
- xkdl6g2 ^[email protected]%[email protected] patches=3877ab548f88597ab2327a2230ee048d2d07ace1062efe81fc92e91b7f39cd00,fc9b61654a3ba1a8d6cd78ce087e7c96366c290bc8d2c299f09828d793b853c8 +sigsegv arch=linux-rhel6-core2
- nsk22pg ^[email protected]%[email protected] arch=linux-rhel6-core2
- wxdawoa ^[email protected]%[email protected]+cpanm+shared+threads arch=linux-rhel6-core2
- x5isbjk ^[email protected]%[email protected] arch=linux-rhel6-core2
- ea5sbdq ^[email protected]%[email protected] arch=linux-rhel6-core2
- tj5hsji ^[email protected]%[email protected]~symlinks~termlib arch=linux-rhel6-core2
- wrblnyo ^[email protected]%[email protected] arch=linux-rhel6-core2
- eexy7pf ^[email protected]%[email protected] arch=linux-rhel6-core2
- cryjtgh ^[email protected]%[email protected] arch=linux-rhel6-core2
- nizawm4 ^[email protected]%[email protected] arch=linux-rhel6-core2
- ddtcqci ^[email protected]%[email protected] arch=linux-rhel6-core2
- giua3so ^[email protected]%[email protected] arch=linux-rhel6-core2
- laq5nlz ^[email protected]%[email protected] patches=66a5d58364113a21405fc53f4a48f4e8 arch=linux-rhel6-core2
- 6phegih ^[email protected]%[email protected]+optimize+pic+shared arch=linux-rhel6-core2
...
But spack arch gives:
$ ./atdm-spack/spack/bin/spack arch
linux-rhel6-broadwell
This shows the miss-match in that spack arch returns linux-rhel6-broadwell but spack install uses arch=linux-rhel6-core2. Again, our scripts require that spack arch returns the name arch that spack install uses.
For now, hopefully, we can just manually pass in --arch <the-arch> to our driver. Have not gotten a successful build of the Spack package we use since upgrading to Spack v0.13.0 so I don't know if this will work. (Trying now.)
This shows the miss-match in that spack arch returns linux-rhel6-broadwell but spack install uses arch=linux-rhel6-core2. Again, our scripts require that spack arch returns the name arch that spack install uses
There's no mismatch, it's the same as before. In the new example you are compiling with [email protected]. Since that old version of gcc knows how to optimize up to the core2 microarchitecture, that is selected as the best match to broadwell.
If you register a newer compiler (like the [email protected] you are building) then the target will be correctly set to broadwell - since the new compiler knows how to generate code for that microarchitecture.
There's no mismatch
@alalazo, how is that? The command spack arch returns linux-rhel6-broadwell but spack install selects arch=linux-rhel6-core2. Therefore, after spack install is complete, when our install-trilinos-env.sh script looks for installed components for spack arch, it will not find anything (because it will be looking for but what is installed will have in the directory name). That means that we can't use spack arch to anything useful.
Here is the bash script that our driver uses which will error out.
# Find a package install dir and echo it to STDOUT
#
# This looks for install directories of the form:
#
# spack/opt/spack/<arch>/<pkg-compiler-name>-<pkg-compiler-ver>/<pkg-name>-<pkg-ver>-<hash>
#
function get_installed_package_path() {
# Input arguments
pkg_and_ver=$1 # <pkg-name>@<pkg-ver>
spack_arch=$2 # <arch>
pkg_compiler_and_ver=$3 # <pkg-compiler-name>@<pkg-compiler-ver>
pkg_name=`get_package_name_from_package_and_ver "${pkg_and_ver}"`
pkg_ver=`get_package_ver_from_package_and_ver "${pkg_and_ver}"`
pkg_compiler_name=`get_package_name_from_package_and_ver "${pkg_compiler_and_ver}"`
pkg_compiler_ver=`get_package_ver_from_package_and_ver "${pkg_compiler_and_ver}"`
pkg_install_dir="atdm-spack/spack/opt/spack/${spack_arch}/${pkg_compiler_name}-${pkg_compiler_ver}/${pkg_name}-${pkg_ver}-*"
pkg_path=`ls -d ${pkg_install_dir} | head -1`
if [ "${pkg_path}" == "" ] ; then
echo "ERROR, can't find ${pkg_install_dir}!" >&2
exit 1
fi
echo "${PWD}/${pkg_path}"
}
We need that to build up pacakges.yaml file for installed tools packages like 'cmake', 'ninja', 'perl', 'python', etc. so that they can be reused and not built over and over again for each compiler.
@bartlettroscoe: not sure what you want us to do. The old compilers will not generate code for the new architecture. We’re labeling the binaries according to where they can be used. You can still load a core2 module on a broadwell. What’s the issue?
I think you need to update your script to search for compatible architectures as well.
@alalazo: we may not have anything that makes it easy for users to do this. Is there some command we could add for @bartlettroscoe that would allow it? We already add compatible architectures to the module path. What does the script need to do?
I think you need to update your script to search for compatible architectures as well.
@tgamblin, how do I do that? I was hoping that sparck arch would return the same value as is implicitly used in spack install. Otherwise, what is the possible value of the spack arch command? What use case would that command be of any value to anyone (other than give them false hope and send them down a rabbit hole of wasted time).
This is not the end of the world as we can script around this (by manaully setting the arch for each) but this is just one more think that makes spack hard to use in raw form.
@tgamblin We might add an option to spack arch to expose that via cli. Something like:
$ spack arch --show-all-compatible
? Are there other options that might be desirable for scripting? In case I can open an issue to improve spack arch and list the improvements we want there.
what about something like spack arch %[email protected] that would return what spack install would use for [email protected]?
@bartlettroscoe Looking at the name of your bash function:
function get_installed_package_path() {
can't that be substituted by spack location -i or spack find -p?
@alalazo said:
spack arch --show-all-compatible
How does that help me? I don't want to know all compatible arch. I want to know the exact arch used by spack intall
@fryeguy52 said:
what about something like
spack arch %[email protected]that would return whatspack installwould use for[email protected]?
Yup, that would work! We know the compilers that we use with each spack install command that we run.
What is interesting though is that the arch will then be different between the spack install command used to build [email protected] using [email protected] and the spack intall commands using [email protected] for later stuff.
@bartlettroscoe: I think this is a case that’s easier in a spack environment, as you just get whatever’s installed in that environment in your path. Is that something that could help your use case? I am not familiar with the custom env you’re building in your script, but we did address this use case with modules and environments in spack itself, so I’m not sure I agree fully that this makes spack hard to use for everyone. It’s a more complex model, but we are trying to make a system that can distribute optimized binaries.
Is your script online somewhere? I know @becker33 is familiar with it. I like both @alalazo and @fryeguy52’s suggestions, though I will say it’s possible (but unlikely at least for now) that we’d generate a hybrid DAG with the run and link deps built with a fast compiler, and the pure build dependencies built with an “easy” compiler like the system compiler. In that case you’d get broadwell binaries for the stuff that needs to be fast and a common build of the build deps, potentially with a different architecture. The goal there would be not to build CMake for every compiler. In that case @fryeguy52’s suggestion may not give you what you want for the whole DAG. We aren’t quite this smart about dependency resolution yet.
@alalazo asked:
can't that be substituted by
spack location -iorspack find -p?
No, I tried that and it was super slow and did not work. (I don't remember all of the details but I can look back at my notes.) The current script was arrived at after days and days of experimenting and testing to find what actually works.
Another option is capture the output from the spack install command and then grep it for the arch and then look for the install paths for each package. That is a bit hacked but it would work for our current use case.
@tgamblin asked:
Is your script online somewhere?
I want to look at making the atdm-spack repo public on github so others can see it. There is nothing sensitive in that repo. It just deals with spack stuff. But Sandia is strange about stuff like this.
After the upgrade to version 0.13.0, this issue is now breaking our script because the arch used by spack install using [email protected] is different than for [email protected]. I will need to script around this by providing different arch for each compiler.
@bartlettroscoe or something using spec like:
$ spack spec zlib %[email protected]
Input spec
--------------------------------
zlib%[email protected]
Concretized
--------------------------------
[email protected]%[email protected]+optimize+pic+shared arch=linux-rhel6-core2
will give us which arch will be used
@fryeguy52 note there is spack spec —json
@bartlettroscoe
I would appreciate if you could find the notes you have on the spack location -i command failure, that is of definite interest to me.
Your script has a failure case if you ever install multiple configurations of the same package/version combination. I don't know how likely it is to come up in your current use-case, but hdf5 with/without mpi would be an easy way for something like that to come up.
@fryeguy52: there is also spack find —json and spack find —format you might want to look at.
Note the JSON output of spack find —json is “flatter” to be more amenable to things like jq. We could also add spack spec —format if you think it’d help.
Wow, that is a slow command and it failed for me:
$ time ../atdm-spack/spack/bin/spack spec zlib %[email protected]
Input spec
--------------------------------
zlib%[email protected]
Concretized
--------------------------------
==> Error: String contains no specs:
real 0m9.369s
user 0m8.522s
sys 0m0.800s
Other than this failing for me, a command that takes 9s to run is not good. The simple find command runs in a split second.
And with an existing spack.yaml file siting in the current directory, it crashes:
$ ./atdm-spack/spack/bin/spack spec zlib %[email protected]
Traceback (most recent call last):
File "./atdm-spack/spack/bin/spack", line 64, in <module>
sys.exit(spack.main.main())
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/main.py", line 653, in main
ev.activate(env, args.use_env_repo)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/environment.py", line 163, in activate
cmds += env.add_default_view_to_shell(shell)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/environment.py", line 1074, in add_default_view_to_shell
spec, self.default_view))
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/environment.py", line 1041, in environment_modifications_for_spec
spec.prefix = Prefix(view.view().get_projection_for_spec(spec))
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/filesystem_view.py", line 461, in get_projection_for_spec
if spec.package.extendee_spec:
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/spec.py", line 1157, in package
self._package = spack.repo.get(self)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/repo.py", line 1203, in get
return path.get(spec)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/repo.py", line 94, in converter
return function(self, spec_like, *args, **kwargs)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/repo.py", line 653, in get
return self.repo_for_pkg(spec).get(spec)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/repo.py", line 94, in converter
return function(self, spec_like, *args, **kwargs)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/repo.py", line 892, in get
package_class = self.get_pkg_class(spec.name)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/repo.py", line 1095, in get_pkg_class
module = self._get_pkg_module(pkg_name)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/repo.py", line 1069, in _get_pkg_module
prepend=_package_prepend)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/util/imp/imp_importer.py", line 42, in load_source
return imp.load_source(full_name, path, f)
File "/home/rabartl/Spack.base4/atdm-spack/spack/var/spack/repos/builtin/packages/snl-atdm-tools/package.py", line 12, in <module>
"""snl-atdm-tools is a dummy package to trick spack into building consistent
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/directives.py", line 153, in __init__
directive(cls)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/directives.py", line 380, in _execute_depends_on
_depends_on(pkg, spec, when=when, type=type, patches=patches)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/directives.py", line 292, in _depends_on
dep_spec = spack.spec.Spec(spec)
File "/home/rabartl/Spack.base4/atdm-spack/spack/lib/spack/spack/spec.py", line 1022, in __init__
raise ValueError("String contains no specs: " + spec_like)
ValueError: String contains no specs:
Something weird must be going on with your configuration. Are you typically seeing worryingly slow times for Spack commands @bartlettroscoe? I see spack spec return in about half a second for zlib.
$ time spack spec zlib %[email protected]
Input spec
--------------------------------
zlib%[email protected]
Concretized
--------------------------------
[email protected]%[email protected]+optimize+pic+shared arch=darwin-mojave-core2
real 0m0.597s
user 0m0.381s
sys 0m0.202s
Note that if your package.py files change, spack spec may need to reindex the to concretize again.
I can sync our atdm-spack repo to the LLNL bitbucket site for now so people can see what we are trying to do. I am currently working on the branch cdofa-68-spack-upgrade-concretize-together. (I have not actually gotten to test out conretization=together yet because the upgrade to version 0.13.0 broke the basic functioning of the install process.)
Note that if your package.py files change, spack spec may need to reindex the to concretize again.
@tgamblin, how does spack determine if a packages.py file has changed?
Modtime vs modtime of the indexes in ~/.spack
Modtime vs modtime of the indexes in ~/.spack
We don't let spack write into ~/.spack/ (which is a disaster if you try to run multiple spack configs in the same user account and destroys reproducability).
What are the "indexes" and how are they computed?
@becker33 said:
Your script has a failure case if you ever install multiple configurations of the same package/version combination. I don't know how likely it is to come up in your current use-case, but hdf5 with/without mpi would be an easy way for something like that to come up.
Right. But in our use case that will not happen. And actually, we only look for installed tools packages like 'cmake', 'ninja-fortran', 'python', etc. which we never need more than one of these install per system. (The only exception is hacks we have been having to put int for missing -L paths for libraries. See #12304).
Will spack install always produce the same arch for the same compiler, independent of the packages it is building?
Yes.
@bartlettroscoe the indexes are files that go in the misc_cache, which I believe you have changed from ~/.spack to another location in your config files.
There are several indexes. Each is computed separately for each repo that you use. The providers index maps packages to the virtual packages they provide. The patches index maps (IIRC) patch hashes to the patch file they describe. The tags index matches packages to their tags. We cache each of these because they are somewhat cumbersome to recompute (generally for I/O reasons, not compute intensity reasons) and are generally static.
FYI: Looks like I can get what I need after a spack install with:
$ time ./atdm-spack/spack/bin/spack find --format "{arch}" | tail -n 1
linux-rhel6-x86_64
real 0m4.622s
user 0m4.475s
sys 0m0.136s
Don't know why that is so slow but is that going to be robust?
And this run instantly:
$ grep arch= spack.install.out | head -1 | sed 's/.*arch=\([0-9a-z-]*\)/\1/' | cut -d' ' -f 1
linux-rhel6-x86_64
@bartlettroscoe
The spack find --format command and the format string syntax should be a stable part of the API now, yes.
The spack find command is slower than your grep script because it had to search every spack package you have installed. If you did spack find --format "{arch}" /hash-of-a-spack-install instead it should be substantially faster
@becker33, the install process don't know the install hash anymore than I know the arch. Spack install determines both of these things internally. All the install process knows is the compiler@version and the package name and version.
The hash is output at the very least as part of the directory name after the [+] in the install output. We could also make spack install spit it out in an easier to parse way if you want.
Based on:
FYI: Looks like I can get what I need after a spack install with:
Closing this as I think it's complete, or the SNL folks have what they need. Let us know if there are further issues.
Most helpful comment
@fryeguy52 note there is
spack spec —json