LCOV - code coverage report
Current view: top level - src/common - kahan_sum.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:123285f) Lines: 15.6 % 687 107
Test Date: 2026-11-04 00:58:17 Functions: 25.7 % 35 9

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief sums arrays of real/complex numbers with *much* reduced round-off as compared to
      10              : !>      a naive implementation (or the one found in most compiler's SUM intrinsic)
      11              : !>      using an implementation of Kahan's algorithm for summing real numbers
      12              : !>      that can be used instead of the standard Fortran SUM(array[,mask]).
      13              : !>
      14              : !>      see also http://en.wikipedia.org/wiki/Kahan_summation_algorithm
      15              : !> \note
      16              : !>      if the compiler optimises away the 'tricky' bit, no accuracy is gained,
      17              : !>      if the compiler uses extended precision inconsistently even worse results might be obtained.
      18              : !>      This has not been observed.
      19              : !>      This algorithm is not fast, and thus not recommended for cases where round-off is not a
      20              : !>      concern but performance is.
      21              : !>
      22              : !>      the standard intrinsic sum can be 'replaced' using the following use statement
      23              : !>
      24              : !>      USE kahan_sum, ONLY: sum => kahan_sum
      25              : !> \par History
      26              : !>      03.2006 [Joost VandeVondele]
      27              : !> \author Joost VandeVondele
      28              : ! **************************************************************************************************
      29              : MODULE kahan_sum
      30              : 
      31              :    IMPLICIT NONE
      32              :    PRIVATE
      33              :    PUBLIC :: accurate_dot_product, accurate_sum, accurate_dot_product_2
      34              :    INTEGER, PARAMETER :: sp = KIND(0.0), dp = KIND(0.0D0)
      35              :    REAL(KIND=sp), PARAMETER :: szero = 0.0_sp
      36              :    REAL(KIND=dp), PARAMETER :: dzero = 0.0_dp
      37              :    COMPLEX(KIND=sp), PARAMETER :: czero = (0.0_sp, 0.0_sp)
      38              :    COMPLEX(KIND=dp), PARAMETER :: zzero = (0.0_dp, 0.0_dp)
      39              :    INTEGER, PARAMETER :: dblksize = 8
      40              : 
      41              :    INTERFACE accurate_sum
      42              :       MODULE PROCEDURE &
      43              :          kahan_sum_s1, kahan_sum_d1, kahan_sum_c1, kahan_sum_z1, &
      44              :          kahan_sum_s2, kahan_sum_d2, kahan_sum_c2, kahan_sum_z2, &
      45              :          kahan_sum_s3, kahan_sum_d3, kahan_sum_c3, kahan_sum_z3, &
      46              :          kahan_sum_s4, kahan_sum_d4, kahan_sum_c4, kahan_sum_z4, &
      47              :          kahan_sum_s5, kahan_sum_d5, kahan_sum_c5, kahan_sum_z5, &
      48              :          kahan_sum_s6, kahan_sum_d6, kahan_sum_c6, kahan_sum_z6, &
      49              :          kahan_sum_s7, kahan_sum_d7, kahan_sum_c7, kahan_sum_z7
      50              :    END INTERFACE accurate_sum
      51              : 
      52              :    INTERFACE accurate_dot_product
      53              :       MODULE PROCEDURE &
      54              :          kahan_dot_product_d1, &
      55              :          kahan_dot_product_s2, kahan_dot_product_d2, kahan_dot_product_z2, &
      56              :          kahan_dot_product_d3, kahan_dot_product_masked_d3
      57              :    END INTERFACE accurate_dot_product
      58              : 
      59              :    INTERFACE accurate_dot_product_2
      60              :       MODULE PROCEDURE kahan_blocked_dot_product_d1
      61              :    END INTERFACE
      62              : 
      63              : CONTAINS
      64              : ! **************************************************************************************************
      65              : !> \brief ...
      66              : !> \param array ...
      67              : !> \param mask ...
      68              : !> \return ...
      69              : ! **************************************************************************************************
      70            0 :    PURE FUNCTION kahan_sum_s1(array, mask) RESULT(ks)
      71              :       REAL(KIND=sp), DIMENSION(:), INTENT(IN)            :: array
      72              :       LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL        :: mask
      73              :       REAL(KIND=sp)                                      :: ks
      74              : 
      75              :       INTEGER                                            :: i1
      76              :       REAL(KIND=sp)                                      :: c, t, y
      77              : 
      78            0 :       ks = szero; t = szero; y = szero; c = szero
      79              : 
      80            0 :       IF (PRESENT(mask)) THEN
      81            0 :          DO i1 = 1, SIZE(array, 1)
      82            0 :             IF (mask(i1)) THEN
      83            0 :                y = array(i1) - c
      84            0 :                t = ks + y
      85            0 :                c = (t - ks) - y
      86            0 :                ks = t
      87              :             END IF
      88              :          END DO
      89              :       ELSE
      90            0 :          DO i1 = 1, SIZE(array, 1)
      91            0 :             y = array(i1) - c
      92            0 :             t = ks + y
      93            0 :             c = (t - ks) - y
      94            0 :             ks = t
      95              :          END DO
      96              :       END IF
      97            0 :    END FUNCTION kahan_sum_s1
      98              : 
      99              : ! **************************************************************************************************
     100              : !> \brief ...
     101              : !> \param array ...
     102              : !> \param mask ...
     103              : !> \return ...
     104              : ! **************************************************************************************************
     105      3458454 :    PURE FUNCTION kahan_sum_d1(array, mask) RESULT(ks)
     106              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: array
     107              :       LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL        :: mask
     108              :       REAL(KIND=dp)                                      :: ks
     109              : 
     110              :       INTEGER                                            :: i1
     111              :       REAL(KIND=dp)                                      :: c, t, y
     112              : 
     113      3458454 :       ks = dzero; t = dzero; y = dzero; c = dzero
     114              : 
     115      3458454 :       IF (PRESENT(mask)) THEN
     116            0 :          DO i1 = 1, SIZE(array, 1)
     117            0 :             IF (mask(i1)) THEN
     118            0 :                y = array(i1) - c
     119            0 :                t = ks + y
     120            0 :                c = (t - ks) - y
     121            0 :                ks = t
     122              :             END IF
     123              :          END DO
     124              :       ELSE
     125  12488346985 :          DO i1 = 1, SIZE(array, 1)
     126  12484888531 :             y = array(i1) - c
     127  12484888531 :             t = ks + y
     128  12484888531 :             c = (t - ks) - y
     129  12488346985 :             ks = t
     130              :          END DO
     131              :       END IF
     132      3458454 :    END FUNCTION kahan_sum_d1
     133              : 
     134              : ! **************************************************************************************************
     135              : !> \brief computes the accurate sum of an array that is the element wise product of two input arrays.
     136              : !> \param array1 array of real numbers
     137              : !> \param array2 another array of real numbers
     138              : !> \return dot product
     139              : ! **************************************************************************************************
     140        25426 :    PURE FUNCTION kahan_dot_product_d1(array1, array2) RESULT(ks)
     141              :       REAL(KIND=dp), DIMENSION(:), INTENT(in)            :: array1, array2
     142              :       REAL(KIND=dp)                                      :: ks
     143              : 
     144              :       INTEGER                                            :: i, n
     145              :       REAL(KIND=dp), DIMENSION(dblksize)                 :: c, ks_local, t, y
     146              : 
     147        25426 :       t = dzero; y = dzero; c = dzero; ks_local = dzero
     148              : 
     149        25426 :       n = SIZE(array1)
     150       101702 :       DO i = 1, MOD(n, dblksize)
     151        76276 :          y(1) = array1(i)*array2(i) - c(1)
     152        76276 :          t(1) = ks_local(1) + y(1)
     153        76276 :          c(1) = (t(1) - ks_local(1)) - y(1)
     154       101702 :          ks_local(1) = t(1)
     155              :       END DO
     156        25426 :       DO i = MOD(n, dblksize) + 1, n, dblksize
     157      4896234 :          y = array1(i:i + (dblksize - 1))*array2(i:i + (dblksize - 1)) - c
     158      4896234 :          t = ks_local + y
     159      4896234 :          c = (t - ks_local) - y
     160       544026 :          ks_local = t
     161              :       END DO
     162       203408 :       DO i = 2, dblksize
     163       177982 :          y(1) = ks_local(i) - (c(1) + c(i))
     164       177982 :          t(1) = ks_local(1) + y(1)
     165       177982 :          c(1) = (t(1) - ks_local(1)) - y(1)
     166       203408 :          ks_local(1) = t(1)
     167              :       END DO
     168        25426 :       ks = ks_local(1)
     169        25426 :    END FUNCTION kahan_dot_product_d1
     170              : 
     171              : ! **************************************************************************************************
     172              : !> \brief ...
     173              : !> \param array ...
     174              : !> \param mask ...
     175              : !> \return ...
     176              : ! **************************************************************************************************
     177            0 :    PURE FUNCTION kahan_sum_c1(array, mask) RESULT(ks)
     178              :       COMPLEX(KIND=sp), DIMENSION(:), INTENT(IN)         :: array
     179              :       LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL        :: mask
     180              :       COMPLEX(KIND=sp)                                   :: ks
     181              : 
     182              :       COMPLEX(KIND=sp)                                   :: c, t, y
     183              :       INTEGER                                            :: i1
     184              : 
     185            0 :       ks = czero; t = czero; y = czero; c = czero
     186              : 
     187            0 :       IF (PRESENT(mask)) THEN
     188            0 :          DO i1 = 1, SIZE(array, 1)
     189            0 :             IF (mask(i1)) THEN
     190            0 :                y = array(i1) - c
     191            0 :                t = ks + y
     192            0 :                c = (t - ks) - y
     193            0 :                ks = t
     194              :             END IF
     195              :          END DO
     196              :       ELSE
     197            0 :          DO i1 = 1, SIZE(array, 1)
     198            0 :             y = array(i1) - c
     199            0 :             t = ks + y
     200            0 :             c = (t - ks) - y
     201            0 :             ks = t
     202              :          END DO
     203              :       END IF
     204            0 :    END FUNCTION kahan_sum_c1
     205              : 
     206              : ! **************************************************************************************************
     207              : !> \brief ...
     208              : !> \param array ...
     209              : !> \param mask ...
     210              : !> \return ...
     211              : ! **************************************************************************************************
     212            0 :    PURE FUNCTION kahan_sum_z1(array, mask) RESULT(ks)
     213              :       COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN)         :: array
     214              :       LOGICAL, DIMENSION(:), INTENT(IN), OPTIONAL        :: mask
     215              :       COMPLEX(KIND=dp)                                   :: ks
     216              : 
     217              :       COMPLEX(KIND=dp)                                   :: c, t, y
     218              :       INTEGER                                            :: i1
     219              : 
     220            0 :       ks = zzero; t = zzero; y = zzero; c = zzero
     221              : 
     222            0 :       IF (PRESENT(mask)) THEN
     223            0 :          DO i1 = 1, SIZE(array, 1)
     224            0 :             IF (mask(i1)) THEN
     225            0 :                y = array(i1) - c
     226            0 :                t = ks + y
     227            0 :                c = (t - ks) - y
     228            0 :                ks = t
     229              :             END IF
     230              :          END DO
     231              :       ELSE
     232            0 :          DO i1 = 1, SIZE(array, 1)
     233            0 :             y = array(i1) - c
     234            0 :             t = ks + y
     235            0 :             c = (t - ks) - y
     236            0 :             ks = t
     237              :          END DO
     238              :       END IF
     239            0 :    END FUNCTION kahan_sum_z1
     240              : 
     241              : ! **************************************************************************************************
     242              : !> \brief ...
     243              : !> \param array ...
     244              : !> \param mask ...
     245              : !> \return ...
     246              : ! **************************************************************************************************
     247            0 :    PURE FUNCTION kahan_sum_s2(array, mask) RESULT(ks)
     248              :       REAL(KIND=sp), DIMENSION(:, :), INTENT(IN)         :: array
     249              :       LOGICAL, DIMENSION(:, :), INTENT(IN), OPTIONAL     :: mask
     250              :       REAL(KIND=sp)                                      :: ks
     251              : 
     252              :       INTEGER                                            :: i1, i2
     253              :       REAL(KIND=sp)                                      :: c, t, y
     254              : 
     255            0 :       ks = szero; t = szero; y = szero; c = szero
     256              : 
     257            0 :       IF (PRESENT(mask)) THEN
     258            0 :          DO i2 = 1, SIZE(array, 2)
     259            0 :          DO i1 = 1, SIZE(array, 1)
     260            0 :             IF (mask(i1, i2)) THEN
     261            0 :                y = array(i1, i2) - c
     262            0 :                t = ks + y
     263            0 :                c = (t - ks) - y
     264            0 :                ks = t
     265              :             END IF
     266              :          END DO
     267              :          END DO
     268              :       ELSE
     269            0 :          DO i2 = 1, SIZE(array, 2)
     270            0 :          DO i1 = 1, SIZE(array, 1)
     271            0 :             y = array(i1, i2) - c
     272            0 :             t = ks + y
     273            0 :             c = (t - ks) - y
     274            0 :             ks = t
     275              :          END DO
     276              :          END DO
     277              :       END IF
     278            0 :    END FUNCTION kahan_sum_s2
     279              : 
     280              : ! **************************************************************************************************
     281              : !> \brief computes the accurate sum of an array that is the element wise product of two input arrays.
     282              : !> \param array1 2-D array of real numbers
     283              : !> \param array2 another 2-D array of real numbers
     284              : !> \return dot product
     285              : ! **************************************************************************************************
     286            0 :    PURE FUNCTION kahan_dot_product_s2(array1, array2) RESULT(ks)
     287              :       REAL(KIND=sp), DIMENSION(:, :), INTENT(in)         :: array1, array2
     288              :       REAL(KIND=dp)                                      :: ks
     289              : 
     290              :       INTEGER                                            :: i1, i2, n1, n2
     291              :       REAL(KIND=dp)                                      :: c, t, y
     292              : 
     293            0 :       ks = dzero; t = dzero; y = dzero; c = dzero
     294              : 
     295            0 :       n1 = SIZE(array1, 1)
     296            0 :       n2 = SIZE(array1, 2)
     297            0 :       DO i2 = 1, n2
     298            0 :          DO i1 = 1, n1
     299            0 :             y = REAL(array1(i1, i2), dp)*REAL(array2(i1, i2), dp) - c
     300            0 :             t = ks + y
     301            0 :             c = (t - ks) - y
     302            0 :             ks = t
     303              :          END DO
     304              :       END DO
     305            0 :    END FUNCTION kahan_dot_product_s2
     306              : 
     307              : ! **************************************************************************************************
     308              : !> \brief ...
     309              : !> \param array ...
     310              : !> \param mask ...
     311              : !> \return ...
     312              : ! **************************************************************************************************
     313        20874 :    PURE FUNCTION kahan_sum_d2(array, mask) RESULT(ks)
     314              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: array
     315              :       LOGICAL, DIMENSION(:, :), INTENT(IN), OPTIONAL     :: mask
     316              :       REAL(KIND=dp)                                      :: ks
     317              : 
     318              :       INTEGER                                            :: i1, i2
     319              :       REAL(KIND=dp)                                      :: c, t, y
     320              : 
     321        20874 :       ks = dzero; t = dzero; y = dzero; c = dzero
     322              : 
     323        20874 :       IF (PRESENT(mask)) THEN
     324            0 :          DO i2 = 1, SIZE(array, 2)
     325            0 :          DO i1 = 1, SIZE(array, 1)
     326            0 :             IF (mask(i1, i2)) THEN
     327            0 :                y = array(i1, i2) - c
     328            0 :                t = ks + y
     329            0 :                c = (t - ks) - y
     330            0 :                ks = t
     331              :             END IF
     332              :          END DO
     333              :          END DO
     334              :       ELSE
     335      1311306 :          DO i2 = 1, SIZE(array, 2)
     336     44934346 :          DO i1 = 1, SIZE(array, 1)
     337     43623040 :             y = array(i1, i2) - c
     338     43623040 :             t = ks + y
     339     43623040 :             c = (t - ks) - y
     340     44913472 :             ks = t
     341              :          END DO
     342              :          END DO
     343              :       END IF
     344        20874 :    END FUNCTION kahan_sum_d2
     345              : 
     346              : ! **************************************************************************************************
     347              : !> \brief computes the accurate sum of an array that is the element wise product of two input arrays.
     348              : !> \param array1 2-D array of real numbers
     349              : !> \param array2 another 2-D array of real numbers
     350              : !> \return dot product
     351              : ! **************************************************************************************************
     352       627200 :    PURE FUNCTION kahan_dot_product_d2(array1, array2) RESULT(ks)
     353              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(in)         :: array1, array2
     354              :       REAL(KIND=dp)                                      :: ks
     355              : 
     356              :       INTEGER                                            :: i1, i2, n1, n2
     357              :       REAL(KIND=dp)                                      :: c, t, y
     358              : 
     359       627200 :       ks = dzero; t = dzero; y = dzero; c = dzero
     360              : 
     361       627200 :       n1 = SIZE(array1, 1)
     362       627200 :       n2 = SIZE(array1, 2)
     363      8602514 :       DO i2 = 1, n2
     364    205395574 :          DO i1 = 1, n1
     365    196793060 :             y = array1(i1, i2)*array2(i1, i2) - c
     366    196793060 :             t = ks + y
     367    196793060 :             c = (t - ks) - y
     368    204768374 :             ks = t
     369              :          END DO
     370              :       END DO
     371       627200 :    END FUNCTION kahan_dot_product_d2
     372              : 
     373              : ! **************************************************************************************************
     374              : !> \brief ...
     375              : !> \param array ...
     376              : !> \param mask ...
     377              : !> \return ...
     378              : ! **************************************************************************************************
     379            0 :    PURE FUNCTION kahan_sum_c2(array, mask) RESULT(ks)
     380              :       COMPLEX(KIND=sp), DIMENSION(:, :), INTENT(IN)      :: array
     381              :       LOGICAL, DIMENSION(:, :), INTENT(IN), OPTIONAL     :: mask
     382              :       COMPLEX(KIND=sp)                                   :: ks
     383              : 
     384              :       COMPLEX(KIND=sp)                                   :: c, t, y
     385              :       INTEGER                                            :: i1, i2
     386              : 
     387            0 :       ks = czero; t = czero; y = czero; c = czero
     388              : 
     389            0 :       IF (PRESENT(mask)) THEN
     390            0 :          DO i2 = 1, SIZE(array, 2)
     391            0 :          DO i1 = 1, SIZE(array, 1)
     392            0 :             IF (mask(i1, i2)) THEN
     393            0 :                y = array(i1, i2) - c
     394            0 :                t = ks + y
     395            0 :                c = (t - ks) - y
     396            0 :                ks = t
     397              :             END IF
     398              :          END DO
     399              :          END DO
     400              :       ELSE
     401            0 :          DO i2 = 1, SIZE(array, 2)
     402            0 :          DO i1 = 1, SIZE(array, 1)
     403            0 :             y = array(i1, i2) - c
     404            0 :             t = ks + y
     405            0 :             c = (t - ks) - y
     406            0 :             ks = t
     407              :          END DO
     408              :          END DO
     409              :       END IF
     410            0 :    END FUNCTION kahan_sum_c2
     411              : 
     412              : ! **************************************************************************************************
     413              : !> \brief ...
     414              : !> \param array ...
     415              : !> \param mask ...
     416              : !> \return ...
     417              : ! **************************************************************************************************
     418            0 :    PURE FUNCTION kahan_sum_z2(array, mask) RESULT(ks)
     419              :       COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(IN)      :: array
     420              :       LOGICAL, DIMENSION(:, :), INTENT(IN), OPTIONAL     :: mask
     421              :       COMPLEX(KIND=dp)                                   :: ks
     422              : 
     423              :       COMPLEX(KIND=dp)                                   :: c, t, y
     424              :       INTEGER                                            :: i1, i2
     425              : 
     426            0 :       ks = zzero; t = zzero; y = zzero; c = zzero
     427              : 
     428            0 :       IF (PRESENT(mask)) THEN
     429            0 :          DO i2 = 1, SIZE(array, 2)
     430            0 :          DO i1 = 1, SIZE(array, 1)
     431            0 :             IF (mask(i1, i2)) THEN
     432            0 :                y = array(i1, i2) - c
     433            0 :                t = ks + y
     434            0 :                c = (t - ks) - y
     435            0 :                ks = t
     436              :             END IF
     437              :          END DO
     438              :          END DO
     439              :       ELSE
     440            0 :          DO i2 = 1, SIZE(array, 2)
     441            0 :          DO i1 = 1, SIZE(array, 1)
     442            0 :             y = array(i1, i2) - c
     443            0 :             t = ks + y
     444            0 :             c = (t - ks) - y
     445            0 :             ks = t
     446              :          END DO
     447              :          END DO
     448              :       END IF
     449            0 :    END FUNCTION kahan_sum_z2
     450              : 
     451              : ! **************************************************************************************************
     452              : !> \brief computes the accurate sum of an array that is the element wise product of two input arrays.
     453              : !> \param array1 2-D array of complex numbers
     454              : !> \param array2 another 2-D array of complex numbers
     455              : !> \param conjugate_a conjugate the first array before multiplication (default: false)
     456              : !> \return dot product
     457              : ! **************************************************************************************************
     458       167358 :    PURE FUNCTION kahan_dot_product_z2(array1, array2, conjugate_a) RESULT(ks)
     459              :       COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(in)      :: array1, array2
     460              :       LOGICAL, INTENT(IN), OPTIONAL                      :: conjugate_a
     461              :       COMPLEX(KIND=dp)                                   :: ks
     462              : 
     463              :       COMPLEX(KIND=dp)                                   :: c, t, value, y
     464              :       INTEGER                                            :: i1, i2, n1, n2
     465              :       LOGICAL                                            :: conjugate
     466              : 
     467       167358 :       ks = zzero; t = zzero; y = zzero; c = zzero
     468       167358 :       conjugate = .FALSE.
     469       167358 :       IF (PRESENT(conjugate_a)) conjugate = conjugate_a
     470              : 
     471       167358 :       n1 = SIZE(array1, 1)
     472       167358 :       n2 = SIZE(array1, 2)
     473      4010090 :       DO i2 = 1, n2
     474    160948476 :          DO i1 = 1, n1
     475    156938386 :             value = array1(i1, i2)
     476    156938386 :             IF (conjugate) value = CONJG(value)
     477    156938386 :             y = value*array2(i1, i2) - c
     478    156938386 :             t = ks + y
     479    156938386 :             c = (t - ks) - y
     480    160781118 :             ks = t
     481              :          END DO
     482              :       END DO
     483       167358 :    END FUNCTION kahan_dot_product_z2
     484              : 
     485              : ! **************************************************************************************************
     486              : !> \brief ...
     487              : !> \param array ...
     488              : !> \param mask ...
     489              : !> \return ...
     490              : ! **************************************************************************************************
     491            0 :    PURE FUNCTION kahan_sum_s3(array, mask) RESULT(ks)
     492              :       REAL(KIND=sp), DIMENSION(:, :, :), INTENT(IN)      :: array
     493              :       LOGICAL, DIMENSION(:, :, :), INTENT(IN), OPTIONAL  :: mask
     494              :       REAL(KIND=sp)                                      :: ks
     495              : 
     496              :       INTEGER                                            :: i1, i2, i3
     497              :       REAL(KIND=sp)                                      :: c, t, y
     498              : 
     499            0 :       ks = szero; t = szero; y = szero; c = szero
     500              : 
     501            0 :       IF (PRESENT(mask)) THEN
     502            0 :          DO i3 = 1, SIZE(array, 3)
     503            0 :          DO i2 = 1, SIZE(array, 2)
     504            0 :          DO i1 = 1, SIZE(array, 1)
     505            0 :             IF (mask(i1, i2, i3)) THEN
     506            0 :                y = array(i1, i2, i3) - c
     507            0 :                t = ks + y
     508            0 :                c = (t - ks) - y
     509            0 :                ks = t
     510              :             END IF
     511              :          END DO
     512              :          END DO
     513              :          END DO
     514              :       ELSE
     515            0 :          DO i3 = 1, SIZE(array, 3)
     516            0 :          DO i2 = 1, SIZE(array, 2)
     517            0 :          DO i1 = 1, SIZE(array, 1)
     518            0 :             y = array(i1, i2, i3) - c
     519            0 :             t = ks + y
     520            0 :             c = (t - ks) - y
     521            0 :             ks = t
     522              :          END DO
     523              :          END DO
     524              :          END DO
     525              :       END IF
     526            0 :    END FUNCTION kahan_sum_s3
     527              : 
     528              : ! **************************************************************************************************
     529              : !> \brief ...
     530              : !> \param array ...
     531              : !> \param mask ...
     532              : !> \return ...
     533              : ! **************************************************************************************************
     534       489673 :    PURE FUNCTION kahan_sum_d3(array, mask) RESULT(ks)
     535              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: array
     536              :       LOGICAL, DIMENSION(:, :, :), INTENT(IN), OPTIONAL  :: mask
     537              :       REAL(KIND=dp)                                      :: ks
     538              : 
     539              :       INTEGER                                            :: i1, i2, i3
     540              :       REAL(KIND=dp)                                      :: c, t, y
     541              : 
     542       489673 :       ks = dzero; t = dzero; y = dzero; c = dzero
     543              : 
     544       489673 :       IF (PRESENT(mask)) THEN
     545            0 :          DO i3 = 1, SIZE(array, 3)
     546            0 :          DO i2 = 1, SIZE(array, 2)
     547            0 :          DO i1 = 1, SIZE(array, 1)
     548            0 :             IF (mask(i1, i2, i3)) THEN
     549            0 :                y = array(i1, i2, i3) - c
     550            0 :                t = ks + y
     551            0 :                c = (t - ks) - y
     552            0 :                ks = t
     553              :             END IF
     554              :          END DO
     555              :          END DO
     556              :          END DO
     557              :       ELSE
     558     22794156 :          DO i3 = 1, SIZE(array, 3)
     559   1102783473 :          DO i2 = 1, SIZE(array, 2)
     560  30617283594 :          DO i1 = 1, SIZE(array, 1)
     561  29514989794 :             y = array(i1, i2, i3) - c
     562  29514989794 :             t = ks + y
     563  29514989794 :             c = (t - ks) - y
     564  30594979111 :             ks = t
     565              :          END DO
     566              :          END DO
     567              :          END DO
     568              :       END IF
     569       489673 :    END FUNCTION kahan_sum_d3
     570              : 
     571              : ! **************************************************************************************************
     572              : !> \brief computes the accurate sum of an array that is the element wise product of two input arrays.
     573              : !> \param array1 3-D array of real numbers
     574              : !> \param array2 another 3-D array of real numbers
     575              : !> \return dot product
     576              : ! **************************************************************************************************
     577       554306 :    PURE FUNCTION kahan_dot_product_d3(array1, array2) RESULT(ks)
     578              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(in)      :: array1, array2
     579              :       REAL(KIND=dp)                                      :: ks
     580              : 
     581              :       INTEGER                                            :: i1, i2, i3, n1, n2, n3
     582              :       REAL(KIND=dp)                                      :: c, t, y
     583              : 
     584       554306 :       ks = dzero; t = dzero; y = dzero; c = dzero
     585              : 
     586       554306 :       n1 = SIZE(array1, 1)
     587       554306 :       n2 = SIZE(array1, 2)
     588       554306 :       n3 = SIZE(array1, 3)
     589      6829404 :       DO i3 = 1, n3
     590    182410360 :          DO i2 = 1, n2
     591   4849012514 :             DO i1 = 1, n1
     592   4667156460 :                y = array1(i1, i2, i3)*array2(i1, i2, i3) - c
     593   4667156460 :                t = ks + y
     594   4667156460 :                c = (t - ks) - y
     595   4842737416 :                ks = t
     596              :             END DO
     597              :          END DO
     598              :       END DO
     599       554306 :    END FUNCTION kahan_dot_product_d3
     600              : 
     601              : ! **************************************************************************************************
     602              : !> \brief computes the accurate sum of an array that is the element wise product of two input arrays.
     603              : !>        a mask array determines which product array points to include in the sum
     604              : !> \param array1 the first input array to compute the product array
     605              : !> \param array2 the second input array to compute the product array
     606              : !> \param mask the mask array
     607              : !> \param th screening threshold: only array points where the value of mask is greater than th are
     608              : !>           included in the sum
     609              : !> \return the result of summation
     610              : ! **************************************************************************************************
     611          180 :    PURE FUNCTION kahan_dot_product_masked_d3(array1, array2, mask, th) RESULT(ks)
     612              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN), &
     613              :          POINTER                                         :: array1, array2, mask
     614              :       REAL(KIND=dp), INTENT(in)                          :: th
     615              :       REAL(KIND=dp)                                      :: ks
     616              : 
     617              :       INTEGER                                            :: i1, i2, i3
     618              :       REAL(KIND=dp)                                      :: c, t, y
     619              : 
     620          180 :       ks = dzero; t = dzero; y = dzero; c = dzero
     621         8636 :       DO i3 = LBOUND(mask, 3), UBOUND(mask, 3)
     622       431252 :       DO i2 = LBOUND(mask, 2), UBOUND(mask, 2)
     623     22808224 :       DO i1 = LBOUND(mask, 1), UBOUND(mask, 1)
     624     21986560 :          IF (mask(i1, i2, i3) > th) THEN
     625      7234016 :             y = array1(i1, i2, i3)*array2(i1, i2, i3) - c
     626      7234016 :             t = ks + y
     627      7234016 :             c = (t - ks) - y
     628      7234016 :             ks = t
     629              :          END IF
     630              :       END DO
     631              :       END DO
     632              :       END DO
     633          180 :    END FUNCTION kahan_dot_product_masked_d3
     634              : 
     635              : ! **************************************************************************************************
     636              : !> \brief ...
     637              : !> \param array ...
     638              : !> \param mask ...
     639              : !> \return ...
     640              : ! **************************************************************************************************
     641            0 :    PURE FUNCTION kahan_sum_c3(array, mask) RESULT(ks)
     642              :       COMPLEX(KIND=sp), DIMENSION(:, :, :), INTENT(IN)   :: array
     643              :       LOGICAL, DIMENSION(:, :, :), INTENT(IN), OPTIONAL  :: mask
     644              :       COMPLEX(KIND=sp)                                   :: ks
     645              : 
     646              :       COMPLEX(KIND=sp)                                   :: c, t, y
     647              :       INTEGER                                            :: i1, i2, i3
     648              : 
     649            0 :       ks = czero; t = czero; y = czero; c = czero
     650              : 
     651            0 :       IF (PRESENT(mask)) THEN
     652            0 :          DO i3 = 1, SIZE(array, 3)
     653            0 :          DO i2 = 1, SIZE(array, 2)
     654            0 :          DO i1 = 1, SIZE(array, 1)
     655            0 :             IF (mask(i1, i2, i3)) THEN
     656            0 :                y = array(i1, i2, i3) - c
     657            0 :                t = ks + y
     658            0 :                c = (t - ks) - y
     659            0 :                ks = t
     660              :             END IF
     661              :          END DO
     662              :          END DO
     663              :          END DO
     664              :       ELSE
     665            0 :          DO i3 = 1, SIZE(array, 3)
     666            0 :          DO i2 = 1, SIZE(array, 2)
     667            0 :          DO i1 = 1, SIZE(array, 1)
     668            0 :             y = array(i1, i2, i3) - c
     669            0 :             t = ks + y
     670            0 :             c = (t - ks) - y
     671            0 :             ks = t
     672              :          END DO
     673              :          END DO
     674              :          END DO
     675              :       END IF
     676            0 :    END FUNCTION kahan_sum_c3
     677              : 
     678              : ! **************************************************************************************************
     679              : !> \brief ...
     680              : !> \param array ...
     681              : !> \param mask ...
     682              : !> \return ...
     683              : ! **************************************************************************************************
     684            0 :    PURE FUNCTION kahan_sum_z3(array, mask) RESULT(ks)
     685              :       COMPLEX(KIND=dp), DIMENSION(:, :, :), INTENT(IN)   :: array
     686              :       LOGICAL, DIMENSION(:, :, :), INTENT(IN), OPTIONAL  :: mask
     687              :       COMPLEX(KIND=dp)                                   :: ks
     688              : 
     689              :       COMPLEX(KIND=dp)                                   :: c, t, y
     690              :       INTEGER                                            :: i1, i2, i3
     691              : 
     692            0 :       ks = zzero; t = zzero; y = zzero; c = zzero
     693              : 
     694            0 :       IF (PRESENT(mask)) THEN
     695            0 :          DO i3 = 1, SIZE(array, 3)
     696            0 :          DO i2 = 1, SIZE(array, 2)
     697            0 :          DO i1 = 1, SIZE(array, 1)
     698            0 :             IF (mask(i1, i2, i3)) THEN
     699            0 :                y = array(i1, i2, i3) - c
     700            0 :                t = ks + y
     701            0 :                c = (t - ks) - y
     702            0 :                ks = t
     703              :             END IF
     704              :          END DO
     705              :          END DO
     706              :          END DO
     707              :       ELSE
     708            0 :          DO i3 = 1, SIZE(array, 3)
     709            0 :          DO i2 = 1, SIZE(array, 2)
     710            0 :          DO i1 = 1, SIZE(array, 1)
     711            0 :             y = array(i1, i2, i3) - c
     712            0 :             t = ks + y
     713            0 :             c = (t - ks) - y
     714            0 :             ks = t
     715              :          END DO
     716              :          END DO
     717              :          END DO
     718              :       END IF
     719            0 :    END FUNCTION kahan_sum_z3
     720              : 
     721              : ! **************************************************************************************************
     722              : !> \brief ...
     723              : !> \param array ...
     724              : !> \param mask ...
     725              : !> \return ...
     726              : ! **************************************************************************************************
     727            0 :    PURE FUNCTION kahan_sum_s4(array, mask) RESULT(ks)
     728              :       REAL(KIND=sp), DIMENSION(:, :, :, :), INTENT(IN)   :: array
     729              :       LOGICAL, DIMENSION(:, :, :, :), INTENT(IN), &
     730              :          OPTIONAL                                        :: mask
     731              :       REAL(KIND=sp)                                      :: ks
     732              : 
     733              :       INTEGER                                            :: i1, i2, i3, i4
     734              :       REAL(KIND=sp)                                      :: c, t, y
     735              : 
     736            0 :       ks = szero; t = szero; y = szero; c = szero
     737              : 
     738            0 :       IF (PRESENT(mask)) THEN
     739            0 :          DO i4 = 1, SIZE(array, 4)
     740            0 :          DO i3 = 1, SIZE(array, 3)
     741            0 :          DO i2 = 1, SIZE(array, 2)
     742            0 :          DO i1 = 1, SIZE(array, 1)
     743            0 :             IF (mask(i1, i2, i3, i4)) THEN
     744            0 :                y = array(i1, i2, i3, i4) - c
     745            0 :                t = ks + y
     746            0 :                c = (t - ks) - y
     747            0 :                ks = t
     748              :             END IF
     749              :          END DO
     750              :          END DO
     751              :          END DO
     752              :          END DO
     753              :       ELSE
     754            0 :          DO i4 = 1, SIZE(array, 4)
     755            0 :          DO i3 = 1, SIZE(array, 3)
     756            0 :          DO i2 = 1, SIZE(array, 2)
     757            0 :          DO i1 = 1, SIZE(array, 1)
     758            0 :             y = array(i1, i2, i3, i4) - c
     759            0 :             t = ks + y
     760            0 :             c = (t - ks) - y
     761            0 :             ks = t
     762              :          END DO
     763              :          END DO
     764              :          END DO
     765              :          END DO
     766              :       END IF
     767            0 :    END FUNCTION kahan_sum_s4
     768              : 
     769              : ! **************************************************************************************************
     770              : !> \brief ...
     771              : !> \param array ...
     772              : !> \param mask ...
     773              : !> \return ...
     774              : ! **************************************************************************************************
     775            0 :    PURE FUNCTION kahan_sum_d4(array, mask) RESULT(ks)
     776              :       REAL(KIND=dp), DIMENSION(:, :, :, :), INTENT(IN)   :: array
     777              :       LOGICAL, DIMENSION(:, :, :, :), INTENT(IN), &
     778              :          OPTIONAL                                        :: mask
     779              :       REAL(KIND=dp)                                      :: ks
     780              : 
     781              :       INTEGER                                            :: i1, i2, i3, i4
     782              :       REAL(KIND=dp)                                      :: c, t, y
     783              : 
     784            0 :       ks = dzero; t = dzero; y = dzero; c = dzero
     785              : 
     786            0 :       IF (PRESENT(mask)) THEN
     787            0 :          DO i4 = 1, SIZE(array, 4)
     788            0 :          DO i3 = 1, SIZE(array, 3)
     789            0 :          DO i2 = 1, SIZE(array, 2)
     790            0 :          DO i1 = 1, SIZE(array, 1)
     791            0 :             IF (mask(i1, i2, i3, i4)) THEN
     792            0 :                y = array(i1, i2, i3, i4) - c
     793            0 :                t = ks + y
     794            0 :                c = (t - ks) - y
     795            0 :                ks = t
     796              :             END IF
     797              :          END DO
     798              :          END DO
     799              :          END DO
     800              :          END DO
     801              :       ELSE
     802            0 :          DO i4 = 1, SIZE(array, 4)
     803            0 :          DO i3 = 1, SIZE(array, 3)
     804            0 :          DO i2 = 1, SIZE(array, 2)
     805            0 :          DO i1 = 1, SIZE(array, 1)
     806            0 :             y = array(i1, i2, i3, i4) - c
     807            0 :             t = ks + y
     808            0 :             c = (t - ks) - y
     809            0 :             ks = t
     810              :          END DO
     811              :          END DO
     812              :          END DO
     813              :          END DO
     814              :       END IF
     815            0 :    END FUNCTION kahan_sum_d4
     816              : 
     817              : ! **************************************************************************************************
     818              : !> \brief ...
     819              : !> \param array ...
     820              : !> \param mask ...
     821              : !> \return ...
     822              : ! **************************************************************************************************
     823            0 :    PURE FUNCTION kahan_sum_c4(array, mask) RESULT(ks)
     824              :       COMPLEX(KIND=sp), DIMENSION(:, :, :, :), &
     825              :          INTENT(IN)                                      :: array
     826              :       LOGICAL, DIMENSION(:, :, :, :), INTENT(IN), &
     827              :          OPTIONAL                                        :: mask
     828              :       COMPLEX(KIND=sp)                                   :: ks
     829              : 
     830              :       COMPLEX(KIND=sp)                                   :: c, t, y
     831              :       INTEGER                                            :: i1, i2, i3, i4
     832              : 
     833            0 :       ks = czero; t = czero; y = czero; c = czero
     834              : 
     835            0 :       IF (PRESENT(mask)) THEN
     836            0 :          DO i4 = 1, SIZE(array, 4)
     837            0 :          DO i3 = 1, SIZE(array, 3)
     838            0 :          DO i2 = 1, SIZE(array, 2)
     839            0 :          DO i1 = 1, SIZE(array, 1)
     840            0 :             IF (mask(i1, i2, i3, i4)) THEN
     841            0 :                y = array(i1, i2, i3, i4) - c
     842            0 :                t = ks + y
     843            0 :                c = (t - ks) - y
     844            0 :                ks = t
     845              :             END IF
     846              :          END DO
     847              :          END DO
     848              :          END DO
     849              :          END DO
     850              :       ELSE
     851            0 :          DO i4 = 1, SIZE(array, 4)
     852            0 :          DO i3 = 1, SIZE(array, 3)
     853            0 :          DO i2 = 1, SIZE(array, 2)
     854            0 :          DO i1 = 1, SIZE(array, 1)
     855            0 :             y = array(i1, i2, i3, i4) - c
     856            0 :             t = ks + y
     857            0 :             c = (t - ks) - y
     858            0 :             ks = t
     859              :          END DO
     860              :          END DO
     861              :          END DO
     862              :          END DO
     863              :       END IF
     864            0 :    END FUNCTION kahan_sum_c4
     865              : 
     866              : ! **************************************************************************************************
     867              : !> \brief ...
     868              : !> \param array ...
     869              : !> \param mask ...
     870              : !> \return ...
     871              : ! **************************************************************************************************
     872            0 :    PURE FUNCTION kahan_sum_z4(array, mask) RESULT(ks)
     873              :       COMPLEX(KIND=dp), DIMENSION(:, :, :, :), &
     874              :          INTENT(IN)                                      :: array
     875              :       LOGICAL, DIMENSION(:, :, :, :), INTENT(IN), &
     876              :          OPTIONAL                                        :: mask
     877              :       COMPLEX(KIND=dp)                                   :: ks
     878              : 
     879              :       COMPLEX(KIND=dp)                                   :: c, t, y
     880              :       INTEGER                                            :: i1, i2, i3, i4
     881              : 
     882            0 :       ks = zzero; t = zzero; y = zzero; c = zzero
     883              : 
     884            0 :       IF (PRESENT(mask)) THEN
     885            0 :          DO i4 = 1, SIZE(array, 4)
     886            0 :          DO i3 = 1, SIZE(array, 3)
     887            0 :          DO i2 = 1, SIZE(array, 2)
     888            0 :          DO i1 = 1, SIZE(array, 1)
     889            0 :             IF (mask(i1, i2, i3, i4)) THEN
     890            0 :                y = array(i1, i2, i3, i4) - c
     891            0 :                t = ks + y
     892            0 :                c = (t - ks) - y
     893            0 :                ks = t
     894              :             END IF
     895              :          END DO
     896              :          END DO
     897              :          END DO
     898              :          END DO
     899              :       ELSE
     900            0 :          DO i4 = 1, SIZE(array, 4)
     901            0 :          DO i3 = 1, SIZE(array, 3)
     902            0 :          DO i2 = 1, SIZE(array, 2)
     903            0 :          DO i1 = 1, SIZE(array, 1)
     904            0 :             y = array(i1, i2, i3, i4) - c
     905            0 :             t = ks + y
     906            0 :             c = (t - ks) - y
     907            0 :             ks = t
     908              :          END DO
     909              :          END DO
     910              :          END DO
     911              :          END DO
     912              :       END IF
     913            0 :    END FUNCTION kahan_sum_z4
     914              : 
     915              : ! **************************************************************************************************
     916              : !> \brief ...
     917              : !> \param array ...
     918              : !> \param mask ...
     919              : !> \return ...
     920              : ! **************************************************************************************************
     921            0 :    PURE FUNCTION kahan_sum_s5(array, mask) RESULT(ks)
     922              :       REAL(KIND=sp), DIMENSION(:, :, :, :, :), &
     923              :          INTENT(IN)                                      :: array
     924              :       LOGICAL, DIMENSION(:, :, :, :, :), INTENT(IN), &
     925              :          OPTIONAL                                        :: mask
     926              :       REAL(KIND=sp)                                      :: ks
     927              : 
     928              :       INTEGER                                            :: i1, i2, i3, i4, i5
     929              :       REAL(KIND=sp)                                      :: c, t, y
     930              : 
     931            0 :       ks = szero; t = szero; y = szero; c = szero
     932              : 
     933            0 :       IF (PRESENT(mask)) THEN
     934            0 :          DO i5 = 1, SIZE(array, 5)
     935            0 :          DO i4 = 1, SIZE(array, 4)
     936            0 :          DO i3 = 1, SIZE(array, 3)
     937            0 :          DO i2 = 1, SIZE(array, 2)
     938            0 :          DO i1 = 1, SIZE(array, 1)
     939            0 :             IF (mask(i1, i2, i3, i4, i5)) THEN
     940            0 :                y = array(i1, i2, i3, i4, i5) - c
     941            0 :                t = ks + y
     942            0 :                c = (t - ks) - y
     943            0 :                ks = t
     944              :             END IF
     945              :          END DO
     946              :          END DO
     947              :          END DO
     948              :          END DO
     949              :          END DO
     950              :       ELSE
     951            0 :          DO i5 = 1, SIZE(array, 5)
     952            0 :          DO i4 = 1, SIZE(array, 4)
     953            0 :          DO i3 = 1, SIZE(array, 3)
     954            0 :          DO i2 = 1, SIZE(array, 2)
     955            0 :          DO i1 = 1, SIZE(array, 1)
     956            0 :             y = array(i1, i2, i3, i4, i5) - c
     957            0 :             t = ks + y
     958            0 :             c = (t - ks) - y
     959            0 :             ks = t
     960              :          END DO
     961              :          END DO
     962              :          END DO
     963              :          END DO
     964              :          END DO
     965              :       END IF
     966            0 :    END FUNCTION kahan_sum_s5
     967              : 
     968              : ! **************************************************************************************************
     969              : !> \brief ...
     970              : !> \param array ...
     971              : !> \param mask ...
     972              : !> \return ...
     973              : ! **************************************************************************************************
     974            0 :    PURE FUNCTION kahan_sum_d5(array, mask) RESULT(ks)
     975              :       REAL(KIND=dp), DIMENSION(:, :, :, :, :), &
     976              :          INTENT(IN)                                      :: array
     977              :       LOGICAL, DIMENSION(:, :, :, :, :), INTENT(IN), &
     978              :          OPTIONAL                                        :: mask
     979              :       REAL(KIND=dp)                                      :: ks
     980              : 
     981              :       INTEGER                                            :: i1, i2, i3, i4, i5
     982              :       REAL(KIND=dp)                                      :: c, t, y
     983              : 
     984            0 :       ks = dzero; t = dzero; y = dzero; c = dzero
     985              : 
     986            0 :       IF (PRESENT(mask)) THEN
     987            0 :          DO i5 = 1, SIZE(array, 5)
     988            0 :          DO i4 = 1, SIZE(array, 4)
     989            0 :          DO i3 = 1, SIZE(array, 3)
     990            0 :          DO i2 = 1, SIZE(array, 2)
     991            0 :          DO i1 = 1, SIZE(array, 1)
     992            0 :             IF (mask(i1, i2, i3, i4, i5)) THEN
     993            0 :                y = array(i1, i2, i3, i4, i5) - c
     994            0 :                t = ks + y
     995            0 :                c = (t - ks) - y
     996            0 :                ks = t
     997              :             END IF
     998              :          END DO
     999              :          END DO
    1000              :          END DO
    1001              :          END DO
    1002              :          END DO
    1003              :       ELSE
    1004            0 :          DO i5 = 1, SIZE(array, 5)
    1005            0 :          DO i4 = 1, SIZE(array, 4)
    1006            0 :          DO i3 = 1, SIZE(array, 3)
    1007            0 :          DO i2 = 1, SIZE(array, 2)
    1008            0 :          DO i1 = 1, SIZE(array, 1)
    1009            0 :             y = array(i1, i2, i3, i4, i5) - c
    1010            0 :             t = ks + y
    1011            0 :             c = (t - ks) - y
    1012            0 :             ks = t
    1013              :          END DO
    1014              :          END DO
    1015              :          END DO
    1016              :          END DO
    1017              :          END DO
    1018              :       END IF
    1019            0 :    END FUNCTION kahan_sum_d5
    1020              : 
    1021              : ! **************************************************************************************************
    1022              : !> \brief ...
    1023              : !> \param array ...
    1024              : !> \param mask ...
    1025              : !> \return ...
    1026              : ! **************************************************************************************************
    1027            0 :    PURE FUNCTION kahan_sum_c5(array, mask) RESULT(ks)
    1028              :       COMPLEX(KIND=sp), DIMENSION(:, :, :, :, :), &
    1029              :          INTENT(IN)                                      :: array
    1030              :       LOGICAL, DIMENSION(:, :, :, :, :), INTENT(IN), &
    1031              :          OPTIONAL                                        :: mask
    1032              :       COMPLEX(KIND=sp)                                   :: ks
    1033              : 
    1034              :       COMPLEX(KIND=sp)                                   :: c, t, y
    1035              :       INTEGER                                            :: i1, i2, i3, i4, i5
    1036              : 
    1037            0 :       ks = czero; t = czero; y = czero; c = czero
    1038              : 
    1039            0 :       IF (PRESENT(mask)) THEN
    1040            0 :          DO i5 = 1, SIZE(array, 5)
    1041            0 :          DO i4 = 1, SIZE(array, 4)
    1042            0 :          DO i3 = 1, SIZE(array, 3)
    1043            0 :          DO i2 = 1, SIZE(array, 2)
    1044            0 :          DO i1 = 1, SIZE(array, 1)
    1045            0 :             IF (mask(i1, i2, i3, i4, i5)) THEN
    1046            0 :                y = array(i1, i2, i3, i4, i5) - c
    1047            0 :                t = ks + y
    1048            0 :                c = (t - ks) - y
    1049            0 :                ks = t
    1050              :             END IF
    1051              :          END DO
    1052              :          END DO
    1053              :          END DO
    1054              :          END DO
    1055              :          END DO
    1056              :       ELSE
    1057            0 :          DO i5 = 1, SIZE(array, 5)
    1058            0 :          DO i4 = 1, SIZE(array, 4)
    1059            0 :          DO i3 = 1, SIZE(array, 3)
    1060            0 :          DO i2 = 1, SIZE(array, 2)
    1061            0 :          DO i1 = 1, SIZE(array, 1)
    1062            0 :             y = array(i1, i2, i3, i4, i5) - c
    1063            0 :             t = ks + y
    1064            0 :             c = (t - ks) - y
    1065            0 :             ks = t
    1066              :          END DO
    1067              :          END DO
    1068              :          END DO
    1069              :          END DO
    1070              :          END DO
    1071              :       END IF
    1072            0 :    END FUNCTION kahan_sum_c5
    1073              : 
    1074              : ! **************************************************************************************************
    1075              : !> \brief ...
    1076              : !> \param array ...
    1077              : !> \param mask ...
    1078              : !> \return ...
    1079              : ! **************************************************************************************************
    1080            0 :    PURE FUNCTION kahan_sum_z5(array, mask) RESULT(ks)
    1081              :       COMPLEX(KIND=dp), DIMENSION(:, :, :, :, :), &
    1082              :          INTENT(IN)                                      :: array
    1083              :       LOGICAL, DIMENSION(:, :, :, :, :), INTENT(IN), &
    1084              :          OPTIONAL                                        :: mask
    1085              :       COMPLEX(KIND=dp)                                   :: ks
    1086              : 
    1087              :       COMPLEX(KIND=dp)                                   :: c, t, y
    1088              :       INTEGER                                            :: i1, i2, i3, i4, i5
    1089              : 
    1090            0 :       ks = zzero; t = zzero; y = zzero; c = zzero
    1091              : 
    1092            0 :       IF (PRESENT(mask)) THEN
    1093            0 :          DO i5 = 1, SIZE(array, 5)
    1094            0 :          DO i4 = 1, SIZE(array, 4)
    1095            0 :          DO i3 = 1, SIZE(array, 3)
    1096            0 :          DO i2 = 1, SIZE(array, 2)
    1097            0 :          DO i1 = 1, SIZE(array, 1)
    1098            0 :             IF (mask(i1, i2, i3, i4, i5)) THEN
    1099            0 :                y = array(i1, i2, i3, i4, i5) - c
    1100            0 :                t = ks + y
    1101            0 :                c = (t - ks) - y
    1102            0 :                ks = t
    1103              :             END IF
    1104              :          END DO
    1105              :          END DO
    1106              :          END DO
    1107              :          END DO
    1108              :          END DO
    1109              :       ELSE
    1110            0 :          DO i5 = 1, SIZE(array, 5)
    1111            0 :          DO i4 = 1, SIZE(array, 4)
    1112            0 :          DO i3 = 1, SIZE(array, 3)
    1113            0 :          DO i2 = 1, SIZE(array, 2)
    1114            0 :          DO i1 = 1, SIZE(array, 1)
    1115            0 :             y = array(i1, i2, i3, i4, i5) - c
    1116            0 :             t = ks + y
    1117            0 :             c = (t - ks) - y
    1118            0 :             ks = t
    1119              :          END DO
    1120              :          END DO
    1121              :          END DO
    1122              :          END DO
    1123              :          END DO
    1124              :       END IF
    1125            0 :    END FUNCTION kahan_sum_z5
    1126              : 
    1127              : ! **************************************************************************************************
    1128              : !> \brief ...
    1129              : !> \param array ...
    1130              : !> \param mask ...
    1131              : !> \return ...
    1132              : ! **************************************************************************************************
    1133            0 :    PURE FUNCTION kahan_sum_s6(array, mask) RESULT(ks)
    1134              :       REAL(KIND=sp), DIMENSION(:, :, :, :, :, :), &
    1135              :          INTENT(IN)                                      :: array
    1136              :       LOGICAL, DIMENSION(:, :, :, :, :, :), INTENT(IN), &
    1137              :          OPTIONAL                                        :: mask
    1138              :       REAL(KIND=sp)                                      :: ks
    1139              : 
    1140              :       INTEGER                                            :: i1, i2, i3, i4, i5, i6
    1141              :       REAL(KIND=sp)                                      :: c, t, y
    1142              : 
    1143            0 :       ks = szero; t = szero; y = szero; c = szero
    1144              : 
    1145            0 :       IF (PRESENT(mask)) THEN
    1146            0 :          DO i6 = 1, SIZE(array, 6)
    1147            0 :          DO i5 = 1, SIZE(array, 5)
    1148            0 :          DO i4 = 1, SIZE(array, 4)
    1149            0 :          DO i3 = 1, SIZE(array, 3)
    1150            0 :          DO i2 = 1, SIZE(array, 2)
    1151            0 :          DO i1 = 1, SIZE(array, 1)
    1152            0 :             IF (mask(i1, i2, i3, i4, i5, i6)) THEN
    1153            0 :                y = array(i1, i2, i3, i4, i5, i6) - c
    1154            0 :                t = ks + y
    1155            0 :                c = (t - ks) - y
    1156            0 :                ks = t
    1157              :             END IF
    1158              :          END DO
    1159              :          END DO
    1160              :          END DO
    1161              :          END DO
    1162              :          END DO
    1163              :          END DO
    1164              :       ELSE
    1165            0 :          DO i6 = 1, SIZE(array, 6)
    1166            0 :          DO i5 = 1, SIZE(array, 5)
    1167            0 :          DO i4 = 1, SIZE(array, 4)
    1168            0 :          DO i3 = 1, SIZE(array, 3)
    1169            0 :          DO i2 = 1, SIZE(array, 2)
    1170            0 :          DO i1 = 1, SIZE(array, 1)
    1171            0 :             y = array(i1, i2, i3, i4, i5, i6) - c
    1172            0 :             t = ks + y
    1173            0 :             c = (t - ks) - y
    1174            0 :             ks = t
    1175              :          END DO
    1176              :          END DO
    1177              :          END DO
    1178              :          END DO
    1179              :          END DO
    1180              :          END DO
    1181              :       END IF
    1182            0 :    END FUNCTION kahan_sum_s6
    1183              : 
    1184              : ! **************************************************************************************************
    1185              : !> \brief ...
    1186              : !> \param array ...
    1187              : !> \param mask ...
    1188              : !> \return ...
    1189              : ! **************************************************************************************************
    1190            0 :    PURE FUNCTION kahan_sum_d6(array, mask) RESULT(ks)
    1191              :       REAL(KIND=dp), DIMENSION(:, :, :, :, :, :), &
    1192              :          INTENT(IN)                                      :: array
    1193              :       LOGICAL, DIMENSION(:, :, :, :, :, :), INTENT(IN), &
    1194              :          OPTIONAL                                        :: mask
    1195              :       REAL(KIND=dp)                                      :: ks
    1196              : 
    1197              :       INTEGER                                            :: i1, i2, i3, i4, i5, i6
    1198              :       REAL(KIND=dp)                                      :: c, t, y
    1199              : 
    1200            0 :       ks = dzero; t = dzero; y = dzero; c = dzero
    1201              : 
    1202            0 :       IF (PRESENT(mask)) THEN
    1203            0 :          DO i6 = 1, SIZE(array, 6)
    1204            0 :          DO i5 = 1, SIZE(array, 5)
    1205            0 :          DO i4 = 1, SIZE(array, 4)
    1206            0 :          DO i3 = 1, SIZE(array, 3)
    1207            0 :          DO i2 = 1, SIZE(array, 2)
    1208            0 :          DO i1 = 1, SIZE(array, 1)
    1209            0 :             IF (mask(i1, i2, i3, i4, i5, i6)) THEN
    1210            0 :                y = array(i1, i2, i3, i4, i5, i6) - c
    1211            0 :                t = ks + y
    1212            0 :                c = (t - ks) - y
    1213            0 :                ks = t
    1214              :             END IF
    1215              :          END DO
    1216              :          END DO
    1217              :          END DO
    1218              :          END DO
    1219              :          END DO
    1220              :          END DO
    1221              :       ELSE
    1222            0 :          DO i6 = 1, SIZE(array, 6)
    1223            0 :          DO i5 = 1, SIZE(array, 5)
    1224            0 :          DO i4 = 1, SIZE(array, 4)
    1225            0 :          DO i3 = 1, SIZE(array, 3)
    1226            0 :          DO i2 = 1, SIZE(array, 2)
    1227            0 :          DO i1 = 1, SIZE(array, 1)
    1228            0 :             y = array(i1, i2, i3, i4, i5, i6) - c
    1229            0 :             t = ks + y
    1230            0 :             c = (t - ks) - y
    1231            0 :             ks = t
    1232              :          END DO
    1233              :          END DO
    1234              :          END DO
    1235              :          END DO
    1236              :          END DO
    1237              :          END DO
    1238              :       END IF
    1239            0 :    END FUNCTION kahan_sum_d6
    1240              : 
    1241              : ! **************************************************************************************************
    1242              : !> \brief ...
    1243              : !> \param array ...
    1244              : !> \param mask ...
    1245              : !> \return ...
    1246              : ! **************************************************************************************************
    1247            0 :    PURE FUNCTION kahan_sum_c6(array, mask) RESULT(ks)
    1248              :       COMPLEX(KIND=sp), DIMENSION(:, :, :, :, :, :), &
    1249              :          INTENT(IN)                                      :: array
    1250              :       LOGICAL, DIMENSION(:, :, :, :, :, :), INTENT(IN), &
    1251              :          OPTIONAL                                        :: mask
    1252              :       COMPLEX(KIND=sp)                                   :: ks
    1253              : 
    1254              :       COMPLEX(KIND=sp)                                   :: c, t, y
    1255              :       INTEGER                                            :: i1, i2, i3, i4, i5, i6
    1256              : 
    1257            0 :       ks = czero; t = czero; y = czero; c = czero
    1258              : 
    1259            0 :       IF (PRESENT(mask)) THEN
    1260            0 :          DO i6 = 1, SIZE(array, 6)
    1261            0 :          DO i5 = 1, SIZE(array, 5)
    1262            0 :          DO i4 = 1, SIZE(array, 4)
    1263            0 :          DO i3 = 1, SIZE(array, 3)
    1264            0 :          DO i2 = 1, SIZE(array, 2)
    1265            0 :          DO i1 = 1, SIZE(array, 1)
    1266            0 :             IF (mask(i1, i2, i3, i4, i5, i6)) THEN
    1267            0 :                y = array(i1, i2, i3, i4, i5, i6) - c
    1268            0 :                t = ks + y
    1269            0 :                c = (t - ks) - y
    1270            0 :                ks = t
    1271              :             END IF
    1272              :          END DO
    1273              :          END DO
    1274              :          END DO
    1275              :          END DO
    1276              :          END DO
    1277              :          END DO
    1278              :       ELSE
    1279            0 :          DO i6 = 1, SIZE(array, 6)
    1280            0 :          DO i5 = 1, SIZE(array, 5)
    1281            0 :          DO i4 = 1, SIZE(array, 4)
    1282            0 :          DO i3 = 1, SIZE(array, 3)
    1283            0 :          DO i2 = 1, SIZE(array, 2)
    1284            0 :          DO i1 = 1, SIZE(array, 1)
    1285            0 :             y = array(i1, i2, i3, i4, i5, i6) - c
    1286            0 :             t = ks + y
    1287            0 :             c = (t - ks) - y
    1288            0 :             ks = t
    1289              :          END DO
    1290              :          END DO
    1291              :          END DO
    1292              :          END DO
    1293              :          END DO
    1294              :          END DO
    1295              :       END IF
    1296            0 :    END FUNCTION kahan_sum_c6
    1297              : 
    1298              : ! **************************************************************************************************
    1299              : !> \brief ...
    1300              : !> \param array ...
    1301              : !> \param mask ...
    1302              : !> \return ...
    1303              : ! **************************************************************************************************
    1304            0 :    PURE FUNCTION kahan_sum_z6(array, mask) RESULT(ks)
    1305              :       COMPLEX(KIND=dp), DIMENSION(:, :, :, :, :, :), &
    1306              :          INTENT(IN)                                      :: array
    1307              :       LOGICAL, DIMENSION(:, :, :, :, :, :), INTENT(IN), &
    1308              :          OPTIONAL                                        :: mask
    1309              :       COMPLEX(KIND=dp)                                   :: ks
    1310              : 
    1311              :       COMPLEX(KIND=dp)                                   :: c, t, y
    1312              :       INTEGER                                            :: i1, i2, i3, i4, i5, i6
    1313              : 
    1314            0 :       ks = zzero; t = zzero; y = zzero; c = zzero
    1315              : 
    1316            0 :       IF (PRESENT(mask)) THEN
    1317            0 :          DO i6 = 1, SIZE(array, 6)
    1318            0 :          DO i5 = 1, SIZE(array, 5)
    1319            0 :          DO i4 = 1, SIZE(array, 4)
    1320            0 :          DO i3 = 1, SIZE(array, 3)
    1321            0 :          DO i2 = 1, SIZE(array, 2)
    1322            0 :          DO i1 = 1, SIZE(array, 1)
    1323            0 :             IF (mask(i1, i2, i3, i4, i5, i6)) THEN
    1324            0 :                y = array(i1, i2, i3, i4, i5, i6) - c
    1325            0 :                t = ks + y
    1326            0 :                c = (t - ks) - y
    1327            0 :                ks = t
    1328              :             END IF
    1329              :          END DO
    1330              :          END DO
    1331              :          END DO
    1332              :          END DO
    1333              :          END DO
    1334              :          END DO
    1335              :       ELSE
    1336            0 :          DO i6 = 1, SIZE(array, 6)
    1337            0 :          DO i5 = 1, SIZE(array, 5)
    1338            0 :          DO i4 = 1, SIZE(array, 4)
    1339            0 :          DO i3 = 1, SIZE(array, 3)
    1340            0 :          DO i2 = 1, SIZE(array, 2)
    1341            0 :          DO i1 = 1, SIZE(array, 1)
    1342            0 :             y = array(i1, i2, i3, i4, i5, i6) - c
    1343            0 :             t = ks + y
    1344            0 :             c = (t - ks) - y
    1345            0 :             ks = t
    1346              :          END DO
    1347              :          END DO
    1348              :          END DO
    1349              :          END DO
    1350              :          END DO
    1351              :          END DO
    1352              :       END IF
    1353            0 :    END FUNCTION kahan_sum_z6
    1354              : 
    1355              : ! **************************************************************************************************
    1356              : !> \brief ...
    1357              : !> \param array ...
    1358              : !> \param mask ...
    1359              : !> \return ...
    1360              : ! **************************************************************************************************
    1361            0 :    PURE FUNCTION kahan_sum_s7(array, mask) RESULT(ks)
    1362              :       REAL(KIND=sp), DIMENSION(:, :, :, :, :, :, :), &
    1363              :          INTENT(IN)                                      :: array
    1364              :       LOGICAL, DIMENSION(:, :, :, :, :, :, :), &
    1365              :          INTENT(IN), OPTIONAL                            :: mask
    1366              :       REAL(KIND=sp)                                      :: ks
    1367              : 
    1368              :       INTEGER                                            :: i1, i2, i3, i4, i5, i6, i7
    1369              :       REAL(KIND=sp)                                      :: c, t, y
    1370              : 
    1371            0 :       ks = szero; t = szero; y = szero; c = szero
    1372              : 
    1373            0 :       IF (PRESENT(mask)) THEN
    1374            0 :          DO i7 = 1, SIZE(array, 7)
    1375            0 :          DO i6 = 1, SIZE(array, 6)
    1376            0 :          DO i5 = 1, SIZE(array, 5)
    1377            0 :          DO i4 = 1, SIZE(array, 4)
    1378            0 :          DO i3 = 1, SIZE(array, 3)
    1379            0 :          DO i2 = 1, SIZE(array, 2)
    1380            0 :          DO i1 = 1, SIZE(array, 1)
    1381            0 :             IF (mask(i1, i2, i3, i4, i5, i6, i7)) THEN
    1382            0 :                y = array(i1, i2, i3, i4, i5, i6, i7) - c
    1383            0 :                t = ks + y
    1384            0 :                c = (t - ks) - y
    1385            0 :                ks = t
    1386              :             END IF
    1387              :          END DO
    1388              :          END DO
    1389              :          END DO
    1390              :          END DO
    1391              :          END DO
    1392              :          END DO
    1393              :          END DO
    1394              :       ELSE
    1395            0 :          DO i7 = 1, SIZE(array, 7)
    1396            0 :          DO i6 = 1, SIZE(array, 6)
    1397            0 :          DO i5 = 1, SIZE(array, 5)
    1398            0 :          DO i4 = 1, SIZE(array, 4)
    1399            0 :          DO i3 = 1, SIZE(array, 3)
    1400            0 :          DO i2 = 1, SIZE(array, 2)
    1401            0 :          DO i1 = 1, SIZE(array, 1)
    1402            0 :             y = array(i1, i2, i3, i4, i5, i6, i7) - c
    1403            0 :             t = ks + y
    1404            0 :             c = (t - ks) - y
    1405            0 :             ks = t
    1406              :          END DO
    1407              :          END DO
    1408              :          END DO
    1409              :          END DO
    1410              :          END DO
    1411              :          END DO
    1412              :          END DO
    1413              :       END IF
    1414            0 :    END FUNCTION kahan_sum_s7
    1415              : 
    1416              : ! **************************************************************************************************
    1417              : !> \brief ...
    1418              : !> \param array ...
    1419              : !> \param mask ...
    1420              : !> \return ...
    1421              : ! **************************************************************************************************
    1422            0 :    PURE FUNCTION kahan_sum_d7(array, mask) RESULT(ks)
    1423              :       REAL(KIND=dp), DIMENSION(:, :, :, :, :, :, :), &
    1424              :          INTENT(IN)                                      :: array
    1425              :       LOGICAL, DIMENSION(:, :, :, :, :, :, :), &
    1426              :          INTENT(IN), OPTIONAL                            :: mask
    1427              :       REAL(KIND=dp)                                      :: ks
    1428              : 
    1429              :       INTEGER                                            :: i1, i2, i3, i4, i5, i6, i7
    1430              :       REAL(KIND=dp)                                      :: c, t, y
    1431              : 
    1432            0 :       ks = dzero; t = dzero; y = dzero; c = dzero
    1433              : 
    1434            0 :       IF (PRESENT(mask)) THEN
    1435            0 :          DO i7 = 1, SIZE(array, 7)
    1436            0 :          DO i6 = 1, SIZE(array, 6)
    1437            0 :          DO i5 = 1, SIZE(array, 5)
    1438            0 :          DO i4 = 1, SIZE(array, 4)
    1439            0 :          DO i3 = 1, SIZE(array, 3)
    1440            0 :          DO i2 = 1, SIZE(array, 2)
    1441            0 :          DO i1 = 1, SIZE(array, 1)
    1442            0 :             IF (mask(i1, i2, i3, i4, i5, i6, i7)) THEN
    1443            0 :                y = array(i1, i2, i3, i4, i5, i6, i7) - c
    1444            0 :                t = ks + y
    1445            0 :                c = (t - ks) - y
    1446            0 :                ks = t
    1447              :             END IF
    1448              :          END DO
    1449              :          END DO
    1450              :          END DO
    1451              :          END DO
    1452              :          END DO
    1453              :          END DO
    1454              :          END DO
    1455              :       ELSE
    1456            0 :          DO i7 = 1, SIZE(array, 7)
    1457            0 :          DO i6 = 1, SIZE(array, 6)
    1458            0 :          DO i5 = 1, SIZE(array, 5)
    1459            0 :          DO i4 = 1, SIZE(array, 4)
    1460            0 :          DO i3 = 1, SIZE(array, 3)
    1461            0 :          DO i2 = 1, SIZE(array, 2)
    1462            0 :          DO i1 = 1, SIZE(array, 1)
    1463            0 :             y = array(i1, i2, i3, i4, i5, i6, i7) - c
    1464            0 :             t = ks + y
    1465            0 :             c = (t - ks) - y
    1466            0 :             ks = t
    1467              :          END DO
    1468              :          END DO
    1469              :          END DO
    1470              :          END DO
    1471              :          END DO
    1472              :          END DO
    1473              :          END DO
    1474              :       END IF
    1475            0 :    END FUNCTION kahan_sum_d7
    1476              : 
    1477              : ! **************************************************************************************************
    1478              : !> \brief ...
    1479              : !> \param array ...
    1480              : !> \param mask ...
    1481              : !> \return ...
    1482              : ! **************************************************************************************************
    1483            0 :    PURE FUNCTION kahan_sum_c7(array, mask) RESULT(ks)
    1484              :       COMPLEX(KIND=sp), DIMENSION(:, :, :, :, :, :, :), &
    1485              :          INTENT(IN)                                      :: array
    1486              :       LOGICAL, DIMENSION(:, :, :, :, :, :, :), &
    1487              :          INTENT(IN), OPTIONAL                            :: mask
    1488              :       COMPLEX(KIND=sp)                                   :: ks
    1489              : 
    1490              :       COMPLEX(KIND=sp)                                   :: c, t, y
    1491              :       INTEGER                                            :: i1, i2, i3, i4, i5, i6, i7
    1492              : 
    1493            0 :       ks = czero; t = czero; y = czero; c = czero
    1494              : 
    1495            0 :       IF (PRESENT(mask)) THEN
    1496            0 :          DO i7 = 1, SIZE(array, 7)
    1497            0 :          DO i6 = 1, SIZE(array, 6)
    1498            0 :          DO i5 = 1, SIZE(array, 5)
    1499            0 :          DO i4 = 1, SIZE(array, 4)
    1500            0 :          DO i3 = 1, SIZE(array, 3)
    1501            0 :          DO i2 = 1, SIZE(array, 2)
    1502            0 :          DO i1 = 1, SIZE(array, 1)
    1503            0 :             IF (mask(i1, i2, i3, i4, i5, i6, i7)) THEN
    1504            0 :                y = array(i1, i2, i3, i4, i5, i6, i7) - c
    1505            0 :                t = ks + y
    1506            0 :                c = (t - ks) - y
    1507            0 :                ks = t
    1508              :             END IF
    1509              :          END DO
    1510              :          END DO
    1511              :          END DO
    1512              :          END DO
    1513              :          END DO
    1514              :          END DO
    1515              :          END DO
    1516              :       ELSE
    1517            0 :          DO i7 = 1, SIZE(array, 7)
    1518            0 :          DO i6 = 1, SIZE(array, 6)
    1519            0 :          DO i5 = 1, SIZE(array, 5)
    1520            0 :          DO i4 = 1, SIZE(array, 4)
    1521            0 :          DO i3 = 1, SIZE(array, 3)
    1522            0 :          DO i2 = 1, SIZE(array, 2)
    1523            0 :          DO i1 = 1, SIZE(array, 1)
    1524            0 :             y = array(i1, i2, i3, i4, i5, i6, i7) - c
    1525            0 :             t = ks + y
    1526            0 :             c = (t - ks) - y
    1527            0 :             ks = t
    1528              :          END DO
    1529              :          END DO
    1530              :          END DO
    1531              :          END DO
    1532              :          END DO
    1533              :          END DO
    1534              :          END DO
    1535              :       END IF
    1536            0 :    END FUNCTION kahan_sum_c7
    1537              : 
    1538              : ! **************************************************************************************************
    1539              : !> \brief ...
    1540              : !> \param array ...
    1541              : !> \param mask ...
    1542              : !> \return ...
    1543              : ! **************************************************************************************************
    1544            0 :    PURE FUNCTION kahan_sum_z7(array, mask) RESULT(ks)
    1545              :       COMPLEX(KIND=dp), DIMENSION(:, :, :, :, :, :, :), &
    1546              :          INTENT(IN)                                      :: array
    1547              :       LOGICAL, DIMENSION(:, :, :, :, :, :, :), &
    1548              :          INTENT(IN), OPTIONAL                            :: mask
    1549              :       COMPLEX(KIND=dp)                                   :: ks
    1550              : 
    1551              :       COMPLEX(KIND=dp)                                   :: c, t, y
    1552              :       INTEGER                                            :: i1, i2, i3, i4, i5, i6, i7
    1553              : 
    1554            0 :       ks = zzero; t = zzero; y = zzero; c = zzero
    1555              : 
    1556            0 :       IF (PRESENT(mask)) THEN
    1557            0 :          DO i7 = 1, SIZE(array, 7)
    1558            0 :          DO i6 = 1, SIZE(array, 6)
    1559            0 :          DO i5 = 1, SIZE(array, 5)
    1560            0 :          DO i4 = 1, SIZE(array, 4)
    1561            0 :          DO i3 = 1, SIZE(array, 3)
    1562            0 :          DO i2 = 1, SIZE(array, 2)
    1563            0 :          DO i1 = 1, SIZE(array, 1)
    1564            0 :             IF (mask(i1, i2, i3, i4, i5, i6, i7)) THEN
    1565            0 :                y = array(i1, i2, i3, i4, i5, i6, i7) - c
    1566            0 :                t = ks + y
    1567            0 :                c = (t - ks) - y
    1568            0 :                ks = t
    1569              :             END IF
    1570              :          END DO
    1571              :          END DO
    1572              :          END DO
    1573              :          END DO
    1574              :          END DO
    1575              :          END DO
    1576              :          END DO
    1577              :       ELSE
    1578            0 :          DO i7 = 1, SIZE(array, 7)
    1579            0 :          DO i6 = 1, SIZE(array, 6)
    1580            0 :          DO i5 = 1, SIZE(array, 5)
    1581            0 :          DO i4 = 1, SIZE(array, 4)
    1582            0 :          DO i3 = 1, SIZE(array, 3)
    1583            0 :          DO i2 = 1, SIZE(array, 2)
    1584            0 :          DO i1 = 1, SIZE(array, 1)
    1585            0 :             y = array(i1, i2, i3, i4, i5, i6, i7) - c
    1586            0 :             t = ks + y
    1587            0 :             c = (t - ks) - y
    1588            0 :             ks = t
    1589              :          END DO
    1590              :          END DO
    1591              :          END DO
    1592              :          END DO
    1593              :          END DO
    1594              :          END DO
    1595              :          END DO
    1596              :       END IF
    1597            0 :    END FUNCTION kahan_sum_z7
    1598              : 
    1599              : ! **************************************************************************************************
    1600              : !> \brief computes the accurate sum of blocks of regular dot products
    1601              : !> \param array1 array of real numbers
    1602              : !> \param array2 another array of real numbers
    1603              : !> \param blksize ...
    1604              : !> \return dot product
    1605              : ! **************************************************************************************************
    1606         6720 :    FUNCTION kahan_blocked_dot_product_d1(array1, array2, blksize) RESULT(ks)
    1607              :       REAL(KIND=dp), DIMENSION(:), INTENT(in)            :: array1, array2
    1608              :       INTEGER, INTENT(IN), OPTIONAL                      :: blksize
    1609              :       REAL(KIND=dp)                                      :: ks
    1610              : 
    1611              :       INTEGER                                            :: my_blksize
    1612              :       REAL(KIND=dp)                                      :: DDOT
    1613              : 
    1614         6720 :       my_blksize = 32
    1615         6720 :       IF (PRESENT(blksize)) my_blksize = blksize
    1616              : 
    1617         6720 :       IF (my_blksize <= 1) THEN
    1618              :          ! The original should be faster
    1619            0 :          ks = accurate_dot_product(array1, array2)
    1620         6720 :       ELSE IF (my_blksize >= SIZE(array1)) THEN
    1621              :          ! Just use standard dot product from BLAS for performance
    1622         6720 :          ks = DDOT(SIZE(array1), array1(1), 1, array2(1), 1)
    1623              :       ELSE
    1624            0 :          ks = 0.0_dp
    1625              :          BLOCK
    1626              :             INTEGER :: i, n, stripesize
    1627              :             REAL(KIND=dp)                                      :: c, dotproduct, t, y
    1628            0 :             t = dzero; y = dzero; c = dzero
    1629              : 
    1630            0 :             n = SIZE(array1)
    1631            0 :             DO i = 1, n, my_blksize
    1632              :                ! Remove 1 to save an operation in the length
    1633            0 :                stripesize = MIN(my_blksize, n - i + 1)
    1634              :                ! Perform dot product on the given stripe
    1635            0 :                dotproduct = DDOT(stripesize, array1(i), 1, array2(i), 1)
    1636            0 :                y = dotproduct - c
    1637            0 :                t = ks + y
    1638            0 :                c = (t - ks) - y
    1639            0 :                ks = t
    1640              :             END DO
    1641              :          END BLOCK
    1642              :       END IF
    1643         6720 :    END FUNCTION kahan_blocked_dot_product_d1
    1644              : 
    1645              : END MODULE kahan_sum
        

Generated by: LCOV version 2.0-1