next up previous contents
Next: HPJava: Work in progress. Up: HPJava Suggestions. Bryan Carpenter, Previous: Subranges and Array sections   Contents

Example

The HPF/F90 program...

  integer n
  parameter(n = 8)

  real u(n, n)

  !hpf$ distribute u (block, block) onto p
  !hpf$ processors p (2, 2)

  integer i, j
  integer iter

  do i = 1, n
    do j = 1, n
      if(i == 1 .or. i == n .or. j == 1 .or. j == n) then
        u(i, j) = 1.0
      else
        u(i, j) = 0.0
      endif
    enddo
  enddo

  do iter = 1, 5
    u(2 : n - 1, 2 : n - 1) = &
        0.25 * (u(2 : n - 1, 1 : n - 2) + u(2 : n - 1, 3 : n) + &
                u(1 : n - 2, 2 : n - 1) + u(3 : n, 2 : n - 1))
  enddo

end
could be translated as...
  final integer n = 8 ;

  Procs p = new Procs(2, 2) ;

  Range x = new Range(n, BLK, p.dim(0)) ;
  Range y = new Range(n, BLK, p.dim(1)) ;

  ArrayFloat  u = new ArrayFloat(x, y) ;
  ArrayInt mask = new ArrayInt(x, y) ;

  mask = x.gt(0).and(x.lt(n - 1)).and(y.gt(0)).and(y.lt(n - 1)) ;

  u.where(mask, 0.0, 1.0) ;

  ArrayFloat tmp1 = new ArrayFloat(x, y) ;
  ArrayFloat tmp2 = new ArrayFloat(x, y) ;
  ArrayFloat tmp3 = new ArrayFloat(x, y) ;
  ArrayFloat tmp4 = new ArrayFloat(x, y) ;

  for(int iter = 1 ; iter <= 5 ; iter++) {
    tmp1.shift(u, -1, 0) ;
    tmp2.shift(u,  1, 0) ;
    tmp4.shift(u, -1, 1) ;
    tmp3.shift(u,  1, 1) ;

    u.where(mask, tmp1.plus(tmp2).plus(tmp3).plus(tmp4).
                       times(0.25)) ;

        // where(mask) u = 0.25 * (tmp1 + tmp2 + tmp3 + tmp4)
  }
This assumes that the arithmetic members on arrays include boolean arithmetic, and that two variants of masked assignment (where) are provided (one with two arguments corresponds to F90 simple WHERE; one with three arguments corresponds to F90 WHERE/ELSEWHERE).

Variation: the where operation in the loop could be replaced by use of sections...

  Range i = x.sub(1, n - 2) ;  // subrange 1 : n - 2
  Range j = y.sub(1, n - 2) ;  // subrange 1 : n - 2

    ...

    u.sect(i, j).assign(tmp1.sect(i, j).plus(tmp2.sect(i, j)).
                   plus(tmp3.sect(i, j)).plus(tmp4.sect(i, j)).
                                                  times(0.25)) ;

        // u(2 : n - 1, 2 : n - 1) = 0.25 *
        //      (tmp1(2 : n - 1, 2 : n - 1) + 
        //       tmp2(2 : n - 1, 2 : n - 1) +
        //       tmp3(2 : n - 1, 2 : n - 1) +
        //       tmp4(2 : n - 1, 2 : n - 1))
Variation: the shift operations could be replaced by remap operations...
  ArrayFloat tmp1 = new ArrayFloat(i, j) ;
  ArrayFloat tmp2 = new ArrayFloat(i, j) ;
  ArrayFloat tmp3 = new ArrayFloat(i, j) ;
  ArrayFloat tmp4 = new ArrayFloat(i, j) ;

  ...

    tmp1.remap(u.sect(x.sub(2, n - 1), j)) ;
    tmp2.remap(u.sect(x.sub(0, n - 3), j)) ;
    tmp3.remap(u.sect(i, y.sub(2, n - 1))) ;
    tmp4.remap(u.sect(i, y.sub(0, n - 3))) ;

    // tmp3 = u(1 : n - 2, 2 : n - 1)
    // tmp2 = u(0 : n - 3, 1 : n - 2)
    // tmp1 = u(2 : n - 1, 1 : n - 2)
    // tmp4 = u(1 : n - 2, 0 : n - 3)

    u.sect(i, j).assign(tmp1.plus(tmp2).plus(tmp3).plus(tmp4).
                        times(0.25)) ;

        // u(2 : n - 1, 2 : n - 1) = 0.25 * 
        //                           (tmp1 + tmp2 + tmp3 + tmp4)
This corresponds more directly to the original Fortran which uses arithmetic on array sections, rather than shift operations.



Bryan Carpenter 2002-07-12