HPC - Mandelbrot set

Moreno Marzolla

Last updated: 2022-11-26

The file mpi-mandelbrot.c contains the skeleton of an MPI program that computes the Mandelbrot set; it is not a parallel version, since the master process does everything.

The program accepts the image height as an optional command-line parameter; the width is computed automatically to include the whole set. The program writes a graphical representation of the Mandelbrot set into a file mandebrot.ppm in PPM (Portable Pixmap) format. If you don’t have a suitable viewer, you can convert the image, e.g., into PNG with the command:

    convert mandelbrot.ppm mandelbrot.png

The goal of this exercise is to write a parallel version of the program, where all MPI processes contribute to the computation. To do this, you should partition the image into \(P\) vertical blocks where \(P\) is the number of MPI processes, and let each process compute a portion of the image (see Figure 1).

Figure 1: Domain decomposition for the computation of the Mandelbrot set with 4 MPI processes
Figure 1: Domain decomposition for the computation of the Mandelbrot set with 4 MPI processes

Specifically, each process computes a portion of the image of size \(\mathit{xsize} \times (\mathit{ysize} / P)\). This is an embarrassingly parallel computation, since there is no need to communicate. However, the processes do need to send their portion of image to the master, which will take care of stitching them together to form the final result. This is done using the MPI_Gather() function. This is a color image where three bytes are used to encode the color of each pixel. Therefore, the MPI_Gather() operation will transfer blocks of \((3 \times \mathit{xsize} \times \mathit{ysize} / P)\) elements of type MPI_BYTE.

You can initially assume that the vertical size ysize is an integer multiple of \(P\), and then relax this assumption. To this aim, you may let process 0 take care of the last (ysize % P) rows, or use MPI_Gatherv() to allow different block sizes to be assembled together.

You may want to keep the serial program as a reference; to check the correctness of the parallel implementation, you can compare the output images produced by both versions with the command:

    cmp file1 file2

Both images should be identical; if not, something is wrong.

To compile:

    mpicc -std=c99 -Wall -Wpedantic mpi-mandelbrot.c -o mpi-mandelbrot

To execute:

    mpirun -n NPROC ./mpi-mandelbrot [ysize]


    mpirun -n 4 ./mpi-mandelbrot 800