Taming Wild Horses: Chapel Asynchronous Tasks
Chapel supports nesting data parallel and task parallel code arbitrary as desired. This allows you, for example, to spawn asynchronous tasks inside a forall loop. The code snippet below shows code for a case like this where a forall is run on an array of 3 elements. The work to be done for second element is time consuming, hence a new task is spawned to run the timeeater(). Seems straightforward isn’t it? What if timeeater() takes more time than the forall loop? You’d expect forall to wait till all the dynamically spawned tasks to complete, but unfortunately it’s not the case. So if you want everything to be done when you exit forall loop use the construct sync to synchronize.
Try running the code with and without sync and observe the value of result, which should be 500500 if forall exit only after all the tasks have completed.
var d : domain(1) = [1..3];
var a : [d] int = d;
var result : int;
sync forall i in a{
writeln(i);
if (i == 2) then {
begin result = timeeater();
}
}
writeln("end of forall");
writeln("result ", result);
proc timeeater(){
var tmp : int = 0;
for i in 1 .. 1000{
tmp = tmp + i;
if (i%25 == 0) then {
writeln("eating time ", i);
}
}
return tmp;
}
Chapel is Sweet
It has been a little while since I started playing around Chapel (http://chapel.cray.com/) language, but could not run anything fun and large until recently. As part of the B524 – Parallelism in Programming Languages and Systems class from Prof. Lumsdaine (http://osl.iu.edu/~lums/), we had to implement Single Source Shortest Path (SSSP) of Graph500 (http://www.cc.gatech.edu/~jriedy/tmp/graph500/) specification. Only then I could realize the easiness of many of the high-level abstractions provided in Chapel compared to other parallel languages or paradigms. Honestly, I did not expect it to work in the first run across a set of machines, but surprisingly it did!