From a1f5bae25e7e6c4472695e856fe59209751b309f Mon Sep 17 00:00:00 2001 From: MB <michael.blaschek@univie.ac.at> Date: Wed, 24 Nov 2021 10:23:41 +0100 Subject: [PATCH] add MPI examples --- ...ty.miniconda3-py39-4.9.2-ubuntu-18.04-OMPI | 91 +++++++++++++ workshop/MPI/README.md | 64 +++++++++ workshop/MPI/log2_std_vs_log2_N.png | Bin 0 -> 24558 bytes workshop/MPI/parallel_pi.py | 123 ++++++++++++++++++ workshop/MPI/pi_vs_log2_N.png | Bin 0 -> 17984 bytes 5 files changed, 278 insertions(+) create mode 100644 definition-files/MPI/Singularity.miniconda3-py39-4.9.2-ubuntu-18.04-OMPI create mode 100644 workshop/MPI/README.md create mode 100644 workshop/MPI/log2_std_vs_log2_N.png create mode 100644 workshop/MPI/parallel_pi.py create mode 100644 workshop/MPI/pi_vs_log2_N.png diff --git a/definition-files/MPI/Singularity.miniconda3-py39-4.9.2-ubuntu-18.04-OMPI b/definition-files/MPI/Singularity.miniconda3-py39-4.9.2-ubuntu-18.04-OMPI new file mode 100644 index 0000000..f8557ed --- /dev/null +++ b/definition-files/MPI/Singularity.miniconda3-py39-4.9.2-ubuntu-18.04-OMPI @@ -0,0 +1,91 @@ +# Bootstrap: library +# From: mblaschek/imgw/ubuntu:18.04 +Bootstrap: localimage +From: ubuntu.sif + +%labels + + APPLICATION_NAME miniconda3 + APPLICATION_VERSION py39-4.9.2-Linux-x86_64 + APPLICATION_URL https://docs.conda.io + + AUTHOR_NAME Michael Blaschek + AUTHOR_EMAIL michael.blaschek@univie.ac.at + + LAST_UPDATED 20211118 + +%setup + +%environment + + # Set the conda distribution type, its version number, the python + # version it utilizes, the root and installation directories where + # the distribution will be installed within the container, and the + # root URL to the installer + export CONDA_DISTRIBUTION='miniconda' + export CONDA_VERSION='3' + export CONDA_PYTHON_VERSION='py39' + export CONDA_INSTALLER_VERSION='4.9.2' + export CONDA_ARCH='Linux-x86_64' + export CONDA_INSTALL_DIR="/opt/${CONDA_DISTRIBUTION}${CONDA_VERSION}" + + # Set PATH to conda distribution + export PATH="${CONDA_INSTALL_DIR}/bin:${PATH}" + +%post -c /bin/bash + + # Set operating system mirror URL + export MIRRORURL='http://at.archive.ubuntu.com/ubuntu' + + # Set operating system version + export OSVERSION='bionic' + + # Set system locale + export LC_ALL='C' + + # Set debian frontend interface + export DEBIAN_FRONTEND='noninteractive' + + # Upgrade all software packages to their latest versions + apt-get -y update && apt-get -y upgrade + + cd /tmp + + # Set the conda distribution type, its version number, the python + # version it utilizes, the root and installation directories where + # the distribution will be installed within the container, and the + # root URL to the installer + export CONDA_DISTRIBUTION='miniconda' + export CONDA_VERSION='3' + export CONDA_PYTHON_VERSION='py39' + export CONDA_INSTALLER_VERSION='4.9.2' + export CONDA_ARCH='Linux-x86_64' + export CONDA_INSTALLER="${CONDA_DISTRIBUTION^}${CONDA_VERSION}-${CONDA_PYTHON_VERSION}_${CONDA_INSTALLER_VERSION}-${CONDA_ARCH}.sh" + export CONDA_INSTALL_DIR="/opt/${CONDA_DISTRIBUTION}${CONDA_VERSION}" + export CONDA_ROOT_URL='https://repo.anaconda.com' + + # Download and install conda distribution + wget "${CONDA_ROOT_URL}/${CONDA_DISTRIBUTION}/${CONDA_INSTALLER}" + chmod +x "${CONDA_INSTALLER}" + "./${CONDA_INSTALLER}" -b -p "${CONDA_INSTALL_DIR}" + + # Remove conda installer + rm "${CONDA_INSTALLER}" + + # Add MPI Package from conda-forge + # ucx + # openmpi + $CONDA_INSTALL_DIR/bin/conda install -y -c conda-forge ucx openmpi mpi4py + + # Cleanup + apt-get -y autoremove --purge + apt-get -y clean + + # Update database for mlocate + updatedb + +%files + +%runscript + +%test diff --git a/workshop/MPI/README.md b/workshop/MPI/README.md new file mode 100644 index 0000000..2671c0d --- /dev/null +++ b/workshop/MPI/README.md @@ -0,0 +1,64 @@ +# MPI Tests with Python + +Based on a course from Ivan Kondov in [VSC Trainigs](https://gitlab.phaidra.org/imgw/trainings-course/-/blob/master/HPC%20with%20Python/docs/03_parallel_part_1.md#exercise-3-installation-and-setup-of-the-mpi4py-package) there are some easy tests that can be run with singularity containers and MPI. + +This requires to use the container built by the definition file: +[`definition-files/MPI/Singularity.miniconda3-py39-4.9.2-ubuntu-18.04-OMPI`](../../definition-files/MPI/Singularity.miniconda3-py39-4.9.2-ubuntu-18.04-OMPI) + + +## Example mpi4py + +There are some builtin tests witht mpi4py package to test its functionality, e.g. the ringtest + +```bash +mpirun -np 4 singularity exec miniconda3-ompi.sif python -m mpi4py.bench ringtest -n 1024 -l 1000 +time for 1000 loops = 0.00760765 seconds (4 processes, 1024 bytes) +``` +or hello world +```bash +mpirun -np 4 singularity exec miniconda3-ompi.sif python -m mpi4py.bench helloworld +Hello, World! I am process 0 of 4 on manjaro. +Hello, World! I am process 1 of 4 on manjaro. +Hello, World! I am process 2 of 4 on manjaro. +Hello, World! I am process 3 of 4 on manjaro. +``` + + +## Example Pi Statistics +based on an example from [Cornell University](https://cvw.cac.cornell.edu/python/exercise) - Monte Carlo with mpi4py + + +Randomly thrown darts: red dots are those darts that land in the unit circle, and blue dots are those that do not. + +Fortunately, even though you are not a very good dart thrower, you are a good random number generator, and you can put those skills to work to estimate the numerical value of pi — the ratio of the circumference of a circle to its diameter. + +```bash +# Install additional python packages not installed in our container +# Will be installed to .local/lib/python3.9/site-packages/ +singularity exec miniconda3-ompi.sif python -m pip install numpy matplotlib +Defaulting to user installation because normal site-packages is not writeable +Collecting matplotlib +... +Successfully installed cycler-0.11.0 fonttools-4.28.2 kiwisolver-1.3.2 matplotlib-3.5.0 numpy-1.21.4 packaging-21.3 pillow-8.4.0 pyparsing-3.0.6 setuptools-scm-6.3.2 tomli-1.2.2 +# Now run the script with MPI +mpirun -np 4 singularity exec miniconda3-ompi.sif python parallel_pi.py +MPI size = 4 +1024 3.1505126953125 0.06090403395917971 +4096 3.1389007568359375 0.025047770509458944 +16384 3.1422119140625 0.012053709369960034 +65536 3.141084671020508 0.006269848947240971 +262144 3.142267942428589 0.0035848687877291755 +1048576 3.1418583393096924 0.0019135112002101906 +4194304 3.1416348814964294 0.0008085763712888695 +16777216 3.1416458263993263 0.0004231117067632255 +67108864 3.141561470925808 0.00018093953356869197 +268435456 3.14160884777084 9.47003093073785e-05 +``` + +Which produces two figures: + +Numerical esimate of pi as a function of how many darts are thrown (log2 scale). Error bars reflect the standard deviation in the estimate over multiple independent runs. + + + +Scaling of the fluctuations in the estimate of pi (log2(standard deviation)) as a function of log2(N) diff --git a/workshop/MPI/log2_std_vs_log2_N.png b/workshop/MPI/log2_std_vs_log2_N.png new file mode 100644 index 0000000000000000000000000000000000000000..f24910d5cea41916a5ce3b5c5fdd30197eb28afe GIT binary patch literal 24558 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 YR&Q<Q@5yH73=9kmp00i_>zopr0QuXcAOHXW literal 0 HcmV?d00001 diff --git a/workshop/MPI/parallel_pi.py b/workshop/MPI/parallel_pi.py new file mode 100644 index 0000000..c243465 --- /dev/null +++ b/workshop/MPI/parallel_pi.py @@ -0,0 +1,123 @@ +from __future__ import print_function, division +""" +An estimate of the numerical value of pi via Monte Carlo integration. +Computation is distributed across processors via MPI. +""" + +import numpy as np +from mpi4py import MPI +import matplotlib +matplotlib.use('Agg') +import matplotlib.pyplot as plt +import sys + + +def throw_darts(n): + """ + returns an array of n uniformly random (x,y) pairs lying within the + square that circumscribes the unit circle centered at the origin, + i.e., the square with corners at (-1,-1), (-1,1), (1,1), (1,-1) + """ + darts = 2*np.random.random((n,2)) - 1 + return darts + +def in_unit_circle(p): + """ + returns a boolean array, whose elements are True if the corresponding + point in the array p is within the unit circle centered at the origin, + and False otherwise -- hint: use np.linalg.norm to find the length of a vector + """ + return np.linalg.norm(p,axis=-1)<=1.0 + +def estimate_pi(n, block=100000): + """ + returns an estimate of pi by drawing n random numbers in the square + [[-1,1], [-1,1]] and calculating what fraction land within the unit circle; + in this version, draw random numbers in blocks of the specified size, + and keep a running total of the number of points within the unit circle; + by throwing darts in blocks, we are spared from having to allocate + very large arrays (and perhaps running out of memory), but still can get + good performance by processing large arrays of random numbers + """ + total_number = 0 + i = 0 + while i < n: + if n-i < block: + block = n-i + darts = throw_darts(block) + number_in_circle = np.sum(in_unit_circle(darts)) + total_number += number_in_circle + i += block + return (4.*total_number)/n + +def estimate_pi_in_parallel(comm, N): + """ + on each of the available processes, + calculate an estimate of pi by drawing N random numbers; + the manager process will assemble all of the estimates + produced by all workers, and compute the mean and + standard deviation across the independent runs + """ + + if rank == 0: + data = [N for i in range(size)] + else: + data = None + data = comm.scatter(data, root=0) + # + pi_est = estimate_pi(N) + # + pi_estimates = comm.gather(pi_est, root=0) + if rank == 0: + return pi_estimates + + +def estimate_pi_statistics(comm, Ndarts, Nruns_per_worker): + results = [] + for i in range(Nruns_per_worker): + result = estimate_pi_in_parallel(comm, Ndarts) + if rank == 0: + results.append(result) + if rank == 0: + pi_est_mean = np.mean(results) + pi_est_std = np.std(results) + return pi_est_mean, pi_est_std + +if __name__ == '__main__': + """ + for N from 4**5 to 4**14 (integer powers of 4), + compute mean and standard deviation of estimates of pi + by throwing N darts multiple times (Nruns_total times, + distributed across workers) + """ + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + size = comm.Get_size() + if rank == 0: + print("MPI size = {}".format(size)) + sys.stdout.flush() + Nruns_total = 64 + Nruns_per_worker = Nruns_total // size + # + estimates = [] + for log4N in range(5,15): + N = int(4**log4N) + result = estimate_pi_statistics(comm, N, Nruns_per_worker) + if rank == 0: + pi_est_mean, pi_est_std = result + estimates.append((N, pi_est_mean, pi_est_std)) + print(N, pi_est_mean, pi_est_std) + sys.stdout.flush() + if rank == 0: + estimates = np.array(estimates) + plt.figure() + plt.errorbar(np.log2(estimates[:,0]), estimates[:,1], yerr=estimates[:,2]) + plt.ylabel('estimate of pi') + plt.xlabel('log2(number of darts N)') + plt.savefig('pi_vs_log2_N.png') + plt.figure() + plt.ylabel('log2(standard deviation)') + plt.xlabel('log2(number of darts N)') + plt.plot(np.log2(estimates[:,0]), np.log2(estimates[:,2])) + plt.savefig('log2_std_vs_log2_N.png') + MPI.Finalize() diff --git a/workshop/MPI/pi_vs_log2_N.png b/workshop/MPI/pi_vs_log2_N.png new file mode 100644 index 0000000000000000000000000000000000000000..2132f4eb3e502862c71a9eacde1670006b976dd5 GIT binary patch literal 17984 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 Mr>mdKI;Vst01hd>sQ>@~ literal 0 HcmV?d00001 -- GitLab