Table of Contents
What Environment Modules Are in an HPC Context
On HPC systems, you rarely install software yourself into system directories. Instead, many versions of compilers, MPI stacks, math libraries, and applications are pre-installed and exposed through environment modules.
An environment module is a small configuration file that, when loaded, modifies your shell environment (e.g. PATH, LD_LIBRARY_PATH) so that a particular software stack becomes available. The most common implementations are Environment Modules and Lmod, but from a user’s perspective they behave similarly and are driven by the module command.
Key ideas:
- Multiple versions of the same software can coexist (e.g.
gcc/9.3.0,gcc/12.1.0). - You choose which version to use by
module load .... - Modules can depend on other modules (e.g. an MPI module depending on a compiler module).
- Your environment is reproducible if you record which modules were loaded.
Modules are central to how software environments are managed on clusters and supercomputers.
Basic `module` Command Usage
Most systems provide a module command that works similarly across sites.
Common subcommands:
module avail— list available modulesmodule list— list currently loaded modulesmodule spider— search (Lmod-specific, but common)module load— load a modulemodule unload— unload a modulemodule purge— unload all modulesmodule showormodule display— inspect what a module does
Examples:
# List all modules that are currently loaded in your session
module list
# See what modules are available (may be long)
module avail
# Search for modules whose name or description contains "fft"
module spider fft
# Load a specific compiler and MPI stack
module load gcc/12.1.0
module load openmpi/4.1.5
# Unload a module
module unload openmpi/4.1.5
# Remove all currently loaded modules
module purge
# Inspect what environment changes a module will apply
module show openmpi/4.1.5Exact syntax may vary slightly depending on your system, but this pattern is widespread.
How Modules Modify Your Environment
When you module load something, several environment variables are typically adjusted:
PATH— so the right executables are found first.LD_LIBRARY_PATH(or equivalent) — so the correct libraries are used at link and run time.CPATH,LIBRARY_PATH,PKG_CONFIG_PATH— to help compilers and build systems find headers and libraries.- Application-specific variables like
MKLROOT,CUDA_HOME, etc.
A simplified view:
- Before loading:
PATH = /usr/bin:/bin:...- After
module load gcc/12.1.0: PATH = /path/to/gcc/12.1.0/bin:/usr/bin:/bin:...
Then when you type gcc, the system finds /path/to/gcc/12.1.0/bin/gcc first.
Inspect with:
module show gcc/12.1.0This will print operations like:
prepend-path PATH /path/to/gcc/12.1.0/binprepend-path LD_LIBRARY_PATH /path/to/gcc/12.1.0/lib64setenv GCC_VERSION 12.1.0
You normally do not need to modify these variables manually; rely on modules instead.
Module Naming Conventions and Hierarchies
HPC sites use naming schemes to manage complexity. You will commonly see:
- Plain names with versions:
gcc/9.3.0,gcc/12.1.0openmpi/4.1.5,mpich/4.0- Compiler/MPI “toolchains”:
foss/2022a(Free/Open Source Stack)intel/2023.1- Compiler-aware modules:
openmpi/4.1.5-gcc-12.1.0fftw/3.3.10-intel-2023.1-mpi
Larger systems often use module hierarchies:
- You first load a compiler module:
module load gcc/12.1.0- This exposes MPI modules compatible with that compiler:
module availnow showsopenmpi/4.1.5,mpich/4.0- After loading MPI, compatible libraries appear:
fftw/mpi,hdf5/mpi,petsc/...
This hierarchical approach reduces conflicts and keeps you from mixing incompatible components.
Managing Conflicts and Incompatible Modules
Modules that cannot be used together may conflict. Common patterns:
- Only one major compiler family at a time (e.g.
gccvsintelvsnvhpc). - Only one MPI implementation at a time (e.g.
openmpivsmpich).
If a conflict arises, you might see a message like:
$ module load intel/2023.1
Lmod has detected the following error: These module(s) exist but cannot be loaded ...
"intel/2023.1" is not compatible with the currently loaded "gcc/12.1.0"Typical resolutions:
- Purge and reload:
module purge
module load intel/2023.1
module load impi/2021.9- Or unload just the conflicting module:
module unload gcc/12.1.0
module load intel/2023.1To avoid confusion, keep your environment minimal: load only what you need.
Typical Usage Patterns in Day-to-Day Work
In a normal HPC session, your workflow might look like:
- Start from a clean environment:
module purge- Load a compiler (and optionally a toolchain):
module load gcc/12.1.0
# or a bundle/toolchain
module load foss/2022a- Load MPI and libraries (often part of the toolchain, but sometimes separate):
module load openmpi/4.1.5
module load fftw/3.3.10
module load hdf5/1.12.2-mpi- Compile your application using the compilers and libraries from the loaded modules.
- Record loaded modules for reproducibility (see below).
You might use different module combinations for different projects, compilers, or architectures.
Saving and Restoring Module Environments
To ensure you can later recreate a working setup, you should save the module state or at least document it.
Saving a list manually
Simple and robust:
module listCopy the output into your notes, a README, or your job script as comments.
Using built-in save/restore (if available)
Many systems with Lmod offer environment collections:
- Save:
module save myproject-env- List collections:
module savelist- Restore later:
module restore myproject-envThis reloads the same module set in new sessions, which is particularly useful for long-lived projects.
Using Modules in Shell Startup Files
To avoid typing the same module load commands repeatedly, you might add some to your shell startup file (e.g. ~/.bashrc, ~/.bash_profile, ~/.profile), but there are trade-offs.
Example
In ~/.bashrc:
# Minimal default environment
module purge
module load gcc/12.1.0
module load openmpi/4.1.5This ensures that interactive logins start with a consistent baseline.
Pros
- Convenient for interactive use.
- Less repetition of common
module loadcommands.
Cons / caveats
- Job scripts might unintentionally inherit this environment, which can:
- Conflict with what the job script expects.
- Break cluster-provided examples that assume a clean environment.
- Site policies sometimes discourage or restrict heavy module changes in startup files.
A common best practice for HPC is:
- Keep startup files minimal.
- For jobs, explicitly load modules in each job script (see next section).
Modules Inside Job Scripts
On HPC systems, batch job scripts (e.g. for SLURM) should explicitly define the software environment they need, so that:
- Runs are reproducible.
- They don’t depend on your interactive shell setup.
- Other users (or future you) can re-run them without guesswork.
A typical job script fragment:
#!/bin/bash
#SBATCH --job-name=myjob
#SBATCH --time=01:00:00
#SBATCH --nodes=1
#SBATCH --ntasks=4
# Start from a clean environment
module purge
# Load exactly the modules needed for this job
module load gcc/12.1.0
module load openmpi/4.1.5
module load hdf5/1.12.2-mpi
# Optionally record for debugging:
module list
# Compile or run your program
srun ./my_programKey points:
module purgeat the top avoids surprises from inherited environments.module listinside the job’s output is very helpful when debugging or comparing runs.- If you later change module versions, that change is clearly visible in the script.
Site-Specific Module Collections and Defaults
Many HPC centers define system-wide module collections or default environments:
- A default set of core modules is often loaded automatically at login:
- Compiler and MPI
- Basic tools (e.g.
cmake,git,python) - There may be named collections like:
module load StdEnv/2023module load default-env
Things to be aware of:
- Document site defaults: They may change over time (e.g. yearly updates).
- If you rely on defaults, your environment might shift between system upgrades.
- For robust workflows, prefer explicit
module loadstatements in scripts, rather than relying solely on defaults.
Discovering and Searching for Software
When you need a piece of software but don’t know whether it’s available:
- Try
module availwith a substring:
module avail fftw
module avail cuda
module avail python- Use
module spider(Lmod):
module spider gromacs
module spider mumpsThis often shows:
- Available versions
- Dependencies (e.g. which compiler/MPI stack to load first)
- Usage examples from the system administrators
- If you can’t find a package:
- Check system documentation or a site-specific software list.
- Contact the support team; they may:
- Tell you which module provides it under a non-obvious name.
- Install it for you.
- Suggest alternatives.
Best Practices for Working with Modules
To use environment modules effectively on HPC systems:
- Be explicit in scripts:
- Always load required modules in your job scripts.
- Prefer
module purgeat the start of scripts for cleanliness. - Keep environments simple:
- Load only what you need.
- Avoid mixing multiple compilers or MPI libraries in the same environment.
- Record your setup:
- Copy
module listoutput into logs or README files. - Use
module saveif your site supports it. - Avoid hidden magic:
- Don’t rely heavily on complex startup files that automatically load many modules.
- Be wary of blindly copying someone else’s
module loadsequence without understanding it. - Use site documentation:
- Many centers have recommended module sets for particular applications or workflows.
- Follow their examples as starting points.
Environment modules are the primary tool for managing software on HPC clusters; mastering basic module commands and practices is essential for building, running, and reproducing scientific applications in this environment.