LCOV - code coverage report
Current view: top level - src/fm - cp_blacs_env.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:b279b6b) Lines: 90 97 92.8 %
Date: 2024-04-24 07:13:09 Functions: 7 8 87.5 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief methods related to the blacs parallel environment
      10             : !> \par History
      11             : !>      08.2002 created [fawzi]
      12             : !>      02.2004 modified to associate a blacs_env with a given para_env
      13             : !> \author Fawzi Mohamed
      14             : ! **************************************************************************************************
      15             : MODULE cp_blacs_env
      16             :    USE cp_array_utils,                  ONLY: cp_2d_i_write
      17             :    USE cp_blacs_types,                  ONLY: cp_blacs_type
      18             :    USE kinds,                           ONLY: dp
      19             :    USE machine,                         ONLY: m_flush
      20             :    USE mathlib,                         ONLY: gcd
      21             :    USE message_passing,                 ONLY: mp_para_env_release,&
      22             :                                               mp_para_env_type
      23             : #include "../base/base_uses.f90"
      24             : 
      25             :    IMPLICIT NONE
      26             :    PRIVATE
      27             : 
      28             :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
      29             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_blacs_env'
      30             : 
      31             :    ! Blacs type of distribution
      32             :    INTEGER, PARAMETER, PUBLIC               :: BLACS_GRID_SQUARE = 1, &
      33             :                                                BLACS_GRID_ROW = 2, &
      34             :                                                BLACS_GRID_COL = 3
      35             : 
      36             :    PUBLIC :: cp_blacs_env_type
      37             :    PUBLIC :: cp_blacs_env_create, cp_blacs_env_release
      38             : 
      39             : ! **************************************************************************************************
      40             : !> \brief represent a blacs multidimensional parallel environment
      41             : !>      (for the mpi corrispective see cp_paratypes/mp_para_cart_type)
      42             : !> \param ref_count the reference count, when it is zero this object gets
      43             : !>        deallocated
      44             : !> \param my_pid process id of the actual processor
      45             : !> \param n_pid number of process ids
      46             : !> \param the para_env associated (and compatible) with this blacs_env
      47             : !> \param blacs2mpi: maps mepos(1)-mepos(2) of blacs to its mpi rank
      48             : !> \param mpi2blacs(i,rank): maps the mpi rank to the mepos(i)
      49             : !> \par History
      50             : !>      08.2002 created [fawzi]
      51             : !> \author Fawzi Mohamed
      52             : ! **************************************************************************************************
      53             :    TYPE, EXTENDS(cp_blacs_type) :: cp_blacs_env_type
      54             :       INTEGER :: my_pid = -1, n_pid = -1, ref_count = -1
      55             :       TYPE(mp_para_env_type), POINTER :: para_env => NULL()
      56             :       INTEGER, DIMENSION(:, :), POINTER :: blacs2mpi => NULL()
      57             :       INTEGER, DIMENSION(:, :), POINTER :: mpi2blacs => NULL()
      58             :       LOGICAL :: repeatable = .FALSE.
      59             :    CONTAINS
      60             :       PROCEDURE, PUBLIC, PASS, NON_OVERRIDABLE :: create => cp_blacs_env_create_low
      61             :       PROCEDURE, PUBLIC, PASS, NON_OVERRIDABLE :: retain => cp_blacs_env_retain
      62             :       PROCEDURE, PUBLIC, PASS, NON_OVERRIDABLE :: release => cp_blacs_env_release_low
      63             :       PROCEDURE, PUBLIC, PASS, NON_OVERRIDABLE :: get => get_blacs_info
      64             :       PROCEDURE, PUBLIC, PASS, NON_OVERRIDABLE :: write => cp_blacs_env_write
      65             :    END TYPE cp_blacs_env_type
      66             : 
      67             : !***
      68             : CONTAINS
      69             : 
      70             : ! **************************************************************************************************
      71             : !> \brief   Return informations about the specified BLACS context.
      72             : !> \param blacs_env ...
      73             : !> \param my_process_row ...
      74             : !> \param my_process_column ...
      75             : !> \param my_process_number ...
      76             : !> \param number_of_process_rows ...
      77             : !> \param number_of_process_columns ...
      78             : !> \param number_of_processes ...
      79             : !> \param para_env ...
      80             : !> \param blacs2mpi ...
      81             : !> \param mpi2blacs ...
      82             : !> \date    19.06.2001
      83             : !> \par     History
      84             : !>          MM.YYYY moved here from qs_blacs (Joost VandeVondele)
      85             : !> \author  Matthias Krack
      86             : !> \version 1.0
      87             : ! **************************************************************************************************
      88       10258 :    SUBROUTINE get_blacs_info(blacs_env, my_process_row, my_process_column, &
      89             :                              my_process_number, number_of_process_rows, &
      90             :                              number_of_process_columns, number_of_processes, &
      91             :                              para_env, blacs2mpi, mpi2blacs)
      92             :       CLASS(cp_blacs_env_type), INTENT(IN)                :: blacs_env
      93             :       INTEGER, INTENT(OUT), OPTIONAL :: my_process_row, my_process_column, my_process_number, &
      94             :                                         number_of_process_rows, number_of_process_columns, number_of_processes
      95             :       TYPE(mp_para_env_type), OPTIONAL, POINTER          :: para_env
      96             :       INTEGER, DIMENSION(:, :), OPTIONAL, POINTER        :: blacs2mpi, mpi2blacs
      97             : 
      98       10258 :       IF (PRESENT(my_process_row)) my_process_row = blacs_env%mepos(1)
      99       10258 :       IF (PRESENT(my_process_column)) my_process_column = blacs_env%mepos(2)
     100       10258 :       IF (PRESENT(my_process_number)) my_process_number = blacs_env%my_pid
     101       10258 :       IF (PRESENT(number_of_process_rows)) number_of_process_rows = blacs_env%num_pe(1)
     102       10258 :       IF (PRESENT(number_of_process_columns)) number_of_process_columns = blacs_env%num_pe(2)
     103       10258 :       IF (PRESENT(number_of_processes)) number_of_processes = blacs_env%n_pid
     104       10258 :       IF (PRESENT(para_env)) para_env => blacs_env%para_env
     105       10258 :       IF (PRESENT(blacs2mpi)) blacs2mpi => blacs_env%blacs2mpi
     106       10258 :       IF (PRESENT(mpi2blacs)) mpi2blacs => blacs_env%mpi2blacs
     107             : 
     108       10258 :    END SUBROUTINE get_blacs_info
     109             : 
     110             : ! **************************************************************************************************
     111             : !> \brief allocates and initializes a type that represent a blacs context
     112             : !> \param blacs_env the type to initialize
     113             : !> \param para_env the para_env for which a blacs env should be created
     114             : !> \param blacs_grid_layout ...
     115             : !> \param blacs_repeatable ...
     116             : !> \param row_major ...
     117             : !> \param grid_2d ...
     118             : !> \par History
     119             : !>      08.2002 created [fawzi]
     120             : !> \author Fawzi Mohamed
     121             : ! **************************************************************************************************
     122       95848 :    SUBROUTINE cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
     123             :       TYPE(cp_blacs_env_type), INTENT(OUT), POINTER      :: blacs_env
     124             :       TYPE(mp_para_env_type), INTENT(INOUT), TARGET      :: para_env
     125             :       INTEGER, INTENT(IN), OPTIONAL                      :: blacs_grid_layout
     126             :       LOGICAL, INTENT(IN), OPTIONAL                      :: blacs_repeatable, row_major
     127             :       INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL        :: grid_2d
     128             : 
     129      670936 :       ALLOCATE (blacs_env)
     130      189890 :       CALL blacs_env%create(para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
     131             : 
     132       95848 :    END SUBROUTINE
     133             : 
     134             : ! **************************************************************************************************
     135             : !> \brief allocates and initializes a type that represent a blacs context
     136             : !> \param blacs_env the type to initialize
     137             : !> \param para_env the para_env for which a blacs env should be created
     138             : !> \param blacs_grid_layout ...
     139             : !> \param blacs_repeatable ...
     140             : !> \param row_major ...
     141             : !> \param grid_2d ...
     142             : !> \par History
     143             : !>      08.2002 created [fawzi]
     144             : !> \author Fawzi Mohamed
     145             : ! **************************************************************************************************
     146       95848 :    SUBROUTINE cp_blacs_env_create_low(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
     147             :       CLASS(cp_blacs_env_type), INTENT(OUT)    :: blacs_env
     148             :       TYPE(mp_para_env_type), TARGET, INTENT(INOUT) :: para_env
     149             :       INTEGER, INTENT(IN), OPTIONAL            :: blacs_grid_layout
     150             :       LOGICAL, INTENT(IN), OPTIONAL            :: blacs_repeatable, row_major
     151             :       INTEGER, DIMENSION(:), INTENT(IN), &
     152             :          OPTIONAL                               :: grid_2d
     153             : 
     154             :       INTEGER                                  :: ipcol, iprow
     155             : #if defined(__parallel)
     156             :       INTEGER                                  :: gcd_max, ipe, jpe, &
     157             :                                                   my_blacs_grid_layout, &
     158             :                                                   npcol, npe, nprow
     159             :       LOGICAL                                  :: my_blacs_repeatable, &
     160             :                                                   my_row_major
     161             : #endif
     162             : 
     163             : #ifdef __parallel
     164             : #ifndef __SCALAPACK
     165             :       CALL cp_abort(__LOCATION__, &
     166             :                     "to USE the blacs environment "// &
     167             :                     "you need the blacs/scalapack library : recompile with -D__SCALAPACK (and link scalapack and blacs) ")
     168             : #endif
     169             : #endif
     170             : 
     171             : #ifdef __SCALAPACK
     172             :       ! get the number of cpus for this blacs grid
     173       95848 :       nprow = 1
     174       95848 :       npcol = 1
     175       95848 :       npe = para_env%num_pe
     176             :       ! get the layout of this grid
     177             : 
     178       95848 :       IF (PRESENT(grid_2d)) THEN
     179        1806 :          nprow = grid_2d(1)
     180        1806 :          npcol = grid_2d(2)
     181             :       END IF
     182             : 
     183       95848 :       IF (nprow*npcol .NE. npe) THEN
     184             :          ! hard code for the time being the grid layout
     185        8974 :          my_blacs_grid_layout = BLACS_GRID_SQUARE
     186        8974 :          IF (PRESENT(blacs_grid_layout)) my_blacs_grid_layout = blacs_grid_layout
     187             :          ! XXXXXX
     188        8974 :          SELECT CASE (my_blacs_grid_layout)
     189             :          CASE (BLACS_GRID_SQUARE)
     190             :             ! make the grid as 'square' as possible, where square is defined as nprow and npcol
     191             :             ! having the largest possible gcd
     192        8974 :             gcd_max = -1
     193       26922 :             DO ipe = 1, CEILING(SQRT(REAL(npe, dp)))
     194       17948 :                jpe = npe/ipe
     195       17948 :                IF (ipe*jpe .NE. npe) CYCLE
     196       26922 :                IF (gcd(ipe, jpe) >= gcd_max) THEN
     197       17948 :                   nprow = ipe
     198       17948 :                   npcol = jpe
     199       17948 :                   gcd_max = gcd(ipe, jpe)
     200             :                END IF
     201             :             END DO
     202             :          CASE (BLACS_GRID_ROW)
     203           0 :             nprow = 1
     204           0 :             npcol = npe
     205             :          CASE (BLACS_GRID_COL)
     206           0 :             nprow = npe
     207        7894 :             npcol = 1
     208             :          END SELECT
     209             :       END IF
     210             : 
     211       95848 :       my_row_major = .TRUE.
     212       95848 :       IF (PRESENT(row_major)) my_row_major = row_major
     213          20 :       IF (my_row_major) THEN
     214       95848 :          CALL blacs_env%gridinit(para_env, "Row-major", nprow, npcol)
     215             :       ELSE
     216           0 :          CALL blacs_env%gridinit(para_env, "Col-major", nprow, npcol)
     217             :       END IF
     218             : 
     219             :       ! We set the components of blacs_env here such that we can still use INTENT(OUT) with gridinit
     220       95848 :       blacs_env%my_pid = para_env%mepos
     221       95848 :       blacs_env%n_pid = para_env%num_pe
     222       95848 :       blacs_env%ref_count = 1
     223             : 
     224       95848 :       my_blacs_repeatable = .FALSE.
     225       95848 :       IF (PRESENT(blacs_repeatable)) my_blacs_repeatable = blacs_repeatable
     226       95848 :       blacs_env%repeatable = my_blacs_repeatable
     227       95848 :       IF (blacs_env%repeatable) CALL blacs_env%set(15, 1)
     228             : 
     229             : #else
     230             :       ! In serial mode, we just have to setup the object
     231             :       CALL blacs_env%gridinit(para_env, "Row-major", 1, 1)
     232             : 
     233             :       blacs_env%ref_count = 1
     234             :       blacs_env%my_pid = 0
     235             :       blacs_env%n_pid = 1
     236             :       MARK_USED(blacs_grid_layout)
     237             :       MARK_USED(blacs_repeatable)
     238             :       MARK_USED(grid_2d)
     239             :       MARK_USED(row_major)
     240             : #endif
     241             : 
     242       95848 :       CALL para_env%retain()
     243       95848 :       blacs_env%para_env => para_env
     244             : 
     245             :       ! generate the mappings blacs2mpi and mpi2blacs
     246      383392 :       ALLOCATE (blacs_env%blacs2mpi(0:blacs_env%num_pe(1) - 1, 0:blacs_env%num_pe(2) - 1))
     247      297658 :       blacs_env%blacs2mpi = 0
     248       95848 :       blacs_env%blacs2mpi(blacs_env%mepos(1), blacs_env%mepos(2)) = para_env%mepos
     249      499468 :       CALL para_env%sum(blacs_env%blacs2mpi)
     250      287544 :       ALLOCATE (blacs_env%mpi2blacs(2, 0:para_env%num_pe - 1))
     251      413428 :       blacs_env%mpi2blacs = -1
     252      191798 :       DO ipcol = 0, blacs_env%num_pe(2) - 1
     253      297658 :          DO iprow = 0, blacs_env%num_pe(1) - 1
     254      105860 :             blacs_env%mpi2blacs(1, blacs_env%blacs2mpi(iprow, ipcol)) = iprow
     255      201810 :             blacs_env%mpi2blacs(2, blacs_env%blacs2mpi(iprow, ipcol)) = ipcol
     256             :          END DO
     257             :       END DO
     258       95848 :    END SUBROUTINE cp_blacs_env_create_low
     259             : 
     260             : ! **************************************************************************************************
     261             : !> \brief retains the given blacs env
     262             : !> \param blacs_env the blacs env to retain
     263             : !> \par History
     264             : !>      08.2002 created [fawzi]
     265             : !> \author Fawzi Mohamed
     266             : ! **************************************************************************************************
     267      494178 :    SUBROUTINE cp_blacs_env_retain(blacs_env)
     268             :       CLASS(cp_blacs_env_type), INTENT(INOUT)            :: blacs_env
     269             : 
     270      494178 :       CPASSERT(blacs_env%ref_count > 0)
     271      494178 :       blacs_env%ref_count = blacs_env%ref_count + 1
     272      494178 :    END SUBROUTINE cp_blacs_env_retain
     273             : 
     274             : ! **************************************************************************************************
     275             : !> \brief releases the given blacs_env
     276             : !> \param blacs_env the blacs env to release
     277             : !> \par History
     278             : !>      08.2002 created [fawzi]
     279             : !> \author Fawzi Mohamed
     280             : ! **************************************************************************************************
     281      609472 :    SUBROUTINE cp_blacs_env_release(blacs_env)
     282             :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     283             : 
     284      609472 :       IF (ASSOCIATED(blacs_env)) THEN
     285      590026 :          CPASSERT(blacs_env%ref_count > 0)
     286      590026 :          blacs_env%ref_count = blacs_env%ref_count - 1
     287      590026 :          IF (blacs_env%ref_count < 1) THEN
     288       95848 :             CALL blacs_env%release()
     289       95848 :             DEALLOCATE (blacs_env)
     290             :          END IF
     291             :       END IF
     292      609472 :       NULLIFY (blacs_env)
     293      609472 :    END SUBROUTINE cp_blacs_env_release
     294             : 
     295             : ! **************************************************************************************************
     296             : !> \brief releases the given blacs_env
     297             : !> \param blacs_env the blacs env to release
     298             : !> \par History
     299             : !>      08.2002 created [fawzi]
     300             : !> \author Fawzi Mohamed
     301             : ! **************************************************************************************************
     302       95848 :    SUBROUTINE cp_blacs_env_release_low(blacs_env)
     303             :       CLASS(cp_blacs_env_type), INTENT(INOUT)                   :: blacs_env
     304             : 
     305       95848 :       CALL blacs_env%gridexit()
     306       95848 :       CALL mp_para_env_release(blacs_env%para_env)
     307       95848 :       DEALLOCATE (blacs_env%mpi2blacs)
     308       95848 :       DEALLOCATE (blacs_env%blacs2mpi)
     309             : 
     310       95848 :    END SUBROUTINE cp_blacs_env_release_low
     311             : 
     312             : ! **************************************************************************************************
     313             : !> \brief writes the description of the given blacs env
     314             : !> \param blacs_env the blacs environment to write
     315             : !> \param unit_nr the unit number where to write the description of the
     316             : !>        blacs environment
     317             : !> \par History
     318             : !>      08.2002 created [fawzi]
     319             : !> \author Fawzi Mohamed
     320             : ! **************************************************************************************************
     321          70 :    SUBROUTINE cp_blacs_env_write(blacs_env, unit_nr)
     322             :       CLASS(cp_blacs_env_type), INTENT(IN)                :: blacs_env
     323             :       INTEGER, INTENT(in)                                :: unit_nr
     324             : 
     325             :       WRITE (unit=unit_nr, fmt="('  group=',i10,', ref_count=',i10,',')") &
     326          70 :          blacs_env%get_handle(), blacs_env%ref_count
     327             :       WRITE (unit=unit_nr, fmt="('  mepos=(',i8,',',i8,'),')") &
     328          70 :          blacs_env%mepos(1), blacs_env%mepos(2)
     329             :       WRITE (unit=unit_nr, fmt="('  num_pe=(',i8,',',i8,'),')") &
     330          70 :          blacs_env%num_pe(1), blacs_env%num_pe(2)
     331          70 :       IF (ASSOCIATED(blacs_env%blacs2mpi)) THEN
     332          70 :          WRITE (unit=unit_nr, fmt="('  blacs2mpi=')", advance="no")
     333          70 :          CALL cp_2d_i_write(blacs_env%blacs2mpi, unit_nr=unit_nr)
     334             :       ELSE
     335           0 :          WRITE (unit=unit_nr, fmt="('  blacs2mpi=*null*')")
     336             :       END IF
     337          70 :       IF (ASSOCIATED(blacs_env%para_env)) THEN
     338             :          WRITE (unit=unit_nr, fmt="('  para_env=<cp_para_env id=',i6,'>,')") &
     339          70 :             blacs_env%para_env%get_handle()
     340             :       ELSE
     341           0 :          WRITE (unit=unit_nr, fmt="('  para_env=*null*')")
     342             :       END IF
     343             :       WRITE (unit=unit_nr, fmt="('  my_pid=',i10,', n_pid=',i10,' }')") &
     344          70 :          blacs_env%my_pid, blacs_env%n_pid
     345          70 :       CALL m_flush(unit_nr)
     346          70 :    END SUBROUTINE cp_blacs_env_write
     347             : 
     348           0 : END MODULE cp_blacs_env

Generated by: LCOV version 1.15