Neko 1.99.1
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 omp_lib
9 implicit none
10 private
11
12 interface
13 subroutine neko_comm_wrapper_init(fcomm) &
14 bind(c, name='neko_comm_wrapper_init')
15 use, intrinsic :: iso_c_binding, only : c_int
16 integer(c_int), value :: fcomm
17 end subroutine neko_comm_wrapper_init
18
19#ifdef HAVE_NVSHMEM
20 subroutine neko_comm_nvshmem_init() &
21 bind(c, name='neko_comm_nvshmem_init')
22 end subroutine neko_comm_nvshmem_init
23
24 subroutine neko_comm_nvshmem_finalize() &
25 bind(c, name='neko_comm_nvshmem_finalize')
26 end subroutine neko_comm_nvshmem_finalize
27#endif
28
29#if defined(HAVE_NCCL) || defined(HAVE_RCCL)
30 subroutine neko_comm_nccl_init() &
31 bind(c, name='neko_comm_nccl_init')
32 end subroutine neko_comm_nccl_init
33
34 subroutine neko_comm_nccl_finalize() &
35 bind(c, name='neko_comm_nccl_finalize')
36 end subroutine neko_comm_nccl_finalize
37#endif
38
39 end interface
40
41
43 type(mpi_comm), public :: neko_comm
44 type(mpi_comm), public :: neko_global_comm
45
47#ifdef HAVE_MPI_PARAM_DTYPE
48 type(mpi_datatype), public, parameter :: mpi_real_precision = mpi_double_precision
49 type(mpi_datatype), public, parameter :: mpi_extra_precision = mpi_double_precision
50#else
51 type(mpi_datatype), public :: mpi_real_precision
52 type(mpi_datatype), public :: mpi_extra_precision
53#endif
54
56 integer, public :: pe_rank
57
59 integer, public :: pe_size
60
62 logical, public :: nio
63
65 integer, public :: global_pe_rank
66
68 integer, public :: global_pe_size
69
70 public :: comm_init, comm_free
71
72contains
73 subroutine comm_init
74 integer :: ierr
75 logical :: initialized
76 integer :: provided, nthrds
77 integer :: color = 0
78 integer :: envvar_len
79 character(len=255) :: color_str
80
81 pe_rank = -1
82 pe_size = 0
83 nio = .false.
84
85 call mpi_initialized(initialized, ierr)
86
87 call get_environment_variable("NEKO_COMM_ID", color_str, envvar_len)
88 if (envvar_len .gt. 0) then
89 read(color_str(1:envvar_len), *) color
90 else
91 color = 0
92 end if
93
94 nthrds = 1
95 !$omp parallel
96 !$omp master
97 !$ nthrds = omp_get_num_threads()
98 !$omp end master
99 !$omp end parallel
100
101 if (.not.initialized) then
102 if (nthrds .gt. 1) then
103 call mpi_init_thread(mpi_thread_multiple, provided, ierr)
104 if (provided .ne. mpi_thread_multiple) then
105 ! MPI_THREAD_MULTIPLE is required for mt. device backends
106 if (neko_bcknd_device .eq. 1) then
107 call neko_error('Invalid thread support provided by MPI')
108 else
109 call mpi_init_thread(mpi_thread_serialized, provided, ierr)
110 if (provided .ne. mpi_thread_serialized) then
111 call neko_error('Invalid thread support provided by MPI')
112 end if
113 end if
114 end if
115 else
116 call mpi_init(ierr)
117 end if
118 end if
119
120#ifndef HAVE_MPI_PARAM_DTYPE
121 mpi_real_precision = mpi_double_precision
122 mpi_extra_precision = mpi_double_precision
123#endif
124
125
126#ifdef HAVE_ADIOS2
127 ! We split the communicator it to work asynchronously (MPMD)
128 call mpi_comm_rank(mpi_comm_world, pe_rank, ierr)
129 call mpi_comm_split(mpi_comm_world, 0, pe_rank, neko_global_comm, ierr)
130#else
131 ! Original version duplicates the communicator:
132 call mpi_comm_dup(mpi_comm_world, neko_global_comm, ierr)
133#endif
134
135 call mpi_comm_rank(neko_global_comm, global_pe_rank, ierr)
136 call mpi_comm_size(neko_global_comm, global_pe_size, ierr)
137 if (envvar_len .gt. 0) then
138 call mpi_comm_split(neko_global_comm, color, global_pe_rank, &
139 neko_comm, ierr)
140 else
141 call mpi_comm_dup(neko_global_comm, neko_comm, ierr)
142 end if
143 call mpi_comm_rank(neko_comm, pe_rank, ierr)
144 call mpi_comm_size(neko_comm, pe_size, ierr)
145
146 ! Setup C/C++ wrapper
148
149
150#ifdef HAVE_NVSHMEM
151 ! Setup NVSHMEM (if requested)
152 call neko_comm_nvshmem_init()
153#endif
154
155#if defined(HAVE_NCCL) | defined(HAVE_RCCL)
156 ! Setup NCCL (if requested)
157 call neko_comm_nccl_init()
158#endif
159
160
161 end subroutine comm_init
162
163 subroutine comm_free
164 integer :: ierr
165
166 call mpi_barrier(neko_comm, ierr)
167 call mpi_comm_free(neko_comm, ierr)
168
169#ifdef HAVE_NCCL
170 call neko_comm_nccl_finalize()
171#endif
172
173#ifdef HAVE_NVSHMEM
174 call neko_comm_nvshmem_finalize()
175#endif
176
177 call mpi_finalize(ierr)
178
179 end subroutine comm_free
180
181end module comm
Definition comm.F90:1
subroutine, public comm_free
Definition comm.F90:164
subroutine, public comm_init
Definition comm.F90:74
logical, public nio
I/O node.
Definition comm.F90:62
type(mpi_comm), public neko_global_comm
Definition comm.F90:44
type(mpi_datatype), public mpi_real_precision
MPI type for working precision of REAL types.
Definition comm.F90:51
integer, public global_pe_rank
Global MPI rank.
Definition comm.F90:65
integer, public pe_size
MPI size of communicator.
Definition comm.F90:59
integer, public pe_rank
MPI rank.
Definition comm.F90:56
integer, public global_pe_size
Global MPI size of communicator.
Definition comm.F90:68
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:43
type(mpi_datatype), public mpi_extra_precision
Definition comm.F90:52
Build configurations.
integer, parameter neko_bcknd_device
Utilities.
Definition utils.f90:35