MPI-Povray consists of a patch to the Povray 3.1g raytracer that distributes work amongst a number of processing elements. Communication between the elements if acheived with MPI message passing.

I'd taken a look at Andreas Dilger's PVMPov patch and noticed that a few people were looking for an MPI version. As I'm not much of a programmer and know little about MPI I thought it would be a laugh to try and implement it.

Plus I wanted something cool to look at when demonstrating MPI code. Crashing Galaxies on a Beowulf cluster isn't as interesting as it sounds...

Not being much of a programmer, I didn't want to re-invent the wheel so this Patch is largely based on Andreas Dilger's excellent PVMPov work. I've re-implemented the message passing aspects in MPI but the block allocation and I/O code is largely the same as PVMpov. By switching from PVM to MPI a lot of the message passing code was simplified (and some got more complex...).

This patch will probably need more work but seems to work OK. It'll need plenty of testing. So far I've built it under Linux (MPICH) and IRIX (MPT/MPI and MPICH). Other *IX platforms should be OK as long as you have some MPI implementation installed. Please give it a go and see how it works for you. I'd be particularly interested in how it behaves on larger Linux clusters...

I haven't given much consideration to optimisation yet. There's probably some rationalisation I could do in the message passing code.

Using 52 R10000 CPUS on 2 SGI Origin 2000s with MPICH I rendered the PovBench test image in 4 seconds...

To get it working.

  1. Download the Povray source code

    This patch is relative to povuni_s.tgz from Povray 3.1g

  2. Dowload the patch. (mpi-povray-1.0.patch.gz)
  3. Unpack the source: tar xvfz povuni_s.tga
  4. Apply the patch: cd povray31; gzip -dc mpi-povray*.patch.gz | patch -p1
  5. cd povray31/source/mpi-unix
  6. Monkey with the Makefile to get the right options for your platform and MPI implementation. (MPICH provides mpicc which makes life easier.)
  7. Build a binary: make newxwin
  8. Run it: mpirun -np ? ./mpi-x-povray [options]
MPI-Povray Adds 2 extra command line options:

       +NH???        Height of MPI chunk
       +NW???        Width of MPI chunk
These control the dimentions of the chunks that get assigned to slave processes. Your milage will vary with these options. In general it's a trade off between message passing overhead and division of labour. If you set too large a chunk size then the odds are one unlucky Processing Element (PE) will get a hard section of the image to do and become rate-limiting for the whole job. Too small, and you may spend valuable processing time passing messages (or, more damagingly, blocking on Send/Recieve of messages) and you'll under-utilize your CPUS

As a guide, If the image is equally difficult to render in all parts of the image and you have a small no. of processors available ( less than 16 ) try making the block size bigger. Try to divide the image equally between PE's. If the image has very easy and very hard sections or you have a large number of processors available ( 50 or so ) then keep the default of 32x32.

Be aware though that the size of the PE's will get bigger as the block size gets bigger as they need to allocate buffers big enough to pack the data into before sending a message containing the rendered pixels back to the master. Plus, if you're using a Network of Workstations, rather than a single MP machine, the messages passing accross your network will be bigger.

This is just based on my experimentation so fiddle around in your setup for best results.
For animations, Each PE will get assigned it's own frame (while no. frames > no PEs) so the block size isn't as relevant.

Current issues