Skip to content

Commit

Permalink
dOxyGenized MOM_coms.F90
Browse files Browse the repository at this point in the history
  Added dOxyGen comments for all routines and arguments in MOM_coms.F90.  All
answers are bitwise identical.
  • Loading branch information
Hallberg-NOAA committed May 7, 2018
1 parent 0116078 commit 5490e5a
Showing 1 changed file with 122 additions and 44 deletions.
166 changes: 122 additions & 44 deletions src/framework/MOM_coms.F90
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,46 @@ module MOM_coms
module procedure reproducing_sum_2d, reproducing_sum_3d
end interface reproducing_sum

! The Extended Fixed Point (EFP) type provides a public interface for doing
! sums and taking differences with this type.
! The Extended Fixed Point (EFP) type provides a public interface for doing sums
! and taking differences with this type. The use of this type is documented in
! Hallberg, R. & A. Adcroft, 2014: An Order-invariant Real-to-Integer Conversion Sum.
! Parallel Computing, 40(5-6), doi:10.1016/j.parco.2014.04.007.
type, public :: EFP_type ; private
integer(kind=8), dimension(ni) :: v
end type EFP_type

interface operator (+); module procedure EFP_plus ; end interface
interface operator (-); module procedure EFP_minus ; end interface
interface operator (+) ; module procedure EFP_plus ; end interface
interface operator (-) ; module procedure EFP_minus ; end interface
interface assignment(=); module procedure EFP_assign ; end interface

contains

!> This subroutine uses a conversion to an integer representation of real numbers to give an
!! order-invariant sum of distributed 2-D arrays that reproduces across domain decomposition.
!! This technique is described in Hallberg & Adcroft, 2014, Parallel Computing,
!! doi:10.1016/j.parco.2014.04.007.
function reproducing_sum_2d(array, isr, ier, jsr, jer, EFP_sum, reproducing, &
overflow_check, err) result(sum)
real, dimension(:,:), intent(in) :: array
integer, optional, intent(in) :: isr, ier, jsr, jer
type(EFP_type), optional, intent(out) :: EFP_sum
logical, optional, intent(in) :: reproducing
logical, optional, intent(in) :: overflow_check
integer, optional, intent(out) :: err
real :: sum ! Result
real, dimension(:,:), intent(in) :: array !< The array to be summed
integer, optional, intent(in) :: isr !< The starting i-index of the sum, noting
!! that the array indices starts at 1
integer, optional, intent(in) :: ier !< The ending i-index of the sum, noting
!! that the array indices starts at 1
integer, optional, intent(in) :: jsr !< The starting j-index of the sum, noting
!! that the array indices starts at 1
integer, optional, intent(in) :: jer !< The ending j-index of the sum, noting
!! that the array indices starts at 1
type(EFP_type), optional, intent(out) :: EFP_sum !< The result in extended fixed point format
logical, optional, intent(in) :: reproducing !< If present and false, do the sum
!! using the naive non-reproducing approach
logical, optional, intent(in) :: overflow_check !< If present and false, disable
!! checking for overflows in incremental results.
!! This can speed up calculations if the number
!! of values being summed is small enough
integer, optional, intent(out) :: err !< If present, return an error code instead of
!! triggering any fatal errors directly from
!! this routine.
real :: sum !< Result

