Constructs the message bodies' MPI datatypes for a unit (a solution) and a given stage. This is done in a sequence of 6 steps (distributed over 3 phases):
step 1: Receive headers from remote addresses requesting data from virtual data containers (models, exchanges, ...) local to this process step 2: Send headers to remote addresses to indicate for which virtual data containers (models, exchanges, ...) data is requested
step 3: Based on the received headers, receive element maps (which elements are to be sent from a contiguous array) for outgoing data step 4: Send element maps to remote addresses to specify incoming data
step 5: Construct the message receive body based on the virtual data items in the virtual data containers, and cache
step 6: Construct the message send body, based on received header data and and maps, from the virtual data containers, and cache
367 class(MpiRouterType) :: this
369 integer(I4B) :: stage
370 integer,
dimension(:) :: body_snd_t
371 integer,
dimension(:) :: body_rcv_t
373 integer(I4B) :: i, j, k
377 integer,
dimension(:),
allocatable :: rcv_req
378 integer,
dimension(:),
allocatable :: snd_req
379 integer,
dimension(:, :),
allocatable :: rcv_stat
381 integer(I4B) :: max_headers
382 type(VdcHeaderType),
dimension(:, :),
allocatable :: headers
383 integer,
dimension(:),
allocatable :: hdr_rcv_t
384 integer,
dimension(:),
allocatable :: hdr_snd_t
385 integer,
dimension(:),
allocatable :: hdr_rcv_cnt
387 type(VdcReceiverMapsType),
dimension(:, :),
allocatable :: rcv_maps
388 integer,
dimension(:),
allocatable :: map_rcv_t
389 integer,
dimension(:),
allocatable :: map_snd_t
392 allocate (rcv_req(this%receivers%size))
393 allocate (snd_req(this%senders%size))
394 allocate (rcv_stat(mpi_status_size, this%receivers%size))
397 rcv_req = mpi_request_null
398 snd_req = mpi_request_null
401 max_headers =
size(this%rte_models) +
size(this%rte_exchanges)
402 allocate (hdr_rcv_t(this%receivers%size))
403 allocate (hdr_snd_t(this%senders%size))
404 allocate (headers(max_headers, this%receivers%size))
405 allocate (hdr_rcv_cnt(this%receivers%size))
408 allocate (map_snd_t(this%senders%size))
409 allocate (map_rcv_t(this%receivers%size))
410 allocate (rcv_maps(max_headers, this%receivers%size))
412 if (this%enable_monitor)
then
413 write (this%imon,
'(2x,a)')
"== communicating headers =="
417 do i = 1, this%receivers%size
418 rnk = this%receivers%at(i)
419 if (this%enable_monitor)
then
420 write (this%imon,
'(4x,a,i0)')
"Ireceive header from process: ", rnk
422 call this%message_builder%create_header_rcv(hdr_rcv_t(i))
423 call mpi_irecv(headers(:, i), max_headers, hdr_rcv_t(i), rnk, stage, &
424 this%mpi_world%comm, rcv_req(i), ierr)
429 do i = 1, this%senders%size
430 rnk = this%senders%at(i)
431 if (this%enable_monitor)
then
432 write (this%imon,
'(4x,a,i0)')
"send header to process: ", rnk
434 call this%message_builder%create_header_snd(rnk, stage, hdr_snd_t(i))
435 call mpi_isend(mpi_bottom, 1, hdr_snd_t(i), rnk, stage, &
436 this%mpi_world%comm, snd_req(i), ierr)
441 call mpi_waitall(this%receivers%size, rcv_req, rcv_stat, ierr)
445 rcv_req = mpi_request_null
446 snd_req = mpi_request_null
449 do i = 1, this%receivers%size
450 call mpi_get_count(rcv_stat(:, i), hdr_rcv_t(i), hdr_rcv_cnt(i), ierr)
452 if (this%enable_monitor)
then
453 rnk = this%senders%at(i)
454 write (this%imon,
'(4x,a,i0)')
"received headers from process: ", rnk
455 write (this%imon,
'(6x,a)')
"expecting data for:"
456 do j = 1, hdr_rcv_cnt(i)
457 write (this%imon,
'(6x,a,i0,a,a)')
"id: ", headers(j, i)%id, &
458 " type: ", trim(vdc_type_to_str(headers(j, i)%container_type))
459 write (this%imon,
'(6x,a,99i6)')
"map sizes: ", headers(j, i)%map_sizes
465 do i = 1, this%receivers%size
466 call mpi_type_free(hdr_rcv_t(i), ierr)
468 do i = 1, this%senders%size
469 call mpi_type_free(hdr_snd_t(i), ierr)
472 if (this%enable_monitor)
then
473 write (this%imon,
'(2x,a)')
"== communicating maps =="
477 do i = 1, this%receivers%size
478 do j = 1, hdr_rcv_cnt(i)
479 call rcv_maps(j, i)%create(headers(j, i)%map_sizes)
484 do i = 1, this%receivers%size
485 rnk = this%receivers%at(i)
486 if (this%enable_monitor)
then
487 write (this%imon,
'(4x,a,i0)')
"Ireceive maps from process: ", rnk
490 call this%message_builder%create_map_rcv(rcv_maps(:, i), hdr_rcv_cnt(i), &
492 call mpi_irecv(mpi_bottom, 1, map_rcv_t(i), rnk, stage, &
493 this%mpi_world%comm, rcv_req(i), ierr)
498 do i = 1, this%senders%size
499 rnk = this%senders%at(i)
500 if (this%enable_monitor)
then
501 write (this%imon,
'(4x,a,i0)')
"send map to process: ", rnk
504 call this%message_builder%create_map_snd(rnk, stage, map_snd_t(i))
505 call mpi_isend(mpi_bottom, 1, map_snd_t(i), rnk, stage, &
506 this%mpi_world%comm, snd_req(i), ierr)
511 call mpi_waitall(this%receivers%size, rcv_req, rcv_stat, ierr)
515 if (this%enable_monitor)
then
516 do i = 1, this%receivers%size
517 rnk = this%receivers%at(i)
518 write (this%imon,
'(4x,a,i0)')
"received maps from process: ", rnk
519 do j = 1, hdr_rcv_cnt(i)
520 write (this%imon,
'(6x,a,i0,a,a)')
"id: ", headers(j, i)%id, &
521 " type: ", trim(vdc_type_to_str(headers(j, i)%container_type))
522 do k = 1, nr_vdc_element_maps
523 write (this%imon,
'(8x,i0, a,i0)') k,
" nr. elements: ", &
524 rcv_maps(j, i)%el_maps(k)%nr_virt_elems
525 if (rcv_maps(j, i)%el_maps(k)%nr_virt_elems > 0)
then
526 write (this%imon,
'(8x,*(i6))') &
527 rcv_maps(j, i)%el_maps(k)%remote_elem_shift
535 do i = 1, this%receivers%size
536 call mpi_type_free(map_rcv_t(i), ierr)
538 do i = 1, this%senders%size
539 call mpi_type_free(map_snd_t(i), ierr)
542 if (this%enable_monitor)
then
543 write (this%imon,
'(2x,a)')
"== composing message bodies =="
547 do i = 1, this%senders%size
548 rnk = this%senders%at(i)
549 if (this%enable_monitor)
then
550 write (this%imon,
'(4x,a,i0)')
"build recv body for process: ", rnk
553 call this%message_builder%create_body_rcv(rnk, stage, body_rcv_t(i))
554 call this%msg_cache%put(unit, rnk, stage, mpi_bdy_rcv, body_rcv_t(i))
558 do i = 1, this%receivers%size
559 rnk = this%receivers%at(i)
560 if (this%enable_monitor)
then
561 write (this%imon,
'(4x,a,i0)')
"build send body for process: ", rnk
564 call this%message_builder%create_body_snd( &
565 rnk, stage, headers(1:hdr_rcv_cnt(i), i), &
566 rcv_maps(:, i), body_snd_t(i))
567 call this%msg_cache%put(unit, rnk, stage, mpi_bdy_snd, body_snd_t(i))
571 do i = 1, this%receivers%size
572 do j = 1, hdr_rcv_cnt(i)
573 call rcv_maps(j, i)%destroy()
577 deallocate (rcv_req, snd_req, rcv_stat)
578 deallocate (hdr_rcv_t, hdr_snd_t, hdr_rcv_cnt)
580 deallocate (map_rcv_t, map_snd_t)
581 deallocate (rcv_maps)