TABLE OF CONTENTS


ABINIT/m_iterators [ Modules ]

[ Top ] [ Modules ]

NAME

  m_iterators

FUNCTION

  This module defines objects (iterators) that are used to facilitate the
  iteration over the elements of an ensemble e.g. set of transitions.

COPYRIGHT

 Copyright (C) 2009-2018 ABINIT group (MG)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .

NOTES

  Iterators are used to obtain an indirect indexing that can be used to access array elements
  or array sections. An iterator is an object that contains the list of indices that should
  be treated. Each processor has its own local version initialized according the the distribution
  of the data across the nodes.
  Using iterators for looping facilitates the implementation of MPI algorithms since all the
  information on the distribution of the tasks is stored in the iterator itself
  For example an MPI loop over spins, k-points and bands can be written in terms of iterators using:

   do isp=1,iter_len(Iter_bks)
     spin = iter_yield(Iter_bks,idx3=isp)

     do ikp=1,iter_len(Iter_bks,idx3=isp)
       ik_ibz = iter_yield(Iter_bks,idx2=ikp,idx3=isp)

       do ibn=1,iter_len(Iter_bks,idx2=ikp,idx3=isp)
         band = iter_yield(Iter_bks,entry1=ibn,idx2=ikp,idx3=isp)

  iter_len gives the number of non-zero entries
  iter_yield returns the global indices used to access the data.

  The main advantage is seen in sections of code that are MPI parallelized because each node
  will have its own iterator (to be initialized by the programmer).
  Therefore it is very easy to distribute the workload among the nodes without having to
  to use "cycle" of "if then" instruction in the inners loops.
  Another important advantage is that the MPI implementation will continue to work even
  if the data distribution is changed, only the iterator has to be modified.

PARENTS

CHILDREN

SOURCE

50 #if defined HAVE_CONFIG_H
51 #include "config.h"
52 #endif
53 
54 #include "abi_common.h"
55 
56 MODULE m_iterators
57 
58  use defs_basis
59  use m_abicore
60  use m_errors
61 
62  implicit none
63 
64  private

