Skip to content

Commit 98c6754

Browse files
committed
Edit the environments tutorial to make it even easier to read and understand
1 parent 9915291 commit 98c6754

1 file changed

Lines changed: 107 additions & 100 deletions

File tree

tutorial_environments.rst

Lines changed: 107 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,52 @@
1010
Environments Tutorial
1111
=====================
1212

13-
We've covered how to install, remove, and list packages with Spack using the commands:
13+
So far in this tutorial, we've covered the basic commands for managing individual packages:
1414

15-
* `spack install <https://spack.readthedocs.io/en/latest/basic_usage.html#cmd-spack-install>`_ to install packages;
16-
* `spack uninstall <https://spack.readthedocs.io/en/latest/basic_usage.html#cmd-spack-uninstall>`_ to remove them; and
17-
* `spack find <https://spack.readthedocs.io/en/latest/basic_usage.html#cmd-spack-find>`_ to look at and query what is installed.
15+
* `spack install <https://spack.readthedocs.io/en/latest/basic_usage.html#cmd-spack-install>`_ to install packages
16+
* `spack uninstall <https://spack.readthedocs.io/en/latest/basic_usage.html#cmd-spack-uninstall>`_ to remove them
17+
* `spack find <https://spack.readthedocs.io/en/latest/basic_usage.html#cmd-spack-find>`_ to view and query installed packages
1818

1919
.. Customizing Spack's installation with configuration files, like
2020
`packages.yaml <https://spack.readthedocs.io/en/latest/build_settings.html#build-settings>`_, was also discussed.
2121
22-
This section of the tutorial introduces **Spack Environments**, which allow you to work with independent groups of packages separately, in a reproducible way.
23-
In some ways, Spack environments are similar to *virtual environments* in other systems (e.g., `Python venv <https://docs.python.org/3/library/venv.html>`_), but they are based around file formats (``spack.yaml`` and ``spack.lock``) that can be shared easily and re-used by others across systems.
22+
Now we'll explore Spack Environments -- a powerful feature that let's us manage collections of packages together in a documented and reproducible way.
23+
Spack environments are similar to *virtual environments* in other package managers (e.g., `Python venv <https://docs.python.org/3/library/venv.html>`_ or `nix-env <https://nix.dev/manual/nix/2.24/command-ref/nix-env>`_).
2424

25-
Administering properly configured software involving lots of packages and/or varying configuration requirements (e.g., different implementations of ``mpi``) for multiple projects and efforts can be overwhelming.
26-
Spack environments allow you to readily:
25+
-------------------------------
26+
What Makes a Spack Environment?
27+
-------------------------------
2728

28-
* establish standard software requirements for your project(s);
29-
* set up run environments for users;
30-
* support your usual development environment(s);
31-
* set up packages for CI/CD;
32-
* reproduce builds (approximately or exactly) on other machines; and
33-
* much more.
29+
Spack environments are based around two key files that can be easily shared and reused across different systems:
3430

35-
This tutorial introduces the basics of creating and using environments, then explains how to expand, configure, and build software in them.
36-
We will start with the command line interface, then cover editing key environment files directly.
37-
We will describe the difference between Spack-managed and independent environments, then finish with a section on reproducible builds.
31+
* ``spack.yaml`` -- The main configuration file where we specify which packages to install, compilers to use, and other Spack settings.
32+
33+
* ``spack.lock`` -- A lockfile that captures the complete provenance of you environment, enabling reproduction of software environments.
34+
35+
---------------------
36+
Why Use Environments?
37+
---------------------
38+
39+
Managing complex software setups with multiple packages and varying configuration (like different MPI) can quickly become overwhelming.
40+
Spack environments solve this by letting you:
41+
42+
* Establish standard software requirements for your project(s)
43+
* Set up consistent runtime environments for your users
44+
* Maintain reproducible development environments
45+
* Configure packages for CI/CD pipelines
46+
* Share and reproduce builds across different machines
47+
* Document your software stack for collaboration
48+
* And much more
49+
50+
----------------------
51+
Goals of this Tutorial
52+
----------------------
53+
This tutorial will teach you the fundamentals of creating and using Spack environments.
54+
We'll cover:
55+
1. Command line basics -- Creating and managing environments with Spack commands.
56+
2. Configuration files -- Editing ``spack.yaml`` and understanding ``spack.lock``.
57+
3. Environment types -- Understanding Spack-managed vs independent environments.
58+
4. Reproducible builds -- Sharing and recreating environments across systems.
3859

