Summary and Version Information

Package Singularity
Description Singularity software containers
Categories Progamming/Development
Version Module tag Availability* GPU
2.3.1 singularity/2.3.1 Non-HPC Glue systems
Deepthought2 HPCC
2.4.2 singularity/2.4.2 Non-HPC Glue systems
Deepthought2 HPCC

*: Packages labelled as "available" on an HPC cluster means that it can be used on the compute nodes of that cluster. Even software not listed as available on an HPC cluster is generally available on the login nodes of the cluster (assuming it is available for the appropriate OS version; e.g. RedHat Linux 6 for the two Deepthought clusters). This is due to the fact that the compute nodes do not use AFS and so have copies of the AFS software tree, and so we only install packages as requested. Contact us if you need a version listed as not available on one of the clusters.

In general, you need to prepare your Unix environment to be able to use this software. To do this, either:

  • tap TAPFOO
  • module load MODFOO

where TAPFOO and MODFOO are one of the tags in the tap and module columns above, respectively. The tap command will print a short usage text (use -q to supress this, this is needed in startup dot files); you can get a similar text with module help MODFOO. For more information on the tap and module commands.

For packages which are libraries which other codes get built against, see the section on compiling codes for more help.

Tap/module commands listed with a version of current will set up for what we considered the most current stable and tested version of the package installed on the system. The exact version is subject to change with little if any notice, and might be platform dependent. Versions labelled new would represent a newer version of the package which is still being tested by users; if stability is not a primary concern you are encouraged to use it. Those with versions listed as old set up for an older version of the package; you should only use this if the newer versions are causing issues. Old versions may be dropped after a while. Again, the exact versions are subject to change with little if any notice.

In general, you can abbreviate the module tags. If no version is given, the default current version is used. For packages with compiler/MPI/etc dependencies, if a compiler module or MPI library was previously loaded, it will try to load the correct build of the package for those packages. If you specify the compiler/MPI dependency, it will attempt to load the compiler/MPI library for you if needed.

What is Singularity and why should I care?

Singularity is a "containerization" system. Basically, it allows for an application to run within a "container" which contains all of its software dependencies. This allows for the application to come with its own version of various system libraries, which can be older or newer than the system libraries provided by the operating system. The Deepthought2 cluster, for example, is currently running a release of RedHat Enterprise Linux 6 (RHEL6). Some applications really want to run with libraries that are not available on that version of RedHat, and really want some version of Ubuntu or Debian instead. While one can sometimes get around this constraints by compiling from source, it does not always work.

Furthermore, sometimes applications are very picky about the exact version of libraries or other applications that they depend on, and will not work (or perhaps even worse, give erroneous results) if used with even slightly different versions. Containers allow each application to "ship" with the exact versions of everything it wants. They can even allow the RHEL6 system running on the Deepthoughts look like Ubuntu 16.04 or some other variant of Linux to the application.

There are limitations, of course. Containers of any type still share the same OS kernel as the system, including all the drivers, and so the container cannot change that. Fortunately, most end user applications are not very fussy about the OS version. The "containment" of containers can also be problematic at times --- containers by design create an isolated environment just for a particular application, containing all of its dependencies. If you need use libraries for a containerized package "foo" in another application "bar", basically you need a new container for "bar" which has "foo" as well as "bar" installed.

Using containerized applications

We currently have only a few packages distributed as containers, but that is likely to increase over the coming months. Especially in certain fields of research which tend to have more difficult to install software. So, depending on your field of study, you might find yourself dealing with containerized applications soon.

The good news, is that hopefully you won't notice much of a difference. The container should still be able to access your home directory and lustre directory, and we provide wrapper scripts to launch the program within the container for you that will behave very much like the application would behave in a native install. So with luck, you won't even notice that you are using a containerized application.

The biggest issues will arise if you need to have a containerized application interact with another application on the system (containerized or not, unless it just happens to exist in the same container image as the first application). In general, this will not work. In such cases, it would be best if you could break the process into multiple steps scuh that at most one application is needed in each step, if this is possible. Otherwise, contact us and we will work with you to try to get around this.

Building your own containers

One advantage of Singularity over other containerization systems is that we can allow you to run containers not built by the Division of Information Technology at the University of Maryland. So you can in theory get Singularity containers built elsewhere, copy them to a Glue or HPC system, and run them. This includes Singularity containers that you build yourself.

Singularity containers will not run reliably from AFS. HPC users are encourarged to place them in their home directory (if small enough) and/or in lustre. On non-HPC systems, you will probably need to place them on a local disk (e.g. /export).

