The foreach Loop

A foreach loop signifies that loop iterations are order-independent. This enables the compiler to vectorize the loop or to offload its execution to the GPU. In contrast, a for loop is order-dependent; and a forall loop can create parallel tasks and distribute iterations based on the iterator, as well as being order-independent.

The syntax of the foreach loop is similar to the other for-like loops:

var A: [1..N] int;
foreach i in A.domain do
  A[i] += 1;

Vectorizability of a foreach loop will be determined transitively based on vectorizability of the iterator it runs over. All default range, domain and array iterators are vectorizable (i.e. implemented using foreach). Therefore, the snippet above will be vectorized when run on a suitable architecture.

Same transitivity applies to vectorizability of forall loops, as well.

var Dom = {1..N} dmapped Block({1..N});
var A: [Dom] int;
forall i in A.domain do
  A[i] += 1;

The forall above will distribute the execution to all the locales and all the tasks within them. As the default parallel iterators for A.domain is implemented using foreach, tasks executing parts of this loop will benefit from vectorization.

Status and Future Work

  • The current implementation does not make full use of vectorization hinting. We hope to expand the coverage especially to vectorize outer loops.

  • We intend to add with clauses to foreach loops to support vector-lane-private variables.