Back to the future: modules for Guix packagesReproducible software deployment for high-performance computing.AboutPackagesChannelsEventsJobsBlogBack to the future: modules for Guix packagesLudovic Courtès — May 6, 2022SysadminModulesHigh-performance computingReleasesSome things in our software world are timeless. The venerable Environment Modules are one of these. If you’ve ever used a high-performance cluster in the last three decades, chances are you’re already familiar with it. Modules is about managing software environments, just like Guix is—or, perhaps more accurately, guix shell.You will be delighted, or surprised, to learn that Guix now has a compatibility layer with Modules.The legacy of ModulesAs Furlani’s 1991 introductory paper explains, Modules were—and still are—a key enabler for Unix users, especially in high-performance computing (HPC). The module command lets users manipulate their software environment in terms of packages, without having to be Unix or shell experts; they let them compose packages and build the software environment of their choice, without interfering with other users; they give a level of flexibility that Unix alone wouldn’t provide. The command-line interface is easily understood:module load gcc/11.2“loads” GCC 11.2 in your shell. You can “load” and “unload” software components at will:module load python/3.8 module unload gccAs an interface, Modules are easy to use and understand. However, they leave it up to sysadmins (sometimes users) to actually deploy the software. The common approach has been for sysadmins to build and install, by themselves, the software that Modules refer to. The end result is that modules vary from machine to machine. For example the gcc module shown above might refer to GCC 11.2 on one cluster and GCC 8 on another; it might have an entirely different name on a third cluster. Likewise, the python/3.8 module above might refer to different patch-level versions of Python 3.8, or it might refer to a variant of Python built with different dependencies or different build flags.These issues have been largely mitigated by package managers such as EasyBuild and Spack: both automate package builds, and both can generate module files—Tcl snippets that define environment variables to set when “loading” a module. With EasyBuild and Spack, it becomes possible to not only automate deployment and module file generation, but also to deploy similar software on different machines.“Similar”, though, does not mean “the same”. Software built with Spack or EasyBuild depends on software already available on the host system: it is built on top of a GNU/Linux distribution, which could be CentOS 7.4 (released in 2017), or Ubuntu 22.04, or really anything else. Thus, software installed with these tools depends on software provided by the underlying distribution, at build time and at run time.This “hidden dependency” makes it hard to redeploy the exact same environment on a different machine or at a different point in time: the same build process might fail, or it might succeed but the resulting software might behave differently. Our approach in Guix is to not have that “hidden dependency”. Instead, the package dependency graph that Guix manipulates is self-contained: it includes package definitions for all the user-land software one may use.From Guix to ModulesThe news today is the release of Guix-Modules, a new tool to generate module files from Guix packages. The primary goal, as with the module file generation tools in EasyBuild and Spack, is to make it easy for HPC cluster sysadmins to provide a set of modules for their users—more on that below. Guix-Modules is an extension of Guix. To use it, you need to install it and to set the GUIX_EXTENSIONS_PATH environment variable, like so:guix install guix-modules export GUIX_EXTENSIONS_PATH="$HOME/.guix-profile/share/guix/extensions"That gives you a new guix module sub-command.Let’s say you want to generate modules to /opt/modules for selected packages; you can do so by running:guix module create -o /opt/modules \ coreutils gcc-toolchain python python-numpyAs with all Guix commands, it will build or download the packages if they’re not around already and populate /opt/modules with a bunch of module files. If /opt/modules already existed, it has been backed up under /var/guix/profiles, which lets you roll back to the previous modules should you regret your changes.As an admin, you can periodically update the set of modules by running:guix pull guix module create -o /opt/modules …The good thing is that users can still access the previous module set, until you explicitly remove it, under /var/guix/profiles.Instead of having those long guix module create command lines, you can opt for listing the packages of interest in a manifest file, which you can keep under version control. As with most other guix commands, you can pass the manifest with:guix module create -m my-modules.scm -o /opt/modulesOnce the modules have been generated, you can happily load and unload them using the familiar module sub-commands:unset MODULEPATH module use /opt/modules module load gcc-toolchain/11.2.0 module load python/3.9.9Voilà! If you’re a sysadmin, here’s a new way to offer scientific software to your users without asking them to change their habits. The generated module files work equally well with the “original” Module implementation and with Lmod.Provenance trackingSince we, Guix developers, pride ourselves on providing a deployment tool with good support for provenance tracking, we couldn’t just let that guix module command generate module files of unclear provenance. Users—we think—ought to be able to determine the provenance of the modules they use. We want to avoid the scenario many HPC practitioners are familiar with whereby, six months after publishing an article, you can no longer reproduce the computational results it contains because the relevant modules have been upgraded or removed from under your feet and you just don’t know how to reproduce them.Thus, guix module create records provenance data in the module files it generates. You can view that info by running module help:$ module help openblas
----------- Module Specific Help for 'openblas/0.3.18' ------------
This module was generated from a GNU Guix package. Provenance data (channels):
(list (channel (url "https://git.savannah.gnu.org/git/guix.git") (branch "master") (commit "4ba35ccd18f90314caa76ea1833ffc383559401c") (name 'guix) (introduction (make-channel-introduction "9edb3f66fd807b096b48283debdcddccfea34bad" (openpgp-fingerprint "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))) What module help shows is the list of channels from which this particular package was built. The information is in a format that guix time-machine can readily consume. Assuming you store the (list (channel …)) snippet in file channels.scm, you can go to another machine, at a later point in time, and deploy the exact same software with this command:guix time-machine -C channels.scm -- \ shell gcc-toolchain openblasFor users, it makes a big difference: modules are no longer ephemeral—they’re now a reproducible artifact that you can redeploy with Guix anywhere, anytime.CustomizationHPC users are often demanding when it comes to customizing software build processes. Guix supports this need with a gamut of package transformation options available from the command line as well as through programming interfaces. Good news: guix module create honors package transformation options.Among those, the --tune option, which instructs Guix to optimize relevant packages for the host micro-architecture, may come in handy. If you know your cluster contains only Skylake CPUs, you’d rather make sure relevant packages are optimized for Skylake. To do that, you would run, say:guix module create --tune=skylake \ gcc-toolchain openblas gslIn this particular case, GSL gets built for Skylake, using GCC’s -march=skylake option (OpenBLAS itself chooses optimized routines at run time so it is unaffected).“But what about reproducibility?”, you ask. The chosen package transformation option(s)—--tune in this case—are also recorded as part of the provenance data. This is what module help reports:$ module help gsl
----------- Module Specific Help for 'gsl/2.7' --------------------
This module was generated from a GNU Guix package. Provenance data (channels):
(list (channel (url "https://git.savannah.gnu.org/git/guix.git") (branch "master") (commit "4ba35ccd18f90314caa76ea1833ffc383559401c") (name 'guix) (introduction (make-channel-introduction "9edb3f66fd807b096b48283debdcddccfea34bad" (openpgp-fingerprint "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA")))))
Package transformations:
((tune . "skylake")) The “Package transformations” bit is self-explanatory; it can be passed as-is to options->transformation in a manifest.We strongly believe one shouldn’t have to choose between performance and reproducibility and this is what this feature set supports.Why all the fuss?Guix is ten years old, Guix-HPC itself is turning five this year, so you might wonder why after all these years we’re adding a Modules compatibility layer. After all, guix shell can set up software environments on-the-fly in a way that is comparable to module load. For instance, to start a shell to use GCC and Python as in the example above, you would type:guix shell gcc-toolchain@11 python@3.8More generally, Guix puts users in control: it lets them upgrade when they want to and allows them to travel in time; it lets them customize packages, and it lets them replicate the same environment elsewhere or at a different point in time.Using Guix directly remains the most empowering approach for users, but module files created from Guix packages can satisfy a number of user needs:Matching user habits. For some communities, not having to learn a new command—even if it’s not all that different, even if it has more to offer—is a big plus. It’s not uncommon for cluster admins to offer Modules in addition to Guix or other tools for that reason.Supporting incremental software environment construction. With module, you can “load” and “unload” modules until you obtain the desired environment, whereas guix shell currently expects a list of packages upfront. While exploring a problem space, the incremental mode might be more convenient—and indeed, patches have recently been discussed to support an incremental mode in guix shell.Supporting simple Guixy cluster setups. The Guix typical cluster setup requires running the build daemon, ensuring it can access the network to download source or binaries, making it accessible to front nodes and (optionally) build nodes, and setting up a couple of NFS exports. Sysadmins who’d rather not do that can instead use guix module create and offer those modules to users. The /gnu/store directory still needs to be exported over NFS, but that’s a read-only export, and it’s all that’s needed—a simpler setup.If you’re an HPC cluster user or system administrator, we’d love to hear your thoughts on the guix-science mailing list or #guix-hpc channel on Libera.chat!Unless otherwise stated, blog posts on this site are copyrighted by their respective authors and published under the terms of the CC-BY-SA 4.0 license and those of the GNU Free Documentation License (version 1.3 or later, with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts).Source of this site |
The compatibility layer between Environment Modules and Guix addresses the challenges of reproducible software deployment, particularly within high-performance computing (HPC) environments. Historically, Environment Modules enabled Unix users, especially in HPC, to manage software environments by loading and unloading components, offering a level of flexibility beyond standard Unix capabilities. However, the traditional implementation suffered from inconsistency because system administrators often built and installed software manually, resulting in modules varying across different machines based on underlying system variations, such as different GNU/Linux distributions or specific build flags, creating "hidden dependencies."
Package managers like EasyBuild and Spack mitigated some of these issues by automating builds, but they introduced new complexities; software built with these tools depended on the host system's existing software, meaning the resulting environment was tied to the specific operating system, which complicated redeployment to different machines or times. Guix addresses this by ensuring the package dependency graph is self-contained, including all necessary user-land software definitions, thereby eliminating these hidden dependencies and ensuring true reproducibility.
The Guix-Modules extension is introduced to bridge this gap by allowing the generation of module files directly from Guix packages, offering a streamlined way for HPC cluster system administrators to provide standardized software sets. Users can leverage Guix commands to create module files, where the process builds or downloads necessary packages and populates a specified directory with module files. This process supports rollback capabilities, as changes are backed up in /var/guix/profiles. Users can further enhance automation by defining the required packages in a manifest file, which can be incorporated into version control.
A critical feature of this integration is the embedding of provenance tracking within the generated module files. This allows users to determine the origin of the modules, recording details such as the channels, branches, and commits from which the packages were built. This provenance data enables time travel capabilities; by storing this information in a file, users can recreate the exact software environment at any point in the past using Guix time-machine.
Furthermore, Guix supports customization of build processes, which is crucial for HPC users. This integration extends to module creation through package transformation options. For instance, the --tune option allows optimization of packages for specific host micro-architectures, such as Skylake CPUs. This tuning information is recorded as part of the module's provenance data. This mechanism allows systems to balance performance optimization with complete reproducibility by tracking exactly which transformations were applied during the build.
The compatibility between Guix modules and traditional Module implementations offers several significant advantages for HPC users. It matches user habits by providing familiar module loading concepts. It supports incremental environment construction through the load and unload module functionality. It simplifies cluster setups by allowing administrators to offer pre-configured modules without requiring complex daemon setups. Ultimately, by integrating provenance and customization, Guix-Modules transforms modules from ephemeral artifacts into reproducible assets, ensuring that software deployments remain consistent and verifiable across various environments and timelines. |