mpiDL is a set of IDL bindings for the Message Passing Interface (MPI). It is used for tasks where communication between processes is required, as opposed to the independent behavior of TaskDL workers. It can make use of the multiple cores of a single computer and/or multiple nodes of a cluster. mpiDL is supported on OS X and Linux for both OpenMPI and MPICH.
As an example of using mpiDL, I will present a simple probability-based computation of pi using many cores of a computer. If you are interesting in evaluating mpiDL or require more information about, please contact me.
Setting up for using mpiDL requires placing the mpiDL lib/
directory in your IDL path and DLM path, as well as setting the MPIDL_DIR
environment variable to the root of your mpiDL distribution (make sure to do it in .bashrc
to make it available to non-interactive processes). Then you are ready to run an mpiDL program, such as the parallel_pi
example provided in the distribution:
examples$ runmpidl -np 8 ${PWD}/parallel_pi.sav
Running mpiexec -np 8 /home/research/mgalloy/software/mpiDL-2.4.0-Linux64/bin/mpidlstart
/home/research/mgalloy/software/mpidl-r431-par/examples/parallel_pi.sav...
******************************************************************
MPIDL Version 2.4.0 - a parallel implementation of IDL
(C) Copyright 2000 - 2014, Tech-X Corp.
All rights reserved.
******************************************************************
Process 1 gave: 3.143600
Process 2 gave: 3.131600
Process 3 gave: 3.137200
Process 4 gave: 3.116400
Process 5 gave: 3.140000
Process 6 gave: 3.172800
Process 7 gave: 3.157200
The final value of pi is: 3.142686
The -np 8
argument indicates that the example should run with 8 processes; the parallel_pi
example code has decided that it will have one master process collecting results and 7 workers computing pi. The example can also run with a single process, where that process both computes pi and collects the result:
examples$ runmpidl -np 1 ${PWD}/parallel_pi.sav
Running mpiexec -np 1 /home/research/mgalloy/software/mpiDL-2.4.0-Linux64/bin/mpidlstart
/home/research/mgalloy/software/mpidl-r433-434M-par/examples/parallel_pi.sav...
Process 0 gave: 3.142200
The final value of pi is: 3.142200
Also, note that a .sav
file is specified. This allows an each process to use a runtime IDL license instead of a full development license.
There are two routines in the source code: parallel_pi_calcpi
, which does not know about MPI and just computes an estimate of pi, and parallel_pi
itself which coordinates the work using the MPI interface. By the nature of MPI, the same routine is executed in each process, but the processes are given an identifier, called the “rank”, which lets the routine decide what it should be doing. In parallel_pi
, we determine that with the following code:
rank = mpidl_comm_rank()
nprocs = mpidl_comm_size()
Here, nprocs
is the total number of processes and rank
is an identifier from 0 to nprocs - 1
. From this information, parallel_pi
can determine if it will be computing pi and sending the results back or if it is the receiver of the information:
am_a_sender = (nprocs eq 1L) or (rank gt 0L)
am_a_receiver = (nprocs eq 1L) or (rank eq 0L)
This is more complicated than might seem to be required in order to handle the case of only one process which would need to be both a sender and receiver.
If it is a sender, the process must compute pi and send it back to the receiver (the rank 0 process referenced by DEST
in the mpidl_send
routine below):
if (am_a_sender) then begin
seedr = rank
a = dblarr(1)
a[0] = parallel_pi_calcpi(neval, seedr)
mpidl_send, a, DEST=0
endif
If it is the receiver, it allocates an array to hold the result from each sender and then receives the result from each sender in turn with mpidl_recv
. Finally, it computes the average of the values to give the result:
if (am_a_receiver) then begin
mypi = dblarr(n_senders)
for j = 0L, n_senders - 1L do begin
mypi[j] = mpidl_recv(COUNT=1, SOURCE=senders[j], /DOUBLE)
print, senders[j], mypi[j], format='(%"Process %d gave: %f")'
endfor
print, total(mypi, /preserve_type) / n_senders, $
format='(%"The final value of pi is: %f")'
endif
Check out the source code for all the details. Also, download the users guide for more information.
Full disclosure: I work for Tech-X and I am the product manager for the FastDL suite which includes mpiDL.