Search code examples
chapelforall

How do I count iterations in a Chapel forall loop


I'd like to know how many times a loop is executed when using Chapel's forall. This code using the CDO Library fails, and I'm sure it's right to do so. Could someone give me a good example?

var j:int = 0;
writeln("\n=== FORALL LOOP ===");
forall row in cursor {
  writeln("from: ", row['from_nm'], "\tto: ", row['to_nm']);
  j += 1;
}
writeln("Expected 10 rows, got ", j);

The error is

faerr.chpl:59: error: illegal lvalue in assignment
faerr.chpl:57: note: The shadow variable 'j' is constant due to forall intents in this loop

Solution

  • By default, most variable types (except arrays) are copied in to a forall loop so you can't modify them. This is done to avoid race conditions in the common case. If you want to be able to modify j within the forall loop, you need to use a forall intent.

    Forall intents are defined in the "Data Parallelism" section of the Chapel language spec. Since this code wants to reduce the j values of the tasks to a single value, you can use a reduce intent on the forall loop to count the iterations:

    var j:int = 0;
    writeln("\n=== FORALL LOOP ===");
    
    forall row in cursor with (+ reduce j) {
      writeln("from: ", row['from_nm'], "\tto: ", row['to_nm']);
      j += 1;
    }
    
    writeln("Expected 10 rows, got ", j);