C     this program is the IPSC version of the host program that implements
C     the fast fourier transform algorithm.

C     NO IMPLICIT VARIABLE ANYWHERE.
C
c     system calls used
C             IPSC - setpid, load, killcube, CSEND, CRECV.
C       user-defined subroutines :

	program FFThost

	include '/usr/include/fcube.h'

	include '../include/fft.h'

	complex		cTmp(0:NN-1)
	complex		x(0:NN-1)
	integer		numpts
	integer 	allNode,npid,gtype,intSize,cmplxSize
	integer		numNode,numDim,numLoc
	data 		allNode,npid,gtype,intSize,cmplxSize / -1,0,999,4,8 /

	print *, 'Loading programs into node... '
	call setpid(npid)
	call load('fftnode', allNode, npid)

	print *, 'Enter # of points: '
	read  *, numpts
	
	numNode	= numnodes()
	numDim	= nodedim()
	numLoc  = numpts/numNode

	call csend(gtype,numpts,intSize,allNode,npid)
	print *, '# of points = ',numpts,'  ',numLoc,' poins in each node'
	print *, 'please wait...'
	do i = 0, numNode-1
	    call crecv(gtype+i,cTmp,cmplxSize*numLoc)

	  k = i*numLoc
	  do j = 0, numLoc
	    x(k) = cTmp(j)
	    k = k + 1
	  end do
	end do

   	call GlbRev(x,numpts)
	print *,'Final Answer:'
	do i= 1, numpts
	   print *,'x=',x(i)
	end do
	print *, 'all done.'
	call killcube(allNode,npid)

	stop
	end

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C			GlbRev					C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 
C     this subroutine incorporates global reverse wherein it sends
C     coefficients to home processors.
C     input parameters:
C         y - the distributed data vector.
C        n - the number of data elements.
C     output parameters:
C        the output is contained in y itself.

   	subroutine GlbRev(y,n)
	integer n
	complex y(0:n-1)

	include '../include/fft.h'

	complex		x(0:NN-1)
	integer Permute

	do i=0,n-1
	  x(i) = y(Permute(i,n))
	end do
	do i=0,n-1
	  y(i) = x(i)
	end do

	return
	end

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C			Permute					C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C     maps the offset of the partially transformed input array into the 
C     index of the element stored at location l.
	integer function Permute(l,m)
	integer l,m

	integer numBit, k, power2, Log2
	logical IsOdd

	numBit 	= Log2(m)
	k	= l
	power2 	= m / 2
	Permute = 0
	do i = 1, numBit
	    if (IsOdd(k)) Permute = Permute + power2
	    power2 = power2 / 2
	    k	   = k / 2
	end do

	return
	end

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C			IsOdd					C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C     returns TRUE if the input is an odd integer.
	logical function IsOdd(n)
	integer n

	if (2*(n/2) .EQ. n) then
	    IsOdd = .FALSE.
	else
	    IsOdd = .TRUE.
	endif

	return
	end

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C			Log2					C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C     returns the logarithm to the base 2 of the input integer.

	integer function Log2(n)
	integer n

	integer k

	k = n
	Log2 = 0
	do i = 1, n
	    if (k .GT. 1) then
	    	Log2 = Log2 + 1
	    	k    = k / 2
	    else
		return
		endif
	end do

	end
