module param1
integer, parameter       :: nx=100,ny=100
real, dimension(nx,ny,1) :: anew, aold
integer, parameter       :: XPROC=2,YPROC=2
integer, parameter       :: NPROC=XPROC*YPROC

!HPF$ PROCESSORS PCS(XPROC,YPROC)
!!!HPF$ DISTRIBUTE (BLOCK,BLOCK,*) onto PCS :: anew,aold
!HPF$ DISTRIBUTE (BLOCK,BLOCK,*) onto PCS :: anew
!HPF$ ALIGN aold(:,:,:) WITH anew(:,:,:)

end module

program base1
use param1
real t,dt
real,dimension(2)        :: dr

real t1(NPROC), t2(NPROC)
!HPF$ PROCESSORS TPROC(NPROC)
!HPF$ DISTRIBUTE t1(BLOCK) onto TPROC
!HPF$ DISTRIBUTE t2(BLOCK) onto TPROC


INTERFACE
      extrinsic(hpf_local) subroutine timer(return_time, initial_time)
      real, dimension(:), intent(in)  :: initial_time
      real, dimension(:), intent(out) :: return_time
!HPF$ DISTRIBUTE *(block) :: initial_time
!HPF$ ALIGN return_time with initial_time
      end subroutine timer

END INTERFACE

aold=1.0
anew=0.0

t=0
dt=1.0
dr=1.0

call timer(t2,t1)

do istep=1,50
call update(t,dt,dr)
enddo
call timer(t1,t2)
print *,'time',t1,' seconds'

stop
end

subroutine update(t,dt,dr)
use param1
real t,dt
real,dimension(2)        :: dr


real, parameter :: cx=1.0,cy=1.0
real  sx,sy,sx2,sy2,sxy,sx1,sy1,sxy1


aold=anew
anew=0.0
t=t+dt

 sx=cx*dt/dr(1)
 sy=cy*dt/dr(2)
 sx2=sx**2
 sy2=sy**2
 sxy=sx*sy
 sx1=1.0/(1.0+sx)
 sy1=1.0/(1.0+sy)
 sxy1=1.0/(1.0+sx+sy)

write(6,*) 'TIME=',t,sx,sy,sxy1

do i=1,200
FORALL(i=1:nx,j=1:ny) anew(i,j,1)=exp(sin(aold(i,j,1)**2))
FORALL(i=1:nx,j=1:ny) anew(i,j,1)=anew(i,j,1)**3
enddo

Forall(i=2:nx-1,j=2:ny-1) anew(i,j,1)=                         &
       aold(i,j,1)                                             &
       -(aold(i+1,j,1)-aold(i-1,j,1))*sx/2.0-(aold(i,j+1,1)    &
       -aold(i,j-1,1))*sy/2.0                                  &
       +(aold(i+1,j,1)-2.0*aold(i,j,1)+aold(i-1,j,1))*sx2/2.0  &
       +(aold(i,j+1,1)-2.0*aold(i,j,1)+aold(i,j-1,1))*sy2/2.0  &
       +(aold(i+1,j+1,1)-aold(i+1,j-1,1)-aold(i-1,j+1,1)       &
       +aold(i-1,j-1,1))*sxy/4.0 

anew(1,:,1)=anew(2,:,1)
anew(nx,:,1)=anew(2,:,1)
anew(:,1,1)=sin(0.15*t)

write(6,*) anew(5,:,1), '*'
return
end

extrinsic(hpf_local) subroutine timer(return_time, initial_time)
real, dimension(:), intent(in)  :: initial_time
real, dimension(:), intent(out) :: return_time
return_time(lbound(return_time, 1)) =     &
    secnds(initial_time(lbound(initial_time, 1)))

end









