This lesson is being piloted (Beta version)

Working with Anaconda and Pip

Overview

Teaching: 25 min
Exercises: 10 min
Questions
  • How does anaconda install software?

  • How can I use anaconda to create independent modules?

  • How can I keep my pip-installed packages separate?

Objectives
  • Learn how to use conda/mamba to create a module-compatible software environment

  • Learn how to install software into a conda environment using pip

License Issues

The company Anaconda that develops conda and provides several package repositories for it has changed their Terms of Service as of Spring 2024 to no longer accommodate free use of their licensed components by academic researchers. Discussion on how to proceed under these ToS within the community and within Anaconda, as well as between the community and Anaconda, is still ongoing as of Nov 2024.

In the meantime, avoid using the package channels defaults, main, anaconda, msys2, or r. You will want to make sure that these package channels do not appear in your ~/.condarc file, and that you do not reference them in your conda install commands. Finally, use miniforge over other modules that provide conda, as it avoids using forbidden channels by default.

Forcing Anaconda to work with environment modules

We have been creating modules by building from source up to this point, but you can also create modules for pre-built executables that you download. One common way of managing and obtaining pre-built software for your computer is to use Anaconda, a tool originally developed for managing python environments that has been extended to work as a general-purpose package manager.

The most basic conda installation procedure looks like the following for pandas (a python toolkit for working with tabular data):

$ module load miniforge
$ conda install pandas

However, Anaconda has its own directory structure that it will impose by default, and it tries to save disk space by linking to files rather than copying them to each individual environment. This makes it difficult to work with conda environments over the long-term, since these aren’t compatible with our module approach. Anaconda does include a tool for creating independent environments, but we have to use some special options to make it behave as we need. Further, the conda tool itself is notoriously slow at creating these environments, so we will be using an alternative tool known as mamba, which re-implements the conda environment management functionality in a more performant way.

So to quickly create a module-friendly environment for pandas, we would run the following:

$ today_date=$(date +%d%m%y)
$ module load mamba
$ mamba create --copy -p $HOME/software.install/pandas/$today_date pandas

This command has a few elements worth noting:

Since anaconda doesn’t work with source code, we don’t have source code to store. Further, we just running the same build command again in the future isn’t guaranteed to recreate the same environment because updates to packages may change how the environment is ‘solved’. We can take a snapshot of the exact package versions used for this environment by running:

$ mkdir ~/software.source/pandas
$ source activate $HOME/software.install/pandas/$today_date
$ conda env export --no-builds | grep -v "prefix" > ~/software.source/pandas/${today_date}.yml
$ source deactivate

The file ${today_date}.yml contains the complete specification for this environment, and you can use it to reinstall an identical environment in the future via, e.g. for a hypothetical environment I made on Jan 5, 2021:

$ module load mamba
$ mamba env create -f ~/software.source/pandas/010521.yml

If you need to change the install location for some reason for this reinstall, you will need to edit the first line of the yml file with the directory you’d like to use before recreating the environment.

Now, while we did use anaconda’s built-in environment management tool above via the source activate command, we don’t want to rely on this when using the environment. The reason for this is that anaconda environments don’t behave well in scripts, and attempting to fix this behavior can cause more issues than it solves. So we will use modulefiles once again, completely sidestepping the issue.

For most anaconda environments you will only need to modify PATH, so your modulefile would look like:

$ mkdir ~/modulefiles.local/pandas
$ nano ~/modulefiles.local/pandas/$today_date
#%Module
prepend-path PATH /users/3/dunn0404/software.install/pandas/032123/bin

Occasionally you will have to also modify the LD_LIBRARY_PATH variable to include the lib directory in the environment, but this will depend on the specific software being installed. In this case we’re OK with just modifying PATH.

Conda caches packages in your home directory

If you frequently use conda or use it to solve large and complex environments, you may find that you run out of storage space more quickly than expected. This might be because conda caches packages to ~/.conda, a hidden directory under your home directory, and this cache can become quite large in terms of both disk space and number of files over time.

The cache makes it faster to repeat conda installations that share common dependencies, but it is necessary to clean it out every once and a while. To check what will be removed by a cache cleaning, you can run the command:

$ conda clean --all --dry-run

And to actually execute the cleaning, you can remove the --dry-run option:

$ conda clean --all

Alternatively, if you want to keep your conda cache around for longer than it is convenient to store in your home directory, you can choose another location to use for the cache by changing the pkg_dirs option in your ~/.condarc file, e.g.

pkgs_dirs:
  - /nfs/volume/user/conda_pkgs

You can read more about this in the official conda documentation on the topic.

Anaconda environment tips

There are a few miscellaneous things to keep in mind when working with anaconda environments to make things work more smoothly and predictably:

# create a conda environment with only pip and its dependencies
$ today_date=$(date +%d%m%y)
$ module load mamba
$ mamba create --copy -p $HOME/software.install/numpy/$today_date python pip

# use conda's environment management to force pip to install there
$ source activate $HOME/software.install/numpy/$today_date
$ pip install numpy
$ source deactivate

The packages you install via pip won’t be captured by conda env export, so you will need to record these manually in a recipe file alongside the yml file.

Key Points

  • Conda environments are complex and finicky, but we can avoid most issues by forcing them to install into our module framework.

  • We can use conda to isolate pip installations.