! This subroutine uses a conversion to an integer representation
! of real numbers to give order-invariant sums that will reproduce
Expand Down Expand Up @@ -202,14 +221,27 @@ function reproducing_sum_2d(array, isr, ier, jsr, jer, EFP_sum, reproducing, &

end function reproducing_sum_2d

!> This subroutine uses a conversion to an integer representation of real numbers to give an
!! order-invariant sum of distributed 3-D arrays that reproduces across domain decomposition.
!! This technique is described in Hallberg & Adcroft, 2014, Parallel Computing,
!! doi:10.1016/j.parco.2014.04.007.
function reproducing_sum_3d(array, isr, ier, jsr, jer, sums, EFP_sum, err) &
result(sum)
real, dimension(:,:,:), intent(in) :: array
integer, optional, intent(in) :: isr, ier, jsr, jer
real, dimension(:), optional, intent(out) :: sums
type(EFP_type), optional, intent(out) :: EFP_sum
integer, optional, intent(out) :: err
real :: sum ! Result
real, dimension(:,:,:), intent(in) :: array !< The array to be summed
integer, optional, intent(in) :: isr !< The starting i-index of the sum, noting
!! that the array indices starts at 1
integer, optional, intent(in) :: ier !< The ending i-index of the sum, noting
!! that the array indices starts at 1
integer, optional, intent(in) :: jsr !< The starting j-index of the sum, noting
!! that the array indices starts at 1
integer, optional, intent(in) :: jer !< The ending j-index of the sum, noting
!! that the array indices starts at 1
real, dimension(:), optional, intent(out) :: sums !< The sums by vertical layer
type(EFP_type), optional, intent(out) :: EFP_sum !< The result in extended fixed point format
integer, optional, intent(out) :: err !< If present, return an error code instead of
!! triggering any fatal errors directly from
!! this routine.
real :: sum !< Result

! This subroutine uses a conversion to an integer representation
! of real numbers to give order-invariant sums that will reproduce
Expand Down Expand Up @@ -365,10 +397,15 @@ function reproducing_sum_3d(array, isr, ier, jsr, jer, sums, EFP_sum, err) &

end function reproducing_sum_3d

!> Convert a real number into the array of integers constitute its extended-fixed-point representation
function real_to_ints(r, prec_error, overflow) result(ints)
real, intent(in) :: r
integer(kind=8), optional, intent(in) :: prec_error
logical, optional, intent(inout) :: overflow
real, intent(in) :: r !< The real number being converted
integer(kind=8), optional, intent(in) :: prec_error !< The PE-count dependent precision of the
!! integers that is safe from overflows during global
!! sums. This will be larger than the compile-time
!! precision parameter, and is used to detect overflows.
logical, optional, intent(inout) :: overflow !< Returns true if the conversion is being
!! done on a value that is too large to be represented
integer(kind=8), dimension(ni) :: ints
! This subroutine converts a real number to an equivalent representation
! using several long integers.
Expand Down Expand Up @@ -401,8 +438,10 @@ function real_to_ints(r, prec_error, overflow) result(ints)

end function real_to_ints

!> Convert the array of integers that constitute an extended-fixed-point
!! representation into a real number
function ints_to_real(ints) result(r)
integer(kind=8), dimension(ni), intent(in) :: ints
integer(kind=8), dimension(ni), intent(in) :: ints !< The array of EFP integers
real :: r
! This subroutine reverses the conversion in real_to_ints.

Expand All @@ -412,10 +451,15 @@ function ints_to_real(ints) result(r)
do i=1,ni ; r = r + pr(i)*ints(i) ; enddo
end function ints_to_real

!> Increment an array of integers that constitutes an extended-fixed-point
!! representation with a another EFP number
subroutine increment_ints(int_sum, int2, prec_error)
integer(kind=8), dimension(ni), intent(inout) :: int_sum
integer(kind=8), dimension(ni), intent(in) :: int2
integer(kind=8), optional, intent(in) :: prec_error
integer(kind=8), dimension(ni), intent(inout) :: int_sum !< The array of EFP integers being incremented
integer(kind=8), dimension(ni), intent(in) :: int2 !< The array of EFP integers being added
integer(kind=8), optional, intent(in) :: prec_error !!< The PE-count dependent precision of the
!! integers that is safe from overflows during global
!! sums. This will be larger than the compile-time
!! precision parameter, and is used to detect overflows.

! This subroutine increments a number with another, both using the integer
! representation in real_to_ints.
Expand All @@ -441,10 +485,12 @@ subroutine increment_ints(int_sum, int2, prec_error)

end subroutine increment_ints

!> Increment an EFP number with a real number without doing any carrying of
!! of overflows and using only minimal error checking.
subroutine increment_ints_faster(int_sum, r, max_mag_term)
integer(kind=8), dimension(ni), intent(inout) :: int_sum
real, intent(in) :: r
real, intent(inout) :: max_mag_term
integer(kind=8), dimension(ni), intent(inout) :: int_sum !< The array of EFP integers being incremented
real, intent(in) :: r !< The real number being added.
real, intent(inout) :: max_mag_term !< A running maximum magnitude of the r's.

! This subroutine increments a number with another, both using the integer
! representation in real_to_ints, but without doing any carrying of overflow.
Expand All @@ -466,9 +512,14 @@ subroutine increment_ints_faster(int_sum, r, max_mag_term)

end subroutine increment_ints_faster

!> This subroutine handles carrying of the overflow.
subroutine carry_overflow(int_sum, prec_error)
integer(kind=8), dimension(ni), intent(inout) :: int_sum
integer(kind=8), intent(in) :: prec_error
integer(kind=8), dimension(ni), intent(inout) :: int_sum !< The array of EFP integers being
!! modified by carries, but without changing value.
integer(kind=8), intent(in) :: prec_error !< The PE-count dependent precision of the
!! integers that is safe from overflows during global
!! sums. This will be larger than the compile-time
!! precision parameter, and is used to detect overflows.

! This subroutine handles carrying of the overflow.
integer :: i, num_carry
Expand All @@ -484,8 +535,13 @@ subroutine carry_overflow(int_sum, prec_error)

end subroutine carry_overflow

!> This subroutine carries the overflow, and then makes sure that
!! all integers are of the same sign as the overall value.
subroutine regularize_ints(int_sum)
integer(kind=8), dimension(ni), intent(inout) :: int_sum
integer(kind=8), dimension(ni), &
intent(inout) :: int_sum !< The array of integers being modified to take a
!! regular form with all integers of the same sign,
!! but without changing value.

! This subroutine carries the overflow, and then makes sure that
! all integers are of the same sign as the overall value.
Expand Down Expand Up @@ -521,37 +577,45 @@ subroutine regularize_ints(int_sum)

end subroutine regularize_ints

!> Returns the status of the module's error flag
function query_EFP_overflow_error()
logical :: query_EFP_overflow_error
query_EFP_overflow_error = overflow_error
end function query_EFP_overflow_error

!> Reset the module's error flag to false
subroutine reset_EFP_overflow_error()
overflow_error = .false.
end subroutine reset_EFP_overflow_error

!> Add two extended-fixed-point numbers
function EFP_plus(EFP1, EFP2)
type(EFP_type) :: EFP_plus
type(EFP_type), intent(in) :: EFP1, EFP2
type(EFP_type) :: EFP_plus !< The result in extended fixed point format
type(EFP_type), intent(in) :: EFP1 !< The first extended fixed point number
type(EFP_type), intent(in) :: EFP2 !< The second extended fixed point number

EFP_plus = EFP1

call increment_ints(EFP_plus%v(:), EFP2%v(:))
end function EFP_plus

!> Subract one extended-fixed-point number from another
function EFP_minus(EFP1, EFP2)
type(EFP_type) :: EFP_minus
type(EFP_type), intent(in) :: EFP1, EFP2
type(EFP_type) :: EFP_minus !< The result in extended fixed point format
type(EFP_type), intent(in) :: EFP1 !< The first extended fixed point number
type(EFP_type), intent(in) :: EFP2 !< The extended fixed point number being
!! subtracted from the first extended fixed point number
integer :: i

do i=1,ni ; EFP_minus%v(i) = -1*EFP2%v(i) ; enddo

call increment_ints(EFP_minus%v(:), EFP1%v(:))
end function EFP_minus

!> Copy one extended-fixed-point number into another
subroutine EFP_assign(EFP1, EFP2)
type(EFP_type), intent(out) :: EFP1
type(EFP_type), intent(in) :: EFP2
type(EFP_type), intent(out) :: EFP1 !< The recipient extended fixed point number
type(EFP_type), intent(in) :: EFP2 !< The source extended fixed point number
integer i
! This subroutine assigns all components of the extended fixed point type
! variable on the RHS (EFP2) to the components of the variable on the LHS
Expand All @@ -560,17 +624,22 @@ subroutine EFP_assign(EFP1, EFP2)
do i=1,ni ; EFP1%v(i) = EFP2%v(i) ; enddo
end subroutine EFP_assign

!> Return the real number that an extended-fixed-point number corresponds with
function EFP_to_real(EFP1)
type(EFP_type), intent(inout) :: EFP1
type(EFP_type), intent(inout) :: EFP1 !< The extended fixed point number being converted
real :: EFP_to_real

call regularize_ints(EFP1%v)
EFP_to_real = ints_to_real(EFP1%v)
end function EFP_to_real

!> Take the difference between two extended-fixed-point numbers (EFP1 - EFP2)
!! and return the result as a real number
function EFP_real_diff(EFP1, EFP2)
type(EFP_type), intent(in) :: EFP1, EFP2
real :: EFP_real_diff
type(EFP_type), intent(in) :: EFP1 !< The first extended fixed point number
type(EFP_type), intent(in) :: EFP2 !< The extended fixed point number being
!! subtracted from the first extended fixed point number
real :: EFP_real_diff !< The real result

type(EFP_type) :: EFP_diff

Expand All @@ -579,9 +648,11 @@ function EFP_real_diff(EFP1, EFP2)

end function EFP_real_diff

!> Return the extended-fixed-point number that a real number corresponds with
function real_to_EFP(val, overflow)
real, intent(in) :: val
logical, optional, intent(inout) :: overflow
real, intent(in) :: val !< The real number being converted
logical, optional, intent(inout) :: overflow !< Returns true if the conversion is being
!! done on a value that is too large to be represented
type(EFP_type) :: real_to_EFP

logical :: over
Expand All @@ -600,10 +671,15 @@ function real_to_EFP(val, overflow)

end function real_to_EFP

!< This subroutine does a sum across PEs of a list of EFP variables,
!! returning the sums in place, with all overflows carried.
subroutine EFP_list_sum_across_PEs(EFPs, nval, errors)
type(EFP_type), dimension(:), intent(inout) :: EFPs
integer, intent(in) :: nval
logical, dimension(:), optional, intent(out) :: errors
type(EFP_type), dimension(:), &
intent(inout) :: EFPs !< The list of extended fixed point numbers
!! being summed across PEs.
integer, intent(in) :: nval !< The number of values being summed.
logical, dimension(:), &
optional, intent(out) :: errors !< A list of error flags for each sum

! This subroutine does a sum across PEs of a list of EFP variables,
! returning the sums in place, with all overflows carried.
Expand Down Expand Up @@ -645,6 +721,8 @@ subroutine EFP_list_sum_across_PEs(EFPs, nval, errors)

end subroutine EFP_list_sum_across_PEs

!< This subroutine carries out all of the calls required to close out the infrastructure cleanly.
!! This should only be called in ocean-only runs, as the coupler takes care of this in coupled runs.
subroutine MOM_infra_end
! This subroutine should contain all of the calls that are required
! to close out the infrastructure cleanly. This should only be called
Expand Down

0 comments on commit 5490e5a

Please sign in to comment.