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
377 class(MpiRouterType) :: this
379 integer(I4B) :: stage
380 integer,
dimension(:) :: body_snd_t
381 integer,
dimension(:) :: body_rcv_t
383 integer(I4B) :: i, j, k
387 integer,
dimension(:),
allocatable :: rcv_req
388 integer,
dimension(:),
allocatable :: snd_req
389 integer,
dimension(:, :),
allocatable :: rcv_stat
391 integer(I4B) :: max_headers
392 type(VdcHeaderType),
dimension(:, :),
allocatable :: headers
393 integer,
dimension(:),
allocatable :: hdr_rcv_t
394 integer,
dimension(:),
allocatable :: hdr_snd_t
395 integer,
dimension(:),
allocatable :: hdr_rcv_cnt
397 type(VdcReceiverMapsType),
dimension(:, :),
allocatable :: rcv_maps
398 integer,
dimension(:),
allocatable :: map_rcv_t
399 integer,
dimension(:),
allocatable :: map_snd_t
402 allocate (rcv_req(this%receivers%size))
403 allocate (snd_req(this%senders%size))
404 allocate (rcv_stat(mpi_status_size, this%receivers%size))
407 rcv_req = mpi_request_null
408 snd_req = mpi_request_null
411 max_headers =
size(this%rte_models) +
size(this%rte_exchanges)
412 allocate (hdr_rcv_t(this%receivers%size))
413 allocate (hdr_snd_t(this%senders%size))
414 allocate (headers(max_headers, this%receivers%size))
415 allocate (hdr_rcv_cnt(this%receivers%size))
418 allocate (map_snd_t(this%senders%size))
419 allocate (map_rcv_t(this%receivers%size))
420 allocate (rcv_maps(max_headers, this%receivers%size))
422 if (this%enable_monitor)
then
423 write (this%imon,
'(2x,a)')
"== communicating headers =="
427 do i = 1, this%receivers%size
428 rnk = this%receivers%at(i)
429 if (this%enable_monitor)
then
430 write (this%imon,
'(4x,a,i0)')
"Ireceive header from process: ", rnk
432 call this%message_builder%create_header_rcv(hdr_rcv_t(i))
433 call mpi_irecv(headers(:, i), max_headers, hdr_rcv_t(i), rnk, stage, &
434 this%mpi_world%comm, rcv_req(i), ierr)
439 do i = 1, this%senders%size
440 rnk = this%senders%at(i)
441 if (this%enable_monitor)
then
442 write (this%imon,
'(4x,a,i0)')
"send header to process: ", rnk
444 call this%message_builder%create_header_snd(rnk, stage, hdr_snd_t(i))
445 call mpi_isend(mpi_bottom, 1, hdr_snd_t(i), rnk, stage, &
446 this%mpi_world%comm, snd_req(i), ierr)
451 call g_prof%start(
"MPI_WaitAll ("//trim(stg_to_str(stage))//
")", &
452 this%tmr_mpi_wait(stage, unit + 1))
453 call mpi_waitall(this%receivers%size, rcv_req, rcv_stat, ierr)
454 call g_prof%stop(this%tmr_mpi_wait(stage, unit + 1))
458 rcv_req = mpi_request_null
459 snd_req = mpi_request_null
462 do i = 1, this%receivers%size
463 call mpi_get_count(rcv_stat(:, i), hdr_rcv_t(i), hdr_rcv_cnt(i), ierr)
465 if (this%enable_monitor)
then
466 rnk = this%senders%at(i)
467 write (this%imon,
'(4x,a,i0)')
"received headers from process: ", rnk
468 write (this%imon,
'(6x,a)')
"expecting data for:"
469 do j = 1, hdr_rcv_cnt(i)
470 write (this%imon,
'(6x,a,i0,a,a)')
"id: ", headers(j, i)%id, &
471 " type: ", trim(vdc_type_to_str(headers(j, i)%container_type))
472 write (this%imon,
'(6x,a,99i6)')
"map sizes: ", headers(j, i)%map_sizes
478 do i = 1, this%receivers%size
479 call mpi_type_free(hdr_rcv_t(i), ierr)
481 do i = 1, this%senders%size
482 call mpi_type_free(hdr_snd_t(i), ierr)
485 if (this%enable_monitor)
then
486 write (this%imon,
'(2x,a)')
"== communicating maps =="
490 do i = 1, this%receivers%size
491 do j = 1, hdr_rcv_cnt(i)
492 call rcv_maps(j, i)%create(headers(j, i)%map_sizes)
497 do i = 1, this%receivers%size
498 rnk = this%receivers%at(i)
499 if (this%enable_monitor)
then
500 write (this%imon,
'(4x,a,i0)')
"Ireceive maps from process: ", rnk
503 call this%message_builder%create_map_rcv(rcv_maps(:, i), hdr_rcv_cnt(i), &
505 call mpi_irecv(mpi_bottom, 1, map_rcv_t(i), rnk, stage, &
506 this%mpi_world%comm, rcv_req(i), ierr)
511 do i = 1, this%senders%size
512 rnk = this%senders%at(i)
513 if (this%enable_monitor)
then
514 write (this%imon,
'(4x,a,i0)')
"send map to process: ", rnk
517 call this%message_builder%create_map_snd(rnk, stage, map_snd_t(i))
518 call mpi_isend(mpi_bottom, 1, map_snd_t(i), rnk, stage, &
519 this%mpi_world%comm, snd_req(i), ierr)
524 call g_prof%start(
"MPI_WaitAll ("//trim(stg_to_str(stage))//
")", &
525 this%tmr_mpi_wait(stage, unit + 1))
526 call mpi_waitall(this%receivers%size, rcv_req, rcv_stat, ierr)
527 call g_prof%stop(this%tmr_mpi_wait(stage, unit + 1))
531 if (this%enable_monitor)
then
532 do i = 1, this%receivers%size
533 rnk = this%receivers%at(i)
534 write (this%imon,
'(4x,a,i0)')
"received maps from process: ", rnk
535 do j = 1, hdr_rcv_cnt(i)
536 write (this%imon,
'(6x,a,i0,a,a)')
"id: ", headers(j, i)%id, &
537 " type: ", trim(vdc_type_to_str(headers(j, i)%container_type))
538 do k = 1, nr_vdc_element_maps
539 write (this%imon,
'(8x,i0, a,i0)') k,
" nr. elements: ", &
540 rcv_maps(j, i)%el_maps(k)%nr_virt_elems
541 if (rcv_maps(j, i)%el_maps(k)%nr_virt_elems > 0)
then
542 write (this%imon,
'(8x,*(i6))') &
543 rcv_maps(j, i)%el_maps(k)%remote_elem_shift
551 do i = 1, this%receivers%size
552 call mpi_type_free(map_rcv_t(i), ierr)
554 do i = 1, this%senders%size
555 call mpi_type_free(map_snd_t(i), ierr)
558 if (this%enable_monitor)
then
559 write (this%imon,
'(2x,a)')
"== composing message bodies =="
563 do i = 1, this%senders%size
564 rnk = this%senders%at(i)
565 if (this%enable_monitor)
then
566 write (this%imon,
'(4x,a,i0)')
"build recv body for process: ", rnk
569 call this%message_builder%create_body_rcv(rnk, stage, body_rcv_t(i))
570 call this%msg_cache%put(unit, rnk, stage, mpi_bdy_rcv, body_rcv_t(i))
574 do i = 1, this%receivers%size
575 rnk = this%receivers%at(i)
576 if (this%enable_monitor)
then
577 write (this%imon,
'(4x,a,i0)')
"build send body for process: ", rnk
580 call this%message_builder%create_body_snd( &
581 rnk, stage, headers(1:hdr_rcv_cnt(i), i), &
582 rcv_maps(:, i), body_snd_t(i))
583 call this%msg_cache%put(unit, rnk, stage, mpi_bdy_snd, body_snd_t(i))
587 do i = 1, this%receivers%size
588 do j = 1, hdr_rcv_cnt(i)
589 call rcv_maps(j, i)%destroy()
593 deallocate (rcv_req, snd_req, rcv_stat)
594 deallocate (hdr_rcv_t, hdr_snd_t, hdr_rcv_cnt)
596 deallocate (map_rcv_t, map_snd_t)
597 deallocate (rcv_maps)