MODFLOW 6  version 6.7.0.dev3
USGS Modular Hydrologic Model
mpimessagebuildermodule Module Reference

Data Types

type  vdcheadertype
 
type  vdcreceivermapstype
 
type  mpimessagebuildertype
 

Functions/Subroutines

subroutine create (this, map_sizes)
 
subroutine destroy (this)
 
subroutine init (this)
 
subroutine attach_data (this, vdc_models, vdc_exchanges)
 
subroutine release_data (this)
 
subroutine set_monitor (this, imon)
 
subroutine create_header_snd (this, rank, stage, hdrs_snd_type)
 Create the header data type to send to the remote process for this particular stage. From these data, the receiver can construct the. More...
 
subroutine create_header_rcv (this, hdr_rcv_type)
 
subroutine create_map_snd (this, rank, stage, map_snd_type)
 
subroutine create_map_rcv (this, rcv_map, nr_headers, map_rcv_type)
 
subroutine create_body_rcv (this, rank, stage, body_rcv_type)
 Create the body to receive based on the headers. More...
 
subroutine create_body_snd (this, rank, stage, headers, maps, body_snd_type)
 Create the body to send based on the received headers. More...
 
integer function create_vdc_snd_hdr (this, vdc, stage)
 Create send header for virtual data container, relative. More...
 
integer function create_vdc_snd_map (this, vdc, stage)
 Create a MPI datatype for sending the maps. More...
 
integer function create_vdc_rcv_body (this, vdc, rank, stage)
 
integer function create_vdc_snd_body (this, vdc, vdc_maps, rank, stage)
 
class(virtualdatacontainertype) function, pointer get_vdc_from_hdr (this, header)
 
subroutine get_mpi_datatype (this, virtual_data, el_displ, el_type, el_map_opt)
 Local routine to get elemental mpi data types representing the virtual data items. Types are automatically committed unless. More...
 
subroutine free_mpi_datatype (virtual_data, el_type)
 Local routine to free elemental mpi data types representing the virtual data items. This can't be done generally, because some. More...
 
subroutine get_mpitype_for_int (mem, el_displ, el_type)
 
subroutine get_mpitype_for_int1d (mem, el_displ, el_type, el_map)
 
subroutine get_mpitype_for_dbl (mem, el_displ, el_type)
 
subroutine get_mpitype_for_dbl1d (mem, el_displ, el_type, el_map)
 
subroutine get_mpitype_for_dbl2d (mem, el_displ, el_type, el_map)
 
subroutine check_map_int1d (mem, map)
 
subroutine check_map_dbl1d (mem, map)
 Bounds check for index maps,. More...
 
subroutine check_map_dbl2d (mem, map)
 

Function/Subroutine Documentation

◆ attach_data()

