upc_forall statement

Phil Merkey

Introduction

Some consider the upc_forall statement to be a main stay of UPC programming. This programmer believe one should use it only for simple ``idiom'' loops like initialization loops and simple vector operations.

The upc_forall statement is a C for statements with an additional field called the affinity field. The affinity field is either an integer expression or a shared address and controls the execution of the body of the loop. The upc_forall loop is equivalent to one of the following forms. In the case where affinity is an integer:

for(i=0; i<N; i++)
 if( MYTHREAD == ( i % THREADS) ){
    body of the loop
 }
In the case where the affinity is an address:
for(i=0; i<N; i++)
 if( MYTHREAD == upc_affinity( &x[i] ) ){
    body of the loop
 }

There is lots of discussion about compiler optimization associated with this construct, but that is beyond the tutorial.

Nested upc_forall statements are legal, but their behavior might be non-intuitive.

The first example is based on an integer value for the affinity. Note that the for statement is executed SIZE number of time. It simply skips the body of the loop if the affinity doesn't match.

<upc-forall1.c>=
#include <stdio.h>
#include <upc.h>

#define NperTHREAD 4
#define SIZE  (NperTHREAD * THREADS)

main ()
{
  int i;
  
  // "affinity" is an int so it is (i mod THREADS)
  upc_forall( i=0;                               // Init field
           i< SIZE;                              //Condition field 
           i++, printf(">%d %d\n", MYTHREAD, i); //Increment field  
           i ){                                  // Affinity field
          printf("MYTHREAD is %d and I am on iteration %d\n", MYTHREAD, i);
  }
}

The second case is the same idea, but this time we have a shared array and we use the affinity of the elements in that array to control the loop.

<upc-forall2.c>=
#include <stdio.h>
#include <upc.h>

#define NperTHREAD 4
#define SIZE  (NperTHREAD * THREADS)

shared int x[SIZE];

main ()
{
  int i;
  
  // "affinity" is an int so it is (i mod THREADS)
  upc_forall( i=0;                               // Init field
           i< SIZE;                              //Condition field 
           i++, printf(">%d %d\n", MYTHREAD, i); //Increment field  
           &x[i] ){                                  // Affinity field
          printf("MYTHREAD is %d and I have affinity to x[%d]\n", MYTHREAD, i);
  }
}