3960
-------------------
4061
Environment Basics
@@ -46,108 +67,99 @@ Let's look at the output of ``spack find`` at this point in the tutorial.
4667
:language: console
4768

4869

49-
This is a complete, but cluttered list of the installed packages and their dependencies.
70+
This is a complete, but cluttered list of all our installed packages and their dependencies.
5071
It contains packages built with both ``openmpi`` and ``mpich``, as well as multiple variants of other packages, like ``hdf5`` and ``zlib-ng``.
51-
The query mechanism we learned about with ``spack find`` can help, but it would be nice if we could start from a clean slate without losing what we've already installed.
72+
The query mechanism we learned about with ``spack find`` can help, but it would be nice if we could see only the software that is relevant to our current project instead of seeing everything on the machine.
5273

5374
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
54-
Creating and activating environments
75+
Creating and Activating Environments
5576
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5677

57-
The ``spack env`` command can help.
58-
Let's create a new environment called ``myproject``:
78+
Let's create a new environment called ``myproject`` using the ``spack env create`` command:
5979

6080
.. literalinclude:: outputs/environments/env-create-1.out
6181
:language: console
6282

63-
64-
An environment is like a virtualized Spack instance that you can use to aggregate package installations for a project or other purpose.
65-
It has an associated *view*, which is a single prefix where all packages from the environment are linked.
66-
67-
You can see the environments we've created so far using the ``spack env list`` command:
83+
To see all of our environments we've created so far we can run ``spack env list``:
6884

6985
.. literalinclude:: outputs/environments/env-list-1.out
7086
:language: console
7187

7288

73-
Now let's **activate** our environment.
74-
You can use ``spack env activate`` command:
89+
.. note::
90+
Once we activate an environment it will show up highlighted in
91+
green in the list of environments.
92+
93+
Now let's **activate** our environment by running the ``spack env activate`` command:
7594

7695
.. literalinclude:: outputs/environments/env-activate-1.out
7796
:language: console
7897

7998
.. note::
80-
If you use the ``-p`` option for ``spack env activate``, Spack
81-
will prepend the environment name to the prompt. This is a handy
99+
If we use the ``-p`` option for ``spack env activate``, Spack
100+
will prepend the environment name to our shell prompt. This is a handy
82101
way to be reminded if and which environment you are in.
83102

84-
You can also use the shorter ``spacktivate`` alias for ``spack env activate``.
85-
86-
.. note::
87-
Alias behavior may vary depending on the shell interpreter used. In Bash,
88-
use of aliases requires the shell option ``expand_aliases`` to be set.
89-
This option is set by default, but it is not set in non-interactive shells,
90-
e.g., when executing a Bash script. In a Bash script, ``expand_aliases``
91-
can be set with the command ``shopt -s expand_aliases``.
92-
93-
94-
Once you activate an environment, ``spack find`` only shows what is in the current environment.
95-
We just created this environment, so it does not contain any installed packages.
103+
Once we activate an environment, ``spack find`` will only show what is in the current environment.
104+
For example, because we just created this environment the output below doesn't show any installed packages.
96105

97106
.. literalinclude:: outputs/environments/find-env-1.out
98107
:language: console
99108

100-
The output from ``spack find`` is now *slightly* different.
101-
It tells you that you're in the ``myproject`` environment, so there is no need to panic when you see that none of the previously installed packages are available.
109+
.. note::
110+
Although Spack doesn't show all installed software packages when
111+
in an active environment, Spack will reuse packages across
112+
environments to save disk space and reduce build times.
113+
114+
Additionally the output now tells us that we're in the ``myproject`` environment, so there is no need to panic when we no longer see our previously installed packages.
102115
It also states that there are **no** *root specs*.
103116
We'll get back to what that means later.
104117

105-
If you *only* want to check what environment you are in, you can use ``spack env status``:
118+
While this detailed output is useful, if we *only* want to check what environment we're are in, we can use ``spack env status``:
106119

107120
.. literalinclude:: outputs/environments/env-status-1.out
108121
:language: console
109122

110123

