Parallel computing in IDLVersion 6.3 of IDL introduced the IDL-to-IDL bridge. Basically, this is a mechanism to start IDL sessions within IDL and communicate with them. Unfortunately, using it for parallel computing in IDL is rather more involved than one might like. LimitationThe IDL-to-IDL bridge requires an X11 connection. So much for running some huge calculation on a remote machine in a screen session. Building BlocksInitializingIDL-to-IDL bridges are created through the command: bridge = obj_new('IDL_IDLBridge') Unfortunately, the IDL session they create doesn't execute your $IDL_STARTUP, nor does it change its working directory to where you think it would be. You have to do that manually: bridge->execute, '@' + pref_get('IDL_STARTUP') bridge->execute, "cd, '" + pwd + "'" I created a wrapper, build_bridges that creates a given number of bridges (defaults to the number of CPUs in the system) and for each one does the above. I also change the number of threads each bridge may run to 1 or a number specified by the user. Using the BridgeWe can now use the bridges to do some work. Of course, we want to capture the output, and perhaps we want to pass some input. bridges = build_bridges() in = indgen(10,20) pout = ptr_new(fltarr(10,20), /no_copy) We'll use a callback routine to populate the output array with the results. pro callback, status, error, bridge, ud out = bridge->getvar('out') (*(ud.pout))[ud.i,ud.j] = out end The bridge needs to know it has to call the callback routine after it completes a task. bridge->setproperty, callback='callback' Then, we can loop over all work packages. We have to set up the ‘userdata’ structure ud appropriately for the callback. for i=0l,9 do for j=0l,19 do begin ud = {i:i,j:j,pout:pout} bridge = get_idle_bridge(bridges) bridge->setproperty, userdata=ud bridge->setvar, 'in', in[i,j] bridge->execute, /nowait, 'worker, in, out' endfor barrier_bridges, bridges There are two routines used that I haven't introduced yet. get_idle_bridge is a wrapper that returns an IDL_IDLBridge object of a bridge that is currently idle. It blocks until it finds one. barrier_bridges blocks until all bridges are idle, i.e., all bridges have finished their computations. At this point, our program worker has processed all inputs, and the output is available to our interactive session: out = (*pout) ptr_free, pout Cleaning upAfter we're done with our bridges, we can destroy them: burn_bridges, bridges Of course, if you have more calculations to do later, you don't have to destroy the bridges. They'll just be idle until you need them again. DownloadDownload my IDL-to-IDL bridges wrappers. Changelog
Bugs & feature requestsPlease send bugreports and feature requests to dwijn at iluvatar.org. |