!----------------------------------------------------------------!
! The current code has the purpose:                              !
! (1) demonstrate firstprivate variables.                        !
! (2) reduction variables.                                       !
!----------------------------------------------------------------!
! Xiaoxu Guan at LSU HPC.                                        !
! March 17, 2016                                                 !
!----------------------------------------------------------------!

      program first_private
      implicit none
      integer            :: i,id,nosize,noprocs,omp_get_num_procs,omp_get_thread_num
      integer, parameter :: idp = 8,nsize = 50
      real(kind=idp), dimension(0:nsize-1) :: array_a
      real(kind=idp)     :: temp,tsum,totsum


      noprocs = omp_get_num_procs()

      nosize = nsize
      do i = 0, nosize-1
         array_a(i) = dble(i)
      end do


         tsum = 0.0_idp
         totsum = 0.0_idp

!$omp parallel default(none) private(id,i) shared(nosize,noprocs,array_a)  &
!$omp firstprivate(tsum) reduction(+: totsum)

      id = omp_get_thread_num()

!$omp do 
      do i = 0, nosize-1
         tsum = tsum + array_a(i)
      end do
!$omp end do
      write(*,'(1x,i3,3x,f12.2)') id, tsum

!$omp do schedule(static,1)
      do i = 0, noprocs-1
         totsum = totsum + tsum 
      end do
!$omp end do
!$omp end parallel

      write(*,*)
      write(*,'(1x,a,f12.2)') 'totsum = ',totsum
      write(*,'(1x,a,f12.2)') 'correct answer = ', 0.5_idp*nosize*(nosize-1)

      end program first_private