111-
If you want to leave this environment, you can use ``spack env deactivate`` or the ``despacktivate`` alias for short.
124+
To now exit out of this environment, we can use ``spack env deactivate``.
112125

113126
After deactivating, we can see everything installed in this Spack instance:
114127

115128
.. literalinclude:: outputs/environments/env-status-2.out
116129
:language: console
117130

118-
119-
Notice that we are no longer in an environment and all our packages are still installed.
120-
121131
^^^^^^^^^^^^^^^^^^^
122132
Installing packages
123133
^^^^^^^^^^^^^^^^^^^
124134

125-
Now that we understand how creation and activation work, let's go back to ``myproject`` and *install* a couple of packages, specifically, ``tcl`` and ``trilinos``.
135+
Now that we understand how creation and activation work, let's go back to our ``myproject`` enviornment and *install* a couple of packages, specifically, ``tcl`` and ``trilinos``.
126136

127-
Try the usual install command first:
137+
Let's try the usual install commands we learned earlier:
128138

129139
.. literalinclude:: outputs/environments/env-fail-install-1.out
130140
:language: console
131141

132-
Environments are special in that you must *add* specs to them before installing. ``spack add`` allows us to queue up several specs to be installed together.
142+
Environments are special in that we must *add* specs to the an environment before we can install them. This additional step helps prevent us from accidentally modifying a shared enviornment when installing new software.
143+
144+
``spack add`` allows us to queue up several specs to be installed together.
133145
Let's try it:
134146

135147
.. literalinclude:: outputs/environments/env-add-1.out
136148
:language: console
137149

138-
Now, ``tcl`` and ``trilinos`` have been registered as **root specs** in this environment.
139-
That is because we explicitly asked for them to be installed, so they are the **roots** of the combined graph of all packages we'll install.
150+
Now, ``tcl`` and ``trilinos`` have been registered as **root specs** in our environment. **Root specs** are packages that we've explicitly requested to be installed in an environment.
151+
They're called **"roots"** because they sit at the top of the dependency graph—when Spack installs these packages, with their respective depenedency packages sitting below them.
140152

141153
Now, let's install:
142154

143155
.. literalinclude:: outputs/environments/env-install-1.out
144156
:language: console
145157

158+
We can see that Spack reused existing installations of ``tcl`` and the dependencies of ``trilinos`` that were already present on the system, rather than rebuilding them from scratch.
146159

147-
We see that ``tcl`` and the dependencies of ``trilinos`` are already installed, and that ``trilinos`` was newly installed.
148-
We also see that the environment's view was updated to include the new installations.
160+
Additionally, the environment's view was automatically updated to include the installations. This means all the software in this environment has been added to our PATH, making the installed packages readily accessible from the command line while we have the environment activated.
149161

150-
Now confirm the contents of the environment using ``spack find``:
162+
Let's now confirm the contents of the environment using ``spack find``:
151163

152164
.. literalinclude:: outputs/environments/find-env-2.out
153165
:language: console
@@ -158,65 +170,60 @@ We can see that the roots and all their dependencies have been installed.
158170
Creating an environment incrementally
159171
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
160172

161-
As a short-hand, you can use the ``install --add`` flag to accomplish the same thing in one step:
162-
163-
.. code-block:: console
164-
165-
$ spack install --add tcl trilinos
166-
167-
This both adds the specs to the environment and installs them.
168-
169-
You can also add and install specs to an environment incrementally. For example:
173+
We can also add and install specs to an environment incrementally. For example:
170174

171175
.. code-block:: console
172176
173177
$ spack install --add tcl
174178
$ spack install --add trilinos
175179
176-
If you create environments incrementally, Spack ensures that already installed roots are not re-concretized.
180+
If we create environments incrementally, Spack ensures that already installed roots are not re-concretized.
177181
So, adding specs to an environment at a later point in time will not cause existing packages to rebuild.
178182

179-
Do note, however, that incrementally creating an environment can give you different package versions from an environment created all at once.
180-
We will cover this after we've discussed different concretization strategies.
183+
.. note::
184+
185+
Incrementally creating an environment may give us different package
186+
versions from an environment created all at once.
187+
We'll cover later in the tutorial this after we've discussed different
188+
concretization strategies.
189+
190+
Further, there are two other advantages of concretizing and installing an
191+
environment all at once:
181192

