MODFLOW 6  version 6.7.0.dev1
USGS Modular Hydrologic Model
MpiMessageCache.f90
Go to the documentation of this file.
2  use kindmodule, only: i4b
4  use listmodule
7  implicit none
8  private
9 
10  ! the message types for caching during a simulation stage:
11  integer(I4B), public, parameter :: mpi_bdy_rcv = 1 !< receiving data (body) from ranks
12  integer(I4B), public, parameter :: mpi_bdy_snd = 2 !< sending data (body) to ranks
13  integer(I4B), public, parameter :: nr_msg_types = 2 !< the total number of message types to be cached
14 
15  ! expose this from the unit cache module
16  public :: no_cached_value
17 
18  !> @brief Facility to cache the constructed MPI datatypes.
19  !! This will avoid having to construct them over and over
20  !! again for the communication inside the timestep loop.
21  !! This class deals with separate caches for different
22  !! units (solutions or global) and for different types of
23  !< messages within the communication stage.
24  type, public :: mpimessagecachetype
25  type(stlvecint) :: cached_ids !< a vector with ids for the cached units (solution ids)
26  type(listtype) :: unit_caches !< a list with caches per unit
27  contains
28  procedure :: init => mmc_init
29  procedure :: get => mmc_get
30  procedure :: put => mmc_put
31  procedure :: clear => mmc_clear
32  procedure :: destroy => mmc_destroy
33  end type mpimessagecachetype
34 
35 contains
36 
37  !< @brief Initialize the MPI type cache system.
38  !<
39  subroutine mmc_init(this)
40  class(mpimessagecachetype) :: this !< the message cache
41 
42  call this%cached_ids%init()
43 
44  end subroutine mmc_init
45 
46  !< @brief Get the cached mpi datatype for the given
47  !! unit, rank, stage, and message element. Returns
48  !< NO_CACHED_VALUE when not in cache.
49  function mmc_get(this, unit, rank, stage, msg_id) result(mpi_type)
50  class(mpimessagecachetype) :: this !< the message cache
51  integer(I4B) :: unit !< the unit (solution or global)
52  integer(I4B) :: rank !< the rank of the MPI process to communicate with
53  integer(I4B) :: stage !< the simulation stage at which the message is sent
54  integer(I4B) :: msg_id !< the message type as an integer between 1 and NR_MSG_TYPES (see above for predefined values)
55  integer :: mpi_type !< the resulting mpi datatype
56  ! local
57  integer(I4B) :: unit_idx
58  class(*), pointer :: obj_ptr
59 
60  mpi_type = no_cached_value
61 
62  unit_idx = this%cached_ids%get_index(unit)
63  if (unit_idx == -1) return ! not cached
64 
65  obj_ptr => this%unit_caches%GetItem(unit_idx)
66  select type (obj_ptr)
67  class is (mpiunitcachetype)
68  mpi_type = obj_ptr%get_cached(rank, stage, msg_id)
69  end select
70 
71  end function mmc_get
72 
73  !> @brief Put the mpi datatype for this particular unit,
74  !! rank, and stage in cache. The datatype should be
75  !< committed to the type database externally.
76  subroutine mmc_put(this, unit, rank, stage, msg_id, mpi_type)
77  class(mpimessagecachetype) :: this !< the message cache
78  integer(I4B) :: unit !< the unit (solution or global)
79  integer(I4B) :: rank !< the rank of the MPI process to communicate with
80  integer(I4B) :: stage !< the simulation stage at which the message is sent
81  integer(I4B) :: msg_id !< the message type as an integer between 1 and NR_MSG_TYPES (see above for predefined values)
82  integer :: mpi_type !< the mpi datatype to cache
83  ! local
84  integer(I4B) :: unit_idx
85  type(mpiunitcachetype), pointer :: new_cache
86  class(*), pointer :: obj_ptr
87 
88  unit_idx = this%cached_ids%get_index(unit)
89  if (unit_idx == -1) then
90  ! add to vector with cached unit ids
91  call this%cached_ids%push_back(unit)
92  ! create and add unit cache
93  allocate (new_cache)
94  call new_cache%init(nr_sim_stages, nr_msg_types)
95  obj_ptr => new_cache
96  call this%unit_caches%Add(obj_ptr)
97  unit_idx = this%cached_ids%size
98  end if
99 
100  ! get the cache for this unit
101  obj_ptr => this%unit_caches%GetItem(unit_idx)
102  select type (obj_ptr)
103  class is (mpiunitcachetype)
104  call obj_ptr%cache(rank, stage, msg_id, mpi_type)
105  end select
106 
107  end subroutine mmc_put
108 
109  !< @brief Clear the MPI type cache system
110  !<
111  subroutine mmc_clear(this)
112  class(mpimessagecachetype) :: this !< the message cache
113  ! local
114  integer(I4B) :: i
115  class(*), pointer :: obj_ptr
116 
117  ! clear caches
118  do i = 1, this%cached_ids%size
119  obj_ptr => this%unit_caches%GetItem(i)
120  select type (obj_ptr)
121  class is (mpiunitcachetype)
122  call obj_ptr%clear()
123  end select
124  end do
125 
126  end subroutine mmc_clear
127 
128  !< @brief Destroy the MPI type cache system.
129  !<
130  subroutine mmc_destroy(this)
131  class(mpimessagecachetype) :: this !< the message cache
132  ! local
133  integer(I4B) :: i
134  class(*), pointer :: obj_ptr
135 
136  ! clear caches
137  do i = 1, this%cached_ids%size
138  obj_ptr => this%unit_caches%GetItem(i)
139  select type (obj_ptr)
140  class is (mpiunitcachetype)
141  call obj_ptr%destroy()
142  end select
143  end do
144  call this%unit_caches%Clear(destroy=.true.)
145 
146  call this%cached_ids%destroy()
147 
148  end subroutine mmc_destroy
149 
150 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 mmc_clear(this)
integer(i4b), parameter, public nr_msg_types
the total number of message types to be cached
integer function mmc_get(this, unit, rank, stage, msg_id)
integer(i4b), parameter, public mpi_bdy_snd
sending data (body) to ranks
subroutine mmc_destroy(this)
subroutine mmc_init(this)
subroutine mmc_put(this, unit, rank, stage, msg_id, mpi_type)
Put the mpi datatype for this particular unit, rank, and stage in cache. The datatype should be.
integer(i4b), parameter, public mpi_bdy_rcv
receiving data (body) from ranks
integer(i4b), parameter, public no_cached_value
integer(i4b), parameter, public nr_sim_stages
before exchange formulate (per solution)
Definition: SimStages.f90:24
subroutine destroy(this)
Definition: STLVecInt.f90:183
A generic heterogeneous doubly-linked list.
Definition: List.f90:14
Facility to cache the constructed MPI datatypes. This will avoid having to construct them over and ov...