Neko  0.8.99
A portable framework for high-order spectral element flow simulations
comm.F90
Go to the documentation of this file.
1 module comm
2  use mpi_f08
3  use utils, only : neko_error
4  use neko_config
5  !$ use omp_lib
6  implicit none
7 
8  interface
9  subroutine neko_comm_wrapper_init(fcomm) &
10  bind(c, name='neko_comm_wrapper_init')
11  integer, value :: fcomm
12  end subroutine neko_comm_wrapper_init
13  end interface
14 
16  type(mpi_comm) :: neko_comm
17 
19 #ifdef HAVE_MPI_PARAM_DTYPE
20  type(mpi_datatype), parameter :: mpi_real_precision = mpi_double_precision
21 #else
22  type(mpi_datatype) :: mpi_real_precision
23 #endif
24 
26  integer :: pe_rank
27 
29  integer :: pe_size
30 
32  logical :: nio
33 
34 contains
35  subroutine comm_init
36  integer :: ierr
37  logical :: initialized
38  integer :: provided, nthrds
39 
40  pe_rank = -1
41  pe_size = 0
42  nio = .false.
43 
44  call mpi_initialized(initialized, ierr)
45 
46  nthrds = 1
47  !$omp parallel
48  !$omp master
49  !$ nthrds = omp_get_num_threads()
50  !$omp end master
51  !$omp end parallel
52 
53  if (.not.initialized) then
54  if (nthrds .gt. 1) then
55  call mpi_init_thread(mpi_thread_multiple, provided, ierr)
56  if (provided .ne. mpi_thread_multiple) then
57  ! MPI_THREAD_MULTIPLE is required for mt. device backends
58  if (neko_bcknd_device .eq. 1) then
59  call neko_error('Invalid thread support provided by MPI')
60  else
61  call mpi_init_thread(mpi_thread_serialized, provided, ierr)
62  if (provided .ne. mpi_thread_serialized) then
63  call neko_error('Invalid thread support provided by MPI')
64  end if
65  end if
66  end if
67  else
68  call mpi_init(ierr)
69  end if
70  end if
71 
72 #ifndef HAVE_MPI_PARAM_DTYPE
73  mpi_real_precision = mpi_double_precision
74 #endif
75 
76 
77 #ifdef HAVE_ADIOS2
78  ! We split the communicator it to work asynchronously (MPMD)
79  call mpi_comm_rank(mpi_comm_world, pe_rank, ierr)
80  call mpi_comm_split(mpi_comm_world, 0, pe_rank, neko_comm, ierr)
81 #else
82  ! Original version duplicates the communicator:
83  call mpi_comm_dup(mpi_comm_world, neko_comm, ierr)
84 #endif
85 
86  call mpi_comm_rank(neko_comm, pe_rank, ierr)
87  call mpi_comm_size(neko_comm, pe_size, ierr)
88 
89  ! Setup C/C++ wrapper
90  call neko_comm_wrapper_init(neko_comm%mpi_val)
91 
92  end subroutine comm_init
93 
94  subroutine comm_free
95  integer :: ierr
96 
97  call mpi_barrier(neko_comm, ierr)
98  call mpi_comm_free(neko_comm, ierr)
99  call mpi_finalize(ierr)
100 
101  end subroutine comm_free
102 
103 end module comm
Definition: comm.F90:1
integer pe_rank
MPI rank.
Definition: comm.F90:26
logical nio
I/O node.
Definition: comm.F90:32
type(mpi_comm) neko_comm
MPI communicator.
Definition: comm.F90:16
subroutine comm_free
Definition: comm.F90:95
type(mpi_datatype) mpi_real_precision
MPI type for working precision of REAL types.
Definition: comm.F90:22
integer pe_size
MPI size of communicator.
Definition: comm.F90:29
subroutine comm_init
Definition: comm.F90:36
Build configurations.
Definition: neko_config.f90:34
integer, parameter neko_bcknd_device
Definition: neko_config.f90:44
Utilities.
Definition: utils.f90:35