Skip to content
Awais Asghar.
HPC & Systems2026

Parallel Laplace Solver on HPC

MPI versus OpenMP for a 2D Jacobi solver on a 128-core AMD EPYC cluster.

Benchmarks distributed-memory (MPI) against shared-memory (OpenMP) parallelism for a 2D Laplace equation solver on the NUST RCMS supercomputer, with correctness checks, cluster mapping scripts and speedup and efficiency plots. MPI scaled to 3.06× at eight processes where OpenMP flattened out.

Parallel Laplace Solver on HPC thumbnail

README · rendered from GitHub

Header

Project Status Platform CPU MPI Language Build License

Image Image Image

Project Structure

HPC_Project/
├── part1/
│   ├── cluster_map.sh
│   └── cluster_visualize.py
│
├── part2/
│   ├── CMakeLists.txt
│   ├── src/
│   │   ├── laplace_serial.cpp
│   │   ├── laplace_mpi.cpp
│   │   ├── laplace_omp.cpp
│   │   ├── verify_correctness.py
│   │   └── benchmark.py
│   ├── build/
│   └── results/
│
└── run_all.sh

Methodology

Image image

Step-by-Step Execution Guide

Phase 1: Upload the Project to HPC

Step 1.1: Open Your Terminal

Open WSL on your Windows PC inside the project folder, or use a Linux terminal.

Step 1.2: Upload the Project Folder to HPC

For a temporary user account:

scp -r -O -oHostKeyAlgorithms=ssh-rsa Project user2@10.19.10.50:~

For your own named account:

rsync -avz --progress -e "ssh -p 22 -oHostKeyAlgorithms=+ssh-rsa" . awais.seecs@10.19.10.150:~/Solution

Enter your HPC password when prompted.

Phase 2: Log Into the HPC

Step 2.1: SSH Into the HPC Head Node

For a temporary user account:

ssh -X user2@10.19.10.50 -oHostKeyAlgorithms=+ssh-rsa
ls

For your own named account:

ssh -X awais.seecs@10.19.10.150 -p 22 -oHostKeyAlgorithms=+ssh-rsa
ls

WARNING: Never run simulations on the head node (afrit). Any simulation on the head node will be terminated without warning and data may be lost.

Step 2.2: Navigate to the Build Folder

cd Solution
ls
cd Project
ls
cd part2
ls
cd build
ls

Step 2.3: Build the Project Using CMake

cmake ..

Step 2.4: Compile All Three Solvers

make -j4

Step 2.5: Verify Binaries Were Created

ls

You should see laplace_mpi, laplace_omp, and laplace_serial listed.

Phase 3: Set Up the Results Folder

Step 3.1: Create the Results Directory

mkdir -p ~/Project/part2/results

Step 3.2: Copy Binaries and Scripts Into Results

cp ./laplace_mpi     ~/Project/part2/results/
cp ./laplace_omp     ~/Project/part2/results/
cp ./laplace_serial  ~/Project/part2/results/
cp ../src/verify_correctness.py ~/Project/part2/results/
cp ../src/benchmark.py          ~/Project/part2/results/

Step 3.3: Confirm Everything Is in Place

cd ..
ls -lh ~/Project/part2/results/

Expected files: benchmark.py laplace_mpi laplace_omp laplace_serial verify_correctness.py

Phase 4: Initial Test Run (Small Grid)

Navigate to the results folder and run a correctness check on a small grid before the full benchmark. Check which Python version is on your HPC first.

cd ~/Project/part2/results

./laplace_serial 32 10000 1e-4

mpirun -n 4 ./laplace_mpi 32 10000 1e-4

./laplace_omp 32 10000 1e-4 4

python3 verify_correctness.py 32

Expected output for each comparison:

RESULT: PASS - outputs match within tolerance.

Phase 5: Full Benchmark

Run each command one at a time. Wait for each to finish before typing the next.

Step 5.1: MPI Scaling Test (N=256, Varying Processes)

mpirun -n 1 ./laplace_mpi 256 5000 1e-4
mpirun -n 2 ./laplace_mpi 256 5000 1e-4
mpirun -n 4 ./laplace_mpi 256 5000 1e-4
mpirun -n 8 ./laplace_mpi 256 5000 1e-4

Step 5.2: OpenMP Scaling Test (N=256, Varying Threads)

./laplace_omp 256 5000 1e-4 1
./laplace_omp 256 5000 1e-4 2
./laplace_omp 256 5000 1e-4 4
./laplace_omp 256 5000 1e-4 8

Step 5.3: Serial Baseline for Different Grid Sizes

./laplace_serial 256 5000 1e-4
./laplace_serial 512 5000 1e-4

Step 5.4: Grid Size Scaling With 4 Procs and 4 Threads

mpirun -n 4 ./laplace_mpi 128 5000 1e-4
mpirun -n 4 ./laplace_mpi 256 5000 1e-4
mpirun -n 4 ./laplace_mpi 512 5000 1e-4

./laplace_omp 128 5000 1e-4 4
./laplace_omp 256 5000 1e-4 4
./laplace_omp 512 5000 1e-4 4

Phase 6: Generate Graphs

Step 6.1: Print the CSV Contents

cat mpi_timing.csv
cat omp_timing.csv
cat serial_timing.csv

Step 6.2: Install matplotlib on Your PC

pip install matplotlib numpy

Step 6.3: Generate All Performance Graphs

python3 benchmark.py

Graphs produced:

