13 integer(I4B) :: container_type
14 integer(I4B),
dimension(NR_VDC_ELEMENT_MAPS) :: map_sizes
25 type(
vdcptrtype),
dimension(:),
pointer :: vdc_models => null()
26 type(
vdcptrtype),
dimension(:),
pointer :: vdc_exchanges => null()
51 integer(I4B),
dimension(NR_VDC_ELEMENT_MAPS) :: map_sizes
56 this%el_maps(i)%nr_virt_elems = map_sizes(i)
57 allocate (this%el_maps(i)%remote_elem_shift(map_sizes(i)))
68 if (
associated(this%el_maps(i)%remote_elem_shift))
then
69 deallocate (this%el_maps(i)%remote_elem_shift)
84 type(
vdcptrtype),
dimension(:),
pointer :: vdc_models
85 type(
vdcptrtype),
dimension(:),
pointer :: vdc_exchanges
87 this%vdc_models => vdc_models
88 this%vdc_exchanges => vdc_exchanges
95 this%vdc_models => null()
96 this%vdc_exchanges => null()
115 integer(I4B) :: stage
116 integer,
intent(out) :: hdrs_snd_type
118 integer(I4B) :: i, offset, nr_types
122 integer,
dimension(:),
allocatable :: blk_cnts, types
123 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
125 call model_idxs%init()
129 do i = 1,
size(this%vdc_models)
130 vdc => this%vdc_models(i)%ptr
131 if (vdc%is_active .and. vdc%orig_rank == rank)
then
132 call model_idxs%push_back(i)
135 do i = 1,
size(this%vdc_exchanges)
136 vdc => this%vdc_exchanges(i)%ptr
137 if (vdc%is_active .and. vdc%orig_rank == rank)
then
138 call exg_idxs%push_back(i)
142 nr_types = model_idxs%size + exg_idxs%size
143 allocate (blk_cnts(nr_types))
144 allocate (types(nr_types))
145 allocate (displs(nr_types))
147 if (this%imon > 0)
then
148 write (this%imon,
'(6x,a,*(i3))')
"create headers for models: ", &
149 model_idxs%get_values()
150 write (this%imon,
'(6x,a,*(i3))')
"create headers for exchange: ", &
151 exg_idxs%get_values()
155 do i = 1, model_idxs%size
156 vdc => this%vdc_models(model_idxs%at(i))%ptr
157 call mpi_get_address(vdc%id, displs(i), ierr)
159 types(i) = this%create_vdc_snd_hdr(vdc, stage)
161 offset = model_idxs%size
162 do i = 1, exg_idxs%size
163 vdc => this%vdc_exchanges(exg_idxs%at(i))%ptr
164 call mpi_get_address(vdc%id, displs(i + offset), ierr)
165 blk_cnts(i + offset) = 1
166 types(i + offset) = this%create_vdc_snd_hdr(vdc, stage)
170 call mpi_type_create_struct(nr_types, blk_cnts, displs, types, &
172 call mpi_type_commit(hdrs_snd_type, ierr)
174 call mpi_type_free(types(i), ierr)
177 call model_idxs%destroy()
178 call exg_idxs%destroy()
180 deallocate (blk_cnts)
188 integer,
intent(out) :: hdr_rcv_type
197 call mpi_type_commit(hdr_rcv_type, ierr)
204 integer(I4B) :: stage
205 integer,
intent(out) :: map_snd_type
207 integer(I4B) :: i, offset, nr_types
211 integer,
dimension(:),
allocatable :: blk_cnts, types
212 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
214 call model_idxs%init()
219 do i = 1,
size(this%vdc_models)
220 vdc => this%vdc_models(i)%ptr
221 if (vdc%is_active .and. vdc%orig_rank == rank)
then
222 call model_idxs%push_back(i)
225 do i = 1,
size(this%vdc_exchanges)
226 vdc => this%vdc_exchanges(i)%ptr
227 if (vdc%is_active .and. vdc%orig_rank == rank)
then
228 call exg_idxs%push_back(i)
232 nr_types = model_idxs%size + exg_idxs%size
233 allocate (blk_cnts(nr_types))
234 allocate (types(nr_types))
235 allocate (displs(nr_types))
237 if (this%imon > 0)
then
238 write (this%imon,
'(6x,a,*(i3))')
"create maps for models: ", &
239 model_idxs%get_values()
240 write (this%imon,
'(6x,a,*(i3))')
"create maps for exchange: ", &
241 exg_idxs%get_values()
245 do i = 1, model_idxs%size
246 vdc => this%vdc_models(model_idxs%at(i))%ptr
247 call mpi_get_address(vdc%id, displs(i), ierr)
249 types(i) = this%create_vdc_snd_map(vdc, stage)
251 offset = model_idxs%size
252 do i = 1, exg_idxs%size
253 vdc => this%vdc_exchanges(exg_idxs%at(i))%ptr
254 call mpi_get_address(vdc%id, displs(i + offset), ierr)
255 blk_cnts(i + offset) = 1
256 types(i + offset) = this%create_vdc_snd_map(vdc, stage)
260 call mpi_type_create_struct(nr_types, blk_cnts, displs, types, &
262 call mpi_type_commit(map_snd_type, ierr)
266 call mpi_type_free(types(i), ierr)
269 call model_idxs%destroy()
270 call exg_idxs%destroy()
272 deallocate (blk_cnts)
281 integer(I4B) :: nr_headers
282 integer,
intent(out) :: map_rcv_type
284 integer(I4B) :: i, j, nr_elems, type_cnt
285 integer :: ierr, max_nr_maps
286 integer,
dimension(:),
allocatable :: types
287 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
288 integer,
dimension(:),
allocatable :: blk_cnts
291 allocate (types(max_nr_maps))
292 allocate (displs(max_nr_maps))
293 allocate (blk_cnts(max_nr_maps))
298 nr_elems = rcv_map(i)%el_maps(j)%nr_virt_elems
299 if (nr_elems == 0) cycle
301 type_cnt = type_cnt + 1
302 call mpi_get_address(rcv_map(i)%el_maps(j)%remote_elem_shift, &
303 displs(type_cnt), ierr)
304 call mpi_type_contiguous(nr_elems, mpi_integer, types(type_cnt), ierr)
305 blk_cnts(type_cnt) = 1
309 call mpi_type_create_struct(type_cnt, blk_cnts, displs, types, &
311 call mpi_type_commit(map_rcv_type, ierr)
315 deallocate (blk_cnts)
324 integer(I4B) :: stage
325 integer,
intent(out) :: body_rcv_type
327 integer(I4B) :: i, nr_types, offset
331 integer,
dimension(:),
allocatable :: types
332 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
333 integer,
dimension(:),
allocatable :: blk_cnts
335 call model_idxs%init()
339 do i = 1,
size(this%vdc_models)
340 vdc => this%vdc_models(i)%ptr
341 if (vdc%is_active .and. vdc%orig_rank == rank)
then
342 if (this%imon > 0)
then
343 write (this%imon,
'(6x,a,i0)')
"expecting model ", vdc%id
345 call model_idxs%push_back(i)
348 do i = 1,
size(this%vdc_exchanges)
349 vdc => this%vdc_exchanges(i)%ptr
350 if (vdc%is_active .and. vdc%orig_rank == rank)
then
351 if (this%imon > 0)
then
352 write (this%imon,
'(6x,a,i0)')
"expecting exchange ", vdc%id
354 call exg_idxs%push_back(i)
358 nr_types = model_idxs%size + exg_idxs%size
359 allocate (types(nr_types))
360 allocate (displs(nr_types))
361 allocate (blk_cnts(nr_types))
364 do i = 1, model_idxs%size
365 vdc => this%vdc_models(model_idxs%at(i))%ptr
366 call mpi_get_address(vdc%id, displs(i), ierr)
367 types(i) = this%create_vdc_rcv_body(vdc, rank, stage)
370 offset = model_idxs%size
371 do i = 1, exg_idxs%size
372 vdc => this%vdc_exchanges(exg_idxs%at(i))%ptr
373 call mpi_get_address(vdc%id, displs(i + offset), ierr)
374 blk_cnts(i + offset) = 1
375 types(i + offset) = this%create_vdc_rcv_body(vdc, rank, stage)
379 call mpi_type_create_struct(nr_types, blk_cnts, displs, types, &
381 call mpi_type_commit(body_rcv_type, ierr)
383 call mpi_type_free(types(i), ierr)
386 call model_idxs%destroy()
387 call exg_idxs%destroy()
390 deallocate (blk_cnts)
399 integer(I4B) :: stage
402 integer,
intent(out) :: body_snd_type
404 integer(I4B) :: i, nr_headers
407 integer,
dimension(:),
allocatable :: types
408 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
409 integer,
dimension(:),
allocatable :: blk_cnts
411 nr_headers =
size(headers)
412 allocate (types(nr_headers))
413 allocate (displs(nr_headers))
414 allocate (blk_cnts(nr_headers))
417 vdc => this%get_vdc_from_hdr(headers(i))
418 call mpi_get_address(vdc%id, displs(i), ierr)
419 types(i) = this%create_vdc_snd_body(vdc, maps(i)%el_maps, rank, stage)
424 call mpi_type_create_struct(nr_headers, blk_cnts, displs, &
425 types, body_snd_type, ierr)
426 call mpi_type_commit(body_snd_type, ierr)
428 call mpi_type_free(types(i), ierr)
433 deallocate (blk_cnts)
442 integer(I4B) :: stage
446 integer,
dimension(NR_VDC_ELEMENT_MAPS + 2) :: blk_cnts
447 integer(kind=MPI_ADDRESS_KIND),
dimension(NR_VDC_ELEMENT_MAPS + 2) :: displs
448 integer,
dimension(NR_VDC_ELEMENT_MAPS + 2) :: types
450 call mpi_get_address(vdc%id, displs(1), ierr)
451 types(1) = mpi_integer
453 call mpi_get_address(vdc%container_type, displs(2), ierr)
454 types(2) = mpi_integer
457 call mpi_get_address(vdc%element_maps(i)%nr_virt_elems, displs(i + 2), ierr)
458 types(i + 2) = mpi_integer
463 displs = displs - displs(1)
465 displs, types, new_type, ierr)
466 call mpi_type_commit(new_type, ierr)
475 integer(I4B) :: stage
478 integer(I4B) :: i, type_cnt
479 integer :: n_elems, ierr
480 integer(kind=MPI_ADDRESS_KIND) :: offset
481 integer,
dimension(:),
allocatable :: types
482 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
483 integer,
dimension(:),
allocatable :: blk_cnts
490 call mpi_get_address(vdc%id, offset, ierr)
494 n_elems = vdc%element_maps(i)%nr_virt_elems
495 if (n_elems == 0) cycle
497 type_cnt = type_cnt + 1
498 call mpi_get_address(vdc%element_maps(i)%remote_elem_shift, &
499 displs(type_cnt), ierr)
500 call mpi_type_contiguous(n_elems, mpi_integer, types(type_cnt), ierr)
501 call mpi_type_commit(types(type_cnt), ierr)
502 blk_cnts(type_cnt) = 1
503 displs(type_cnt) = displs(type_cnt) - offset
506 call mpi_type_create_struct(type_cnt, blk_cnts, displs, types, &
508 call mpi_type_commit(new_type, ierr)
511 call mpi_type_free(types(i), ierr)
516 deallocate (blk_cnts)
524 integer(I4B) :: stage
529 integer(kind=MPI_ADDRESS_KIND) :: offset
530 integer,
dimension(:),
allocatable :: types
531 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
532 integer,
dimension(:),
allocatable :: blk_cnts
537 call vdc%get_recv_items(stage, rank, items)
540 allocate (types(items%size))
541 allocate (displs(items%size))
542 allocate (blk_cnts(items%size))
544 call mpi_get_address(vdc%id, offset, ierr)
551 displs(i) = displs(i) - offset
554 call mpi_type_create_struct(items%size, blk_cnts, displs, &
555 types, new_type, ierr)
556 call mpi_type_commit(new_type, ierr)
565 deallocate (blk_cnts)
576 integer(I4B) :: stage
581 integer(kind=MPI_ADDRESS_KIND) :: offset
582 integer,
dimension(:),
allocatable :: types
583 integer(kind=MPI_ADDRESS_KIND),
dimension(:),
allocatable :: displs
584 integer,
dimension(:),
allocatable :: blk_cnts
587 integer(I4B),
dimension(:),
pointer,
contiguous :: el_map
590 call vdc%get_send_items(stage, rank, items)
593 allocate (types(items%size))
594 allocate (displs(items%size))
595 allocate (blk_cnts(items%size))
597 call mpi_get_address(vdc%id, offset, ierr)
601 if (vd%map_type > 0)
then
602 el_map => vdc_maps(vd%map_type)%remote_elem_shift
609 displs(i) = displs(i) - offset
612 call mpi_type_create_struct(items%size, blk_cnts, displs, &
613 types, new_type, ierr)
614 call mpi_type_commit(new_type, ierr)
623 deallocate (blk_cnts)
640 do i = 1,
size(this%vdc_models)
641 vdc => this%vdc_models(i)%ptr
642 if (vdc%id == header%id)
return
648 do i = 1,
size(this%vdc_exchanges)
649 vdc => this%vdc_exchanges(i)%ptr
650 if (vdc%id == header%id)
return
664 integer(kind=MPI_ADDRESS_KIND) :: el_displ
666 integer(I4B),
dimension(:),
pointer,
contiguous,
optional :: el_map_opt
669 integer(I4B),
dimension(:),
pointer,
contiguous :: el_map
672 if (
present(el_map_opt)) el_map => el_map_opt
674 if (this%imon > 0)
then
675 if (.not.
associated(el_map))
then
676 write (this%imon,
'(8x,2a,i0)') virtual_data%var_name,
' all ', &
677 virtual_data%virtual_mt%isize
679 write (this%imon,
'(8x,2a,i0)') virtual_data%var_name, &
680 ' with map size ',
size(el_map)
684 mt => virtual_data%virtual_mt
686 if (
associated(mt%intsclr))
then
688 else if (
associated(mt%aint1d))
then
690 else if (
associated(mt%dblsclr))
then
692 else if (
associated(mt%adbl1d))
then
694 else if (
associated(mt%adbl2d))
then
697 write (*, *)
'unsupported datatype in MPI messaging for ', &
698 virtual_data%var_name, virtual_data%mem_path
714 mt => virtual_data%virtual_mt
715 if (
associated(mt%intsclr))
then
718 else if (
associated(mt%dblsclr))
then
721 else if (
associated(mt%logicalsclr))
then
726 call mpi_type_free(el_type, ierr)
734 integer(kind=MPI_ADDRESS_KIND) :: el_displ
739 call mpi_get_address(mem%intsclr, el_displ, ierr)
740 el_type = mpi_integer
747 integer(kind=MPI_ADDRESS_KIND) :: el_displ
749 integer,
dimension(:),
pointer :: el_map
753 call mpi_get_address(mem%aint1d, el_displ, ierr)
754 if (
associated(el_map))
then
755 call mpi_type_create_indexed_block( &
756 size(el_map), 1, el_map, mpi_integer, el_type, ierr)
758 call mpi_type_contiguous(mem%isize, mpi_integer, el_type, ierr)
760 call mpi_type_commit(el_type, ierr)
766 integer(kind=MPI_ADDRESS_KIND) :: el_displ
771 call mpi_get_address(mem%dblsclr, el_displ, ierr)
772 el_type = mpi_double_precision
779 integer(kind=MPI_ADDRESS_KIND) :: el_displ
781 integer,
dimension(:),
pointer :: el_map
785 call mpi_get_address(mem%adbl1d, el_displ, ierr)
786 if (
associated(el_map))
then
787 call mpi_type_create_indexed_block( &
788 size(el_map), 1, el_map, mpi_double_precision, el_type, ierr)
790 call mpi_type_contiguous(mem%isize, mpi_double_precision, el_type, ierr)
792 call mpi_type_commit(el_type, ierr)
798 integer(kind=MPI_ADDRESS_KIND) :: el_displ
800 integer,
dimension(:),
pointer :: el_map
803 integer :: entry_type
805 call mpi_get_address(mem%adbl2d, el_displ, ierr)
806 if (
associated(el_map))
then
807 call mpi_type_contiguous( &
808 size(mem%adbl2d, dim=1), mpi_double_precision, entry_type, ierr)
809 call mpi_type_create_indexed_block( &
810 size(el_map), 1, el_map, entry_type, el_type, ierr)
812 call mpi_type_contiguous(mem%isize, mpi_double_precision, el_type, ierr)
814 call mpi_type_commit(el_type, ierr)
This module defines variable data types.
subroutine get_mpitype_for_dbl2d(mem, el_displ, el_type, el_map)
subroutine set_monitor(this, imon)
subroutine release_data(this)
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 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.