Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

External packages #120

Merged
merged 18 commits into from
Mar 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
59f89dd
Allow long names in format string variables
mplegendre May 29, 2015
b5c597b
Allow specs to be sorted based on preferred packages, versions, compi…
mplegendre May 29, 2015
8d7b7e5
Use preferred package rules when concretize'ing specs
mplegendre May 29, 2015
ee68a76
Bug fixes from testing spack preferred packages
mplegendre May 29, 2015
987cd9e
Update docs for YAML configuration files and preferred concretization
mplegendre Jul 7, 2015
53cde11
Update Spack mirror command to match docs
mplegendre Jul 7, 2015
53d70ff
Fix type error with YAML config when merging lists from different con…
mplegendre Jul 7, 2015
650c9d4
Allow spack to build against external non-spack-installed packages.
mplegendre Sep 16, 2015
e4d2ba3
Fix failure in spack.test.config.ConfigTest from incorrect compiler c…
mplegendre Oct 2, 2015
18f0b24
Add tests for spack external dependencies, plus fixes for issues foun…
mplegendre Oct 5, 2015
fac4428
Documentation for external packages.
mplegendre Oct 5, 2015
72d5cdf
fixed two minor typos
alalazo Jan 20, 2016
fa888a4
Merge branch 'develop' into features/external-packages
mplegendre Jan 25, 2016
d4a771a
Merge pull request #1 from alalazo/features/external-packages
mplegendre Jan 25, 2016
87db694
Merge branch 'develop' into features/external-packages
mplegendre Mar 9, 2016
a384ad5
Fix problem with pure integer arguments in preferred versions list (e…
mplegendre Mar 10, 2016
1f06dd4
Update documentation for new packages.yaml config format.
mplegendre Mar 10, 2016
dd0ae25
Merge branch 'features/external-packages' of github.com:mplegendre/sp…
mplegendre Mar 10, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 22 additions & 15 deletions lib/spack/docs/basic_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ Spack, you can simply run ``spack compiler add`` with the path to
where the compiler is installed. For example::

$ spack compiler add /usr/local/tools/ic-13.0.079
==> Added 1 new compiler to /Users/gamblin2/.spackconfig
==> Added 1 new compiler to /Users/gamblin2/.spack/compilers.yaml
intel@13.0.079

Or you can run ``spack compiler add`` with no arguments to force
Expand All @@ -367,7 +367,7 @@ installed, but you know that new compilers have been added to your

$ module load gcc-4.9.0
$ spack compiler add
==> Added 1 new compiler to /Users/gamblin2/.spackconfig
==> Added 1 new compiler to /Users/gamblin2/.spack/compilers.yaml
gcc@4.9.0

This loads the environment module for gcc-4.9.0 to get it into the
Expand Down Expand Up @@ -398,27 +398,34 @@ Manual compiler configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If auto-detection fails, you can manually configure a compiler by
editing your ``~/.spackconfig`` file. You can do this by running
``spack config edit``, which will open the file in your ``$EDITOR``.
editing your ``~/.spack/compilers.yaml`` file. You can do this by running
``spack config edit compilers``, which will open the file in your ``$EDITOR``.

Each compiler configuration in the file looks like this::

...
[compiler "intel@15.0.0"]
cc = /usr/local/bin/icc-15.0.024-beta
cxx = /usr/local/bin/icpc-15.0.024-beta
f77 = /usr/local/bin/ifort-15.0.024-beta
fc = /usr/local/bin/ifort-15.0.024-beta
...
chaos_5_x86_64_ib:
...
intel@15.0.0:
cc: /usr/local/bin/icc-15.0.024-beta
cxx: /usr/local/bin/icpc-15.0.024-beta
f77: /usr/local/bin/ifort-15.0.024-beta
fc: /usr/local/bin/ifort-15.0.024-beta
...

The chaos_5_x86_64_ib string is an architecture string, and multiple
compilers can be listed underneath an architecture. The architecture
string may be replaced with the string 'all' to signify compilers that
work on all architectures.

For compilers, like ``clang``, that do not support Fortran, put
``None`` for ``f77`` and ``fc``::

[compiler "clang@3.3svn"]
cc = /usr/bin/clang
cxx = /usr/bin/clang++
f77 = None
fc = None
clang@3.3svn:
cc: /usr/bin/clang
cxx: /usr/bin/clang++
f77: None
fc: None

Once you save the file, the configured compilers will show up in the
list displayed by ``spack compilers``.
Expand Down
9 changes: 4 additions & 5 deletions lib/spack/docs/mirrors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,11 @@ And, if you want to remove a mirror, just remove it by name::
Mirror precedence
----------------------------

Adding a mirror really just adds a section in ``~/.spackconfig``::
Adding a mirror really just adds a section in ``~/.spack/mirrors.yaml``::

[mirror "local_filesystem"]
url = file:///Users/gamblin2/spack-mirror-2014-06-24
[mirror "remote_server"]
url = https://example.com/some/web-hosted/directory/spack-mirror-2014-06-24
mirrors:
- local_filesystem: file:///Users/gamblin2/spack-mirror-2014-06-24
- remote_server: https://example.com/some/web-hosted/directory/spack-mirror-2014-06-24

If you want to change the order in which mirrors are searched for
packages, you can edit this file and reorder the sections. Spack will
Expand Down
65 changes: 64 additions & 1 deletion lib/spack/docs/packaging_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ Default
revision instead.

Revisions
Add ``hg`` and ``revision``parameters:
Add ``hg`` and ``revision`` parameters:

.. code-block:: python

Expand Down Expand Up @@ -1553,6 +1553,69 @@ This is useful when you want to know exactly what Spack will do when
you ask for a particular spec.


``Concretization Policies``
~~~~~~~~~~~~~~~~~~~~~~~~~~~

A user may have certain perferrences for how packages should
be concretized on their system. For example, one user may prefer packages
built with OpenMPI and the Intel compiler. Another user may prefer
packages be built with MVAPICH and GCC.

Spack can be configurated to prefer certain compilers, package
versions, depends_on, and variants during concretization.
The preferred configuration can be controlled via the
``~/.spack/packages.yaml`` file for user configuations, or the
``etc/spack/packages.yaml`` site configuration.


Here's an example packages.yaml file that sets preferred packages:

.. code-block:: sh

packages:
dyninst:
compiler: [gcc@4.9]
variants: +debug
gperftools:
version: [2.2, 2.4, 2.3]
all:
compiler: [gcc@4.4.7, gcc@4.6:, intel, clang, pgi]
providers:
mpi: [mvapich, mpich, openmpi]


At a high level, this example is specifying how packages should be
concretized. The dyninst package should prefer using gcc 4.9 and
be built with debug options. The gperftools package should prefer version
2.2 over 2.4. Every package on the system should prefer mvapich for
its MPI and gcc 4.4.7 (except for Dyninst, which overrides this by perfering gcc 4.9).
These options are used to fill in implicit defaults. Any of them can be overwritten
on the command line if explicitly requested.

Each packages.yaml file begin with the string ``packages:`` and
package names are specified on the next level. The special string ``all``
applies settings to each package. Underneath each package name is
one or more components: ``compiler``, ``variants``, ``version``,
or ``providers``. Each component has an ordered list of spec
``constraints``, with earlier entries in the list being prefered over
later entries.

Sometimes a package installation may have constraints that forbid
the first concretization rule, in which case Spack will use the first
legal concretization rule. Going back to the example, if a user
requests gperftools 2.3 or later, then Spack will install version 2.4
as the 2.4 version of gperftools is preferred over 2.3.

An explicit concretization rule in the preferred section will always
take preference over unlisted concretizations. In the above example,
xlc isn't listed in the compiler list. Every listed compiler from
gcc to pgi will thus be preferred over the xlc compiler.

The syntax for the ``provider`` section differs slightly from other
concretization rules. A provider lists a value that packages may
``depend_on`` (e.g, mpi) and a list of rules for fulfilling that
dependency.

.. _install-method:

Implementing the ``install`` method
Expand Down
151 changes: 69 additions & 82 deletions lib/spack/docs/site_configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,88 +54,75 @@ more elements to the list to indicate where your own site's temporary
directory is.


.. _concretization-policies:

Concretization policies
----------------------------

When a user asks for a package like ``mpileaks`` to be installed,
Spack has to make decisions like what version should be installed,
what compiler to use, and how its dependencies should be configured.
This process is called *concretization*, and it's covered in detail in
:ref:`its own section <abstract-and-concrete>`.

The default concretization policies are in the
:py:mod:`spack.concretize` module, specifically in the
:py:class:`spack.concretize.DefaultConcretizer` class. These are the
important methods used in the concretization process:

* :py:meth:`concretize_version(self, spec) <spack.concretize.DefaultConcretizer.concretize_version>`
* :py:meth:`concretize_architecture(self, spec) <spack.concretize.DefaultConcretizer.concretize_architecture>`
* :py:meth:`concretize_compiler(self, spec) <spack.concretize.DefaultConcretizer.concretize_compiler>`
* :py:meth:`choose_provider(self, spec, providers) <spack.concretize.DefaultConcretizer.choose_provider>`

The first three take a :py:class:`Spec <spack.spec.Spec>` object and
modify it by adding constraints for the version. For example, if the
input spec had a version range like `1.0:5.0.3`, then the
``concretize_version`` method should set the spec's version to a
*single* version in that range. Likewise, ``concretize_architecture``
selects an architecture when the input spec does not have one, and
``concretize_compiler`` needs to set both a concrete compiler and a
concrete compiler version.

``choose_provider()`` affects how concrete implementations are chosen
based on a virtual dependency spec. The input spec is some virtual
dependency and the ``providers`` index is a :py:class:`ProviderIndex
<spack.packages.ProviderIndex>` object. The ``ProviderIndex`` maps
the virtual spec to specs for possible implementations, and
``choose_provider()`` should simply choose one of these. The
``concretize_*`` methods will be called on the chosen implementation
later, so there is no need to fully concretize the spec when returning
it.

The ``DefaultConcretizer`` is intended to provide sensible defaults
for each policy, but there are certain choices that it can't know
about. For example, one site might prefer ``OpenMPI`` over ``MPICH``,
or another might prefer an old version of some packages. These types
of special cases can be integrated with custom concretizers.

Writing a custom concretizer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To write your own concretizer, you need only subclass
``DefaultConcretizer`` and override the methods you want to change.
For example, you might write a class like this to change *only* the
``concretize_version()`` behavior:

.. code-block:: python

from spack.concretize import DefaultConcretizer

class MyConcretizer(DefaultConcretizer):
def concretize_version(self, spec):
# implement custom logic here.

Once you have written your custom concretizer, you can make Spack use
it by editing ``globals.py``. Find this part of the file:

.. code-block:: python

#
# This controls how things are concretized in spack.
# Replace it with a subclass if you want different
# policies.
#
concretizer = DefaultConcretizer()

Set concretizer to *your own* class instead of the default:

.. code-block:: python

concretizer = MyConcretizer()

The next time you run Spack, your changes should take effect.

External Packages
~~~~~~~~~~~~~~~~~~~~~
Spack can be configured to use externally-installed
packages rather than building its own packages. This may be desirable
if machines ship with system packages, such as a customized MPI
that should be used instead of Spack building its own MPI.

External packages are configured through the ``packages.yaml`` file found
in a Spack installation's ``etc/spack/`` or a user's ``~/.spack/``
directory. Here's an example of an external configuration:

.. code-block:: yaml

packages:
openmpi:
paths:
openmpi@1.4.3%gcc@4.4.7=chaos_5_x86_64_ib: /opt/openmpi-1.4.3
openmpi@1.4.3%gcc@4.4.7=chaos_5_x86_64_ib+debug: /opt/openmpi-1.4.3-debug
openmpi@1.6.5%intel@10.1=chaos_5_x86_64_ib: /opt/openmpi-1.6.5-intel

This example lists three installations of OpenMPI, one built with gcc,
one built with gcc and debug information, and another built with Intel.
If Spack is asked to build a package that uses one of these MPIs as a
dependency, it will use the the pre-installed OpenMPI in
the given directory. This example also specifies that Spack should never
build its own OpenMPI via the ``nobuild: True`` option.

Each ``packages.yaml`` begins with a ``packages:`` token, followed
by a list of package names. To specify externals, add a ``paths``
token under the package name, which lists externals in a
``spec : /path`` format. Each spec should be as
well-defined as reasonably possible. If a
package lacks a spec component, such as missing a compiler or
package version, then Spack will guess the missing component based
on its most-favored packages, and it may guess incorrectly.

Each package version and compilers listed in an external should
have entries in Spack's packages and compiler configuration, even
though the package and compiler may not every be built.

The packages configuration can tell Spack to use an external location
for certain package versions, but it does not restrict Spack to using
external packages. In the above example, if an OpenMPI 1.8.4 became
available Spack may choose to start building and linking with that version
rather than continue using the pre-installed OpenMPI versions.

To prevent this, the ``packages.yaml`` configuration also allows packages
to be flagged as non-buildable. The previous example could be modified to
be:

.. code-block:: yaml

packages:
openmpi:
paths:
openmpi@1.4.3%gcc@4.4.7=chaos_5_x86_64_ib: /opt/openmpi-1.4.3
openmpi@1.4.3%gcc@4.4.7=chaos_5_x86_64_ib+debug: /opt/openmpi-1.4.3-debug
openmpi@1.6.5%intel@10.1=chaos_5_x86_64_ib: /opt/openmpi-1.6.5-intel
nobuild: True

The addition of the ``nobuild`` flag tells Spack that it should never build
its own version of OpenMPI, and it will instead always rely on a pre-built
OpenMPI. Similar to ``paths``, ``nobuild`` is specified as a property under
a package name.

The ``nobuild`` does not need to be paired with external packages.
It could also be used alone to forbid packages that may be
buggy or otherwise undesirable.


Profiling
~~~~~~~~~~~~~~~~~~~~~
Expand Down
14 changes: 14 additions & 0 deletions lib/spack/spack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@
from spack.directory_layout import YamlDirectoryLayout
install_layout = YamlDirectoryLayout(install_path)

#
# This controls how packages are sorted when trying to choose
# the most preferred package. More preferred packages are sorted
# first.
#
from spack.preferred_packages import PreferredPackages
pkgsort = PreferredPackages()

#
# This tests ABI compatibility between packages
#
from spack.abi import ABI
abi = ABI()

#
# This controls how things are concretized in spack.
# Replace it with a subclass if you want different
Expand Down