FileDescription
speedup_comparison.pngMPI vs OpenMP speedup line chart
execution_time.pngExecution time vs parallelism
grid_scaling.pngTime vs grid size (log-log)
efficiency.pngParallel efficiency percentage
bar_comparison.pngSerial vs OpenMP vs MPI at N=256
mpi_scaling.pngMPI execution time per process count

Phase 7: Part I | Mapping the HPC Cluster

Step 7.1: SSH Back Into HPC and Go to Part 1 Folder

ssh -X awais.seecs@10.19.10.150 -p 22 -oHostKeyAlgorithms=+ssh-rsa
cd ~/Project/part1

Step 7.2: Run the Cluster Mapping Script

bash cluster_map.sh

Takes 2 to 4 minutes as it probes 29 nodes. Two files are created:

  • cluster_report.txt — human readable ranking table
  • cluster_data.csv — comma separated data for graph generation

Step 7.3: View the Node Ranking

cat cluster_report.txt

Step 7.4: Cluster Graphs Produced

FileDescription
node_availability.pngBar chart of node availability scores
node_ram.pngRAM usage per node
node_cpu_specs.pngCPU specification chart
numa_architecture.pngNUMA topology diagram
ram_pie.pngRAM distribution pie chart

Solver Arguments

All solvers accept: [N] [max_epochs] [tolerance]

BinaryExtra ArgExample
laplace_serialnone./laplace_serial 256 5000 1e-4
laplace_mpinonempirun -n 8 ./laplace_mpi 256 5000 1e-4
laplace_omp[num_threads]./laplace_omp 256 5000 1e-4 8

Algorithm Details (MPI)

  1. The NxN grid is split row-wise across MPI ranks.
  2. Each rank owns N/size rows (remainder distributed across first few ranks).
  3. Each rank allocates 2 extra ghost rows (top and bottom).
  4. Every Jacobi iteration, each rank computes new values for its real rows.
  5. MPI_Sendrecv exchanges boundary rows with neighboring ranks.
  6. Convergence checked globally using MPI_Allreduce (max of all local deltas).
  7. Final solution gathered to rank 0 using MPI_Gatherv.

Boundary Conditions:

WallTemperature
Top100 deg C (HOT)
Bottom0 deg C (COLD)
Left / Right0 deg C (Insulated)

Results

MPI Scaling

Image

OpenMP Scaling

Image

MPI vs OpenMP Head-to-Head

Image

Grid Size Scaling

Image

Verification and Correctness

Image

Parallel Efficiency

Image

Performance Results Summary

MPI Scaling (N=256, 5000 epochs)

MPI ProcessesTime (s)SpeedupEfficiency (%)
11.4661.00x100.0
20.9111.61x80.5
40.5382.72x68.1
80.4793.06x38.3

OpenMP Scaling (N=256, 5000 epochs)

OMP ThreadsTime (s)SpeedupEfficiency (%)
10.9971.00x100.0
20.9591.04x52.0
41.2530.80x19.9
81.7900.56x6.9

Grid Size Scaling (4 procs / 4 threads, 5000 epochs)

Grid SizeSerial (s)MPI 4P (s)OMP 4T (s)MPI vs Serial
128x128N/A0.2180.368N/A
256x2561.8950.5381.2533.52x
512x5125.3461.7824.6673.00x

Key Findings

  • MPI achieves 3.06x speedup at 8 processes with consistent scaling.
  • OpenMP degrades beyond 2 threads due to NUMA effects on the AMD EPYC 7452 dual-socket machine.
  • MPI is the superior model for this memory-bandwidth-bound problem on NUMA hardware.
  • All three solvers produce bit-for-bit identical results verified with 0.0 max absolute difference.
  • Primary MPI bottleneck is ghost row communication overhead at high process counts.
  • For N=512, more than 5000 epochs are needed for full convergence — consider SOR or multigrid.
Image

Output Files Reference

FileDescription
cluster_report.txtText report of all nodes
cluster_data.csvNode metrics in CSV format
laplace_mpi_N.csvMPI solution grid for size N
laplace_omp_N.csvOpenMP solution grid for size N
laplace_serial_N.csvSerial solution grid for size N
mpi_timing.csvTiming data for all MPI runs
omp_timing.csvTiming data for all OpenMP runs
serial_timing.csvTiming data for all serial runs

Important Notes

  • Do NOT run heavy simulations on the head node (afrit). Use compute nodes.
  • For N=1024, each grid takes ~8 MB. Stay within the free RAM shown in Part I.
  • For grids N >= 512, set max_epochs to at least 5000.
  • Convergence gets slower as N increases (more cells to equilibrate).
  • Offline nodes from the cluster scan: compute-0-7, 14, 15, 20, 25, 29, 30.

HPC System Info

FieldValue
Head Nodeafrit
IP Address10.19.10.150
CPUAMD EPYC 7452 32-Core
Total CPUs128 (2 sockets x 32 cores x 2 threads)
Total RAM125 GB
Compute Nodes29 (all offline during this project)
MPI VersionOpenMPI 3.1
OpenMP Version4.5
CompilerGCC 8.5.0

Conclusion

Image

More in Systems

Related projects

See all
  • Systems2025

    Cache Architecture Simulator

    A from-scratch cache simulator driven by valgrind traces, comparing LRU and random eviction.

    • C
    • C++
    • Make
    • valgrind
  • Systems2026

    maketensor

    The data pipeline that turns telescope FITS frames into training-ready HDF5 tensors.

    • Python
    • HDF5
    • Astropy
    • NumPy