MPI parallelisation¶
Pycasino uses mpi4py to distribute VMC and DMC workloads across multiple processes via the Message Passing Interface (MPI) standard.
Installation¶
Before installing mpi4py, install the system MPI library:
$ sudo apt install libopenmpi-dev # Debian/Ubuntu
$ brew install open-mpi # macOS
mpi4py is installed automatically with Pycasino, but requires the system library to be present at install time.
Running with MPI¶
Pass the number of processes to mpirun (or mpiexec):
$ mpirun -n 4 casino /path/to/input/directory
Each MPI rank runs an independent Markov chain starting from a different random initial electron configuration. The ranks synchronise after every VMC block to accumulate statistics and to broadcast optimised parameters.
Note
The total number of VMC steps is divided evenly among ranks. Setting vmc_nstep : 1000000
with 4 ranks means each rank performs 250 000 steps. The statistical error therefore scales
as \(1/\sqrt{N_\text{rank} \times N_\text{step}}\).
Memory model¶
Pycasino uses MPI.Win.Allocate_shared to create a shared-memory energy buffer on each
compute node. This means:
Ranks on the same node read each other’s energy arrays directly from shared memory — no network transfer.
Ranks on different nodes exchange data through the normal MPI network layer after each block (
MPI.Barrierat block boundaries).
This design works well when vmc_nblock is large enough so that the synchronisation overhead
is small compared to the per-block compute time.
Choosing the number of ranks¶
A practical starting point is one rank per physical CPU core. MPI parallelisation in Pycasino is purely statistical (independent walkers), so efficiency does not degrade with large rank counts as long as each rank accumulates enough steps for meaningful statistics.
For wavefunction optimisation (runtype : vmc_opt), the parameter broadcast uses
mpi_comm.bcast so all ranks always start the next optimisation cycle from identical
parameters.
Combining MPI with Numba threading¶
Pycasino’s inner loops are compiled with Numba (@nb.njit). The JIT kernels currently use
parallel=False, so each rank is single-threaded and occupies one CPU core. Setting
NUMBA_NUM_THREADS therefore has no effect; use one MPI rank per physical core instead.