Installing Qlua
Building Qlua and the pieces of the USQCD software stack it needs, from one tarball and one make command.
Qlua is built by the build3 system: a single tarball holding a top-level
Makefile, a description of every component, and nothing else. It carries no
sources of its own. Given a target to build for, make fetches each component
from this site, checks it against a recorded SHA-256 sum, and builds the stack in
dependency order — Lua, the USQCD libraries (QMP, QLA, QIO, QDP), the solvers
(clover, twisted, MDWF, QOPQDP, and QUDA where there is a GPU), and finally
qlua itself.
There is no configure script. What a configure script would discover,
you write down instead, in a target description under config/targets/.
That file is the whole of the local configuration.
Get the tarball
The current build system is version
2026.10e. Earlier releases are on the
downloads page; unless you have a reason to reproduce
an older build, take the newest.
curl -O https://web.mit.edu/qlua/files/build3-2026.10e.tar.gz
tar xzf build3-2026.10e.tar.gz
cd build3-2026.10e
What you need first
build3 builds the lattice stack; it does not build a toolchain, an MPI, or CUDA.
Those must already be on the machine, and on a cluster that usually means loading
the right modules before you start. The build itself calls for:
| Tool | Used for |
GNU make | the build itself; -j with a number is worth using |
curl | fetching component tarballs |
sha256sum | verifying them against etc/parts.sums |
pkg-config | locating libraries the components need |
aclocal, automake | components that regenerate their build files (automake 1.16) |
| MPI C, C++ and Fortran compilers | the target build — mpicc, mpic++, mpif77 by default |
| a host C compiler | code-generation tools that run on the build machine |
| CUDA | GPU targets only, for QUDA |
Each of these is a make variable with a default, so a machine that spells
one of them differently is accommodated in the target file rather than in the
environment.
Choose a target
A target names the components to build and the compilers and flags to build them
with. The tarball ships four:
| Target | What it builds |
wombat-a100 | Wombat, NVIDIA A100 — the full stack including CUDA, QUDA and the GPU qlua |
wombat-cpu | Wombat, CPU only — the same stack without CUDA and QUDA |
perlmutter-cpu | Perlmutter, CPU only, installing under a CFS project directory |
haktor | a macOS laptop, checked on x86 — and the one target that takes the 2026 AFF |
If none of them is your machine, copy the closest one and edit it — starting from an
existing target is much less work than starting from common.mk. A target
file is short: it lists parts, carries a default
INSTALL_TOP, and includes config/targets/common.mk, which
supplies every compiler and flag the parts expect.
Build it
make TARGET=wombat-a100 INSTALL_TOP=/opt/software/qlua-a100-2026.10e -j8
Both TARGET and INSTALL_TOP must be given.
TARGET names the target description to build from;
INSTALL_TOP is the directory everything is installed into, and it is
where you will point PATH afterwards. The makefile stops with an error
without a target, and that includes make clean, so every invocation on
this page carries both.
Give -j a number. On its own it places no limit at all:
make starts as many compilations as it finds work for, and a stack this
size will start enough of them to exhaust the memory on the machine. The build then
fails in ways that look like anything but too much parallelism — a compiler killed
with no message, an assembler out of memory, a link that dies. If a build fails and
the failure moves or changes between runs, suspect this first: build again with a
smaller -j, or with no -j at all, before looking for a real
error.
Expect hours, not minutes — on a CPU target as much as on a GPU one. The
stack is large and much of it is slow to compile; QUDA is the largest single piece,
so a GPU target is longer still. Build logs and per-step timestamps land in
logs/, which is where to look while it runs.
The build also copies etc/ and config/ into
$INSTALL_TOP/versions/ and writes the target name beside them, so an
installation says exactly which component versions it was built from.
Changing a component
The files in config/parts/ are shared by every target, so it is better not
to edit them. To build one component differently, copy its file and point your target
at the copy. For HDF5, say:
cp config/parts/hdf5.mk config/parts/hdf5-my-target.mk
# edit config/parts/hdf5-my-target.mk
# then in config/targets/my-target.mk, replace hdf5 with hdf5-my-target
# in the parts list
The aff-y26 part is this pattern already in use: haktor builds
the 2026 AFF by naming aff-y26 where the other targets name
aff.
Where things are
| Path | What it holds |
Makefile | the top makefile |
config/targets/ | one description per installation |
config/parts/ | per-component variable definitions |
parts/ | the makefile that builds each component |
etc/parts.master | the version — a git commit, or a release number — of every component |
etc/parts.sums | their SHA-256 checksums |
downloads/ | created by make: component tarballs as fetched |
build/ | created by make: where components are unpacked and built |
logs/ | created by make: build logs and step timestamps |
Fetching and cleaning
Component tarballs come from https://web.mit.edu/qlua/files — the same
files this site serves. curl is run with
-f, so a missing file is an error rather than a saved error page, and
every tarball is checked against etc/parts.sums before it is used, which
catches a bad download either way.
Four goals do the fetching and the clearing up. Each needs
TARGET and INSTALL_TOP, like every other invocation.
make TARGET=wombat-cpu INSTALL_TOP=/opt/software/qlua-cpu-2026.10e download
Downloads every component the target calls for into downloads/, and
stops there. Nothing is unpacked and nothing is built.
make TARGET=wombat-cpu INSTALL_TOP=/opt/software/qlua-cpu-2026.10e checksum
Verifies each downloaded tarball against etc/parts.sums, downloading
first anything not yet fetched — so this one goal both fetches and checks, and
running download beforehand is optional. This is the goal to use when
you want everything in hand and verified without starting a build, and it is the
first step of
building a disconnected machine.
make TARGET=wombat-cpu INSTALL_TOP=/opt/software/qlua-cpu-2026.10e clean
Removes build/ and the step markers in logs/, leaving the
downloaded tarballs where they are. The next build recompiles from the beginning but
does not fetch anything again. This is what to use after changing a target or a part
file.
make TARGET=wombat-cpu INSTALL_TOP=/opt/software/qlua-cpu-2026.10e realclean
The same, and removes the downloads as well, so the next build fetches every
component over again. Use it when a download is suspect, or to get back to the tree
as it came out of the tarball.
Building without a network
A machine that cannot reach this site can still be built on: fetch the components
somewhere that can, and carry the tree across. Nothing after the fetch needs the
network.
On a connected machine, unpack the tarball and run the checksum step with the target
and prefix you intend to use on the final host:
make TARGET=haktor INSTALL_TOP=/opt/software/qlua-cpu-2026.10e checksum
That downloads every component the target calls for and verifies each one against
etc/parts.sums. It builds nothing, so the connected machine need not be
the same architecture as the one you are building for — and because the sums are
checked here, a tarball that arrives corrupted is caught before it is carried
anywhere.
Then pack the tree, downloads and all, and move it across:
cd ..
tar czf build3-2026.10e-with-downloads.tar.gz build3-2026.10e
# copy it to the disconnected machine and unpack it there
On the disconnected machine, continue the build as usual. The download and checksum
steps are already recorded as done in logs/, so make goes
straight to compiling:
make TARGET=haktor INSTALL_TOP=/opt/software/qlua-cpu-2026.10e -j8
Carry the tree whole, with logs/ in it. Those files are what
record that the components have been fetched and checked; without them
make will try to download again and stop when it cannot. Use the same
TARGET on both machines — a different target may call for components the
first one never fetched.
|