From b77acd0896203e2c250a71f6a3b9809c26e598ab Mon Sep 17 00:00:00 2001 From: becker33 Date: Sun, 12 Nov 2017 19:12:57 -0800 Subject: [PATCH] Add configuration tutorial for SC17 (#6141) --- lib/spack/docs/tutorial.rst | 6 +- lib/spack/docs/tutorial_configuration.rst | 848 ++++++++++++++++++++++ 2 files changed, 852 insertions(+), 2 deletions(-) create mode 100644 lib/spack/docs/tutorial_configuration.rst diff --git a/lib/spack/docs/tutorial.rst b/lib/spack/docs/tutorial.rst index 4bfc772dde..47dc17a407 100644 --- a/lib/spack/docs/tutorial.rst +++ b/lib/spack/docs/tutorial.rst @@ -37,13 +37,15 @@ These scripts will take you step-by-step through basic Spack tasks. They correspond to sections in the slides above. 1. :ref:`basics-tutorial` - 2. :ref:`packaging-tutorial` - 3. :ref:`modules-tutorial` + 2. :ref:`configs-tutorial` + 3. :ref:`packaging-tutorial` + 4. :ref:`modules-tutorial` Full contents: .. toctree:: tutorial_basics + tutorial_configuration tutorial_packaging tutorial_advanced_packaging tutorial_modules diff --git a/lib/spack/docs/tutorial_configuration.rst b/lib/spack/docs/tutorial_configuration.rst new file mode 100644 index 0000000000..e7ef5b92cd --- /dev/null +++ b/lib/spack/docs/tutorial_configuration.rst @@ -0,0 +1,848 @@ +.. _configs-tutorial: + +====================== +Configuration Tutorial +====================== + +This tutorial will guide you through various configuration options +that allow you to customize Spack's behavior with respect to +software installation. We will first cover the configuration file +hierarchy. Then, we will cover configuration options for compilers, +focusing on how it can be used to extend Spack's compiler auto-detection. +Next, we will cover the packages configuration file, focusing on +how it can be used to override default build options as well as +specify external package installations to use. Finally, we will +briefly touch on the config configuration file, which manages more +high-level Spack configuration options. + +For all of these features we will demonstrate how we build up a full +configuration file. For some we will then demonstrate how the +configuration affects the install command, and for others we will use +the ``spack spec`` command to demonstrate how the configuration +changes have affected Spack's concretization algorithm. The provided +output is all from a server running Ubuntu version 16.04. + +.. _configs-tutorial-scopes: + +-------------------- +Configuration Scopes +-------------------- + +Depending on your use case, you may want to provide configuration +settings common to everyone on your team, or you may want to set +default behaviors specific to a single user account. Spack provides +4 configuration *scopes* to handle this customization. These scopes, +in order of decreasing priority, are: + +====================== ================================== +Scope Directory +====================== ================================== +User configurations ``~/.spack`` +Project configurations ``$SPACK_ROOT/etc/spack`` +System configurations ``/etc/spack`` +Default configurations ``$SPACK_ROOT/etc/spack/defaults`` +====================== ================================== + +Spack's default configuration settings reside in +``$SPACK_ROOT/etc/spack/defaults``. These are useful for reference, +but should never be directly edited. To override these settings, +create new configuration files in any of the higher-priority +configuration scopes. + +A particular cluster may have multiple Spack installations associated +with different projects. To provide settings common to all Spack +installations, put your configuration files in ``/etc/spack``. +To provide settings specific to a particular Spack installation, +you can use the ``$SPACK_ROOT/etc/spack`` directory. + +For settings specific to a particular user, you will want to add +configuration files to the ``~/.spack`` directory. When Spack first +checked for compilers on your system, you may have noticed that it +placed your compiler configuration in this directory. + +Some facilities manage multiple platforms from a single shared +filesystem. In order to handle this, each of the configuration +scopes listed above has two *sub-scopes*: platform-specific and +platform-independent. For example, compiler settings can be stored +in ``compilers.yaml`` configuration files in the following locations: + +- ``~/.spack//compilers.yaml`` +- ``~/.spack/compilers.yaml`` +- ``$SPACK_ROOT/etc/spack//compilers.yaml`` +- ``$SPACK_ROOT/etc/spack/compilers.yaml`` +- ``/etc/spack//compilers.yaml`` +- ``/etc/spack/compilers.yaml`` +- ``$SPACK_ROOT/etc/defaults//compilers.yaml`` +- ``$SPACK_ROOT/etc/defaults/compilers.yaml`` + +These files are listed in decreasing order of precedence, so files in +``~/.spack/`` will override settings in ``~/.spack``. + +Spack configurations are YAML dictionaries. Every configuration file +begins with a top-level dictionary that tells Spack which +configuration set it modifies. When Spack checks it's configuration, +the configuration scopes are updated as dictionaries in increasing +order of precedence, allowing higher precedence files to override +lower. YAML dictionaries use a colon ":" to specify key-value +pairs. Spack extends YAML syntax slightly to allow a double-colon +"::" to specify a key-value pair. When a double-colon is used to +specify a key-value pair, instead of adding that section Spack +replaces what was in that section with the new value. For example, a +user compilers configuration file as follows: + +.. code-block:: yaml + + compilers:: + - compiler: + environment: {} + extra_rpaths: [] + flags: {} + modules: [] + operating_system: ubuntu16.04 + paths: + cc: /usr/bin/gcc + cxx: /usr/bin/g++ + f77: /usr/bin/gfortran + fc: /usr/bin/gfortran + spec: gcc@5.4.0 + target: x86_64 + + +ensures that no other compilers are used, as the user configuration +scope is the last scope searched and the ``compilers::`` line replaces +all previous configuration files information. If the same +configuration file had a single colon instead of the double colon, it +would add the gcc version 5.4.0 compiler to whatever other compilers +were listed in other configuration files. + +.. _configs-tutorial-compilers: + +---------------------- +Compiler Configuration +---------------------- + +For most tasks, we can use Spack with the compilers auto-detected the +first time Spack runs on a system. As we discussed in the basic +installation section, we can also tell Spack where compilers are +located using the ``spack compiler add`` command. However, in some +circumstances we want even more fine-grained control over the +compilers available. This section will teach you how to exercise that +control using the compilers configuration file. + +We will start by opening the compilers configuration file + +.. code-block:: console + + spack config edit compilers + + +.. code-block:: yaml + + compilers: + - compiler: + environment: {} + extra_rpaths: [] + flags: {} + modules: [] + operating_system: ubuntu16.04 + paths: + cc: /usr/bin/clang + cxx: /usr/bin/clang++ + f77: null + fc: null + spec: clang@3.8.0-2ubuntu4 + target: x86_64 + - compiler: + environment: {} + extra_rpaths: [] + flags: {} + modules: [] + operating_system: ubuntu16.04 + paths: + cc: /usr/bin/gcc + cxx: /usr/bin/g++ + f77: /usr/bin/gfortran + fc: /usr/bin/gfortran + spec: gcc@5.4.0 + target: x86_64 + + +This specifies one version of the gcc compiler and one version of the +clang compiler with no flang compiler. Now suppose we have a code that +we want to compile with the clang compiler for C/C++ code, but with +gfortran for Fortran components. We can do this by adding another entry +to the ``compilers.yaml`` file. + +.. code-block:: yaml + + - compiler: + environment: {} + extra_rpaths: [] + flags: {} + modules: [] + operating_system: ubuntu16.04 + paths: + cc: /usr/bin/clang + cxx: /usr/bin/clang++ + f77: /usr/bin/gfortran + fc: /usr/bin/gfortran + spec: clang@3.8.0-gfortran + target: x86_64 + + +Let's talk about the sections of this compiler entry that we've changed. +The biggest change we've made is to the ``paths`` section. This lists +the paths to the compilers to use for each language/specification. +In this case, we point to the clang compiler for C/C++ and the gfortran +compiler for both specifications of Fortran. We've also changed the +``spec`` entry for this compiler. The ``spec`` entry is effectively the +name of the compiler for Spack. It consists of a name and a version +number, separated by the ``@`` sigil. The name must be one of the supported +compiler names in Spack (gcc, intel, pgi, xl, xl_r, clang, nag, cce). +The version number can be an arbitrary string of alphanumeric characters, +as well as ``-``, ``.``, and ``_``. The ``target`` and ``operating_system`` +sections we leave unchanged. These sections specify when Spack can use +different compilers, and are primarily useful for configuration files that +will be used across multiple systems. + +We can verify that our new compiler works by invoking it now: + +.. code-block:: console + + $ spack install zlib %clang@3.8.0-gfortran + ... + + +This new compiler also works on Fortran codes: + +.. code-block:: console + + $ spack install cfitsio %clang@3.8.0-gfortran + ... + + +^^^^^^^^^^^^^^ +Compiler Flags +^^^^^^^^^^^^^^ + +Some compilers may require specific compiler flags to work properly in +a particular computing environment. Spack provides configuration +options for setting compiler flags every time a specific compiler is +invoked. These flags become part of the package spec and therefore of +the build provenance. As on the command line, the flags are set +through the implicit build variables ``cflags``, ``cxxflags``, ``cppflags``, +``fflags``, ``ldflags``, and ``ldlibs``. + +Let's open our compilers configuration file again and add a compiler flag. + +.. code-block:: yaml + + - compiler: + environment: {} + extra_rpaths: [] + flags: + cppflags: -g + modules: [] + operating_system: ubuntu16.04 + paths: + cc: /usr/bin/clang + cxx: /usr/bin/clang++ + f77: /usr/bin/gfortran + fc: /usr/bin/gfortran + spec: clang@3.8.0-gfortran + target: x86_64 + + +We can test this out using the ``spack spec`` command to show how the +spec is concretized. + +.. code-block:: console + + $ spack spec cfitsio %clang@3.8.0-gfortran + Input spec + -------------------------------- + cfitsio%clang@3.8.0-gfortran + + Normalized + -------------------------------- + cfitsio%clang@3.8.0-gfortran + + Concretized + -------------------------------- + cfitsio@3.410%clang@3.8.0-gfortran cppflags="-g" +bzip2+shared arch=linux-ubuntu16.04-x86_64 + ^bzip2@1.0.6%clang@3.8.0-gfortran cppflags="-g" +shared arch=linux-ubuntu16.04-x86_64 + + +We can see that "cppflags=-g" has been added to every node in the DAG. + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Advanced Compiler Configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are three fields of the compiler configuration entry that we +have not talked about yet. + +The ``modules`` field of the compiler is used primarily on Cray systems, +but can be useful on any system that has compilers that are only +useful when a particular module is loaded. Any modules in the +``modules`` field of the compiler configuration will be loaded as part +of the build environment for packages using that compiler. + +The ``extra_rpaths`` field of the compiler configuration is used for +compilers that do not rpath all of their dependencies by +default. Since compilers are generally installed externally to Spack, +Spack is unable to manage compiler dependencies and enforce +rpath usage. This can lead to packages not finding link dependencies +imposed by the compiler properly. For compilers that impose link +dependencies on the resulting executables that are not rpath'ed into +the executable automatically, the ``extra_rpath`` field of the compiler +configuration tells Spack which dependencies to rpath into every +executable created by that compiler. The executables will then be able +to find the link dependencies imposed by the compiler. + +The ``environment`` field of the compiler configuration is used for +compilers that require environment variables to be set during build +time. For example, if your Intel compiler suite requires the +``INTEL_LICENSE_FILE`` environment variable to point to the proper +license server, you can set this in ``compilers.yaml``. + +------------------------------- +Configuring Package Preferences +------------------------------- + +Package preferences in Spack are managed through the ``packages.yaml`` +configuration file. First, we will look at the default +``packages.yaml`` file. + +.. code-block:: console + + $ spack config --scope defaults edit packages + + +.. literalinclude:: ../../../etc/spack/defaults/packages.yaml + :language: yaml + + +This sets the default preferences for compilers and for providers of +virtual packages. To illustrate how this works, suppose we want to +change the preferences to prefer the clang compiler and to prefer +mpich over openmpi. Currently, we prefer gcc and openmpi + +.. code-block:: console + + $ spack spec hdf5 + Input spec + -------------------------------- + hdf5 + + Normalized + -------------------------------- + hdf5 + ^zlib@1.1.2: + + Concretized + -------------------------------- + hdf5@1.10.1%gcc@5.4.0+cxx~debug+fortran+mpi+pic+shared~szip~threadsafe arch=linux-ubuntu16.04-x86_64 + ^openmpi@3.0.0%gcc@5.4.0~cuda fabrics= ~java schedulers= ~sqlite3~thread_multiple+vt arch=linux-ubuntu16.04-x86_64 + ^hwloc@1.11.7%gcc@5.4.0~cuda+libxml2~pci arch=linux-ubuntu16.04-x86_64 + ^libxml2@2.9.4%gcc@5.4.0~python arch=linux-ubuntu16.04-x86_64 + ^pkg-config@0.29.2%gcc@5.4.0+internal_glib arch=linux-ubuntu16.04-x86_64 + ^xz@5.2.3%gcc@5.4.0 arch=linux-ubuntu16.04-x86_64 + ^zlib@1.2.11%gcc@5.4.0+pic+shared arch=linux-ubuntu16.04-x86_64 + + +Now we will open the packages configuration file and update our +preferences. + +.. code-block:: console + + $ spack config edit packages + + +.. code-block:: yaml + + packages: + all: + compiler: [clang, gcc, intel, pgi, xl, nag] + providers: + mpi: [mpich, openmpi] + + +Because of the configuration scoping we discussed earlier, this +overrides the default settings just for these two items. + +.. code-block:: console + + $ spack spec hdf5 + Input spec + -------------------------------- + hdf5 + + Normalized + -------------------------------- + hdf5 + ^zlib@1.1.2: + + Concretized + -------------------------------- + hdf5@1.10.1%clang@3.8.0-2ubuntu4+cxx~debug~fortran~hl+mpi+pic+shared~szip~threadsafe arch=linux-ubuntu16.04-x86_64 + ^mpich@3.2%clang@3.8.0-2ubuntu4 device=ch3 +hydra netmod=tcp +pmi+romio~verbs arch=linux-ubuntu16.04-x86_64 + ^zlib@1.2.11%clang@3.8.0-2ubuntu4+pic+shared arch=linux-ubuntu16.04-x86_64 + + +^^^^^^^^^^^^^^^^^^^ +Variant Preferences +^^^^^^^^^^^^^^^^^^^ + +The packages configuration file can also set variant preferences for +package variants. For example, let's change our preferences to build all +packages without shared libraries. We will accomplish this by turning +off the ``shared`` variant on all packages that have one. + +.. code-block:: yaml + + packages: + all: + compiler: [clang, gcc, intel, pgi, xl, nag] + providers: + mpi: [mpich, openmpi] + variants: ~shared + + +We can check the effect of this command with ``spack spec hdf5`` again. + +.. code-block:: console + + $ spack spec hdf5 + Input spec + -------------------------------- + hdf5 + + Normalized + -------------------------------- + hdf5 + ^zlib@1.1.2: + + Concretized + -------------------------------- + hdf5@1.10.1%clang@3.8.0-2ubuntu4+cxx~debug~fortran~hl+mpi+pic~shared~szip~threadsafe arch=linux-ubuntu16.04-x86_64 + ^mpich@3.2%clang@3.8.0-2ubuntu4 device=ch3 +hydra netmod=tcp +pmi+romio~verbs arch=linux-ubuntu16.04-x86_64 + ^zlib@1.2.11%clang@3.8.0-2ubuntu4+pic~shared arch=linux-ubuntu16.04-x86_64 + + +So far we have only made global changes to the package preferences. As +we've seen throughout this tutorial, hdf5 builds with MPI enabled by +default in Spack. If we were working on a project that would routinely +need serial hdf5, that might get annoying quickly, having to type +``hdf5~mpi`` all the time. Instead, we'll update our preferences for +hdf5. + +.. code-block:: yaml + + packages: + all: + compiler: [clang, gcc, intel, pgi, xl, nag] + providers: + mpi: [mpich, openmpi] + variants: ~shared + hdf5: + variants: ~mpi + + +Now hdf5 will concretize without an MPI dependency by default. + +.. code-block:: console + + $ spack spec hdf5 + Input spec + -------------------------------- + hdf5 + + Normalized + -------------------------------- + hdf5 + ^zlib@1.1.2: + + Concretized + -------------------------------- + hdf5@1.10.1%clang@3.8.0-2ubuntu4+cxx~debug~fortran~hl+mpi+pic~shared~szip~threadsafe arch=linux-ubuntu16.04-x86_64 + ^zlib@1.2.11%clang@3.8.0-2ubuntu4+pic~shared arch=linux-ubuntu16.04-x86_64 + + +In general, every attribute that we can set for all packages we can +set separately for an individual package. + +^^^^^^^^^^^^^^^^^ +External Packages +^^^^^^^^^^^^^^^^^ + +The packages configuration file also controls when Spack will build +against an externally installed package. On these systems we have a +pre-installed zlib. + +.. code-block:: yaml + + packages: + all: + compiler: [clang, gcc, intel, pgi, xl, nag] + providers: + mpi: [mpich, openmpi] + variants: ~shared + hdf5: + variants: ~mpi + zlib: + paths: + zlib@1.2.8%gcc@5.4.0 arch=linux-ubuntu16.04-x86_64: /usr + + +Here, we've told Spack that zlib 1.2.8 is installed on our system. +We've also told it the installation prefix where zlib can be found. +We don't know exactly which variants it was built with, but that's +okay. + +.. code-block:: console + + $ spack spec hdf5 + Input spec + -------------------------------- + hdf5 + + Normalized + -------------------------------- + hdf5 + ^zlib@1.1.2: + + Concretized + -------------------------------- + hdf5@1.10.1%clang@3.8.0-2ubuntu4+cxx~debug~fortran~hl+mpi+pic~shared~szip~threadsafe arch=linux-ubuntu16.04-x86_64 + ^zlib@1.2.11%clang@3.8.0-2ubuntu4+pic~shared arch=linux-ubuntu16.04-x86_64 + + +You'll notice that this did not use our external zlib. Why? +Because Spack concretized zlib to a different Spec than the +one we provided. There are two ways we could get Spack to +build with our external zlib. One would be to explicitly ask +for that spec on the command line. The other is to tell Spack +it's not allowed to build its own zlib. We'll go with the latter. + +.. code-block:: yaml + + packages: + all: + compiler: [clang, gcc, intel, pgi, xl, nag] + providers: + mpi: [mpich, openmpi] + variants: ~shared + hdf5: + variants: ~mpi + zlib: + paths: + zlib@1.2.11%gcc@5.4.0 arch=linux-ubuntu16.04-x86_64: /usr + buildable: False + + +Now Spack will be forced to choose the external zlib. + +.. code-block:: console + + $ spack spec hdf5 + Input spec + -------------------------------- + hdf5 + + Normalized + -------------------------------- + hdf5 + ^zlib@1.1.2: + + Concretized + -------------------------------- + hdf5@1.10.1%gcc@5.4.0+cxx~debug~fortran~hl+mpi+pic~shared~szip~threadsafe arch=linux-ubuntu16.04-x86_64 + ^zlib@1.2.11%gcc@5.4.0+pic+shared arch=linux-ubuntu16.04-x86_64 + + +Note that Spack now concretizes the entire DAG to use the gcc +compiler. Because we did not specify a build using the clang compiler +(only expressed a preference) Spack used the gcc compiler specified by +the zlib spec. If we want to use clang for the rest of the build, we +have to specify it. + +.. code-block:: console + + $ spack spec hdf5 %clang + Input spec + -------------------------------- + hdf5%clang + + Normalized + -------------------------------- + hdf5%clang + ^zlib@1.1.2: + + Concretized + -------------------------------- + hdf5@1.10.1%clang@3.8.0-2ubuntu4+cxx~debug~fortran~hl+mpi+pic~shared~szip~threadsafe arch=linux-ubuntu16.04-x86_64 + ^zlib@1.2.11%gcc@5.4.0+pic+shared arch=linux-ubuntu16.04-x86_64 + + +This gets slightly more complicated with virtual dependencies. Suppose +we don't want to build our own MPI, but we now want a parallel version +of hdf5? Well, fortunately we have mpich installed on these systems. + +.. code-block:: yaml + + packages: + all: + compiler: [clang, gcc, intel, pgi, xl, nag] + providers: + mpi: [mpich, openmpi] + variants: ~shared + hdf5: + variants: ~mpi + zlib: + paths: + zlib@1.2.11%gcc@5.4.0 arch=linux-ubuntu16.04-x86_64: /usr + buildable: False + mpich: + paths: + mpich@3.2%gcc@5.4.0 device=ch3 +hydra netmod=tcp +pmi+romio~verbs arch=linux-ubuntu16.04-x86_64: /usr + buildable: False + + +If we concretize ``hdf5+mpi`` with this configuration file, we will just +build with an alternate MPI implementation. + +.. code-block:: console + + $ spack spec hdf5 %clang +mpi + Input spec + -------------------------------- + hdf5%clang+mpi + + Normalized + -------------------------------- + hdf5%clang+mpi + ^mpi + ^zlib@1.1.2: + + Concretized + -------------------------------- + hdf5@1.10.1%clang@3.8.0-2ubuntu4~cxx~debug~fortran~hl+mpi+pic~shared~szip~threadsafe arch=linux-ubuntu16.04-x86_64 + ^openmpi@3.0.0%clang@3.8.0-2ubuntu4~cuda fabrics=verbs ~java schedulers= ~sqlite3~thread_multiple+vt arch=linux-ubuntu16.04-x86_64 + ^hwloc@1.11.8%clang@3.8.0-2ubuntu4~cuda+libxml2+pci arch=linux-ubuntu16.04-x86_64 + ^libpciaccess@0.13.5%clang@3.8.0-2ubuntu4 arch=linux-ubuntu16.04-x86_64 + ^libtool@2.4.6%clang@3.8.0-2ubuntu4 arch=linux-ubuntu16.04-x86_64 + ^m4@1.4.18%clang@3.8.0-2ubuntu4 patches=3877ab548f88597ab2327a2230ee048d2d07ace1062efe81fc92e91b7f39cd00 +sigsegv arch=linux-ubuntu16.04-x86_64 + ^libsigsegv@2.11%clang@3.8.0-2ubuntu4 arch=linux-ubuntu16.04-x86_64 + ^pkg-config@0.29.2%clang@3.8.0-2ubuntu4+internal_glib arch=linux-ubuntu16.04-x86_64 + ^util-macros@1.19.1%clang@3.8.0-2ubuntu4 arch=linux-ubuntu16.04-x86_64 + ^libxml2@2.9.4%clang@3.8.0-2ubuntu4~python arch=linux-ubuntu16.04-x86_64 + ^xz@5.2.3%clang@3.8.0-2ubuntu4 arch=linux-ubuntu16.04-x86_64 + ^zlib@1.2.11%gcc@5.4.0+optimize+pic+shared arch=linux-ubuntu16.04-x86_64 + + +We have only expressed a preference for mpich over other MPI +implementations, and Spack will happily build with one we haven't +forbid it from using. We could resolve this by requesting +``hdf5%clang+mpi^mpich`` explicitly, or we can configure Spack not to +use any other MPI implementation. Since we're focused on +configurations here and the former can get tedious, we'll need to +modify our ``packages.yaml`` file again. + +While we're at it, we can configure hdf5 to build with MPI by default +again. + +.. code-block:: yaml + + packages: + all: + compiler: [clang, gcc, intel, pgi, xl, nag] + providers: + mpi: [mpich, openmpi] + variants: ~shared + zlib: + paths: + zlib@1.2.11%gcc@5.4.0 arch=linux-ubuntu16.04-x86_64: /usr + buildable: False + mpich: + paths: + mpich@3.2%gcc@5.4.0 device=ch3 +hydra netmod=tcp +pmi+romio~verbs arch=linux-ubuntu16.04-x86_64: /usr + buildable: False + openmpi: + buildable: False + mvapich2: + buildable: False + intel-mpi: + buildable: False + spectrum-mpi: + buildable: False + intel-parallel-studio: + buildable: False + +Now that we have configured Spack not to build any of the possible +providers for MPI we can try again. + +.. code-block:: console + + $ spack spec hdf5 %clang + Input spec + -------------------------------- + hdf5%clang + + Normalized + -------------------------------- + hdf5%clang + ^mpi + ^zlib@1.1.2: + + Concretized + -------------------------------- + hdf5@1.10.1%clang@3.8.0-2ubuntu4+cxx~debug~fortran~hl+mpi+pic~shared~szip~threadsafe arch=linux-ubuntu16.04-x86_64 + ^mpich@3.2%gcc@5.4.0 device=ch3 +hydra netmod=tcp +pmi+romio~verbs arch=linux-ubuntu16.04-x86_64 + ^zlib@1.2.11%gcc@5.4.0+pic+shared arch=linux-ubuntu16.04-x86_64 + +Now that we have hdf5 configured to install exactly as we want it, we +can install it. We've now minimized the command line effort necessary +to get exactly the hdf5 installation we want, and we can now build +hdf5 against our external installations of zlib and mpich. + +.. code-block:: console + + $ spack install hdf5 %clang + ... + + +----------------- +High-level Config +----------------- + +In addition to compiler and package settings, Spack allows customization +of several high-level settings. These settings are stored in the generic +``config.yaml`` configuration file. You can see the default settings by +running: + +.. code-block:: console + + $ spack config --scope defaults edit config + + +.. literalinclude:: ../../../etc/spack/defaults/config.yaml + :language: yaml + + +As you can see, many of the directories Spack uses can be customized. +For example, you can tell Spack to install packages to a prefix +outside of the ``$SPACK_ROOT`` hierarchy. Module files can be +written to a central location if you are using multiple Spack +instances. If you have a fast scratch filesystem, you can run builds +from this filesystem with the following ``config.yaml``: + +.. code-block:: yaml + + config: + build_stage: + - /scratch/$user + + +On systems with compilers that absolutely *require* environment variables +like ``LD_LIBRARY_PATH``, it is possible to prevent Spack from cleaning +the build environment with the ``dirty`` setting: + +.. code-block:: yaml + + config: + dirty: true + + +However, this is strongly discouraged, as it can pull unwanted libraries +into the build. + +One last setting that may be of interest to users building on a shared +login node is the ability to customize the parallelism of Spack builds. +By default, Spack installs all packages in parallel with the number of +jobs equal to the number of cores on the node. For example, on a node +with 36 cores, this will look like: + +.. code-block:: console + + $ spack install --verbose zlib + ==> Installing zlib + ==> Using cached archive: ~/spack/var/spack/cache/zlib/zlib-1.2.11.tar.gz + ==> Staging archive: ~/spack/var/spack/stage/zlib-1.2.11-5nus6knzumx4ik2yl44jxtgtsl7d54xb/zlib-1.2.11.tar.gz + ==> Created stage in ~/spack/var/spack/stage/zlib-1.2.11-5nus6knzumx4ik2yl44jxtgtsl7d54xb + ==> No patches needed for zlib + ==> Building zlib [Package] + ==> Executing phase: 'install' + ==> './configure' '--prefix=~/spack/opt/spack/linux-ubuntu16.04-x86_64/gcc-5.4.0/zlib-1.2.11-5nus6knzumx4ik2yl44jxtgtsl7d54xb' + Checking for shared library support... + Building shared library libz.so.1.2.11 with ~/spack/lib/spack/env/gcc/gcc. + Checking for size_t... Yes. + Checking for off64_t... Yes. + Checking for fseeko... Yes. + Checking for strerror... Yes. + Checking for unistd.h... Yes. + Checking for stdarg.h... Yes. + Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). + Checking for vsnprintf() in stdio.h... Yes. + Checking for return value of vsnprintf()... Yes. + Checking for attribute(visibility) support... Yes. + ==> 'make' '-j36' + ... + ==> 'make' '-j36' 'install' + ... + + +As you can see, we are building with all 36 cores on the node. If you are +on a shared login node, this can slow down the system for other users. If +you have a strict ulimit or restriction on the number of available licenses, +you may not be able to build at all with this many cores. On nodes with 64+ +cores, you may not see a significant speedup of the build anyway. To limit +the number of cores our build uses, set ``build_jobs`` like so: + +.. code-block:: yaml + + config: + build_jobs: 4 + + +If we uninstall and reinstall zlib, we see that it now uses only 4 cores: + +.. code-block:: console + + $ spack install -v zlib + ==> Installing zlib + ==> Using cached archive: ~/spack/var/spack/cache/zlib/zlib-1.2.11.tar.gz + ==> Staging archive: ~/spack/var/spack/stage/zlib-1.2.11-ezuwp4pa52e75v6iweawzwymmf4ahxxn/zlib-1.2.11.tar.gz + ==> Created stage in ~/spack/var/spack/stage/zlib-1.2.11-ezuwp4pa52e75v6iweawzwymmf4ahxxn + ==> No patches needed for zlib + ==> Building zlib [Package] + ==> Executing phase: 'install' + ==> './configure' '--prefix=~/spack/opt/spack/linux-ubuntu16.04-x86_64/gcc-7.2.0/zlib-1.2.11-ezuwp4pa52e75v6iweawzwymmf4ahxxn' + Checking for shared library support... + Building shared library libz.so.1.2.11 with ~/spack/lib/spack/env/gcc/gcc. + Checking for size_t... Yes. + Checking for off64_t... Yes. + Checking for fseeko... Yes. + Checking for strerror... Yes. + Checking for unistd.h... Yes. + Checking for stdarg.h... Yes. + Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). + Checking for vsnprintf() in stdio.h... Yes. + Checking for return value of vsnprintf()... Yes. + Checking for attribute(visibility) support... Yes. + ==> 'make' '-j4' + ... + ==> 'make' '-j4' 'install' + ... + + +Obviously, if you want to build everything in serial for whatever reason, +you would set ``build_jobs`` to 1. + +.. warning:: + + At this point, make sure you delete or move the ``packages.yaml`` and + ``config.yaml`` you have been editing up to this point. Otherwise, they + will change the hashes of your packages, leading to differences in the + output of later tutorial sections. +