182-
Further, there are two other advantages of concretizing and installing an environment all at once:
183193

184-
* If you have a number of specs that can be installed together,
185-
adding them first and installing them together enables them to
186-
share dependencies and reduces total installation time.
194+
* If you have a number of specs that can be installed together,
195+
adding them first and installing them together enables them to
196+
share dependencies and reduces total installation time.
187197

188-
* You can launch all builds in parallel by taking advantage of Spack's `install-level build parallelism <https://spack.readthedocs.io/en/latest/packaging_guide.html#install-level-build-parallelism>`_.
198+
* You can launch all builds in parallel by taking advantage of Spack's
199+
`install-level build parallelism <https://spack.readthedocs.io/en/latest/packaging_guide.html#install-level-build-parallelism>`_.
189200

190201
^^^^^^^^^^^^^^
191202
Using packages
192203
^^^^^^^^^^^^^^
193204

194205
Environments provide a convenient way for using installed packages.
195-
Running ``spack env activate`` gives you everything in the environment on your ``PATH``.
196-
Otherwise, you would need to use `spack load <https://spack.readthedocs.io/en/latest/basic_usage.html#cmd-spack-load>`_ or `module load <https://spack.readthedocs.io/en/latest/module_file_support.html>`_ for each package in order to set up the environment for the package (and its dependencies).
206+
When we run ``spack env activate`` Spack by default prepends packages in the environment to our ``PATH``, ``MANPATH``, and ``CMAKE_PREFIX_PATH`` environment variables.
197207

198-
When you install packages into an environment, they are, by default, linked into a single prefix, or *view*.
199-
Activating the environment with ``spack env activate`` results in subdirectories from the view being added to ``PATH``, ``MANPATH``, ``CMAKE_PREFIX_PATH``, and other environment variables.
200-
This makes the environment easier to use.
208+
Let's try it out to get a better sense of how views are constructed and added to our shell environment.
201209

202-
Let's try it out.
203210
We just installed ``tcl`` into our ``myproject`` environment. ``Tcl`` includes a shell-like application called ``tclsh``.
204-
You can see the path to ``tclsh`` using ``which``:
211+
To can see the path to ``tclsh`` let's use ``which``:
205212

206213
.. literalinclude:: outputs/environments/use-tcl-1.out
207214
:language: console
208215

209216

210217
Notice its path includes the name of our environment *and* a ``view`` subdirectory.
211218

212-
You can now run ``tclsh`` like you would any other program that is in your path:
219+
We can now run ``tclsh`` just like you would any other program that is in your path:
213220

214221
.. code-block:: console
215222
216-
$ tclsh
217-
% echo "hello world!"
218-
hello world!
219-
% exit
223+
$ tclsh
224+
% echo "hello world!"
225+
hello world!
226+
% exit
220227
221228
^^^^^^^^^^^^^^^^^^^^^
222229
Uninstalling packages
@@ -406,24 +413,24 @@ Let's create a program called ``mpi-hello.c`` that contains the following code:
406413

407414
.. code-block:: c
408415
409-
#include <stdio.h>
410-
#include <mpi.h>
411-
#include <zlib.h>
416+
#include <stdio.h>
417+
#include <mpi.h>
418+
#include <zlib.h>
412419
413-
int main(int argc, char **argv) {
414-
int rank;
415-
MPI_Init(&argc, &argv);
420+
int main(int argc, char **argv) {
421+
int rank;
422+
MPI_Init(&argc, &argv);
416423
417-
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
418-
printf("Hello world from rank %d\n", rank);
424+
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
425+
printf("Hello world from rank %d\n", rank);
419426
420-
if (rank == 0) {
421-
printf("zlib version: %s\n", ZLIB_VERSION);
427+
if (rank == 0) {
428+
printf("zlib version: %s\n", ZLIB_VERSION);
422429
printf("zlib-ng version: %s\n", ZLIBNG_VERSION);
423-
}
430+
}
424431
425-
MPI_Finalize();
426-
}
432+
MPI_Finalize();
433+
}
427434
428435
This program includes headers from ``mpi`` and ``zlib``.
429436
It also prints out a message from each MPI rank and the version of ``zlib``.

0 commit comments

Comments
 (0)