15 integer(I4B) :: container_type
16 integer(I4B),
dimension(NR_VDC_ELEMENT_MAPS) :: map_sizes
27 type(
vdcptrtype),
dimension(:),
pointer :: vdc_models => null()
28 type(
vdcptrtype),
dimension(:),
pointer :: vdc_exchanges => null()
53 integer(I4B),
dimension(NR_VDC_ELEMENT_MAPS) :: map_sizes
58 this%el_maps(i)%nr_virt_elems = map_sizes(i)
59 allocate (this%el_maps(i)%remote_elem_shift(map_sizes(i)))
70 if (
associated(this%el_maps(i)%remote_elem_shift))
then
71 deallocate (this%el_maps(i)%remote_elem_shift)
86 type(
vdcptrtype),
dimension(:),
pointer :: vdc_models
87 type(
vdcptrtype),
dimension(:),
pointer :: vdc_exchanges
89 this%vdc_models => vdc_models
90 this%vdc_exchanges => vdc_exchanges
97 this%vdc_models => null()
98 this%vdc_exchanges => null()
117 integer(I4B) :: stage
118 integer,
intent(out) :: hdrs_snd_type
120 integer(I4B) :: i, offset, nr_types
124 integer,
dimension(:),
allocatable :: blk_cnts, types
125 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
127 call model_idxs%init()
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)
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)
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))
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()
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)
161 types(i) = this%create_vdc_snd_hdr(vdc, stage)
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)
172 call mpi_type_create_struct(nr_types, blk_cnts, displs, types, &
174 call mpi_type_commit(hdrs_snd_type, ierr)
176 call mpi_type_free(types(i), ierr)
179 call model_idxs%destroy()
180 call exg_idxs%destroy()
182 deallocate (blk_cnts)
190 integer,
intent(out) :: hdr_rcv_type
199 call mpi_type_commit(hdr_rcv_type, ierr)
206 integer(I4B) :: stage
207 integer,
intent(out) :: map_snd_type
209 integer(I4B) :: i, offset, nr_types
213 integer,
dimension(:),
allocatable :: blk_cnts, types
214 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
216 call model_idxs%init()
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)
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)
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))
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()
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)
251 types(i) = this%create_vdc_snd_map(vdc, stage)
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)
262 call mpi_type_create_struct(nr_types, blk_cnts, displs, types, &
264 call mpi_type_commit(map_snd_type, ierr)
268 call mpi_type_free(types(i), ierr)
271 call model_idxs%destroy()
272 call exg_idxs%destroy()
274 deallocate (blk_cnts)
283 integer(I4B) :: nr_headers
284 integer,
intent(out) :: map_rcv_type
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
293 allocate (types(max_nr_maps))
294 allocate (displs(max_nr_maps))
295 allocate (blk_cnts(max_nr_maps))
300 nr_elems = rcv_map(i)%el_maps(j)%nr_virt_elems
301 if (nr_elems == 0) cycle
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
311 call mpi_type_create_struct(type_cnt, blk_cnts, displs, types, &
313 call mpi_type_commit(map_rcv_type, ierr)
317 deallocate (blk_cnts)
326 integer(I4B) :: stage
327 integer,
intent(out) :: body_rcv_type
329 integer(I4B) :: i, nr_types, offset
333 integer,
dimension(:),
allocatable :: types
334 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
335 integer,
dimension(:),
allocatable :: blk_cnts
337 call model_idxs%init()
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
347 call model_idxs%push_back(i)
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
356 call exg_idxs%push_back(i)
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))
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)
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)
381 call mpi_type_create_struct(nr_types, blk_cnts, displs, types, &
383 call mpi_type_commit(body_rcv_type, ierr)
385 call mpi_type_free(types(i), ierr)
388 call model_idxs%destroy()
389 call exg_idxs%destroy()
392 deallocate (blk_cnts)
401 integer(I4B) :: stage
404 integer,
intent(out) :: body_snd_type
406 integer(I4B) :: i, nr_headers
409 integer,
dimension(:),
allocatable :: types
410 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
411 integer,
dimension(:),
allocatable :: blk_cnts
413 nr_headers =
size(headers)
414 allocate (types(nr_headers))
415 allocate (displs(nr_headers))
416 allocate (blk_cnts(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)
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)
430 call mpi_type_free(types(i), ierr)
435 deallocate (blk_cnts)
444 integer(I4B) :: stage
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
452 call mpi_get_address(vdc%id, displs(1), ierr)
453 types(1) = mpi_integer
455 call mpi_get_address(vdc%container_type, displs(2), ierr)
456 types(2) = mpi_integer
459 call mpi_get_address(vdc%element_maps(i)%nr_virt_elems, displs(i + 2), ierr)
460 types(i + 2) = mpi_integer
465 displs = displs - displs(1)
467 displs, types, new_type, ierr)
468 call mpi_type_commit(new_type, ierr)
477 integer(I4B) :: stage
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
492 call mpi_get_address(vdc%id, offset, ierr)
496 n_elems = vdc%element_maps(i)%nr_virt_elems
497 if (n_elems == 0) cycle
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
508 call mpi_type_create_struct(type_cnt, blk_cnts, displs, types, &
510 call mpi_type_commit(new_type, ierr)
513 call mpi_type_free(types(i), ierr)
518 deallocate (blk_cnts)
526 integer(I4B) :: stage
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
539 call vdc%get_recv_items(stage, rank, items)
542 allocate (types(items%size))
543 allocate (displs(items%size))
544 allocate (blk_cnts(items%size))
546 call mpi_get_address(vdc%id, offset, ierr)
553 displs(i) = displs(i) - offset
556 call mpi_type_create_struct(items%size, blk_cnts, displs, &
557 types, new_type, ierr)
558 call mpi_type_commit(new_type, ierr)
567 deallocate (blk_cnts)
578 integer(I4B) :: stage
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
589 integer(I4B),
dimension(:),
pointer,
contiguous :: el_map
592 call vdc%get_send_items(stage, rank, items)
595 allocate (types(items%size))
596 allocate (displs(items%size))
597 allocate (blk_cnts(items%size))
599 call mpi_get_address(vdc%id, offset, ierr)
603 if (vd%map_type > 0)
then
604 el_map => vdc_maps(vd%map_type)%remote_elem_shift
611 displs(i) = displs(i) - offset
614 call mpi_type_create_struct(items%size, blk_cnts, displs, &
615 types, new_type, ierr)
616 call mpi_type_commit(new_type, ierr)
625 deallocate (blk_cnts)
642 do i = 1,
size(this%vdc_models)
643 vdc => this%vdc_models(i)%ptr
644 if (vdc%id == header%id)
return
650 do i = 1,
size(this%vdc_exchanges)
651 vdc => this%vdc_exchanges(i)%ptr
652 if (vdc%id == header%id)
return
666 integer(kind=MPI_ADDRESS_KIND) :: el_displ
668 integer(I4B),
dimension(:),
pointer,
contiguous,
optional :: el_map_opt
671 integer(I4B),
dimension(:),
pointer,
contiguous :: el_map
674 if (
present(el_map_opt)) el_map => el_map_opt
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
681 write (this%imon,
'(8x,2a,i0)') virtual_data%var_name, &
682 ' with map size ',
size(el_map)
686 mt => virtual_data%virtual_mt
688 if (
associated(mt%intsclr))
then
690 else if (
associated(mt%aint1d))
then
692 else if (
associated(mt%dblsclr))
then
694 else if (
associated(mt%adbl1d))
then
696 else if (
associated(mt%adbl2d))
then
699 write (*, *)
'unsupported datatype in MPI messaging for ', &
700 virtual_data%var_name, virtual_data%mem_path
716 mt => virtual_data%virtual_mt
717 if (
associated(mt%intsclr))
then
720 else if (
associated(mt%dblsclr))
then
723 else if (
associated(mt%logicalsclr))
then
728 call mpi_type_free(el_type, ierr)
736 integer(kind=MPI_ADDRESS_KIND) :: el_displ
741 call mpi_get_address(mem%intsclr, el_displ, ierr)
742 el_type = mpi_integer
749 integer(kind=MPI_ADDRESS_KIND) :: el_displ
751 integer,
dimension(:),
pointer :: el_map
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)
763 call mpi_type_contiguous(mem%isize, mpi_integer, el_type, ierr)
765 call mpi_type_commit(el_type, ierr)
771 integer(kind=MPI_ADDRESS_KIND) :: el_displ
776 call mpi_get_address(mem%dblsclr, el_displ, ierr)
777 el_type = mpi_double_precision
784 integer(kind=MPI_ADDRESS_KIND) :: el_displ
786 integer,
dimension(:),
pointer :: el_map
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)
798 call mpi_type_contiguous(mem%isize, mpi_double_precision, el_type, ierr)
800 call mpi_type_commit(el_type, ierr)
806 integer(kind=MPI_ADDRESS_KIND) :: el_displ
808 integer,
dimension(:),
pointer :: el_map
811 integer :: entry_type
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)
823 call mpi_type_contiguous(mem%isize, mpi_double_precision, el_type, ierr)
825 call mpi_type_commit(el_type, ierr)
831 integer,
dimension(:),
pointer :: map
833 logical(LGP) :: is_valid
834 integer(I4B) :: min_idx, max_idx
836 if (.not.
associated(map))
return
837 if (
size(map) == 0)
return
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)
856 integer,
dimension(:),
pointer :: map
858 logical(LGP) :: is_valid
859 integer(I4B) :: min_idx, max_idx
861 if (.not.
associated(map))
return
862 if (
size(map) == 0)
return
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)
878 integer,
dimension(:),
pointer :: map
880 logical(LGP) :: is_valid
881 integer(I4B) :: min_idx, max_idx
883 if (.not.
associated(map))
return
884 if (
size(map) == 0)
return
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)
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
This module defines variable data types.
subroutine get_mpitype_for_dbl2d(mem, el_displ, el_type, el_map)
subroutine set_monitor(this, imon)
subroutine check_map_dbl1d(mem, map)
Bounds check for index maps,.
subroutine release_data(this)
subroutine check_map_int1d(mem, map)
integer function create_vdc_snd_body(this, vdc, vdc_maps, rank, stage)
subroutine get_mpitype_for_int(mem, el_displ, el_type)
integer function create_vdc_snd_hdr(this, vdc, stage)
Create send header for virtual data container, relative.
subroutine get_mpitype_for_dbl(mem, el_displ, el_type)
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....
subroutine attach_data(this, vdc_models, vdc_exchanges)
subroutine create(this, map_sizes)
subroutine create_map_snd(this, rank, stage, map_snd_type)
subroutine create_body_rcv(this, rank, stage, body_rcv_type)
Create the body to receive based on the headers.
integer function create_vdc_snd_map(this, vdc, stage)
Create a MPI datatype for sending the maps.
subroutine create_map_rcv(this, rcv_map, nr_headers, map_rcv_type)
subroutine get_mpitype_for_dbl1d(mem, el_displ, el_type, el_map)
subroutine free_mpi_datatype(virtual_data, el_type)
Local routine to free elemental mpi data types representing the virtual data items....
subroutine create_body_snd(this, rank, stage, headers, maps, body_snd_type)
Create the body to send based on the received headers.
integer function create_vdc_rcv_body(this, vdc, rank, stage)
subroutine check_map_dbl2d(mem, map)
subroutine create_header_rcv(this, hdr_rcv_type)
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....
class(virtualdatacontainertype) function, pointer get_vdc_from_hdr(this, header)
subroutine get_mpitype_for_int1d(mem, el_displ, el_type, el_map)
This module contains simulation methods.
subroutine, public ustop(stopmess, ioutlocal)
Stop the simulation.
class(virtualdatatype) function, pointer, public get_virtual_data_from_list(list, idx)
integer(i4b), parameter, public nr_vdc_element_maps
integer(i4b), parameter, public vdc_gwtmodel_type
integer(i4b), parameter, public vdc_gwemodel_type
integer(i4b), parameter, public vdc_gwfmodel_type
integer(i4b), parameter, public vdc_gwtexg_type
integer(i4b), parameter, public vdc_gwfexg_type
integer(i4b), parameter, public vdc_gweexg_type
This is a generic data structure to virtualize pieces of memory in 2 distinct ways:
Wrapper for virtual data containers.
Container (list) of virtual data items.