LCOV - code coverage report
Current view: top level - shared/common/src/12_hide_mpi - xmpi_allgatherv.finc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 25.6 % 281 72
Test Date: 2026-09-21 13:49:52 Functions: 61.5 % 13 8

            Line data    Source code
       1              : !{\src2tex{textfont=tt}}
       2              : !!****f* ABINIT/xmpi_allgatherv_int2d
       3              : !! NAME
       4              : !!  xmpi_allgatherv_int2d
       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_allgatherv is the generic function.
      10              : !!
      11              : !! COPYRIGHT
      12              : !!  Copyright (C) 2001-2026 ABINIT group (AR,XG)
      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              : !! SOURCE
      18              : 
      19        12694 : subroutine xmpi_allgatherv_int2d(xval,nelem,recvbuf,recvcounts,displs,comm,ier)
      20              : 
      21              : !Arguments-------------------------
      22              :  integer, DEV_CONTARRD intent(in) :: xval(:,:)
      23              :  integer, DEV_CONTARRD intent(inout) :: recvbuf(:,:)
      24              :  integer, DEV_CONTARRD intent(in) :: recvcounts(:),displs(:)
      25              :  integer,intent(in) :: nelem,comm
      26              :  integer,intent(out) :: ier
      27              : 
      28              : !Local variables--------------
      29              :  integer :: cc,dd,sz1
      30              : ! *************************************************************************
      31              : 
      32        12694 :  ier=0
      33              : #if defined HAVE_MPI
      34        12694 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
      35              :    call MPI_ALLGATHERV(xval,nelem,MPI_INTEGER,recvbuf,recvcounts,displs,&
      36        12660 : &   MPI_INTEGER,comm,ier)
      37           34 :  else if (comm == MPI_COMM_SELF) then
      38              : #endif
      39           34 :    sz1=size(xval,1)
      40           34 :    dd=0;if (size(displs)>0) dd=displs(1)/sz1
      41           34 :    cc=size(xval,2);if (size(recvcounts)>0) cc=recvcounts(1)/sz1
      42       626754 :    recvbuf(:,dd+1:dd+cc)=xval(:,1:cc)
      43              : #if defined HAVE_MPI
      44              :  end if
      45              : #endif
      46        12694 : end subroutine xmpi_allgatherv_int2d
      47              : !!***
      48              : 
      49              : !!****f* ABINIT/xmpi_allgatherv_int
      50              : !! NAME
      51              : !!  xmpi_allgatherv_int
      52              : !!
      53              : !! FUNCTION
      54              : !!  Gathers data from all tasks and delivers it to all.
      55              : !!  Target: one-dimensional integer arrays.
      56              : !!
      57              : !! INPUTS
      58              : !!  xval= buffer array
      59              : !!  recvcounts= number of received elements
      60              : !!  displs= relative offsets for incoming data
      61              : !!  nelem= number of elements
      62              : !!  comm= MPI communicator
      63              : !!
      64              : !! OUTPUT
      65              : !!  ier= exit status, a non-zero value meaning there is an error
      66              : !!
      67              : !! SIDE EFFECTS
      68              : !!  recvbuf= received buffer
      69              : !!
      70              : !! SOURCE
      71              : 
      72         5905 : subroutine xmpi_allgatherv_int(xval,nelem,recvbuf,recvcounts,displs,comm,ier)
      73              : 
      74              : !Arguments-------------------------
      75              :  integer, DEV_CONTARRD intent(in) :: xval(:)
      76              :  integer, DEV_CONTARRD intent(inout) :: recvbuf(:)
      77              :  integer, DEV_CONTARRD intent(in) :: recvcounts(:),displs(:)
      78              :  integer,intent(in) :: nelem,comm
      79              :  integer,intent(out) :: ier
      80              : 
      81              : !Local variables-------------------
      82              :  integer :: cc,dd
      83              : ! *************************************************************************
      84              : 
      85         5905 :  ier=0
      86              : #if defined HAVE_MPI
      87         5905 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
      88              :    call MPI_ALLGATHERV(xval,nelem,MPI_INTEGER,recvbuf,recvcounts,displs,&
      89         5889 : &   MPI_INTEGER,comm,ier)
      90           16 :  else if (comm == MPI_COMM_SELF) then
      91              : #endif
      92           16 :    dd=0;if (size(displs)>0) dd=displs(1)
      93           16 :    cc=size(xval);if (size(recvcounts)>0) cc=recvcounts(1)
      94           32 :    recvbuf(dd+1:dd+cc)=xval(1:cc)
      95              : #if defined HAVE_MPI
      96              :  end if
      97              : #endif
      98         5905 : end subroutine xmpi_allgatherv_int
      99              : !!***
     100              : 
     101              : !!****f* ABINIT/xmpi_allgatherv_int1_dp1
     102              : !! NAME
     103              : !!  xmpi_allgatherv_int1_dp1
     104              : !!
     105              : !! FUNCTION
     106              : !!  Gathers data from all tasks and delivers it to all.
     107              : !!  Target :  one-dimensional integer arrray and one-dimensionnal dp array
     108              : !!
     109              : !! INPUTS
     110              : !!  buf_int=buffer integer array that is going to be gathered
     111              : !!  buf_int_size=size of buf_int array
     112              : !!  buf_dp=buffer dp array that is going to be gathered
     113              : !!  buf_dp_size=size of buf_dp array
     114              : !!  comm=MPI communicator
     115              : !!
     116              : !! OUTPUT
     117              : !!  buf_int_all=buffer integer array gathered
     118              : !!  buf_int_size_all=size of buffer integer array gathered
     119              : !!  buf_dp_all=buffer dp array gathered
     120              : !!  buf_dp_size_all=size of buffer dp array gathered
     121              : !!  ier=exit status, a non-zero value meaning there is an error
     122              : !!
     123              : !! SOURCE
     124              : 
     125            0 : subroutine xmpi_allgatherv_int1_dp1(buf_int,buf_int_size,buf_dp,buf_dp_size,&
     126              : &       buf_int_all,buf_int_size_all,buf_dp_all,buf_dp_size_all,comm,ier)
     127              : 
     128              : !Arguments-------------------------
     129              : !scalars
     130              :  integer,intent(in) :: buf_dp_size,buf_int_size,comm
     131              :  integer,intent(out) :: buf_dp_size_all,buf_int_size_all,ier
     132              : !arrays
     133              :  integer, intent(in) :: buf_int(:)
     134              :  integer,allocatable,target,intent(out) :: buf_int_all(:)
     135              :  real(dp),intent(in) :: buf_dp(:)
     136              :  real(dp),allocatable,target,intent(out) :: buf_dp_all(:)
     137              : 
     138              : !Local variables--------------
     139              : !scalars
     140              :  integer :: buf_pack_size,ierr,ii,iproc,istart_dp,istart_int,lg,lg1,lg2,lg_dp,lg_int
     141              :  integer :: nproc,position,totalbufcount
     142              :  logical,parameter :: use_pack=.false.
     143              : !arrays
     144              :  integer :: buf_size(2),pos(3)
     145            0 :  integer ,allocatable :: buf_int_size1(:),buf_dp_size1(:)
     146            0 :  integer,allocatable :: count_dp(:),count_int(:),count_size(:),counts(:)
     147            0 :  integer,allocatable :: disp_dp(:),disp_int(:),displ(:),displ_dp(:),displ_int(:)
     148            0 :  integer,allocatable :: pos_all(:)
     149            0 :  integer,pointer :: outbuf_int(:)
     150            0 :  real(dp),pointer:: outbuf_dp(:)
     151            0 :  character,allocatable :: buf_pack(:),buf_pack_tot(:)
     152              : ! *************************************************************************
     153              : 
     154            0 :  ier=0
     155              : 
     156              : #if defined HAVE_MPI
     157            0 :  if (comm/=MPI_COMM_SELF.and.comm/=MPI_COMM_NULL) then
     158              : 
     159            0 :    nproc=xmpi_comm_size(comm)
     160              : 
     161              : !First version: using 2 allgather (one for ints, another for reals)
     162              : !------------------------------------------------------------------
     163              :    if (.not.use_pack) then
     164              : 
     165              : !  Prepare communications
     166            0 :      ABI_MALLOC(count_int,(nproc))
     167            0 :      ABI_MALLOC(disp_int,(nproc))
     168            0 :      ABI_MALLOC(count_dp,(nproc))
     169            0 :      ABI_MALLOC(disp_dp,(nproc))
     170            0 :      ABI_MALLOC(count_size,(2*nproc))
     171            0 :      buf_size(1)=buf_int_size; buf_size(2)=buf_dp_size
     172            0 :      call xmpi_allgather(buf_size,2,count_size,comm,ier)
     173            0 :      do iproc=1,nproc
     174            0 :        count_int(iproc)=count_size(2*iproc-1)
     175            0 :        count_dp(iproc)=count_size(2*iproc)
     176              :      end do
     177            0 :      disp_int(1)=0;disp_dp(1)=0
     178            0 :      do ii=2,nproc
     179            0 :        disp_int(ii)=disp_int(ii-1)+count_int(ii-1)
     180            0 :        disp_dp (ii)=disp_dp (ii-1)+count_dp (ii-1)
     181              :      end do
     182            0 :      buf_int_size_all=sum(count_int)
     183            0 :      buf_dp_size_all =sum(count_dp)
     184              : 
     185            0 :      ABI_STAT_MALLOC(buf_int_all,(buf_int_size_all), ier)
     186            0 :      if (ier/=0) call xmpi_abort(msg='error allocating buf_int_all in xmpi_allgatherv')
     187            0 :      ABI_STAT_MALLOC(buf_dp_all ,(buf_dp_size_all), ierr)
     188              :      if (ier/=0) call xmpi_abort(msg='error allocating buf_dp_all in xmpi_allgatherv')
     189              : 
     190              : !  Communicate (one call for integers, one call for reals)
     191            0 :      call xmpi_allgatherv(buf_int,buf_int_size,buf_int_all,count_int,disp_int,comm,ierr)
     192            0 :      call xmpi_allgatherv(buf_dp,buf_dp_size,buf_dp_all,count_dp,disp_dp,comm,ierr)
     193              : 
     194              : !  Release the memory
     195            0 :      ABI_FREE(count_int)
     196            0 :      ABI_FREE(disp_int)
     197            0 :      ABI_FREE(count_dp)
     198            0 :      ABI_FREE(disp_dp)
     199            0 :      ABI_FREE(count_size)
     200              : 
     201              : !2nd version: using 1 allgather (with MPI_PACK)
     202              : !-----------------------------------------------------------------
     203              :    else
     204              : 
     205              : !  Compute size of message
     206              :      call MPI_PACK_SIZE(buf_int_size,MPI_INTEGER,comm,lg1,ier)
     207              :      call MPI_PACK_SIZE(buf_dp_size,MPI_DOUBLE_PRECISION,comm,lg2,ier)
     208              :      lg=lg1+lg2
     209              : 
     210              : !  Pack data to be sent
     211              :      position=0 ; buf_pack_size=lg1+lg2
     212              :      ABI_MALLOC(buf_pack,(buf_pack_size))
     213              :      call MPI_PACK(buf_int,buf_int_size,MPI_INTEGER,buf_pack,buf_pack_size,position,comm,ier)
     214              :      call MPI_PACK(buf_dp,buf_dp_size,MPI_DOUBLE_PRECISION,buf_pack,buf_pack_size,position,comm,ier)
     215              : 
     216              : !  Gather size of all packed messages
     217              :      ABI_MALLOC(pos_all,(nproc*3))
     218              :      ABI_MALLOC(counts,(nproc))
     219              :      ABI_MALLOC(buf_int_size1,(nproc))
     220              :      ABI_MALLOC(buf_dp_size1,(nproc))
     221              :      ABI_MALLOC(displ,(nproc))
     222              :      ABI_MALLOC(displ_int,(nproc))
     223              :      ABI_MALLOC(displ_dp,(nproc))
     224              :      pos(1)=position;pos(2)=buf_int_size;pos(3)=buf_dp_size
     225              :      call MPI_ALLGATHER(pos,3,MPI_INTEGER,pos_all,3,MPI_INTEGER,comm,ier)
     226              :      ii=1
     227              :      do iproc=1,nproc
     228              :        counts(iproc)=pos_all(ii);ii=ii+1
     229              :        buf_int_size1(iproc)=pos_all(ii);ii=ii+1
     230              :        buf_dp_size1(iproc)=pos_all(ii);ii=ii+1
     231              :      end do
     232              : 
     233              :      displ(1)=0 ; displ_int(1)=0 ; displ_dp(1)=0
     234              :      do iproc=2,nproc
     235              :        displ(iproc)=displ(iproc-1)+counts(iproc-1)
     236              :        displ_int(iproc)=displ_int(iproc-1)+buf_int_size1(iproc-1)
     237              :        displ_dp(iproc)=displ_dp(iproc-1)+buf_dp_size1(iproc-1)
     238              :      end do
     239              : 
     240              :      totalbufcount=displ(nproc)+counts(nproc)
     241              :      ABI_STAT_MALLOC(buf_pack_tot,(totalbufcount), ier)
     242              :      if (ier/= 0) call xmpi_abort(msg='error allocating totalbufcount in xmpi_allgatherv')
     243              :      buf_int_size_all=sum(buf_int_size1)
     244              :      buf_dp_size_all=sum(buf_dp_size1)
     245              :      ABI_STAT_MALLOC(buf_int_all,(buf_int_size_all), ier)
     246              :      if (ier/=0) call xmpi_abort(msg='error allocating buf_int_all in xmpi_allgatherv')
     247              :      ABI_STAT_MALLOC(buf_dp_all,(buf_dp_size_all), ier)
     248              :      if (ier/=0) call xmpi_abort(msg='error allocating buf_dp_size_all in xmpi_allgatherv')
     249              : 
     250              : !  Gather all packed messages
     251              :      call MPI_ALLGATHERV(buf_pack,position,MPI_PACKED,buf_pack_tot,counts,displ,MPI_PACKED,comm,ier)
     252              :      position=0
     253              :      do iproc=1,nproc
     254              :        lg_int=buf_int_size1(iproc); lg_dp=buf_dp_size1(iproc)
     255              :        istart_int=displ_int(iproc); istart_dp=displ_dp(iproc)
     256              :        outbuf_int=>buf_int_all(istart_int+1:istart_int+lg_int)
     257              :        call MPI_UNPACK(buf_pack_tot,totalbufcount,position, outbuf_int,&
     258              : &       lg_int,MPI_INTEGER,comm,ier)
     259              :        outbuf_dp=>buf_dp_all(istart_dp+1:istart_dp+lg_dp)
     260              :        call MPI_UNPACK(buf_pack_tot,totalbufcount,position,outbuf_dp,&
     261              : &       lg_dp,MPI_DOUBLE_PRECISION,comm,ier)
     262              :      end do
     263              : 
     264              : !  Release the memory
     265              :      ABI_FREE(pos_all)
     266              :      ABI_FREE(counts)
     267              :      ABI_FREE(buf_int_size1)
     268              :      ABI_FREE(buf_dp_size1)
     269              :      ABI_FREE(displ)
     270              :      ABI_FREE(displ_int)
     271              :      ABI_FREE(displ_dp)
     272              :      ABI_FREE(buf_pack_tot)
     273              :      ABI_FREE(buf_pack)
     274              : 
     275              :    end if
     276            0 :  else if (comm==MPI_COMM_SELF) then
     277              : #endif
     278              : 
     279              : !Sequential version
     280            0 :    ABI_STAT_MALLOC(buf_int_all,(buf_int_size), ier)
     281            0 :    if (ier/=0) call xmpi_abort(msg='error allocating buf_int_all in xmpi_allgatherv')
     282            0 :    ABI_STAT_MALLOC(buf_dp_all,(buf_dp_size), ier)
     283            0 :    if (ier/=0) call xmpi_abort(msg='error allocating buf_dp_all in xmpi_allgatherv')
     284              : 
     285            0 :    buf_int_all(:)=buf_int(:)
     286            0 :    buf_dp_all(:)=buf_dp(:)
     287            0 :    buf_int_size_all=buf_int_size
     288            0 :    buf_dp_size_all=buf_dp_size
     289              : 
     290              : #if defined HAVE_MPI
     291              :  end if
     292              : #endif
     293              : 
     294            0 : end subroutine xmpi_allgatherv_int1_dp1
     295              : !!***
     296              : 
     297              : !!****f* ABINIT/xmpi_allgatherv_dp
     298              : !! NAME
     299              : !!  xmpi_allgatherv_dp
     300              : !!
     301              : !! FUNCTION
     302              : !!  Gathers data from all tasks and delivers it to all.
     303              : !!  Target: one-dimensional double precision arrays.
     304              : !!
     305              : !! INPUTS
     306              : !!  xval= buffer array
     307              : !!  recvcounts= number of received elements
     308              : !!  displs= relative offsets for incoming data
     309              : !!  nelem= number of elements
     310              : !!  comm= MPI communicator
     311              : !!
     312              : !! OUTPUT
     313              : !!  ier= exit status, a non-zero value meaning there is an error
     314              : !!
     315              : !! SIDE EFFECTS
     316              : !!  recvbuf= received buffer
     317              : !!
     318              : !! SOURCE
     319              : 
     320        15314 : subroutine xmpi_allgatherv_dp(xval,nelem,recvbuf,recvcounts,displs,comm,ier)
     321              : 
     322              : !Arguments-------------------------
     323              :  real(dp), DEV_CONTARRD intent(in) :: xval(:)
     324              :  real(dp), DEV_CONTARRD intent(inout) :: recvbuf(:)
     325              :  integer,intent(in) :: recvcounts(:),displs(:)
     326              :  integer,intent(in) :: nelem,comm
     327              :  integer,intent(out) :: ier
     328              : 
     329              : !Local variables--------------
     330              :  integer :: cc,dd
     331              : 
     332              : ! *************************************************************************
     333              : 
     334        15314 :  ier=0
     335              : #if defined HAVE_MPI
     336        15314 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     337              :    call MPI_ALLGATHERV(xval,nelem,MPI_DOUBLE_PRECISION,recvbuf,recvcounts,displs,&
     338        15270 : &   MPI_DOUBLE_PRECISION,comm,ier)
     339           44 :  else if (comm == MPI_COMM_SELF) then
     340              : #endif
     341           44 :    dd=0;if (size(displs)>0) dd=displs(1)
     342           44 :    cc=size(xval);if (size(recvcounts)>0) cc=recvcounts(1)
     343       136641 :    recvbuf(dd+1:dd+cc)=xval(1:cc)
     344              : #if defined HAVE_MPI
     345              :  end if
     346              : #endif
     347        15314 : end subroutine xmpi_allgatherv_dp
     348              : !!***
     349              : 
     350              : !!****f* ABINIT/xmpi_allgatherv_dp2d
     351              : !! NAME
     352              : !!  xmpi_allgatherv_dp2d
     353              : !!
     354              : !! FUNCTION
     355              : !!  Gathers data from all tasks and delivers it to all.
     356              : !!  Target: double precision two-dimensional arrays.
     357              : !!
     358              : !! INPUTS
     359              : !!  xval= buffer array
     360              : !!  recvcounts= number of received elements
     361              : !!  displs= relative offsets for incoming data
     362              : !!  nelem= number of elements
     363              : !!  comm= MPI communicator
     364              : !!
     365              : !! OUTPUT
     366              : !!  ier= exit status, a non-zero value meaning there is an error
     367              : !!
     368              : !! SIDE EFFECTS
     369              : !!  recvbuf= received buffer
     370              : !!
     371              : !! SOURCE
     372              : 
     373         4052 : subroutine xmpi_allgatherv_dp2d(xval,nelem,recvbuf,recvcounts,displs,comm,ier)
     374              : 
     375              : !Arguments-------------------------
     376              :  real(dp), DEV_CONTARRD intent(in) :: xval(:,:)
     377              :  real(dp), DEV_CONTARRD intent(inout) :: recvbuf(:,:)
     378              :  integer, DEV_CONTARRD intent(in) :: recvcounts(:),displs(:)
     379              :  integer,intent(in) :: nelem,comm
     380              :  integer,intent(out) :: ier
     381              : 
     382              : !Local variables--------------
     383              :  integer :: cc,dd,sz1
     384              : 
     385              : ! *************************************************************************
     386              : 
     387         4052 :  ier=0
     388              : #if defined HAVE_MPI
     389         4052 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     390              :    call MPI_ALLGATHERV(xval,nelem,MPI_DOUBLE_PRECISION,recvbuf,recvcounts,displs,&
     391         4052 : &   MPI_DOUBLE_PRECISION,comm,ier)
     392            0 :  else if (comm == MPI_COMM_SELF) then
     393              : #endif
     394            0 :    sz1=size(xval,1)
     395            0 :    dd=0;if (size(displs)>0) dd=displs(1)/sz1
     396            0 :    cc=size(xval,2);if (size(recvcounts)>0) cc=recvcounts(1)/sz1
     397            0 :    recvbuf(:,dd+1:dd+cc)=xval(:,1:cc)
     398              : #if defined HAVE_MPI
     399              :  end if
     400              : #endif
     401         4052 : end subroutine xmpi_allgatherv_dp2d
     402              : !!***
     403              : 
     404              : !!****f* ABINIT/get_gcd_of_array
     405              : !! NAME
     406              : !!  get_gcd_of_array
     407              : !!
     408              : !! FUNCTION
     409              : !!  Returns the GCD (Greatest Common Divider, or PGCD in French)
     410              : !!  of an integer array.
     411              : !!
     412              : !! INPUTS
     413              : !!  tab= integer array
     414              : !!
     415              : !! OUTPUT
     416              : !!  r= GCD
     417              : !!
     418              : !! SOURCE
     419              : 
     420            0 : function get_gcd_of_array(array) result(r)
     421              : 
     422              : !Arguments-------------------------
     423              :  integer, intent(in) :: array(:)
     424              : 
     425              : !Local variables--------------
     426              :  integer :: r, i, a, b, temp
     427              : 
     428              : ! *************************************************************************
     429              : 
     430            0 :  r = array(1)
     431            0 :  do i = 2, size(array)
     432            0 :    a = r
     433            0 :    b = array(i)
     434            0 :    do while (b /= 0)
     435            0 :      temp = b
     436            0 :      b = mod(a, b)
     437            0 :      a = temp
     438              :    end do
     439            0 :    r = a
     440            0 :    if (r == 1) then
     441              :      return
     442              :    end if
     443              :  end do
     444            0 : end function get_gcd_of_array
     445              : !!***
     446              : 
     447              : !!****f* ABINIT/xmpi_allgatherv_dp3d
     448              : !! NAME
     449              : !!  xmpi_allgatherv_dp3d
     450              : !!
     451              : !! FUNCTION
     452              : !!  Gathers data from all tasks and delivers it to all.
     453              : !!  Target: double precision three-dimensional arrays.
     454              : !!
     455              : !! INPUTS
     456              : !!  xval= buffer array
     457              : !!  recvcounts= number of received elements
     458              : !!  displs= relative offsets for incoming data
     459              : !!  nelem= number of elements
     460              : !!  comm= MPI communicator
     461              : !!
     462              : !! OUTPUT
     463              : !!  ier= exit status, a non-zero value meaning there is an error
     464              : !!
     465              : !! SIDE EFFECTS
     466              : !!  recvbuf= received buffer
     467              : !!
     468              : !! SOURCE
     469              : 
     470        19798 : subroutine xmpi_allgatherv_dp3d(xval,nelem,recvbuf,recvcounts,displs,comm,ier)
     471              : 
     472              : !Arguments-------------------------
     473              :  real(dp), DEV_CONTARRD intent(in) :: xval(:,:,:)
     474              :  real(dp), DEV_CONTARRD intent(inout) :: recvbuf(:,:,:)
     475              :  integer, target, DEV_CONTARRD intent(in) :: recvcounts(:),displs(:)
     476              :  integer,intent(in) :: nelem,comm
     477              :  integer,intent(out) :: ier
     478              : 
     479              : !Local variables--------------
     480              :  integer :: cc,dd,sz12
     481              :  integer :: my_dt,my_op,n1,n2,n3,nn,r,i
     482              :  integer(kind=int64) :: ntot
     483        19798 :  integer, DEV_CONTARRD pointer :: my_recvcounts(:),my_displs(:)
     484              : 
     485              : ! *************************************************************************
     486              : 
     487        19798 :  ier=0
     488              : #if defined HAVE_MPI
     489        19798 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     490        19720 :    n1 = size(recvbuf,dim=1)
     491        19720 :    n2 = size(recvbuf,dim=2)
     492        19720 :    n3 = size(recvbuf,dim=3)
     493              : 
     494              :    !This product of dimensions can be greater than a 32bit integer
     495              :    !We use a INT64 to store it. If it is too large, we switch to an
     496              :    !alternate routine because MPI<4 doesnt handle 64 bit counts.
     497        19720 :    ntot=int(n1,kind=int64)*n2*n3
     498        19720 :    if (ntot<=xmpi_maxint32_64) then
     499        19720 :      nn=nelem ; my_dt=MPI_DOUBLE_PRECISION
     500        19720 :      my_recvcounts => recvcounts; my_displs => displs
     501              :    else
     502            0 :      r=get_gcd_of_array(recvcounts)
     503            0 :      nn=nelem/r ; call xmpi_largetype_create(int(r,int64),MPI_DOUBLE_PRECISION,my_dt,my_op,MPI_OP_NULL)
     504            0 :      ABI_MALLOC(my_recvcounts, (size(recvcounts)))
     505            0 :      my_recvcounts(:)=recvcounts(:)/r
     506            0 :      ABI_MALLOC(my_displs, (size(displs)))
     507            0 :      my_displs(1)=0
     508            0 :      do i=2,size(displs)
     509            0 :        my_displs(i)=my_displs(i-1)+my_recvcounts(i-1)
     510              :      end do
     511              :    end if
     512              :    call MPI_ALLGATHERV(xval,nn,my_dt,recvbuf,my_recvcounts,my_displs,&
     513        19720 : &   my_dt,comm,ier)
     514        19720 :    if (ntot>xmpi_maxint32_64) then
     515            0 :      call xmpi_largetype_free(my_dt,my_op)
     516            0 :      ABI_FREE(my_recvcounts); ABI_FREE(my_displs)
     517              :    end if
     518           78 :  else if (comm == MPI_COMM_SELF) then
     519              : #endif
     520           78 :    sz12=size(xval,1)*size(xval,2)
     521           78 :    dd=0;if (size(displs)>0) dd=displs(1)/sz12
     522           78 :    cc=size(xval,3);if (size(recvcounts)>0) cc=recvcounts(1)/sz12
     523      6771276 :    recvbuf(:,:,dd+1:dd+cc)=xval(:,:,1:cc)
     524              : #if defined HAVE_MPI
     525              :  end if
     526              : #endif
     527        19798 : end subroutine xmpi_allgatherv_dp3d
     528              : !!***
     529              : 
     530              : !!****f* ABINIT/xmpi_allgatherv_dp4d
     531              : !! NAME
     532              : !!  xmpi_allgatherv_dp4d
     533              : !!
     534              : !! FUNCTION
     535              : !!  Gathers data from all tasks and delivers it to all.
     536              : !!  Target: double precision four-dimensional arrays.
     537              : !!
     538              : !! INPUTS
     539              : !!  xval= buffer array
     540              : !!  recvcounts= number of received elements
     541              : !!  displs= relative offsets for incoming data
     542              : !!  nelem= number of elements
     543              : !!  comm= MPI communicator
     544              : !!
     545              : !! OUTPUT
     546              : !!  ier= exit status, a non-zero value meaning there is an error
     547              : !!
     548              : !! SIDE EFFECTS
     549              : !!  recvbuf= received buffer
     550              : !!
     551              : !! SOURCE
     552              : 
     553        19798 : subroutine xmpi_allgatherv_dp4d(xval,nelem,recvbuf,recvcounts,displs,comm,ier)
     554              : 
     555              : !Arguments-------------------------
     556              :  real(dp), DEV_CONTARRD intent(in) :: xval(:,:,:,:)
     557              :  real(dp), DEV_CONTARRD intent(inout)   :: recvbuf(:,:,:,:)
     558              :  integer, DEV_CONTARRD intent(in) :: recvcounts(:),displs(:)
     559              :  integer,intent(in) :: nelem,comm
     560              :  integer,intent(out) :: ier
     561              : 
     562              : !Local variables-------------------
     563              :  integer :: cc,dd,sz123
     564              : 
     565              : ! *************************************************************************
     566              : 
     567        19798 :  ier=0
     568              : #if defined HAVE_MPI
     569        19798 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     570              :    call MPI_ALLGATHERV(xval,nelem,MPI_DOUBLE_PRECISION,recvbuf,recvcounts,displs,&
     571        19720 : &   MPI_DOUBLE_PRECISION,comm,ier)
     572           78 :  else if (comm == MPI_COMM_SELF) then
     573              : #endif
     574           78 :    sz123=size(xval,1)*size(xval,2)*size(xval,3)
     575           78 :    dd=0;if (size(displs)>0) dd=displs(1)/sz123
     576           78 :    cc=size(xval,4);if (size(recvcounts)>0) cc=recvcounts(1)/sz123
     577     23873700 :    recvbuf(:,:,:,dd+1:dd+cc)=xval(:,:,:,1:cc)
     578              : #if defined HAVE_MPI
     579              :  end if
     580              : #endif
     581        19798 : end subroutine xmpi_allgatherv_dp4d
     582              : !!***
     583              : 
     584              : !!****f* ABINIT/xmpi_allgatherv_dp5d
     585              : !! NAME
     586              : !!  xmpi_allgatherv_dp5d
     587              : !!
     588              : !! FUNCTION
     589              : !!  Gathers data from all tasks and delivers it to all.
     590              : !!  Target: double precision six-dimensional arrays.
     591              : !!
     592              : !! INPUTS
     593              : !!  xval= buffer array
     594              : !!  recvcounts= number of received elements
     595              : !!  displs= relative offsets for incoming data
     596              : !!  nelem= number of elements
     597              : !!  comm= MPI communicator
     598              : !!
     599              : !! OUTPUT
     600              : !!  ier= exit status, a non-zero value meaning there is an error
     601              : !!
     602              : !! SIDE EFFECTS
     603              : !!  recvbuf= received buffer
     604              : !!
     605              : !! SOURCE
     606              : 
     607           39 : subroutine xmpi_allgatherv_dp5d(xval,nelem,recvbuf,recvcounts,displs,comm,ier)
     608              : 
     609              : !Arguments-------------------------
     610              :  real(dp), DEV_CONTARRD intent(in) :: xval(:,:,:,:,:)
     611              :  real(dp), DEV_CONTARRD intent(inout)   :: recvbuf(:,:,:,:,:)
     612              :  integer, DEV_CONTARRD intent(in) :: recvcounts(:),displs(:)
     613              :  integer,intent(in) :: nelem,comm
     614              :  integer,intent(out) :: ier
     615              : 
     616              : !Local variables-------------------
     617              :  integer :: cc,dd,sz1234
     618              : 
     619              : ! *************************************************************************
     620              : 
     621           39 :  ier=0
     622              : #if defined HAVE_MPI
     623           39 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     624              :    call MPI_ALLGATHERV(xval,nelem,MPI_DOUBLE_PRECISION,recvbuf,recvcounts,displs,&
     625           39 : &   MPI_DOUBLE_PRECISION,comm,ier)
     626            0 :  else if (comm == MPI_COMM_SELF) then
     627              : #endif
     628            0 :    sz1234=size(xval,1)*size(xval,2)*size(xval,3)*size(xval,4)
     629            0 :    dd=0;if (size(displs)>0) dd=displs(1)/sz1234
     630            0 :    cc=size(xval,5);if (size(recvcounts)>0) cc=recvcounts(1)/sz1234
     631            0 :    recvbuf(:,:,:,:,dd+1:dd+cc)=xval(:,:,:,:,1:cc)
     632              : #if defined HAVE_MPI
     633              :  end if
     634              : #endif
     635           39 : end subroutine xmpi_allgatherv_dp5d
     636              : !!***
     637              : 
     638              : 
     639              : !!****f* ABINIT/xmpi_allgatherv_dp6d
     640              : !! NAME
     641              : !!  xmpi_allgatherv_dp6d
     642              : !!
     643              : !! FUNCTION
     644              : !!  Gathers data from all tasks and delivers it to all.
     645              : !!  Target: double precision six-dimensional arrays.
     646              : !!
     647              : !! INPUTS
     648              : !!  xval= buffer array
     649              : !!  recvcounts= number of received elements
     650              : !!  displs= relative offsets for incoming data
     651              : !!  nelem= number of elements
     652              : !!  comm= MPI communicator
     653              : !!
     654              : !! OUTPUT
     655              : !!  ier= exit status, a non-zero value meaning there is an error
     656              : !!
     657              : !! SIDE EFFECTS
     658              : !!  recvbuf= received buffer
     659              : !!
     660              : !! SOURCE
     661              : 
     662            0 : subroutine xmpi_allgatherv_dp6d(xval,nelem,recvbuf,recvcounts,displs,comm,ier)
     663              : 
     664              : !Arguments-------------------------
     665              :  real(dp), DEV_CONTARRD intent(in) :: xval(:,:,:,:,:,:)
     666              :  real(dp), DEV_CONTARRD intent(inout)   :: recvbuf(:,:,:,:,:,:)
     667              :  integer, DEV_CONTARRD intent(in) :: recvcounts(:),displs(:)
     668              :  integer,intent(in) :: nelem,comm
     669              :  integer,intent(out) :: ier
     670              : 
     671              : !Local variables-------------------
     672              :  integer :: cc,dd,sz12345
     673              : 
     674              : ! *************************************************************************
     675              : 
     676            0 :  ier=0
     677              : #if defined HAVE_MPI
     678            0 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
     679              :    call MPI_ALLGATHERV(xval,nelem,MPI_DOUBLE_PRECISION,recvbuf,recvcounts,displs,&
     680            0 : &   MPI_DOUBLE_PRECISION,comm,ier)
     681            0 :  else if (comm == MPI_COMM_SELF) then
     682              : #endif
     683            0 :    sz12345=size(xval,1)*size(xval,2)*size(xval,3)*size(xval,4)*size(xval,5)
     684            0 :    dd=0;if (size(displs)>0) dd=displs(1)/sz12345
     685            0 :    cc=size(xval,6);if (size(recvcounts)>0) cc=recvcounts(1)/sz12345
     686            0 :    recvbuf(:,:,:,:,:,dd+1:dd+cc)=xval(:,:,:,:,:,1:cc)
     687              : #if defined HAVE_MPI
     688              :  end if
     689              : #endif
     690            0 : end subroutine xmpi_allgatherv_dp6d
     691              : !!***
     692              : 
     693              : !!****f* ABINIT/xmpi_allgatherv_coeff2d
     694              : !! NAME
     695              : !!  xmpi_allgatherv_coeff2d
     696              : !!
     697              : !! FUNCTION
     698              : !!  Gathers data from all tasks and delivers it to all.
     699              : !!  Target: coeff2_type 1D-structure
     700              : !!
     701              : !! INPUTS
     702              : !!  xval_in = coeff2d_type array structure
     703              : !!  comm= MPI communicator
     704              : !!
     705              : !! OUTPUT
     706              : !!  xval_out = coeff2d_type array structure
     707              : !!  ier= exit status, a non-zero value meaning there is an error
     708              : !!
     709              : !! SIDE EFFECTS
     710              : !!
     711              : !! SOURCE
     712              : 
     713            0 : subroutine xmpi_allgatherv_coeff2d(xval_in,xval_out,comm,ierr)
     714              : 
     715              : !Arguments ------------------------------------
     716              : !scalars
     717              :  integer,intent(in) :: comm
     718              :  integer,intent(out)   :: ierr
     719              : !arrays
     720              :  type(coeff2_type),intent(in) :: xval_in(:)
     721              :  type(coeff2_type),intent(out) :: xval_out(:)
     722              : 
     723              : !Local variables-------------------------------
     724              : !scalars
     725              :  integer :: ii,n1,n2
     726              : #if defined HAVE_MPI
     727              :  integer :: buf_int_size,buf_int_size_all,buf_dp_size,buf_dp_size_all
     728              :  integer :: i2,indx_int,indx_dp,nb,nb_out,nproc
     729              : #endif
     730              : !arrays
     731              : #if defined HAVE_MPI
     732            0 :  integer, allocatable ::  buf_int(:),buf_int_all(:)
     733            0 :  integer, allocatable :: dimxval(:,:)
     734            0 :  real(dp),allocatable :: buf_dp(:),buf_dp_all(:)
     735              : #endif
     736              : 
     737              : ! *************************************************************************
     738              : 
     739            0 :  ierr=0
     740              : #if defined HAVE_MPI
     741            0 :  if (comm /= MPI_COMM_NULL) then
     742              : 
     743            0 :    nproc=xmpi_comm_size(comm)
     744            0 :    nb = size(xval_in,1)
     745              : 
     746            0 :    if (comm==MPI_COMM_SELF.or.nproc==1) then
     747            0 :      do ii=1,nb
     748            0 :        n1=size(xval_in(ii)%value,1)
     749            0 :        n2=size(xval_in(ii)%value,2)
     750            0 :        if (allocated(xval_out(ii)%value)) then
     751            0 :          ABI_FREE(xval_out(ii)%value)
     752              :        end if
     753            0 :        ABI_STAT_MALLOC(xval_out(ii)%value,(n1,n2), ierr)
     754            0 :        if (ierr/= 0) call xmpi_abort(msg='error allocating xval_out%value in xmpi_allgatherv')
     755            0 :        xval_out(ii)%value=xval_in(ii)%value
     756              :      end do
     757              :      return
     758              :    end if
     759              : 
     760            0 :    buf_dp_size=0
     761            0 :    ABI_MALLOC(dimxval,(nb,2))
     762            0 :    do ii=1,nb
     763            0 :      dimxval(ii,1)=size(xval_in(ii)%value,dim=1)
     764            0 :      dimxval(ii,2)=size(xval_in(ii)%value,dim=2)
     765            0 :      buf_dp_size=buf_dp_size+dimxval(ii,1)*dimxval(ii,2)
     766              :    end do
     767              : 
     768            0 :    buf_int_size=2*nb;
     769            0 :    ABI_STAT_MALLOC(buf_int,(buf_int_size), ierr)
     770            0 :    if (ierr/= 0) call xmpi_abort(msg='error allocating buf_int in xmpi_allgatherv')
     771              :    indx_int=1
     772            0 :    do ii=1,nb
     773            0 :      buf_int(indx_int  )=dimxval(ii,1)
     774            0 :      buf_int(indx_int+1)=dimxval(ii,2)
     775            0 :      indx_int=indx_int+2
     776              :    end do
     777              : 
     778            0 :    ABI_STAT_MALLOC(buf_dp,(buf_dp_size) ,ierr)
     779            0 :    if (ierr/= 0) call xmpi_abort(msg='error allocating buf_dp_size in xmpi_allgatherv')
     780              :    indx_dp=1
     781            0 :    do ii=1,nb
     782            0 :      n1=dimxval(ii,1); n2=dimxval(ii,2)
     783            0 :      do i2=1,n2
     784            0 :        buf_dp(indx_dp:indx_dp+n1-1)=xval_in(ii)%value(1:n1,i2)
     785            0 :        indx_dp=indx_dp+n1
     786              :      end do
     787              :    end do
     788              : 
     789              :    call xmpi_allgatherv(buf_int,buf_int_size,buf_dp,buf_dp_size,buf_int_all, &
     790            0 : &   buf_int_size_all,buf_dp_all,buf_dp_size_all,comm,ierr)
     791              : 
     792              : 
     793            0 :    nb_out=buf_int_size_all/2
     794              : 
     795            0 :    indx_int=1;indx_dp=1
     796            0 :    do ii=1,nb_out
     797            0 :      n1=buf_int_all(indx_int)
     798            0 :      n2=buf_int_all(indx_int+1)
     799            0 :      indx_int=indx_int+2
     800            0 :      if (allocated(xval_out(ii)%value)) then
     801            0 :        ABI_FREE(xval_out(ii)%value)
     802              :      end if
     803            0 :      ABI_STAT_MALLOC(xval_out(ii)%value,(n1,n2), ierr)
     804            0 :      if (ierr/= 0) call xmpi_abort(msg='error allocating xval_out%value in xmpi_allgatherv')
     805            0 :      do i2=1,n2
     806            0 :        xval_out(ii)%value(1:n1,i2)=buf_dp_all(indx_dp:indx_dp+n1-1)
     807            0 :        indx_dp=indx_dp+n1
     808              :      end do
     809              :    end do
     810              : 
     811              : 
     812            0 :    ABI_FREE(buf_dp_all)
     813            0 :    ABI_FREE(buf_int_all)
     814            0 :    ABI_FREE(buf_int)
     815            0 :    ABI_FREE(buf_dp)
     816            0 :    ABI_FREE(dimxval)
     817              : 
     818              :  end if
     819              : 
     820              : #else
     821              :  do ii=1,size(xval_in,1)
     822              :    n1=size(xval_in(ii)%value,1)
     823              :    n2=size(xval_in(ii)%value,2)
     824              :    if (allocated(xval_out(ii)%value)) then
     825              :      ABI_FREE(xval_out(ii)%value)
     826              :    end if
     827              :    ABI_STAT_MALLOC(xval_out(ii)%value,(n1,n2), ierr)
     828              :    if (ierr/= 0) call xmpi_abort(msg='error allocating xval_out%value in xmpi_allgatherv')
     829              :    xval_out(ii)%value=xval_in(ii)%value
     830              :  end do
     831              : #endif
     832              : 
     833            0 : end subroutine xmpi_allgatherv_coeff2d
     834              : !!***
     835              : 
     836              : !!****f* ABINIT/xmpi_allgatherv_coeff2d_indx
     837              : !! NAME
     838              : !!  xmpi_allgatherv_coeff2d_indx
     839              : !!
     840              : !! FUNCTION
     841              : !!  Gathers data from all tasks and delivers it to all.
     842              : !!  Target: coeff2_type 1D-structure
     843              : !!          use of an indirect index to sort data
     844              : !!
     845              : !! INPUTS
     846              : !!  xval_in = coeff2d_type array structure
     847              : !!  comm= MPI communicator
     848              : !!  indx= gives the indexes of xval_in in xval_out.
     849              : !!        xval_in(i) will be transfered in xval_out(indx(i))
     850              : !!
     851              : !! OUTPUT
     852              : !!  xval_out = coeff2d_type array structure
     853              : !!  ierr= exit status, a non-zero value meaning there is an error
     854              : !!
     855              : !! SOURCE
     856              : 
     857            0 : subroutine xmpi_allgatherv_coeff2d_indx(xval_in,xval_out,comm,indx,ierr)
     858              : 
     859              : !Arguments ------------------------------------
     860              : !scalars
     861              :  integer,intent(in) :: comm
     862              :  integer,intent(out)   :: ierr
     863              : !arrays
     864              :  integer,intent(in) :: indx(:)
     865              :  type(coeff2_type),intent(in) :: xval_in(:)
     866              :  type(coeff2_type),intent(out) :: xval_out(:)
     867              : 
     868              : !Local variables-------------------------------
     869              : !scalars
     870              :  integer :: ii,ival,n1,n2,nb
     871              : #if defined HAVE_MPI
     872              :  integer :: buf_int_size,buf_int_size_all,buf_dp_size,buf_dp_size_all
     873              :  integer :: i2,indx_int,indx_dp,nb_out,nproc
     874              : #endif
     875              : !arrays
     876              : #if defined HAVE_MPI
     877            0 :  integer, allocatable :: buf_int(:),buf_int_all(:)
     878            0 :  integer, allocatable :: dimxval(:,:)
     879            0 :  real(dp),allocatable :: buf_dp(:),buf_dp_all(:)
     880              : #endif
     881              : 
     882              : ! *************************************************************************
     883              : 
     884            0 :  ierr=0 ; nb = size(xval_in,1)
     885              : 
     886              : #if defined HAVE_MPI
     887            0 :  if (comm == MPI_COMM_NULL) return
     888            0 :  nproc=xmpi_comm_size(comm)
     889            0 :  if (comm==MPI_COMM_SELF.or.nproc==1) then
     890              : #endif
     891            0 :    do ii=1,nb
     892            0 :      n1=size(xval_in(ii)%value,1)
     893            0 :      n2=size(xval_in(ii)%value,2)
     894            0 :      ival=indx(ii)
     895            0 :      if (allocated(xval_out(ival)%value)) then
     896            0 :        ABI_FREE(xval_out(ival)%value)
     897              :      end if
     898            0 :      ABI_STAT_MALLOC(xval_out(ival)%value,(n1,n2), ierr)
     899            0 :      if (ierr/= 0) call xmpi_abort(msg='error allocating xval_out%value in xmpi_allgatherv')
     900            0 :      xval_out(ii)%value=xval_in(ival)%value
     901              :    end do
     902              :    return
     903              : 
     904              : #if defined HAVE_MPI
     905              :  end if
     906              : 
     907            0 :  buf_dp_size=0
     908            0 :  ABI_STAT_MALLOC(dimxval,(nb,2), ierr)
     909            0 :  if (ierr/= 0) call xmpi_abort(msg='error allocating dimxval in xmpi_allgatherv')
     910            0 :  do ii=1,nb
     911            0 :    dimxval(ii,1)=size(xval_in(ii)%value,dim=1)
     912            0 :    dimxval(ii,2)=size(xval_in(ii)%value,dim=2)
     913            0 :    buf_dp_size=buf_dp_size+dimxval(ii,1)*dimxval(ii,2)
     914              :  end do
     915              : 
     916            0 :  buf_int_size=3*nb
     917            0 :  ABI_STAT_MALLOC(buf_int,(buf_int_size), ierr)
     918            0 :  if (ierr/= 0) call xmpi_abort(msg='error allocating buf_int in xmpi_allgatherv')
     919              :  indx_int=1
     920            0 :  do ii=1,nb
     921            0 :    buf_int(indx_int  )=dimxval(ii,1)
     922            0 :    buf_int(indx_int+1)=dimxval(ii,2)
     923            0 :    buf_int(indx_int+2)=indx(ii)
     924            0 :    indx_int=indx_int+3
     925              :  end do
     926              : 
     927            0 :  ABI_STAT_MALLOC(buf_dp,(buf_dp_size), ierr)
     928            0 :  if (ierr/= 0) call xmpi_abort(msg='error allocating buf_dp in xmpi_allgatherv')
     929              :  indx_dp=1
     930            0 :  do ii=1,nb
     931            0 :    n1=dimxval(ii,1); n2=dimxval(ii,2)
     932            0 :    do i2=1,n2
     933            0 :      buf_dp(indx_dp:indx_dp+n1-1)=xval_in(ii)%value(1:n1,i2)
     934            0 :      indx_dp=indx_dp+n1
     935              :    end do
     936              :  end do
     937              : 
     938              :  call xmpi_allgatherv(buf_int,buf_int_size,buf_dp,buf_dp_size,buf_int_all, &
     939            0 : &   buf_int_size_all,buf_dp_all,buf_dp_size_all,comm,ierr)
     940              : 
     941            0 :  nb_out=buf_int_size_all/3
     942            0 :  indx_int=1;indx_dp=1
     943            0 :  do ii=1,nb_out
     944            0 :    n1=buf_int_all(indx_int)
     945            0 :    n2=buf_int_all(indx_int+1)
     946            0 :    ival=buf_int_all(indx_int+2)
     947            0 :    indx_int=indx_int+3
     948            0 :    if (allocated(xval_out(ival)%value)) then
     949            0 :      ABI_FREE(xval_out(ival)%value)
     950              :    end if
     951            0 :    ABI_STAT_MALLOC(xval_out(ival)%value,(n1,n2), ierr)
     952            0 :    if (ierr/= 0) call xmpi_abort(msg='error allocating xval_out%value in xmpi_allgatherv')
     953            0 :    do i2=1,n2
     954            0 :      xval_out(ival)%value(1:n1,i2)=buf_dp_all(indx_dp:indx_dp+n1-1)
     955            0 :      indx_dp=indx_dp+n1
     956              :    end do
     957              :  end do
     958              : 
     959            0 :  ABI_FREE(buf_dp_all)
     960            0 :  ABI_FREE(buf_int_all)
     961            0 :  ABI_FREE(buf_int)
     962            0 :  ABI_FREE(buf_dp)
     963            0 :  ABI_FREE(dimxval)
     964              : #endif
     965              : 
     966              : end subroutine xmpi_allgatherv_coeff2d_indx
     967              : !!***
     968              : 
     969              : !!****f* ABINIT/xmpi_allgatherv_dc
     970              : !! NAME
     971              : !!  xmpi_allgatherv_dc
     972              : !!
     973              : !! FUNCTION
     974              : !!  Gathers data from all tasks and delivers it to all.
     975              : !!  Target: one-dimensional double complex arrays.
     976              : !!
     977              : !! INPUTS
     978              : !!  xval= buffer array
     979              : !!  recvcounts= number of received elements
     980              : !!  displs= relative offsets for incoming data
     981              : !!  nelem= number of elements
     982              : !!  comm= MPI communicator
     983              : !!
     984              : !! OUTPUT
     985              : !!  ier= exit status, a non-zero value meaning there is an error
     986              : !!
     987              : !! SIDE EFFECTS
     988              : !!  recvbuf= received buffer
     989              : !!
     990              : !! SOURCE
     991              : 
     992         8277 : subroutine xmpi_allgatherv_dc(xval,nelem,recvbuf,recvcounts,displs,comm,ier)
     993              : 
     994              : !Arguments-------------------------
     995              :  complex(dp), DEV_CONTARRD intent(in) :: xval(:)
     996              :  complex(dp), DEV_CONTARRD intent(inout) :: recvbuf(:)
     997              :  integer,intent(in) :: recvcounts(:),displs(:)
     998              :  integer,intent(in) :: nelem,comm
     999              :  integer,intent(out) :: ier
    1000              : 
    1001              : !Local variables--------------
    1002              :  integer :: cc,dd
    1003              : ! *************************************************************************
    1004              : 
    1005         8277 :  ier=0
    1006              : #if defined HAVE_MPI
    1007         8277 :  if (comm /= MPI_COMM_SELF .and. comm /= MPI_COMM_NULL) then
    1008              :    call MPI_ALLGATHERV(xval,nelem,MPI_DOUBLE_COMPLEX,recvbuf,recvcounts,displs,&
    1009         8277 : &   MPI_DOUBLE_COMPLEX,comm,ier)
    1010            0 :  else if (comm == MPI_COMM_SELF) then
    1011              : #endif
    1012            0 :    dd=0;if (size(displs)>0) dd=displs(1)
    1013            0 :    cc=size(xval);if (size(recvcounts)>0) cc=recvcounts(1)
    1014            0 :    recvbuf(dd+1:dd+cc)=xval(1:cc)
    1015              : #if defined HAVE_MPI
    1016              :  end if
    1017              : #endif
    1018         8277 : end subroutine xmpi_allgatherv_dc
    1019              : !!***
        

Generated by: LCOV version 2.3-1