a2eda2ebe98a6f2f61f14175b4238aaabf1fd18a
[dealii.wiki.git] / deal.II-in-Spack.md
1 # Using deal.II on Mac OS X and Linux via Spack
2
3 The deal.II suite is also available on Spack (https://github.com/LLNL/spack) -- a flexible package manager developed with High-Performance-Computing in mind. It is intended to let you build for many combinations of compiler, architectures, dependency libraries, and build configurations, all with a friendly, intuitive user interface.
4
5 For a quick overview of Spack's features, we recommend this short presentation https://tgamblin.github.io/files/Gamblin-Spack-SC15-Talk.pdf
6 or the following videos from lead developers:
7 [Massimiliano Culpo - SPACK: A Package Manager for Supercomputers, Linux and MacOS](https://www.youtube.com/watch?v=Qok-nXfIWfg) and 
8 [Todd Gamblin (LLNL) - Managing HPC Software Complexity with Spack](https://www.youtube.com/watch?v=Ie1cZTR09kk).
9
10 [Spack tutorial 101](http://spack.readthedocs.io/en/latest/tutorial.html) is good place to start as well.
11
12 Note: Spack is in active development and is in alpha state, thereby below we recommend using the specific snapshot of the code (hash), that was tested on macOS / Ubuntu / CentOS7 with deal.II and is being used to run the complete testsuite on `Unbutu16.04` with `openmpi` and `openblas`. See [Experimental section of CDash](https://cdash.kyomu.43-1.org/index.php?project=deal.II).
13
14 ## Quick installation on the desktop
15
16 Add the following to `~/.bashrc` (or equivalent)
17 ```
18 export SPACK_ROOT=/path/to/spack
19 PATH="$SPACK_ROOT/bin:$PATH"
20 ```
21 `SPACK_ROOT` is the destination where you want Spack to be installed (i.e. `$HOME/spack`).
22
23 Now clone Spack
24 ```
25 cd $SPACK_ROOT
26 git clone https://github.com/llnl/spack.git .
27 git checkout develop
28 git reset --hard 3e67b98e29579ae8203f308f9e14e2f1de8f7b77
29 ```
30
31 **Make sure C/C++/Fortran compilers are in path** (on Ubuntu you need to `sudo apt-get install gfortran`, on macOS you can compile `gcc` with spack, see [below](#installing-gcc), and you have **curl** (`sudo apt-get install curl`) to download packages. Then install the complete deal.II suite
32 ```
33 spack install dealii
34 ```
35 **DONE**! No extra (preliminary) configuration steps are needed on most Linux distributions. **IMPORTANT:** If you compile deal.II on a cluster, see the next section on how to use externally provided MPI implementation instead.
36
37 Before configuring your project you need to set `DEAL_II_DIR` by 
38 ```
39 export DEAL_II_DIR=$(spack location -i dealii)
40 ```
41 You may jump ahead and read [best practices using spack](#best-practices-using-spack). Also a good starting point is [Getting Started Guide](http://spack.readthedocs.io/en/latest/getting_started.html).
42
43
44 ## Installation example on a Centos7 cluster (Emmy cluster of RRZE, Erlangen, Germany)
45 In order to use Spack on a cluster, there are two options: (1) you are a sysadmin and you know hardware details and can use Spack to properly configure and build MPI providers (e.g. `openmpi`); (2) you are a user and you need to make Spack work with MPI provided on your cluster. Below we consider the latter case.
46
47 Here is a brief step-by-step instruction to install deal.II on [Emmy cluster](https://www.rrze.fau.de/dienste/arbeiten-rechnen/hpc/systeme/emmy-cluster.shtml#access) of RRZE, Erlangen, Germany:
48
49 (1) Download spack
50 ```
51 module load git
52 mkdir $WOODYHOME/spack
53 cd $WOODYHOME/spack
54 git clone https://github.com/llnl/spack.git $WOODYHOME/spack
55 git reset --hard 3e67b98e29579ae8203f308f9e14e2f1de8f7b77
56 export PATH=$WOODYHOME/spack/bin:$PATH
57 ```
58 (2) Load `openmpi` and let Spack find GCC compiler which is also loaded as a dependency:
59 ```
60 module load openmpi/2.0.2-gcc
61 spack compiler find
62 ```
63 (3) Add `openmpi` as an external package, along with `python` and a few other self explanatory setting for `deal.ii`. That is done by adding the following to `~/.spack/linux/packages.yaml`
64 ```
65 packages:
66   all:
67     compiler: [gcc]
68     providers:
69       mpi: [openmpi]
70       blas: [openblas]
71       lapack: [openblas]
72   openmpi:
73     version: [2.0.2]
74     paths:
75       openmpi@2.0.2%gcc@4.8.5: /apps/OpenMPI/2.0.2-gcc/
76     buildable: False
77   dealii:
78     variants: +optflags~python
79 ```
80 Those paths are the location where external packages can be found (i.e. `<prefix>` instead of `<prefix>/bin` or `<prefix>/lib`). `providers` section essentially tells Spack which packages to use to satisfy virtual dependencies such as `MPI`, `BLAS`, `LAPACK`, `ScaLAPACK`, etc.
81
82 (4) Now install deal.II:  `spack install dealii`.
83
84 ## Environment Modules
85 Spack provides some integration with Environment Modules and Dotkit to make it easier to use the packages it installs. For a full description, read http://spack.readthedocs.io/en/latest/getting_started.html#environment-modules
86
87 To add the support for Environment Modules run
88 ```
89 spack install environment-modules
90 ```
91 Get the path to the prefix of `environment-modules` by:
92 ```
93 spack location --install-dir environment-modules
94 ```
95 and then add to `~/.bashrc` (or equivalent)
96 ```
97 MODULES_HOME=/path/to/environment-modules
98 source ${MODULES_HOME}/Modules/init/bash
99 . $SPACK_ROOT/share/spack/setup-env.sh
100 ```
101
102 If you install `deal.II` before setting up environment modules,
103 the module files have to be regenerated
104 ```
105 spack module refresh
106 ```
107
108 Then run
109 ```
110 spack load dealii
111 spack load cmake
112 ```
113 Now `DEAL_II_DIR` environment variable should be set appropriately and `cmake` executable will be available in path. Keep in mind that `spack load dealii` will also set `LD_LIBRARY_PATH` accordingly, this may or may not be what you need. An alternative is to use `export DEAL_II_DIR=$(spack location -i dealii)`.
114
115 ## System provided packages
116 Spack is flexible to use both self-compiled and system provided packages. 
117 In most cases this is desirable for `MPI`, which is already installed on computational clusters. To configure external packages you need to edit `~/.spack/linux/packages.yaml`. For `openmpi` this could be
118 ```
119 packages:
120   openmpi:
121     version: [1.8.8]
122     paths:
123       openmpi@1.8.8%gcc@6.2.0: /opt/openmpi-1.8.8
124     buildable: False
125 ```
126 In order to make sure that we use to build packages `1.8.8` version of `openmpi` and not the most recent one (i.e. `2.0.2`), we specified conretization preferences with `version: [1.8.8]`.
127
128 One can also specify which packages should be used to provide `mpi`, `blas/lapack` , preferred compilers and preferred variants:
129 ```
130 packages:
131   all:
132     compiler: [gcc,clang]
133     providers:
134       mpi: [openmpi]
135       blas: [openblas]
136       lapack: [openblas]
137     boost:
138       variants: +python
139 ```
140
141 For more elaborated discussion, see [Configuration Files in Spack](http://spack.readthedocs.io/en/latest/configuration.html).
142
143 ## Installing GCC
144 If your system does not provide any Fortran compiler or you want to have the most recent `gcc`,
145 you can install it by
146 ```
147 spack install gcc
148 ```
149
150 Assuming that you configured [Environment Modules](#environment-modules), load `gcc` and let Spack find the newly installed compilers:
151 ```
152 spack load gcc
153 spack compiler find
154 ```
155 Now you can install deal.II with `gcc`
156 ```
157 spack install dealii%gcc
158 ```
159
160 If you are on the mac, read the following instructions on [Mixed Toolchains](http://spack.readthedocs.io/en/latest/getting_started.html#mixed-toolchains).
161
162 On following these instructions, you will be able to install deal.II with clang+gfortran
163 ```
164 spack install dealii%clang
165 ```
166
167 ## Best practices using Spack:
168
169 Spack is complicated and flexible package manager primarily aimed at High-Performance-Computing.
170 Below are some examples of using Spack to build and develop deal.II:
171
172 ### Info:
173 If you are not sure which options a given package has, simply run
174 ```
175 spack info <package>
176 ```
177 The output will contain available versions, variants, dependencies and description:
178 ```
179 $ spack info dealii
180 CMakePackage:   dealii
181
182 Description:
183     C++ software library providing well-documented tools to build finite
184     element codes for a broad variety of PDEs.
185
186 Homepage: https://www.dealii.org
187
188 Preferred version:  
189     8.5.1      https://github.com/dealii/dealii/releases/download/v8.5.1/dealii-8.5.1.tar.gz
190
191 Safe versions:  
192     develop    [git] https://github.com/dealii/dealii.git
193     8.5.1      https://github.com/dealii/dealii/releases/download/v8.5.1/dealii-8.5.1.tar.gz
194     8.5.0      https://github.com/dealii/dealii/releases/download/v8.5.0/dealii-8.5.0.tar.gz
195     8.4.2      https://github.com/dealii/dealii/releases/download/v8.4.2/dealii-8.4.2.tar.gz
196     8.4.1      https://github.com/dealii/dealii/releases/download/v8.4.1/dealii-8.4.1.tar.gz
197     8.4.0      https://github.com/dealii/dealii/releases/download/v8.4.0/dealii-8.4.0.tar.gz
198     8.3.0      https://github.com/dealii/dealii/releases/download/v8.3.0/dealii-8.3.0.tar.gz
199     8.2.1      https://github.com/dealii/dealii/releases/download/v8.2.1/dealii-8.2.1.tar.gz
200     8.1.0      https://github.com/dealii/dealii/releases/download/v8.1.0/dealii-8.1.0.tar.gz
201
202 Variants:
203     Name [Default]               Allowed values          Description
204
205
206     adol-c [off]                 True, False             Compile with Adol-c
207     arpack [on]                  True, False             Compile with Arpack and
208                                                          PArpack (only with MPI)
209     build_type [DebugRelease]    Debug, Release,         The build type to build
210                                  DebugRelease            
211     doc [off]                    True, False             Compile with documentation
212     gsl [on]                     True, False             Compile with GSL
213     hdf5 [on]                    True, False             Compile with HDF5 (only with
214                                                          MPI)
215     int64 [off]                  True, False             Compile with 64 bit indices
216                                                          support
217     metis [on]                   True, False             Compile with Metis
218     mpi [on]                     True, False             Compile with MPI
219     nanoflann [off]              True, False             Compile with Nanoflann
220     netcdf [on]                  True, False             Compile with Netcdf (only with
221                                                          MPI)
222     oce [on]                     True, False             Compile with OCE
223     optflags [off]               True, False             Compile using additional
224                                                          optimization flags
225     p4est [on]                   True, False             Compile with P4est (only with
226                                                          MPI)
227     petsc [on]                   True, False             Compile with Petsc (only with
228                                                          MPI)
229     python [on]                  True, False             Compile with Python bindings
230     slepc [on]                   True, False             Compile with Slepc (only with
231                                                          Petsc and MPI)
232     sundials [off]               True, False             Compile with Sundials
233     trilinos [on]                True, False             Compile with Trilinos (only
234                                                          with MPI)
235
236 Installation Phases:
237     cmake    build    install
238
239 Build Dependencies:
240     adol-c     cmake     hdf5     muparser    oce     slepc         trilinos
241     arpack-ng  doxygen   lapack   nanoflann   p4set   suite-sparse  zlib
242     blas       graphivz  metis    netcdf      petsc   sundials      
243     boost      gsl       mpi      netcdf-cxx  python  tbb
244
245 Link Dependencies:
246     adol-c     doxygen   lapack   nanoflann   p4est   suite-sparse  zlib
247     arpack-ng  graphviz  metis    netcdf      petsc   sundials      
248     blas       graphviz  mpi      netcdf-cxx  python  tbb
249     boost      hdf5      muparser oce         slepc   trilinos
250
251 Run Dependencies:
252     None
253
254 Virtual Packages: 
255     None
256 ```
257
258 A lot of `spack` commands have help, for example
259 ```
260 $ spack install -h
261 usage: spack install [-h] [--only {package,dependencies}] [-j JOBS]
262                      [--keep-prefix] [--keep-stage] [--restage] [-n] [-v]
263                      [--fake] [-f] [--clean | --dirty] [--run-tests]
264                      [--log-format {junit}] [--log-file LOG_FILE]
265                      ...
266
267 build and install packages
268
269 positional arguments:
270   package               spec of the package to install
271
272 optional arguments:
273   -h, --help            show this help message and exit
274   --only {package,dependencies}
275                         select the mode of installation. the default is to
276                         install the package along with all its dependencies.
277                         alternatively one can decide to install only the
278                         package or only the dependencies
279   -j JOBS, --jobs JOBS  explicitly set number of make jobs. default is #cpus
280   --keep-prefix         don't remove the install prefix if installation fails
281   --keep-stage          don't remove the build stage if installation succeeds
282   --restage             if a partial install is detected, delete prior state
283   -n, --no-checksum     do not check packages against checksum
284   -v, --verbose         display verbose build output while installing
285   --fake                fake install. just remove prefix and create a fake
286                         file
287   -f, --file            install from file. Read specs to install from .yaml
288                         files
289   --clean               clean environment before installing package
290   --dirty               do NOT clean environment before installing
291   --run-tests           run package level tests during installation
292   --log-format {junit}  format to be used for log files
293   --log-file LOG_FILE   filename for the log file. if not passed a default
294                         will be used
295 ```
296
297 ### Extra options:
298 One can specify extra options for packages in the deal.II suite. For example if you want to have boost with `python` module, this can be done by
299 ```
300 spack install dealii@develop+mpi~python ^boost+python
301 ```
302
303 If you want to specify blas/lapack/mpi implementations, this can be done similarly
304 ```
305 spack install dealii@develop+mpi ^mpich
306 ```
307 To check which packages implement `mpi` run
308 ```
309 spack providers mpi
310 ```
311 One can also specify which Blas/Lapack implementation to use. For example to build deal.II suite with `atlas` run
312 ```
313 spack install dealii ^atlas
314 ```
315
316 ### Compiler flags
317 You can specify compiler flags on the command line as
318 ```
319 spack install dealii cppflags="-march=native -O3"
320 ```
321 Note that these flags will be inherited by dependencies such as `petsc`, `trilinos`, etc. Same can be done by declaring these flags in `~/.spack/compilers.yaml`:
322 ```
323 compilers:
324 - compiler:
325     modules: []
326     operating_system: centos6
327     paths:
328       cc: /usr/bin/gcc
329       cxx: /usr/bin/g++
330       f77: /usr/bin/gfortran
331       fc: /usr/bin/gfortran
332     flags:
333       cflags: -O3 -fPIC
334       cxxflags: -O3 -fPIC
335       cppflags: -O3 -fPIC
336     spec: gcc@4.7.2
337 ```
338
339 If you want to use flags for `dealii` only, you can first build all the dependencies without flags and then build `dealii` with custom flags:
340 ```
341 spack install --only dependencies dealii
342 spack install dealii cppflags="-march=native -O3"
343 ```
344
345 See this [google forum topic](https://groups.google.com/forum/?fromgroups#!topic/dealii/3Yjy8CBIrgU) for discussion on which flags to use. You can also use `spack install dealii+optflags` to enable extra optimization flags in release build.
346
347 ### Different versions coexisting:
348 One can easily have slightly different versions of deal.II side-by-side, e.g. to compile development version of deal.II with complex-valued PETSc and `gcc` compiler run
349 ```
350 spack install dealii@develop+mpi+petsc~int64%gcc ^petsc+complex~hypre
351 ```
352 The good thing is that if you already have deal.ii built with real-valued petsc, then only `petsc`, `slepc` and `deal.ii` itself will be rebuild. Everything else (`trilinos`, `mumps`, `metis`, etc) will be reused.
353
354 One can use `environment-modules` (see above) to automatically set `DEAL_II_DIR` to the complex version: 
355 ```
356 spack load dealii@develop+mpi+petsc~int64%gcc ^petsc+complex~hypre
357 ```
358
359 ### Filesystem Views:
360 If you prefer to have the whole dealii suite (and possible something else) symlinked into a single path (like `/usr/local`), one can use [Filesystem Views](http://spack.readthedocs.io/en/latest/workflows.html#filesystem-views):
361 ```
362 spack view -v symlink dealii_suite dealii@develop
363 ```
364 You can also add to this view other packages, i.e.
365 ```
366 spack view -v symlink dealii_suite the-silver-searcher
367 ```
368
369
370 ### Check before build:
371 It is often convenient to check which version of packages, compilers, variants etc will be used before actually starting installation. That can be done by examining the concretized spec via `spack spec` command, e.g. 
372 ```
373 spack spec dealii@develop+mpi+petsc~int64%gcc ^petsc+complex~hypre
374 ```
375
376 The `spec` command has a useful flag `-I` which will show install status of dependencies in the graph.
377
378 ### Develop using Spack
379 Probably the easiest way to use Spack while contributing patches to the deal.II is the following. 
380 Install `deal.II` via Spack, go to its installation prefix and copy-paste the CMake command from `.spack/build.out`, which looks like
381 ```
382 'cmake' '/path/to/spack/var/spack/stage/dealii-develop-tkowxhk55kpi7facfh3ufipofyolt6h7/dealii' '-DCMAKE_INSTALL_PREFIX:PATH=path/to/spack/opt/spack/darwin-sierra-x86_64/clang-8.1.0-apple/dealii-develop-tkowxhk55kpi7facfh3ufipofyolt6h7' '-DCMAKE_BUILD_TYPE:STRING=DebugRelease' <more options>
383 ```
384 You would need to adjust the path to the `dea.II` source folder (first path) and should remove the `DCMAKE_INSTALL_PREFIX` as you probably don't want to accidentally override the version installed by Spack. 
385
386 Assuming that your build folder is within the `dealii` sources (tha'ts what `..\/` is for below), you can get this substitution done by
387 ```
388 $ cat $(spack location -i dealii)/.spack/build.out | grep "==> 'cmake'" | sed -e "s/[^ ]*[^ ]/'..\/'/3" | cut -d " " -f2-
389 ```
390
391 Before running `cmake` from the build folder, you may want to run 
392 ```
393 spack env dealii@develop+mpi^openmpi^openblas bash
394 ```
395 to make sure your environment (paths, variables, etc) is set exactly the same way as when compiling `deal.II` from Spack
396 (adjust the spec `dealii@develop+mpi^openmpi^openblas` to be what you use when you installed `deal.II`).
397
398 An alternative is to create a [Filesystem view](#filesystem-views) for an already installed library and then compile patched version of deal.II manually by providing path to the view for each dependency. 
399
400 ### Keep the stage to run unit tests
401 By default, the build folder (aka `stage`) for each package is created in a temporary system dependent location.
402 This gets purge by system on next restart.
403 If you want to keep the stage after the installation, you need to do two things:
404 First, make spack use a custom location for stage by adding the following to your `~/.spack/config.yaml`:
405 ```
406 config:
407   build_stage:
408     - $spack/var/spack/stage
409 ```
410 Second, prescribe an extra argument to `install` command to keep the stage after successful installation:
411 ```
412 spack install --keep-stage dealii@develop
413 ```
414
415 ### MKL and Licensed software
416 Spack supports installation of [licensed software](http://spack.readthedocs.io/en/latest/packaging_guide.html#license) as well as usage of [Licensed compilers](http://spack.readthedocs.io/en/latest/getting_started.html#licensed-compilers). For example in order to install MKL on Linux:
417
418 1. add `Intel` license file as `license.lic` file to `${SPACK_ROOT}/etc/spack/licenses/intel/`.
419 2. run `spack install dealii ^intel-mkl@11.3.2.210`
420
421 In order to configure Intel compilers see [this page](http://spack.readthedocs.io/en/latest/getting_started.html#vendor-specific-compiler-configuration).
422
423
424 ### Freeze package versions
425 Currently Spack does not try to re-use already installed packages. On another hand, by default
426 the most recent version of a package will be installed. When updating deal.II build (for example to use the new version of `trilinos`), the combination of the two factors may lead to recompilation of many other packages used in the deal.II suite when one of the main build dependency like `cmake` has a new version.
427
428 To circumvent the problem, the user can specify preferred versions of packages in `~/.spack/packages.yaml`:
429 ```
430 packages:
431   cmake:
432     version: [3.6.1]
433   curl:
434     version: [7.50.3]
435   openssl:
436     version: [1.0.2j]
437   python:
438     version: [2.7.12]
439 ```
440 This settings will be taken into account during conretization process and thus will help to avoid rebuilding most of the deal.II suite when, for example, `openssl` is updated to the new version.

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.