diff --git a/mpi_pi_cpu/.gitignore b/mpi_pi_cpu/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..130dcdd146fdc58240a3bfeab9f238c426c46ce7
--- /dev/null
+++ b/mpi_pi_cpu/.gitignore
@@ -0,0 +1,2 @@
+mpi_pi_cpu
+output
diff --git a/mpi_pi_cpu/Makefile b/mpi_pi_cpu/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..928fa286aa46bb71712ac3f4371962dbc9771a57
--- /dev/null
+++ b/mpi_pi_cpu/Makefile
@@ -0,0 +1,2 @@
+mpi_pi_cpu: mpi_pi_cpu.c
+	mpicc $< -o $@
diff --git a/mpi_pi_cpu/load_modules.sh b/mpi_pi_cpu/load_modules.sh
new file mode 100755
index 0000000000000000000000000000000000000000..81909335de558a56da2a58a5fd9d86f03d458ce0
--- /dev/null
+++ b/mpi_pi_cpu/load_modules.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+module purge
+module load spack git gcc/7.3.0 openmpi/3.1.4-pmi-cuda-ucx
+
diff --git a/mpi_pi_cpu/mpi_pi_cpu.c b/mpi_pi_cpu/mpi_pi_cpu.c
new file mode 100644
index 0000000000000000000000000000000000000000..722d7c9b5e7d314a0c05b29686a1793681af5dba
--- /dev/null
+++ b/mpi_pi_cpu/mpi_pi_cpu.c
@@ -0,0 +1,57 @@
+/*
+* mpipi.c
+* Neil Gershenfeld 2/5/11
+* Erik Strand 3/6/2021
+* use MPI to evaluate pi by summation
+*/
+
+#include <stdio.h>
+#include <mpi.h>
+#include <sys/time.h>
+
+// number of terms evaluated by each process
+#define NPTS 250000000
+
+void main(int argc, char** argv) {
+    // variables used by all ranks
+    int rank;
+    long unsigned int i, istart, iend;
+    double sum, pi;
+
+    // variables used only by rank 0
+    unsigned long int start_time, end_time;
+    struct timeval start, end;
+    int nproc;
+    unsigned long int total_terms;
+    double mflops;
+
+    MPI_Init(&argc, &argv);
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+    if (rank == 0) {
+        MPI_Comm_size(MPI_COMM_WORLD, &nproc);
+        total_terms = nproc;
+        total_terms *= NPTS;
+        gettimeofday(&start, NULL);
+    }
+
+    istart = (long unsigned int)NPTS * rank + 1;
+    iend = istart + NPTS;
+    sum = 0.0;
+    for (i = istart; i <= iend; ++i) {
+        sum += 0.5 / ((i - 0.75) * (i - 0.25));
+    }
+    MPI_Reduce(&sum, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
+
+    if (rank == 0) {
+        gettimeofday(&end, NULL);
+        start_time = start.tv_sec * 1e6 + start.tv_usec;
+        end_time = end.tv_sec * 1e6 + end.tv_usec;
+        mflops = (double)nproc * NPTS * 5.0 / (end_time - start_time);
+        printf("processes = %d, terms per process = %ldM, total terms = %ldM\n", nproc, NPTS / 1000000, total_terms / 1000000);
+        printf("time = %fs, estimated GFlops = %f\n", (end_time - start_time) / 1.0e6, mflops / 1000);
+        printf("pi ~ %f\n", pi);
+    }
+
+    MPI_Finalize();
+}
diff --git a/mpi_pi_cpu/mpi_pi_cpu.slurm b/mpi_pi_cpu/mpi_pi_cpu.slurm
new file mode 100644
index 0000000000000000000000000000000000000000..d56bf5596185e08255f7229633fc2006d104f04f
--- /dev/null
+++ b/mpi_pi_cpu/mpi_pi_cpu.slurm
@@ -0,0 +1,19 @@
+#!/bin/bash
+#SBATCH -J mpi_pi_cpu
+#SBATCH -o output/mpi_pi_cpu_%j.out
+#SBATCH -e output/mpi_pi_cpu_%j.err
+#SBATCH --nodes=2
+#SBATCH --ntasks-per-node=40
+#SBATCH --gres=gpu:0
+#SBATCH --cpus-per-task=1
+#SBATCH --ntasks-per-core=1
+#SBATCH --threads-per-core=1
+#SBATCH --mem=10G
+#SBATCH --time 00:01:00
+
+source ./load_modules.sh
+srun ./mpi_pi_cpu
+
+echo ''
+echo $SLURM_NODEID
+lscpu