1!--------------------------------------------------------------------------------------------------! 2! CP2K: A general program to perform molecular dynamics simulations ! 3! Copyright (C) 2000 - 2019 CP2K developers group ! 4!--------------------------------------------------------------------------------------------------! 5 6! ************************************************************************************************** 7!> \brief type to store parallelization informations (at the moment assumes 1d 8!> position and uses mpi) 9!> \par History 10!> 07.2002 created [fawzi] 11!> \author Fawzi Mohamed 12! ************************************************************************************************** 13MODULE cp_para_env 14 USE cp_para_types, ONLY: cp_para_cart_type,& 15 cp_para_env_type 16 USE message_passing, ONLY: mp_comm_free,& 17 mp_environ 18#include "../base/base_uses.f90" 19 20 IMPLICIT NONE 21 PRIVATE 22 23 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE. 24 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_para_env' 25 26 PUBLIC :: cp_para_env_retain, cp_para_env_release, cp_para_env_create 27 PUBLIC :: cp_cart_create, cp_cart_release 28!*** 29CONTAINS 30 31! ************************************************************************************************** 32!> \brief creates a new para environment 33!> \param para_env the new parallel environment 34!> \param group the id of the actual mpi_group 35!> \param source the id of the special (master) processor (defaults to 0) 36!> \param mepos the id of the actual processor 37!> \param num_pe the number of processors in the group 38!> \param owns_group if the group is owned by this object (defaults to true) 39!> \par History 40!> 08.2002 created [fawzi] 41!> \author Fawzi Mohamed 42! ************************************************************************************************** 43 SUBROUTINE cp_para_env_create(para_env, group, source, mepos, num_pe, & 44 owns_group) 45 TYPE(cp_para_env_type), POINTER :: para_env 46 INTEGER, INTENT(in) :: group 47 INTEGER, INTENT(in), OPTIONAL :: source, mepos, num_pe 48 LOGICAL, INTENT(in), OPTIONAL :: owns_group 49 50 CHARACTER(len=*), PARAMETER :: routineN = 'cp_para_env_create', & 51 routineP = moduleN//':'//routineN 52 53 CPASSERT(.NOT. ASSOCIATED(para_env)) 54 ALLOCATE (para_env) 55 para_env%group = group 56 para_env%source = 0 57 para_env%ref_count = 1 58 para_env%owns_group = .TRUE. 59 IF (PRESENT(source)) para_env%source = source 60 IF (PRESENT(owns_group)) para_env%owns_group = owns_group 61 IF (.NOT. (PRESENT(mepos) .AND. PRESENT(num_pe))) THEN 62 CALL cp_para_env_update(para_env) 63 ELSE 64 para_env%mepos = mepos 65 para_env%num_pe = num_pe 66 END IF 67 para_env%ionode = para_env%mepos == para_env%source 68 END SUBROUTINE cp_para_env_create 69 70! ************************************************************************************************** 71!> \brief retains the para object (to be called when you want to keep a 72!> shared copy of this object) 73!> \param para_env the new group 74!> \par History 75!> 08.2002 created [fawzi] 76!> \author Fawzi Mohamed 77! ************************************************************************************************** 78 SUBROUTINE cp_para_env_retain(para_env) 79 TYPE(cp_para_env_type), POINTER :: para_env 80 81 CHARACTER(len=*), PARAMETER :: routineN = 'cp_para_env_retain', & 82 routineP = moduleN//':'//routineN 83 84 CPASSERT(ASSOCIATED(para_env)) 85 CPASSERT(para_env%ref_count > 0) 86 para_env%ref_count = para_env%ref_count + 1 87 END SUBROUTINE cp_para_env_retain 88 89! ************************************************************************************************** 90!> \brief releases the para object (to be called when you don't want anymore 91!> the shared copy of this object) 92!> \param para_env the new group 93!> \par History 94!> 08.2002 created [fawzi] 95!> \author Fawzi Mohamed 96!> \note 97!> to avoid circular dependencies cp_log_handling has a private copy 98!> of this method (see cp_log_handling:my_cp_para_env_release)! 99! ************************************************************************************************** 100 SUBROUTINE cp_para_env_release(para_env) 101 TYPE(cp_para_env_type), POINTER :: para_env 102 103 CHARACTER(len=*), PARAMETER :: routineN = 'cp_para_env_release', & 104 routineP = moduleN//':'//routineN 105 106 IF (ASSOCIATED(para_env)) THEN 107 CPASSERT(para_env%ref_count > 0) 108 para_env%ref_count = para_env%ref_count - 1 109 IF (para_env%ref_count < 1) THEN 110 IF (para_env%owns_group) THEN 111 CALL mp_comm_free(para_env%group) 112 END IF 113 DEALLOCATE (para_env) 114 END IF 115 END IF 116 NULLIFY (para_env) 117 END SUBROUTINE cp_para_env_release 118 119! ************************************************************************************************** 120!> \brief gets again the position and size of the group from the mpi_group 121!> \param para_env the new group 122!> \par History 123!> 08.2002 created [fawzi] 124!> \author Fawzi Mohamed 125! ************************************************************************************************** 126 SUBROUTINE cp_para_env_update(para_env) 127 TYPE(cp_para_env_type), POINTER :: para_env 128 129 CHARACTER(len=*), PARAMETER :: routineN = 'cp_para_env_update', & 130 routineP = moduleN//':'//routineN 131 132 CPASSERT(ASSOCIATED(para_env)) 133 CPASSERT(para_env%ref_count > 0) 134 CALL mp_environ(taskid=para_env%mepos, numtask=para_env%num_pe, & 135 groupid=para_env%group) 136 para_env%ionode = para_env%mepos == para_env%source 137 END SUBROUTINE cp_para_env_update 138 139! ************************************************************************************************** 140!> \brief creates a cart (multidimensional parallel environment) 141!> \param cart the cart environment to create 142!> \param group the mpi communicator 143!> \param ndims the number of dimensions of the cart 144!> \param owns_group if this object owns the underlying cart (and should 145!> free it) 146!> \author fawzi 147! ************************************************************************************************** 148 SUBROUTINE cp_cart_create(cart, group, ndims, owns_group) 149 TYPE(cp_para_cart_type), POINTER :: cart 150 INTEGER, INTENT(in) :: group, ndims 151 LOGICAL, INTENT(in), OPTIONAL :: owns_group 152 153 CHARACTER(len=*), PARAMETER :: routineN = 'cp_cart_create', routineP = moduleN//':'//routineN 154 155 CPASSERT(.NOT. ASSOCIATED(cart)) 156 ALLOCATE (cart) 157 cart%owns_group = .TRUE. 158 IF (PRESENT(owns_group)) cart%owns_group = owns_group 159 cart%ndims = ndims 160 cart%group = group 161 162 ALLOCATE (cart%source(ndims), cart%periodic(ndims), cart%mepos(ndims), & 163 cart%num_pe(ndims)) 164 165 cart%source = 0 166 cart%mepos = 0 167 cart%periodic = .FALSE. 168 cart%ref_count = 1 169 cart%ntask = 1 170 CALL cp_cart_update(cart) 171 END SUBROUTINE cp_cart_create 172 173! ************************************************************************************************** 174!> \brief updates the information about the given cart 175!> \param cart the cart to update 176!> \author fawzi 177! ************************************************************************************************** 178 SUBROUTINE cp_cart_update(cart) 179 TYPE(cp_para_cart_type), POINTER :: cart 180 181 CHARACTER(len=*), PARAMETER :: routineN = 'cp_cart_update', routineP = moduleN//':'//routineN 182 183 CPASSERT(ASSOCIATED(cart)) 184 CPASSERT(cart%ref_count > 0) 185 CALL mp_environ(cart%group, cart%ndims, cart%num_pe, task_coor=cart%mepos, & 186 periods=cart%periodic) 187 CALL mp_environ(numtask=cart%ntask, taskid=cart%rank, groupid=cart%group) 188 END SUBROUTINE cp_cart_update 189 190! ************************************************************************************************** 191!> \brief releases the given cart 192!> \param cart the cart to release 193!> \author fawzi 194! ************************************************************************************************** 195 SUBROUTINE cp_cart_release(cart) 196 TYPE(cp_para_cart_type), POINTER :: cart 197 198 CHARACTER(len=*), PARAMETER :: routineN = 'cp_cart_release', & 199 routineP = moduleN//':'//routineN 200 201 IF (ASSOCIATED(cart)) THEN 202 CPASSERT(cart%ref_count > 0) 203 cart%ref_count = cart%ref_count - 1 204 IF (cart%ref_count == 0) THEN 205 IF (cart%owns_group) THEN 206 CALL mp_comm_free(cart%group) 207 END IF 208 DEALLOCATE (cart%source, cart%periodic, cart%mepos, cart%num_pe) 209 DEALLOCATE (cart) 210 END IF 211 END IF 212 NULLIFY (cart) 213 END SUBROUTINE cp_cart_release 214 215END MODULE cp_para_env 216