LCOV - code coverage report
Current view: top level - shared/common/src/12_hide_mpi - xmpi_sum.finc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 33.1 % 933 309
Test Date: 2026-09-20 15:27:41 Functions: 34.3 % 67 23

            Line data    Source code
       1              : !{\src2tex{textfont=tt}}
       2              : !!****f* ABINIT/xmpi_sum_int
       3              : !! NAME
       4              : !!  xmpi_sum_int
       5              : !!
       6              : !! FUNCTION
       7              : !!  This module contains functions that calls MPI routine,
       8              : !!  if we compile the code using the MPI CPP flags.
       9              : !!  xmpi_sum is the generic function.
      10              : !!
      11              : !! COPYRIGHT
      12              : !!  Copyright (C) 2001-2026 ABINIT group (AR,XG,MB)
      13              : !!  This file is distributed under the terms of the
      14              : !!  GNU General Public License, see ~ABINIT/COPYING
      15              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      16              : !!
      17              : !! NOTES
      18              : !!  MPI2 defines an option MPI_IN_PLACE to do the SUM in-place in the case of intra-communicators.
      19              : !!  The additional array xsum is therefore not needed if MPI_INPLACE is defined.
      20              : !!
      21              : !! SOURCE
      22              : 
      23     30715265 : subroutine xmpi_sum_int(xval,comm,ier)
      24              : 
      25              : !Arguments ------------------------------------
      26              :  integer, DEV_CONTARRD intent(inout) :: xval(:)
      27              :  integer,intent(in)                  :: comm
      28              :  integer,intent(out)                 :: ier
      29              : 
      30              : !Local variables-------------------------------
      31              : #if defined HAVE_MPI
      32              :  integer :: n1
      33     30715265 :  integer,allocatable :: xsum(:)
      34              : #endif
      35              : ! *************************************************************************
      36              : 
      37     30715265 :  ier=0
      38              : #if defined HAVE_MPI
      39     30715265 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
      40        36524 :    n1 = size(xval)
      41              : 
      42              :    !  Accumulate xval on all proc. in comm
      43              : #if defined HAVE_MPI2_INPLACE
      44        36524 :    if (xmpi_use_inplace_operations) then
      45        36524 :      call MPI_ALLREDUCE(MPI_IN_PLACE,xval,n1,MPI_INTEGER,MPI_SUM,comm,ier)
      46              :    else
      47              : #endif
      48            0 :      ABI_STAT_MALLOC(xsum,(n1), ier)
      49            0 :      if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_int')
      50            0 :      call MPI_ALLREDUCE(xval,xsum,n1,MPI_INTEGER,MPI_SUM,comm,ier)
      51            0 :      xval (:) = xsum(:)
      52            0 :      ABI_FREE(xsum)
      53              : #if defined HAVE_MPI2_INPLACE
      54              :    end if
      55              : #endif
      56              : 
      57              :  end if
      58              : #endif
      59              : 
      60     30715265 : end subroutine xmpi_sum_int
      61              : !!***
      62              : 
      63              : !> wrapper arround xmpi_sum_int than can be called in C/CUDA
      64            0 : subroutine xmpi_sum_int_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_int_c")
      65              : 
      66              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
      67              :   implicit none
      68              : 
      69              :   ! dummy args
      70              :   type(c_ptr),                    intent(inout) :: xval_ptr
      71              :   integer(kind=c_int32_t), value, intent(in)    :: xval_size
      72              :   integer(kind=c_int32_t),        intent(in)    :: comm
      73              :   integer(kind=c_int32_t),        intent(out)   :: ier
      74              : 
      75              :   ! local vars
      76              :   integer, pointer :: xval(:) => null()
      77              :   integer(kind=c_int32_t) :: arr_xval_size(1)
      78              : 
      79            0 :   arr_xval_size(1) = xval_size
      80              :   ! convert the c pointer into a fortran array
      81            0 :   call c_f_pointer(xval_ptr, xval, arr_xval_size)
      82              : 
      83            0 :   call xmpi_sum_int(xval, comm, ier)
      84              : 
      85            0 : end subroutine xmpi_sum_int_c
      86              : 
      87              : !----------------------------------------------------------------------
      88              : 
      89              : !!****f* ABINIT/xmpi_sum_intv
      90              : !! NAME
      91              : !!  xmpi_sum_intv
      92              : !!
      93              : !! FUNCTION
      94              : !!  Combines values from all processes and distribute
      95              : !!  the result back to all processes.
      96              : !!  Target: scalar integers.
      97              : !!
      98              : !! INPUTS
      99              : !!  comm= MPI communicator
     100              : !!
     101              : !! OUTPUT
     102              : !!  ier= exit status, a non-zero value meaning there is an error
     103              : !!
     104              : !! SIDE EFFECTS
     105              : !!  xval= buffer array
     106              : !!
     107              : !! SOURCE
     108              : 
     109      5686724 : subroutine xmpi_sum_intv(xval,comm,ier)
     110              : 
     111              : !Arguments----------------------
     112              :  integer,intent(inout) :: xval
     113              :  integer,intent(in)    :: comm
     114              :  integer,intent(out)   :: ier
     115              : 
     116              : !Local variables----------------
     117              : #if defined HAVE_MPI
     118              :  integer :: arr_xsum(1),arr_xval(1)
     119              : #endif
     120              : ! *************************************************************************
     121              : 
     122      5686724 :  ier=0
     123              : #if defined HAVE_MPI
     124      5686724 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     125              : !  Accumulate xval on all proc. in comm
     126       300233 :    arr_xval(1) = xval
     127       300233 :    call MPI_ALLREDUCE(arr_xval,arr_xsum,1,MPI_INTEGER,MPI_SUM,comm,ier)
     128       300233 :    xval = arr_xsum(1)
     129              :  end if
     130              : #endif
     131      5686724 : end subroutine xmpi_sum_intv
     132              : !!***
     133              : 
     134              : !> wrapper arround xmpi_sum_intv than can be called in C/CUDA
     135            0 : subroutine xmpi_sum_intv_c(xval_ptr,comm,ier) bind(c, name="xmpi_sum_intv_c")
     136              : 
     137              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     138              :   implicit none
     139              : 
     140              :   ! dummy args
     141              :   type(c_ptr),                    intent(inout) :: xval_ptr
     142              :   integer(kind=c_int32_t),        intent(in)    :: comm
     143              :   integer(kind=c_int32_t),        intent(out)   :: ier
     144              : 
     145              :   ! local vars
     146              :   integer, pointer :: xval => null()
     147              : 
     148              :   ! convert the c pointer into a fortran variable
     149            0 :   call c_f_pointer(xval_ptr, xval)
     150              : 
     151            0 :   call xmpi_sum_intv(xval, comm, ier)
     152              : 
     153            0 : end subroutine xmpi_sum_intv_c
     154              : 
     155              : 
     156              : !----------------------------------------------------------------------
     157              : 
     158              : !!****f* ABINIT/xmpi_sum_intv2
     159              : !! NAME
     160              : !!  xmpi_sum_intv2
     161              : !!
     162              : !! FUNCTION
     163              : !!  Combines values from all processes and distribute
     164              : !!  the result back to all processes.
     165              : !!  Target: scalar integer without transfers.
     166              : !!
     167              : !! INPUTS
     168              : !!  comm= MPI communicator
     169              : !!
     170              : !! OUTPUT
     171              : !!  ier= exit status, a non-zero value meaning there is an error
     172              : !!
     173              : !! SIDE EFFECTS
     174              : !!  xval= buffer array
     175              : !!  xsum= receive buffer
     176              : !!
     177              : !! SOURCE
     178              : 
     179           38 : subroutine xmpi_sum_intv2(xval,xsum,comm,ier)
     180              : 
     181              : !Arguments---------------------
     182              :  integer,intent(inout) :: xval,xsum
     183              :  integer,intent(in) :: comm
     184              :  integer,intent(out) :: ier
     185              : 
     186              : !Local variables----------------
     187              : #if defined HAVE_MPI
     188              :  integer :: arr_xsum(1),arr_xval(1)
     189              : #endif
     190              : ! *************************************************************************
     191              : 
     192           38 :  ier=0
     193              : #if defined HAVE_MPI
     194           38 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     195           38 :    arr_xval(1) = xval
     196           38 :    call MPI_ALLREDUCE(arr_xval,arr_xsum,1,MPI_INTEGER,MPI_SUM,comm,ier)
     197           38 :    xsum=arr_xsum(1)
     198              :  else
     199              : #endif
     200            0 :    xsum=xval
     201              : #if defined HAVE_MPI
     202              :  end if
     203              : #endif
     204              : 
     205           38 : end subroutine xmpi_sum_intv2
     206              : !!***
     207              : 
     208              : !> wrapper arround xmpi_sum_intv2 than can be called in C/CUDA
     209            0 : subroutine xmpi_sum_intv2_c(xval_ptr,xsum_ptr,comm,ier) bind(c, name="xmpi_sum_intv2_c")
     210              : 
     211              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     212              :   implicit none
     213              : 
     214              :   ! dummy args
     215              :   type(c_ptr),                    intent(inout) :: xval_ptr
     216              :   type(c_ptr),                    intent(inout) :: xsum_ptr
     217              :   integer(kind=c_int32_t),        intent(in)    :: comm
     218              :   integer(kind=c_int32_t),        intent(out)   :: ier
     219              : 
     220              :   ! local vars
     221              :   integer, pointer :: xval => null()
     222              :   integer, pointer :: xsum => null()
     223              : 
     224              :   ! convert the c pointer into a fortran variable
     225            0 :   call c_f_pointer(xval_ptr, xval)
     226            0 :   call c_f_pointer(xsum_ptr, xsum)
     227              : 
     228            0 :   call xmpi_sum_intv2(xval, xsum, comm, ier)
     229              : 
     230            0 : end subroutine xmpi_sum_intv2_c
     231              : 
     232              : !!****f* ABINIT/xmpi_sum_intn
     233              : !! NAME
     234              : !!  xmpi_sum_intn
     235              : !!
     236              : !! FUNCTION
     237              : !!  Combines values from all processes and distribute
     238              : !!  the result back to all processes.
     239              : !!  Target: one-dimensional integer arrays.
     240              : !!
     241              : !! INPUTS
     242              : !!  n1= first dimension of the array
     243              : !!  comm= MPI communicator
     244              : !!
     245              : !! OUTPUT
     246              : !!  ier= exit status, a non-zero value meaning there is an error
     247              : !!
     248              : !! SIDE EFFECTS
     249              : !!  xval= buffer array
     250              : !!
     251              : !! SOURCE
     252              : 
     253            0 : subroutine xmpi_sum_intn(xval,n1,comm,ier)
     254              : 
     255              : !Arguments-------------------------
     256              :  integer, DEV_CONTARRD intent(inout) :: xval(:)
     257              :  integer,intent(in) :: n1
     258              :  integer,intent(in) :: comm
     259              :  integer,intent(out) :: ier
     260              : 
     261              : !Local variables-------------------
     262              : #if defined HAVE_MPI
     263              :  integer :: nproc_space_comm
     264            0 :  integer , allocatable :: xsum(:)
     265              : #endif
     266              : ! *************************************************************************
     267              : 
     268            0 :  ier=0
     269              : #if defined HAVE_MPI
     270            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     271            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
     272            0 :    if (nproc_space_comm /= 1) then
     273              : 
     274              : !    Accumulate xval on all proc. in comm
     275              : #if defined HAVE_MPI2_INPLACE
     276            0 :      if (xmpi_use_inplace_operations) then
     277            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,n1,MPI_INTEGER,MPI_SUM,comm,ier)
     278              :      else
     279              : #endif
     280            0 :        ABI_STAT_MALLOC(xsum,(n1), ier)
     281            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_intn')
     282            0 :        call MPI_ALLREDUCE(xval,xsum,n1,MPI_INTEGER,MPI_SUM,comm,ier)
     283            0 :        xval (:) = xsum(:)
     284            0 :        ABI_FREE(xsum)
     285              : #if defined HAVE_MPI2_INPLACE
     286              :      endif
     287              : #endif
     288              : 
     289              :    end if
     290              :  end if
     291              : #endif
     292              : 
     293            0 : end subroutine xmpi_sum_intn
     294              : !!***
     295              : 
     296              : !> wrapper arround xmpi_sum_intn than can be called in C/CUDA
     297            0 : subroutine xmpi_sum_intn_c(xval_ptr,xval_size,n1,comm,ier) bind(c, name="xmpi_sum_intn_c")
     298              : 
     299              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     300              :   implicit none
     301              : 
     302              :   ! dummy args
     303              :   type(c_ptr),                    intent(inout) :: xval_ptr
     304              :   integer(kind=c_int32_t), value, intent(in)    :: xval_size
     305              :   integer(kind=c_int32_t),        intent(in)    :: n1
     306              :   integer(kind=c_int32_t),        intent(in)    :: comm
     307              :   integer(kind=c_int32_t),        intent(out)   :: ier
     308              : 
     309              :   ! local vars
     310              :   integer, pointer :: xval(:) => null()
     311              :   integer(kind=c_int32_t) :: arr_xval_size(1)
     312              : 
     313            0 :   arr_xval_size(1) = xval_size
     314              :   ! convert the c pointer into a fortran array
     315            0 :   call c_f_pointer(xval_ptr, xval, arr_xval_size)
     316              : 
     317            0 :   call xmpi_sum_intn(xval, n1, comm, ier)
     318              : 
     319            0 : end subroutine xmpi_sum_intn_c
     320              : 
     321              : !----------------------------------------------------------------------
     322              : 
     323              : !!****f* ABINIT/xmpi_sum_int2t
     324              : !! NAME
     325              : !!  xmpi_sum_int2t
     326              : !!
     327              : !! FUNCTION
     328              : !!  Combines values from all processes and distribute
     329              : !!  the result back to all processes.
     330              : !!  Target: one-dimensional integer array without transfers.
     331              : !!
     332              : !! INPUTS
     333              : !!  n1= first dimension of the array
     334              : !!  comm= MPI communicator
     335              : !!
     336              : !! OUTPUT
     337              : !!  ier= exit status, a non-zero value meaning there is an error
     338              : !!
     339              : !! SIDE EFFECTS
     340              : !!  xval= buffer array
     341              : !!  xsum= receive buffer
     342              : !!
     343              : !! SOURCE
     344              : 
     345          788 : subroutine xmpi_sum_int2t(xval,xsum,n1,comm,ier)
     346              : 
     347              : !Arguments-------------------------
     348              :  integer, DEV_CONTARRD intent(inout) :: xval(:),xsum(:)
     349              :  integer,intent(in) :: n1
     350              :  integer,intent(in) :: comm
     351              :  integer,intent(out) :: ier
     352              : ! *************************************************************************
     353              : 
     354          788 :  ier=0
     355              : #if defined HAVE_MPI
     356          788 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     357              : !  Accumulate xval on all proc. in comm
     358          772 :    call MPI_ALLREDUCE(xval,xsum,n1,MPI_INTEGER,MPI_SUM,comm,ier)
     359              :  else
     360              : #endif
     361           32 :    xsum=xval
     362              : #if defined HAVE_MPI
     363              :  end if
     364              : #endif
     365              : 
     366          788 : end subroutine xmpi_sum_int2t
     367              : !!***
     368              : 
     369              : !----------------------------------------------------------------------
     370              : 
     371              : !!****f* ABINIT/xmpi_sum_int2d
     372              : !! NAME
     373              : !!  xmpi_sum_int2d
     374              : !!
     375              : !! FUNCTION
     376              : !!  Combines values from all processes and distribute
     377              : !!  the result back to all processes.
     378              : !!  Target: two-dimensional integer arrays.
     379              : !!
     380              : !! INPUTS
     381              : !!  comm= MPI communicator
     382              : !!
     383              : !! OUTPUT
     384              : !!  ier= exit status, a non-zero value meaning there is an error
     385              : !!
     386              : !! SIDE EFFECTS
     387              : !!  xval= buffer array
     388              : !!
     389              : !! SOURCE
     390              : 
     391          857 : subroutine xmpi_sum_int2d(xval,comm,ier)
     392              : 
     393              : !Arguments-------------------------
     394              :  integer, DEV_CONTARRD intent(inout) :: xval(:,:)
     395              :  integer,intent(in) :: comm
     396              :  integer,intent(out) :: ier
     397              : 
     398              : !Local variables-------------------
     399              : #if defined HAVE_MPI
     400              :  integer :: my_dt,my_op,n1,n2,nn,nproc_space_comm
     401              :  integer(kind=int64) :: ntot
     402          857 :  integer,allocatable :: xsum(:,:)
     403              : #endif
     404              : ! *************************************************************************
     405              : 
     406          857 :  ier=0
     407              : #if defined HAVE_MPI
     408          857 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     409          852 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
     410          852 :    if (nproc_space_comm /= 1) then
     411          174 :      n1 =size(xval,dim=1)
     412          174 :      n2 =size(xval,dim=2)
     413              : 
     414              :      !This product of dimensions can be greater than a 32bit integer
     415              :      !We use a INT64 to store it. If it is too large, we switch to an
     416              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
     417          174 :      ntot=int(n1,kind=int64)*n2
     418          174 :      if (ntot<=xmpi_maxint32_64) then
     419          174 :        nn=n1*n2 ; my_dt=MPI_INTEGER ; my_op=MPI_SUM
     420              :      else
     421            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_INTEGER,my_dt,my_op,MPI_SUM)
     422              :      end if
     423              : 
     424              : !    Accumulate xval on all proc. in comm
     425              : #if defined HAVE_MPI2_INPLACE
     426          174 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
     427              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
     428          174 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
     429              :      else
     430              : #endif
     431            0 :        ABI_STAT_MALLOC(xsum,(n1,n2), ier)
     432            0 :        if (ier/=0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_int2d')
     433            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
     434            0 :        xval (:,:) = xsum(:,:)
     435            0 :        ABI_FREE(xsum)
     436              : #if defined HAVE_MPI2_INPLACE
     437              :      end if
     438              : #endif
     439              : 
     440          174 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
     441              :    end if
     442              :  end if
     443              : #endif
     444              : 
     445          857 : end subroutine xmpi_sum_int2d
     446              : !!***
     447              : 
     448              : !> wrapper arround xmpi_sum_int2d than can be called in C/CUDA
     449            0 : subroutine xmpi_sum_int2d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_int2d_c")
     450              : 
     451              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     452              :   implicit none
     453              : 
     454              :   ! dummy args
     455              :   type(c_ptr),                    intent(inout) :: xval_ptr
     456              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(2)
     457              :   integer(kind=c_int32_t),        intent(in)    :: comm
     458              :   integer(kind=c_int32_t),        intent(out)   :: ier
     459              : 
     460              :   ! local vars
     461              :   integer, pointer :: xval(:,:) => null()
     462              : 
     463              :   ! convert the c pointer into a fortran array
     464            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
     465              : 
     466            0 :   call xmpi_sum_int2d(xval, comm, ier)
     467              : 
     468            0 : end subroutine xmpi_sum_int2d_c
     469              : 
     470              : !----------------------------------------------------------------------
     471              : 
     472              : !!****f* ABINIT/xmpi_sum_int3d
     473              : !! NAME
     474              : !!  xmpi_sum_int3d
     475              : !!
     476              : !! FUNCTION
     477              : !!  Combines values from all processes and distribute
     478              : !!  the result back to all processes.
     479              : !!  Target: three-dimensional integer arrays.
     480              : !!
     481              : !! INPUTS
     482              : !!  comm= MPI communicator
     483              : !!
     484              : !! OUTPUT
     485              : !!  ier= exit status, a non-zero value meaning there is an error
     486              : !!
     487              : !! SIDE EFFECTS
     488              : !!  xval= buffer array
     489              : !!
     490              : !! SOURCE
     491              : 
     492          706 : subroutine xmpi_sum_int3d(xval,comm,ier)
     493              : 
     494              : !Arguments-------------------------
     495              :  integer, DEV_CONTARRD intent(inout) :: xval(:,:,:)
     496              :  integer,intent(in) :: comm
     497              :  integer,intent(out) :: ier
     498              : 
     499              : !Local variables-------------------
     500              : #if defined HAVE_MPI
     501              :  integer :: my_dt,my_op,n1,n2,n3,nn,nproc_space_comm
     502              :  integer(kind=int64) :: ntot
     503          706 :  integer,allocatable :: xsum(:,:,:)
     504              : #endif
     505              : ! *************************************************************************
     506              : 
     507          706 :  ier=0
     508              : #if defined HAVE_MPI
     509          706 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     510          706 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
     511          706 :    if (nproc_space_comm /= 1) then
     512          234 :      n1 =size(xval,dim=1)
     513          234 :      n2 =size(xval,dim=2)
     514          234 :      n3 =size(xval,dim=3)
     515              : 
     516              :      !This product of dimensions can be greater than a 32bit integer
     517              :      !We use a INT64 to store it. If it is too large, we switch to an
     518              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
     519          234 :      ntot=int(n1,kind=int64)*n2*n3
     520          234 :      if (ntot<=xmpi_maxint32_64) then
     521          234 :        nn=n1*n2*n3 ; my_dt=MPI_INTEGER ; my_op=MPI_SUM
     522              :      else
     523            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_INTEGER,my_dt,my_op,MPI_SUM)
     524              :      end if
     525              : 
     526              : !    Accumulate xval on all proc. in comm
     527              : #if defined HAVE_MPI2_INPLACE
     528          234 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
     529              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
     530          234 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
     531              : #endif
     532              :      else
     533            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3), ier)
     534            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_int3d')
     535            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
     536            0 :        xval (:,:,:) = xsum(:,:,:)
     537            0 :        ABI_FREE(xsum)
     538              : #if defined HAVE_MPI2_INPLACE
     539              :      end if
     540              : #endif
     541              : 
     542          234 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
     543              :    end if
     544              :  end if
     545              : #endif
     546              : 
     547          706 : end subroutine xmpi_sum_int3d
     548              : !!***
     549              : 
     550              : !> wrapper arround xmpi_sum_int3d than can be called in C/CUDA
     551            0 : subroutine xmpi_sum_int3d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_int3d_c")
     552              : 
     553              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     554              :   implicit none
     555              : 
     556              :   ! dummy args
     557              :   type(c_ptr),                    intent(inout) :: xval_ptr
     558              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(3)
     559              :   integer(kind=c_int32_t),        intent(in)    :: comm
     560              :   integer(kind=c_int32_t),        intent(out)   :: ier
     561              : 
     562              :   ! local vars
     563              :   integer, pointer :: xval(:,:,:) => null()
     564              : 
     565              :   ! convert the c pointer into a fortran array
     566            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
     567              : 
     568            0 :   call xmpi_sum_int3d(xval, comm, ier)
     569              : 
     570            0 : end subroutine xmpi_sum_int3d_c
     571              : 
     572              : !----------------------------------------------------------------------
     573              : 
     574              : !!****f* ABINIT/xmpi_sum_int4d
     575              : !! NAME
     576              : !!  xmpi_sum_int4d
     577              : !!
     578              : !! FUNCTION
     579              : !!  Combines values from all processes and distribute
     580              : !!  the result back to all processes.
     581              : !!  Target: four-dimensional integer arrays.
     582              : !!
     583              : !! INPUTS
     584              : !!  comm= MPI communicator
     585              : !!
     586              : !! OUTPUT
     587              : !!  ier= exit status, a non-zero value meaning there is an error
     588              : !!
     589              : !! SIDE EFFECTS
     590              : !!  xval= buffer array
     591              : !!
     592              : !! SOURCE
     593              : 
     594         4420 : subroutine xmpi_sum_int4d(xval,comm,ier)
     595              : 
     596              : !Arguments-------------------------
     597              :  integer, DEV_CONTARRD intent(inout) :: xval(:,:,:,:)
     598              :  integer,intent(in) :: comm
     599              :  integer,intent(out) :: ier
     600              : 
     601              : !Local variables-------------------
     602              : #if defined HAVE_MPI
     603              :  integer :: my_dt,my_op,n1,n2,n3,n4,nn,nproc_space_comm
     604              :  integer(kind=int64) :: ntot
     605         4420 :  integer,allocatable :: xsum(:,:,:,:)
     606              : #endif
     607              : ! *************************************************************************
     608              : 
     609         4420 :  ier=0
     610              : #if defined HAVE_MPI
     611         4420 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     612         4403 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
     613         4403 :    if (nproc_space_comm /= 1) then
     614         4244 :      n1 =size(xval,dim=1)
     615         4244 :      n2 =size(xval,dim=2)
     616         4244 :      n3 =size(xval,dim=3)
     617         4244 :      n4 =size(xval,dim=4)
     618              : 
     619              :      !This product of dimensions can be greater than a 32bit integer
     620              :      !We use a INT64 to store it. If it is too large, we switch to an
     621              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
     622         4244 :      ntot=int(n1,kind=int64)*n2*n3*n4
     623         4244 :      if (ntot<=xmpi_maxint32_64) then
     624         4244 :        nn=n1*n2*n3*n4 ; my_dt=MPI_INTEGER ; my_op=MPI_SUM
     625              :      else
     626            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_INTEGER,my_dt,my_op,MPI_SUM)
     627              :      end if
     628              : 
     629              : !    Accumulate xval on all proc. in comm
     630              : #if defined HAVE_MPI2_INPLACE
     631         4244 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
     632              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
     633         4244 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
     634              :      else
     635              : #endif
     636            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4), ier)
     637            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_int4d')
     638            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
     639            0 :        xval (:,:,:,:) = xsum(:,:,:,:)
     640            0 :        ABI_FREE(xsum)
     641              : #if defined HAVE_MPI2_INPLACE
     642              :      end if
     643              : #endif
     644              : 
     645         4244 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
     646              :    end if
     647              :  end if
     648              : #endif
     649              : 
     650         4420 : end subroutine xmpi_sum_int4d
     651              : !!***
     652              : 
     653              : !> wrapper arround xmpi_sum_int4d than can be called in C/CUDA
     654            0 : subroutine xmpi_sum_int4d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_int4d_c")
     655              : 
     656              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     657              :   implicit none
     658              : 
     659              :   ! dummy args
     660              :   type(c_ptr),                    intent(inout) :: xval_ptr
     661              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(4)
     662              :   integer(kind=c_int32_t),        intent(in)    :: comm
     663              :   integer(kind=c_int32_t),        intent(out)   :: ier
     664              : 
     665              :   ! local vars
     666              :   integer, pointer :: xval(:,:,:,:) => null()
     667              : 
     668              :   ! convert the c pointer into a fortran array
     669            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
     670              : 
     671            0 :   call xmpi_sum_int4d(xval, comm, ier)
     672              : 
     673            0 : end subroutine xmpi_sum_int4d_c
     674              : 
     675              : !----------------------------------------------------------------------
     676              : 
     677              : !!****f* ABINIT/xmpi_sum_dp
     678              : !! NAME
     679              : !!  xmpi_sum_dp
     680              : !!
     681              : !! FUNCTION
     682              : !!  Combines values from all processes and distribute
     683              : !!  the result back to all processes.
     684              : !!  Target: one-dimensional double precision arrays.
     685              : !!
     686              : !! INPUTS
     687              : !!  comm= MPI communicator
     688              : !!
     689              : !! OUTPUT
     690              : !!  ier= exit status, a non-zero value meaning there is an error
     691              : !!
     692              : !! SIDE EFFECTS
     693              : !!  xval= buffer array
     694              : !!
     695              : !! SOURCE
     696              : 
     697     28034202 : subroutine xmpi_sum_dp(xval,comm,ier)
     698              : 
     699              : !Arguments-------------------------
     700              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:)
     701              :  integer,intent(in) :: comm
     702              :  integer,intent(out) :: ier
     703              : 
     704              : !Local variables-------------------
     705              : #if defined HAVE_MPI
     706              :  integer :: n1,nproc_space_comm
     707     28034202 :  real(dp),allocatable :: xsum(:)
     708              : #endif
     709              : ! *************************************************************************
     710              : 
     711     28034202 :  ier=0
     712              : #if defined HAVE_MPI
     713     28034202 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     714       989678 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
     715       989678 :    if (nproc_space_comm /= 1) then
     716       271296 :      n1 = size(xval)
     717              : 
     718              : !    Accumulate xval on all proc. in comm
     719              : #if defined HAVE_MPI2_INPLACE
     720       271296 :      if (xmpi_use_inplace_operations) then
     721       271296 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,n1,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
     722              :      else
     723              : #endif
     724            0 :        ABI_STAT_MALLOC(xsum,(n1), ier)
     725            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_dp')
     726            0 :        call MPI_ALLREDUCE(xval,xsum,n1,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
     727            0 :        xval (:) = xsum(:)
     728            0 :        ABI_FREE(xsum)
     729              : #if defined HAVE_MPI2_INPLACE
     730              :      end if
     731              : #endif
     732              : 
     733              :    end if
     734              :  end if
     735              : #endif
     736              : 
     737     28034202 : end subroutine xmpi_sum_dp
     738              : !!***
     739              : 
     740              : !> wrapper arround xmpi_sum_dp than can be called in C/CUDA
     741            0 : subroutine xmpi_sum_dp_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_dp_c")
     742              : 
     743              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     744              :   implicit none
     745              : 
     746              :   ! dummy args
     747              :   type(c_ptr),                    intent(inout) :: xval_ptr
     748              :   integer(kind=c_int32_t), value, intent(in)    :: xval_size
     749              :   integer(kind=c_int32_t),        intent(in)    :: comm
     750              :   integer(kind=c_int32_t),        intent(out)   :: ier
     751              : 
     752              :   ! local vars
     753              :   real(dp), pointer :: xval(:) => null()
     754              :   integer(kind=c_int32_t) :: arr_xval_size(1)
     755              : 
     756            0 :   arr_xval_size(1) = xval_size
     757              :   ! convert the c pointer into a fortran array
     758            0 :   call c_f_pointer(xval_ptr, xval, arr_xval_size)
     759              : 
     760            0 :   call xmpi_sum_dp(xval, comm, ier)
     761              : 
     762            0 : end subroutine xmpi_sum_dp_c
     763              : 
     764              : !----------------------------------------------------------------------
     765              : 
     766              : !!****f* ABINIT/xmpi_sum_dpvt
     767              : !! NAME
     768              : !!  xmpi_sum_dpvt
     769              : !!
     770              : !! FUNCTION
     771              : !!  Combines values from all processes and distribute
     772              : !!  the result back to all processes.
     773              : !!  Target: scalar double precisions.
     774              : !!
     775              : !! INPUTS
     776              : !!  xval= buffer array
     777              : !!  comm= MPI communicator
     778              : !!
     779              : !! OUTPUT
     780              : !!  xsum= receive buffer
     781              : !!  ier= exit status, a non-zero value meaning there is an error
     782              : !!
     783              : !! SIDE EFFECTS
     784              : !!  None
     785              : !!
     786              : !! SOURCE
     787              : 
     788            0 : subroutine xmpi_sum_dpvt(xval,xsum,comm,ier)
     789              : 
     790              : !Arguments-------------------------
     791              :  real(dp),intent(in) :: xval
     792              :  real(dp),intent(out) :: xsum
     793              :  integer ,intent(in) :: comm
     794              :  integer ,intent(out)   :: ier
     795              : 
     796              : !Local variables-------------------
     797              : #if defined HAVE_MPI
     798              :  integer :: nproc_space_comm
     799              :  real(dp) :: arr_xsum(1),arr_xval(1)
     800              : #endif
     801              : ! *************************************************************************
     802              : 
     803            0 :  ier=0
     804              : #if defined HAVE_MPI
     805            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     806            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
     807            0 :    if (nproc_space_comm /= 1) then
     808              : !    Accumulate xval on all proc. in comm
     809            0 :      arr_xval(1) = xval
     810            0 :      call MPI_ALLREDUCE(arr_xval,arr_xsum,1,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
     811            0 :      xsum=arr_xsum(1)
     812              :    else
     813            0 :      xsum=xval
     814              :    end if
     815              :  else
     816              : #endif
     817            0 :    xsum=xval
     818              : #if defined HAVE_MPI
     819              :  end if
     820              : #endif
     821              : 
     822            0 : end subroutine xmpi_sum_dpvt
     823              : !!***
     824              : 
     825              : !> wrapper arround xmpi_sum_dpvt than can be called in C/CUDA
     826            0 : subroutine xmpi_sum_dpvt_c(xval_ptr,xsum_ptr,comm,ier) bind(c, name="xmpi_sum_dpvt_c")
     827              : 
     828              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     829              :   implicit none
     830              : 
     831              :   ! dummy args
     832              :   type(c_ptr),                    intent(inout) :: xval_ptr
     833              :   type(c_ptr),                    intent(inout) :: xsum_ptr
     834              :   integer(kind=c_int32_t),        intent(in)    :: comm
     835              :   integer(kind=c_int32_t),        intent(out)   :: ier
     836              : 
     837              :   ! local vars
     838              :   real(dp), pointer :: xval => null()
     839              :   real(dp), pointer :: xsum => null()
     840              : 
     841              :   ! convert the c pointer into a fortran array
     842            0 :   call c_f_pointer(xval_ptr, xval)
     843            0 :   call c_f_pointer(xsum_ptr, xsum)
     844              : 
     845            0 :   call xmpi_sum_dpvt(xval, xsum, comm, ier)
     846              : 
     847            0 : end subroutine xmpi_sum_dpvt_c
     848              : 
     849              : !----------------------------------------------------------------------
     850              : 
     851              : !!****f* ABINIT/xmpi_sum_dpv
     852              : !! NAME
     853              : !!  xmpi_sum_dpv
     854              : !!
     855              : !! FUNCTION
     856              : !!  Combines values from all processes and distribute
     857              : !!  the result back to all processes.
     858              : !!  Target: scalar double precisions.
     859              : !!
     860              : !! INPUTS
     861              : !!  comm= MPI communicator
     862              : !!
     863              : !! OUTPUT
     864              : !!  ier= exit status, a non-zero value meaning there is an error
     865              : !!
     866              : !! SIDE EFFECTS
     867              : !!  xval= buffer array
     868              : !!
     869              : !! SOURCE
     870     33406387 : subroutine xmpi_sum_dpv(xval,comm,ier)
     871              : 
     872              : !Arguments-------------------------
     873              :  real(dp),intent(inout) :: xval
     874              :  integer ,intent(in) :: comm
     875              :  integer ,intent(out) :: ier
     876              : 
     877              : !Local variables-------------------
     878              : #if defined HAVE_MPI
     879              :  integer :: nproc_space_comm
     880              :  real(dp) :: arr_xsum(1),arr_xval(1)
     881              : #endif
     882              : ! *************************************************************************
     883              : 
     884     33406387 :  ier=0
     885              : #if defined HAVE_MPI
     886     33406387 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     887              : !  Accumulate xval on all proc. in comm
     888       780141 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
     889       780141 :    if (nproc_space_comm /= 1) then
     890       688122 :      arr_xval(1) = xval
     891       688122 :      call MPI_ALLREDUCE(arr_xval,arr_xsum,1,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
     892       688122 :      xval  = arr_xsum(1)
     893              :    end if
     894              :  end if
     895              : #endif
     896              : 
     897     33406387 : end subroutine xmpi_sum_dpv
     898              : !!***
     899              : 
     900              : !> wrapper arround xmpi_sum_dpv than can be called in C/CUDA
     901            0 : subroutine xmpi_sum_dpv_c(xval_ptr,comm,ier) bind(c, name="xmpi_sum_dpv_c")
     902              : 
     903              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     904              :   implicit none
     905              : 
     906              :   ! dummy args
     907              :   type(c_ptr),                    intent(inout) :: xval_ptr
     908              :   integer(kind=c_int32_t),        intent(in)    :: comm
     909              :   integer(kind=c_int32_t),        intent(out)   :: ier
     910              : 
     911              :   ! local vars
     912              :   real(dp), pointer :: xval => null()
     913              : 
     914              :   ! convert the c pointer into a fortran array
     915            0 :   call c_f_pointer(xval_ptr, xval)
     916              : 
     917            0 :   call xmpi_sum_dpv(xval, comm, ier)
     918              : 
     919            0 : end subroutine xmpi_sum_dpv_c
     920              : 
     921              : !----------------------------------------------------------------------
     922              : 
     923              : !!****f* ABINIT/xmpi_sum_dpn
     924              : !! NAME
     925              : !!  xmpi_sum_dpn
     926              : !!
     927              : !! FUNCTION
     928              : !!  Combines values from all processes and distribute
     929              : !!  the result back to all processes.
     930              : !!  Target: one-dimensional double precision arrays.
     931              : !!
     932              : !! INPUTS
     933              : !!  n1= first dimension of the array
     934              : !!  comm= MPI communicator
     935              : !!
     936              : !! OUTPUT
     937              : !!  ier= exit status, a non-zero value meaning there is an error
     938              : !!
     939              : !! SIDE EFFECTS
     940              : !!  xval= buffer array
     941              : !!
     942              : !! SOURCE
     943              : 
     944       224339 : subroutine xmpi_sum_dpn(xval,n1,comm,ier)
     945              : 
     946              : !Arguments-------------------------
     947              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:)
     948              :  integer ,intent(in) :: n1
     949              :  integer ,intent(in) :: comm
     950              :  integer ,intent(out) :: ier
     951              : 
     952              : !Local variables-------------------
     953              : #if defined HAVE_MPI
     954              :  integer :: nproc_space_comm
     955       224339 :  real(dp) , allocatable :: xsum(:)
     956              : #endif
     957              : ! *************************************************************************
     958              : 
     959       224339 :  ier=0
     960              : #if defined HAVE_MPI
     961       224339 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     962       223815 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
     963       223815 :    if (nproc_space_comm /= 1) then
     964              : 
     965              : !    Accumulate xval on all proc. in comm
     966              : #if defined HAVE_MPI2_INPLACE
     967       163930 :      if (xmpi_use_inplace_operations) then
     968       163930 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,n1,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
     969              :      else
     970              : #endif
     971            0 :        ABI_STAT_MALLOC(xsum,(n1), ier)
     972            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_dpn')
     973            0 :        call MPI_ALLREDUCE(xval,xsum,n1,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
     974            0 :        xval (:) = xsum(:)
     975            0 :        ABI_FREE(xsum)
     976              : #if defined HAVE_MPI2_INPLACE
     977              :      end if
     978              : #endif
     979              : 
     980              :    end if
     981              :  end if
     982              : #endif
     983              : 
     984       224339 : end subroutine xmpi_sum_dpn
     985              : !!***
     986              : 
     987              : !> wrapper arround xmpi_sum_dpn than can be called in C/CUDA
     988            0 : subroutine xmpi_sum_dpn_c(xval_ptr,xval_size,n1,comm,ier) bind(c, name="xmpi_sum_dpn_c")
     989              : 
     990              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
     991              :   implicit none
     992              : 
     993              :   ! dummy args
     994              :   type(c_ptr),                    intent(inout) :: xval_ptr
     995              :   integer(kind=c_int32_t), value, intent(in)    :: xval_size
     996              :   integer(kind=c_int32_t),        intent(in)    :: n1
     997              :   integer(kind=c_int32_t),        intent(in)    :: comm
     998              :   integer(kind=c_int32_t),        intent(out)   :: ier
     999              : 
    1000              :   ! local vars
    1001              :   real(dp), pointer :: xval(:) => null()
    1002              :   integer(kind=c_int32_t) :: arr_xval_size(1)
    1003              : 
    1004            0 :   arr_xval_size(1) = xval_size
    1005              :   ! convert the c pointer into a fortran array
    1006            0 :   call c_f_pointer(xval_ptr, xval, arr_xval_size)
    1007              : 
    1008            0 :   call xmpi_sum_dpn(xval, n1, comm, ier)
    1009              : 
    1010            0 : end subroutine xmpi_sum_dpn_c
    1011              : 
    1012              : !----------------------------------------------------------------------
    1013              : 
    1014              : !!****f* ABINIT/xmpi_sum_sp2d
    1015              : !! NAME
    1016              : !!  xmpi_sum_sp2d
    1017              : !!
    1018              : !! FUNCTION
    1019              : !!  Combines values from all processes and distribute
    1020              : !!  the result back to all processes.
    1021              : !!  Target: double precision two-dimensional arrays.
    1022              : !!
    1023              : !! INPUTS
    1024              : !!  comm= MPI communicator
    1025              : !!
    1026              : !! OUTPUT
    1027              : !!  ier= exit status, a non-zero value meaning there is an error
    1028              : !!
    1029              : !! SIDE EFFECTS
    1030              : !!  xval= buffer array
    1031              : !!
    1032              : !! SOURCE
    1033              : 
    1034            0 : subroutine xmpi_sum_sp2d(xval,comm,ier)
    1035              : 
    1036              : !Arguments-------------------------
    1037              :  real(sp), DEV_CONTARRD intent(inout) :: xval(:,:)
    1038              :  integer ,intent(in) :: comm
    1039              :  integer ,intent(out) :: ier
    1040              : 
    1041              : !Local variables-------------------
    1042              : #if defined HAVE_MPI
    1043              :  integer :: my_dt,my_op,n1,n2,nn,nproc_space_comm
    1044              :  integer(kind=int64) :: ntot
    1045            0 :  real(sp),allocatable :: xsum(:,:)
    1046              : #endif
    1047              : ! *************************************************************************
    1048              : 
    1049            0 :  ier=0
    1050              : #if defined HAVE_MPI
    1051            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1052            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    1053            0 :    if (nproc_space_comm /= 1) then
    1054            0 :      n1 = size(xval,dim=1)
    1055            0 :      n2 = size(xval,dim=2)
    1056              : 
    1057              :      !This product of dimensions can be greater than a 32bit integer
    1058              :      !We use a INT64 to store it. If it is too large, we switch to an
    1059              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    1060            0 :      ntot=int(n1,kind=int64)*n2
    1061            0 :      if (ntot<=xmpi_maxint32_64) then
    1062            0 :        nn=n1*n2 ; my_dt=MPI_REAL ; my_op=MPI_SUM
    1063              :      else
    1064            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_REAL,my_dt,my_op,MPI_SUM)
    1065              :      end if
    1066              : 
    1067              : !    Accumulate xval on all proc. in comm
    1068              : #if defined HAVE_MPI2_INPLACE
    1069            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    1070              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    1071            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1072              :      else
    1073              : #endif
    1074            0 :        ABI_STAT_MALLOC(xsum,(n1,n2), ier)
    1075            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_sp2d')
    1076            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1077            0 :        xval (:,:) = xsum(:,:)
    1078            0 :        ABI_FREE(xsum)
    1079              : #if defined HAVE_MPI2_INPLACE
    1080              :     end if
    1081              : #endif
    1082              : 
    1083            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    1084              :    end if
    1085              :  end if
    1086              : #endif
    1087              : 
    1088            0 : end subroutine xmpi_sum_sp2d
    1089              : !!***
    1090              : 
    1091              : !> wrapper arround xmpi_sum_sp2d than can be called in C/CUDA
    1092            0 : subroutine xmpi_sum_sp2d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_sp2d_c")
    1093              : 
    1094              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    1095              :   implicit none
    1096              : 
    1097              :   ! dummy args
    1098              :   type(c_ptr),                    intent(inout) :: xval_ptr
    1099              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(2)
    1100              :   integer(kind=c_int32_t),        intent(in)    :: comm
    1101              :   integer(kind=c_int32_t),        intent(out)   :: ier
    1102              : 
    1103              :   ! local vars
    1104              :   real(sp), pointer :: xval(:,:) => null()
    1105              : 
    1106              :   ! convert the c pointer into a fortran array
    1107            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    1108              : 
    1109            0 :   call xmpi_sum_sp2d(xval, comm, ier)
    1110              : 
    1111            0 : end subroutine xmpi_sum_sp2d_c
    1112              : 
    1113              : !----------------------------------------------------------------------
    1114              : 
    1115              : !!****f* ABINIT/xmpi_sum_sp3d
    1116              : !! NAME
    1117              : !!  xmpi_sum_sp3d
    1118              : !!
    1119              : !! FUNCTION
    1120              : !!  Combines values from all processes and distribute
    1121              : !!  the result back to all processes.
    1122              : !!  Target: double precision three-dimensional arrays.
    1123              : !!
    1124              : !! INPUTS
    1125              : !!  comm= MPI communicator
    1126              : !!
    1127              : !! OUTPUT
    1128              : !!  ier= exit status, a non-zero value meaning there is an error
    1129              : !!
    1130              : !! SIDE EFFECTS
    1131              : !!  xval= buffer array
    1132              : !!
    1133              : !! SOURCE
    1134              : 
    1135            0 : subroutine xmpi_sum_sp3d(xval,comm,ier)
    1136              : 
    1137              : !Arguments-------------------------
    1138              :  real(sp), DEV_CONTARRD intent(inout) :: xval(:,:,:)
    1139              :  integer ,intent(in) :: comm
    1140              :  integer ,intent(out)   :: ier
    1141              : 
    1142              : !Local variables-------------------
    1143              : #if defined HAVE_MPI
    1144              :  integer :: my_dt,my_op,n1,n2,n3,nn,nproc_space_comm
    1145              :  integer(kind=int64) :: ntot
    1146            0 :  real(sp),allocatable :: xsum(:,:,:)
    1147              : #endif
    1148              : ! *************************************************************************
    1149              : 
    1150            0 :  ier=0
    1151              : #if defined HAVE_MPI
    1152            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1153            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    1154            0 :    if (nproc_space_comm /= 1) then
    1155            0 :      n1 = size(xval,dim=1)
    1156            0 :      n2 = size(xval,dim=2)
    1157            0 :      n3 = size(xval,dim=3)
    1158              : 
    1159              :      !This product of dimensions can be greater than a 32bit integer
    1160              :      !We use a INT64 to store it. If it is too large, we switch to an
    1161              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    1162            0 :      ntot=int(n1,kind=int64)*n2*n3
    1163            0 :      if (ntot<=xmpi_maxint32_64) then
    1164            0 :        nn=n1*n2*n3 ; my_dt=MPI_REAL ; my_op=MPI_SUM
    1165              :      else
    1166            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_REAL,my_dt,my_op,MPI_SUM)
    1167              :      end if
    1168              : 
    1169              : !    Accumulate xval on all proc. in comm
    1170              : #if defined HAVE_MPI2_INPLACE
    1171            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    1172              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    1173            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1174              :      else
    1175              : #endif
    1176            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3), ier)
    1177            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_sp3d')
    1178            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1179            0 :        xval (:,:,:) = xsum(:,:,:)
    1180            0 :        ABI_FREE(xsum)
    1181              : #if defined HAVE_MPI2_INPLACE
    1182              :      end if
    1183              : #endif
    1184              : 
    1185            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    1186              :    end if
    1187              :  end if
    1188              : #endif
    1189              : 
    1190            0 : end subroutine xmpi_sum_sp3d
    1191              : !!***
    1192              : 
    1193              : !> wrapper arround xmpi_sum_sp3d than can be called in C/CUDA
    1194            0 : subroutine xmpi_sum_sp3d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_sp3d_c")
    1195              : 
    1196              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    1197              :   implicit none
    1198              : 
    1199              :   ! dummy args
    1200              :   type(c_ptr),                    intent(inout) :: xval_ptr
    1201              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(3)
    1202              :   integer(kind=c_int32_t),        intent(in)    :: comm
    1203              :   integer(kind=c_int32_t),        intent(out)   :: ier
    1204              : 
    1205              :   ! local vars
    1206              :   real(sp), pointer :: xval(:,:,:) => null()
    1207              : 
    1208              :   ! convert the c pointer into a fortran array
    1209            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    1210              : 
    1211            0 :   call xmpi_sum_sp3d(xval, comm, ier)
    1212              : 
    1213            0 : end subroutine xmpi_sum_sp3d_c
    1214              : 
    1215              : !----------------------------------------------------------------------
    1216              : 
    1217              : !!****f* ABINIT/xmpi_sum_sp4d
    1218              : !! NAME
    1219              : !!  xmpi_sum_sp4d
    1220              : !!
    1221              : !! FUNCTION
    1222              : !!  Combines values from all processes and distribute
    1223              : !!  the result back to all processes.
    1224              : !!  Target: double precision four-dimensional arrays.
    1225              : !!
    1226              : !! INPUTS
    1227              : !!  comm= MPI communicator
    1228              : !!
    1229              : !! OUTPUT
    1230              : !!  ier= exit status, a non-zero value meaning there is an error
    1231              : !!
    1232              : !! SIDE EFFECTS
    1233              : !!  xval= buffer array
    1234              : !!
    1235              : !! SOURCE
    1236            0 : subroutine xmpi_sum_sp4d(xval,comm,ier)
    1237              : 
    1238              : !Arguments-------------------------
    1239              :  real(sp),DEV_CONTARRD intent(inout) :: xval(:,:,:,:)
    1240              :  integer ,intent(in) :: comm
    1241              :  integer ,intent(out) :: ier
    1242              : 
    1243              : !Local variables-------------------
    1244              : #if defined HAVE_MPI
    1245              :  integer :: my_dt,my_op,n1,n2,n3,n4,nn,nproc_space_comm
    1246              :  integer(kind=int64) :: ntot
    1247            0 :  real(sp),allocatable :: xsum(:,:,:,:)
    1248              : #endif
    1249              : ! *************************************************************************
    1250              : 
    1251            0 :  ier=0
    1252              : #if defined HAVE_MPI
    1253            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1254            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    1255            0 :    if (nproc_space_comm /= 1) then
    1256            0 :      n1 = size(xval,dim=1)
    1257            0 :      n2 = size(xval,dim=2)
    1258            0 :      n3 = size(xval,dim=3)
    1259            0 :      n4 = size(xval,dim=4)
    1260              : 
    1261              :      !This product of dimensions can be greater than a 32bit integer
    1262              :      !We use a INT64 to store it. If it is too large, we switch to an
    1263              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    1264            0 :      ntot=int(n1,kind=int64)*n2*n3*n4
    1265            0 :      if (ntot<=xmpi_maxint32_64) then
    1266            0 :        nn=n1*n2*n3*n4 ; my_dt=MPI_REAL ; my_op=MPI_SUM
    1267              :      else
    1268            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_REAL,my_dt,my_op,MPI_SUM)
    1269              :      end if
    1270              : 
    1271              : !    Accumulate xval on all proc. in comm
    1272              : #if defined HAVE_MPI2_INPLACE
    1273            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    1274              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    1275            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1276              :      else
    1277              : #endif
    1278            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4), ier)
    1279            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_sp4d')
    1280            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1281            0 :        xval (:,:,:,:) = xsum(:,:,:,:)
    1282            0 :        ABI_FREE(xsum)
    1283              : #if defined HAVE_MPI2_INPLACE
    1284              :      endif
    1285              : #endif
    1286              : 
    1287            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    1288              :    end if
    1289              :  end if
    1290              : #endif
    1291              : 
    1292            0 : end subroutine xmpi_sum_sp4d
    1293              : !!***
    1294              : 
    1295              : !> wrapper arround xmpi_sum_sp4d than can be called in C/CUDA
    1296            0 : subroutine xmpi_sum_sp4d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_sp4d_c")
    1297              : 
    1298              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    1299              :   implicit none
    1300              : 
    1301              :   ! dummy args
    1302              :   type(c_ptr),                    intent(inout) :: xval_ptr
    1303              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(4)
    1304              :   integer(kind=c_int32_t),        intent(in)    :: comm
    1305              :   integer(kind=c_int32_t),        intent(out)   :: ier
    1306              : 
    1307              :   ! local vars
    1308              :   real(sp), pointer :: xval(:,:,:,:) => null()
    1309              : 
    1310              :   ! convert the c pointer into a fortran array
    1311            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    1312              : 
    1313            0 :   call xmpi_sum_sp4d(xval, comm, ier)
    1314              : 
    1315            0 : end subroutine xmpi_sum_sp4d_c
    1316              : 
    1317              : !----------------------------------------------------------------------
    1318              : 
    1319              : !!****f* ABINIT/xmpi_sum_sp5d
    1320              : !! NAME
    1321              : !!  xmpi_sum_sp5d
    1322              : !!
    1323              : !! FUNCTION
    1324              : !!  Combines values from all processes and distribute
    1325              : !!  the result back to all processes.
    1326              : !!  Target: double precision five-dimensional arrays.
    1327              : !!
    1328              : !! INPUTS
    1329              : !!  comm= MPI communicator
    1330              : !!
    1331              : !! OUTPUT
    1332              : !!  ier= exit status, a non-zero value meaning there is an error
    1333              : !!
    1334              : !! SIDE EFFECTS
    1335              : !!  xval= buffer array
    1336              : !!
    1337              : !! SOURCE
    1338            0 : subroutine xmpi_sum_sp5d(xval,comm,ier)
    1339              : 
    1340              : !Arguments-------------------------
    1341              :  real(sp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:)
    1342              :  integer ,intent(in) :: comm
    1343              :  integer ,intent(out) :: ier
    1344              : 
    1345              : !Local variables-------------------
    1346              : #if defined HAVE_MPI
    1347              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,nn,nproc_space_comm
    1348              :  integer(kind=int64) :: ntot
    1349            0 :  real(sp),allocatable :: xsum(:,:,:,:,:)
    1350              : #endif
    1351              : ! *************************************************************************
    1352              : 
    1353            0 :  ier=0
    1354              : #if defined HAVE_MPI
    1355            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1356            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    1357            0 :    if (nproc_space_comm /= 1) then
    1358            0 :      n1 = size(xval,dim=1)
    1359            0 :      n2 = size(xval,dim=2)
    1360            0 :      n3 = size(xval,dim=3)
    1361            0 :      n4 = size(xval,dim=4)
    1362            0 :      n5 = size(xval,dim=5)
    1363              : 
    1364              :      !This product of dimensions can be greater than a 32bit integer
    1365              :      !We use a INT64 to store it. If it is too large, we switch to an
    1366              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    1367            0 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5
    1368            0 :      if (ntot<=xmpi_maxint32_64) then
    1369            0 :        nn=n1*n2*n3*n4*n5 ; my_dt=MPI_REAL ; my_op=MPI_SUM
    1370              :      else
    1371            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_REAL,my_dt,my_op,MPI_SUM)
    1372              :      end if
    1373              : 
    1374              : !    Accumulate xval on all proc. in comm
    1375              : #if defined HAVE_MPI2_INPLACE
    1376            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    1377              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    1378            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1379              :      else
    1380              : #endif
    1381            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5), ier)
    1382            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_sp5d')
    1383            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1384            0 :        xval (:,:,:,:,:) = xsum(:,:,:,:,:)
    1385            0 :        ABI_FREE(xsum)
    1386              : #if defined HAVE_MPI2_INPLACE
    1387              :      endif
    1388              : #endif
    1389              : 
    1390            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    1391              :    end if
    1392              :  end if
    1393              : #endif
    1394              : 
    1395            0 : end subroutine xmpi_sum_sp5d
    1396              : !!***
    1397              : 
    1398              : !> wrapper arround xmpi_sum_sp5d than can be called in C/CUDA
    1399            0 : subroutine xmpi_sum_sp5d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_sp5d_c")
    1400              : 
    1401              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    1402              :   implicit none
    1403              : 
    1404              :   ! dummy args
    1405              :   type(c_ptr),                    intent(inout) :: xval_ptr
    1406              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(5)
    1407              :   integer(kind=c_int32_t),        intent(in)    :: comm
    1408              :   integer(kind=c_int32_t),        intent(out)   :: ier
    1409              : 
    1410              :   ! local vars
    1411              :   real(sp), pointer :: xval(:,:,:,:,:) => null()
    1412              : 
    1413              :   ! convert the c pointer into a fortran array
    1414            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    1415              : 
    1416            0 :   call xmpi_sum_sp5d(xval, comm, ier)
    1417              : 
    1418            0 : end subroutine xmpi_sum_sp5d_c
    1419              : 
    1420              : !----------------------------------------------------------------------
    1421              : 
    1422              : !!****f* ABINIT/xmpi_sum_sp6d
    1423              : !! NAME
    1424              : !!  xmpi_sum_sp6d
    1425              : !!
    1426              : !! FUNCTION
    1427              : !!  Combines values from all processes and distribute
    1428              : !!  the result back to all processes.
    1429              : !!  Target: double precision six-dimensional arrays.
    1430              : !!
    1431              : !! INPUTS
    1432              : !!  comm= MPI communicator
    1433              : !!
    1434              : !! OUTPUT
    1435              : !!  ier= exit status, a non-zero value meaning there is an error
    1436              : !!
    1437              : !! SIDE EFFECTS
    1438              : !!  xval= buffer array
    1439              : !!
    1440              : !! SOURCE
    1441            0 : subroutine xmpi_sum_sp6d(xval,comm,ier)
    1442              : 
    1443              : !Arguments-------------------------
    1444              :  real(sp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:,:)
    1445              :  integer ,intent(in) :: comm
    1446              :  integer ,intent(out) :: ier
    1447              : 
    1448              : !Local variables-------------------
    1449              : #if defined HAVE_MPI
    1450              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,n6,nn,nproc_space_comm
    1451              :  integer(kind=int64) :: ntot
    1452            0 :  real(sp), allocatable :: xsum(:,:,:,:,:,:)
    1453              : #endif
    1454              : ! *************************************************************************
    1455              : 
    1456            0 :  ier=0
    1457              : #if defined HAVE_MPI
    1458            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1459            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    1460            0 :    if (nproc_space_comm /= 1) then
    1461            0 :      n1 = size(xval,dim=1)
    1462            0 :      n2 = size(xval,dim=2)
    1463            0 :      n3 = size(xval,dim=3)
    1464            0 :      n4 = size(xval,dim=4)
    1465            0 :      n5 = size(xval,dim=5)
    1466            0 :      n6 = size(xval,dim=6)
    1467              : 
    1468              :      !This product of dimensions can be greater than a 32bit integer
    1469              :      !We use a INT64 to store it. If it is too large, we switch to an
    1470              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    1471            0 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5*n6
    1472            0 :      if (ntot<=xmpi_maxint32_64) then
    1473            0 :        nn=n1*n2*n3*n4*n5*n6 ; my_dt=MPI_REAL ; my_op=MPI_SUM
    1474              :      else
    1475            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_REAL,my_dt,my_op,MPI_SUM)
    1476              :      end if
    1477              : 
    1478              : !    Accumulate xval on all proc. in comm
    1479              : #if defined HAVE_MPI2_INPLACE
    1480            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    1481              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    1482            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1483              :      else
    1484              : #endif
    1485            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5,n6), ier)
    1486            0 :        if (ier/=0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_sp6d')
    1487            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1488            0 :        xval (:,:,:,:,:,:) = xsum(:,:,:,:,:,:)
    1489            0 :        ABI_FREE(xsum)
    1490              : #if defined HAVE_MPI2_INPLACE
    1491              :      end if
    1492              : #endif
    1493              : 
    1494            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    1495              :    end if
    1496              :  end if
    1497              : #endif
    1498              : 
    1499            0 : end subroutine xmpi_sum_sp6d
    1500              : !!***
    1501              : 
    1502              : !> wrapper arround xmpi_sum_sp6d than can be called in C/CUDA
    1503            0 : subroutine xmpi_sum_sp6d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_sp6d_c")
    1504              : 
    1505              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    1506              :   implicit none
    1507              : 
    1508              :   ! dummy args
    1509              :   type(c_ptr),                    intent(inout) :: xval_ptr
    1510              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(6)
    1511              :   integer(kind=c_int32_t),        intent(in)    :: comm
    1512              :   integer(kind=c_int32_t),        intent(out)   :: ier
    1513              : 
    1514              :   ! local vars
    1515              :   real(sp), pointer :: xval(:,:,:,:,:,:) => null()
    1516              : 
    1517              :   ! convert the c pointer into a fortran array
    1518            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    1519              : 
    1520            0 :   call xmpi_sum_sp6d(xval, comm, ier)
    1521              : 
    1522            0 : end subroutine xmpi_sum_sp6d_c
    1523              : 
    1524              : !----------------------------------------------------------------------
    1525              : 
    1526              : !!****f* ABINIT/xmpi_sum_sp7d
    1527              : !! NAME
    1528              : !!  xmpi_sum_sp7d
    1529              : !!
    1530              : !! FUNCTION
    1531              : !!  Combines values from all processes and distribute
    1532              : !!  the result back to all processes.
    1533              : !!  Target: double precision six-dimensional arrays.
    1534              : !!
    1535              : !! INPUTS
    1536              : !!  comm= MPI communicator
    1537              : !!
    1538              : !! OUTPUT
    1539              : !!  ier= exit status, a non-zero value meaning there is an error
    1540              : !!
    1541              : !! SIDE EFFECTS
    1542              : !!  xval= buffer array
    1543              : !!
    1544              : !! SOURCE
    1545            0 : subroutine xmpi_sum_sp7d(xval,comm,ier)
    1546              : 
    1547              : !Arguments-------------------------
    1548              :  real(sp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:,:,:)
    1549              :  integer ,intent(in) :: comm
    1550              :  integer ,intent(out) :: ier
    1551              : 
    1552              : !Local variables-------------------
    1553              : #if defined HAVE_MPI
    1554              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,n6,n7,nn,nproc_space_comm
    1555              :  integer(kind=int64) :: ntot
    1556            0 :  real(sp),allocatable :: xsum(:,:,:,:,:,:,:)
    1557              : #endif
    1558              : ! *************************************************************************
    1559            0 :  ier=0
    1560              : #if defined HAVE_MPI
    1561            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1562            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    1563            0 :    if (nproc_space_comm /= 1) then
    1564            0 :      n1 = size(xval,dim=1)
    1565            0 :      n2 = size(xval,dim=2)
    1566            0 :      n3 = size(xval,dim=3)
    1567            0 :      n4 = size(xval,dim=4)
    1568            0 :      n5 = size(xval,dim=5)
    1569            0 :      n6 = size(xval,dim=6)
    1570            0 :      n7 = size(xval,dim=7)
    1571              : 
    1572              :      !This product of dimensions can be greater than a 32bit integer
    1573              :      !We use a INT64 to store it. If it is too large, we switch to an
    1574              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    1575            0 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5*n6*n7
    1576            0 :      if (ntot<=xmpi_maxint32_64) then
    1577            0 :        nn=n1*n2*n3*n4*n5*n6*n7 ; my_dt=MPI_REAL ; my_op=MPI_SUM
    1578              :      else
    1579            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_REAL,my_dt,my_op,MPI_SUM)
    1580              :      end if
    1581              : 
    1582              : !    Accumulate xval on all proc. in comm
    1583              : #if defined HAVE_MPI2_INPLACE
    1584            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    1585              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    1586            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1587              :      else
    1588              : #endif
    1589            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5,n6,n7), ier)
    1590            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_sp7d')
    1591            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1592            0 :        xval (:,:,:,:,:,:,:) = xsum(:,:,:,:,:,:,:)
    1593            0 :        ABI_FREE(xsum)
    1594              : #if defined HAVE_MPI2_INPLACE
    1595              :      endif
    1596              : #endif
    1597              : 
    1598            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    1599              :    end if
    1600              :  end if
    1601              : #endif
    1602              : 
    1603            0 : end subroutine xmpi_sum_sp7d
    1604              : !!***
    1605              : 
    1606              : !> wrapper arround xmpi_sum_sp7d than can be called in C/CUDA
    1607            0 : subroutine xmpi_sum_sp7d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_sp7d_c")
    1608              : 
    1609              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    1610              :   implicit none
    1611              : 
    1612              :   ! dummy args
    1613              :   type(c_ptr),                    intent(inout) :: xval_ptr
    1614              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(7)
    1615              :   integer(kind=c_int32_t),        intent(in)    :: comm
    1616              :   integer(kind=c_int32_t),        intent(out)   :: ier
    1617              : 
    1618              :   ! local vars
    1619              :   real(sp), pointer :: xval(:,:,:,:,:,:,:) => null()
    1620              : 
    1621              :   ! convert the c pointer into a fortran array
    1622            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    1623              : 
    1624            0 :   call xmpi_sum_sp7d(xval, comm, ier)
    1625              : 
    1626            0 : end subroutine xmpi_sum_sp7d_c
    1627              : 
    1628              : 
    1629              : !----------------------------------------------------------------------
    1630              : 
    1631              : !!****f* ABINIT/xmpi_sum_dp2d
    1632              : !! NAME
    1633              : !!  xmpi_sum_dp2d
    1634              : !!
    1635              : !! FUNCTION
    1636              : !!  Combines values from all processes and distribute
    1637              : !!  the result back to all processes.
    1638              : !!  Target: double precision two-dimensional arrays.
    1639              : !!
    1640              : !! INPUTS
    1641              : !!  comm= MPI communicator
    1642              : !!  use_omp_map= wether to use OpenMP GPU mapping (fefault: false)
    1643              : !!
    1644              : !! OUTPUT
    1645              : !!  ier= exit status, a non-zero value meaning there is an error
    1646              : !!
    1647              : !! SIDE EFFECTS
    1648              : !!  xval= buffer array
    1649              : !!
    1650              : !! SOURCE
    1651              : 
    1652     65943258 : subroutine xmpi_sum_dp2d(xval,comm,ier,use_omp_map)
    1653              : 
    1654              : !Arguments-------------------------
    1655              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:,:)
    1656              :  integer ,intent(in) :: comm
    1657              :  logical ,intent(in), optional :: use_omp_map
    1658              :  integer ,intent(out) :: ier
    1659              : 
    1660              : !Local variables-------------------
    1661              : #if defined HAVE_MPI
    1662              :  integer :: my_dt,my_op,n1,n2,nn,nproc_space_comm
    1663              : #ifdef HAVE_GPU_MPI
    1664              :  integer :: i1,i2
    1665              : #endif
    1666              :  logical :: l_use_omp_map
    1667              :  integer(kind=int64) :: ntot
    1668     65943258 :  real(dp),allocatable :: xsum(:,:)
    1669              : #endif
    1670              : ! *************************************************************************
    1671              : 
    1672     65943258 :  ier=0
    1673              : #if defined HAVE_MPI
    1674     65943258 :  l_use_omp_map=.false.
    1675     65943258 :  if(present(use_omp_map)) l_use_omp_map=use_omp_map
    1676     65943258 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1677      2475902 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    1678      2475902 :    if (nproc_space_comm /= 1) then
    1679      2404454 :      n1 = size(xval,dim=1)
    1680      2404454 :      n2 = size(xval,dim=2)
    1681              : 
    1682              :      !This product of dimensions can be greater than a 32bit integer
    1683              :      !We use a INT64 to store it. If it is too large, we switch to an
    1684              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    1685      2404454 :      ntot=int(n1,kind=int64)*n2
    1686      2404454 :      if (ntot<=xmpi_maxint32_64) then
    1687      2404454 :        nn=n1*n2 ; my_dt=MPI_DOUBLE_PRECISION ; my_op=MPI_SUM
    1688              :      else
    1689            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_SUM)
    1690              :      end if
    1691              : 
    1692              : !    Accumulate xval on all proc. in comm
    1693              : #if defined HAVE_MPI2_INPLACE
    1694      2404454 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    1695              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    1696      2404454 :        if(.not. l_use_omp_map) then
    1697      2404454 :          call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1698              :        else
    1699              : #ifdef HAVE_OPENMP_OFFLOAD
    1700              : #ifdef HAVE_GPU_MPI
    1701              :          ! Proper GPU-aware call
    1702              :          !$OMP TARGET DATA USE_DEVICE_ADDR(xval)
    1703              :          call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1704              :          !$OMP END TARGET DATA
    1705              : #else
    1706              :          !$OMP TARGET UPDATE FROM(xval)
    1707              :          call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1708              :          !$OMP TARGET UPDATE TO(xval)
    1709              : #endif
    1710              : #endif
    1711              :        end if
    1712              :      else
    1713              : #endif
    1714            0 :        ABI_STAT_MALLOC(xsum,(n1,n2), ier)
    1715            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_dp2d')
    1716            0 :        if(.not. l_use_omp_map) then
    1717            0 :          call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1718            0 :          xval (:,:) = xsum(:,:)
    1719              :        else
    1720              : #ifdef HAVE_OPENMP_OFFLOAD
    1721              :          !$OMP TARGET ENTER DATA MAP(alloc:xsum)
    1722              : #ifdef HAVE_GPU_MPI
    1723              :          ! Proper GPU-aware call
    1724              :          !$OMP TARGET DATA USE_DEVICE_ADDR(xval,xsum)
    1725              :          call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1726              :          !$OMP END TARGET DATA
    1727              :          !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(2) PRIVATE(i2,i1) MAP(to:xval,xsum)
    1728              :          do i2=1,n2
    1729              :            do i1=1,n1
    1730              :              xval(i1,i2)=xsum(i1,i2)
    1731              :            end do
    1732              :          end do
    1733              : #else
    1734              :          !$OMP TARGET UPDATE FROM(xval)
    1735              :          call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1736              :          xval (:,:) = xsum(:,:)
    1737              :          !$OMP TARGET UPDATE TO(xval)
    1738              : #endif
    1739              :          !$OMP TARGET EXIT DATA MAP(delete:xsum)
    1740              : #endif
    1741              :        end if
    1742            0 :        ABI_FREE(xsum)
    1743              : #if defined HAVE_MPI2_INPLACE
    1744              :      endif
    1745              : #endif
    1746              : 
    1747      2404454 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    1748              :    end if
    1749              :  end if
    1750              : #endif
    1751              : 
    1752     65943258 : end subroutine xmpi_sum_dp2d
    1753              : !!***
    1754              : 
    1755              : !> wrapper arround xmpi_sum_dp2d than can be called in C/CUDA
    1756            0 : subroutine xmpi_sum_dp2d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_dp2d_c")
    1757              : 
    1758              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    1759              :   implicit none
    1760              : 
    1761              :   ! dummy args
    1762              :   type(c_ptr),                    intent(inout) :: xval_ptr
    1763              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(2)
    1764              :   integer(kind=c_int32_t),        intent(in)    :: comm
    1765              :   integer(kind=c_int32_t),        intent(out)   :: ier
    1766              : 
    1767              :   ! local vars
    1768              :   real(dp), pointer :: xval(:,:) => null()
    1769              : 
    1770              :   ! convert the c pointer into a fortran array
    1771            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    1772              : 
    1773            0 :   call xmpi_sum_dp2d(xval, comm, ier)
    1774              : 
    1775            0 : end subroutine xmpi_sum_dp2d_c
    1776              : 
    1777              : !----------------------------------------------------------------------
    1778              : 
    1779              : !!****f* ABINIT/xmpi_sum_dp3d
    1780              : !! NAME
    1781              : !!  xmpi_sum_dp3d
    1782              : !!
    1783              : !! FUNCTION
    1784              : !!  Combines values from all processes and distribute
    1785              : !!  the result back to all processes.
    1786              : !!  Target: double precision three-dimensional arrays.
    1787              : !!
    1788              : !! INPUTS
    1789              : !!  comm= MPI communicator
    1790              : !!
    1791              : !! OUTPUT
    1792              : !!  ier= exit status, a non-zero value meaning there is an error
    1793              : !!
    1794              : !! SIDE EFFECTS
    1795              : !!  xval= buffer array
    1796              : !!
    1797              : !! SOURCE
    1798              : 
    1799      5934427 : subroutine xmpi_sum_dp3d(xval,comm,ier,use_omp_map)
    1800              : 
    1801              : !Arguments-------------------------
    1802              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:)
    1803              :  integer ,intent(in) :: comm
    1804              :  logical ,intent(in), optional :: use_omp_map
    1805              :  integer ,intent(out)   :: ier
    1806              : 
    1807              : !Local variables-------------------
    1808              : #if defined HAVE_MPI
    1809              :  integer :: my_dt,my_op,n1,n2,n3,nn,nproc_space_comm
    1810              : #ifdef HAVE_GPU_MPI
    1811              :  integer :: i1,i2,i3
    1812              : #endif
    1813              :  logical :: l_use_omp_map
    1814              :  integer(kind=int64) :: ntot
    1815      5934427 :  real(dp),allocatable :: xsum(:,:,:)
    1816              : #endif
    1817              : ! *************************************************************************
    1818              : 
    1819      5934427 :  ier=0
    1820              : #if defined HAVE_MPI
    1821      5934427 :  l_use_omp_map=.false.
    1822      5934427 :  if(present(use_omp_map)) l_use_omp_map=use_omp_map
    1823      5934427 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1824       771772 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    1825       771772 :    if (nproc_space_comm /= 1) then
    1826       116816 :      n1 = size(xval,dim=1)
    1827       116816 :      n2 = size(xval,dim=2)
    1828       116816 :      n3 = size(xval,dim=3)
    1829              : 
    1830              :      !This product of dimensions can be greater than a 32bit integer
    1831              :      !We use a INT64 to store it. If it is too large, we switch to an
    1832              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    1833       116816 :      ntot=int(n1,kind=int64)*n2*n3
    1834       116816 :      if (ntot<=xmpi_maxint32_64) then
    1835       116816 :        nn=n1*n2*n3 ; my_dt=MPI_DOUBLE_PRECISION ; my_op=MPI_SUM
    1836              :      else
    1837            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_SUM)
    1838              :      end if
    1839              : 
    1840              : !    Accumulate xval on all proc. in comm
    1841              : #if defined HAVE_MPI2_INPLACE
    1842       116816 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    1843              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    1844       116816 :        if(.not. l_use_omp_map) then
    1845       116816 :          call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1846              :        else
    1847              : #ifdef HAVE_OPENMP_OFFLOAD
    1848              : #ifdef HAVE_GPU_MPI
    1849              :          ! Proper GPU-aware call
    1850              :          !$OMP TARGET DATA USE_DEVICE_ADDR(xval)
    1851              :          call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1852              :          !$OMP END TARGET DATA
    1853              : #else
    1854              :          !$OMP TARGET UPDATE FROM(xval)
    1855              :          call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1856              :          !$OMP TARGET UPDATE TO(xval)
    1857              : #endif
    1858              : #endif
    1859              :        end if ! l_use_omp_map
    1860              :      else
    1861              : #endif
    1862            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3), ier)
    1863            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_dp3d')
    1864            0 :        if(.not. l_use_omp_map) then
    1865            0 :          call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1866            0 :          xval (:,:,:) = xsum(:,:,:)
    1867              :        else
    1868              : #ifdef HAVE_OPENMP_OFFLOAD
    1869              :          !$OMP TARGET ENTER DATA MAP(alloc:xsum)
    1870              : #ifdef HAVE_GPU_MPI
    1871              :          ! Proper GPU-aware call
    1872              :          !$OMP TARGET DATA USE_DEVICE_ADDR(xval,xsum)
    1873              :          call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1874              :          !$OMP END TARGET DATA
    1875              :          !$OMP TARGET TEAMS DISTRIBUTE PRIVATE(i3) MAP(to:xval,xsum)
    1876              :          do i3=1,n3
    1877              :            !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(i2,i1)
    1878              :            do i2=1,n2
    1879              :              do i1=1,n1
    1880              :                xval(i1,i2,i3)=xsum(i1,i2,i3)
    1881              :              end do
    1882              :            end do
    1883              :          end do
    1884              : #else
    1885              :          !$OMP TARGET UPDATE FROM(xval)
    1886              :          call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1887              :          xval (:,:,:) = xsum(:,:,:)
    1888              :          !$OMP TARGET UPDATE TO(xval)
    1889              : #endif
    1890              :          !$OMP TARGET EXIT DATA MAP(delete:xsum)
    1891              : #endif
    1892              :        end if ! l_use_omp_map
    1893            0 :        ABI_FREE(xsum)
    1894              : #if defined HAVE_MPI2_INPLACE
    1895              :      endif
    1896              : #endif
    1897              : 
    1898       116816 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    1899              :    end if
    1900              :  end if
    1901              : #endif
    1902              : 
    1903      5934427 : end subroutine xmpi_sum_dp3d
    1904              : !!***
    1905              : 
    1906              : !> wrapper arround xmpi_sum_dp3d than can be called in C/CUDA
    1907            0 : subroutine xmpi_sum_dp3d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_dp3d_c")
    1908              : 
    1909              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    1910              :   implicit none
    1911              : 
    1912              :   ! dummy args
    1913              :   type(c_ptr),                    intent(inout) :: xval_ptr
    1914              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(3)
    1915              :   integer(kind=c_int32_t),        intent(in)    :: comm
    1916              :   integer(kind=c_int32_t),        intent(out)   :: ier
    1917              : 
    1918              :   ! local vars
    1919              :   real(dp), pointer :: xval(:,:,:) => null()
    1920              : 
    1921              :   ! convert the c pointer into a fortran array
    1922            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    1923              : 
    1924            0 :   call xmpi_sum_dp3d(xval, comm, ier)
    1925              : 
    1926            0 : end subroutine xmpi_sum_dp3d_c
    1927              : 
    1928              : !----------------------------------------------------------------------
    1929              : 
    1930              : !!****f* ABINIT/xmpi_sum_dp4d
    1931              : !! NAME
    1932              : !!  xmpi_sum_dp4d
    1933              : !!
    1934              : !! FUNCTION
    1935              : !!  Combines values from all processes and distribute
    1936              : !!  the result back to all processes.
    1937              : !!  Target: double precision four-dimensional arrays.
    1938              : !!
    1939              : !! INPUTS
    1940              : !!  comm= MPI communicator
    1941              : !!
    1942              : !! OUTPUT
    1943              : !!  ier= exit status, a non-zero value meaning there is an error
    1944              : !!
    1945              : !! SIDE EFFECTS
    1946              : !!  xval= buffer array
    1947              : !!
    1948              : !! SOURCE
    1949              : 
    1950       525337 : subroutine xmpi_sum_dp4d(xval,comm,ier)
    1951              : 
    1952              : !Arguments-------------------------
    1953              :  real(dp),DEV_CONTARRD intent(inout) :: xval(:,:,:,:)
    1954              :  integer ,intent(in) :: comm
    1955              :  integer ,intent(out) :: ier
    1956              : 
    1957              : !Local variables-------------------
    1958              : #if defined HAVE_MPI
    1959              :  integer :: my_dt,my_op,n1,n2,n3,n4,nn,nproc_space_comm
    1960              :  integer(kind=int64) :: ntot
    1961       525337 :  real(dp),allocatable :: xsum(:,:,:,:)
    1962              : #endif
    1963              : ! *************************************************************************
    1964              : 
    1965       525337 :  ier=0
    1966              : #if defined HAVE_MPI
    1967       525337 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1968       521335 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    1969       521335 :    if (nproc_space_comm /= 1) then
    1970       520266 :      n1 = size(xval,dim=1)
    1971       520266 :      n2 = size(xval,dim=2)
    1972       520266 :      n3 = size(xval,dim=3)
    1973       520266 :      n4 = size(xval,dim=4)
    1974              : 
    1975              :      !This product of dimensions can be greater than a 32bit integer
    1976              :      !We use a INT64 to store it. If it is too large, we switch to an
    1977              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    1978       520266 :      ntot=int(n1,kind=int64)*n2*n3*n4
    1979       520266 :      if (ntot<=xmpi_maxint32_64) then
    1980       520266 :        nn=n1*n2*n3*n4 ; my_dt=MPI_DOUBLE_PRECISION ; my_op=MPI_SUM
    1981              :      else
    1982            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_SUM)
    1983              :      end if
    1984              : 
    1985              : !    Accumulate xval on all proc. in comm
    1986              : #if defined HAVE_MPI2_INPLACE
    1987       520266 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    1988              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    1989       520266 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    1990              :      else
    1991              : #endif
    1992            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4), ier)
    1993            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_dp4d')
    1994            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    1995            0 :        xval (:,:,:,:) = xsum(:,:,:,:)
    1996            0 :        ABI_FREE(xsum)
    1997              : #if defined HAVE_MPI2_INPLACE
    1998              :      endif
    1999              : #endif
    2000              : 
    2001       520266 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    2002              :    end if
    2003              :  end if
    2004              : #endif
    2005              : 
    2006       525337 : end subroutine xmpi_sum_dp4d
    2007              : !!***
    2008              : 
    2009              : !> wrapper arround xmpi_sum_dp4d than can be called in C/CUDA
    2010            0 : subroutine xmpi_sum_dp4d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_dp4d_c")
    2011              : 
    2012              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    2013              :   implicit none
    2014              : 
    2015              :   ! dummy args
    2016              :   type(c_ptr),                    intent(inout) :: xval_ptr
    2017              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(4)
    2018              :   integer(kind=c_int32_t),        intent(in)    :: comm
    2019              :   integer(kind=c_int32_t),        intent(out)   :: ier
    2020              : 
    2021              :   ! local vars
    2022              :   real(dp), pointer :: xval(:,:,:,:) => null()
    2023              : 
    2024              :   ! convert the c pointer into a fortran array
    2025            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    2026              : 
    2027            0 :   call xmpi_sum_dp4d(xval, comm, ier)
    2028              : 
    2029            0 : end subroutine xmpi_sum_dp4d_c
    2030              : 
    2031              : !----------------------------------------------------------------------
    2032              : 
    2033              : !!****f* ABINIT/xmpi_sum_dp5d
    2034              : !! NAME
    2035              : !!  xmpi_sum_dp5d
    2036              : !!
    2037              : !! FUNCTION
    2038              : !!  Combines values from all processes and distribute
    2039              : !!  the result back to all processes.
    2040              : !!  Target: double precision five-dimensional arrays.
    2041              : !!
    2042              : !! INPUTS
    2043              : !!  comm= MPI communicator
    2044              : !!
    2045              : !! OUTPUT
    2046              : !!  ier= exit status, a non-zero value meaning there is an error
    2047              : !!
    2048              : !! SIDE EFFECTS
    2049              : !!  xval= buffer array
    2050              : !!
    2051              : !! SOURCE
    2052              : 
    2053     87167386 : subroutine xmpi_sum_dp5d(xval,comm,ier)
    2054              : 
    2055              : !Arguments-------------------------
    2056              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:)
    2057              :  integer ,intent(in) :: comm
    2058              :  integer ,intent(out) :: ier
    2059              : 
    2060              : !Local variables-------------------
    2061              : #if defined HAVE_MPI
    2062              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,nn,nproc_space_comm
    2063              :  integer(kind=int64) :: ntot
    2064     87167386 :  real(dp),allocatable :: xsum(:,:,:,:,:)
    2065              : #endif
    2066              : ! *************************************************************************
    2067              : 
    2068     87167386 :  ier=0
    2069              : #if defined HAVE_MPI
    2070     87167386 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2071      1951190 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    2072      1951190 :    if (nproc_space_comm /= 1) then
    2073       601586 :      n1 = size(xval,dim=1)
    2074       601586 :      n2 = size(xval,dim=2)
    2075       601586 :      n3 = size(xval,dim=3)
    2076       601586 :      n4 = size(xval,dim=4)
    2077       601586 :      n5 = size(xval,dim=5)
    2078              : 
    2079              :      !This product of dimensions can be greater than a 32bit integer
    2080              :      !We use a INT64 to store it. If it is too large, we switch to an
    2081              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    2082       601586 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5
    2083       601586 :      if (ntot<=xmpi_maxint32_64) then
    2084       601586 :        nn=n1*n2*n3*n4*n5 ; my_dt=MPI_DOUBLE_PRECISION ; my_op=MPI_SUM
    2085              :      else
    2086            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_SUM)
    2087              :      end if
    2088              : 
    2089              : !    Accumulate xval on all proc. in comm
    2090              : #if defined HAVE_MPI2_INPLACE
    2091       601586 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    2092              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    2093       601586 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    2094              :      else
    2095              : #endif
    2096            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5), ier)
    2097            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_dp5d')
    2098            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    2099            0 :        xval (:,:,:,:,:) = xsum(:,:,:,:,:)
    2100            0 :        ABI_FREE(xsum)
    2101              : #if defined HAVE_MPI2_INPLACE
    2102              :      endif
    2103              : #endif
    2104              : 
    2105       601586 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    2106              :    end if
    2107              :  end if
    2108              : #endif
    2109              : 
    2110     87167386 : end subroutine xmpi_sum_dp5d
    2111              : !!***
    2112              : 
    2113              : !> wrapper arround xmpi_sum_dp5d than can be called in C/CUDA
    2114            0 : subroutine xmpi_sum_dp5d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_dp5d_c")
    2115              : 
    2116              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    2117              :   implicit none
    2118              : 
    2119              :   ! dummy args
    2120              :   type(c_ptr),                    intent(inout) :: xval_ptr
    2121              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(5)
    2122              :   integer(kind=c_int32_t),        intent(in)    :: comm
    2123              :   integer(kind=c_int32_t),        intent(out)   :: ier
    2124              : 
    2125              :   ! local vars
    2126              :   real(dp), pointer :: xval(:,:,:,:,:) => null()
    2127              : 
    2128              :   ! convert the c pointer into a fortran array
    2129            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    2130              : 
    2131            0 :   call xmpi_sum_dp5d(xval, comm, ier)
    2132              : 
    2133            0 : end subroutine xmpi_sum_dp5d_c
    2134              : 
    2135              : !----------------------------------------------------------------------
    2136              : 
    2137              : !!****f* ABINIT/xmpi_sum_dp6d
    2138              : !! NAME
    2139              : !!  xmpi_sum_dp6d
    2140              : !!
    2141              : !! FUNCTION
    2142              : !!  Combines values from all processes and distribute
    2143              : !!  the result back to all processes.
    2144              : !!  Target: double precision six-dimensional arrays.
    2145              : !!
    2146              : !! INPUTS
    2147              : !!  comm= MPI communicator
    2148              : !!
    2149              : !! OUTPUT
    2150              : !!  ier= exit status, a non-zero value meaning there is an error
    2151              : !!
    2152              : !! SIDE EFFECTS
    2153              : !!  xval= buffer array
    2154              : !!
    2155              : !! SOURCE
    2156      6998811 : subroutine xmpi_sum_dp6d(xval,comm,ier)
    2157              : 
    2158              : !Arguments-------------------------
    2159              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:,:)
    2160              :  integer ,intent(in) :: comm
    2161              :  integer ,intent(out) :: ier
    2162              : 
    2163              : !Local variables-------------------
    2164              : #if defined HAVE_MPI
    2165              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,n6,nn,nproc_space_comm
    2166              :  integer(kind=int64) :: ntot
    2167      6998811 :  real(dp), allocatable :: xsum(:,:,:,:,:,:)
    2168              : #endif
    2169              : ! *************************************************************************
    2170              : 
    2171      6998811 :  ier=0
    2172              : #if defined HAVE_MPI
    2173      6998811 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2174        33582 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    2175        33582 :    if (nproc_space_comm /= 1) then
    2176        11758 :      n1 = size(xval,dim=1)
    2177        11758 :      n2 = size(xval,dim=2)
    2178        11758 :      n3 = size(xval,dim=3)
    2179        11758 :      n4 = size(xval,dim=4)
    2180        11758 :      n5 = size(xval,dim=5)
    2181        11758 :      n6 = size(xval,dim=6)
    2182              : 
    2183              :      !This product of dimensions can be greater than a 32bit integer
    2184              :      !We use a INT64 to store it. If it is too large, we switch to an
    2185              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    2186        11758 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5*n6
    2187        11758 :      if (ntot<=xmpi_maxint32_64) then
    2188        11758 :        nn=n1*n2*n3*n4*n5*n6 ; my_dt=MPI_DOUBLE_PRECISION ; my_op=MPI_SUM
    2189              :      else
    2190            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_SUM)
    2191              :      end if
    2192              : 
    2193              : !    Accumulate xval on all proc. in comm
    2194              : #if defined HAVE_MPI2_INPLACE
    2195        11758 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    2196              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    2197        11758 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    2198              :      else
    2199              : #endif
    2200            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5,n6), ier)
    2201            0 :        if (ier/=0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_dp6d')
    2202            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    2203            0 :        xval (:,:,:,:,:,:) = xsum(:,:,:,:,:,:)
    2204            0 :        ABI_FREE(xsum)
    2205              : #if defined HAVE_MPI2_INPLACE
    2206              :      endif
    2207              : #endif
    2208              : 
    2209        11758 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    2210              :    end if
    2211              :  end if
    2212              : #endif
    2213              : 
    2214      6998811 : end subroutine xmpi_sum_dp6d
    2215              : !!***
    2216              : 
    2217              : !> wrapper arround xmpi_sum_dp6d than can be called in C/CUDA
    2218            0 : subroutine xmpi_sum_dp6d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_dp6d_c")
    2219              : 
    2220              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    2221              :   implicit none
    2222              : 
    2223              :   ! dummy args
    2224              :   type(c_ptr),                    intent(inout) :: xval_ptr
    2225              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(6)
    2226              :   integer(kind=c_int32_t),        intent(in)    :: comm
    2227              :   integer(kind=c_int32_t),        intent(out)   :: ier
    2228              : 
    2229              :   ! local vars
    2230              :   real(dp), pointer :: xval(:,:,:,:,:,:) => null()
    2231              : 
    2232              :   ! convert the c pointer into a fortran array
    2233            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    2234              : 
    2235            0 :   call xmpi_sum_dp6d(xval, comm, ier)
    2236              : 
    2237            0 : end subroutine xmpi_sum_dp6d_c
    2238              : 
    2239              : !----------------------------------------------------------------------
    2240              : 
    2241              : !!****f* ABINIT/xmpi_sum_dp7d
    2242              : !! NAME
    2243              : !!  xmpi_sum_dp7d
    2244              : !!
    2245              : !! FUNCTION
    2246              : !!  Combines values from all processes and distribute
    2247              : !!  the result back to all processes.
    2248              : !!  Target: double precision six-dimensional arrays.
    2249              : !!
    2250              : !! INPUTS
    2251              : !!  comm= MPI communicator
    2252              : !!
    2253              : !! OUTPUT
    2254              : !!  ier= exit status, a non-zero value meaning there is an error
    2255              : !!
    2256              : !! SIDE EFFECTS
    2257              : !!  xval= buffer array
    2258              : !!
    2259              : !! SOURCE
    2260              : 
    2261          248 : subroutine xmpi_sum_dp7d(xval,comm,ier)
    2262              : 
    2263              : !Arguments-------------------------
    2264              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:,:,:)
    2265              :  integer ,intent(in) :: comm
    2266              :  integer ,intent(out) :: ier
    2267              : 
    2268              : !Local variables-------------------
    2269              : #if defined HAVE_MPI
    2270              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,n6,n7,nn,nproc_space_comm
    2271              :  integer(kind=int64) :: ntot
    2272          248 :  real(dp),allocatable :: xsum(:,:,:,:,:,:,:)
    2273              : #endif
    2274              : ! *************************************************************************
    2275          248 :  ier=0
    2276              : #if defined HAVE_MPI
    2277          248 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2278          245 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    2279          245 :    if (nproc_space_comm /= 1) then
    2280           84 :      n1 = size(xval,dim=1)
    2281           84 :      n2 = size(xval,dim=2)
    2282           84 :      n3 = size(xval,dim=3)
    2283           84 :      n4 = size(xval,dim=4)
    2284           84 :      n5 = size(xval,dim=5)
    2285           84 :      n6 = size(xval,dim=6)
    2286           84 :      n7 = size(xval,dim=7)
    2287              : 
    2288              :      !This product of dimensions can be greater than a 32bit integer
    2289              :      !We use a INT64 to store it. If it is too large, we switch to an
    2290              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    2291           84 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5*n6*n7
    2292           84 :      if (ntot<=xmpi_maxint32_64) then
    2293           84 :        nn=n1*n2*n3*n4*n5*n6*n7 ; my_dt=MPI_DOUBLE_PRECISION ; my_op=MPI_SUM
    2294              :      else
    2295            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_SUM)
    2296              :      end if
    2297              : 
    2298              : !    Accumulate xval on all proc. in comm
    2299              : #if defined HAVE_MPI2_INPLACE
    2300           84 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    2301              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    2302           84 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    2303              :      else
    2304              : #endif
    2305            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5,n6,n7), ier)
    2306            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_dp7d')
    2307            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    2308            0 :        xval (:,:,:,:,:,:,:) = xsum(:,:,:,:,:,:,:)
    2309            0 :        ABI_FREE(xsum)
    2310              : #if defined HAVE_MPI2_INPLACE
    2311              :      endif
    2312              : #endif
    2313              : 
    2314           84 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    2315              :    end if
    2316              :  end if
    2317              : #endif
    2318              : 
    2319          248 : end subroutine xmpi_sum_dp7d
    2320              : !!***
    2321              : 
    2322              : !> wrapper arround xmpi_sum_dp7d than can be called in C/CUDA
    2323            0 : subroutine xmpi_sum_dp7d_c(xval_ptr,xval_size,comm,ier) bind(c, name="xmpi_sum_dp7d_c")
    2324              : 
    2325              :   use, intrinsic :: iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer,c_int32_t
    2326              :   implicit none
    2327              : 
    2328              :   ! dummy args
    2329              :   type(c_ptr),                    intent(inout) :: xval_ptr
    2330              :   integer(kind=c_int32_t),        intent(in)    :: xval_size(7)
    2331              :   integer(kind=c_int32_t),        intent(in)    :: comm
    2332              :   integer(kind=c_int32_t),        intent(out)   :: ier
    2333              : 
    2334              :   ! local vars
    2335              :   real(dp), pointer :: xval(:,:,:,:,:,:,:) => null()
    2336              : 
    2337              :   ! convert the c pointer into a fortran array
    2338            0 :   call c_f_pointer(xval_ptr, xval, xval_size)
    2339              : 
    2340            0 :   call xmpi_sum_dp7d(xval, comm, ier)
    2341              : 
    2342            0 : end subroutine xmpi_sum_dp7d_c
    2343              : 
    2344              : !----------------------------------------------------------------------
    2345              : 
    2346              : !!****f* ABINIT/xmpi_sum_dp2t
    2347              : !! NAME
    2348              : !!  xmpi_sum_dp2t
    2349              : !!
    2350              : !! FUNCTION
    2351              : !!  Combines values from all processes and distribute
    2352              : !!  the result back to all processes.
    2353              : !!  Target: double precision one-dimensional array without transfers.
    2354              : !!
    2355              : !! INPUTS
    2356              : !!  n1= first dimension of the array
    2357              : !!  comm= MPI communicator
    2358              : !!
    2359              : !! OUTPUT
    2360              : !!  ier= exit status, a non-zero value meaning there is an error
    2361              : !!
    2362              : !! SIDE EFFECTS
    2363              : !!  xval= buffer array
    2364              : !!  xsum= receive buffer
    2365              : !!
    2366              : !! SOURCE
    2367              : 
    2368        11415 : subroutine xmpi_sum_dp2t(xval,xsum,n1,comm,ier)
    2369              : 
    2370              : !Arguments-------------------------
    2371              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:),xsum(:)
    2372              :  integer ,intent(in) :: n1
    2373              :  integer ,intent(in) :: comm
    2374              :  integer ,intent(out) :: ier
    2375              : ! *************************************************************************
    2376              : 
    2377        11415 :  ier=0
    2378              : #if defined HAVE_MPI
    2379        11415 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2380              : !  Accumulate xval on all proc. in comm
    2381        11398 :    call MPI_ALLREDUCE(xval,xsum,n1,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
    2382              :  else
    2383              : #endif
    2384          457 :    xsum=xval
    2385              : #if defined HAVE_MPI
    2386              :  end if
    2387              : #endif
    2388              : 
    2389        11415 : end subroutine xmpi_sum_dp2t
    2390              : !!***
    2391              : 
    2392              : !----------------------------------------------------------------------
    2393              : 
    2394              : !!****f* ABINIT/xmpi_sum_dp2d2t
    2395              : !! NAME
    2396              : !!  xmpi_sum_dp2d2t
    2397              : !!
    2398              : !! FUNCTION
    2399              : !!  Combines values from all processes and distribute
    2400              : !!  the result back to all processes.
    2401              : !!  Target:  double precisions bi-dimensional array
    2402              : !!
    2403              : !! INPUTS
    2404              : !!  n = total send size
    2405              : !!  xval= buffer array
    2406              : !!  comm= MPI communicator
    2407              : !!
    2408              : !! OUTPUT
    2409              : !!  xsum= receive buffer
    2410              : !!  ier= exit status, a non-zero value meaning there is an error
    2411              : !!
    2412              : !! SOURCE
    2413              : 
    2414            0 : subroutine xmpi_sum_dp2d2t(xval,xsum,n,comm,ier)
    2415              : 
    2416              : !Arguments-------------------------
    2417              :  real(dp), DEV_CONTARRD intent(in) :: xval(:,:)
    2418              :  real(dp), DEV_CONTARRD intent(out) :: xsum(:,:)
    2419              :  integer ,intent(in) :: n
    2420              :  integer ,intent(in) :: comm
    2421              :  integer ,intent(out) :: ier
    2422              : ! *************************************************************************
    2423              : 
    2424            0 :  ier=0
    2425              : #if defined HAVE_MPI
    2426            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2427              : !  Accumulate xval on all proc. in comm
    2428            0 :    call MPI_ALLREDUCE(xval,xsum,n,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
    2429              :  else
    2430              : #endif
    2431            0 :    xsum=xval
    2432              : #if defined HAVE_MPI
    2433              :  end if
    2434              : #endif
    2435              : 
    2436            0 : end subroutine xmpi_sum_dp2d2t
    2437              : !!***
    2438              : 
    2439              : !----------------------------------------------------------------------
    2440              : 
    2441              : !!****f* ABINIT/xmpi_sum_dp3d2t
    2442              : !! NAME
    2443              : !!  xmpi_sum_dp3d2t
    2444              : !!
    2445              : !! FUNCTION
    2446              : !!  Combines values from all processes and distribute
    2447              : !!  the result back to all processes.
    2448              : !!  Target: double precision three-dimensional array without transfers.
    2449              : !!
    2450              : !! INPUTS
    2451              : !!  n1= first dimension of the array
    2452              : !!  comm= MPI communicator
    2453              : !!
    2454              : !! OUTPUT
    2455              : !!  ier= exit status, a non-zero value meaning there is an error
    2456              : !!
    2457              : !! SIDE EFFECTS
    2458              : !!  xval= buffer array
    2459              : !!  xsum= receive buffer
    2460              : !!
    2461              : !! SOURCE
    2462              : 
    2463            0 : subroutine xmpi_sum_dp3d2t(xval,xsum,n1,comm,ier)
    2464              : 
    2465              : !Arguments-------------------------
    2466              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:),xsum(:,:,:)
    2467              :  integer ,intent(in) :: n1
    2468              :  integer ,intent(in) :: comm
    2469              :  integer ,intent(out) :: ier
    2470              : ! *************************************************************************
    2471              : 
    2472            0 :  ier=0
    2473              : #if defined HAVE_MPI
    2474            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2475              : !  Accumulate xval on all proc. in comm
    2476            0 :    call MPI_ALLREDUCE(xval,xsum,n1,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
    2477              :  else
    2478              : #endif
    2479            0 :    xsum=xval
    2480              : #if defined HAVE_MPI
    2481              :  end if
    2482              : #endif
    2483              : 
    2484            0 : end subroutine xmpi_sum_dp3d2t
    2485              : !!***
    2486              : 
    2487              : !----------------------------------------------------------------------
    2488              : 
    2489              : !!****f* ABINIT/xmpi_sum_dp4d2t
    2490              : !! NAME
    2491              : !!  xmpi_sum_dp4d2t
    2492              : !!
    2493              : !! FUNCTION
    2494              : !!  Combines values from all processes and distribute
    2495              : !!  the result back to all processes.
    2496              : !!  Target: double precision four-dimensional array without transfers.
    2497              : !!
    2498              : !! INPUTS
    2499              : !!  n1= first dimension of the array
    2500              : !!  comm= MPI communicator
    2501              : !!
    2502              : !! OUTPUT
    2503              : !!  ier= exit status, a non-zero value meaning there is an error
    2504              : !!
    2505              : !! SIDE EFFECTS
    2506              : !!  xval= buffer array
    2507              : !!  xsum= receive buffer
    2508              : !!
    2509              : !! SOURCE
    2510              : 
    2511            0 : subroutine xmpi_sum_dp4d2t(xval,xsum,n1,comm,ier)
    2512              : 
    2513              : !Arguments-------------------------
    2514              :  real(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:),xsum(:,:,:,:)
    2515              :  integer ,intent(in) :: n1
    2516              :  integer ,intent(in) :: comm
    2517              :  integer ,intent(out) :: ier
    2518              : ! *************************************************************************
    2519              : 
    2520            0 :  ier=0
    2521              : #if defined HAVE_MPI
    2522            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2523              : !  Accumulate xval on all proc. in comm
    2524            0 :    call MPI_ALLREDUCE(xval,xsum,n1,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
    2525              :  else
    2526              : #endif
    2527            0 :    xsum=xval
    2528              : #if defined HAVE_MPI
    2529              :  end if
    2530              : #endif
    2531              : 
    2532            0 : end subroutine xmpi_sum_dp4d2t
    2533              : !!***
    2534              : 
    2535              : !----------------------------------------------------------------------
    2536              : 
    2537              : !!****f* ABINIT/xmpi_sum_c0dc
    2538              : !! NAME
    2539              : !!  xmpi_sum_c0dc
    2540              : !!
    2541              : !! FUNCTION
    2542              : !!  Combines values from all processes and distribute the result back to all processes.
    2543              : !!  Target: double complex scalar
    2544              : !!
    2545              : !! INPUTS
    2546              : !!  comm= MPI communicator
    2547              : !!
    2548              : !! OUTPUT
    2549              : !!  ier= exit status, a non-zero value meaning there is an error
    2550              : !!
    2551              : !! SIDE EFFECTS
    2552              : !!  xval= scalar to be summed.
    2553              : !!
    2554              : !! SOURCE
    2555              : 
    2556       351836 : subroutine xmpi_sum_c0dc(xval,comm,ier)
    2557              : 
    2558              : !Arguments-------------------------
    2559              :  complex(dp),intent(inout) :: xval
    2560              :  integer,intent(in) :: comm
    2561              :  integer,intent(out) :: ier
    2562              : 
    2563              : !Local variables-------------------
    2564              : #if defined HAVE_MPI
    2565              :  integer :: nproc_space_comm
    2566              :  complex(dp) :: arr_xsum(1),arr_xval(1)
    2567              : #endif
    2568              : ! *************************************************************************
    2569              : 
    2570       351836 :  ier=0
    2571              : #if defined HAVE_MPI
    2572       351836 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2573       334558 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    2574       334558 :    if (nproc_space_comm /= 1) then
    2575              : !    Accumulate xval on all proc. in comm
    2576         2640 :      arr_xval(1) = xval
    2577         2640 :      call MPI_ALLREDUCE(arr_xval,arr_xsum,1,MPI_DOUBLE_COMPLEX,MPI_SUM,comm,ier)
    2578         2640 :      xval = arr_xsum(1)
    2579              :    end if
    2580              :  end if
    2581              : #endif
    2582              : 
    2583       351836 : end subroutine xmpi_sum_c0dc
    2584              : !!***
    2585              : 
    2586              : !----------------------------------------------------------------------
    2587              : 
    2588              : !!****f* ABINIT/xmpi_sum_c0sc
    2589              : !! NAME
    2590              : !!  xmpi_sum_c0sc
    2591              : !!
    2592              : !! FUNCTION
    2593              : !!  Combines values from all processes and distribute the result back to all processes.
    2594              : !!  Target: single-precision complex scalar
    2595              : !!
    2596              : !! INPUTS
    2597              : !!  comm= MPI communicator
    2598              : !!
    2599              : !! OUTPUT
    2600              : !!  ier= exit status, a non-zero value meaning there is an error
    2601              : !!
    2602              : !! SIDE EFFECTS
    2603              : !!  xval= scalar to be summed.
    2604              : !!
    2605              : !! SOURCE
    2606              : 
    2607            0 : subroutine xmpi_sum_c0sc(xval,comm,ier)
    2608              : 
    2609              : !Arguments-------------------------
    2610              :  complex(sp),intent(inout) :: xval
    2611              :  integer,intent(in) :: comm
    2612              :  integer,intent(out) :: ier
    2613              : 
    2614              : !Local variables-------------------
    2615              : #if defined HAVE_MPI
    2616              :  integer :: nproc_space_comm
    2617              :  complex(sp) :: arr_xsum(1),arr_xval(1)
    2618              : #endif
    2619              : ! *************************************************************************
    2620              : 
    2621            0 :  ier=0
    2622              : #if defined HAVE_MPI
    2623            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2624            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    2625            0 :    if (nproc_space_comm /= 1) then
    2626              :      ! Accumulate xval on all proc. in comm
    2627            0 :      arr_xval(1) = xval
    2628            0 :      call MPI_ALLREDUCE(arr_xval,arr_xsum,1,MPI_COMPLEX,MPI_SUM,comm,ier)
    2629            0 :      xval = arr_xsum(1)
    2630              :    end if
    2631              :  end if
    2632              : #endif
    2633              : 
    2634            0 : end subroutine xmpi_sum_c0sc
    2635              : !!***
    2636              : 
    2637              : !----------------------------------------------------------------------
    2638              : 
    2639              : !!****f* ABINIT/xmpi_sum_c1dc
    2640              : !! NAME
    2641              : !!  xmpi_sum_c1dc
    2642              : !!
    2643              : !! FUNCTION
    2644              : !!  Combines values from all processes and distribute
    2645              : !!  the result back to all processes.
    2646              : !!  Target: one-dimensional double complex arrays.
    2647              : !!
    2648              : !! INPUTS
    2649              : !!  comm= MPI communicator
    2650              : !!
    2651              : !! OUTPUT
    2652              : !!  ier= exit status, a non-zero value meaning there is an error
    2653              : !!
    2654              : !! SIDE EFFECTS
    2655              : !!  xval= buffer array
    2656              : !!
    2657              : !! SOURCE
    2658              : 
    2659        42432 : subroutine xmpi_sum_c1dc(xval,comm,ier)
    2660              : 
    2661              : !Arguments-------------------------
    2662              :  complex(dp), DEV_CONTARRD intent(inout) :: xval(:)
    2663              :  integer,intent(in) :: comm
    2664              :  integer,intent(out) :: ier
    2665              : 
    2666              : !Local variables-------------------
    2667              : #if defined HAVE_MPI
    2668              :  integer :: n1,nproc_space_comm
    2669        42432 :  complex(dp) , allocatable :: xsum(:)
    2670              : #endif
    2671              : ! *************************************************************************
    2672              : 
    2673        42432 :  ier=0
    2674              : #if defined HAVE_MPI
    2675        42432 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2676        38291 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    2677        38291 :    if (nproc_space_comm /= 1) then
    2678         9988 :      n1 =size(xval,dim=1)
    2679              : 
    2680              : !    Accumulate xval on all proc. in comm
    2681              : #if defined HAVE_MPI2_INPLACE
    2682         9988 :      if (xmpi_use_inplace_operations) then
    2683         9988 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,n1,MPI_DOUBLE_COMPLEX,MPI_SUM,comm,ier)
    2684              :      else
    2685              : #endif
    2686            0 :        ABI_STAT_MALLOC(xsum,(n1), ier)
    2687            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c1dc')
    2688            0 :        call MPI_ALLREDUCE(xval,xsum,n1,MPI_DOUBLE_COMPLEX,MPI_SUM,comm,ier)
    2689            0 :        xval (:) = xsum(:)
    2690            0 :        ABI_FREE(xsum)
    2691              : #if defined HAVE_MPI2_INPLACE
    2692              :      endif
    2693              : #endif
    2694              : 
    2695              :    end if
    2696              :  end if
    2697              : #endif
    2698              : 
    2699        42432 : end subroutine xmpi_sum_c1dc
    2700              : !!***
    2701              : 
    2702              : !----------------------------------------------------------------------
    2703              : 
    2704              : !!****f* ABINIT/xmpi_sum_c2dc
    2705              : !! NAME
    2706              : !!  xmpi_sum_c2dc
    2707              : !!
    2708              : !! FUNCTION
    2709              : !!  Combines values from all processes and distribute
    2710              : !!  the result back to all processes.
    2711              : !!  Target: two-dimensional double complex arrays.
    2712              : !!
    2713              : !! INPUTS
    2714              : !!  comm= MPI communicator
    2715              : !!
    2716              : !! OUTPUT
    2717              : !!  ier= exit status, a non-zero value meaning there is an error
    2718              : !!
    2719              : !! SIDE EFFECTS
    2720              : !!  xval= buffer array
    2721              : !!
    2722              : !! SOURCE
    2723              : 
    2724      4447673 : subroutine xmpi_sum_c2dc(xval,comm,ier,use_omp_map)
    2725              : 
    2726              : !Arguments-------------------------
    2727              :  complex(dp), DEV_CONTARRD intent(inout) :: xval(:,:)
    2728              :  integer,intent(in) :: comm
    2729              :  logical,intent(in), optional :: use_omp_map
    2730              :  integer,intent(out) :: ier
    2731              : 
    2732              : !Local variables-------------------
    2733              : #if defined HAVE_MPI
    2734              :  integer :: my_dt,my_op,n1,n2,nn,nproc_space_comm
    2735              : #ifdef HAVE_GPU_MPI
    2736              :  integer :: i1,i2
    2737              : #endif
    2738              :  logical :: l_use_omp_map
    2739              :  integer(kind=int64) :: ntot
    2740      4447673 :  complex(dp),allocatable :: xsum(:,:)
    2741              : #endif
    2742              : ! *************************************************************************
    2743              : 
    2744      4447673 :  ier=0
    2745              : #if defined HAVE_MPI
    2746      4447673 :  l_use_omp_map=.false.
    2747      4447673 :  if(present(use_omp_map)) l_use_omp_map=use_omp_map
    2748      4447673 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2749      4425673 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    2750      4425673 :    if (nproc_space_comm /= 1) then
    2751      4413382 :      n1 =size(xval,dim=1)
    2752      4413382 :      n2 =size(xval,dim=2)
    2753              : 
    2754              :      !This product of dimensions can be greater than a 32bit integer
    2755              :      !We use a INT64 to store it. If it is too large, we switch to an
    2756              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    2757      4413382 :      ntot=int(n1,kind=int64)*n2
    2758      4413382 :      if (ntot<=xmpi_maxint32_64) then
    2759      4413382 :        nn=n1*n2 ; my_dt=MPI_DOUBLE_COMPLEX ; my_op=MPI_SUM
    2760              :      else
    2761            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_COMPLEX,my_dt,my_op,MPI_SUM)
    2762              :      end if
    2763              : 
    2764              : !    Accumulate xval on all proc. in comm
    2765              : #if defined HAVE_MPI2_INPLACE
    2766      4413382 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    2767              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    2768      4413382 :        if(.not. l_use_omp_map) then
    2769      4413382 :          call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    2770              :        else
    2771              : #ifdef HAVE_OPENMP_OFFLOAD
    2772              : #ifdef HAVE_GPU_MPI
    2773              :          ! Proper GPU-aware call
    2774              :          !$OMP TARGET DATA USE_DEVICE_ADDR(xval)
    2775              :          call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    2776              :          !$OMP END TARGET DATA
    2777              : #else
    2778              :          !$OMP TARGET UPDATE FROM(xval)
    2779              :          call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    2780              :          !$OMP TARGET UPDATE TO(xval)
    2781              : #endif
    2782              : #endif
    2783              :        end if ! use_omp_map
    2784              :      else
    2785              : #endif
    2786            0 :        ABI_STAT_MALLOC(xsum,(n1,n2), ier)
    2787            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c2dc')
    2788            0 :        if(.not. l_use_omp_map) then
    2789            0 :          call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    2790            0 :          xval (:,:) = xsum(:,:)
    2791              :        else
    2792              : #ifdef HAVE_OPENMP_OFFLOAD
    2793              :          !$OMP TARGET ENTER DATA MAP(alloc:xsum)
    2794              : #ifdef HAVE_GPU_MPI
    2795              :          ! Proper GPU-aware call
    2796              :          !$OMP TARGET DATA USE_DEVICE_ADDR(xval,xsum)
    2797              :          call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    2798              :          !$OMP END TARGET DATA
    2799              :          !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(2) PRIVATE(i2,i1) MAP(to:xval,xsum)
    2800              :          do i2=1,n2
    2801              :            do i1=1,n1
    2802              :              xval(i1,i2)=xsum(i1,i2)
    2803              :            end do
    2804              :          end do
    2805              : #else
    2806              :          !$OMP TARGET UPDATE FROM(xval)
    2807              :          call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    2808              :          xval (:,:) = xsum(:,:)
    2809              :          !$OMP TARGET UPDATE TO(xval)
    2810              : #endif
    2811              :          !$OMP TARGET EXIT DATA MAP(delete:xsum)
    2812              : #endif
    2813              :        end if
    2814            0 :        ABI_FREE(xsum)
    2815              : #if defined HAVE_MPI2_INPLACE
    2816              :      end if
    2817              : #endif
    2818              : 
    2819      4413382 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    2820              :    end if
    2821              :  end if
    2822              : #endif
    2823              : 
    2824      4447673 : end subroutine xmpi_sum_c2dc
    2825              : !!***
    2826              : 
    2827              : !----------------------------------------------------------------------
    2828              : 
    2829              : !!****f* ABINIT/xmpi_sum_c3dc
    2830              : !! NAME
    2831              : !!  xmpi_sum_c3dc
    2832              : !!
    2833              : !! FUNCTION
    2834              : !!  Combines values from all processes and distribute
    2835              : !!  the result back to all processes.
    2836              : !!  Target: three-dimensional double complex arrays.
    2837              : !!
    2838              : !! INPUTS
    2839              : !!  comm= MPI communicator
    2840              : !!
    2841              : !! OUTPUT
    2842              : !!  ier= exit status, a non-zero value meaning there is an error
    2843              : !!
    2844              : !! SIDE EFFECTS
    2845              : !!  xval= buffer array
    2846              : !!
    2847              : !! SOURCE
    2848              : 
    2849         1956 : subroutine xmpi_sum_c3dc(xval,comm,ier)
    2850              : 
    2851              : !Arguments-------------------------
    2852              :  complex(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:)
    2853              :  integer,intent(in) :: comm
    2854              :  integer,intent(out) :: ier
    2855              : 
    2856              : !Local variables-------------------
    2857              : #if defined HAVE_MPI
    2858              :  integer :: my_dt,my_op,n1,n2,n3,nn,nproc_space_comm
    2859              :  integer(kind=int64) :: ntot
    2860         1956 :  complex(dp),allocatable :: xsum(:,:,:)
    2861              : #endif
    2862              : ! *************************************************************************
    2863              : 
    2864         1956 :  ier=0
    2865              : #if defined HAVE_MPI
    2866         1956 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2867         1954 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    2868         1954 :    if (nproc_space_comm /= 1) then
    2869          298 :      n1 =size(xval,dim=1)
    2870          298 :      n2 =size(xval,dim=2)
    2871          298 :      n3 =size(xval,dim=3)
    2872              : 
    2873              :      !This product of dimensions can be greater than a 32bit integer
    2874              :      !We use a INT64 to store it. If it is too large, we switch to an
    2875              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    2876          298 :      ntot=int(n1,kind=int64)*n2*n3
    2877          298 :      if (ntot<=xmpi_maxint32_64) then
    2878          298 :        nn=n1*n2*n3 ; my_dt=MPI_DOUBLE_COMPLEX ; my_op=MPI_SUM
    2879              :      else
    2880            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_COMPLEX,my_dt,my_op,MPI_SUM)
    2881              :      end if
    2882              : 
    2883              : !    Accumulate xval on all proc. in comm
    2884              : #if defined HAVE_MPI2_INPLACE
    2885          298 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    2886              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    2887          298 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    2888              :      else
    2889              : #endif
    2890            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3), ier)
    2891            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c3dc')
    2892            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    2893            0 :        xval (:,:,:) = xsum(:,:,:)
    2894            0 :        ABI_FREE(xsum)
    2895              : #if defined HAVE_MPI2_INPLACE
    2896              :      end if
    2897              : #endif
    2898              : 
    2899          298 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    2900              :    end if
    2901              :  end if
    2902              : #endif
    2903              : 
    2904         1956 : end subroutine xmpi_sum_c3dc
    2905              : !!***
    2906              : 
    2907              : !----------------------------------------------------------------------
    2908              : 
    2909              : !!****f* ABINIT/xmpi_sum_c4dc
    2910              : !! NAME
    2911              : !!  xmpi_sum_c4dc
    2912              : !!
    2913              : !! FUNCTION
    2914              : !!  Combines values from all processes and distribute
    2915              : !!  the result back to all processes.
    2916              : !!  Target: four-dimensional double complex arrays.
    2917              : !!
    2918              : !! INPUTS
    2919              : !!  comm= MPI communicator
    2920              : !!
    2921              : !! OUTPUT
    2922              : !!  ier= exit status, a non-zero value meaning there is an error
    2923              : !!
    2924              : !! SIDE EFFECTS
    2925              : !!  xval= buffer array
    2926              : !!
    2927              : !! SOURCE
    2928              : 
    2929       288352 : subroutine xmpi_sum_c4dc(xval,comm,ier)
    2930              : 
    2931              : !Arguments-------------------------
    2932              :  complex(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:)
    2933              :  integer,intent(in) :: comm
    2934              :  integer,intent(out) :: ier
    2935              : 
    2936              : !Local variables-------------------
    2937              : #if defined HAVE_MPI
    2938              :  integer :: my_dt,my_op,n1,n2,n3,n4,nn,nproc_space_comm
    2939              :  integer(kind=int64) :: ntot
    2940       288352 :  complex(dp),allocatable :: xsum(:,:,:,:)
    2941              : #endif
    2942              : ! *************************************************************************
    2943              : 
    2944       288352 :  ier=0
    2945              : #if defined HAVE_MPI
    2946       288352 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    2947       285064 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    2948       285064 :    if (nproc_space_comm /= 1) then
    2949         3926 :      n1 =size(xval,dim=1)
    2950         3926 :      n2 =size(xval,dim=2)
    2951         3926 :      n3 =size(xval,dim=3)
    2952         3926 :      n4 =size(xval,dim=4)
    2953              : 
    2954              :      !This product of dimensions can be greater than a 32bit integer
    2955              :      !We use a INT64 to store it. If it is too large, we switch to an
    2956              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    2957         3926 :      ntot=int(n1,kind=int64)*n2*n3*n4
    2958         3926 :      if (ntot<=xmpi_maxint32_64) then
    2959         3926 :        nn=n1*n2*n3*n4 ; my_dt=MPI_DOUBLE_COMPLEX ; my_op=MPI_SUM
    2960              :      else
    2961            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_COMPLEX,my_dt,my_op,MPI_SUM)
    2962              :      end if
    2963              : 
    2964              : !    Accumulate xval on all proc. in comm
    2965              : #if defined HAVE_MPI2_INPLACE
    2966         3926 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    2967              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    2968         3926 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    2969              :      else
    2970              : #endif
    2971            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4), ier)
    2972            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c4dc')
    2973            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    2974            0 :        xval (:,:,:,:) = xsum(:,:,:,:)
    2975            0 :        ABI_FREE(xsum)
    2976              : #if defined HAVE_MPI2_INPLACE
    2977              :      endif
    2978              : #endif
    2979              : 
    2980         3926 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    2981              :    end if
    2982              :  end if
    2983              : #endif
    2984              : 
    2985       288352 : end subroutine xmpi_sum_c4dc
    2986              : !!***
    2987              : 
    2988              : !----------------------------------------------------------------------
    2989              : 
    2990              : !!****f* ABINIT/xmpi_sum_c5dc
    2991              : !! NAME
    2992              : !!  xmpi_sum_c5dc
    2993              : !!
    2994              : !! FUNCTION
    2995              : !!  Combines values from all processes and distribute the result back to all processes.
    2996              : !!  Target: five-dimensional double precision complex arrays.
    2997              : !!
    2998              : !! INPUTS
    2999              : !!  comm= MPI communicator
    3000              : !!
    3001              : !! OUTPUT
    3002              : !!  ier= exit status, a non-zero value meaning there is an error
    3003              : !!
    3004              : !! SIDE EFFECTS
    3005              : !!  xval= buffer array
    3006              : !!
    3007              : !! SOURCE
    3008              : 
    3009          667 : subroutine xmpi_sum_c5dc(xval,comm,ier)
    3010              : 
    3011              : !Arguments-------------------------
    3012              :  complex(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:)
    3013              :  integer,intent(in) :: comm
    3014              :  integer,intent(out) :: ier
    3015              : 
    3016              : !Local variables-------------------
    3017              : #if defined HAVE_MPI
    3018              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,nn,nproc_space_comm
    3019              :  integer(kind=int64) :: ntot
    3020          667 :  complex(dp),allocatable :: xsum(:,:,:,:,:)
    3021              : #endif
    3022              : ! *************************************************************************
    3023              : 
    3024          667 :  ier=0
    3025              : #if defined HAVE_MPI
    3026          667 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3027          667 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3028          667 :    if (nproc_space_comm /= 1) then
    3029          210 :      n1 =size(xval,dim=1)
    3030          210 :      n2 =size(xval,dim=2)
    3031          210 :      n3 =size(xval,dim=3)
    3032          210 :      n4 =size(xval,dim=4)
    3033          210 :      n5 =size(xval,dim=5)
    3034              : 
    3035              :      !This product of dimensions can be greater than a 32bit integer
    3036              :      !We use a INT64 to store it. If it is too large, we switch to an
    3037              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    3038          210 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5
    3039          210 :      if (ntot<=xmpi_maxint32_64) then
    3040          210 :        nn=n1*n2*n3*n4*n5 ; my_dt=MPI_DOUBLE_COMPLEX ; my_op=MPI_SUM
    3041              :      else
    3042            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_COMPLEX,my_dt,my_op,MPI_SUM)
    3043              :      end if
    3044              : 
    3045              : !    Accumulate xval on all proc. in comm
    3046              : #if defined HAVE_MPI2_INPLACE
    3047          210 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    3048              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    3049          210 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    3050              :      else
    3051              : #endif
    3052            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5), ier)
    3053            0 :        if (ier/=0) call xmpi_abort(comm,msg='error allocating xsum in xmpi_sum_c5dc')
    3054            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    3055            0 :        xval (:,:,:,:,:) = xsum(:,:,:,:,:)
    3056            0 :        ABI_FREE(xsum)
    3057              : #if defined HAVE_MPI2_INPLACE
    3058              :      endif
    3059              : #endif
    3060              : 
    3061          210 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    3062              :    end if
    3063              :  end if
    3064              : #endif
    3065              : 
    3066          667 : end subroutine xmpi_sum_c5dc
    3067              : !!***
    3068              : 
    3069              : !----------------------------------------------------------------------
    3070              : 
    3071              : !!****f* ABINIT/xmpi_sum_c6dc
    3072              : !! NAME
    3073              : !!  xmpi_sum_c6dc
    3074              : !!
    3075              : !! FUNCTION
    3076              : !!  Combines values from all processes and distribute the result back to all processes.
    3077              : !!  Target: six-dimensional double precision complex arrays.
    3078              : !!
    3079              : !! INPUTS
    3080              : !!  comm= MPI communicator
    3081              : !!
    3082              : !! OUTPUT
    3083              : !!  ier= exit status, a non-zero value meaning there is an error
    3084              : !!
    3085              : !! SIDE EFFECTS
    3086              : !!  xval= buffer array
    3087              : !!
    3088              : !! SOURCE
    3089              : 
    3090            0 : subroutine xmpi_sum_c6dc(xval,comm,ier)
    3091              : 
    3092              : !Arguments-------------------------
    3093              :  complex(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:,:)
    3094              :  integer,intent(in) :: comm
    3095              :  integer,intent(out) :: ier
    3096              : 
    3097              : !Local variables-------------------
    3098              : #if defined HAVE_MPI
    3099              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,n6,nn,nproc_space_comm
    3100              :  integer(kind=int64) :: ntot
    3101            0 :  complex(dp),allocatable :: xsum(:,:,:,:,:,:)
    3102              : #endif
    3103              : ! *************************************************************************
    3104              : 
    3105            0 :  ier=0
    3106              : #if defined HAVE_MPI
    3107            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3108            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3109            0 :    if (nproc_space_comm /= 1) then
    3110            0 :      n1 =size(xval,dim=1)
    3111            0 :      n2 =size(xval,dim=2)
    3112            0 :      n3 =size(xval,dim=3)
    3113            0 :      n4 =size(xval,dim=4)
    3114            0 :      n5 =size(xval,dim=5)
    3115            0 :      n6 =size(xval,dim=6)
    3116              : 
    3117              :      !This product of dimensions can be greater than a 32bit integer
    3118              :      !We use a INT64 to store it. If it is too large, we switch to an
    3119              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    3120            0 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5*n6
    3121            0 :      if (ntot<=xmpi_maxint32_64) then
    3122            0 :        nn=n1*n2*n3*n4*n5*n6 ; my_dt=MPI_DOUBLE_COMPLEX ; my_op=MPI_SUM
    3123              :      else
    3124            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_COMPLEX,my_dt,my_op,MPI_SUM)
    3125              :      end if
    3126              : 
    3127              : !    Accumulate xval on all proc. in comm
    3128              : #if defined HAVE_MPI2_INPLACE
    3129            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    3130              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    3131            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    3132              :      else
    3133              : #endif
    3134            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5,n6), ier)
    3135            0 :        if (ier/=0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c6dc')
    3136            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    3137            0 :        xval = xsum
    3138            0 :        ABI_FREE(xsum)
    3139              : #if defined HAVE_MPI2_INPLACE
    3140              :      endif
    3141              : #endif
    3142              : 
    3143            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    3144              :    end if
    3145              :  end if
    3146              : #endif
    3147              : 
    3148            0 : end subroutine xmpi_sum_c6dc
    3149              : !!***
    3150              : 
    3151              : !----------------------------------------------------------------------
    3152              : 
    3153              : !!****f* ABINIT/xmpi_sum_c7dc
    3154              : !! NAME
    3155              : !!  xmpi_sum_c7dc
    3156              : !!
    3157              : !! FUNCTION
    3158              : !!  Combines values from all processes and distribute the result back to all processes.
    3159              : !!  Target: six-dimensional double precision complex arrays.
    3160              : !!
    3161              : !! INPUTS
    3162              : !!  comm= MPI communicator
    3163              : !!
    3164              : !! OUTPUT
    3165              : !!  ier= exit status, a non-zero value meaning there is an error
    3166              : !!
    3167              : !! SIDE EFFECTS
    3168              : !!  xval= buffer array
    3169              : !!
    3170              : !! SOURCE
    3171              : 
    3172            0 : subroutine xmpi_sum_c7dc(xval,comm,ier)
    3173              : 
    3174              : !Arguments-------------------------
    3175              :  complex(dp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:,:,:)
    3176              :  integer,intent(in) :: comm
    3177              :  integer,intent(out) :: ier
    3178              : 
    3179              : !Local variables-------------------
    3180              : #if defined HAVE_MPI
    3181              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,n6,n7,nn,nproc_space_comm
    3182              :  integer(kind=int64) :: ntot
    3183            0 :  complex(dp),allocatable :: xsum(:,:,:,:,:,:,:)
    3184              : #endif
    3185              : ! *************************************************************************
    3186              : 
    3187            0 :  ier=0
    3188              : #if defined HAVE_MPI
    3189            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3190            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3191            0 :    if (nproc_space_comm /= 1) then
    3192            0 :      n1 =size(xval,dim=1)
    3193            0 :      n2 =size(xval,dim=2)
    3194            0 :      n3 =size(xval,dim=3)
    3195            0 :      n4 =size(xval,dim=4)
    3196            0 :      n5 =size(xval,dim=5)
    3197            0 :      n6 =size(xval,dim=6)
    3198            0 :      n7 =size(xval,dim=7)
    3199              : 
    3200              :      !This product of dimensions can be greater than a 32bit integer
    3201              :      !We use a INT64 to store it. If it is too large, we switch to an
    3202              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    3203            0 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5*n6*n7
    3204            0 :      if (ntot<=xmpi_maxint32_64) then
    3205            0 :        nn=n1*n2*n3*n4*n5*n6*n7 ; my_dt=MPI_DOUBLE_COMPLEX ; my_op=MPI_SUM
    3206              :      else
    3207            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_DOUBLE_COMPLEX,my_dt,my_op,MPI_SUM)
    3208              :      end if
    3209              : 
    3210              : !    Accumulate xval on all proc. in comm
    3211              : #if defined HAVE_MPI2_INPLACE
    3212            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    3213              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    3214            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    3215              :      else
    3216              : #endif
    3217            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5,n6,n7),ier)
    3218            0 :        if (ier/=0) call xmpi_abort(comm=comm,msg='error allocating xsum in xmpi_sum_c7dc')
    3219            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    3220            0 :        xval = xsum
    3221            0 :        ABI_FREE(xsum)
    3222              : #if defined HAVE_MPI2_INPLACE
    3223              :      endif
    3224              : #endif
    3225              : 
    3226            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    3227              :    end if
    3228              :  end if
    3229              : #endif
    3230              : 
    3231            0 : end subroutine xmpi_sum_c7dc
    3232              : !!***
    3233              : 
    3234              : !----------------------------------------------------------------------
    3235              : 
    3236              : !!****f* ABINIT/xmpi_sum_c1cplx
    3237              : !! NAME
    3238              : !!  xmpi_sum_c1cplx
    3239              : !!
    3240              : !! FUNCTION
    3241              : !!  Combines values from all processes and distribute
    3242              : !!  the result back to all processes.
    3243              : !!  Target: one-dimensional complex arrays.
    3244              : !!
    3245              : !! INPUTS
    3246              : !!  comm= MPI communicator
    3247              : !!
    3248              : !! OUTPUT
    3249              : !!  ier= exit status, a non-zero value meaning there is an error
    3250              : !!
    3251              : !! SIDE EFFECTS
    3252              : !!  xval= buffer array
    3253              : !!
    3254              : !! SOURCE
    3255              : 
    3256            0 : subroutine xmpi_sum_c1cplx(xval,comm,ier)
    3257              : 
    3258              : !Arguments----------------
    3259              :  complex(sp), DEV_CONTARRD intent(inout) :: xval(:)
    3260              :  integer,intent(in) :: comm
    3261              :  integer,intent(out) :: ier
    3262              : 
    3263              : !Local variables--------------
    3264              : #if defined HAVE_MPI
    3265              :  integer :: n1,nproc_space_comm
    3266            0 :  complex(sp),allocatable :: xsum(:)
    3267              : #endif
    3268              : ! *************************************************************************
    3269              : 
    3270            0 :  ier=0
    3271              : #if defined HAVE_MPI
    3272            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3273            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3274            0 :    if (nproc_space_comm /= 1) then
    3275            0 :      n1 =size(xval,dim=1)
    3276              : 
    3277              : !    Accumulate xval on all proc. in comm
    3278              : #if defined HAVE_MPI2_INPLACE
    3279            0 :      if (xmpi_use_inplace_operations) then
    3280            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,n1,MPI_COMPLEX,MPI_SUM,comm,ier)
    3281              :      else
    3282              : #endif
    3283            0 :        ABI_STAT_MALLOC(xsum,(n1), ier)
    3284            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c1cplx')
    3285            0 :        call MPI_ALLREDUCE(xval,xsum,n1,MPI_COMPLEX,MPI_SUM,comm,ier)
    3286            0 :        xval (:) = xsum(:)
    3287            0 :        ABI_FREE(xsum)
    3288              : #if defined HAVE_MPI2_INPLACE
    3289              :      endif
    3290              : #endif
    3291              : 
    3292              :    end if
    3293              :  end if
    3294              : #endif
    3295              : 
    3296            0 : end subroutine xmpi_sum_c1cplx
    3297              : !!***
    3298              : 
    3299              : !----------------------------------------------------------------------
    3300              : 
    3301              : !!****f* ABINIT/xmpi_sum_c2cplx
    3302              : !! NAME
    3303              : !!  xmpi_sum_c2cplx
    3304              : !!
    3305              : !! FUNCTION
    3306              : !!  Combines values from all processes and distribute
    3307              : !!  the result back to all processes.
    3308              : !!  Target: two-dimensional complex arrays.
    3309              : !!
    3310              : !! INPUTS
    3311              : !!  comm= MPI communicator
    3312              : !!
    3313              : !! OUTPUT
    3314              : !!  ier= exit status, a non-zero value meaning there is an error
    3315              : !!
    3316              : !! SIDE EFFECTS
    3317              : !!  xval= buffer array
    3318              : !!
    3319              : !! SOURCE
    3320              : 
    3321            0 : subroutine xmpi_sum_c2cplx(xval,comm,ier)
    3322              : 
    3323              : !Arguments----------------
    3324              :  complex(sp), DEV_CONTARRD intent(inout) :: xval(:,:)
    3325              :  integer,intent(in) :: comm
    3326              :  integer,intent(out) :: ier
    3327              : 
    3328              : !Local variables--------------
    3329              : #if defined HAVE_MPI
    3330              :  integer :: my_dt,my_op,n1,n2,nn,nproc_space_comm
    3331              :  integer(kind=int64) :: ntot
    3332            0 :  complex(sp), allocatable :: xsum(:,:)
    3333              : #endif
    3334              : ! *************************************************************************
    3335              : 
    3336            0 :  ier=0
    3337              : #if defined HAVE_MPI
    3338            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3339            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3340            0 :    if (nproc_space_comm /= 1) then
    3341            0 :      n1 =size(xval,dim=1)
    3342            0 :      n2 =size(xval,dim=2)
    3343              : 
    3344              :      !This product of dimensions can be greater than a 32bit integer
    3345              :      !We use a INT64 to store it. If it is too large, we switch to an
    3346              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    3347            0 :      ntot=int(n1,kind=int64)*n2
    3348            0 :      if (ntot<=xmpi_maxint32_64) then
    3349            0 :        nn=n1*n2 ; my_dt=MPI_COMPLEX ; my_op=MPI_SUM
    3350              :      else
    3351            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_COMPLEX,my_dt,my_op,MPI_SUM)
    3352              :      end if
    3353              : 
    3354              : !    Accumulate xval on all proc. in comm
    3355              : #if defined HAVE_MPI2_INPLACE
    3356            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    3357              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    3358            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    3359              :      else
    3360              : #endif
    3361            0 :        ABI_STAT_MALLOC(xsum,(n1,n2), ier)
    3362            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c2cplx')
    3363            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    3364            0 :        xval (:,:) = xsum(:,:)
    3365            0 :        ABI_FREE(xsum)
    3366              : #if defined HAVE_MPI2_INPLACE
    3367              :      endif
    3368              : #endif
    3369              : 
    3370            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    3371              :    end if
    3372              :  end if
    3373              : #endif
    3374              : 
    3375            0 : end subroutine xmpi_sum_c2cplx
    3376              : !!***
    3377              : 
    3378              : !----------------------------------------------------------------------
    3379              : 
    3380              : !!****f* ABINIT/xmpi_sum_c3cplx
    3381              : !! NAME
    3382              : !!  xmpi_sum_c3cplx
    3383              : !!
    3384              : !! FUNCTION
    3385              : !!  Combines values from all processes and distribute
    3386              : !!  the result back to all processes.
    3387              : !!  Target: three-dimensional complex arrays.
    3388              : !!
    3389              : !! INPUTS
    3390              : !!  comm= MPI communicator
    3391              : !!
    3392              : !! OUTPUT
    3393              : !!  ier= exit status, a non-zero value meaning there is an error
    3394              : !!
    3395              : !! SIDE EFFECTS
    3396              : !!  xval= buffer array
    3397              : !!
    3398              : !! SOURCE
    3399              : 
    3400            0 : subroutine xmpi_sum_c3cplx(xval,comm,ier)
    3401              : 
    3402              : !Arguments----------------
    3403              :  complex(sp), DEV_CONTARRD intent(inout) :: xval(:,:,:)
    3404              :  integer,intent(in) :: comm
    3405              :  integer,intent(out) :: ier
    3406              : 
    3407              : !Local variables--------------
    3408              : #if defined HAVE_MPI
    3409              :  integer :: my_dt,my_op,n1,n2,n3,nn,nproc_space_comm
    3410              :  integer(kind=int64) :: ntot
    3411            0 :  complex(sp), allocatable :: xsum(:,:,:)
    3412              : #endif
    3413              : ! *************************************************************************
    3414              : 
    3415            0 :  ier=0
    3416              : #if defined HAVE_MPI
    3417            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3418            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3419            0 :    if (nproc_space_comm /= 1) then
    3420            0 :      n1 =size(xval,dim=1)
    3421            0 :      n2 =size(xval,dim=2)
    3422            0 :      n3 =size(xval,dim=3)
    3423              : 
    3424              :      !This product of dimensions can be greater than a 32bit integer
    3425              :      !We use a INT64 to store it. If it is too large, we switch to an
    3426              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    3427            0 :      ntot=int(n1,kind=int64)*n2*n3
    3428            0 :      if (ntot<=xmpi_maxint32_64) then
    3429            0 :        nn=n1*n2*n3 ; my_dt=MPI_COMPLEX ; my_op=MPI_SUM
    3430              :      else
    3431            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_COMPLEX,my_dt,my_op,MPI_SUM)
    3432              :      end if
    3433              : 
    3434              : !    Accumulate xval on all proc. in comm
    3435              : #if defined HAVE_MPI2_INPLACE
    3436            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    3437              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    3438            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    3439              :      else
    3440              : #endif
    3441            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3), ier)
    3442            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c3cplx')
    3443            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    3444            0 :        xval (:,:,:) = xsum(:,:,:)
    3445            0 :        ABI_FREE(xsum)
    3446              : #if defined HAVE_MPI2_INPLACE
    3447              :      endif
    3448              : #endif
    3449              : 
    3450            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    3451              :    end if
    3452              :  end if
    3453              : #endif
    3454              : 
    3455            0 : end subroutine xmpi_sum_c3cplx
    3456              : !!***
    3457              : 
    3458              : !----------------------------------------------------------------------
    3459              : 
    3460              : !!****f* ABINIT/xmpi_sum_c4cplx
    3461              : !! NAME
    3462              : !!  xmpi_sum_c4cplx
    3463              : !!
    3464              : !! FUNCTION
    3465              : !!  Combines values from all processes and distribute
    3466              : !!  the result back to all processes.
    3467              : !!  Target: four-dimensional complex arrays.
    3468              : !!
    3469              : !! INPUTS
    3470              : !!  comm= MPI communicator
    3471              : !!
    3472              : !! OUTPUT
    3473              : !!  ier= exit status, a non-zero value meaning there is an error
    3474              : !!
    3475              : !! SIDE EFFECTS
    3476              : !!  xval= buffer array
    3477              : !!
    3478              : !! SOURCE
    3479              : 
    3480            0 : subroutine xmpi_sum_c4cplx(xval,comm,ier)
    3481              : 
    3482              : !Arguments----------------
    3483              :  complex(sp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:)
    3484              :  integer,intent(in) :: comm
    3485              :  integer,intent(out) :: ier
    3486              : 
    3487              : !Local variables--------------
    3488              : #if defined HAVE_MPI
    3489              :  integer :: my_dt,my_op,n1,n2,n3,n4,nn,nproc_space_comm
    3490              :  integer(kind=int64) :: ntot
    3491            0 :  complex(sp),allocatable :: xsum(:,:,:,:)
    3492              : #endif
    3493              : ! *************************************************************************
    3494              : 
    3495            0 :  ier=0
    3496              : #if defined HAVE_MPI
    3497            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3498            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3499            0 :    if (nproc_space_comm /= 1) then
    3500            0 :      n1 =size(xval,dim=1)
    3501            0 :      n2 =size(xval,dim=2)
    3502            0 :      n3 =size(xval,dim=3)
    3503            0 :      n4 =size(xval,dim=4)
    3504              : 
    3505              :      !This product of dimensions can be greater than a 32bit integer
    3506              :      !We use a INT64 to store it. If it is too large, we switch to an
    3507              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    3508            0 :      ntot=int(n1,kind=int64)*n2*n3*n4
    3509            0 :      if (ntot<=xmpi_maxint32_64) then
    3510            0 :        nn=n1*n2*n3*n4 ; my_dt=MPI_COMPLEX ; my_op=MPI_SUM
    3511              :      else
    3512            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_COMPLEX,my_dt,my_op,MPI_SUM)
    3513              :      end if
    3514              : 
    3515              : !    Accumulate xval on all proc. in comm
    3516              : #if defined HAVE_MPI2_INPLACE
    3517            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    3518              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    3519            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    3520              :      else
    3521              : #endif
    3522            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4), ier)
    3523            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c4cplx')
    3524            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    3525            0 :        xval (:,:,:,:) = xsum(:,:,:,:)
    3526            0 :        ABI_FREE(xsum)
    3527              : #if defined HAVE_MPI2_INPLACE
    3528              :      endif
    3529              : #endif
    3530              : 
    3531            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    3532              :    end if
    3533              :  end if
    3534              : #endif
    3535              : 
    3536            0 : end subroutine xmpi_sum_c4cplx
    3537              : !!***
    3538              : 
    3539              : !----------------------------------------------------------------------
    3540              : 
    3541              : !!****f* ABINIT/xmpi_sum_c5cplx
    3542              : !! NAME
    3543              : !!  xmpi_sum_c5cplx
    3544              : !!
    3545              : !! FUNCTION
    3546              : !!  Combines values from all processes and distribute
    3547              : !!  the result back to all processes.
    3548              : !!  Target: five-dimensional complex arrays.
    3549              : !!
    3550              : !! INPUTS
    3551              : !!  comm= MPI communicator
    3552              : !!
    3553              : !! OUTPUT
    3554              : !!  ier= exit status, a non-zero value meaning there is an error
    3555              : !!
    3556              : !! SIDE EFFECTS
    3557              : !!  xval= buffer array
    3558              : !!
    3559              : !! SOURCE
    3560              : 
    3561            0 : subroutine xmpi_sum_c5cplx(xval,comm,ier)
    3562              : 
    3563              : !Arguments----------------
    3564              :  complex(sp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:)
    3565              :  integer,intent(in) :: comm
    3566              :  integer,intent(out) :: ier
    3567              : 
    3568              : !Local variables--------------
    3569              : #if defined HAVE_MPI
    3570              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,nn,nproc_space_comm
    3571              :  integer(kind=int64) :: ntot
    3572            0 :  complex(sp),allocatable :: xsum(:,:,:,:,:)
    3573              : #endif
    3574              : ! *************************************************************************
    3575              : 
    3576            0 :  ier=0
    3577              : #if defined HAVE_MPI
    3578            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3579            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3580            0 :    if (nproc_space_comm /= 1) then
    3581            0 :      n1 =size(xval,dim=1)
    3582            0 :      n2 =size(xval,dim=2)
    3583            0 :      n3 =size(xval,dim=3)
    3584            0 :      n4 =size(xval,dim=4)
    3585            0 :      n5 =size(xval,dim=5)
    3586              : 
    3587              :      !This product of dimensions can be greater than a 32bit integer
    3588              :      !We use a INT64 to store it. If it is too large, we switch to an
    3589              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    3590            0 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5
    3591            0 :      if (ntot<=xmpi_maxint32_64) then
    3592            0 :        nn=n1*n2*n3*n4*n5 ; my_dt=MPI_COMPLEX ; my_op=MPI_SUM
    3593              :      else
    3594            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_COMPLEX,my_dt,my_op,MPI_SUM)
    3595              :      end if
    3596              : 
    3597              : !    Accumulate xval on all proc. in comm
    3598              : #if defined HAVE_MPI2_INPLACE
    3599            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    3600              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    3601            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    3602              :      else
    3603              : #endif
    3604            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5), ier)
    3605            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c5cplx')
    3606            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    3607            0 :        xval (:,:,:,:,:) = xsum(:,:,:,:,:)
    3608            0 :        ABI_FREE(xsum)
    3609              : #if defined HAVE_MPI2_INPLACE
    3610              :      endif
    3611              : #endif
    3612              : 
    3613            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    3614              :    end if
    3615              :  end if
    3616              : #endif
    3617              : 
    3618            0 : end subroutine xmpi_sum_c5cplx
    3619              : !!***
    3620              : 
    3621              : !----------------------------------------------------------------------
    3622              : 
    3623              : !!****f* ABINIT/xmpi_sum_c6cplx
    3624              : !! NAME
    3625              : !!  xmpi_sum_c6cplx
    3626              : !!
    3627              : !! FUNCTION
    3628              : !!  Combines values from all processes and distribute the result back to all processes.
    3629              : !!  Target: six-dimensional complex arrays.
    3630              : !!
    3631              : !! INPUTS
    3632              : !!  comm= MPI communicator
    3633              : !!
    3634              : !! OUTPUT
    3635              : !!  ier= exit status, a non-zero value meaning there is an error
    3636              : !!
    3637              : !! SIDE EFFECTS
    3638              : !!  xval= buffer array
    3639              : !!
    3640              : !! SOURCE
    3641              : 
    3642            0 : subroutine xmpi_sum_c6cplx(xval,comm,ier)
    3643              : 
    3644              : !Arguments----------------
    3645              :  complex(sp), DEV_CONTARRD intent(inout) :: xval(:,:,:,:,:,:)
    3646              :  integer,intent(in) :: comm
    3647              :  integer,intent(out) :: ier
    3648              : 
    3649              : !Local variables--------------
    3650              : #if defined HAVE_MPI
    3651              :  integer :: my_dt,my_op,n1,n2,n3,n4,n5,n6,nn,nproc_space_comm
    3652              :  integer(kind=int64) :: ntot
    3653            0 :  complex(sp),allocatable :: xsum(:,:,:,:,:,:)
    3654              : #endif
    3655              : ! *************************************************************************
    3656              : 
    3657            0 :  ier=0
    3658              : #if defined HAVE_MPI
    3659            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3660            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3661            0 :    if (nproc_space_comm /= 1) then
    3662            0 :      n1 =size(xval,dim=1)
    3663            0 :      n2 =size(xval,dim=2)
    3664            0 :      n3 =size(xval,dim=3)
    3665            0 :      n4 =size(xval,dim=4)
    3666            0 :      n5 =size(xval,dim=5)
    3667            0 :      n6 =size(xval,dim=6)
    3668              : 
    3669              :      !This product of dimensions can be greater than a 32bit integer
    3670              :      !We use a INT64 to store it. If it is too large, we switch to an
    3671              :      !alternate routine because MPI<4 doesnt handle 64 bit counts.
    3672            0 :      ntot=int(n1,kind=int64)*n2*n3*n4*n5*n6
    3673            0 :      if (ntot<=xmpi_maxint32_64) then
    3674            0 :        nn=n1*n2*n3*n4*n5*n6 ; my_dt=MPI_COMPLEX ; my_op=MPI_SUM
    3675              :      else
    3676            0 :        nn=1 ; call xmpi_largetype_create(ntot,MPI_COMPLEX,my_dt,my_op,MPI_SUM)
    3677              :      end if
    3678              : 
    3679              : !    Accumulate xval on all proc. in comm
    3680              : #if defined HAVE_MPI2_INPLACE
    3681            0 :      if (xmpi_use_inplace_operations .and. my_op == MPI_SUM) then
    3682              :        if (my_op/=MPI_SUM) call xmpi_abort(msg="Too many data for in-place reductions!")
    3683            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,xval,nn,my_dt,my_op,comm,ier)
    3684              :      else
    3685              : #endif
    3686            0 :        ABI_STAT_MALLOC(xsum,(n1,n2,n3,n4,n5,n6), ier)
    3687            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum_c6cplx')
    3688            0 :        call MPI_ALLREDUCE(xval,xsum,nn,my_dt,my_op,comm,ier)
    3689            0 :        xval = xsum
    3690            0 :        ABI_FREE(xsum)
    3691              : #if defined HAVE_MPI2_INPLACE
    3692              :      endif
    3693              : #endif
    3694              : 
    3695            0 :      if (ntot>xmpi_maxint32_64) call xmpi_largetype_free(my_dt,my_op)
    3696              :    end if
    3697              :  end if
    3698              : #endif
    3699              : 
    3700            0 : end subroutine xmpi_sum_c6cplx
    3701              : !!***
    3702              : 
    3703              : !----------------------------------------------------------------------
    3704              : 
    3705              : !!****f* ABINIT/xmpi_sum_coeff5d1
    3706              : !! NAME
    3707              : !!  xmpi_sum_coeff5d1
    3708              : !!
    3709              : !! FUNCTION
    3710              : !!  Combines values from all processes and distribute the result back to all processes.
    3711              : !!  Target: coeff5_type 1D-structure
    3712              : !!
    3713              : !! INPUTS
    3714              : !!  comm= MPI communicator
    3715              : !!
    3716              : !! OUTPUT
    3717              : !!  ier= exit status, a non-zero value meaning there is an error
    3718              : !!
    3719              : !! SIDE EFFECTS
    3720              : !!  xval = coeff5d_type array structure (input and output)
    3721              : !!
    3722              : !! SOURCE
    3723              : 
    3724            0 : subroutine xmpi_sum_coeff5d1(xval,comm,ier)
    3725              : 
    3726              : !Arguments ------------------------------------
    3727              :  type(coeff5_type),intent(inout) :: xval(:)
    3728              :  integer,intent(in) :: comm
    3729              :  integer,intent(out)   :: ier
    3730              : 
    3731              : !Local variables-------------------------------
    3732              : #if defined HAVE_MPI
    3733              :  integer :: buf_size,i2,i3,i4,i5,ii,indx_buf,n1,n2,n3,n4,n5,nb,nproc_space_comm
    3734            0 :  integer, allocatable :: dims(:,:)
    3735            0 :  real(dp),allocatable :: buf(:),xsum(:)
    3736              : #endif
    3737              : ! *************************************************************************
    3738              : 
    3739            0 :  ier=0
    3740              : #if defined HAVE_MPI
    3741            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    3742            0 :    call MPI_COMM_SIZE(comm,nproc_space_comm,ier)
    3743            0 :    if (nproc_space_comm /= 1) then
    3744            0 :      nb = size(xval,1)
    3745              : 
    3746              : !    Retrieve sizes of 'value' fields
    3747            0 :      ABI_MALLOC(dims,(5,nb))
    3748            0 :      buf_size=0
    3749            0 :      do ii=1,nb
    3750            0 :        if (.not.allocated(xval(ii)%value)) &
    3751            0 : &        call xmpi_abort(msg='bug in xmpi_sum(coeff5): xval should be allocated!')
    3752            0 :        dims(1,ii)=size(xval(ii)%value,dim=1)
    3753            0 :        dims(2,ii)=size(xval(ii)%value,dim=2)
    3754            0 :        dims(3,ii)=size(xval(ii)%value,dim=3)
    3755            0 :        dims(4,ii)=size(xval(ii)%value,dim=4)
    3756            0 :        dims(5,ii)=size(xval(ii)%value,dim=5)
    3757            0 :        buf_size=buf_size+dims(1,ii)*dims(2,ii)*dims(3,ii)*dims(4,ii)*dims(5,ii)
    3758              :      end do
    3759              : 
    3760              : !    Fill in buffer
    3761            0 :      ABI_STAT_MALLOC(buf,(buf_size) ,ier)
    3762            0 :      if (ier/= 0) call xmpi_abort(msg='error allocating buf in xmpi_sum(coeff5)!')
    3763              :      indx_buf=1
    3764            0 :      do ii=1,nb
    3765            0 :        n1=dims(1,ii); n2=dims(2,ii)
    3766            0 :        n3=dims(3,ii); n4=dims(4,ii); n5=dims(5,ii)
    3767            0 :        do i5=1,n5
    3768            0 :          do i4=1,n4
    3769            0 :            do i3=1,n3
    3770            0 :              do i2=1,n2
    3771            0 :                buf(indx_buf:indx_buf+n1-1)=xval(ii)%value(1:n1,i2,i3,i4,i5)
    3772            0 :                indx_buf=indx_buf+n1
    3773              :              end do
    3774              :            end do
    3775              :          end do
    3776              :        end do
    3777              :      end do
    3778              : 
    3779              : !    Accumulate xval%value on all proc. in comm
    3780              : #if defined HAVE_MPI2_INPLACE
    3781            0 :      if (xmpi_use_inplace_operations) then
    3782            0 :        call MPI_ALLREDUCE(MPI_IN_PLACE,buf,buf_size,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
    3783              :      else
    3784              : #endif
    3785            0 :        ABI_STAT_MALLOC(xsum,(buf_size), ier)
    3786            0 :        if (ier/= 0) call xmpi_abort(msg='error allocating xsum in xmpi_sum(coeff5)!')
    3787            0 :        call MPI_ALLREDUCE(buf,xsum,buf_size,MPI_DOUBLE_PRECISION,MPI_SUM,comm,ier)
    3788            0 :        buf = xsum
    3789            0 :        ABI_FREE(xsum)
    3790              : #if defined HAVE_MPI2_INPLACE
    3791              :      endif
    3792              : #endif
    3793              : 
    3794              : !    Transfer buffer into output datastructure
    3795            0 :      indx_buf=1
    3796            0 :      do ii=1,nb
    3797            0 :        n1=dims(1,ii); n2=dims(2,ii)
    3798            0 :        n3=dims(3,ii); n4=dims(4,ii); n5=dims(5,ii)
    3799            0 :        do i5=1,n5
    3800            0 :          do i4=1,n4
    3801            0 :            do i3=1,n3
    3802            0 :              do i2=1,n2
    3803            0 :                xval(ii)%value(1:n1,i2,i3,i4,i5)=buf(indx_buf:indx_buf+n1-1)
    3804            0 :                indx_buf=indx_buf+n1
    3805              :              end do
    3806              :            end do
    3807              :          end do
    3808              :        end do
    3809              :      end do
    3810              : 
    3811            0 :      ABI_FREE(dims)
    3812            0 :      ABI_FREE(buf)
    3813              : 
    3814              :    end if
    3815              :  end if
    3816              : #endif
    3817              : 
    3818            0 : end subroutine xmpi_sum_coeff5d1
    3819              : !!***
        

Generated by: LCOV version 2.3-1