Installing OpenPFC¶
This document is the supported source build guide. On Tohtori, the current site Open MPI 5.0.10 module uses GCC 15.2.0. Other compilers may work, but OpenPFC, HeFFTe, and MPI must use one matching compiler/MPI stack.
Choose an installation route¶
If your site already provides an OpenPFC installation, load its module and
matching compiler/MPI environment. The Tohtori
and LUMI guides list the site modules. The
first-model walkthrough
then checks the SDK with openpfc doctor, creates a CPU diffusion model and
shows how to inspect its output. This requires an installation containing the
native CLI commands described here; older release modules may not include them.
For a source checkout, use scripts/build.sh for routine
builds and tests. On Tohtori, run ./scripts/build.sh --machine=tohtori --cpu.
On an ordinary workstation with the dependencies below installed, use
./scripts/build.sh --machine=portable --cpu; this preserves your environment
and package discovery. On LUMI, follow the site’s scheduled build instructions
and keep build trees on flash outside the clone. Run ./scripts/build.sh --help
for options. The remaining sections provide manual dependency and toolchain
details.
Reference stack (at a glance)¶
Piece |
Documented / exercised baseline |
|---|---|
CMake |
3.15+ |
GCC |
15.2.x with the current Tohtori Open MPI 5.0.10 module |
Open MPI |
5.0.10 (Slurm |
HeFFTe |
2.4.1 (separate install per CPU/CUDA/ROCm variant) |
Native CLI cryptography |
OpenSSL Crypto 1.1 or newer, with development headers |
The native openpfc CLI requires OpenSSL development files (libssl-dev on
Debian/Ubuntu, openssl-devel on RPM-based systems). It uses Crypto for SHA-256
and does not link the simulation runtime. Python remains optional tooling for
scientific reference checks, documentation and build scripts; the installed CLI
and generated model projects do not require it.
One-page matrix (optional / QA tooling, doc check scripts): docs/dependency_matrix.md.
For common failures (mpi.h, wrong compiler in cache, HeFFTe not found, link errors involving libheffte.so and GLIBCXX_*), see docs/troubleshooting.md.
After a successful install, use Start here for your first model and result files. For source examples, applications and CMake integration, continue with Quick start. The learning paths and documentation index help you choose the next step.
Contributing (builds, tests, documentation, changelog notes): CONTRIBUTING.md.
MPI: OpenMPI from modules — do not improvise with another stack¶
This guide’s source of truth for MPI is Open MPI from environment modules (module load openmpi after module load gcc/…), as in §1 below. That matches how OpenPFC and HeFFTe are meant to be built together on clusters and many dev machines.
Recommended on Slurm clusters: Open MPI 5.0.10 from modules (e.g. module load openmpi/5.0.10), built or packaged with Slurm PMI/PMIx support, so srun direct launch works. If you see OMPI was not built with SLURM's PMI support, switch to this stack and rebuild HeFFTe and OpenPFC against it.
IDE / preset pins: cmake/toolchains/tohtori-gcc11-openmpi.cmake defaults to /share/apps/OpenMPI/5.0.10 when OPENMPI_ROOT is unset (matching module show openmpi/5.0.10 on typical nodes). For another install or module layout, set OPENMPI_ROOT to that prefix before CMake.
Keep one compiler and MPI stack per build: use the compiler loaded by the Open MPI module for HeFFTe and OpenPFC, then use the same Open MPI for mpirun/srun at run time.
Run with the same MPI you built with: after loading modules,
which mpirunandwhich mpicxxmust come from the same Open MPI installation (e.g. both under/share/apps/OpenMPI/5.0.10/binwhen using that module). Do not launch binaries with a system MPICHmpirun(e.g./usr/lib64/mpich/bin/mpirun) if OpenPFC was linked against Open MPI — you will see link warnings about conflictinglibmpi.soand runtime errors aroundMPI_Finalize.Do not point CMake at an arbitrary system MPI just because
mpiccexists (for example MPICH under/usr/lib64/mpichon RHEL-style systems). Open MPI and MPICH are different implementations; HeFFTe and OpenPFC must be configured, built, and run against the same MPI. Mixing “HeFFTe built with MPICH” and “OpenPFC expecting Open MPI” (or the reverse) produces confusing link or runtime failures.Do run
module load openmpi(or your site’s equivalent name — usemodule avail openmpi), then confirm you are using that toolchain before building HeFFTe and OpenPFC:which mpicc mpicc --version # should identify Open MPI / openmpi, not MPICH
Bare OS without modules: install Open MPI development packages (not MPICH) if you want to follow this document literally. If your site standardizes on MPICH only, you may still build everything consistently with MPICH — but that is not the combination this file describes step-by-step; keep HeFFTe and OpenPFC on the same
mpicc/mpicxxthroughout.
1. Environment modules (recommended on clusters)¶
Load Open MPI first so Lmod also selects the compiler with which that MPI was built. Load CUDA as needed:
module purge
module load openmpi/5.0.10 # currently loads gcc/15.2.0 on Tohtori
module load cuda/13.1 # current Tohtori toolkit; verify with `nvcc --version`
Site note (tohtori): see docs/hpc/INSTALL.tohtori.md for the usual module stack, module load cuda, CUDA-capable HeFFTe, and avoiding the wrong HeFFTe package when both CPU and GPU installs exist.
Verify:
g++ --version # expect the compiler named by `module show openmpi/5.0.10`
mpicc --version
nvcc --version # after loading CUDA, for GPU builds
Important: CMake may still pick /usr/bin/gcc if it was run before modules were loaded or if the cache is stale. HeFFTe must be built and consumed with the same toolchain. After loading Open MPI and its compiler dependency, set compilers explicitly when configuring OpenPFC (and when building HeFFTe):
export CC=$(which gcc)
export CXX=$(which g++)
(or pass -DCMAKE_C_COMPILER=$(which gcc) -DCMAKE_CXX_COMPILER=$(which g++) to cmake.)
Stale CMake cache: If an earlier configure picked the wrong compiler, build-*/CMakeCache.txt may still point at /usr/bin/gcc. Remove the build directory and reconfigure, or pass -DCMAKE_C_COMPILER and -DCMAKE_CXX_COMPILER explicitly on every cmake invocation.
CUDA note: Load a cuda module that points at an installed toolkit (check with nvcc --version after loading). If your site’s cuda/13 (or similar) sets PATH but nvcc is missing, pick another module version that matches a real install (e.g. module avail cuda), or set -DCMAKE_CUDA_COMPILER=/path/to/nvcc / CUDAToolkit_ROOT explicitly.
compile_commands.json (IDEs, clang-tidy, agents)¶
After modules and compilers are set (§1), configure with CMAKE_EXPORT_COMPILE_COMMANDS=ON so CMake writes an accurate compile_commands.json inside the build directory (e.g. build-cpu/compile_commands.json). Tools such as clangd, clang-tidy, and scripted builds depend on this file matching the same mpicc/GCC the project uses — so always re-run cmake after module load, never from a “clean” shell that falls back to /usr/bin/gcc and a different MPI.
cmake -S . -B build-cpu -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ... # plus your usual flags (§5)
# Optional: symlink for tools that expect it at the repo root
ln -sf build-cpu/compile_commands.json compile_commands.json
To mirror CI static analysis locally (see .github/workflows/clang-tidy.yml), use the build directory that contains compile_commands.json as -p for run-clang-tidy / clang-tidy.
VS Code / Cursor on tohtori (CMake presets)¶
CMake Tools often launches cmake without an interactive Lmod shell, so the generic dev-debug preset can pick the OS default compiler and fail to find Open MPI. On Tohtori, select the tohtori-debug or tohtori-release configure preset in CMakePresets.json: they apply the historically named cmake/toolchains/tohtori-gcc11-openmpi.cmake plus PATH / LD_LIBRARY_PATH matching the current GCC 15.2.0 + Open MPI 5.0.10 site module. For a custom stack, set both OPENPFC_GCC_ROOT and OPENMPI_ROOT before CMake. If $HOME/opt/heffte/2.4.1-cpu exists, the toolchain prepends it to CMAKE_PREFIX_PATH. Those presets set OpenPFC_ENABLE_CODE_COVERAGE=OFF (many cluster images lack lcov); install lcov (e.g. EPEL + dnf install lcov on EL8) and reconfigure with -DOpenPFC_ENABLE_CODE_COVERAGE=ON if you want ninja coverage.
Optionally create .vscode/settings.json with "cmake.configurePreset": "tohtori-debug" so the folder opens with the right preset (this repo .gitignore ignores .vscode unless you change that). For different paths after a cluster upgrade, use CMakeUserPresets.json at the repo root — see cmake/README.md.
AddressSanitizer / UBSan (dev): The dev-asan configure preset in CMakePresets.json extends dev-debug with -fsanitize=address,undefined (and matching link flags) for local debugging with GCC/Clang that support those flags. Example: cmake --preset dev-asan then cmake --build --preset dev-asan. When running tests or mpirun, you may set ASAN_OPTIONS=detect_leaks=1 (and related runtime flags) in the environment; mixed MPI + sanitizers can be environment-sensitive, so match the same gcc / OpenMPI stack as the rest of this guide.
For a one-command configure, build, and test workflow on Tohtori, run
./scripts/build.sh. It defaults to a 32-way Release CPU build under
builds/release, runs the serial and explicit 2-, 3-, and 4-rank MPI CTest
suites with failure output enabled, writes phase logs into the build directory,
and reports configure/build/test timings. Use, for example,
./scripts/build.sh --build-type=Debug --with-timestamp or
./scripts/build.sh --machine=tohtori --with-cuda --with-timestamp --test.
Environment variables provide the same controls; see ./scripts/build.sh --help.
For dependency bootstrapping, sh ./scripts/build_tohtori.sh (or
./scripts/build_tohtori.sh) sources Lmod when needed and loads the site
openmpi/5.0.10 module, including its compiler dependency. Pass
--build-openmpi to compile Open MPI 5.0.10 with --with-slurm under
$HOME/opt/openmpi/5.0.10; OPENPFC_GCC_MODULE selects that custom build’s
compiler module and defaults to gcc/11.2.0. The script sets
OPENPFC_GCC_ROOT and OPENMPI_ROOT together, builds HeFFTe 2.4.1 under
$HOME/opt/heffte/2.4.1-cpu if needed, and configures OpenPFC with
OpenPFC_ENABLE_HDF5=ON. Run --help for options.
2. Other dependencies¶
CMake 3.15+
FFTW (development packages) — required for HeFFTe’s CPU backend
nlohmann/json — optional system install; otherwise CMake may fetch it during configuration
MPI — Required for all supported builds (HeFFTe and the distributed FFT stack depend on it). The documented setup is OpenMPI from modules (see §1 and the MPI callout above). CMake must find
MPI_CXXfor that MPI — not a random MPICH install earlier onPATH. There is no supported serial-only configuration yet —-DOpenPFC_ENABLE_MPI=OFFis rejected at configure time with a pointer to this list. Ifmpi.his missing during configure, see §5.1 (modules +CC/CXX+ stale cache).toml++ and Catch2 — if not found on the system, CMake may download them (e.g. when building tests). Ensure network access on first configure, or install/provide packages your site supports.
Doxygen — optional; if present, documentation generation is enabled by default (disable with
-DOpenPFC_BUILD_DOCUMENTATION=OFFif you do not need it)
Installed consumers of the public settings loader also need toml++.
OpenPFC exports that dependency through its CMake target. When the build
fetches toml++ 3.4, installation delivers its headers, license and a separate
relocatable tomlplusplus CMake package beside OpenPFC. A system-provided
toml++ remains an external package discoverable through the consumer’s
normal CMake search paths.
3. HeFFTe (required)¶
Build and install HeFFTe yourself, then point OpenPFC at it with CMAKE_PREFIX_PATH or Heffte_DIR.
If you omit those, CMake still runs find_package(Heffte) first, then probes common install prefixes automatically (see cmake/OpenPFCHeffteHints.cmake: e.g. **$HOME/opt/heffte/*, /opt/heffte/..., /share/apps/heffte/..., Spack EBROOTHEFFTE). The first prefix that contains lib64/cmake/Heffte or lib/cmake/Heffte wins. Add your site’s root to that file if needed.
Releases: https://github.com/icl-utk-edu/heffte/releases (recommended: v2.4.1)
Upstream install guide: https://icl-utk-edu.github.io/heffte/md_doxygen_installation.html
Install layout: $HOME/opt/heffte/<variant>¶
Use one install prefix per backend, all under $HOME/opt/heffte/, so you can keep CPU, CUDA, and ROCm builds side by side and wire them in with modules:
Variant |
Typical |
Notes |
|---|---|---|
CPU (FFTW only) |
|
No GPU backend in HeFFTe |
CUDA |
|
|
ROCm / HIP |
|
|
OpenPFC CPU builds should use CMAKE_PREFIX_PATH (or Heffte_DIR) pointing at 2.4.1-cpu. GPU builds must use the matching -cuda or -rocm install.
Do not unpack or build HeFFTe inside the OpenPFC repository¶
Keep the OpenPFC clone free of HeFFTe source trees, long-lived build trees, and release tarballs (nothing like heffte-2.4.1/ or v2.4.1.tar.gz next to OpenPFC’s top-level CMakeLists.txt).
Download tarballs to
$HOME/src,/tmp, or any directory outside the OpenPFC tree.Point
-Sat the extracted source outside the repo (e.g.$HOME/src/heffte-2.4.1).Point
-Bat a build directory outside the repo (e.g.$HOME/opt/heffte/build-cpu-2.4.1or/tmp/heffte-build-cpu-2.4.1).cmake --installinto$HOME/opt/heffte/2.4.1-cpu(or-cuda/-rocm).
OpenPFC’s own build-cpu/ / build-gpu/ directories are only for OpenPFC (usually gitignored); do not use the repository root as a dump for HeFFTe sources or tarballs.
GitHub Actions in this repository follow the same policy: workflows download HeFFTe to /tmp, build in a temporary directory there, install to $HOME/opt/heffte/2.4.1-cpu on the runner, and delete the extract — the checked-out OpenPFC tree is not used as a HeFFTe working directory.
Optional: OpenPFC_FETCH_HEFFTE=ON¶
If no HeFFTe is found, CMake can fetch v2.4.1 via FetchContent into build/_deps/ inside an OpenPFC build directory (FFTW + MPI still required). This is a fallback only: for day-to-day work, prefer installs under $HOME/opt/heffte/<variant> as above. FetchContent must not be used as an excuse to extract HeFFTe into the OpenPFC source tree.
The fallback pins the v2.4.1 source commit and archive checksum and applies
OpenPFC’s FFTW real-plan correction (Git is required). Stock HeFFTe 2.4.1 plans
with two null pointers, which FFTW treats as an in-place layout, then executes
with distinct arrays. On macOS this can corrupt a 512-point transform or crash
with a reduced singleton axis. The correction plans with separate temporary
arrays sized for the complete strided batch. It uses FFTW_UNALIGNED so later
execution need not match the temporary arrays’ alignment; FFTW may consequently
use fewer SIMD optimizations. Performance has not been qualified.
An already installed HeFFTe takes precedence and is never modified by OpenPFC.
Rebuild it from corrected sources using the manual instructions below. For an
explicit fallback build, combine -DOpenPFC_FETCH_HEFFTE=ON with
-DCMAKE_DISABLE_FIND_PACKAGE_Heffte=ON.
Optional: Lmod modulefiles ($HOME/privatemodules)¶
After installing to e.g. $HOME/opt/heffte/2.4.1-cpu, you can add a personal module that prepends CMAKE_PREFIX_PATH** (and anything else your site needs):
#%Module1.0
set root $env(HOME)/opt/heffte/2.4.1-cpu
prepend-path CMAKE_PREFIX_PATH $root
Place the file where Lmod looks (e.g. $HOME/privatemodules/heffte/2.4.1-cpu.lua or .modulepath layout your site uses), then module load heffte/2.4.1-cpu before configuring OpenPFC. Repeat with different paths for 2.4.1-cuda and 2.4.1-rocm.
Build and install HeFFTe manually (outside OpenPFC)¶
Load Open MPI (which selects its matching GCC) and, for CUDA, cuda first (§1). Use the same CC/CXX as for OpenPFC.
Working copy outside the repo (adjust SRC / BUILD):
export VER=2.4.1
export SRC=$HOME/src/heffte-${VER}
export BUILD=$HOME/opt/heffte/build-cuda-${VER}
mkdir -p "$HOME/src" "$HOME/opt/heffte"
wget -q -O "$HOME/src/v${VER}.tar.gz" \
https://github.com/icl-utk-edu/heffte/archive/refs/tags/v${VER}.tar.gz
tar xf "$HOME/src/v${VER}.tar.gz" -C "$HOME/src"
export CC=$(which gcc)
export CXX=$(which g++)
From the OpenPFC checkout, apply the bounded correction before configuring HeFFTe (including CPU, CUDA and ROCm variants that enable FFTW):
cmake -DSOURCE_DIR="$SRC" -P cmake/PatchHeffteFftw.cmake
This accepts the original v2.4.1 header or an already corrected copy. It refuses unexpected header contents without overwriting them. Rebuild and reinstall HeFFTe afterward; changing source alone does not update an installed provider.
CUDA + FFTW → install to $HOME/opt/heffte/2.4.1-cuda:
cmake -S "$SRC" -B "$BUILD" -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-DCMAKE_INSTALL_PREFIX=$HOME/opt/heffte/2.4.1-cuda \
-DHeffte_ENABLE_FFTW=ON \
-DHeffte_ENABLE_CUDA=ON \
-DCMAKE_CUDA_ARCHITECTURES=80
cmake --build "$BUILD" -j"$(nproc)"
cmake --install "$BUILD"
Replace 80 with your GPU’s compute capability, use native with CMake 3.24+, or pass several architectures (e.g. 75;80;86).
CPU only → install to $HOME/opt/heffte/2.4.1-cpu (use a separate BUILD path, e.g. $HOME/opt/heffte/build-cpu-${VER}):
cmake -S "$SRC" -B "$BUILD" -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-DCMAKE_INSTALL_PREFIX=$HOME/opt/heffte/2.4.1-cpu \
-DHeffte_ENABLE_FFTW=ON \
-DHeffte_ENABLE_CUDA=OFF
cmake --build "$BUILD" -j"$(nproc)"
cmake --install "$BUILD"
Point OpenPFC at the install (see lib vs lib64 on your system):
export CMAKE_PREFIX_PATH=$HOME/opt/heffte/2.4.1-cpu:$CMAKE_PREFIX_PATH
# or, explicitly:
# cmake ... -DHeffte_DIR=$HOME/opt/heffte/2.4.1-cpu/lib64/cmake/Heffte
Use the directory that contains HeffteConfig.cmake.
4. Get OpenPFC sources¶
git clone https://github.com/VTT-ProperTune/OpenPFC.git
cd OpenPFC
5. Configure and build OpenPFC (CPU)¶
5.1 If cmake fails immediately — what is actually blocking?¶
OpenPFC’s CMake is not broken on a correctly prepared machine. Configuration almost always fails for one of these environment reasons (all fixable without changing the repo):
Symptom |
Cause |
Fix (see earlier sections) |
|---|---|---|
|
No install on |
Build and install HeFFTe to |
|
Shell never ran |
Load GCC + OpenMPI modules first, then |
Wrong compiler / MPI after you “fixed” modules |
Stale |
Remove the build directory ( |
Agents and IDEs: Do not point CMake at a hard-coded MPI under /share/apps/... unless that matches this machine’s documented modules. Follow §1 and §3 every time; the supported recipe is module-loaded OpenMPI + HeFFTe under $HOME/opt/heffte/<variant>.
With modules loaded (§1), CMAKE_PREFIX_PATH including $HOME/opt/heffte/2.4.1-cpu (or a module load that sets it — §3), pass the same compilers as for HeFFTe:
export CC=$(which gcc)
export CXX=$(which g++)
export CMAKE_PREFIX_PATH=$HOME/opt/heffte/2.4.1-cpu:$CMAKE_PREFIX_PATH
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-S . -B build-cpu
cmake --build build-cpu -j"$(nproc)"
If you omit -DCMAKE_BUILD_TYPE, single-config generators default to
RelWithDebInfo (cmake/ProjectSetup.cmake), not Debug. Multi-config
generators ignore CMAKE_BUILD_TYPE; CMake presets may set the type explicitly.
The examples below still pass -DCMAKE_BUILD_TYPE=Release when a fully
optimized, non-debug-info build is intended.
Minimal configure (optional): By default, OpenPFC may enable code coverage and (if Doxygen is installed) documentation. For binaries only:
export CMAKE_PREFIX_PATH=$HOME/opt/heffte/2.4.1-cpu:$CMAKE_PREFIX_PATH
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-DOpenPFC_ENABLE_CODE_COVERAGE=OFF \
-DOpenPFC_BUILD_DOCUMENTATION=OFF \
-S . -B build-cpu
5.2 CMake cache variables (quick reference)¶
These switches are defined under cmake/ (see BuildOptions.cmake, Dependencies.cmake, CUDASupport.cmake, HIPSupport.cmake, LibraryConfiguration.cmake, CodeCoverage.cmake, ProjectSetup.cmake, CompilerSettings.cmake). Use -DNAME=ON|OFF (or STRING where noted) on the cmake command line.
Cache variable |
Typical use |
|---|---|
|
Single-config default is RelWithDebInfo if unset ( |
|
Must stay ON for supported builds (see §2). |
|
HeFFTe FFT stack (ON by default). OFF is an FD-only / kernel-only build: HeFFTe is not required; spectral sources, apps, and examples are skipped. Catch2 TUs that include |
|
Fetch HeFFTe into |
|
Optional HDF5 for profiling dumps and JSON |
|
GPU toolkit backends. Finite-difference / kernel-only GPU apps can build with the toolkit plus CPU HeFFTe; spectral GPU FFT paths additionally require matching CUDA/ROCm HeFFTe (§3, §6–§8). |
|
Derived from the found HeFFTe package (CUDA/ROCm backend present). Gates spectral GPU FFT sources and spectral GPU apps; finite-difference GPU targets can still build with CPU-only HeFFTe. |
|
GPU-aware MPI when supported (defaults ON when CUDA/HIP is enabled). |
|
Scope of targets built alongside |
|
Doxygen docs (ON if |
|
|
|
Development extras such as |
|
|
|
Optional NaN guards (OFF by default). Debug builds enable NaN checks automatically; set ON to force them in non-Debug builds ( |
|
Build |
5.2.1 GPU-aware MPI (configure vs runtime)¶
When CUDA is enabled and OpenPFC_MPI_CUDA_AWARE=ON, CMake builds and runs a tiny probe (cmake/openpfc_mpix_cuda_probe.c, linked against MPI::MPI_C from find_package(MPI REQUIRED COMPONENTS C CXX)) using try_run, which exercises MPIX_Query_cuda_support() under MPI_Init / MPI_Finalize. If the probe exits non-zero, configuration prints a warning—use a CUDA-aware Open MPI build, or set -DOpenPFC_MPI_CUDA_AWARE=OFF and reconfigure.
Other MPI stacks (for example Cray MPICH on LUMI-G) are not probed this way. OpenPFC_MPI_HIP_AWARE is also not configure-probed; follow docs/INSTALL.LUMI.md for MPICH_GPU_SUPPORT_ENABLED, and use verify_gpu_aware_mpi (installed under bin/ with HIP builds) for a multi-rank device-buffer smoke test.
Cross-compiling: the runtime part of the CUDA probe is skipped; validate on the target machine instead.
For toolchain-specific examples (cluster CMAKE_TOOLCHAIN_FILE), see CMakePresets.json and cmake/toolchains/.
6. Configure and build OpenPFC (CUDA)¶
HeFFTe requirement: OpenPFC always needs a HeFFTe package for CPU FFT/decomposition. With OpenPFC_ENABLE_CUDA=ON, CMake splits CUDA support into two levels:
CUDA runtime / kernel targets: require the CUDA toolkit. Finite-difference CUDA apps that do not use FFTs (for example
wave2d_cuda) can still build when the detected HeFFTe package is CPU-only.CUDA spectral FFT targets: require HeFFTe built with
-DHeffte_ENABLE_CUDA=ON, installed under e.g.$HOME/opt/heffte/2.4.1-cuda(§3). If this is missing, CMake printsOpenPFC_ENABLE_CUDA_SPECTRAL = OFF, skips CUDA spectral FFT runtime and spectral CUDA apps/tests, and continues configuring finite-difference CUDA targets.
For a full CUDA spectral build, set CMAKE_PREFIX_PATH to include the CUDA HeFFTe prefix (or load a module that does).
Load the CUDA module so nvcc is on PATH, then configure with explicit host compilers:
export CC=$(which gcc)
export CXX=$(which g++)
export CMAKE_PREFIX_PATH=$HOME/opt/heffte/2.4.1-cuda:$CMAKE_PREFIX_PATH
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-DOpenPFC_ENABLE_CUDA=ON \
-DCMAKE_CUDA_ARCHITECTURES=80 \
-S . -B build-gpu
cmake --build build-gpu -j"$(nproc)"
Match CMAKE_CUDA_ARCHITECTURES to your GPU (or native on CMake 3.24+). To find your GPU’s compute capability, run:
nvidia-smi --query-gpu=compute_cap --format=csv,noheader # e.g. 8.6 → use 86
Minimal configure (optional): As with the CPU build (§5), you can disable optional features:
export CMAKE_PREFIX_PATH=$HOME/opt/heffte/2.4.1-cuda:$CMAKE_PREFIX_PATH
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-DOpenPFC_ENABLE_CUDA=ON \
-DCMAKE_CUDA_ARCHITECTURES=80 \
-DOpenPFC_ENABLE_CODE_COVERAGE=OFF \
-DOpenPFC_BUILD_DOCUMENTATION=OFF \
-S . -B build-gpu
If CUDA is missing: If you pass -DOpenPFC_ENABLE_CUDA=ON but CMake cannot find the CUDA toolkit, configuration still succeeds with a warning and CUDA support is turned off. Always check the configuration summary: OpenPFC_ENABLE_CUDA should be ON for a true GPU build. Fix PATH, CMAKE_CUDA_COMPILER, or CUDAToolkit_ROOT, then reconfigure from a clean build directory.
7. Install prefix (optional)¶
export CC=$(which gcc)
export CXX=$(which g++)
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-DCMAKE_INSTALL_PREFIX=$HOME/opt/openpfc \
-S . -B build
cmake --build build -j"$(nproc)"
cmake --install build
(Keep CMAKE_PREFIX_PATH including HeFFTe when running this cmake.)
8. AMD GPU (HIP)¶
For ROCm / HIP builds, load a recent GCC, OpenMPI, and ROCm before configuring anything (see §1 for compiler notes). Many clusters provide a ROCm module:
module purge
module load openmpi/5.0.10 # also selects its matching GCC on Tohtori
module load rocm/6.4.0 # for GPU — run `module avail rocm` and pick a version
If ROCm is not in a module, ensure its bin directory is on PATH (e.g. export PATH=/opt/rocm-6.4.0/bin:$PATH).
Verify:
g++ --version
mpicc --version
hipcc --version # after loading ROCm or setting PATH
rocm-smi # optional: list AMD GPUs
CMAKE_PREFIX_PATH for ROCm: CMake finds HIP via find_package(HIP). If HIP is not found, set CMAKE_PREFIX_PATH to your ROCm installation (e.g. -DCMAKE_PREFIX_PATH=/opt/rocm or /opt/rocm-6.4.0) so that HIPConfig.cmake is found.
HeFFTe requirement (same split as CUDA in §6): OpenPFC always links a HeFFTe package for CPU FFT/decomposition. With OpenPFC_ENABLE_HIP=ON, CMake separates:
HIP runtime / kernel targets: need ROCm/HIP. Finite-difference HIP apps (for example
kobayashi_fd_hip,wave2d_hip,allen_cahn_hip) can build when the detected HeFFTe install is CPU-only.HIP spectral FFT targets: need HeFFTe built with
-DHeffte_ENABLE_ROCM=ON(§8.1). If ROCm HeFFTe is missing, CMake setsOpenPFC_ENABLE_HIP_SPECTRAL = OFF, skips HIP spectral FFT sources and spectral HIP apps/tests, and keeps finite-difference HIP targets enabled.
8.1. Build and install HeFFTe with ROCm¶
For HIP spectral FFT (HeFFTe with rocFFT), install HeFFTe with -DHeffte_ENABLE_ROCM=ON under $HOME/opt/heffte/2.4.1-rocm (§3). Pure finite-difference HIP builds do not need this variant. Use the same host compilers as for OpenPFC (§1). Do not build inside the OpenPFC repo; use $HOME/src (or similar) for the tarball and source, and a build directory outside the repo.
export VER=2.4.1
export SRC=$HOME/src/heffte-${VER}
export BUILD=$HOME/opt/heffte/build-rocm-${VER}
mkdir -p "$HOME/src" "$HOME/opt/heffte"
wget -q -O "$HOME/src/v${VER}.tar.gz" \
https://github.com/icl-utk-edu/heffte/archive/refs/tags/v${VER}.tar.gz
tar xf "$HOME/src/v${VER}.tar.gz" -C "$HOME/src"
export CC=$(which gcc)
export CXX=$(which g++)
# Ensure ROCm is on PATH; optionally:
export CMAKE_PREFIX_PATH=/opt/rocm-6.4.0:$CMAKE_PREFIX_PATH
cmake -S "$SRC" -B "$BUILD" -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-DCMAKE_INSTALL_PREFIX=$HOME/opt/heffte/2.4.1-rocm \
-DHeffte_ENABLE_FFTW=ON \
-DHeffte_ENABLE_ROCM=ON
cmake --build "$BUILD" -j"$(nproc)"
cmake --install "$BUILD"
Optionally set -DCMAKE_HIP_ARCHITECTURES=<arch> to match your GPU (e.g. gfx90a for MI210, gfx1100 for some RDNA3). Use rocm-smi or your vendor docs to get the architecture code.
Point CMake at this installation when building OpenPFC (see §3 for lib vs lib64):
export CMAKE_PREFIX_PATH=$HOME/opt/heffte/2.4.1-rocm:$CMAKE_PREFIX_PATH
8.2. Configure and build OpenPFC (HIP)¶
Load the ROCm module (or set PATH) so hipcc and HIP are available. Set CMAKE_PREFIX_PATH to include both the HeFFTe ROCm install and your ROCm installation, so OpenPFC can find HeFFTe and find_package(HIP) succeeds:
export CC=$(which gcc)
export CXX=$(which g++)
export CMAKE_PREFIX_PATH=$HOME/opt/heffte/2.4.1-rocm:/opt/rocm-6.4.0:$CMAKE_PREFIX_PATH
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-DOpenPFC_ENABLE_HIP=ON \
-S . -B build-hip
cmake --build build-hip -j"$(nproc)"
Adjust the ROCm path in CMAKE_PREFIX_PATH if your install is elsewhere (e.g. /opt/rocm). Optionally add -DCMAKE_HIP_ARCHITECTURES=<arch> to match your AMD GPU.
GPU-aware MPI (HIP): OpenPFC_MPI_HIP_AWARE defaults to ON when HIP is found. It enables device-pointer halo exchange in OpenPFC and should match a HeFFTe build with GPU-aware MPI (see HeFFTe’s Heffte_ENABLE_GPU_AWARE_MPI). The install includes verify_gpu_aware_mpi in bin/ to probe device-buffer MPI at runtime. On LUMI-G, see docs/INSTALL.LUMI.md for MPICH_GPU_SUPPORT_ENABLED and job layout.
Minimal configure (optional): To disable code coverage and documentation (avoids gcov link issues with the HIP toolchain):
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$CC" -DCMAKE_CXX_COMPILER="$CXX" \
-DOpenPFC_ENABLE_HIP=ON \
-DOpenPFC_ENABLE_CODE_COVERAGE=OFF \
-DOpenPFC_BUILD_DOCUMENTATION=OFF \
-S . -B build-hip
If HIP is not found: -DOpenPFC_ENABLE_HIP=ON is fail-closed — configure stops with a fatal error instead of silently building a CPU tree. Load the ROCm module so hipcc is on PATH, or set CMAKE_PREFIX_PATH / ROCM_PATH to the ROCm prefix that contains lib/cmake/hip/hip-config.cmake (ROCm 6/7) or HIPConfig.cmake. scripts/build.sh --with-rocm locates that prefix (Tohtori rocm/7.2.1 does not set CMAKE_PREFIX_PATH; hipcc may live in /usr/bin, so the script does not use dirname hipcc/.. as ROCM_PATH). CMake 3.21–3.24 must use ROCm Clang as CMAKE_HIP_COMPILER, not the hipcc wrapper. Then reconfigure from a clean build directory.
CMake will warn if HIP is enabled but HeFFTe lacks ROCm support; that only disables HIP spectral paths (OpenPFC_ENABLE_HIP_SPECTRAL = OFF). Add the ROCm HeFFTe install from §8.1 when you need spectral HIP FFT or Tungsten HIP.
Code coverage: If the HIP build fails at link with undefined __gcov_* symbols, disable code coverage (e.g. -DOpenPFC_ENABLE_CODE_COVERAGE=OFF); coverage is not always compatible with the HIP/Clang toolchain.
toml++ and ROCm headers: If you see a preprocessor error in toml++ about __has_attribute requiring an identifier, it is due to ROCm headers defining the __noinline__ macro. As a workaround, ensure translation units that use both OpenPFC (with HIP) and toml++ include the toml-based headers before any OpenPFC or HIP includes, or try a different ROCm version.
Compiler notes¶
The current Tohtori reference stack is GCC 15.2.0 with Open MPI 5.0.10.
Older GCC (e.g. 8.x) may need extra link flags for
std::filesystem; OpenPFC’s CMake linkslibstdc++fsautomatically for GCC versions older than 9 when using GNU.