m_iterators/indices_free [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  indices_free

FUNCTION

INPUTS

OUTPUT

PARENTS

      m_iterators

CHILDREN

      wrtout

SOURCE

208 subroutine indices_free(Ids)
209 
210 !Arguments ------------------------------------
211 
212 !This section has been created automatically by the script Abilint (TD).
213 !Do not modify the following lines by hand.
214 #undef ABI_FUNC
215 #define ABI_FUNC 'indices_free'
216 !End of the abilint section
217 
218  type(indices_t),intent(inout) :: Ids
219 
220 ! *************************************************************************
221 
222  Ids%leng=0
223  if (allocated(Ids%indx))  then
224    ABI_FREE(Ids%indx)
225  end if
226 
227 end subroutine indices_free

m_iterators/indices_t [ Types ]

[ Top ] [ m_iterators ] [ Types ]

NAME

  indices_t

FUNCTION

  A base datatype for constructing ragged arrays.

SOURCE

78  type,private :: indices_t
79    integer :: leng
80    integer, allocatable :: indx(:)
81    ! indx(leng) The set of indices.
82  end type indices_t

m_iterators/iter2_alloc [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  iter2_alloc

FUNCTION

INPUTS

OUTPUT

PARENTS

CHILDREN

      wrtout

SOURCE

249 subroutine iter2_alloc(Iter2,sizes,starts)
250 
251  use defs_basis
252 
253 !This section has been created automatically by the script Abilint (TD).
254 !Do not modify the following lines by hand.
255 #undef ABI_FUNC
256 #define ABI_FUNC 'iter2_alloc'
257 !End of the abilint section
258 
259  implicit none
260 
261 !Arguments ------------------------------------
262 !scalars
263  type(iter2_t),intent(inout) :: Iter2
264 !arrays
265  integer,intent(in) :: sizes(2)
266  integer,optional,intent(in) :: starts(2)
267 
268 !Local variables ------------------------------
269 !scalars
270  integer :: s1,s2,i1,i2
271 
272 !************************************************************************
273  s1=1; s2=1
274  if (PRESENT(starts)) then
275    s1=starts(1)
276    s2=starts(2)
277  end if
278 
279  Iter2%starts=(/s1,s2/)
280  Iter2%sizes =sizes
281 
282  ABI_DT_MALLOC( Iter2%slice,(s1:s1+sizes(1)-1, s2:s2+sizes(2)-1))
283 
284  do i2=LBOUND(Iter2%slice,DIM=2),UBOUND(Iter2%slice,DIM=2)
285    do i1=LBOUND(Iter2%slice,DIM=1),UBOUND(Iter2%slice,DIM=1)
286      Iter2%slice(i1,i2)%leng=0
287    end do
288  end do
289 
290 end subroutine iter2_alloc

m_iterators/iter2_free [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  iter2_free

FUNCTION

INPUTS

OUTPUT

PARENTS

CHILDREN

      wrtout

SOURCE

369 subroutine iter2_free(Iter2)
370 
371  use defs_basis
372 
373 !This section has been created automatically by the script Abilint (TD).
374 !Do not modify the following lines by hand.
375 #undef ABI_FUNC
376 #define ABI_FUNC 'iter2_free'
377 !End of the abilint section
378 
379  implicit none
380 
381 !Arguments ------------------------------------
382 !scalars
383  type(iter2_t),intent(inout) :: Iter2
384 
385 !Local variables ------------------------------
386 !scalars
387  integer :: i1,i2
388 
389 !************************************************************************
390 
391  do i2=LBOUND(Iter2%slice,DIM=2),UBOUND(Iter2%slice,DIM=2)
392    do i1=LBOUND(Iter2%slice,DIM=1),UBOUND(Iter2%slice,DIM=1)
393      call indices_free(Iter2%slice(i1,i2))
394    end do
395  end do
396 
397  ABI_DT_FREE(Iter2%slice)
398 
399 end subroutine iter2_free

m_iterators/iter2_lbound [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  iter2_lbound

FUNCTION

INPUTS

OUTPUT

SOURCE

451 function iter2_lbound(Iter2,dim)
452 
453  use defs_basis
454 
455 !This section has been created automatically by the script Abilint (TD).
456 !Do not modify the following lines by hand.
457 #undef ABI_FUNC
458 #define ABI_FUNC 'iter2_lbound'
459 !End of the abilint section
460 
461  implicit none
462 
463 !Arguments ------------------------------------
464 !scalars
465  integer,intent(in) :: dim
466  integer :: iter2_lbound
467  type(iter2_t),intent(in) :: Iter2
468 
469 !************************************************************************
470 
471  iter2_lbound = Iter2%starts(dim)
472 
473 end function iter2_lbound

m_iterators/iter2_len [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  iter2_len

FUNCTION

INPUTS

OUTPUT

SOURCE

416 function iter2_len(Iter2,i1,i2)
417 
418 !Arguments ------------------------------------
419 
420 !This section has been created automatically by the script Abilint (TD).
421 !Do not modify the following lines by hand.
422 #undef ABI_FUNC
423 #define ABI_FUNC 'iter2_len'
424 !End of the abilint section
425 
426  integer,intent(in) :: i1,i2
427  integer :: iter2_len
428  type(iter2_t),intent(in) :: Iter2
429 
430 ! *************************************************************************
431 
432  iter2_len = Iter2%slice(i1,i2)%leng
433 
434 end function iter2_len

m_iterators/iter2_print [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  iter2_print

FUNCTION

INPUTS

OUTPUT

PARENTS

CHILDREN

      wrtout

SOURCE

608 subroutine iter2_print(Iter2,header,unit,mode_paral,prtvol)
609 
610 
611 !This section has been created automatically by the script Abilint (TD).
612 !Do not modify the following lines by hand.
613 #undef ABI_FUNC
614 #define ABI_FUNC 'iter2_print'
615 !End of the abilint section
616 
617  implicit none
618 
619 !Arguments ------------------------------------
620 !scalars
621  integer,optional,intent(in) :: unit,prtvol
622  character(len=4),optional,intent(in) :: mode_paral
623  character(len=*),optional,intent(in) :: header
624  type(iter2_t),intent(in) :: Iter2
625 
626 !Local variables-------------------------------
627  integer :: my_unt,my_prtvol,ntot,i1,i2,idx
628  character(len=4) :: my_mode
629  character(len=500) :: msg
630 ! *********************************************************************
631 
632  my_unt   =std_out; if (PRESENT(unit      )) my_unt   =unit
633  my_prtvol=0      ; if (PRESENT(prtvol    )) my_prtvol=prtvol
634  my_mode  ='COLL' ; if (PRESENT(mode_paral)) my_mode  =mode_paral
635 
636  msg=' ==== Content of the iter2_t object ==== '
637  if (PRESENT(header)) msg=' ==== '//TRIM(ADJUSTL(header))//' ==== '
638  call wrtout(my_unt,msg,my_mode)
639 
640  ntot = PRODUCT(Iter2%sizes)
641  write(std_out,*)"total number of elements:",ntot
642  write(std_out,*)"list of indices: "
643 
644  do i2=iter2_lbound(Iter2,DIM=2),iter2_ubound(Iter2,DIM=2)
645    do i1=iter2_lbound(Iter2,DIM=1),iter2_lbound(Iter2,DIM=1)
646       write(std_out,*) (iter_yield(Iter2,idx,i1,i2), idx=1,iter_len(Iter2,i1,i2))
647    end do
648  end do
649 
650 end subroutine iter2_print
651 
652 END MODULE m_iterators

m_iterators/iter2_push [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  iter2_push

FUNCTION

INPUTS

OUTPUT

PARENTS

CHILDREN

      wrtout

SOURCE

312 subroutine iter2_push(Iter2,i1,i2,list)
313 
314  use defs_basis
315 
316 !This section has been created automatically by the script Abilint (TD).
317 !Do not modify the following lines by hand.
318 #undef ABI_FUNC
319 #define ABI_FUNC 'iter2_push'
320 !End of the abilint section
321 
322  implicit none
323 
324 !Arguments ------------------------------------
325 !scalars
326  integer,intent(in) :: i1,i2
327  type(iter2_t),intent(inout) :: Iter2
328 !arrays
329  integer,intent(in) :: list(:)
330 
331 !Local variables ------------------------------
332 !scalars
333  integer :: leng
334 
335 !************************************************************************
336 
337  leng = SIZE(list)
338 
339  if (allocated( Iter2%slice(i1,i2)%indx) ) then
340    MSG_ERROR("Iter2%slice already allocated")
341  end if
342 
343  Iter2%slice(i1,i2)%leng = leng
344  ABI_MALLOC(Iter2%slice(i1,i2)%indx,(leng))
345  Iter2%slice(i1,i2)%indx(:) = list
346 
347 end subroutine iter2_push

m_iterators/iter2_size [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  iter2_size

FUNCTION

INPUTS

OUTPUT

SOURCE

529 function iter2_size(Iter2,dim)
530 
531  use defs_basis
532 
533 !This section has been created automatically by the script Abilint (TD).
534 !Do not modify the following lines by hand.
535 #undef ABI_FUNC
536 #define ABI_FUNC 'iter2_size'
537 !End of the abilint section
538 
539  implicit none
540 
541 !Arguments ------------------------------------
542 !scalars
543  integer,intent(in) :: dim
544  integer :: iter2_size
545  type(iter2_t),intent(in) :: Iter2
546 
547 !************************************************************************
548 
549  iter2_size = iter2_ubound(Iter2,dim) - iter2_lbound(Iter2,dim) + 1
550 
551 end function iter2_size

m_iterators/iter2_t [ Types ]

[ Top ] [ m_iterators ] [ Types ]

NAME

  iter2_t

FUNCTION

SOURCE

 95  type,public :: iter2_t
 96    private
 97    integer :: sizes(2)
 98    integer :: starts(2)
 99    type(indices_t),allocatable :: slice(:,:)
100    ! Temporary structure to store the indices in full storage mode.
101 
102 #if 0
103    integer :: len3
104    ! The number of non-zero entries in the last dimension.
105 
106    integer,allocatable :: map3(:)
107    ! map3(len3)
108    ! Indirect indexing packed --> full for the last dimension.
109 
110    integer,allocatable :: len2(:)
111    ! len2(len3)
112    ! Gives the number of non-zero entries along the second dimension for each non-null index along the 3-dimension.
113 
114    type(indices_t),allocatable :: map2(:)
115    ! map2(len3)%indices
116    ! Indirect indexing packed --> full for the second dimension.
117 
118    type(indices_t),allocatable :: len1(:,:)
119    ! len1(MAX(len2),len3)
120    ! Gives the number of non-zero entries along the first dimension.
121 
122    type(indices_t),allocatable :: map1(:)
123    ! map1(MAX(len2),len3)%indices
124    ! Indirect indexing packed --> full for the first dimension.
125 #endif
126 
127  end type iter2_t
128 
129  public :: iter_alloc         ! Allocate the iterator.
130  public :: iter_push          ! Copy a set of indices in the iterator
131  public :: iter_free          ! Deallocate the iterator.
132  public :: OPERATOR(.LBOUND.) !
133  public :: OPERATOR(.UBOUND.) !
134  public :: OPERATOR(.SIZE.)   !
135  public :: iter_len           ! The number of indices in a slice of the iterator
136  public :: iter_yield         ! Return the indices in of the slice of the iterator.
137  public :: iter_print         ! Printout of the iterator, just for debugging purposes.

m_iterators/iter2_ubound [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  iter2_ubound

FUNCTION

INPUTS

OUTPUT

SOURCE

490 function iter2_ubound(Iter2,dim)
491 
492  use defs_basis
493 
494 !This section has been created automatically by the script Abilint (TD).
495 !Do not modify the following lines by hand.
496 #undef ABI_FUNC
497 #define ABI_FUNC 'iter2_ubound'
498 !End of the abilint section
499 
500  implicit none
501 
502 !Arguments ------------------------------------
503 !scalars
504  integer,intent(in) :: dim
505  integer :: iter2_ubound
506  type(iter2_t),intent(in) :: Iter2
507 
508 !************************************************************************
509 
510  iter2_ubound = Iter2%starts(dim) + Iter2%sizes(dim) -1
511 
512 end function iter2_ubound

m_iterators/iter2_yield [ Functions ]

[ Top ] [ m_iterators ] [ Functions ]

NAME

  iter2_yield

FUNCTION

INPUTS

OUTPUT

SOURCE

568 function iter2_yield(Iter2,idx,i1,i2)
569 
570 !Arguments ------------------------------------
571 
572 !This section has been created automatically by the script Abilint (TD).
573 !Do not modify the following lines by hand.
574 #undef ABI_FUNC
575 #define ABI_FUNC 'iter2_yield'
576 !End of the abilint section
577 
578  integer,intent(in) :: idx,i1,i2
579  integer :: iter2_yield
580  type(iter2_t),intent(in) :: Iter2
581 
582 ! *************************************************************************
583 
584  iter2_yield = Iter2%slice(i1,i2)%indx(idx)
585 
586 end function iter2_yield