Octopus
mpi.F90
Go to the documentation of this file.
1!! Copyright (C) 2005-2006 Heiko Appel, Florian Lorenzen
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
21module mpi_oct_m
22#ifdef HAVE_MPI
23 use mpi_f08
24#else
26#endif
27 use blacs_oct_m
28 use loct_oct_m
30 use iso_c_binding
31 use, intrinsic :: iso_fortran_env
32#ifdef HAVE_OPENMP
33 use omp_lib
34#endif
35
36
37 implicit none
38
39 ! I do not make this module private on purpose, so that the symbols defined either in
40 ! module mpi, or in mpif.h are exported
41
43 type(MPI_Comm), parameter, public :: MPI_COMM_UNDEFINED = mpi_comm(-1)
44
46 type mpi_grp_t
47 ! Components are public by default
48 type(MPI_Comm) :: comm = mpi_comm_undefined
49 integer :: size = 0
50 integer :: rank = 0
51 contains
52 ! Wrapper functions for common MPI calls
53 ! We do not check the error code in any of those wrappers because the behavior of
54 ! an application is undefined after an MPI error according to the standard. The
55 ! default is to let the application crash in such a case with an error message
56 ! from the MPI runtime.
57 procedure :: barrier => mpi_grp_barrier
58 procedure :: dmpi_grp_scatterv, zmpi_grp_scatterv, impi_grp_scatterv, lmpi_grp_scatterv
59 generic :: scatterv => dmpi_grp_scatterv, zmpi_grp_scatterv, impi_grp_scatterv, lmpi_grp_scatterv
60 procedure :: dmpi_grp_scatterv_i8, zmpi_grp_scatterv_i8, impi_grp_scatterv_i8, lmpi_grp_scatterv_i8
61 generic :: scatterv => dmpi_grp_scatterv_i8, zmpi_grp_scatterv_i8, impi_grp_scatterv_i8, lmpi_grp_scatterv_i8
62 procedure :: dmpi_grp_gatherv, zmpi_grp_gatherv, impi_grp_gatherv, lmpi_grp_gatherv
63 generic :: gatherv => dmpi_grp_gatherv, zmpi_grp_gatherv, impi_grp_gatherv, lmpi_grp_gatherv
64 procedure :: dmpi_grp_gather_0, zmpi_grp_gather_0, impi_grp_gather_0, lmpi_grp_gather_0
65 generic :: gather => dmpi_grp_gather_0, zmpi_grp_gather_0, impi_grp_gather_0, lmpi_grp_gather_0
66 procedure :: dmpi_grp_gatherv_i8, zmpi_grp_gatherv_i8, impi_grp_gatherv_i8, lmpi_grp_gatherv_i8
67 generic :: gatherv => dmpi_grp_gatherv_i8, zmpi_grp_gatherv_i8, impi_grp_gatherv_i8, lmpi_grp_gatherv_i8
68 procedure :: dmpi_grp_alltoallv, zmpi_grp_alltoallv, impi_grp_alltoallv, lmpi_grp_alltoallv
69 generic :: alltoallv => dmpi_grp_alltoallv, zmpi_grp_alltoallv, impi_grp_alltoallv, lmpi_grp_alltoallv
70 procedure :: dmpi_grp_alltoallv_2, zmpi_grp_alltoallv_2, impi_grp_alltoallv_2, lmpi_grp_alltoallv_2
71 generic :: alltoallv => dmpi_grp_alltoallv_2, zmpi_grp_alltoallv_2, impi_grp_alltoallv_2, lmpi_grp_alltoallv_2
72 procedure :: dmpi_grp_alltoallv_3, zmpi_grp_alltoallv_3, impi_grp_alltoallv_3, lmpi_grp_alltoallv_3
73 generic :: alltoallv => dmpi_grp_alltoallv_3, zmpi_grp_alltoallv_3, impi_grp_alltoallv_3, lmpi_grp_alltoallv_3
74 procedure :: dmpi_grp_alltoallv_i8, zmpi_grp_alltoallv_i8, impi_grp_alltoallv_i8, lmpi_grp_alltoallv_i8
75 generic :: alltoallv => dmpi_grp_alltoallv_i8, zmpi_grp_alltoallv_i8, impi_grp_alltoallv_i8, lmpi_grp_alltoallv_i8
76 procedure :: dmpi_grp_alltoall, zmpi_grp_alltoall, impi_grp_alltoall, lmpi_grp_alltoall
77 generic :: alltoall => dmpi_grp_alltoall, zmpi_grp_alltoall, impi_grp_alltoall, lmpi_grp_alltoall
78 procedure :: dmpi_grp_allgatherv, zmpi_grp_allgatherv, impi_grp_allgatherv, lmpi_grp_allgatherv
79 generic :: allgatherv => dmpi_grp_allgatherv, zmpi_grp_allgatherv, impi_grp_allgatherv, lmpi_grp_allgatherv
80 procedure :: dmpi_grp_allgatherv_2, zmpi_grp_allgatherv_2, impi_grp_allgatherv_2, lmpi_grp_allgatherv_2
81 generic :: allgatherv => dmpi_grp_allgatherv_2, zmpi_grp_allgatherv_2, impi_grp_allgatherv_2, lmpi_grp_allgatherv_2
82 procedure :: dmpi_grp_allgatherv_3, zmpi_grp_allgatherv_3, impi_grp_allgatherv_3, lmpi_grp_allgatherv_3
83 generic :: allgatherv => dmpi_grp_allgatherv_3, zmpi_grp_allgatherv_3, impi_grp_allgatherv_3, lmpi_grp_allgatherv_3
84 procedure :: dmpi_grp_allgatherv_3_1, zmpi_grp_allgatherv_3_1, impi_grp_allgatherv_3_1, lmpi_grp_allgatherv_3_1
85 generic :: allgatherv => dmpi_grp_allgatherv_3_1, zmpi_grp_allgatherv_3_1, impi_grp_allgatherv_3_1, lmpi_grp_allgatherv_3_1
86 procedure :: dmpi_grp_allgatherv_i8, zmpi_grp_allgatherv_i8, impi_grp_allgatherv_i8, lmpi_grp_allgatherv_i8
87 generic :: allgatherv => dmpi_grp_allgatherv_i8, zmpi_grp_allgatherv_i8, impi_grp_allgatherv_i8, lmpi_grp_allgatherv_i8
88 procedure :: dmpi_grp_bcast, zmpi_grp_bcast, impi_grp_bcast, lmpi_grp_bcast
89 generic :: bcast => dmpi_grp_bcast, zmpi_grp_bcast, impi_grp_bcast, lmpi_grp_bcast
90 procedure :: dmpi_grp_bcast_0, zmpi_grp_bcast_0, impi_grp_bcast_0, lmpi_grp_bcast_0
91 generic :: bcast => dmpi_grp_bcast_0, zmpi_grp_bcast_0, impi_grp_bcast_0, lmpi_grp_bcast_0
92 procedure :: dmpi_grp_bcast_2, zmpi_grp_bcast_2, impi_grp_bcast_2, lmpi_grp_bcast_2
93 generic :: bcast => dmpi_grp_bcast_2, zmpi_grp_bcast_2, impi_grp_bcast_2, lmpi_grp_bcast_2
94 procedure :: dmpi_grp_bcast_3, zmpi_grp_bcast_3, impi_grp_bcast_3, lmpi_grp_bcast_3
95 generic :: bcast => dmpi_grp_bcast_3, zmpi_grp_bcast_3, impi_grp_bcast_3, lmpi_grp_bcast_3
96 procedure :: chmpi_grp_bcast_0, lompi_grp_bcast_0
97 generic :: bcast => chmpi_grp_bcast_0, lompi_grp_bcast_0
98 procedure :: dmpi_grp_bcast_0_l, zmpi_grp_bcast_0_l, impi_grp_bcast_0_l, lmpi_grp_bcast_0_l
99 generic :: bcast => dmpi_grp_bcast_0_l, zmpi_grp_bcast_0_l, impi_grp_bcast_0_l, lmpi_grp_bcast_0_l
100 procedure :: dmpi_grp_allreduce, zmpi_grp_allreduce, impi_grp_allreduce, lmpi_grp_allreduce
101 generic :: allreduce => dmpi_grp_allreduce, zmpi_grp_allreduce, impi_grp_allreduce, lmpi_grp_allreduce
102 procedure :: dmpi_grp_allreduce_2, zmpi_grp_allreduce_2, impi_grp_allreduce_2, lmpi_grp_allreduce_2
103 generic :: allreduce => dmpi_grp_allreduce_2, zmpi_grp_allreduce_2, impi_grp_allreduce_2, lmpi_grp_allreduce_2
104 procedure :: dmpi_grp_allreduce_3, zmpi_grp_allreduce_3, impi_grp_allreduce_3, lmpi_grp_allreduce_3
105 generic :: allreduce => dmpi_grp_allreduce_3, zmpi_grp_allreduce_3, impi_grp_allreduce_3, lmpi_grp_allreduce_3
106 procedure :: dmpi_grp_allreduce_0, zmpi_grp_allreduce_0, impi_grp_allreduce_0, lmpi_grp_allreduce_0
107 generic :: allreduce => dmpi_grp_allreduce_0, zmpi_grp_allreduce_0, impi_grp_allreduce_0, lmpi_grp_allreduce_0
108 procedure :: lompi_grp_allreduce_0
109 generic :: allreduce => lompi_grp_allreduce_0
110 procedure :: dmpi_grp_allreduce_inplace_0, zmpi_grp_allreduce_inplace_0
111 procedure :: impi_grp_allreduce_inplace_0, lmpi_grp_allreduce_inplace_0
112 procedure :: lompi_grp_allreduce_inplace_0
113 generic :: allreduce_inplace => dmpi_grp_allreduce_inplace_0, zmpi_grp_allreduce_inplace_0
114 generic :: allreduce_inplace => impi_grp_allreduce_inplace_0, lmpi_grp_allreduce_inplace_0
115 generic :: allreduce_inplace => lompi_grp_allreduce_inplace_0
116 procedure :: dmpi_grp_allreduce_inplace_1, zmpi_grp_allreduce_inplace_1, &
117 impi_grp_allreduce_inplace_1, lmpi_grp_allreduce_inplace_1
118 generic :: allreduce_inplace => dmpi_grp_allreduce_inplace_1, zmpi_grp_allreduce_inplace_1, &
119 impi_grp_allreduce_inplace_1, lmpi_grp_allreduce_inplace_1
120 procedure :: dmpi_grp_allgather, zmpi_grp_allgather, impi_grp_allgather, lmpi_grp_allgather
121 generic :: allgather => dmpi_grp_allgather, zmpi_grp_allgather, impi_grp_allgather, lmpi_grp_allgather
122 procedure :: dmpi_grp_allgather_0, zmpi_grp_allgather_0, impi_grp_allgather_0, lmpi_grp_allgather_0
123 generic :: allgather => dmpi_grp_allgather_0, zmpi_grp_allgather_0, impi_grp_allgather_0, lmpi_grp_allgather_0
124 procedure :: dmpi_grp_recv, zmpi_grp_recv, impi_grp_recv, lmpi_grp_recv
125 generic :: recv => dmpi_grp_recv, zmpi_grp_recv, impi_grp_recv, lmpi_grp_recv
126 procedure :: dmpi_grp_recv_0, zmpi_grp_recv_0, impi_grp_recv_0, lmpi_grp_recv_0
127 generic :: recv => dmpi_grp_recv_0, zmpi_grp_recv_0, impi_grp_recv_0, lmpi_grp_recv_0
128 procedure :: dmpi_grp_recv_2, zmpi_grp_recv_2, impi_grp_recv_2, lmpi_grp_recv_2
129 generic :: recv => dmpi_grp_recv_2, zmpi_grp_recv_2, impi_grp_recv_2, lmpi_grp_recv_2
130 procedure :: dmpi_grp_recv_3, zmpi_grp_recv_3, impi_grp_recv_3, lmpi_grp_recv_3
131 generic :: recv => dmpi_grp_recv_3, zmpi_grp_recv_3, impi_grp_recv_3, lmpi_grp_recv_3
132 procedure :: lompi_grp_recv_0
133 generic :: recv => lompi_grp_recv_0
134 procedure :: dmpi_grp_send, zmpi_grp_send, impi_grp_send, lmpi_grp_send
135 generic :: send => dmpi_grp_send, zmpi_grp_send, impi_grp_send, lmpi_grp_send
140 procedure :: dmpi_grp_send_3, zmpi_grp_send_3, impi_grp_send_3, lmpi_grp_send_3
141 generic :: send => dmpi_grp_send_3, zmpi_grp_send_3, impi_grp_send_3, lmpi_grp_send_3
142 procedure :: lompi_grp_send_0
143 generic :: send => lompi_grp_send_0
165 generic :: wait => mpi_grp_wait, mpi_grp_waitall
166 procedure :: abort => mpi_grp_abort
167 end type mpi_grp_t
169 type(mpi_grp_t), public :: mpi_world
172 integer, public :: mpi_err
174 private :: not_in_openmp
177contains
184 subroutine mpi_init_comm(comm)
185 type(mpi_comm), intent(out) :: comm
186#if defined(HAVE_MPI)
187#if defined(HAVE_OPENMP)
188 integer :: provided
190 call mpi_init_thread(mpi_thread_funneled, provided, mpi_err)
191#else
192 call mpi_init(mpi_err)
193#endif
194 comm = mpi_comm_world
195#else
196 comm = mpi_comm_undefined
197#endif
199 end subroutine mpi_init_comm
203 subroutine blacs_init()
204#if defined(HAVE_MPI)
205#ifdef HAVE_SCALAPACK
206 integer :: iam, nprocs
207 integer :: blacs_default_system_context
209 ! Determine my process number and the number of processes in machine
210 call blacs_pinfo(iam, nprocs)
212 ! If machine needs additional set up, do it now
213 if (nprocs < 1) then
214 call blacs_setup(iam, mpi_world%size)
215 end if
217 ! blacs_gridinit() or blacs_gridmap() must be called, else
218 ! blacs_exit() triggers an error with openmpi:
219 ! *** An error occurred in MPI_Type_free
220 ! *** MPI_ERR_TYPE: invalid datatype
221 call blacs_get(0, 0, blacs_default_system_context)
222 call blacs_gridinit(blacs_default_system_context, 'R', mpi_world%size, 1)
223 call blacs_gridexit(blacs_default_system_context)
224#endif
225#endif
226 end subroutine blacs_init
230 subroutine mpi_mod_end()
232#ifdef HAVE_SCALAPACK
233 if (mpi_world%comm /= mpi_comm_undefined) call blacs_exit(1)
234#endif
236#if defined(HAVE_MPI)
237 ! end MPI, if we started it
238 if (mpi_world%comm /= mpi_comm_undefined) call mpi_finalize(mpi_err)
239#endif
241 end subroutine mpi_mod_end
248 subroutine mpi_grp_init(grp, comm)
249 type(mpi_grp_t), intent(out) :: grp
250 type(mpi_comm), intent(in) :: comm
252 grp%comm = comm
253#if defined(HAVE_MPI)
254 if (grp%comm == mpi_comm_null) grp%comm = mpi_comm_undefined
255#endif
257 if (grp%comm == mpi_comm_undefined) then
258 grp%rank = 0
259 grp%size = 1
260#if defined(HAVE_MPI)
261 else
262 call mpi_comm_rank(grp%comm, grp%rank, mpi_err)
264
265 call mpi_comm_size(grp%comm, grp%size, mpi_err)
267#endif
268 end if
269
270 end subroutine mpi_grp_init
271
272
273 logical &
274#ifndef have_openmp
275 pure &
276#endif
277 function not_in_openmp()
278
279#ifdef HAVE_OPENMP
280 not_in_openmp = .not. omp_in_parallel()
281#else
283#endif
284
285 end function not_in_openmp
286
287
288 !-----------------------------------------------------------
289 subroutine mpi_error_check(error)
290 integer, intent(in) :: error
291
292#if defined(HAVE_MPI)
293 character(len=MPI_MAX_ERROR_STRING) :: message
294 integer :: length, temp
295
296 if (error /= mpi_success ) then
297 call mpi_error_string( error, message, length, temp)
298 print * , message(1:length)
299 call mpi_abort(mpi_comm_world, 1 , temp)
300 end if
301#endif
302 end subroutine mpi_error_check
303
304 ! ---------------------------------------------------------
305 subroutine mpi_grp_copy(mpi_grp_out, mpi_grp_in)
306 type(mpi_grp_t), intent(out) :: mpi_grp_out
307 type(mpi_grp_t), intent(in) :: mpi_grp_in
308
309 mpi_grp_out%comm = mpi_grp_in%comm
310 mpi_grp_out%size = mpi_grp_in%size
311 mpi_grp_out%rank = mpi_grp_in%rank
312 end subroutine mpi_grp_copy
313
314 ! ---------------------------------------------------------
315 subroutine mpi_grp_duplicate(mpi_grp_out, mpi_grp_in)
316 type(mpi_grp_t), intent(out) :: mpi_grp_out
317 type(mpi_grp_t), intent(in) :: mpi_grp_in
318
319#if defined(HAVE_MPI)
320 call mpi_comm_dup(mpi_grp_in%comm, mpi_grp_out%comm, mpi_err)
322 call mpi_comm_rank(mpi_grp_out%comm, mpi_grp_out%rank, mpi_err)
324 call mpi_comm_size(mpi_grp_out%comm, mpi_grp_out%size, mpi_err)
326#else
327 call mpi_grp_copy(mpi_grp_out, mpi_grp_in)
328#endif
329 end subroutine mpi_grp_duplicate
330
331 ! ---------------------------------------------------------
332 logical function mpi_grp_is_root(grp)
333 type(mpi_grp_t), intent(in) :: grp
334
335 mpi_grp_is_root = (grp%rank == 0)
336 end function mpi_grp_is_root
337
338 ! ---------------------------------------------------------
339 subroutine mpi_grp_barrier(mpi_grp)
340 class(mpi_grp_t), intent(in) :: mpi_grp
342 if (mpi_grp%comm == mpi_comm_undefined) return
343#if defined(HAVE_MPI)
344 assert(not_in_openmp())
345
346 call mpi_debug_in(mpi_grp%comm, c_mpi_barrier)
347 call mpi_barrier(mpi_grp%comm, mpi_err)
349 call mpi_debug_out(mpi_grp%comm, c_mpi_barrier)
350#endif
351 end subroutine mpi_grp_barrier
352
353 ! ---------------------------------------------------------
354 subroutine chmpi_grp_bcast_0(mpi_grp, buf, cnt, sendtype, root)
355 class(mpi_grp_t), intent(in) :: mpi_grp
356 character(len=*), intent(inout) :: buf
357 integer, intent(in) :: cnt
358 type(mpi_datatype), intent(in) :: sendtype
359 integer, intent(in) :: root
360
361#if defined(HAVE_MPI)
362 assert(not_in_openmp())
363
364 call mpi_debug_in(mpi_grp%comm, c_mpi_bcast)
365 if (mpi_grp%comm /= mpi_comm_undefined) then
366 call mpi_bcast(buf, cnt, sendtype, root, mpi_grp%comm, mpi_err)
368 end if
369 call mpi_debug_out(mpi_grp%comm, c_mpi_bcast)
370#endif
371 end subroutine chmpi_grp_bcast_0
372
373 ! ---------------------------------------------------------
374 subroutine lompi_grp_bcast_0(mpi_grp, buf, cnt, sendtype, root)
375 class(mpi_grp_t), intent(in) :: mpi_grp
376 logical, intent(inout) :: buf
377 integer, intent(in) :: cnt
378 type(mpi_datatype), intent(in) :: sendtype
379 integer, intent(in) :: root
380
381#if defined(HAVE_MPI)
383
384 call mpi_debug_in(mpi_grp%comm, c_mpi_bcast)
385 if (mpi_grp%comm /= mpi_comm_undefined) then
386 call mpi_bcast(buf, cnt, sendtype, root, mpi_grp%comm, mpi_err)
388 end if
389 call mpi_debug_out(mpi_grp%comm, c_mpi_bcast)
390#endif
391 end subroutine lompi_grp_bcast_0
392
393 ! ---------------------------------------------------------
394 ! copy routine for serial case
395 subroutine lompi_grp_copy_0(sendbuf, recvbuf, count)
396 use iso_c_binding
397 logical, target, intent(in) :: sendbuf
398 logical, target, intent(out) :: recvbuf
399 integer, intent(in) :: count
400 integer :: ii
401 logical, pointer :: send(:), recv(:)
402
403 call c_f_pointer(c_loc(sendbuf), send, [count])
404 call c_f_pointer(c_loc(recvbuf), recv, [count])
405 do ii = 1, count
406 recv(ii) = send(ii)
407 end do
408 end subroutine lompi_grp_copy_0
409
410 ! ---------------------------------------------------------
411 subroutine lompi_grp_allreduce_0(mpi_grp, sendbuf, recvbuf, count, datatype, op)
412 class(mpi_grp_t), intent(in) :: mpi_grp
413 logical, intent(in) :: sendbuf
414 logical, intent(out) :: recvbuf
415 integer, intent(in) :: count
416 type(mpi_datatype), intent(in):: datatype
417 type(mpi_op), intent(in) :: op
418
419#if defined(HAVE_MPI)
420 assert(not_in_openmp())
421
422 call mpi_debug_in(mpi_grp%comm, c_mpi_allreduce)
423 if (mpi_grp%comm /= mpi_comm_undefined) then
424 call mpi_allreduce(sendbuf, recvbuf, count, datatype, op, &
425 mpi_grp%comm, mpi_err)
427 else
428 call lompi_grp_copy_0(sendbuf, recvbuf, count)
429 end if
430 call mpi_debug_out(mpi_grp%comm, c_mpi_allreduce)
431#else
432 call lompi_grp_copy_0(sendbuf, recvbuf, count)
433#endif
434 end subroutine lompi_grp_allreduce_0
435
436 ! ---------------------------------------------------------
437 subroutine lompi_grp_allreduce_inplace_0(mpi_grp, recvbuf, count, datatype, op)
438 class(mpi_grp_t), intent(in) :: mpi_grp
439 logical, intent(inout) :: recvbuf
440 integer, intent(in) :: count
441 type(mpi_datatype), intent(in) :: datatype
442 type(mpi_op), intent(in) :: op
443
444#if defined(HAVE_MPI)
445 assert(not_in_openmp())
446
447 call mpi_debug_in(mpi_grp%comm, c_mpi_allreduce)
448 if (mpi_grp%comm /= mpi_comm_undefined) then
449 call mpi_allreduce(mpi_in_place, recvbuf, count, datatype, op, &
450 mpi_grp%comm, mpi_err)
452 end if
453 call mpi_debug_out(mpi_grp%comm, c_mpi_allreduce)
454#endif
455 end subroutine lompi_grp_allreduce_inplace_0
456
457 ! ---------------------------------------------------------
458 subroutine lompi_grp_recv_0(mpi_grp, recvbuf, recvcount, recvtype, source, tag)
459 class(mpi_grp_t), intent(in) :: mpi_grp
460 logical, intent(out) :: recvbuf
461 integer, intent(in) :: recvcount
462 type(mpi_datatype),intent(in) :: recvtype
463 integer, intent(in) :: source
464 integer, optional, intent(in) :: tag
465
466 integer :: tag_
468 tag_ = 0
469 if (present(tag)) tag_ = tag
470 if (mpi_grp%comm == mpi_comm_undefined) return
471#if defined(HAVE_MPI)
472 assert(not_in_openmp())
473
474 call mpi_recv(recvbuf, recvcount, recvtype, source, tag_, mpi_grp%comm, mpi_status_ignore, mpi_err)
476#endif
477 end subroutine lompi_grp_recv_0
478
479 ! ---------------------------------------------------------
480 subroutine lompi_grp_send_0(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
481 class(mpi_grp_t), intent(in) :: mpi_grp
482 logical, intent(out) :: sendbuf
483 integer, intent(in) :: sendcount
484 type(mpi_datatype),intent(in) :: sendtype
485 integer, intent(in) :: dest
486 integer, optional, intent(in) :: tag
487
488 integer :: tag_
489
490 tag_ = 0
491 if (present(tag)) tag_ = tag
492 if (mpi_grp%comm == mpi_comm_undefined) return
493#if defined(HAVE_MPI)
494 assert(not_in_openmp())
495
496 call mpi_send(sendbuf, sendcount, sendtype, dest, tag_, mpi_grp%comm, mpi_err)
498#endif
499 end subroutine lompi_grp_send_0
500
501 ! ---------------------------------------------------------
502 subroutine mpi_grp_wait(mpi_grp, request)
503 class(mpi_grp_t), intent(in) :: mpi_grp
504 type(mpi_request), intent(inout) :: request
505
506 if (mpi_grp%comm == mpi_comm_undefined) return
507#if defined(HAVE_MPI)
508 assert(not_in_openmp())
509
510 call mpi_wait(request, mpi_status_ignore, mpi_err)
512#endif
513 end subroutine mpi_grp_wait
514
515 ! ---------------------------------------------------------
516 subroutine mpi_grp_waitall(mpi_grp, count, requests)
517 class(mpi_grp_t), intent(in) :: mpi_grp
518 integer, intent(in) :: count
519 type(mpi_request), intent(inout) :: requests(:)
520
521 if (mpi_grp%comm == mpi_comm_undefined) return
522#if defined(HAVE_MPI)
523 assert(not_in_openmp())
524
525 call mpi_waitall(count, requests, mpi_statuses_ignore, mpi_err)
527#endif
528 end subroutine mpi_grp_waitall
529
530 ! ---------------------------------------------------------
531 subroutine mpi_grp_abort(mpi_grp)
532 class(mpi_grp_t), intent(in) :: mpi_grp
533
534 if (mpi_grp%comm /= mpi_comm_undefined) then
535#if defined(HAVE_MPI)
536 assert(not_in_openmp())
537
538 ! Abort with an arbitrary error code
539 call mpi_abort(mpi_grp%comm, 999, mpi_err)
541#endif
542 end if
543
544 end subroutine mpi_grp_abort
545
546 ! ---------------------------------------------------------
548 real(real64) function mpi_get_Wtime() result(now)
549#if defined(HAVE_MPI)
550 now = mpi_wtime()
551#else
552 now = loct_clock()
553#endif
554 end function mpi_get_wtime
555
556#include "undef.F90"
557#include "real.F90"
558#include "mpi_inc.F90"
559
560#include "undef.F90"
561#include "complex.F90"
562#include "mpi_inc.F90"
563
564#include "undef.F90"
565#include "integer.F90"
566#include "mpi_inc.F90"
567
568#include "undef.F90"
569#include "integer8.F90"
570#include "mpi_inc.F90"
571
572end module mpi_oct_m
574
575!! Local Variables:
576!! mode: f90
577!! coding: utf-8
578!! End:
This module contains interfaces for BLACS routines Interfaces are from http:
Definition: blacs.F90:27
integer, parameter, public c_mpi_allreduce
Definition: mpi_debug.F90:137
subroutine, public mpi_debug_in(comm, index)
Definition: mpi_debug.F90:241
integer, parameter, public c_mpi_bcast
Definition: mpi_debug.F90:137
integer, parameter, public c_mpi_barrier
Definition: mpi_debug.F90:137
subroutine, public mpi_debug_out(comm, index)
Definition: mpi_debug.F90:265
subroutine mpi_grp_abort(mpi_grp)
Definition: mpi.F90:625
subroutine impi_grp_irecv(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:4515
subroutine zmpi_grp_isend_0(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:3173
subroutine mpi_grp_duplicate(mpi_grp_out, mpi_grp_in)
Definition: mpi.F90:409
subroutine impi_grp_irecv_0(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:4493
subroutine lmpi_grp_isend(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:6065
subroutine lompi_grp_copy_0(sendbuf, recvbuf, count)
Definition: mpi.F90:489
subroutine zmpi_grp_irecv_0_int64(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:3035
subroutine blacs_init()
Initialize BLACS to enable use of SCALAPACK.
Definition: mpi.F90:297
real(real64) function, public mpi_get_wtime()
. Returns an elapsed time on the calling processor.
Definition: mpi.F90:642
subroutine dmpi_grp_irecv_3(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:1693
subroutine zmpi_grp_isend(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:3196
subroutine dmpi_grp_isend_3(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:1808
subroutine zmpi_grp_irecv_3(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:3127
subroutine lompi_grp_bcast_0(mpi_grp, buf, cnt, sendtype, root)
Definition: mpi.F90:468
logical function mpi_grp_is_root(grp)
Definition: mpi.F90:426
subroutine impi_grp_irecv_2(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:4538
subroutine zmpi_grp_irecv(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:3081
subroutine mpi_grp_copy(mpi_grp_out, mpi_grp_in)
Definition: mpi.F90:399
subroutine zmpi_grp_isend_3(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:3242
subroutine impi_grp_isend_2(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:4653
subroutine impi_grp_isend(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:4630
subroutine impi_grp_send_0(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
Definition: mpi.F90:4381
subroutine lompi_grp_allreduce_inplace_0(mpi_grp, recvbuf, count, datatype, op)
Definition: mpi.F90:531
subroutine impi_grp_isend_0_int64(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:4583
subroutine zmpi_grp_irecv_2(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:3104
subroutine dmpi_grp_isend_0(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:1739
subroutine zmpi_grp_send_0(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
Definition: mpi.F90:2947
subroutine dmpi_grp_irecv(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:1647
subroutine lmpi_grp_irecv_0_int64(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:5904
subroutine dmpi_grp_send_2(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
Definition: mpi.F90:1557
subroutine impi_grp_irecv_0_int64(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:4469
subroutine lompi_grp_recv_0(mpi_grp, recvbuf, recvcount, recvtype, source, tag)
Definition: mpi.F90:552
subroutine dmpi_grp_send_0(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
Definition: mpi.F90:1513
subroutine mpi_grp_wait(mpi_grp, request)
Definition: mpi.F90:596
subroutine lmpi_grp_irecv(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:5950
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:262
subroutine impi_grp_isend_0(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:4607
subroutine mpi_mod_end()
Finalize MPI, and optionally BLACS.
Definition: mpi.F90:324
logical pure function, private not_in_openmp()
Definition: mpi.F90:371
subroutine lmpi_grp_isend_2(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:6088
subroutine mpi_grp_init(grp, comm)
Initialize MPI group instance.
Definition: mpi.F90:342
subroutine zmpi_grp_send_2(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
Definition: mpi.F90:2991
subroutine dmpi_grp_irecv_0(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:1625
subroutine impi_grp_irecv_3(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:4561
subroutine impi_grp_isend_3(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:4676
subroutine dmpi_grp_isend(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:1762
subroutine dmpi_grp_isend_2(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:1785
subroutine zmpi_grp_isend_0_int64(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:3149
subroutine lmpi_grp_irecv_3(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:5996
subroutine mpi_grp_barrier(mpi_grp)
Definition: mpi.F90:433
subroutine zmpi_grp_irecv_0(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:3059
subroutine lmpi_grp_send_2(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
Definition: mpi.F90:5860
subroutine mpi_init_comm(comm)
Wrapper for MPI_COMM_WORLD initialisation.
Definition: mpi.F90:278
subroutine impi_grp_send_2(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
Definition: mpi.F90:4425
subroutine dmpi_grp_irecv_2(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:1670
integer, public mpi_err
used to store return values of mpi calls
Definition: mpi.F90:265
subroutine lmpi_grp_isend_0_int64(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:6018
subroutine dmpi_grp_irecv_0_int64(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:1601
subroutine lmpi_grp_send_0(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
Definition: mpi.F90:5816
subroutine lmpi_grp_isend_0(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:6042
subroutine dmpi_grp_isend_0_int64(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:1715
subroutine zmpi_grp_isend_2(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:3219
subroutine mpi_grp_waitall(mpi_grp, count, requests)
Definition: mpi.F90:610
subroutine lompi_grp_allreduce_0(mpi_grp, sendbuf, recvbuf, count, datatype, op)
Definition: mpi.F90:505
subroutine lmpi_grp_irecv_0(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:5928
subroutine lompi_grp_send_0(mpi_grp, sendbuf, sendcount, sendtype, dest, tag)
Definition: mpi.F90:574
subroutine mpi_error_check(error)
Definition: mpi.F90:383
subroutine lmpi_grp_isend_3(mpi_grp, sendbuf, sendcount, sendtype, source, request, tag)
Definition: mpi.F90:6111
subroutine chmpi_grp_bcast_0(mpi_grp, buf, cnt, sendtype, root)
Definition: mpi.F90:448
subroutine lmpi_grp_irecv_2(mpi_grp, recvbuf, recvcount, recvtype, source, request, tag)
Definition: mpi.F90:5973
This is defined even when running serial.
Definition: mpi.F90:139
int true(void)