
      SUBROUTINE globalInit(numChunk)
          USE chunkModule
          IMPLICIT NONE
          INTEGER numChunk
          numChunk = 1024
      END SUBROUTINE

      SUBROUTINE processorInit()
      END SUBROUTINE

      SUBROUTINE chunkInit(obj, width,height, chunkStruct, thisIndex)
          USE chunkModule
	  IMPLICIT NONE

          TYPE(chunk_struct) :: chunkStruct
          TYPE(chunk_type), POINTER :: chunk
          INTEGER width, height, thisIndex
          INTEGER (KIND=8) obj
          INTEGER i,j

          ALLOCATE (chunk)
          chunkStruct%chunk_ptr => chunk

          chunk%height = height
          chunk%width = width + 2
          chunk%objPtr = obj
          chunk%index = thisIndex
          chunk%iterations = 0

          DO i = 1, width
            DO j = 0, height-1
              chunk%temperature(j+1, i+1) = 100*(i-1) + j
            ENDDO 
          ENDDO

          nblock = 1024

          if (chunk%index .eq. 0) then
          start = IMPI_Wtime()
          endif

        END SUBROUTINE        

        SUBROUTINE nextIteration(chunkStruct)
          USE chunkModule
	  IMPLICIT NONE

          TYPE(chunk_struct) :: chunkStruct
          TYPE(chunk_type), POINTER :: chunk
          INTEGER i,j
          DOUBLE PRECISION   val

          chunk => chunkStruct%chunk_ptr

          DO i = 2, 11
           DO j = 2, 99
             val = ( chunk%temperature(j, i) + chunk%&
     &temperature(j, i+1) + chunk%temperature(j, i-1) + chunk%temperatur&
     &e(j+1, i) + chunk%temperature(j-1, i))/5.0
             chunk%temperature(j,i) = val
	   END DO
	  ENDDO

        END SUBROUTINE

        RECURSIVE SUBROUTINE sendToNeighbors(chunkStruct)
          USE chunkModule
	  IMPLICIT NONE

          TYPE(chunk_struct) :: chunkStruct
          TYPE(chunk_type), POINTER :: chunk
          REAL(KIND=8) buf(1:200)
          INTEGER left, right

          EXTERNAL nextStep

          chunk => chunkStruct%chunk_ptr

          right = mod(chunk%index+1,nblock)
          left = mod(chunk%index-1+nblock,nblock)

!          buf(1:chunk%height) = chunk%temperature(1:chunk%height, 2);
!          call f_send(left, buf, 100, AMPI_DOUBLE_PRECISION, 1, chunk%index, chunk%iterations)
          call f_send(left, chunk%temperature(1, 2), 100, AMPI_DOUBLE_PRECISION, 1, chunk%index, chunk%iterations)

!          buf(1:chunk%height) = chunk%temperature(1:chunk%height, chunk%width-1);
!         call f_send(right, buf,100,AMPI_DOUBLE_PRECISION,0,chunk%index,chunk%iterations)
         call f_send(right,chunk%temperature(1,chunk%width-1),100,AMPI_DOUBLE_PRECISION,0,chunk%index,chunk%iterations)
 
!          call f_irecv(chunk%objPtr, chunk%buf1, 100, AMPI_DOUBLE_PRECISION, 1, right, chunk%iterations)
         call f_irecv(chunk%objPtr, chunk%temperature(1,chunk%width),100, AMPI_DOUBLE_PRECISION, 1, right, chunk%iterations)

!          call f_irecv(chunk%objPtr, chunk%buf2, 100, AMPI_DOUBLE_PRECISION, 0, left, chunk%iterations)
          call f_irecv(chunk%objPtr, chunk%temperature(1,1), 100, AMPI_DOUBLE_PRECISION, 0, left, chunk%iterations)

          call f_iwaitall(chunk%objPtr, nextStep, chunkStruct, chunk%iterations)

        END SUBROUTINE


        RECURSIVE SUBROUTINE nextStep(chunkStruct)
          USE chunkModule
	  IMPLICIT NONE

          TYPE(chunk_struct) :: chunkStruct
          TYPE(chunk_type), POINTER :: chunk

          chunk => chunkStruct%chunk_ptr

!          chunk%temperature(1:chunk%height,chunk%width) = chunk%buf1(1:chunk%height)
!          chunk%temperature(1:chunk%height,1) = chunk%buf2(1:chunk%height)

          chunk%iterations = chunk%iterations + 1

          IF ( chunk%iterations .lt. 30) THEN
             call nextIteration(chunkStruct);
             call sendToNeighbors(chunkStruct);
          ELSE
             if (chunk%index .eq. 0) then
               endTime = IMPI_Wtime()
               write (*,*) "index:", chunk%index, "Time per Iteration:", (endTime-start)/30.0
             endif
          ENDIF

        END SUBROUTINE



