Want to understand the numerical result? Follow the six-step diffusion course from sampling and stability through controlled error studies to a checked C++/MPI run.

Start with diffusion

After installing and checking the SDK:

openpfc init my-model --model=diffusion
cd my-model
openpfc run model.cpp input.json --launcher=none

The destination must be new. model.cpp is a complete editable C++20 program; input.json sets its parameters. run compiles when necessary, preserves the input and launches one rank directly. Use openpfc compile model.cpp to compile without running. Add --sdk /path/to/openpfc-sdk when your installation requires it.

The starter solves the periodic heat equation using finite differences and forward Euler. Its initial field is \(1+0.1\cos(2\pi x/L)\). Diffusion should reduce this oscillation and conserve its mean. The diffusion lesson derives that expectation and shows why the time step matters.

Read the attempt, not just the terminal

The CLI prints the saved attempt directory. Inside it:

File What it tells you
stdout.log, stderr.log The program’s messages and errors
status.json Exit status and output checksums
results/summary.json Global mean, initial and final L2 norms, time and rank count
results/diagnostics.csv Time history of the mean and L2 norm
results/field_rank_0.csv Rank zero’s final field values

With the default input, check that the mean remains near 1 and final_l2 < initial_l2. A clean exit establishes successful execution; the conserved mean and decaying mode check the intended behaviour of this particular equation. They do not validate a different physical model.

Edit only input.json and repeat run: the build can be reused, and a new attempt is saved. Editing the source triggers compilation. Keep outputs under results/. For a record that must survive cache cleanup:

openpfc export /path/to/cache/runs/openpfc-run-SHA256 /durable/new-record

Replace both paths with the printed run directory and a new destination. The CLI reference explains source dependencies, input snapshots and export in detail.

Add MPI deliberately

Invoke the CLI once, letting it launch the model processes:

openpfc run model.cpp input.json --ranks=2 --launcher=mpirun

Each rank writes its own field CSV; the mean and L2 diagnostics remain global. The default global problem should have the same physical answer as the one-rank run, up to floating-point reduction differences. Check that before measuring speed. Continue with HPC usage for Slurm, shared storage and GPU application paths.

Bundle the compiled CPU model

openpfc bundle packages a compiled model into an Apptainer/Singularity image. The image holds the executable and its selected runtime libraries. Host MPI and fabric libraries stay on the host and are bound at launch. It contains the program you compiled; it does not rebuild the model inside the image.

Replace these example prefixes with the MPI and fabric installations used by your compiler/SDK environment. First inspect the prepared recipe:

openpfc bundle model.cpp -o model.sif \
  --host-prefix /path/to/openmpi --host-prefix /path/to/ucx \
  --prepare-only

Then build on a host where Apptainer image creation is allowed:

openpfc bundle model.cpp -o model.sif \
  --host-prefix /path/to/openmpi --host-prefix /path/to/ucx

With no --base, the scratch image copies the build host’s dynamic loader, required glibc libraries and /bin/sh. Use a pinned local image with --base /path/to/base.sif when that image should supply them instead. Use the same SDK and compiler options as the model build.

The qualified source-model and bundle profile is CPU. These commands do not make an image portable across arbitrary CPU hosts, MPI installations or GPU vendors. CUDA and LUMI-G bundle profiles are not qualified.

If a fabric library shares a system directory with glibc, declare that file with --host-lib /path/to/library.so instead of binding the entire system library directory. The command identifies missing files. Read the packaging contract for library discovery, plugins and site-specific limitations.

The outputs include model.sif, its SHA-256 sidecar and model.sif.run, a helper that binds the declared host libraries. For a direct one-rank run with the matching host environment:

./model.sif.run input.json

Run from a writable directory and keep the input’s output paths under results/. Image creation and launching are separate operations. You can inspect a recipe without building it, and test an image before putting it into a larger scheduled job. Use openpfc bundle --help for exact options.