Neko 1.99.3
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
comm.F90
Go to the documentation of this file.
1module comm
2 use mpi_f08, only : mpi_comm, mpi_datatype, mpi_initialized, mpi_init_thread, &
3 mpi_init, mpi_thread_multiple, mpi_thread_serialized, mpi_comm_rank, &
4 mpi_comm_split, mpi_comm_dup, mpi_barrier, mpi_comm_free, mpi_finalize, &
5 mpi_comm_world, mpi_double_precision, mpi_real, mpi_comm_size
6 use utils, only : neko_error
8 use shmem
9 !$ use omp_lib
10 implicit none
11 private
12
13 interface
14 subroutine neko_comm_wrapper_init(fcomm) &
15 bind(c, name='neko_comm_wrapper_init')
16 use, intrinsic :: iso_c_binding, only : c_int
17 integer(c_int), value :: fcomm
18 end subroutine neko_comm_wrapper_init
19
20#ifdef HAVE_NVSHMEM
21 subroutine neko_comm_nvshmem_init() &
22 bind(c, name='neko_comm_nvshmem_init')
23 end subroutine neko_comm_nvshmem_init
24
25 subroutine neko_comm_nvshmem_finalize() &
26 bind(c, name='neko_comm_nvshmem_finalize')
27 end subroutine neko_comm_nvshmem_finalize
28#endif
29
30#if defined(HAVE_NCCL) || defined(HAVE_RCCL)
31 subroutine neko_comm_nccl_init() &
32 bind(c, name='neko_comm_nccl_init')
33 end subroutine neko_comm_nccl_init
34
35 subroutine neko_comm_nccl_finalize() &
36 bind(c, name='neko_comm_nccl_finalize')
37 end subroutine neko_comm_nccl_finalize
38#endif
39
40 end interface
41
42
44 type(mpi_comm), public :: neko_comm
45 type(mpi_comm), public :: neko_global_comm
46
48#ifdef HAVE_MPI_PARAM_DTYPE
49 type(mpi_datatype), public, parameter :: mpi_real_precision = mpi_double_precision
50 type(mpi_datatype), public, parameter :: mpi_extra_precision = mpi_double_precision
51#else
52 type(mpi_datatype), public :: mpi_real_precision
53 type(mpi_datatype), public :: mpi_extra_precision
54#endif
55
57 integer, public :: pe_rank
58
60 integer, public :: pe_size
61
63 logical, public :: nio
64
66 integer, public :: global_pe_rank
67
69 integer, public :: global_pe_size
70
71 public :: comm_init, comm_free
72
73contains
74 subroutine comm_init
75 integer :: ierr
76 logical :: initialized
77 integer :: provided, nthrds
78 integer :: color = 0
79 integer :: envvar_len
80 character(len=255) :: color_str
81#ifdef HAVE_OPENSHMEM
82 integer :: shmem_ierr
83#endif
84
85 pe_rank = -1
86 pe_size = 0
87 nio = .false.
88
89 call mpi_initialized(initialized, ierr)
90
91 call get_environment_variable("NEKO_COMM_ID", color_str, envvar_len)
92 if (envvar_len .gt. 0) then
93 read(color_str(1:envvar_len), *) color
94 else
95 color = 0
96 end if
97
98 nthrds = 1
99 !$omp parallel
100 !$omp master
101 !$ nthrds = omp_get_num_threads()
102 !$omp end master
103 !$omp end parallel
104
105 if (.not.initialized) then
106 if (nthrds .gt. 1) then
107 call mpi_init_thread(mpi_thread_multiple, provided, ierr)
108 if (provided .ne. mpi_thread_multiple) then
109 ! MPI_THREAD_MULTIPLE is required for mt. device backends
110 if (neko_bcknd_device .eq. 1) then
111 call neko_error('Invalid thread support provided by MPI')
112 else
113 call mpi_init_thread(mpi_thread_serialized, provided, ierr)
114 if (provided .ne. mpi_thread_serialized) then
115 call neko_error('Invalid thread support provided by MPI')
116 end if
117 end if
118 end if
119 else
120 call mpi_init(ierr)
121 end if
122 end if
123
124#ifndef HAVE_MPI_PARAM_DTYPE
125 mpi_real_precision = mpi_double_precision
126 mpi_extra_precision = mpi_double_precision
127#endif
128
129
130#ifdef HAVE_ADIOS2
131 ! We split the communicator it to work asynchronously (MPMD)
132 call mpi_comm_rank(mpi_comm_world, pe_rank, ierr)
133 call mpi_comm_split(mpi_comm_world, 0, pe_rank, neko_global_comm, ierr)
134#else
135 ! Original version duplicates the communicator:
136 call mpi_comm_dup(mpi_comm_world, neko_global_comm, ierr)
137#endif
138
139 call mpi_comm_rank(neko_global_comm, global_pe_rank, ierr)
140 call mpi_comm_size(neko_global_comm, global_pe_size, ierr)
141 if (envvar_len .gt. 0) then
142 call mpi_comm_split(neko_global_comm, color, global_pe_rank, &
143 neko_comm, ierr)
144 else
145 call mpi_comm_dup(neko_global_comm, neko_comm, ierr)
146 end if
147 call mpi_comm_rank(neko_comm, pe_rank, ierr)
148 call mpi_comm_size(neko_comm, pe_size, ierr)
149
150 ! Setup C/C++ wrapper
152
153
154#ifdef HAVE_NVSHMEM
155 ! Setup NVSHMEM (if requested)
156 call neko_comm_nvshmem_init()
157#endif
158
159#if defined(HAVE_NCCL) | defined(HAVE_RCCL)
160 ! Setup NCCL (if requested)
161 call neko_comm_nccl_init()
162#endif
163
164#ifdef HAVE_OPENSHMEM
165 ! Setup OpenSHMEM (if requested)
166 if (nthrds .gt. 1) then
167 shmem_ierr = shmem_init_thread(shmem_thread_multiple, provided)
168 if (provided .ne. shmem_thread_multiple) then
169 if (neko_bcknd_device .eq. 1) then
170 call neko_error('Invalid thread support provided by SHMEM')
171 else
172 shmem_ierr = shmem_init_thread(shmem_thread_serialized, provided)
173 if (provided .ne. shmem_thread_serialized) then
174 call neko_error('Invalid thread support provided by SHMEM')
175 end if
176 end if
177 end if
178 else
179 call shmem_init()
180 end if
181#endif
182
183
184 end subroutine comm_init
185
186 subroutine comm_free
187 integer :: ierr
188
189 call mpi_barrier(neko_comm, ierr)
190 call mpi_comm_free(neko_comm, ierr)
191 call mpi_comm_free(neko_global_comm, ierr)
192
193#ifdef HAVE_NCCL
194 call neko_comm_nccl_finalize()
195#endif
196
197#ifdef HAVE_NVSHMEM
198 call neko_comm_nvshmem_finalize()
199#endif
200
201#ifdef HAVE_OPENSHMEM
202 call shmem_finalize()
203#endif
204
205 call mpi_finalize(ierr)
206
207 end subroutine comm_free
208
209end module comm
Definition comm.F90:1
subroutine, public comm_free
Definition comm.F90:187
subroutine, public comm_init
Definition comm.F90:75
logical, public nio
I/O node.
Definition comm.F90:63
type(mpi_comm), public neko_global_comm
Definition comm.F90:45
type(mpi_datatype), public mpi_real_precision
MPI type for working precision of REAL types.
Definition comm.F90:52
integer, public global_pe_rank
Global MPI rank.
Definition comm.F90:66
integer, public pe_size
MPI size of communicator.
Definition comm.F90:60
integer, public pe_rank
MPI rank.
Definition comm.F90:57
integer, public global_pe_size
Global MPI size of communicator.
Definition comm.F90:69
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:44
type(mpi_datatype), public mpi_extra_precision
Definition comm.F90:53
Build configurations.
integer, parameter neko_bcknd_device
Fortran bindings to SHMEM's C API.
Definition shmem.F90:34
@ shmem_thread_serialized
Definition shmem.F90:56
@ shmem_thread_multiple
Definition shmem.F90:57
Utilities.
Definition utils.f90:35