next up previous
Next: Communication library functions Up: Operators Previous: Operator new

Restricted type conversion

When an array has position information in its dimensions, Location references, instead of int values are used as indexes. Given a global index we can get a location reference by | operation from the range. Sometimes it is also convenient that given a location reference, we can get the order of the location in the range it comes from. So a type conversion is defined from Location to int inside at and over constructs.

  on(q)
    over(Location i= x|0:3) {
      b[i]=(int)i;
    }

will assign the location id to each array element. It is equivalent to,

  on(q)
    over(Location i= x|0:3) {
      b[i]=x.id(i);
    }

Whenever necessary, this conversion can be an implicit one.

We call it as a restricted conversion, because it works only with at and over constructs. For example,

  on(q)
    over(Location i= x|0:3) {
      Location j=i;
      b[i]=j;          //error, j can not be converted;
      
      Range y=x;   
      Location k=y|i;  //correct, i converted to an integer;
      b[i]=k;          //error, k can not be converted;
    }

Another restricted type conversion is vice versa, from int to Location. This only happens when an integer used as an index in a dimension which is not a collapsed dimension, and it will be converted to the location mapping from the range which define the dimension of the array.

For example, suppose b is a distributed array,

  int i=3;
  b[(Location)i]=i;

is equivalent to,

  int i=3;
  b[b.range[0]|i]=i;

Similarly, a triplet expression can be converted to a subrange. Both conversions are valid only when their results expected to be a location or subrange. And they also can be implicit ones.

Adding integers and triplets as access keys for distributed array provides a ``higher level'' access for programmers. But they are not intend to be abused. A programmer should consider their code to exploit the possibility to reuse concepts such as location and subrange to improve efficiency, instead of depending compiler to find reusable patterns. One more thing need to be noticed is that though it is actually correct to use both location reference and integer to access array element in a non-collapsed dimension, we still use symbol # to mark non-collapsed dimension when defining a distributed array. The reason to do this is to help compiler generate better code for address caculation when an array dimension is collapsed.

These type conversions are defined to simplify program writing. If they look confusing, one can always use inquiry functions to get the desired results.

One typical use of the type conversion is location shift. It supports ghost regions, which require a new constructor for BlockRange with specification of ghost widths. A collective operation Adlib.writeHalo can update the ghost regions of a distribute array, copying values from the physical segments of neighboring processes. For example, the following is a version of Jacobi iteration with only one iteration inside.

  Procs2 p(2, 4);

  on(p) {
    Range x = new BlockRange(100, p.dim(0), 1);  // ghost width 1
    Range y = new BlockRange(200, p.dim(1), 1);  // ghost width 1

    int [[#,#]] a = new int [[x,y]] ;

    // ... some code to initialize `a'

    int [[#,#]] b = new int [[x,y]];

    Adlib.writeHalo(a);

    over(Location i=x|:)
      over(Location j=y|:)
        b[i,j] = (a[i-1,j] + a[i+1,j] + a[i,j-1] + a[i,j+1]) / 4;
        // location i, j converted to integer + or - one, converted back;

    over(Location i=x|:)
      over(Location j=y|:)
        a[i,j] = b[i,j];

  }


next up previous
Next: Communication library functions Up: Operators Previous: Operator new
Bryan Carpenter 2002-07-12