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
subroutine, public storeerror(number, where, err, cause_c, cause_i)
integer, parameter, public dc_noerr
エラー等を保持
integer, parameter, public hst_empinoaxisdata
subroutine, public dbgmessage(fmt, i, r, d, l, n, c1, c2, c3, ca)
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
integer, parameter, public string
文字列を保持する 文字型変数の種別型パラメタ
integer, parameter, public dp
倍精度実数型変数