      program main
      parameter(n=64)
      parameter(m=25)
      parameter (ir1=1)
      parameter (ic1=1)
      parameter (ir2=3)
      parameter (ic2=2)
      parameter (ir3=3)
      parameter (ic3=2)
      parameter (ir4=1)
      parameter (ic4=3)
      
      integer a(n,n),b(n,n)
      integer i
      
      template t(n)
      align a(i,j) with t(i)
      align b(i,j) with t(i)
      distribute t(cyclic(ir1*ic1))
      
      enter tasking
      do i=1,m
         call colffts(a)
         output (a)
         processor(ir2,ic2),(1,0)
         
         call rowffts(a)
         input (a)
	 output(a)
         output (a)
         processor(ir3,ic3),(1,2)

         call verify(a)
         input(a)
	 output(a)
         processor (ir4,ic4), (0,1)
      enddo
      exit tasking
      
      end
      
      
      subroutine verify(atemp)
      parameter(n=64)
      parameter (ir1=1)
      parameter (ic1=1)
      parameter (ir4=1)
      parameter (ic4=3)
      integer i, atemp(n,n), a(n,n)
      integer temp
      integer fxbuffer(n*n+1)
      template t(n), atempt(n)
      align a(i,j) with t(j)
      align atemp(i,j) with atempt(i)
      distribute t(cyclic(ir4*ic4)), atempt(cyclic(ir1*ic1))
      
C     Scatter atemp to a
      a = atemp
      
c     check results
      pdo j=1,n
      pin a(:,j)
         do i=1,n
            if (a(i,j) .ne. ((i-1)*(j-1))) then
               call p_int(i) 
               call p_int(j)
               temp = a(i,j)
               call p_int(temp)
            endif
         enddo
      endpdo
      
      end
      
      subroutine rowffts(atemp)
      parameter(n=64)
      parameter (ir1=1)
      parameter (ic1=1)
      parameter (ir2=3)
      parameter (ic2=2)
      integer i, atemp(n,n),btemp(n,n), a(n,n),b(n,n)
      integer temp
      integer fxbuffer(n*n+1)
      template t(n), atempt(n)
      align a(i,j) with t(i)
      align b(i,j) with t(i)
      align atemp(i,j) with atempt(i)
      align btemp(i,j) with atempt(i)
      distribute t(cyclic(ir2*ic2)), atempt(cyclic(ir1*ic1))

C     Initialize b
      b = 0

C     Scatter atemp to a
      a = atemp
      
      pdo i=1,n
      pin a(i,:),b(i,:)   
      pout b(i,:)

      do j=1,n
         do k=1,j-1
            b(i,j) = b(i,j) + a(i,k)
         enddo
      enddo

      endpdo

C     Gather btemp from b
      atemp = b
      
      end
      
      subroutine colffts(atemp)
      parameter(n=64)
      parameter (ir1=1)
      parameter (ic1=1)
      parameter (ir3=3)
      parameter (ic3=2)
      integer i,j,k, atemp(n,n), a(n,n),b(n,n)
      integer temp
      integer fxbuffer(n*n+1)
      template t(n), atempt(n)
      align a(i,j) with t(j)
      align b(i,j) with t(j)
      align atemp(i,j) with atempt(i)
      distribute t(cyclic(ir3*ic3)), atempt(cyclic(ir1*ic1))
      
C     Initialize a and b
      a = 1
      b = 0
      
C     Perform the column "fft"
      pdo j=1,n
      pin a(:,j),b(:,j)   
      pout b(:,j)
      
      do i=1,n
         do k=1,i-1
            b(i,j) = b(i,j) + a(k,j)
         enddo
      enddo

      endpdo
      
C     Gather atemp from b
      atemp = b
      
      end
