MODFLOW 6  version 6.7.0.dev1
USGS Modular Hydrologic Model
MpiUnitCache.f90
Go to the documentation of this file.
2  use kindmodule, only: i4b, lgp
3  use listmodule
6  use mpiworldmodule, only: check_mpi
7  use mpi
8  implicit none
9  private
10 
11  integer(I4B), public, parameter :: no_cached_value = -1
12 
13  type, public :: mpiunitcachetype
14  ! private
15  type(stlvecint), private :: cached_ranks
16  type(stlvecint), private :: cached_messages
17  integer(I4B), private :: nr_stages
18  integer(I4B), private :: nr_msg_types
19  contains
20  procedure :: init => cc_init
21  procedure :: get_cached => cc_get_cached
22  procedure :: cache => cc_cache
23  procedure :: clear => cc_clear
24  procedure :: destroy => cc_destroy
25  ! private
26  procedure, private :: is_rank_cached
27  procedure, private :: add_rank_cache
28  procedure, private :: get_rank_index
29  procedure, private :: get_msg_index
30  end type mpiunitcachetype
31 
32 contains
33 
34  !> @brief Initialize the unit cache.
35  !<
36  subroutine cc_init(this, nr_stages, nr_msg_types)
37  class(mpiunitcachetype) :: this
38  integer(I4B) :: nr_stages !< number of (simulation) stages
39  integer(I4B) :: nr_msg_types !< number of message types to be cached during a stage
40 
41  this%nr_stages = nr_stages
42  this%nr_msg_types = nr_msg_types
43  call this%cached_ranks%init()
44  call this%cached_messages%init()
45 
46  end subroutine cc_init
47 
48  !> @brief Get the cached mpi type for this rank and
49  !< stage. Equal to NO_CACHED_VALUE when not present.
50  function cc_get_cached(this, rank, stage, msg_id) result(mpi_type)
51  class(mpiunitcachetype) :: this
52  integer(I4B) :: rank
53  integer(I4B) :: stage
54  integer(I4B) :: msg_id
55  integer :: mpi_type
56  ! local
57  integer(I4B) :: msg_idx
58 
59  mpi_type = no_cached_value
60  msg_idx = this%get_msg_index(rank, stage, msg_id)
61  if (msg_idx > 0) then
62  mpi_type = this%cached_messages%at(msg_idx)
63  end if
64 
65  end function cc_get_cached
66 
67  !> @brief Cache the mpi datatype for this particular
68  !! rank and stage. The datatype should be committed
69  !< to the type database externally.
70  subroutine cc_cache(this, rank, stage, msg_id, mpi_type)
71  class(mpiunitcachetype) :: this
72  integer(I4B) :: rank
73  integer(I4B) :: stage
74  integer(I4B) :: msg_id
75  integer :: mpi_type
76  ! local
77  integer(I4B) :: msg_idx
78 
79  ! add if rank not present in cache yet
80  if (.not. this%is_rank_cached(rank)) then
81  call this%add_rank_cache(rank)
82  end if
83 
84  ! rank has been added to cache, now set
85  ! mpi datatype for this stage's message:
86  msg_idx = this%get_msg_index(rank, stage, msg_id)
87  call this%cached_messages%set(msg_idx, mpi_type)
88 
89  end subroutine cc_cache
90 
91  function is_rank_cached(this, rank) result(in_cache)
92  class(mpiunitcachetype) :: this
93  integer(I4B) :: rank
94  logical(LGP) :: in_cache
95 
96  in_cache = this%cached_ranks%contains(rank)
97 
98  end function is_rank_cached
99 
100  subroutine add_rank_cache(this, rank)
101  class(mpiunitcachetype) :: this
102  integer(I4B) :: rank
103  ! local
104  integer(I4B) :: i, j
105 
106  call this%cached_ranks%push_back(rank)
107  do i = 1, this%nr_stages
108  do j = 1, this%nr_msg_types
109  call this%cached_messages%push_back(no_cached_value)
110  end do
111  end do
112 
113  end subroutine add_rank_cache
114 
115  !> @Brief returns -1 when not present
116  !<
117  function get_rank_index(this, rank) result(rank_index)
118  class(mpiunitcachetype) :: this
119  integer(I4B) :: rank
120  integer(I4B) :: rank_index
121 
122  rank_index = this%cached_ranks%get_index(rank)
123 
124  end function get_rank_index
125 
126  !> @Brief returns -1 when not present
127  !<
128  function get_msg_index(this, rank, stage, msg_id) result(msg_index)
129  class(mpiunitcachetype) :: this
130  integer(I4B) :: rank
131  integer(I4B) :: stage
132  integer(I4B) :: msg_id
133  integer(I4B) :: msg_index
134  ! local
135  integer(I4B) :: rank_idx
136  integer(I4B) :: rank_offset, stage_offset
137 
138  msg_index = -1
139  rank_idx = this%get_rank_index(rank)
140  if (rank_idx < 1) return
141 
142  rank_offset = (rank_idx - 1) * (this%nr_stages * this%nr_msg_types)
143  stage_offset = (stage - 1) * this%nr_msg_types
144  msg_index = rank_offset + stage_offset + msg_id
145 
146  end function get_msg_index
147 
148  !> @brief Clear the cache: free MPI types
149  !<
150  subroutine cc_clear(this)
151  class(mpiunitcachetype) :: this
152  ! local
153  integer(I4B) :: i
154  integer :: mpi_type, ierr
155 
156  do i = 1, this%cached_messages%size
157  mpi_type = this%cached_messages%at(i)
158  if (mpi_type /= no_cached_value) then
159  call mpi_type_free(mpi_type, ierr)
160  call check_mpi(ierr)
161  end if
162  end do
163  call this%cached_messages%clear()
164 
165  end subroutine cc_clear
166 
167  !> @brief Destroy unit cache.
168  !<
169  subroutine cc_destroy(this)
170  class(mpiunitcachetype) :: this
171 
172  call this%cached_ranks%destroy()
173  call this%cached_messages%destroy()
174 
175  end subroutine cc_destroy
176 
177 end module
subroutine init()
Definition: GridSorting.f90:24
This module defines variable data types.
Definition: kind.f90:8
subroutine clear(this, destroy)
Deallocate all items in list.
Definition: List.f90:89
subroutine cc_destroy(this)
Destroy unit cache.
integer(i4b) function get_msg_index(this, rank, stage, msg_id)
@Brief returns -1 when not present
subroutine add_rank_cache(this, rank)
logical(lgp) function is_rank_cached(this, rank)
subroutine cc_init(this, nr_stages, nr_msg_types)
Initialize the unit cache.
subroutine cc_clear(this)
Clear the cache: free MPI types.
integer(i4b), parameter, public no_cached_value
subroutine cc_cache(this, rank, stage, msg_id, mpi_type)
Cache the mpi datatype for this particular rank and stage. The datatype should be committed.
integer function cc_get_cached(this, rank, stage, msg_id)
Get the cached mpi type for this rank and.
integer(i4b) function get_rank_index(this, rank)
@Brief returns -1 when not present
subroutine, public check_mpi(mpi_error_code)
Check the MPI error code, report, and.
Definition: MpiWorld.f90:116
integer(i4b), parameter, public nr_sim_stages
before exchange formulate (per solution)
Definition: SimStages.f90:24
subroutine destroy(this)
Definition: STLVecInt.f90:183