MODFLOW 6  version 6.6.0.dev0
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 :: destroy => mmc_destroy
32  end type mpimessagecachetype
33 
34 contains
35 
36  !< @brief Initialize the MPI type cache system.
37  !<
38  subroutine mmc_init(this)
39  class(mpimessagecachetype) :: this !< the message cache
40 
41  call this%cached_ids%init()
42 
43  end subroutine mmc_init
44 
45  !< @brief Get the cached mpi datatype for the given
46  !! unit, rank, stage, and message element. Returns
47  !< NO_CACHED_VALUE when not in cache.
48  function mmc_get(this, unit, rank, stage, msg_id) result(mpi_type)
49  class(mpimessagecachetype) :: this !< the message cache
50  integer(I4B) :: unit !< the unit (solution or global)
51  integer(I4B) :: rank !< the rank of the MPI process to communicate with
52  integer(I4B) :: stage !< the simulation stage at which the message is sent
53  integer(I4B) :: msg_id !< the message type as an integer between 1 and NR_MSG_TYPES (see above for predefined values)
54  integer :: mpi_type !< the resulting mpi datatype
55  ! local
56  integer(I4B) :: unit_idx
57  class(*), pointer :: obj_ptr
58 
59  mpi_type = no_cached_value
60 
61  unit_idx = this%cached_ids%get_index(unit)
62  if (unit_idx == -1) return ! not cached
63 
64  obj_ptr => this%unit_caches%GetItem(unit_idx)
65  select type (obj_ptr)
66  class is (mpiunitcachetype)
67  mpi_type = obj_ptr%get_cached(rank, stage, msg_id)
68  end select
69 
70  end function mmc_get
71 
72  !> @brief Put the mpi datatype for this particular unit,
73  !! rank, and stage in cache. The datatype should be
74  !< committed to the type database externally.
75  subroutine mmc_put(this, unit, rank, stage, msg_id, mpi_type)
76  class(mpimessagecachetype) :: this !< the message cache
77  integer(I4B) :: unit !< the unit (solution or global)
78  integer(I4B) :: rank !< the rank of the MPI process to communicate with
79  integer(I4B) :: stage !< the simulation stage at which the message is sent
80  integer(I4B) :: msg_id !< the message type as an integer between 1 and NR_MSG_TYPES (see above for predefined values)
81  integer :: mpi_type !< the mpi datatype to cache
82  ! local
83  integer(I4B) :: unit_idx
84  type(mpiunitcachetype), pointer :: new_cache
85  class(*), pointer :: obj_ptr
86 
87  unit_idx = this%cached_ids%get_index(unit)
88  if (unit_idx == -1) then
89  ! add to vector with cached unit ids
90  call this%cached_ids%push_back(unit)
91  ! create and add unit cache
92  allocate (new_cache)
93  call new_cache%init(nr_sim_stages, nr_msg_types)
94  obj_ptr => new_cache
95  call this%unit_caches%Add(obj_ptr)
96  unit_idx = this%cached_ids%size
97  end if
98 
99  ! get the cache for this unit
100  obj_ptr => this%unit_caches%GetItem(unit_idx)
101  select type (obj_ptr)
102  class is (mpiunitcachetype)
103  call obj_ptr%cache(rank, stage, msg_id, mpi_type)
104  end select
105 
106  end subroutine mmc_put
107 
108  !< @brief Destroy the MPI type cache system.
109  !<
110  subroutine mmc_destroy(this)
111  class(mpimessagecachetype) :: this !< the message cache
112  ! local
113  integer(I4B) :: i
114  class(*), pointer :: obj_ptr
115 
116  ! clear caches
117  do i = 1, this%cached_ids%size
118  obj_ptr => this%unit_caches%GetItem(i)
119  select type (obj_ptr)
120  class is (mpiunitcachetype)
121  call obj_ptr%destroy()
122  end select
123  end do
124  call this%unit_caches%Clear(destroy=.true.)
125 
126  call this%cached_ids%destroy()
127 
128  end subroutine mmc_destroy
129 
130 end module
subroutine init()
Definition: GridSorting.f90:24
This module defines variable data types.
Definition: kind.f90:8
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:170
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...