A routine to collect all the row level data and store in passed array Gather the row blocks up for this cell to fill an array DD>FOR NOW USE ALL_REDUCE AS EASIER, BUT SHOULD BE ABLE
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(supercell_type), | intent(in) | :: | self | |||
complex, | intent(out), | dimension(:,:) | :: | arr |
subroutine sc_pull_rows_to_arr(self,arr)
use mp, only: sum_allreduce_sub
use array_utils, only: zero_array
implicit none
class(supercell_type), intent(in) :: self
complex, dimension(:,:), intent(out) :: arr !Note: Dimensions should be self%ncol, self%nrow
integer :: ic, rl,ru, cl,cu, irb
! Zero out arr |--> Not needed if gathering
! This may look like it is only needed for the sum_allreduce_sub branch below,
! however without this line we would end up not setting arr in cases where we
! think of this supercell as empty. This is usually fine, but for the ky=kx=0
! mode all processors consider the supercell to be empty, but we still need to
! initialise this array in some cases (e.g. when dumping to file). We could
! attempt to only do this zeroing in this special case to save some time, but
! we don't expect to be calling this routine much so opt for simpler approach.
call zero_array(arr)
!Now see if we want to exit
if (self%is_empty) return
if (.not.self%is_local) return
!Place local piece in arr
!$OMP PARALLEL DO DEFAULT(none) &
!$OMP PRIVATE(ic, irb, rl, ru, cl, cu) &
!$OMP SHARED(self, arr) &
!$OMP SCHEDULE(static)
do ic = 1, self%ncell
if (self%cells(ic)%is_empty) cycle
do irb = 1, self%cells(ic)%nrb
rl=self%cells(ic)%rb(irb)%row_llim
ru=self%cells(ic)%rb(irb)%row_ulim
cl=self%cells(ic)%rb(irb)%col_llim
cu=self%cells(ic)%rb(irb)%col_ulim
arr(cl:cu,rl:ru)=self%cells(ic)%rb(irb)%data
end do
end do
!$OMP END PARALLEL DO
!If we're now all local then also need comms
if (.not. self%is_all_local) then
!Now use MPI to get the rest of the data from other procs
!<DD>FOR NOW USE ALL_REDUCE AS EASIER, BUT SHOULD BE ABLE
!TO DO THIS WITH ALL_GATHERV WHICH SHOULD BE FASTER
! We only actually need the result on the head of the supercell
! as this is the only process which operates on the result.
! We could therefore replace allreduce with reduce.
if (self%sc_sub_pd%nproc > 0) call sum_allreduce_sub(arr, self%sc_sub_pd%id)
end if
end subroutine sc_pull_rows_to_arr