Neko  0.9.0
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  type(mpi_datatype), parameter :: mpi_extra_precision = mpi_double_precision
22 #else
23  type(mpi_datatype) :: mpi_real_precision
24  type(mpi_datatype) :: mpi_extra_precision
25 #endif
26 
28  integer :: pe_rank
29 
31  integer :: pe_size
32 
34  logical :: nio
35 
36 contains
37  subroutine comm_init
38  integer :: ierr
39  logical :: initialized
40  integer :: provided, nthrds
41 
42  pe_rank = -1
43  pe_size = 0
44  nio = .false.
45 
46  call mpi_initialized(initialized, ierr)
47 
48  nthrds = 1
49  !$omp parallel
50  !$omp master
51  !$ nthrds = omp_get_num_threads()
52  !$omp end master
53  !$omp end parallel
54 
55  if (.not.initialized) then
56  if (nthrds .gt. 1) then
57  call mpi_init_thread(mpi_thread_multiple, provided, ierr)
58  if (provided .ne. mpi_thread_multiple) then
59  ! MPI_THREAD_MULTIPLE is required for mt. device backends
60  if (neko_bcknd_device .eq. 1) then
61  call neko_error('Invalid thread support provided by MPI')
62  else
63  call mpi_init_thread(mpi_thread_serialized, provided, ierr)
64  if (provided .ne. mpi_thread_serialized) then
65  call neko_error('Invalid thread support provided by MPI')
66  end if
67  end if
68  end if
69  else
70  call mpi_init(ierr)
71  end if
72  end if
73 
74 #ifndef HAVE_MPI_PARAM_DTYPE
75  mpi_real_precision = mpi_double_precision
76  mpi_extra_precision = mpi_double_precision
77 #endif
78 
79 
80 #ifdef HAVE_ADIOS2
81  ! We split the communicator it to work asynchronously (MPMD)
82  call mpi_comm_rank(mpi_comm_world, pe_rank, ierr)
83  call mpi_comm_split(mpi_comm_world, 0, pe_rank, neko_comm, ierr)
84 #else
85  ! Original version duplicates the communicator:
86  call mpi_comm_dup(mpi_comm_world, neko_comm, ierr)
87 #endif
88 
89  call mpi_comm_rank(neko_comm, pe_rank, ierr)
90  call mpi_comm_size(neko_comm, pe_size, ierr)
91 
92  ! Setup C/C++ wrapper
93  call neko_comm_wrapper_init(neko_comm%mpi_val)
94 
95  end subroutine comm_init
96 
97  subroutine comm_free
98  integer :: ierr
99 
100  call mpi_barrier(neko_comm, ierr)
101  call mpi_comm_free(neko_comm, ierr)
102  call mpi_finalize(ierr)
103 
104  end subroutine comm_free
105 
106 end module comm
Definition: comm.F90:1
integer pe_rank
MPI rank.
Definition: comm.F90:28
logical nio
I/O node.
Definition: comm.F90:34
type(mpi_comm) neko_comm
MPI communicator.
Definition: comm.F90:16
subroutine comm_free
Definition: comm.F90:98
type(mpi_datatype) mpi_real_precision
MPI type for working precision of REAL types.
Definition: comm.F90:23
integer pe_size
MPI size of communicator.
Definition: comm.F90:31
type(mpi_datatype) mpi_extra_precision
Definition: comm.F90:24
subroutine comm_init
Definition: comm.F90:38
Build configurations.
Definition: neko_config.f90:34
integer, parameter neko_bcknd_device
Definition: neko_config.f90:44
Utilities.
Definition: utils.f90:35