453
454
455
464 use mpi
465 implicit none
466 type(GT_HISTORY), intent(inout):: hst
467 logical, intent(out), optional:: err
468 integer:: i, j, k, ra, numdims
469 integer:: err_mpi, st_mpi(MPI_STATUS_SIZE)
470 integer, allocatable:: index_all_buf(:)
471 character(STRING):: url, dimname
472 real:: accuracy
473 real(DP):: zero_limit
474 logical:: flag_hit
475 real(DP), pointer:: large =>null(), small =>null()
476 integer:: stat
477 character(STRING):: cause_c
478 character(*), parameter:: subname = 'gtmpi_axis_register'
479 character(*), parameter:: subnameup = 'HistoryPut'
480 continue
482 cause_c = ""
484 numdims = size( hst % dimvars )
485 accuracy = 1.0e-3
486 zero_limit = 1.0e-6_dp
487 allocate( hst % mpi_gthr_info(numdims) )
488
489
490
491 do i = 1, numdims
492 if ( hst % unlimited_index == i ) cycle
493 if ( hst % time_nv_index == i ) cycle
494 if ( hst % mpi_myrank == 0 ) then
495 call inquire( hst % dimvars(i), &
496 & url = url )
498 & var = dimname )
499 call mpi_bcast( dimname,
string, mpi_character, 0, mpi_comm_world, err_mpi )
500 else
501 call mpi_bcast( dimname,
string, mpi_character, 0, mpi_comm_world, err_mpi )
502 end if
503 if ( hst % mpi_myrank == 0 ) then
504 if ( hst % mpi_dimdata_all(i) % length < 0 ) then
506 & 'data of axis (%c) in whole area is lack. ' // &
507 & 'Specify the data by "HistoryPutAxisMPI" explicitly.', &
508 & c1 = trim(dimname) )
510 cause_c = dimname
511 goto 999
512 end if
513 end if
514 if ( hst % mpi_dimdata_each(i) % length < 0 ) then
516 & 'data of axis (%c) on node (%d) is lack. ' // &
517 & 'Specify the data by "HistoryPut" explicitly.', &
518 & c1 = trim(dimname), i = (/ hst % mpi_myrank /) )
520 cause_c = dimname
521 goto 999
522 end if
523 end do
524
525
526
527 do i = 1, numdims
528 if ( hst % unlimited_index == i ) cycle
529 if ( hst % time_nv_index == i ) cycle
530 allocate( &
531 & hst % mpi_gthr_info(i) % length( 0: hst % mpi_nprocs - 1 ) )
532 allocate( &
533 & hst % mpi_gthr_info(i) % &
534 & index_all( 0: hst % mpi_nprocs - 1, &
535 & hst % mpi_dimdata_all(i) % length ) )
536 hst % mpi_gthr_info(i) % index_all(:,:) = -1
537 hst % mpi_gthr_info(i) % length( hst % mpi_myrank ) = &
538 & hst % mpi_dimdata_each(i) % length
539 k = 1
540 do j = 1, hst % mpi_dimdata_all(i) % length
541 flag_hit = .false.
542 if ( abs( hst % mpi_dimdata_all(i) % a_Axis(j) ) > &
543 & abs( hst % mpi_dimdata_each(i) % a_Axis(k) ) ) then
544 large => hst % mpi_dimdata_all(i) % a_Axis(j)
545 small => hst % mpi_dimdata_each(i) % a_Axis(k)
546 else
547 large => hst % mpi_dimdata_each(i) % a_Axis(k)
548 small => hst % mpi_dimdata_all(i) % a_Axis(j)
549 end if
550 if ( large > 0.0_dp .and. small < 0.0_dp &
551 & .or. large < 0.0_dp .and. small > 0.0_dp ) then
552 cycle
553 end if
554 if ( abs( large ) < zero_limit .and. abs( small ) < zero_limit ) then
555 flag_hit = .true.
556 end if
557 if ( .not. flag_hit .and. &
558 & abs( ( large / small ) - 1.0_dp ) < accuracy ) then
559 flag_hit = .true.
560 end if
561 if ( flag_hit ) then
562 hst % mpi_gthr_info(i) % index_all ( hst % mpi_myrank, k ) = j
563 k = k + 1
564 end if
565 if ( k > hst % mpi_gthr_info(i) % length( hst % mpi_myrank ) ) exit
566 end do
567 end do
568
569
570
571 if ( hst % mpi_myrank == 0 ) then
572 do i = 1, numdims
573 if ( hst % unlimited_index == i ) cycle
574 if ( hst % time_nv_index == i ) cycle
575 allocate( index_all_buf( hst % mpi_dimdata_all(i) % length ) )
576 do ra = 1, hst % mpi_nprocs - 1
577 call mpi_recv( &
578 & index_all_buf, &
579 & hst % mpi_dimdata_all(i) % length, &
580 & mpi_integer, ra, 0, mpi_comm_world, st_mpi, err_mpi )
581 hst % mpi_gthr_info(i) % index_all (ra,:) = index_all_buf(:)
582 end do
583 deallocate( index_all_buf )
584 do ra = 1, hst % mpi_nprocs - 1
585 call mpi_recv( &
586 & hst % mpi_gthr_info(i) % length (ra), &
587 & 1, &
588 & mpi_integer, ra, 0, mpi_comm_world, st_mpi, err_mpi )
589 end do
590 end do
591 else
592 do i = 1, numdims
593 if ( hst % unlimited_index == i ) cycle
594 if ( hst % time_nv_index == i ) cycle
595 allocate( index_all_buf( hst % mpi_dimdata_all(i) % length ) )
596 index_all_buf(:) = hst % mpi_gthr_info(i) % index_all (hst % mpi_myrank,:)
597 call mpi_send( &
598 & index_all_buf, &
599 & hst % mpi_dimdata_all(i) % length, &
600 & mpi_integer, 0, 0, mpi_comm_world, err_mpi )
601 deallocate( index_all_buf )
602 call mpi_send( &
603 & hst % mpi_gthr_info(i) % length (hst % mpi_myrank), &
604 & 1, &
605 & mpi_integer, 0, 0, mpi_comm_world, err_mpi )
606 end do
607 end if
608
609
610
611 if ( hst % mpi_myrank == 0 ) then
612 do ra = 0, hst % mpi_nprocs - 1
613 do i = 1, numdims
614 if ( hst % unlimited_index == i ) cycle
615 if ( hst % time_nv_index == i ) cycle
616 end do
617 end do
618 do ra = 0, hst % mpi_nprocs - 1
619 do i = 1, numdims
620 if ( hst % unlimited_index == i ) cycle
621 if ( hst % time_nv_index == i ) cycle
622 do j = 1, hst % mpi_gthr_info(i) % length (ra)
623 if ( hst % mpi_gthr_info(i) % index_all (ra,j) < 1 ) then
624 call inquire( hst % dimvars(i), &
625 & url = url )
627 & var = dimname )
629 & 'data of axis (%c) on node (%d) or ' // &
630 & 'in whole area are lack. ' // &
631 & 'Specify the data by "HistoryPut" or "HistoryPutAxisMPI" explicitly.', &
632 & c1 = trim(dimname), i = (/ ra /) )
634 cause_c = dimname
635 goto 999
636 end if
637 end do
638 end do
639 end do
640 end if
641999 continue
integer, parameter, public hst_empinoaxisdata
integer, parameter, public dp
Double Precision Real number
Variable URL string parser.