ICON Community Interface 0.4.0
Loading...
Searching...
No Matches
comin_parallel.F90
Go to the documentation of this file.
1
3!
4! @authors 09/2022 :: ICON Community Interface <comin@icon-model.org>
5!
6! SPDX-License-Identifier: BSD-3-Clause
7!
8! See LICENSES for license information.
9! Where software is supplied by third parties, it is indicated in the
10! headers of the routines.
11!
13
14 USE mpi
15 USE comin_state, ONLY: state
17 USE iso_c_binding, ONLY: c_int
19
20 IMPLICIT NONE
21
22 PRIVATE
23
30
31#include "comin_global.inc"
32
33 ! max. character string length (e.g. MPI group name)
34 INTEGER, PARAMETER :: MAX_GRPNAMELEN = 256
35
36 INTEGER, PARAMETER :: MAX_GROUPS = 64
37
38 ! level for debug output verbosity (0: quiet)
39 INTEGER, PARAMETER :: debug_level = 0
40
41CONTAINS
42
48 SUBROUTINE comin_parallel_mpi_handshake(comm, group_names, component_name)
50
51 INTEGER, INTENT(IN) :: comm
52 CHARACTER(LEN=MAX_GRPNAMELEN), INTENT(IN) :: group_names(:)
53 CHARACTER(LEN=*), INTENT(IN) :: component_name
54 !
55 INTEGER :: num_plugin_comms
56 CHARACTER(LEN=MAX_GRPNAMELEN), ALLOCATABLE :: all_group_names(:)
57 INTEGER, ALLOCATABLE :: all_comms(:)
58
59 num_plugin_comms = count(group_names /= "")
60 ALLOCATE(all_group_names(num_plugin_comms+1))
61 IF(num_plugin_comms > 0) &
62 all_group_names(1:num_plugin_comms) = pack(group_names, group_names /= "")
63 all_group_names(num_plugin_comms+1) = "comin_host_"//component_name
64
65 ALLOCATE(all_comms(num_plugin_comms+1))
66 CALL mpi_handshake(comm, all_group_names, all_comms)
67
68 ALLOCATE(state%parallel_info%component_name_bilateral(num_plugin_comms))
69 state%parallel_info%component_name_bilateral = all_group_names(1:num_plugin_comms)
70 state%parallel_info%mpi_comm_bilateral = all_comms(1:num_plugin_comms)
71 state%parallel_info%host_comm = all_comms(num_plugin_comms+1)
72
73 DEALLOCATE(all_group_names)
74 DEALLOCATE(all_comms)
75 END SUBROUTINE comin_parallel_mpi_handshake
76
78 INTEGER :: i, ierr, nmpi_comm
79
80 IF (.NOT. ALLOCATED(state%parallel_info%mpi_comm_bilateral)) RETURN
81 nmpi_comm = SIZE(state%parallel_info%mpi_comm_bilateral)
82 DO i=1,nmpi_comm
83 CALL mpi_comm_free(state%parallel_info%mpi_comm_bilateral(i), ierr)
85 state%parallel_info%mpi_comm_bilateral(i) = mpi_comm_null
86 END DO
87 DEALLOCATE(state%parallel_info%mpi_comm_bilateral)
88 DEALLOCATE(state%parallel_info%component_name_bilateral)
90
94 INTEGER FUNCTION comin_parallel_get_host_mpi_comm() RESULT(mpi_comm)
95 mpi_comm = state%parallel_info%host_comm
97
98 ! Wrapper function that converts the communicator to C_INT
99 INTEGER(KIND=C_INT) FUNCTION comin_parallel_get_host_mpi_comm_c() &
100 result(mpi_comm) BIND(C, name="comin_parallel_get_host_mpi_comm")
102 END FUNCTION comin_parallel_get_host_mpi_comm_c
103
109 INTEGER FUNCTION comin_parallel_get_plugin_mpi_comm() RESULT(mpi_comm)
110 mpi_comm = comin_parallel_find_mpi_comm(state%parallel_info, state%current_plugin%comm)
111 IF(mpi_comm == mpi_comm_null) THEN
112 CALL comin_plugin_finish("comin_parallel_get_plugin_mpi_comm", &
113 & "Error: To use the plugin_comm, 'comm' must be set in the plugin namelist")
114 END IF
116
117 ! Wrapper function that converts the communicator to C_INT
118 INTEGER(KIND=C_INT) FUNCTION comin_parallel_get_plugin_mpi_comm_c() &
119 result(mpi_comm) BIND(C, name="comin_parallel_get_plugin_mpi_comm")
121 END FUNCTION comin_parallel_get_plugin_mpi_comm_c
122
127 INTEGER(KIND=C_INT) FUNCTION comin_parallel_get_host_mpi_rank() RESULT(mpi_rank) BIND(C)
128 INTEGER :: mpi_comm, ierr, rank_f
130 CALL mpi_comm_rank(mpi_comm, rank_f, ierr)
132 mpi_rank = rank_f
134
136 ! by a PE of each group plus a "root group".
137 !
138 INTEGER FUNCTION comin_parallel_find_mpi_comm(parallel_info, component_name)
139 TYPE(t_comin_parallel_info), INTENT(IN) :: parallel_info
140 CHARACTER(LEN=*), INTENT(IN) :: component_name
141 !
142 INTEGER :: i, nmpi_comm
143
144 comin_parallel_find_mpi_comm = mpi_comm_null
145 IF (.NOT. ALLOCATED(parallel_info%mpi_comm_bilateral)) RETURN
146 nmpi_comm = SIZE(parallel_info%mpi_comm_bilateral)
147 loop : DO i=1,nmpi_comm
148 IF (trim(parallel_info%component_name_bilateral(i)) == component_name) THEN
149 comin_parallel_find_mpi_comm = parallel_info%mpi_comm_bilateral(i)
150 EXIT loop
151 END IF
152 END DO loop
153 END FUNCTION comin_parallel_find_mpi_comm
154
157 INTEGER, INTENT(IN) :: errcode
158 INTEGER :: ierr
159 IF (errcode .NE. mpi_success) THEN
160 WRITE (0,*) "Error in MPI program. Terminating."
161 CALL mpi_abort(mpi_comm_world, errcode, ierr)
162 END IF
164
165END MODULE comin_parallel
integer function, public comin_parallel_get_host_mpi_comm()
Returns the communicator with all ICON processes.
subroutine, public mpi_handshake(comm, group_names, group_comms)
Procedure for the communicator splitting ("MPI handshake") that has been harmonized with the respecti...
subroutine, public comin_parallel_mpi_handshake(comm, group_names, component_name)
Procedure for the communicator splitting ("MPI handshake") that has been harmonized with the respecti...
subroutine, public comin_plugin_finish(routine, text)
Wrapper function for callback to ICON's "finish" routine.
integer function, public comin_parallel_get_plugin_mpi_comm()
Called within a plugin's callback function: get MPI communicator which contains all MPI tasks of the ...
integer(kind=c_int) function, public comin_parallel_get_host_mpi_rank()
Called within a plugin's callback function: get MPI rank with respect to the "host" MPI communicator.
subroutine, public comin_parallel_handle_mpi_errcode(errcode)
Utility function.
subroutine, public comin_parallel_free_mpi_comms()
type(t_comin_state), pointer, public state