Parallel Mandelbrot Set Generator

I was once told that every programming worth his salt has, at some point, written a Mandelbrot set generator at some point in his/her life. I took this as advise and put this little program together.

Introduction

This is a fast Mandelbrot set generator written in C. It splits the work among an arbitrary number of processes (specified in a config file), making it perfect for generating fractals on a cluster. It is geared towards generating high quality Mandelbrot set zooms on a cluster without needing to use any external libraries.

All output images are bitmaps (gzipped if needed) so no special graphics libraries are needed. Pipes are used for inter-process communication (IPC), so nothing more than a POSIX interface to the operating system is needed here.

Here is an example of an image created by the generator. This is my favorite image that I have generated so far.

Mandelbrot set zoom

For video of zoom sequences,

mandel-zoom.ogg - 27M, Ogg Theora (free codec)
mandel-zoom.avi - 40M, Xvid (free software, but patent-encumbered codec)

Unfortunately, it right now only uses fixed-precision numbers. This limits the zoom level to a certain depth before the image will start to become blocky. Because all image data needs to be able to be sent over pipes, using multi-precision becomes much more difficult. Also, using multi-precision would require use of external libraries, which may limit use on clusters missing a multi-precision library.

Documentation

Using the generator is pretty simple. You just write a config file that looks like this,

## Example Mandelbrot set zoom configuration file
## ----------------------------------------------
## All lines that begin with a # are comments

## Image dimensions (pixels)
image_width  = 800
image_height = 600

## Plot properties
iterations = 512         # Iterations per pixel
xmin = -2.5              # Real minimum
xmax = 1.5               # Real maximum
ymin = -1.5              # Imaginary minimum
ymax = 1.5               # Imaginary maximum

## Jobs
image_jobs = 1           # Jobs per image
zoom_jobs = 4            # Number of frames to run at once

## Zoom
zoom_frames = 200        # Number of frames to produce
zoom_rate = 0.25         # Rate of zoom (smaller == slower)
zoomx = -1.268794803623  # Zoom real coordinate
zoomy =  0.353676833206  # Zoom imaginary coordinate

## Colormap
color_width = 50         # The scale of the colormap
red   = { 0, 0,   0,   0,   128, 255, 255, 255 }
green = { 0, 0,   128, 255, 128, 128, 255, 255 }
blue  = { 0, 255, 255, 128, 0,   0,   128, 255 }

This is the example config file that can be found with the source code. The xmin, xmax, ymin, and ymax options set the window for the first fractal.

image_jobs is the number of processes to run per image. zoom_jobs is the number of frames of the zoom to generate at a time. image_jobs times zoom_jobs gives the total number of CPU intensive processes that will exist. There will be a few more processes present, but this are just overhead that handle I/O.

The zoom options set how the images will be sequence so that a zoom sequence can be generated. The zoom_rate decides how much the generator window shrink per step. In the example above, the window will shrink by 25% each step. This is pretty fast. zoomx and zoomy give the position in the Mandelbrot set where the zoom will travel.

The colormap decides the series of colors that the generator will loop through. It starts with the first color and proceeds through the colormap in order interpolating between each color with color_width steps in between. After the last color, the colormap will loop back to the second color and start again. Color values are between 0 and 255 (one byte per value, three bytes per color).

In addition to the config file there are command line arguments,

Usage: ./mandel [options] CONFIG_FILE

Options:

        -c           Create a colormap image
        -z           Zip output files
        -q           Quiet. Only output errors
        -v           Print version info
        -h           Print this usage text

The -c option will create an image of the colormap to see how the colormap looks. The -z option will gzip the bitmaps (gzip needs to be installed) so that the generated data takes up megabytes rather than gigabytes.

Download

This program is licensed under the GPL.

This was mostly written for fun and I have no plans to make versioned releases at this time. You can get the code here (with Git),

git clone http://git.nullprogram.com/mandel.git

Or you can just download the latest snapshot: http://git.nullprogram.com/mandel.git

The Makefile assumes you are using gcc and gmake. If these assumptions are true, just run make and the code will be built.

Tips

Even on a single processor system that is not in a cluster, setting many jobs to generate a zoom sequence can be very useful. This is because writing the images out to the disk is slow. By generating many frames at once, the generator can be pipe-lined. When one frame is being written out to the disk, other frames will step up and use the CPU while the first process is waiting on the disk.

Bitmaps are uncompressed and can be very large in size, quickly taking up disk space. This can be a particular problem on a cluster where disk space may be limited because it is shared among many users. To get around the problem, the generator can gzip the bitmaps after they are created. It uses the "--fast" gzip setting so that more CPU time can be spent on generating fractals than compressing bitmaps. I have found that, for fractals, a gzipped bitmap is just as small (sometimes smaller) than the equivalent PNG image. Yes, I am surprised by this too. Try it out for yourself to see it first-hand.

On a cluster, I recommend configuring for the generator to use several times as many jobs as you have nodes on the cluster. I generally set image_jobs to the number of nodes on the cluster. I set zoom_jobs to 2 or 3 times the number of nodes. This should maximize the use of the cluster even when many of the jobs are caught up in I/O. They tend to bunch up like that. If they are bunching, add more jobs to the config file.