Lattice field theory in modern C++.

A header-only C++20 Template Lattice framework. Write the physics as mathematical expressions — TempLat compiles it into fused kernels and runs it on CPU threads, NVIDIA and AMD GPUs, and across thousands of MPI ranks. Same source, any machine.

C++20 header-only Kokkos MPI CUDA / HIP HDF5

Features

Built for the physics, not the plumbing.

TempLat is the computational core behind CosmoLattice. It handles all the background tasks, memory, devices, halos and FFTs, while your code stays close to the equations.

Expressions, not loops

The energy density $\mathcal{e} = \tfrac12\pi^2 + \tfrac12(\nabla\phi)^2 + \tfrac12m^2\phi^2$ of a Klein-Gordon field, using TempLat's vocabulary:

auto expression = 0.5 * pow<2>(pi)
                 + 0.5 * Grad2(phi)
                 + 0.5 * m2 * pow<2>(phi);

TempLat builds the actual loop over the lattice for you. Expression templates fuse the whole right-hand side into one kernel — no temporaries, no hand-written indices, and deep optimization at compile time.

One source, any device

TempLat builds on Kokkos for shared-memory parallelism performance portability. TempLat supports CUDA, HIP, OpenMP, C++ threads or serial execution. TempLat automatically detects what your machine provides; override auto-detection easily via CMake flags.

Scales from your laptop to exascale clusters

Automatic domain decomposition across any number of MPI nodes, with ghost cells exchanged automatically when an expression needs it — GPU/NVLink-aware where the interconnect allows it.

Distributed FFTs

Parallel transforms through ParaFaFT, with support for CPU and multi-GPU. FFTW3 and KokkosFFT on a single node. Automatically dispatches FFTs when expressions operate in Fourier space.

Gauge fields included

SU(2) and U(1) link algebras, complex and matrix algebras, plaquettes, covariant and spatial derivatives, coordinate and momentum-space views — all as first-class expression types.

Output and measurements

Parallel HDF5 snapshots, measurement tools, projectors, spectra, a parameter-file reader and a rank-aware logger. The scaffolding around a simulation, already written.

How to use

Three steps to a running lattice simulation.

TempLat is header-only. You need CMake ≥ 3.16 and a C++20 compiler — clang, g++ or equivalent. There is nothing to install: CMake fetches and configures it inside your own build.

01

Add it to your CMake project

FetchContent downloads TempLat and builds it as part of your project. Link your executable against TempLat::TempLat and every include path, definition and dependency comes with it.

CMakeLists.txt
cmake_minimum_required(VERSION 3.16)

project(my_project LANGUAGES CXX)

include(FetchContent)
set(FETCHCONTENT_QUIET ON)
FetchContent_Declare(TempLat
  GIT_REPOSITORY https://github.com/cosmolattice/templat.git
  GIT_TAG main)
FetchContent_MakeAvailable(TempLat)

# Add your executable and link it against TempLat
add_executable(my_executable main.cpp)
target_link_libraries(my_executable PRIVATE TempLat::TempLat)
02

Write your first program

SessionGuard brings up MPI and the device backend and tears them down again when it goes out of scope. MemoryToolBox owns the lattice geometry — here a 128³ grid with one layer of ghost cells — and every Field built from it shares that decomposition. The assignment is a single fused kernel: a scalar plus a Gaussian random configuration, evaluated once per site. average reduces over the whole lattice, across all ranks, and sayMPI prints once from rank 0 with a timestamp and source location.

main.cpp
#include "TempLat.h"

int main(int argc, char *argv[])
{
  using namespace TempLat;
  SessionGuard guard(argc, argv);

  auto toolBox = MemoryToolBox<3>::makeShared(128, 1);
  Field<double, 3> phi("phi", toolBox);

  phi = 2 + RandomGaussianFieldConfig<double, 3>("seed", toolBox);

  const double result = average(phi);
  sayMPI << "Hello, TempLat!  <phi> = " << result << "\n";

  return 0;
};
build & run
mkdir build && cd build
cmake ..
make -j
./my_executable
output
(0.000s)
Using FFTW backend for FFTs.

(0.000s) MPI Rank 0 - memorytoolbox.h:209 -->
Using the following domain decomposition:(1 1 1 ).

(0.086s) MPI Rank 0 - main.cpp:15 -->
Hello, TempLat!  <phi> = 1.99973

The mean comes back at 1.99973 rather than exactly 2 because the Gaussian noise averages to zero only up to the sampling error of a finite lattice.

03

Pick your backend

The hardware and software you build for is chosen when you configure your project — for example cmake -DMPI=ON -DHDF5=ON .. — so there is nothing to configure inside TempLat itself. Leave the device flags off and it auto-detects: GPU first (CUDA, then HIP), then OpenMP, then C++ threads, then serial.

Flag What it enables Default
MPI Distributed runs across ranks OFF
CUDA NVIDIA GPUs (needs the CUDA toolkit or NVHPC SDK) OFF
HIP AMD GPUs — also set CXX=hipcc OFF
OPENMP OpenMP CPU parallelisation OFF
PARAFAFT ParaFaFT parallel FFTs $MPI
HDF5 Parallel HDF5 output OFF
TEMPLAT_TEST Build TempLat's own test suite for ctest OFF

Offline compilation for a cluster architecture, the runtime environment variables and the full flag table are explained in the README ↗. Testing is documented in TEST.md ↗.

Paper & citation

If TempLat helped your work, please cite it.

TempLat is developed by researchers. Citations are what make that sustainable.

TODO — paper title fill in

TODO — author list

TODO — journal, volume, page (year) · arXiv:TODO

BibTeX
@article{TempLat,
    author        = "TODO",
    title         = "{TODO}",
    eprint        = "TODO",
    archivePrefix = "arXiv",
    primaryClass  = "hep-ph",
    doi           = "TODO",
    journal       = "TODO",
    volume        = "TODO",
    pages         = "TODO",
    year          = "TODO"
}

TempLat grew out of, and powers, CosmoLattice. If you used it through CosmoLattice, please cite that code as well: arXiv:2102.01031.

People

Who builds TempLat.

TempLat is developed as part of the CosmoLattice project.

Adrien Florio

Adrien Florio

Bielefeld University, Germany

Franz R. Sattler

Franz R. Sattler

Bielefeld University, Germany

Contributors

Jorge Baeza-Ballesteros

Jorge Baeza-Ballesteros

DESY, Zeuthen, Germany

Wessel Valkenburg

Wessel Valkenburg

Enjoying la vida loca out of academia