subroutine dist_size(nPEs, erank, noper, oper, value, dist, memRank, rc)
!-----------------------------------------------------------------------------
! routine to populate the distribution sizes according to the specification
! file.
!-----------------------------------------------------------------------------
integer, intent(in ) :: nPEs ! number of PEs
integer, intent(in ) :: erank ! rank of dim seeded with base dist size
integer, intent(in ) :: noper(:) ! number of operators
type(character_array), intent(in ) :: oper(:,:) ! operator
real(ESMF_KIND_R8) :: value(:,:) ! value for operator
type(dist_specification_record), intent(inout) :: dist ! dist spec record
integer, intent(in ) :: memRank ! rank of memory
integer, intent(inout) :: rc
! local integers
integer :: ibase, irank, n
! local reals
real(ESMF_KIND_R8) :: arg, base
! initialize return flag
rc = ESMF_RC_NOT_IMPL
!-----------------------------------------------------------------------------
! compute the base distribution dimension size. Base is always at least one.
!-----------------------------------------------------------------------------
ibase = 1
if( erank > 0 ) then
arg = 1.0*erank
base = (nPEs)**(1.0/arg)
ibase = int(base)
endif
!-----------------------------------------------------------------------------
! initialize distribution size to base value
!-----------------------------------------------------------------------------
do irank=1, dist%drank
dist%dsize(irank) = ibase
enddo
!-----------------------------------------------------------------------------
! modify distribution size based on operators
!-----------------------------------------------------------------------------
do irank=1, dist%drank
do n=1,noper(irank)
if( pattern_query(trim(adjustL(oper(irank,n)%string)), "==") /= 0 ) then
! if equivalence operator, overwrite base value, and set to value
dist%dsize(irank) = value(irank,n)
if( noper(irank) > 1 ) then
! error - should only be one operator when equivalence is found
call ESMF_LogSetError(ESMF_FAILURE,msg="only one operator " // &
"should be found when equivalence operator == is used. " // &
" More than one was found. ", rcToReturn=rc)
return
endif
elseif( pattern_query(trim(adjustL(oper(irank,n)%string)),"=+") /= 0) then
! if addition operator, add new value to base value.
dist%dsize(irank) = dist%dsize(irank) + value(irank,n)
elseif( pattern_query(trim(adjustL(oper(irank,n)%string)),"=*") /= 0) then
! if multiplication operator, multiply new value with base value.
dist%dsize(irank) = dist%dsize(irank) * value(irank,n)
else
! error - unrecognized operator
call ESMF_LogSetError(ESMF_FAILURE,msg="unrecognized operator " // &
trim(adjustL(oper(irank,n)%string)) // " found. ", rcToReturn=rc)
return
endif
enddo ! n
enddo !irank
!-----------------------------------------------------------------------------
! check that each dimension has a minimum value of 1, specifically the memory
! locations beyond the dist rank. This means that tensor dimensions are
! distributed by one processor.
!-----------------------------------------------------------------------------
do irank=1, memRank
if( dist%dsize(irank) < 1 ) dist%dsize(irank) = 1
enddo !irank
!-----------------------------------------------------------------------------
rc = ESMF_SUCCESS
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
end subroutine dist_size