In order to build a Singularity container, you will need root access to a system with Singularity installed. Chances are, that is not a Glue/TerpConnect/HPC/DIT maintained system, but something like a desktop you installed Ubuntu or Fedora on. So the first step is to install Singularity on it. You can search for prebuilt binary packages, or you can follow the installation from source instructions; the latter are fairly straightforward.

Once Singularity is installed, you can generate images for use with Singularity on DIT maintained systems. The steps to do so depend on the version of Singularity you are using (i.e. on the system you have root on). Glue/Terpconnect and the Deepthought HPC clusters support Singularity version 2.4.2 at the time of this writing ("module load singularity/2.4.2") --- images created with earlier versions of singularity should be runnable, but images created with newer versions might not be. (At the time of writing, 2.4.2 is the latest version released.)

Building images with Singularity versions 2.x < 2.4

For Singularity versions 2.2 and 2.3, the basics steps are:

  1. Create a blank image
  2. Populate the image

Creating a blank image is easy, just use the singularity create command. You will need to run this as root; either su to root before running the command, or prefix the command with sudo. Assuming you opt for the latter, something like

my-linux-box> sudo singularity create -s 4096 ./my-sing-image.img
This will create a 4 GiB image (4096 Mib) in the current directory named my-sing-image.img. The default size, if you omit the -s argument, is 768 MiB, which is probably too small. Although this will try to make a sparse file (i.e. the newly created file from the above example will report a size of 4 GiB, but du on the file will report much less. However, as content is added, the discrepancy will become smaller.), the "sparseness" of the file can be lost as the file is transferred from system to system, and not all filesystems support sparseness to the same degree, so I recommend making the size as small as possible. (I usually create a test image, quite large, the first time around, install the application, and then figure out how much space is really needed, and repeat for the final image with a much more tightly fitting size). There are a number of ways to populate an image. We list some of them here:
  • Singularity maintains a Singularity hub or collection of containers much like Docker hub, although not nearly as well populated at this time.
  • Singularity has some support for importing images from Docker. There are several ways to do this, including:
    • singularity import my-image.img docker://ubuntu:latest
    • Using a bootstrap definition spec file, e.g.
      Bootstrap: docker
      From: ubuntu:latest
    • If you have Docker installed, something like docker export ubuntu:latest | singulrity import my-image.img
    • The above is made easier with the script ubuntu:latest
  • Singularity comes with a recipe definition format wherein you can define the commands needed to setup a container and just bootstrap them. Basically, you start with a base OS image (e.g. Ubuntu or Debian) as specified in your header, and you install .deb or .rpm packages as appropriate for the OS. Details on the bootstrap definition spec file format.. After the bootstrap file is created, you simply run sudo singularity bootstrap my-image.img my-bootstrap.def.
  • Finally, you can start with an image created from one of the above mechanisms, and either mount it (sudo singularity mount my-image.img) and modify the contents directly, or start a shell (sudo singularity --writable shell my-image.img) and run yum or apt, etc. commands to set it up manually. This is not recommended, as it makes the container hard to reproduce, and is likely to cause you more problems in the long run when you need to upgrade the application version, etc.

Building images with Singularity versions 2.4 (or higher?)

For Singularity versions 2.4, the create and bootstrap subcommands have been combined into a single "build" subcommand. They have also added a couple of new formats for containers, namely a compressed read-only squashfs format (the default), and a chrooted directory format available with the --sandbox option. The old default ext3 based format has been deprecated, but is available with the --writable option.

The command for building a container image has been simplified, and is basically

singularity build [BUILD_OPTIONS] path-to-new-container SOURCE-SPEC

The command singularity help build will give full details, but basically BUILD_OPTIONS can be --sandbox or --writable to specify the sandbox or ext3 image formats above (if neither specified, will use the squashfs format). path-to-new-container is the path to the new container to be built. And SOURCE-SPEC can be any of the following:

  • the path to a recipe definition as described in the previous section.
  • the path to an existing Singularity image (which can be used to copy it to a new format)
  • a tar (or .tar.gz) file (must have .tar in the name) which will be used to populate the image
  • or a URI starting with shub:// or docker:: to generate an image from a remote Singularity registry or Docker registry.

If you wish to modify an existing container to better suit your requirements, two strategies for doing so are:

  1. You can get the recipe file to build the original container using the singularity inspect -d path-to-container. This requires that the image was constructed using a recipe file and was generated under singularity 2.4 or higher, but those conditions should be met for newer images created by DIT. You can then edit that recipe and use it to build the image of your desire.
  2. You can convert an existing image into the sandbox format using singularity build -s path-to-new-container path-to-existing-container. Note that the new container will be a directory. You can then use singularity shell --writable path-to-new-container and you will have a shell in the new container. You can then interactively modify the container (e.g. install packages, etc) as needed, which will be retained in the image after you exit the shell.

Useful links, more information, etc.