Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
gs_comm.f90
Go to the documentation of this file.
1! Copyright (c) 2022-2026, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
34module gs_comm
35 use num_types, only : rp
36 use comm, only : pe_size
37 use stack, only : stack_i4_t
38 use utils, only : neko_error
39 use, intrinsic :: iso_c_binding
40 implicit none
41 private
42
43 integer, public, parameter :: gs_comm_mpi = 1, gs_comm_mpigpu = 2, &
47
50 integer, public, parameter :: gs_vec_nc = 3
51
53 type, public, abstract :: gs_comm_t
55 type(stack_i4_t), allocatable :: send_dof(:)
58 type(stack_i4_t), allocatable :: recv_dof(:)
62 integer, allocatable :: send_pe(:)
64 integer, allocatable :: recv_pe(:)
68 logical :: vec_supported = .false.
79 logical :: vec_ready = .false.
80 contains
81 procedure(gs_comm_init), pass(this), deferred :: init
82 procedure(gs_comm_free), pass(this), deferred :: free
83 procedure(gs_nbsend), pass(this), deferred :: nbsend
84 procedure(gs_nbrecv), pass(this), deferred :: nbrecv
85 procedure(gs_nbwait), pass(this), deferred :: nbwait
86 procedure, pass(this) :: init_dofs
87 procedure, pass(this) :: free_dofs
88 procedure, pass(this) :: init_order
89 procedure, pass(this) :: free_order
90 procedure, pass(this) :: take_schedule
91 procedure, pass(this) :: init_schedule
94 procedure, pass(this) :: init_vec => gs_init_vec
95 procedure, pass(this) :: nbsend_vec => gs_nbsend_vec
96 procedure, pass(this) :: nbrecv_vec => gs_nbrecv_vec
97 procedure, pass(this) :: nbwait_vec => gs_nbwait_vec
98 end type gs_comm_t
99
103 abstract interface
104 subroutine gs_comm_init(this, send_pe, recv_pe)
105 import gs_comm_t
106 import stack_i4_t
107 class(gs_comm_t), intent(inout) :: this
108 type(stack_i4_t), intent(inout) :: send_pe
109 type(stack_i4_t), intent(inout) :: recv_pe
110 end subroutine gs_comm_init
111 end interface
112
114 abstract interface
115 subroutine gs_comm_free(this)
116 import gs_comm_t
117 class(gs_comm_t), intent(inout) :: this
118 end subroutine gs_comm_free
119 end interface
120
127 abstract interface
128 subroutine gs_nbsend(this, u, n, tag, deps, strm)
129 import gs_comm_t
130 import stack_i4_t
131 import c_ptr
132 import rp
133 class(gs_comm_t), intent(inout) :: this
134 integer, intent(in) :: n
135 real(kind=rp), dimension(n), intent(inout) :: u
136 integer, intent(in) :: tag
137 type(c_ptr), intent(inout) :: deps
138 type(c_ptr), intent(inout) :: strm
139 end subroutine gs_nbsend
140 end interface
141
142
145 abstract interface
146 subroutine gs_nbrecv(this, tag)
147 import gs_comm_t
148 class(gs_comm_t), intent(inout) :: this
149 integer, intent(in) :: tag
150 end subroutine gs_nbrecv
151 end interface
152
161 abstract interface
162 subroutine gs_nbwait(this, u, n, op, strm)
163 import gs_comm_t
164 import stack_i4_t
165 import c_ptr
166 import rp
167 class(gs_comm_t), intent(inout) :: this
168 integer, intent(in) :: n
169 real(kind=rp), dimension(n), intent(inout) :: u
170 integer :: op
171 type(c_ptr), intent(inout) :: strm
172 end subroutine gs_nbwait
173 end interface
174
176contains
177 !Initalize stacks for each rank of dof indices to send/recv
178 subroutine init_dofs(this)
179 class(gs_comm_t), intent(inout) :: this
180 integer :: i
181
182 call this%free_dofs()
183
184 allocate(this%send_dof(0:pe_size-1))
185 allocate(this%recv_dof(0:pe_size-1))
186
187 do i = 0, pe_size -1
188 call this%send_dof(i)%init()
189 call this%recv_dof(i)%init()
190 end do
191
192 end subroutine init_dofs
193
194 subroutine free_dofs(this)
195 class(gs_comm_t), intent(inout) :: this
196 integer :: i
197
198 if (allocated(this%send_dof)) then
199 do i = 0, pe_size - 1
200 call this%send_dof(i)%free()
201 end do
202 deallocate(this%send_dof)
203 end if
204
205 if (allocated(this%recv_dof)) then
206 do i = 0, pe_size - 1
207 call this%recv_dof(i)%free()
208 end do
209 deallocate(this%recv_dof)
210 end if
211
212 end subroutine free_dofs
213
217 subroutine init_order(this, send_pe, recv_pe)
218 class(gs_comm_t), intent(inout) :: this
219 type(stack_i4_t), intent(inout) :: send_pe
220 type(stack_i4_t), intent(inout) :: recv_pe
221 integer, pointer :: sp(:)
222 integer :: i
223
224 allocate(this%send_pe(send_pe%size()))
225
226 sp => send_pe%array()
227 do i = 1, send_pe%size()
228 this%send_pe(i) = sp(i)
229 end do
230
231 allocate(this%recv_pe(recv_pe%size()))
232
233 sp => recv_pe%array()
234 do i = 1, recv_pe%size()
235 this%recv_pe(i) = sp(i)
236 end do
237
238 end subroutine init_order
239
240 subroutine free_order(this)
241 class(gs_comm_t), intent(inout) :: this
242
243 if (allocated(this%send_pe)) then
244 deallocate(this%send_pe)
245 end if
246
247 if (allocated(this%recv_pe)) then
248 deallocate(this%recv_pe)
249 end if
250
251 end subroutine free_order
252
261 subroutine take_schedule(this, src)
262 class(gs_comm_t), intent(inout) :: this
263 class(gs_comm_t), intent(inout) :: src
264
265 if (.not. allocated(src%send_dof) .or. .not. allocated(src%recv_dof) .or. &
266 .not. allocated(src%send_pe) .or. .not. allocated(src%recv_pe)) then
267 call neko_error('Gather-scatter comm. method has no schedule')
268 end if
269
270 call this%free_dofs()
271 call this%free_order()
272
273 call move_alloc(src%send_dof, this%send_dof)
274 call move_alloc(src%recv_dof, this%recv_dof)
275 call move_alloc(src%send_pe, this%send_pe)
276 call move_alloc(src%recv_pe, this%recv_pe)
277
278 end subroutine take_schedule
279
282 subroutine init_schedule(this)
283 class(gs_comm_t), intent(inout) :: this
284 type(stack_i4_t) :: send_pe, recv_pe
285 integer, allocatable :: sp(:), rp(:)
286 integer :: i, pe
287
288 if (.not. allocated(this%send_pe) .or. .not. allocated(this%recv_pe)) then
289 call neko_error('Gather-scatter comm. method has no schedule')
290 end if
291
292 ! init_order allocates send_pe/recv_pe from the stacks, so hand the
293 ! peer lists back as stacks and leave the arrays deallocated
294 call move_alloc(this%send_pe, sp)
295 call move_alloc(this%recv_pe, rp)
296
297 call send_pe%init(max(size(sp), 1))
298 do i = 1, size(sp)
299 pe = sp(i)
300 call send_pe%push(pe)
301 end do
302
303 call recv_pe%init(max(size(rp), 1))
304 do i = 1, size(rp)
305 pe = rp(i)
306 call recv_pe%push(pe)
307 end do
308
309 deallocate(sp, rp)
310
311 call this%init(send_pe, recv_pe)
312
313 call send_pe%free()
314 call recv_pe%free()
315
316 end subroutine init_schedule
317
324 subroutine gs_init_vec(this)
325 class(gs_comm_t), intent(inout) :: this
326 call neko_error('Vector gather-scatter not supported by this comm backend')
327 end subroutine gs_init_vec
328
333 subroutine gs_nbsend_vec(this, u, n, nc, tag, deps, strm)
334 class(gs_comm_t), intent(inout) :: this
335 integer, intent(in) :: n, nc
336 real(kind=rp), dimension(nc*n), intent(inout) :: u
337 integer, intent(in) :: tag
338 type(c_ptr), intent(inout) :: deps
339 type(c_ptr), intent(inout) :: strm
340 call neko_error('Vector gather-scatter not supported by this comm backend')
341 end subroutine gs_nbsend_vec
342
344 subroutine gs_nbrecv_vec(this, tag, nc)
345 class(gs_comm_t), intent(inout) :: this
346 integer, intent(in) :: tag, nc
347 call neko_error('Vector gather-scatter not supported by this comm backend')
348 end subroutine gs_nbrecv_vec
349
351 subroutine gs_nbwait_vec(this, u, n, nc, op, strm)
352 class(gs_comm_t), intent(inout) :: this
353 integer, intent(in) :: n, nc
354 real(kind=rp), dimension(nc*n), intent(inout) :: u
355 integer :: op
356 type(c_ptr), intent(inout) :: strm
357 call neko_error('Vector gather-scatter not supported by this comm backend')
358 end subroutine gs_nbwait_vec
359
360end module gs_comm
Abstract interface for deallocating a Gather-scatter communication method.
Definition gs_comm.f90:115
Abstract interface for initializing a Gather-scatter communication method.
Definition gs_comm.f90:104
Abstract interface for initiating non-blocking recieve operations Posts non-blocking recieve of value...
Definition gs_comm.f90:146
Abstract interface for initiating non-blocking send operations Sends the values in u(send_dof(send_pe...
Definition gs_comm.f90:128
Abstract interface for waiting on non-blocking operations Waits and checks that data is in buffers an...
Definition gs_comm.f90:162
Definition comm.F90:1
integer, public pe_size
MPI size of communicator.
Definition comm.F90:62
Defines a gather-scatter communication method.
Definition gs_comm.f90:34
integer, parameter, public gs_comm_mpirma
Definition gs_comm.f90:43
subroutine init_schedule(this)
Set up this communication method for the schedule taken over by take_schedule. Collective,...
Definition gs_comm.f90:283
subroutine gs_nbsend_vec(this, u, n, nc, tag, deps, strm)
Default fused vector send. Abort unless a backend overrides it.
Definition gs_comm.f90:334
subroutine init_dofs(this)
Definition gs_comm.f90:179
subroutine gs_nbrecv_vec(this, tag, nc)
Default fused vector receive. Abort unless a backend overrides it.
Definition gs_comm.f90:345
integer, parameter, public gs_vec_nc
Maximum number of components handled by the fused vector (multi-component) halo exchange used by gs_o...
Definition gs_comm.f90:50
integer, parameter, public gs_comm_crystal
Definition gs_comm.f90:43
integer, parameter, public gs_comm_mpigpu
Definition gs_comm.f90:43
integer, parameter, public gs_comm_crystalgpu
Definition gs_comm.f90:43
subroutine take_schedule(this, src)
Take over the gather-scatter schedule (dof lists and peer order) of src, avoiding a second (expensive...
Definition gs_comm.f90:262
integer, parameter, public gs_comm_neighbour
Definition gs_comm.f90:43
integer, parameter, public gs_comm_mpi
Definition gs_comm.f90:43
subroutine init_order(this, send_pe, recv_pe)
Obtains which ranks to send and receive data from.
Definition gs_comm.f90:218
subroutine gs_nbwait_vec(this, u, n, nc, op, strm)
Default fused vector wait/reduce. Abort unless a backend overrides it.
Definition gs_comm.f90:352
integer, parameter, public gs_comm_nvshmem
Definition gs_comm.f90:43
integer, parameter, public gs_comm_openshmem
Definition gs_comm.f90:43
integer, parameter, public gs_comm_utofu
Definition gs_comm.f90:43
subroutine gs_init_vec(this)
Default deferred allocation of the fused vector buffers. Reached only on a backend that advertises ve...
Definition gs_comm.f90:325
subroutine free_dofs(this)
Definition gs_comm.f90:195
integer, parameter, public gs_comm_nccl
Definition gs_comm.f90:43
subroutine free_order(this)
Definition gs_comm.f90:241
integer, parameter, public gs_comm_caf
Definition gs_comm.f90:43
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Implements a dynamic stack ADT.
Definition stack.f90:49
Utilities.
Definition utils.f90:35
Gather-scatter communication method.
Definition gs_comm.f90:53
Integer based stack.
Definition stack.f90:77
#define max(a, b)
Definition tensor.cu:40