LCOV - code coverage report
Current view: top level - shared/libpaw/src - m_paral_atom.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 75.0 % 72 54
Test Date: 2026-11-07 19:31:18 Functions: 80.0 % 5 4
Branches: 50.0 % 82 41

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_paral_atom
       2                 :             : !! NAME
       3                 :             : !!  m_paral_atom
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  This module provides routines and methods used to manage the parallelisation/distribution
       7                 :             : !!  of PAW data over atomic sites
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !! Copyright (C) 2012-2026 ABINIT group (MT, MD)
      11                 :             : !! This file is distributed under the terms of the
      12                 :             : !! GNU General Public License, see ~abinit/COPYING
      13                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      14                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
      15                 :             : !!
      16                 :             : !! NOTES
      17                 :             : !!  FOR DEVELOPPERS: in order to preserve the portability of libPAW library,
      18                 :             : !!  please consult ~abinit/src/??_libpaw/libpaw-coding-rules.txt
      19                 :             : !!
      20                 :             : !! SOURCE
      21                 :             : 
      22                 :             : #include "libpaw.h"
      23                 :             : 
      24                 :             : MODULE m_paral_atom
      25                 :             : 
      26                 :             :  USE_DEFS
      27                 :             :  USE_MSG_HANDLING
      28                 :             :  USE_MPI_WRAPPERS
      29                 :             :  USE_MEMORY_PROFILING
      30                 :             : 
      31                 :             :  implicit none
      32                 :             : 
      33                 :             :  private
      34                 :             : 
      35                 :             : !public procedures.
      36                 :             :  public :: get_my_natom
      37                 :             :  public :: get_my_atmtab
      38                 :             :  public :: free_my_atmtab
      39                 :             :  public :: get_proc_atmtab
      40                 :             :  public :: get_atm_proc
      41                 :             : !!***
      42                 :             : 
      43                 :             : CONTAINS
      44                 :             : !!***
      45                 :             : 
      46                 :             : !----------------------------------------------------------------------
      47                 :             : 
      48                 :             : !!****f* m_paral_atom/get_my_natom
      49                 :             : !! NAME
      50                 :             : !! get_my_natom
      51                 :             : !!
      52                 :             : !! FUNCTION
      53                 :             : !! Given the total number of atoms, return the number of atoms treated by current process
      54                 :             : !!
      55                 :             : !! INPUTS
      56                 :             : !!  comm_atom=communicator over atoms
      57                 :             : !!  natom=total number of atoms
      58                 :             : !!
      59                 :             : !! OUTPUT
      60                 :             : !!  my_natom=number of atoms treated by current process
      61                 :             : !!
      62                 :             : !! SOURCE
      63                 :             : 
      64                 :             : 
      65                 :        2284 : subroutine get_my_natom(comm_atom,my_natom,natom)
      66                 :             : 
      67                 :             : !Arguments ---------------------------------------------
      68                 :             : !scalars
      69                 :             :  integer,intent(in) :: comm_atom,natom
      70                 :             :  integer,intent(out) :: my_natom
      71                 :             : !arrays
      72                 :             : 
      73                 :             : !Local variables ---------------------------------------
      74                 :             : !scalars
      75                 :             :  integer ::  me,nproc
      76                 :             : !arrays
      77                 :             : 
      78                 :             : ! *************************************************************************
      79                 :             : 
      80                 :        2284 :  my_natom=natom
      81         [ +  - ]:        2284 :  if (comm_atom/=xmpi_comm_self.and.comm_atom/=xmpi_comm_null)  then
      82                 :        2284 :    nproc=xmpi_comm_size(comm_atom)
      83                 :        2284 :    me=xmpi_comm_rank(comm_atom)
      84                 :        2284 :    my_natom=natom/nproc
      85         [ +  + ]:        2284 :    if (me<=(mod(natom,nproc)-1)) my_natom=natom/nproc + 1
      86                 :             :  endif
      87                 :             : 
      88                 :        2284 : end subroutine get_my_natom
      89                 :             : !!***
      90                 :             : 
      91                 :             : !----------------------------------------------------------------------
      92                 :             : 
      93                 :             : !!****f* m_paral_atom/get_my_atmtab
      94                 :             : !! NAME
      95                 :             : !! get_my_atmtab
      96                 :             : !!
      97                 :             : !! FUNCTION
      98                 :             : !! Given the total number of atoms and a MPI communicator return a table
      99                 :             : !! containing the indexes of atoms treated by current processor.
     100                 :             : !!
     101                 :             : !! INPUTS
     102                 :             : !!  comm_atom=communicator over atoms
     103                 :             : !!  my_natom_ref= --optional-- a reference value for the local number of atoms
     104                 :             : !!                (just for checking purposes)
     105                 :             : !!  natom=total number of atoms
     106                 :             : !!
     107                 :             : !! OUTPUT
     108                 :             : !!
     109                 :             : !! SIDE EFFECTS
     110                 :             : !!  my_atmtab(:)=indexes of atoms treated by current process
     111                 :             : !!               nothing is done if my_atmtab(:) is already associated to a target
     112                 :             : !!  my_atmtab_allocated=true if my_atmtab is allocated
     113                 :             : !!  paral_atom=flag controlling parallelism over atoms
     114                 :             : !!
     115                 :             : !! SOURCE
     116                 :             : 
     117                 :             : 
     118                 :     2430020 : subroutine get_my_atmtab(comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,&
     119                 :             : &                        my_natom_ref) ! optional argument
     120                 :             : 
     121                 :             : !Arguments ---------------------------------------------
     122                 :             : !scalars
     123                 :             :  integer,intent(in) :: comm_atom,natom
     124                 :             :  integer,intent(in),optional :: my_natom_ref
     125                 :             :  logical,intent(inout) :: my_atmtab_allocated,paral_atom
     126                 :             : !arrays
     127                 :             :  integer,pointer :: my_atmtab(:)
     128                 :             : !Local variables ---------------------------------------
     129                 :             : !scalars
     130                 :             :  integer :: iatom,me,my_natom,natom_bef,nmod,nproc
     131                 :             :  character(len=500) :: msg
     132                 :             : !arrays
     133                 :             : 
     134                 :             : ! *************************************************************************
     135                 :             : 
     136                 :     2430020 :  my_atmtab_allocated=.false.
     137         [ +  + ]:     2430020 :  if (.not.paral_atom) return
     138                 :             : 
     139         [ +  + ]:       77832 :  if (comm_atom==xmpi_comm_self.or.comm_atom==xmpi_comm_null) paral_atom=.false.
     140         [ +  + ]:       77832 :  if (paral_atom)  then
     141                 :       77632 :    nproc=xmpi_comm_size(comm_atom)
     142                 :       77632 :    paral_atom=(nproc>1)
     143         [ +  - ]:       77632 :    if (paral_atom) then
     144         [ +  + ]:       77632 :      if (.not.associated(my_atmtab)) then
     145                 :             : !      Get local number of atoms
     146                 :        3530 :        me=xmpi_comm_rank(comm_atom)
     147                 :        3530 :        my_natom=natom/nproc
     148         [ +  + ]:        3530 :        if (me<=(mod(natom,nproc)-1)) my_natom=natom/nproc + 1
     149                 :             : !      Get table of atoms
     150         [ +  + ]:        3530 :        if (my_natom>0) then
     151   [ -  +  +  -  :        7956 :          LIBPAW_POINTER_ALLOCATE(my_atmtab,(my_natom))
          +  -  -  +  -  
                      + ]
     152                 :        2652 :          my_atmtab_allocated=.true.
     153         [ -  + ]:        2652 :          if (my_natom==natom) then
     154   [ #  #  #  # ]:           0 :            my_atmtab(1:my_natom)=(/(iatom,iatom=1,natom)/)
     155                 :             :          else
     156                 :             : !          The atoms are distributed contigously by egal part
     157                 :             : !          (the rest is distributed on all the procs)
     158                 :        2652 :            nmod=mod(natom,nproc)
     159         [ +  + ]:        2652 :            if (me<=(nmod-1)) then
     160                 :        1097 :              natom_bef=me*(natom/nproc)+me
     161                 :             :            else
     162                 :        1555 :              natom_bef=me*(natom/nproc)+nmod
     163                 :             :            endif
     164         [ +  + ]:        6045 :            do iatom=1,my_natom
     165                 :        6045 :              my_atmtab(iatom)=iatom+natom_bef
     166                 :             :            enddo
     167                 :             :          end if
     168                 :             :        end if
     169                 :             :      else
     170                 :       74102 :        my_natom=size(my_atmtab)
     171                 :             :      end if
     172         [ +  + ]:       77632 :      if (present(my_natom_ref).and.(my_natom>0)) then
     173         [ -  + ]:       53696 :        if (my_natom_ref/=size(my_atmtab)) then
     174                 :           0 :          msg='my_atmtab should have a size equal to my_natom !'
     175                 :           0 :          LIBPAW_BUG(msg)
     176                 :             :        end if
     177                 :             :      end if
     178                 :             :    end if
     179                 :             :  endif
     180                 :             : 
     181                 :             : end subroutine get_my_atmtab
     182                 :             : !!***
     183                 :             : 
     184                 :             : !----------------------------------------------------------------------
     185                 :             : 
     186                 :             : !!****f* m_paral_atom/free_my_atmtab
     187                 :             : !! NAME
     188                 :             : !! free_my_atmtab
     189                 :             : !!
     190                 :             : !! FUNCTION
     191                 :             : !! Cleanly deallocate a table of atom indexes (my_atmtab)
     192                 :             : !!
     193                 :             : !! INPUTS
     194                 :             : !!
     195                 :             : !! OUTPUT
     196                 :             : !!
     197                 :             : !! SIDE EFFECTS
     198                 :             : !!  my_atmtab_allocated=true if my_atmtab is allocated
     199                 :             : !!  my_atmtab(:)=indexes of atoms treated by current process
     200                 :             : !!               nothing is done if my_atmtab(:) is already associated to a target
     201                 :             : !!
     202                 :             : !! SOURCE
     203                 :             : 
     204                 :     1789321 : subroutine free_my_atmtab(my_atmtab,my_atmtab_allocated)
     205                 :             : 
     206                 :             : !Arguments ---------------------------------------------
     207                 :             : !scalars
     208                 :             :  logical,intent(inout) :: my_atmtab_allocated
     209                 :             : !arrays
     210                 :             :  integer,pointer :: my_atmtab(:)
     211                 :             : !Local variables ---------------------------------------
     212                 :             : !scalars
     213                 :             : !arrays
     214                 :             : 
     215                 :             : ! *************************************************************************
     216                 :             : 
     217         [ +  + ]:     1789321 :  if (my_atmtab_allocated) then
     218         [ -  + ]:        8697 :    LIBPAW_POINTER_DEALLOCATE(my_atmtab)
     219                 :             :    nullify(my_atmtab)
     220                 :        8697 :    my_atmtab_allocated=.false.
     221                 :             :  end if
     222                 :             : 
     223                 :     1789321 : end subroutine free_my_atmtab
     224                 :             : !!***
     225                 :             : 
     226                 :             : !----------------------------------------------------------------------
     227                 :             : 
     228                 :             : !!****f* m_paral_atom/get_proc_atmtab
     229                 :             : !! NAME
     230                 :             : !! get_proc_atmtab
     231                 :             : !!
     232                 :             : !! FUNCTION
     233                 :             : !!  Given the total number of atoms and the size of a communicator,
     234                 :             : !!  return a table containing the indexes of atoms treated by a processor (with index iproc)
     235                 :             : !!
     236                 :             : !! INPUTS
     237                 :             : !!  comm_atom_size= size of communicator (over atoms)
     238                 :             : !!  iproc= rank of the processor
     239                 :             : !!  natom= total number of atoms
     240                 :             : !!
     241                 :             : !! OUTPUT
     242                 :             : !!  atmtab(natom_out)= indexes of atoms treated by process iproc
     243                 :             : !!  natom_out= number of atoms treated by process iproc
     244                 :             : !!
     245                 :             : !! NOTES
     246                 :             : !! In case of modification of the distribution of atom over proc,
     247                 :             : !!   get_atmtab must be modified accordingly
     248                 :             : !!
     249                 :             : !! SOURCE
     250                 :             : 
     251                 :           0 :  subroutine get_proc_atmtab(iproc,atmtab,natom_out,natom,comm_atom_size)
     252                 :             : 
     253                 :             : !Arguments ---------------------------------------------
     254                 :             : !scalars
     255                 :             :  integer, intent(in) :: comm_atom_size,iproc,natom
     256                 :             : !arrays
     257                 :             :  integer,intent(out) :: natom_out
     258                 :             :  integer,allocatable, intent(out):: atmtab(:)
     259                 :             : 
     260                 :             : !Local variables ---------------------------------------
     261                 :             : !scalars
     262                 :             :  integer :: iatom,natom_bef,nmod,nproc
     263                 :             : !arrays
     264                 :             : 
     265                 :             : ! *************************************************************************
     266                 :             : 
     267                 :           0 :  nproc=comm_atom_size
     268                 :             : 
     269         [ #  # ]:           0 :  natom_out=natom/nproc ; if (iproc<=(mod(natom,nproc)-1)) natom_out=natom/nproc+1
     270                 :             : 
     271                 :             : ! Get table of atoms
     272         [ #  # ]:           0 :  if (natom_out>0) then
     273   [ #  #  #  #  :           0 :    LIBPAW_ALLOCATE(atmtab,(natom_out))
          #  #  #  #  #  
                #  #  # ]
     274                 :             : !  The atoms are distributed contigously by egal part
     275                 :             : !  The rest is distributed on all the procs
     276                 :             : !  (see get_my_atmtab)
     277                 :           0 :    nmod=mod(natom,nproc)
     278         [ #  # ]:           0 :    if (iproc<=(nmod-1)) then
     279                 :           0 :      natom_bef=iproc*(natom/nproc)+iproc
     280                 :             :    else
     281                 :           0 :      natom_bef=iproc*(natom/nproc)+nmod
     282                 :             :    end if
     283         [ #  # ]:           0 :    do iatom=1,natom_out
     284                 :           0 :      atmtab(iatom)=iatom+natom_bef
     285                 :             :    end do
     286                 :             : 
     287                 :             :  else
     288                 :           0 :    natom_out=0
     289   [ #  #  #  # ]:           0 :    LIBPAW_ALLOCATE(atmtab,(0))
     290                 :             :  end if
     291                 :             : 
     292                 :           0 : end subroutine get_proc_atmtab
     293                 :             : !!***
     294                 :             : 
     295                 :             : !----------------------------------------------------------------------
     296                 :             : 
     297                 :             : !!****f* m_paral_atom/get_atm_proc
     298                 :             : !! NAME
     299                 :             : !! get_atm_proc
     300                 :             : !!
     301                 :             : !! FUNCTION
     302                 :             : !!  Given a list of atoms and a MPI communicator size, return a table
     303                 :             : !!  containing the corresponding processor indexes.
     304                 :             : !!
     305                 :             : !! COPYRIGHT
     306                 :             : !! Copyright (C) 2012-2026 ABINIT group (MD)
     307                 :             : !! This file is distributed under the terms of the
     308                 :             : !! GNU General Public License, see ~abinit/COPYING
     309                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
     310                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
     311                 :             : !!
     312                 :             : !! INPUTS
     313                 :             : !!  atom_list(:)= index of atoms
     314                 :             : !!  nproc=size of communicator over atoms
     315                 :             : !!  natom=total number of atoms
     316                 :             : !!
     317                 :             : !! OUTPUT
     318                 :             : !! proc_list(:) = index of procs
     319                 :             : !!
     320                 :             : !! NOTES
     321                 :             : !!  The atoms are distributed contigously by egal part; the rest is distributed
     322                 :             : !!  on all the procs (see get_my_atmtab).
     323                 :             : !!  In case of modification of the distribution of atom over proc, this routine
     324                 :             : !!  must be modified accordingly.
     325                 :             : !!
     326                 :             : !! SOURCE
     327                 :             : 
     328   [ -  +  -  + ]:          56 :  subroutine get_atm_proc(atom_list,natom,nproc,proc_list)
     329                 :             : 
     330                 :             : !Arguments ---------------------------------------------
     331                 :             : !scalars
     332                 :             :  integer, intent(in) :: natom,nproc
     333                 :             : !arrays
     334                 :             :  integer, intent(in) :: atom_list(:)
     335                 :             :  integer, intent(out) :: proc_list(:)
     336                 :             : 
     337                 :             : !Local variables ---------------------------------------
     338                 :             : !scalars
     339                 :             :  integer :: nb_atom,dn,dn1,iatom,natomlim,iatm,jproclim,nmod
     340                 :             : !arrays
     341                 :             : 
     342                 :             : ! *************************************************************************
     343                 :             : 
     344                 :          56 :  nmod=mod(natom,nproc);nb_atom=size(atom_list)
     345                 :             : 
     346         [ +  + ]:          56 :  if (nmod==0) then
     347                 :          24 :    dn=natom/nproc
     348         [ +  + ]:          48 :    do iatm =1, nb_atom
     349                 :          24 :      iatom=atom_list(iatm)
     350                 :          48 :      proc_list(iatm)=(iatom-1)/dn
     351                 :             :    end do
     352                 :             :  else
     353                 :          32 :    dn=natom/nproc
     354                 :          32 :    dn1=natom/nproc + 1
     355                 :             : !  Under (jproclim+1), 1 atome by proc is added
     356                 :             : !  The rest nmod is distributed among jproclim+1 first procs
     357                 :          32 :    jproclim=nmod -1
     358                 :          32 :    natomlim=dn1*(jproclim+1)
     359         [ +  + ]:          64 :    do iatm=1,nb_atom
     360                 :          32 :      iatom=atom_list(iatm)
     361         [ +  - ]:          64 :      if (iatom<=natomlim) then
     362                 :          32 :        proc_list(iatm)=(iatom -1 )/dn1
     363                 :             :      else
     364                 :           0 :        proc_list(iatm)=jproclim + 1 + (iatom - 1 -(natomlim))/dn
     365                 :             :      end if
     366                 :             :    enddo
     367                 :             :  end if
     368                 :             : 
     369                 :          56 : end subroutine get_atm_proc
     370                 :             : !!***
     371                 :             : 
     372                 :             : !----------------------------------------------------------------------
     373                 :             : 
     374                 :             : END MODULE m_paral_atom
     375                 :             : !!***
        

Generated by: LCOV version 2.3-1