subroutine mpimessagebuildermodule::attach_data ( class(mpimessagebuildertype this,
type(vdcptrtype), dimension(:), pointer  vdc_models,
type(vdcptrtype), dimension(:), pointer  vdc_exchanges 
)
private

Definition at line 84 of file MpiMessageBuilder.f90.

85  class(MpiMessageBuilderType) :: this
86  type(VdcPtrType), dimension(:), pointer :: vdc_models
87  type(VdcPtrType), dimension(:), pointer :: vdc_exchanges
88 
89  this%vdc_models => vdc_models
90  this%vdc_exchanges => vdc_exchanges
91 

◆ check_map_dbl1d()

subroutine mpimessagebuildermodule::check_map_dbl1d ( type(memorytype), pointer  mem,
integer, dimension(:), pointer  map 
)
private
Parameters
memmemory type
mapZERO-based map (for creating mpi types)

Definition at line 854 of file MpiMessageBuilder.f90.

855  type(MemoryType), pointer :: mem !< memory type
856  integer, dimension(:), pointer :: map !< ZERO-based map (for creating mpi types)
857  ! local
858  logical(LGP) :: is_valid
859  integer(I4B) :: min_idx, max_idx
860 
861  if (.not. associated(map)) return
862  if (size(map) == 0) return ! nothing to check
863 
864  min_idx = minval(map) + 1
865  max_idx = maxval(map) + 1
866  is_valid = max_idx <= size(mem%adbl1d) .and. min_idx > 0
867  if (.not. is_valid) then
868  write (*, '(/,4x,4a)') &
869  'Error: invalid map in MPI datatype for ', &
870  trim(mem%name), ' in ', trim(mem%path)
871  call ustop()
872  end if
873 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_map_dbl2d()

subroutine mpimessagebuildermodule::check_map_dbl2d ( type(memorytype), pointer  mem,
integer, dimension(:), pointer  map 
)
private
Parameters
mapZERO-based map (for creating mpi types)

Definition at line 876 of file MpiMessageBuilder.f90.

877  type(MemoryType), pointer :: mem
878  integer, dimension(:), pointer :: map !< ZERO-based map (for creating mpi types)
879  ! local
880  logical(LGP) :: is_valid
881  integer(I4B) :: min_idx, max_idx
882 
883  if (.not. associated(map)) return
884  if (size(map) == 0) return ! nothing to check
885 
886  min_idx = minval(map) + 1
887  max_idx = maxval(map) + 1
888  is_valid = max_idx <= size(mem%adbl2d, 2) .and. min_idx > 0
889  if (.not. is_valid) then
890  write (*, '(/,4x,4a)') &
891  'Error: invalid map in MPI datatype for ', &
892  trim(mem%name), ' in ', trim(mem%path)
893  call ustop()
894  end if
895 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_map_int1d()

subroutine mpimessagebuildermodule::check_map_int1d ( type(memorytype), pointer  mem,
integer, dimension(:), pointer  map 
)
private
Parameters
mapZERO-based map (for creating mpi types)

Definition at line 829 of file MpiMessageBuilder.f90.

830  type(MemoryType), pointer :: mem
831  integer, dimension(:), pointer :: map !< ZERO-based map (for creating mpi types)
832  ! local
833  logical(LGP) :: is_valid
834  integer(I4B) :: min_idx, max_idx
835 
836  if (.not. associated(map)) return
837  if (size(map) == 0) return ! nothing to check
838 
839  ! bounds check
840  min_idx = minval(map) + 1
841  max_idx = maxval(map) + 1
842  is_valid = max_idx <= size(mem%aint1d) .and. min_idx > 0
843  if (.not. is_valid) then
844  write (*, '(/,4x,4a)') &
845  'Error: invalid map in MPI datatype for ', &
846  trim(mem%name), ' in ', trim(mem%path)
847  call ustop()
848  end if
849 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create()

subroutine mpimessagebuildermodule::create ( class(vdcreceivermapstype this,
integer(i4b), dimension(nr_vdc_element_maps)  map_sizes 
)

Definition at line 51 of file MpiMessageBuilder.f90.

52  class(VdcReceiverMapsType) :: this
53  integer(I4B), dimension(NR_VDC_ELEMENT_MAPS) :: map_sizes
54  ! local
55  integer(I4B) :: i
56 
57  do i = 1, nr_vdc_element_maps
58  this%el_maps(i)%nr_virt_elems = map_sizes(i)
59  allocate (this%el_maps(i)%remote_elem_shift(map_sizes(i)))
60  end do
61 

◆ create_body_rcv()

subroutine mpimessagebuildermodule::create_body_rcv ( class(mpimessagebuildertype this,
integer(i4b)  rank,
integer(i4b)  stage,
integer, intent(out)  body_rcv_type 
)
private

Definition at line 323 of file MpiMessageBuilder.f90.

324  class(MpiMessageBuilderType) :: this
325  integer(I4B) :: rank
326  integer(I4B) :: stage
327  integer, intent(out) :: body_rcv_type
328  ! local
329  integer(I4B) :: i, nr_types, offset
330  class(VirtualDataContainerType), pointer :: vdc
331  type(STLVecInt) :: model_idxs, exg_idxs
332  integer :: ierr
333  integer, dimension(:), allocatable :: types
334  integer(kind=MPI_ADDRESS_KIND), dimension(:), allocatable :: displs
335  integer, dimension(:), allocatable :: blk_cnts
336 
337  call model_idxs%init()
338  call exg_idxs%init()
339 
340  ! gather all containers from this rank
341  do i = 1, size(this%vdc_models)
342  vdc => this%vdc_models(i)%ptr
343  if (vdc%is_active .and. vdc%orig_rank == rank) then
344  if (this%imon > 0) then
345  write (this%imon, '(6x,a,i0)') "expecting model ", vdc%id
346  end if
347  call model_idxs%push_back(i)
348  end if
349  end do
350  do i = 1, size(this%vdc_exchanges)
351  vdc => this%vdc_exchanges(i)%ptr
352  if (vdc%is_active .and. vdc%orig_rank == rank) then
353  if (this%imon > 0) then
354  write (this%imon, '(6x,a,i0)') "expecting exchange ", vdc%id
355  end if
356  call exg_idxs%push_back(i)
357  end if
358  end do
359 
360  nr_types = model_idxs%size + exg_idxs%size
361  allocate (types(nr_types))
362  allocate (displs(nr_types))
363  allocate (blk_cnts(nr_types))
364 
365  ! loop over included containers
366  do i = 1, model_idxs%size
367  vdc => this%vdc_models(model_idxs%at(i))%ptr
368  call mpi_get_address(vdc%id, displs(i), ierr)
369  types(i) = this%create_vdc_rcv_body(vdc, rank, stage)
370  blk_cnts(i) = 1
371  end do
372  offset = model_idxs%size
373  do i = 1, exg_idxs%size
374  vdc => this%vdc_exchanges(exg_idxs%at(i))%ptr
375  call mpi_get_address(vdc%id, displs(i + offset), ierr)
376  blk_cnts(i + offset) = 1
377  types(i + offset) = this%create_vdc_rcv_body(vdc, rank, stage)
378  end do
379 
380  ! create a MPI data type for the virtual data containers to receive
381  call mpi_type_create_struct(nr_types, blk_cnts, displs, types, &
382  body_rcv_type, ierr)
383  call mpi_type_commit(body_rcv_type, ierr)
384  do i = 1, nr_types
385  call mpi_type_free(types(i), ierr)
386  end do
387 
388  call model_idxs%destroy()
389  call exg_idxs%destroy()
390  deallocate (types)
391  deallocate (displs)
392  deallocate (blk_cnts)
393 

◆ create_body_snd()

subroutine mpimessagebuildermodule::create_body_snd ( class(mpimessagebuildertype this,
integer(i4b)  rank,
integer(i4b)  stage,
type(vdcheadertype), dimension(:)  headers,
type(vdcreceivermapstype), dimension(:)  maps,
integer, intent(out)  body_snd_type 
)
private

Definition at line 398 of file MpiMessageBuilder.f90.

399  class(MpiMessageBuilderType) :: this
400  integer(I4B) :: rank
401  integer(I4B) :: stage
402  type(VdcHeaderType), dimension(:) :: headers
403  type(VdcReceiverMapsType), dimension(:) :: maps
404  integer, intent(out) :: body_snd_type
405  ! local
406  integer(I4B) :: i, nr_headers
407  class(VirtualDataContainerType), pointer :: vdc
408  integer :: ierr
409  integer, dimension(:), allocatable :: types
410  integer(kind=MPI_ADDRESS_KIND), dimension(:), allocatable :: displs
411  integer, dimension(:), allocatable :: blk_cnts
412 
413  nr_headers = size(headers)
414  allocate (types(nr_headers))
415  allocate (displs(nr_headers))
416  allocate (blk_cnts(nr_headers))
417 
418  do i = 1, nr_headers
419  vdc => this%get_vdc_from_hdr(headers(i))
420  call mpi_get_address(vdc%id, displs(i), ierr)
421  types(i) = this%create_vdc_snd_body(vdc, maps(i)%el_maps, rank, stage)
422  blk_cnts(i) = 1
423  end do
424 
425  ! create the list of virtual data containers to receive
426  call mpi_type_create_struct(nr_headers, blk_cnts, displs, &
427  types, body_snd_type, ierr)
428  call mpi_type_commit(body_snd_type, ierr)
429  do i = 1, nr_headers
430  call mpi_type_free(types(i), ierr)
431  end do
432 
433  deallocate (types)
434  deallocate (displs)
435  deallocate (blk_cnts)
436 

◆ create_header_rcv()

subroutine mpimessagebuildermodule::create_header_rcv ( class(mpimessagebuildertype this,
integer, intent(out)  hdr_rcv_type 
)
private

Definition at line 188 of file MpiMessageBuilder.f90.

189  class(MpiMessageBuilderType) :: this
190  integer, intent(out) :: hdr_rcv_type
191  ! local
192  integer :: ierr
193 
194  ! this will be for one data container, the mpi recv
195  ! call will accept an array of them, no need to create
196  ! an overarching contiguous type...
197  call mpi_type_contiguous(nr_vdc_element_maps + 2, mpi_integer, &
198  hdr_rcv_type, ierr)
199  call mpi_type_commit(hdr_rcv_type, ierr)
200 

◆ create_header_snd()

subroutine mpimessagebuildermodule::create_header_snd ( class(mpimessagebuildertype this,
integer(i4b)  rank,
integer(i4b)  stage,
integer, intent(out)  hdrs_snd_type 
)
private

Definition at line 114 of file MpiMessageBuilder.f90.

115  class(MpiMessageBuilderType) :: this
116  integer(I4B) :: rank
117  integer(I4B) :: stage
118  integer, intent(out) :: hdrs_snd_type
119  ! local
120  integer(I4B) :: i, offset, nr_types
121  class(VirtualDataContainerType), pointer :: vdc
122  integer :: ierr
123  type(STLVecInt) :: model_idxs, exg_idxs
124  integer, dimension(:), allocatable :: blk_cnts, types
125  integer(kind=MPI_ADDRESS_KIND), dimension(:), allocatable :: displs
126 
127  call model_idxs%init()
128  call exg_idxs%init()
129 
130  ! determine which containers to include
131  do i = 1, size(this%vdc_models)
132  vdc => this%vdc_models(i)%ptr
133  if (vdc%is_active .and. vdc%orig_rank == rank) then
134  call model_idxs%push_back(i)
135  end if
136  end do
137  do i = 1, size(this%vdc_exchanges)
138  vdc => this%vdc_exchanges(i)%ptr
139  if (vdc%is_active .and. vdc%orig_rank == rank) then
140  call exg_idxs%push_back(i)
141  end if
142  end do
143 
144  nr_types = model_idxs%size + exg_idxs%size
145  allocate (blk_cnts(nr_types))
146  allocate (types(nr_types))
147  allocate (displs(nr_types))
148 
149  if (this%imon > 0) then
150  write (this%imon, '(6x,a,*(i3))') "create headers for models: ", &
151  model_idxs%get_values()
152  write (this%imon, '(6x,a,*(i3))') "create headers for exchange: ", &
153  exg_idxs%get_values()
154  end if
155 
156  ! loop over containers
157  do i = 1, model_idxs%size
158  vdc => this%vdc_models(model_idxs%at(i))%ptr
159  call mpi_get_address(vdc%id, displs(i), ierr)
160  blk_cnts(i) = 1
161  types(i) = this%create_vdc_snd_hdr(vdc, stage)
162  end do
163  offset = model_idxs%size
164  do i = 1, exg_idxs%size
165  vdc => this%vdc_exchanges(exg_idxs%at(i))%ptr
166  call mpi_get_address(vdc%id, displs(i + offset), ierr)
167  blk_cnts(i + offset) = 1
168  types(i + offset) = this%create_vdc_snd_hdr(vdc, stage)
169  end do
170 
171  ! create a MPI data type for the headers to send
172  call mpi_type_create_struct(nr_types, blk_cnts, displs, types, &
173  hdrs_snd_type, ierr)
174  call mpi_type_commit(hdrs_snd_type, ierr)
175  do i = 1, nr_types
176  call mpi_type_free(types(i), ierr)
177  end do
178 
179  call model_idxs%destroy()
180  call exg_idxs%destroy()
181 
182  deallocate (blk_cnts)
183  deallocate (types)
184  deallocate (displs)
185 

◆ create_map_rcv()

subroutine mpimessagebuildermodule::create_map_rcv ( class(mpimessagebuildertype this,
type(vdcreceivermapstype), dimension(:)  rcv_map,
integer(i4b)  nr_headers,
integer, intent(out)  map_rcv_type 
)
private

Definition at line 280 of file MpiMessageBuilder.f90.

281  class(MpiMessageBuilderType) :: this
282  type(VdcReceiverMapsType), dimension(:) :: rcv_map
283  integer(I4B) :: nr_headers
284  integer, intent(out) :: map_rcv_type
285  ! local
286  integer(I4B) :: i, j, nr_elems, type_cnt
287  integer :: ierr, max_nr_maps
288  integer, dimension(:), allocatable :: types
289  integer(kind=MPI_ADDRESS_KIND), dimension(:), allocatable :: displs
290  integer, dimension(:), allocatable :: blk_cnts
291 
292  max_nr_maps = nr_headers * nr_vdc_element_maps
293  allocate (types(max_nr_maps))
294  allocate (displs(max_nr_maps))
295  allocate (blk_cnts(max_nr_maps))
296 
297  type_cnt = 0
298  do i = 1, nr_headers
299  do j = 1, nr_vdc_element_maps
300  nr_elems = rcv_map(i)%el_maps(j)%nr_virt_elems
301  if (nr_elems == 0) cycle
302 
303  type_cnt = type_cnt + 1
304  call mpi_get_address(rcv_map(i)%el_maps(j)%remote_elem_shift, &
305  displs(type_cnt), ierr)
306  call mpi_type_contiguous(nr_elems, mpi_integer, types(type_cnt), ierr)
307  blk_cnts(type_cnt) = 1
308  end do
309  end do
310 
311  call mpi_type_create_struct(type_cnt, blk_cnts, displs, types, &
312  map_rcv_type, ierr)
313  call mpi_type_commit(map_rcv_type, ierr)
314 
315  deallocate (types)
316  deallocate (displs)
317  deallocate (blk_cnts)
318 

◆ create_map_snd()

subroutine mpimessagebuildermodule::create_map_snd ( class(mpimessagebuildertype this,
integer(i4b)  rank,
integer(i4b)  stage,
integer, intent(out)  map_snd_type 
)
private

Definition at line 203 of file MpiMessageBuilder.f90.

204  class(MpiMessageBuilderType) :: this
205  integer(I4B) :: rank
206  integer(I4B) :: stage
207  integer, intent(out) :: map_snd_type
208  ! local
209  integer(I4B) :: i, offset, nr_types
210  class(VirtualDataContainerType), pointer :: vdc
211  integer :: ierr
212  type(STLVecInt) :: model_idxs, exg_idxs
213  integer, dimension(:), allocatable :: blk_cnts, types
214  integer(kind=MPI_ADDRESS_KIND), dimension(:), allocatable :: displs
215 
216  call model_idxs%init()
217  call exg_idxs%init()
218 
219  ! determine which containers to include,
220  ! currently models + exchanges
221  do i = 1, size(this%vdc_models)
222  vdc => this%vdc_models(i)%ptr
223  if (vdc%is_active .and. vdc%orig_rank == rank) then
224  call model_idxs%push_back(i)
225  end if
226  end do
227  do i = 1, size(this%vdc_exchanges)
228  vdc => this%vdc_exchanges(i)%ptr
229  if (vdc%is_active .and. vdc%orig_rank == rank) then
230  call exg_idxs%push_back(i)
231  end if
232  end do
233 
234  nr_types = model_idxs%size + exg_idxs%size
235  allocate (blk_cnts(nr_types))
236  allocate (types(nr_types))
237  allocate (displs(nr_types))
238 
239  if (this%imon > 0) then
240  write (this%imon, '(6x,a,*(i3))') "create maps for models: ", &
241  model_idxs%get_values()
242  write (this%imon, '(6x,a,*(i3))') "create maps for exchange: ", &
243  exg_idxs%get_values()
244  end if
245 
246  ! loop over containers
247  do i = 1, model_idxs%size
248  vdc => this%vdc_models(model_idxs%at(i))%ptr
249  call mpi_get_address(vdc%id, displs(i), ierr)
250  blk_cnts(i) = 1
251  types(i) = this%create_vdc_snd_map(vdc, stage)
252  end do
253  offset = model_idxs%size
254  do i = 1, exg_idxs%size
255  vdc => this%vdc_exchanges(exg_idxs%at(i))%ptr
256  call mpi_get_address(vdc%id, displs(i + offset), ierr)
257  blk_cnts(i + offset) = 1
258  types(i + offset) = this%create_vdc_snd_map(vdc, stage)
259  end do
260 
261  ! create a compound MPI data type for the maps
262  call mpi_type_create_struct(nr_types, blk_cnts, displs, types, &
263  map_snd_type, ierr)
264  call mpi_type_commit(map_snd_type, ierr)
265 
266  ! free the subtypes
267  do i = 1, nr_types
268  call mpi_type_free(types(i), ierr)
269  end do
270 
271  call model_idxs%destroy()
272  call exg_idxs%destroy()
273 
274  deallocate (blk_cnts)
275  deallocate (types)
276  deallocate (displs)
277 

◆ create_vdc_rcv_body()

integer function mpimessagebuildermodule::create_vdc_rcv_body ( class(mpimessagebuildertype this,
class(virtualdatacontainertype), pointer  vdc,
integer(i4b)  rank,
integer(i4b)  stage 
)
private

Definition at line 522 of file MpiMessageBuilder.f90.

523  class(MpiMessageBuilderType) :: this
524  class(VirtualDataContainerType), pointer :: vdc
525  integer(I4B) :: rank
526  integer(I4B) :: stage
527  integer :: new_type
528  ! local
529  type(STLVecInt) :: items
530  integer :: ierr
531  integer(kind=MPI_ADDRESS_KIND) :: offset
532  integer, dimension(:), allocatable :: types
533  integer(kind=MPI_ADDRESS_KIND), dimension(:), allocatable :: displs
534  integer, dimension(:), allocatable :: blk_cnts
535  integer(I4B) :: i
536  class(VirtualDataType), pointer :: vd
537 
538  call items%init()
539  call vdc%get_recv_items(stage, rank, items)
540  !if (this%imon > 0) call vdc%print_items(this%imon, items)
541 
542  allocate (types(items%size))
543  allocate (displs(items%size))
544  allocate (blk_cnts(items%size))
545 
546  call mpi_get_address(vdc%id, offset, ierr)
547 
548  do i = 1, items%size
549  vd => get_virtual_data_from_list(vdc%virtual_data_list, items%at(i))
550  call get_mpi_datatype(this, vd, displs(i), types(i))
551  blk_cnts(i) = 1
552  ! rebase w.r.t. id field
553  displs(i) = displs(i) - offset
554  end do
555 
556  call mpi_type_create_struct(items%size, blk_cnts, displs, &
557  types, new_type, ierr)
558  call mpi_type_commit(new_type, ierr)
559 
560  do i = 1, items%size
561  vd => get_virtual_data_from_list(vdc%virtual_data_list, items%at(i))
562  call free_mpi_datatype(vd, types(i))
563  end do
564 
565  deallocate (types)
566  deallocate (displs)
567  deallocate (blk_cnts)
568 
569  call items%destroy()
570 
Here is the call graph for this function:

◆ create_vdc_snd_body()

integer function mpimessagebuildermodule::create_vdc_snd_body ( class(mpimessagebuildertype this,
class(virtualdatacontainertype), pointer  vdc,
type(vdcelementmaptype), dimension(:)  vdc_maps,
integer(i4b)  rank,
integer(i4b)  stage 
)
private

Definition at line 573 of file MpiMessageBuilder.f90.

574  class(MpiMessageBuilderType) :: this
575  class(VirtualDataContainerType), pointer :: vdc
576  type(VdcElementMapType), dimension(:) :: vdc_maps
577  integer(I4B) :: rank
578  integer(I4B) :: stage
579  integer :: new_type
580  ! local
581  type(STLVecInt) :: items
582  integer :: ierr
583  integer(kind=MPI_ADDRESS_KIND) :: offset
584  integer, dimension(:), allocatable :: types
585  integer(kind=MPI_ADDRESS_KIND), dimension(:), allocatable :: displs
586  integer, dimension(:), allocatable :: blk_cnts
587  integer(I4B) :: i
588  class(VirtualDataType), pointer :: vd
589  integer(I4B), dimension(:), pointer, contiguous :: el_map
590 
591  call items%init()
592  call vdc%get_send_items(stage, rank, items)
593  !if (this%imon > 0) call vdc%print_items(this%imon, items)
594 
595  allocate (types(items%size))
596  allocate (displs(items%size))
597  allocate (blk_cnts(items%size))
598 
599  call mpi_get_address(vdc%id, offset, ierr)
600 
601  do i = 1, items%size
602  vd => get_virtual_data_from_list(vdc%virtual_data_list, items%at(i))
603  if (vd%map_type > 0) then
604  el_map => vdc_maps(vd%map_type)%remote_elem_shift
605  else
606  el_map => null()
607  end if
608  call get_mpi_datatype(this, vd, displs(i), types(i), el_map)
609  blk_cnts(i) = 1
610  ! rebase w.r.t. id field
611  displs(i) = displs(i) - offset
612  end do
613 
614  call mpi_type_create_struct(items%size, blk_cnts, displs, &
615  types, new_type, ierr)
616  call mpi_type_commit(new_type, ierr)
617 
618  do i = 1, items%size
619  vd => get_virtual_data_from_list(vdc%virtual_data_list, items%at(i))
620  call free_mpi_datatype(vd, types(i))
621  end do
622 
623  deallocate (types)
624  deallocate (displs)
625  deallocate (blk_cnts)
626 
627  call items%destroy()
628 
Here is the call graph for this function:

◆ create_vdc_snd_hdr()

integer function mpimessagebuildermodule::create_vdc_snd_hdr ( class(mpimessagebuildertype this,
class(virtualdatacontainertype vdc,
integer(i4b)  stage 
)
private

Definition at line 441 of file MpiMessageBuilder.f90.

442  class(MpiMessageBuilderType) :: this
443  class(VirtualDataContainerType) :: vdc
444  integer(I4B) :: stage
445  integer :: new_type ! the created MPI datatype, uncommitted
446  ! local
447  integer :: i, ierr
448  integer, dimension(NR_VDC_ELEMENT_MAPS + 2) :: blk_cnts
449  integer(kind=MPI_ADDRESS_KIND), dimension(NR_VDC_ELEMENT_MAPS + 2) :: displs
450  integer, dimension(NR_VDC_ELEMENT_MAPS + 2) :: types
451 
452  call mpi_get_address(vdc%id, displs(1), ierr)
453  types(1) = mpi_integer
454  blk_cnts(1) = 1
455  call mpi_get_address(vdc%container_type, displs(2), ierr)
456  types(2) = mpi_integer
457  blk_cnts(2) = 1
458  do i = 1, nr_vdc_element_maps
459  call mpi_get_address(vdc%element_maps(i)%nr_virt_elems, displs(i + 2), ierr)
460  types(i + 2) = mpi_integer
461  blk_cnts(i + 2) = 1
462  end do
463 
464  ! rebase to id field
465  displs = displs - displs(1)
466  call mpi_type_create_struct(nr_vdc_element_maps + 2, blk_cnts, &
467  displs, types, new_type, ierr)
468  call mpi_type_commit(new_type, ierr)
469 

◆ create_vdc_snd_map()

integer function mpimessagebuildermodule::create_vdc_snd_map ( class(mpimessagebuildertype this,
class(virtualdatacontainertype), pointer  vdc,
integer(i4b)  stage 
)
private

Definition at line 474 of file MpiMessageBuilder.f90.

475  class(MpiMessageBuilderType) :: this
476  class(VirtualDataContainerType), pointer :: vdc
477  integer(I4B) :: stage
478  integer :: new_type
479  ! local
480  integer(I4B) :: i, type_cnt
481  integer :: n_elems, ierr
482  integer(kind=MPI_ADDRESS_KIND) :: offset
483  integer, dimension(:), allocatable :: types
484  integer(kind=MPI_ADDRESS_KIND), dimension(:), allocatable :: displs
485  integer, dimension(:), allocatable :: blk_cnts
486 
487  allocate (types(nr_vdc_element_maps))
488  allocate (displs(nr_vdc_element_maps))
489  allocate (blk_cnts(nr_vdc_element_maps))
490 
491  ! displ relative to id field
492  call mpi_get_address(vdc%id, offset, ierr)
493 
494  type_cnt = 0
495  do i = 1, nr_vdc_element_maps
496  n_elems = vdc%element_maps(i)%nr_virt_elems
497  if (n_elems == 0) cycle ! only non-empty maps are sent
498 
499  type_cnt = type_cnt + 1
500  call mpi_get_address(vdc%element_maps(i)%remote_elem_shift, &
501  displs(type_cnt), ierr)
502  call mpi_type_contiguous(n_elems, mpi_integer, types(type_cnt), ierr)
503  call mpi_type_commit(types(type_cnt), ierr)
504  blk_cnts(type_cnt) = 1
505  displs(type_cnt) = displs(type_cnt) - offset
506  end do
507 
508  call mpi_type_create_struct(type_cnt, blk_cnts, displs, types, &
509  new_type, ierr)
510  call mpi_type_commit(new_type, ierr)
511 
512  do i = 1, type_cnt
513  call mpi_type_free(types(i), ierr)
514  end do
515 
516  deallocate (types)
517  deallocate (displs)
518  deallocate (blk_cnts)
519 

◆ destroy()

subroutine mpimessagebuildermodule::destroy ( class(vdcreceivermapstype this)
private

Definition at line 64 of file MpiMessageBuilder.f90.

65  class(VdcReceiverMapsType) :: this
66  ! local
67  integer(I4B) :: i
68 
69  do i = 1, nr_vdc_element_maps
70  if (associated(this%el_maps(i)%remote_elem_shift)) then
71  deallocate (this%el_maps(i)%remote_elem_shift)
72  end if
73  end do
74 

◆ free_mpi_datatype()

subroutine mpimessagebuildermodule::free_mpi_datatype ( class(virtualdatatype), pointer  virtual_data,
integer  el_type 
)

Definition at line 709 of file MpiMessageBuilder.f90.

710  class(VirtualDataType), pointer :: virtual_data
711  integer :: el_type
712  ! local
713  type(MemoryType), pointer :: mt
714  integer :: ierr
715 
716  mt => virtual_data%virtual_mt
717  if (associated(mt%intsclr)) then
718  ! type is MPI_INTEGER, don't free this!
719  return
720  else if (associated(mt%dblsclr)) then
721  ! type is MPI_DOUBLE_PRECISION, don't free this!
722  return
723  else if (associated(mt%logicalsclr)) then
724  ! type is MPI_LOGICAL, don't free this!
725  return
726  else
727  ! all other types are freed here
728  call mpi_type_free(el_type, ierr)
729  return
730  end if
731 
Here is the caller graph for this function:

◆ get_mpi_datatype()

subroutine mpimessagebuildermodule::get_mpi_datatype ( class(mpimessagebuildertype this,
class(virtualdatatype), pointer  virtual_data,
integer(kind=mpi_address_kind)  el_displ,
integer  el_type,
integer(i4b), dimension(:), optional, pointer, contiguous  el_map_opt 
)
private
Parameters
el_map_optoptional, and can be null

Definition at line 662 of file MpiMessageBuilder.f90.

663  use simmodule, only: ustop
664  class(MpiMessageBuilderType) :: this
665  class(VirtualDataType), pointer :: virtual_data
666  integer(kind=MPI_ADDRESS_KIND) :: el_displ
667  integer :: el_type
668  integer(I4B), dimension(:), pointer, contiguous, optional :: el_map_opt !< optional, and can be null
669  ! local
670  type(MemoryType), pointer :: mt
671  integer(I4B), dimension(:), pointer, contiguous :: el_map
672 
673  el_map => null()
674  if (present(el_map_opt)) el_map => el_map_opt
675 
676  if (this%imon > 0) then
677  if (.not. associated(el_map)) then
678  write (this%imon, '(8x,2a,i0)') virtual_data%var_name, ' all ', &
679  virtual_data%virtual_mt%isize
680  else
681  write (this%imon, '(8x,2a,i0)') virtual_data%var_name, &
682  ' with map size ', size(el_map)
683  end if
684  end if
685 
686  mt => virtual_data%virtual_mt
687 
688  if (associated(mt%intsclr)) then
689  call get_mpitype_for_int(mt, el_displ, el_type)
690  else if (associated(mt%aint1d)) then
691  call get_mpitype_for_int1d(mt, el_displ, el_type, el_map)
692  else if (associated(mt%dblsclr)) then
693  call get_mpitype_for_dbl(mt, el_displ, el_type)
694  else if (associated(mt%adbl1d)) then
695  call get_mpitype_for_dbl1d(mt, el_displ, el_type, el_map)
696  else if (associated(mt%adbl2d)) then
697  call get_mpitype_for_dbl2d(mt, el_displ, el_type, el_map)
698  else
699  write (*, *) 'unsupported datatype in MPI messaging for ', &
700  virtual_data%var_name, virtual_data%mem_path
701  call ustop()
702  end if
703 
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public ustop(stopmess, ioutlocal)
Stop the simulation.
Definition: Sim.f90:312
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_mpitype_for_dbl()

subroutine mpimessagebuildermodule::get_mpitype_for_dbl ( type(memorytype), pointer  mem,
integer(kind=mpi_address_kind)  el_displ,
integer  el_type 
)
private

Definition at line 769 of file MpiMessageBuilder.f90.

770  type(MemoryType), pointer :: mem
771  integer(kind=MPI_ADDRESS_KIND) :: el_displ
772  integer :: el_type
773  ! local
774  integer :: ierr
775 
776  call mpi_get_address(mem%dblsclr, el_displ, ierr)
777  el_type = mpi_double_precision
778  ! no need to commit primitive type
779 
Here is the caller graph for this function:

◆ get_mpitype_for_dbl1d()

subroutine mpimessagebuildermodule::get_mpitype_for_dbl1d ( type(memorytype), pointer  mem,
integer(kind=mpi_address_kind)  el_displ,
integer  el_type,
integer, dimension(:), pointer  el_map 
)
private

Definition at line 782 of file MpiMessageBuilder.f90.

783  type(MemoryType), pointer :: mem
784  integer(kind=MPI_ADDRESS_KIND) :: el_displ
785  integer :: el_type
786  integer, dimension(:), pointer :: el_map
787  ! local
788  integer :: ierr
789 
790  ! sanity check on map
791  call check_map_dbl1d(mem, el_map)
792 
793  call mpi_get_address(mem%adbl1d, el_displ, ierr)
794  if (associated(el_map)) then
795  call mpi_type_create_indexed_block( &
796  size(el_map), 1, el_map, mpi_double_precision, el_type, ierr)
797  else
798  call mpi_type_contiguous(mem%isize, mpi_double_precision, el_type, ierr)
799  end if
800  call mpi_type_commit(el_type, ierr)
801 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_mpitype_for_dbl2d()

subroutine mpimessagebuildermodule::get_mpitype_for_dbl2d ( type(memorytype), pointer  mem,
integer(kind=mpi_address_kind)  el_displ,
integer  el_type,
integer, dimension(:), pointer  el_map 
)
private

Definition at line 804 of file MpiMessageBuilder.f90.

805  type(MemoryType), pointer :: mem
806  integer(kind=MPI_ADDRESS_KIND) :: el_displ
807  integer :: el_type
808  integer, dimension(:), pointer :: el_map
809  ! local
810  integer :: ierr
811  integer :: entry_type
812 
813  ! sanity check on map
814  call check_map_dbl2d(mem, el_map)
815 
816  call mpi_get_address(mem%adbl2d, el_displ, ierr)
817  if (associated(el_map)) then
818  call mpi_type_contiguous( &
819  size(mem%adbl2d, dim=1), mpi_double_precision, entry_type, ierr)
820  call mpi_type_create_indexed_block( &
821  size(el_map), 1, el_map, entry_type, el_type, ierr)
822  else
823  call mpi_type_contiguous(mem%isize, mpi_double_precision, el_type, ierr)
824  end if
825  call mpi_type_commit(el_type, ierr)
826 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_mpitype_for_int()

subroutine mpimessagebuildermodule::get_mpitype_for_int ( type(memorytype), pointer  mem,
integer(kind=mpi_address_kind)  el_displ,
integer  el_type 
)
private

Definition at line 734 of file MpiMessageBuilder.f90.

735  type(MemoryType), pointer :: mem
736  integer(kind=MPI_ADDRESS_KIND) :: el_displ
737  integer :: el_type
738  ! local
739  integer :: ierr
740 
741  call mpi_get_address(mem%intsclr, el_displ, ierr)
742  el_type = mpi_integer
743  ! no need to commit primitive type
744 
Here is the caller graph for this function:

◆ get_mpitype_for_int1d()

subroutine mpimessagebuildermodule::get_mpitype_for_int1d ( type(memorytype), pointer  mem,
integer(kind=mpi_address_kind)  el_displ,
integer  el_type,
integer, dimension(:), pointer  el_map 
)
private

Definition at line 747 of file MpiMessageBuilder.f90.

748  type(MemoryType), pointer :: mem
749  integer(kind=MPI_ADDRESS_KIND) :: el_displ
750  integer :: el_type
751  integer, dimension(:), pointer :: el_map
752  ! local
753  integer :: ierr
754 
755  ! sanity check on map
756  call check_map_int1d(mem, el_map)
757 
758  call mpi_get_address(mem%aint1d, el_displ, ierr)
759  if (associated(el_map)) then
760  call mpi_type_create_indexed_block( &
761  size(el_map), 1, el_map, mpi_integer, el_type, ierr)
762  else
763  call mpi_type_contiguous(mem%isize, mpi_integer, el_type, ierr)
764  end if
765  call mpi_type_commit(el_type, ierr)
766 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_vdc_from_hdr()

class(virtualdatacontainertype) function, pointer mpimessagebuildermodule::get_vdc_from_hdr ( class(mpimessagebuildertype this,
type(vdcheadertype header 
)
private

Definition at line 631 of file MpiMessageBuilder.f90.

632  class(MpiMessageBuilderType) :: this
633  type(VdcHeaderType) :: header
634  class(VirtualDataContainerType), pointer :: vdc
635  ! local
636  integer(I4B) :: i
637 
638  vdc => null()
639  if (header%container_type == vdc_gwfmodel_type .or. &
640  header%container_type == vdc_gwtmodel_type .or. &
641  header%container_type == vdc_gwemodel_type) then
642  do i = 1, size(this%vdc_models)
643  vdc => this%vdc_models(i)%ptr
644  if (vdc%id == header%id) return
645  vdc => null()
646  end do
647  else if (header%container_type == vdc_gwfexg_type .or. &
648  header%container_type == vdc_gwtexg_type .or. &
649  header%container_type == vdc_gweexg_type) then
650  do i = 1, size(this%vdc_exchanges)
651  vdc => this%vdc_exchanges(i)%ptr
652  if (vdc%id == header%id) return
653  vdc => null()
654  end do
655  end if
656 

◆ init()

subroutine mpimessagebuildermodule::init ( class(mpimessagebuildertype this)
private

Definition at line 77 of file MpiMessageBuilder.f90.

78  class(MpiMessageBuilderType) :: this
79 
80  this%imon = -1
81 

◆ release_data()

subroutine mpimessagebuildermodule::release_data ( class(mpimessagebuildertype this)
private

Definition at line 94 of file MpiMessageBuilder.f90.

95  class(MpiMessageBuilderType) :: this
96 
97  this%vdc_models => null()
98  this%vdc_exchanges => null()
99 

◆ set_monitor()

subroutine mpimessagebuildermodule::set_monitor ( class(mpimessagebuildertype this,
integer(i4b)  imon 
)
private

Definition at line 102 of file MpiMessageBuilder.f90.

103  class(MpiMessageBuilderType) :: this
104  integer(I4B) :: imon
105 
106  this%imon = imon
107