3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549 integer, intent(in) :: ng, model, Npts
3550
3551 integer, intent(in), optional :: InpComm
3552
3553 real(r8), intent(in) :: Aspv
3554
3555 real(r8), intent(inout) :: A(Npts)
3556
3557
3558
3559 integer :: Lstr, MyCOMM, MyError, Nnodes, Serror
3560 integer :: i, rank, request
3561
3562 integer, dimension(MPI_STATUS_SIZE) :: status
3563
3564# if defined COLLECT_ALLGATHER
3565 real(r8), dimension(Npts,0:NtileI(ng)*NtileJ(ng)-1) :: Arecv
3566# elif defined COLLECT_ALLREDUCE
3567 real(r8), dimension(Npts) :: Asend
3568# else
3569 real(r8), allocatable :: Arecv(:)
3570# endif
3571
3572 character (len=MPI_MAX_ERROR_STRING) :: string
3573
3574 character (len=*), parameter :: MyFile = &
3575 & __FILE__//", mp_collect_f"
3576
3577# ifdef PROFILE
3578
3579
3580
3581
3582
3583 CALL wclock_on (ng, model, 69, __line__, myfile)
3584# endif
3585# ifdef MPI
3586
3587
3588
3589
3590
3591 IF (PRESENT(inpcomm)) THEN
3592 mycomm=inpcomm
3593 ELSE
3594 mycomm=ocn_comm_world
3595 END IF
3596# endif
3597
3598
3599
3600
3601
3602
3603
3604# if defined COLLECT_ALLGATHER
3605 bmemmax(ng)=max(bmemmax(ng), real(SIZE(arecv)*kind(a),r8))
3606# else
3607 bmemmax(ng)=max(bmemmax(ng), real(npts*kind(a),r8))
3608# endif
3609
3610# if defined COLLECT_ALLGATHER
3611
3612 CALL mpi_allgather (a, npts, mp_float, arecv, npts, mp_float, &
3613 & mycomm, myerror)
3614 IF (myerror.ne.mpi_success) THEN
3615 CALL mpi_error_string (myerror, string, lstr, serror)
3616 lstr=len_trim(string)
3617 WRITE (stdout,10) 'MPI_ALLGATHER', myrank, myerror, &
3618 & string(1:lstr)
3619 exit_flag=2
3620 RETURN
3621 END IF
3622
3623
3624
3625 nnodes=ntilei(ng)*ntilej(ng)-1
3626 IF (aspv.eq.0.0_r8) THEN
3627 DO i=1,npts
3628 a(i)=0.0_r8
3629 DO rank=0,nnodes
3630 a(i)=a(i)+arecv(i,rank)
3631 END DO
3632 END DO
3633 ELSE
3634 DO i=1,npts
3635 DO rank=0,nnodes
3636 IF (arecv(i,rank).ne.aspv) THEN
3637 a(i)=arecv(i,rank)
3638 END IF
3639 END DO
3640 END DO
3641 END IF
3642# elif defined COLLECT_ALLREDUCE
3643
3644
3645
3646 DO i=1,npts
3647 asend(i)=a(i)
3648 END DO
3649
3650
3651
3652 CALL mpi_allreduce (asend, a, npts, mp_float, mpi_sum, &
3653 & mycomm, myerror)
3654 IF (myerror.ne.mpi_success) THEN
3655 CALL mpi_error_string (myerror, string, lstr, serror)
3656 lstr=len_trim(string)
3657 WRITE (stdout,10) 'MPI_ALLREDUCE', myrank, myerror, &
3658 & string(1:lstr)
3659 exit_flag=2
3660 RETURN
3661 END IF
3662# else
3663
3664 IF (myrank.eq.mymaster) THEN
3665
3666
3667
3668 IF (.not.allocated(arecv)) THEN
3669 allocate (arecv(npts))
3670 END IF
3671
3672
3673
3674
3675 DO rank=1,ntilei(ng)*ntilej(ng)-1
3676 CALL mpi_irecv (arecv, npts, mp_float, rank, rank+5, &
3677 & mycomm, request, myerror)
3678 CALL mpi_wait (request, status, myerror)
3679 IF (myerror.ne.mpi_success) THEN
3680 CALL mpi_error_string (myerror, string, lstr, serror)
3681 lstr=len_trim(string)
3682 WRITE (stdout,10) 'MPI_IRECV', rank, myerror, string(1:lstr)
3683 exit_flag=2
3684 RETURN
3685 END IF
3686 DO i=1,npts
3687 a(i)=a(i)+arecv(i)
3688 END DO
3689 END DO
3690 deallocate (arecv)
3691
3692
3693
3694 ELSE
3695 CALL mpi_isend (a, npts, mp_float, mymaster, myrank+5, &
3696 & mycomm, request, myerror)
3697 CALL mpi_wait (request, status, myerror)
3698 IF (myerror.ne.mpi_success) THEN
3699 CALL mpi_error_string (myerror, string, lstr, serror)
3700 lstr=len_trim(string)
3701 WRITE (stdout,10) 'MPI_ISEND', myrank, myerror, string(1:lstr)
3702 exit_flag=2
3703 RETURN
3704 END IF
3705 END IF
3706
3707
3708
3709 CALL mpi_bcast (a, npts, mp_float, mymaster, mycomm, myerror)
3710 IF (myerror.ne.mpi_success) THEN
3711 CALL mpi_error_string (myerror, string, lstr, serror)
3712 lstr=len_trim(string)
3713 WRITE (stdout,10) 'MPI_BCAST', myrank, myerror, string(1:lstr)
3714 exit_flag=2
3715 RETURN
3716 END IF
3717# endif
3718 10 FORMAT (/,' MP_COLLECT_F - error during ',a,' call, Task = ', &
3719 & i3.3,' Error = ',i3,/,14x,a)
3720
3721# ifdef PROFILE
3722
3723
3724
3725
3726
3727 CALL wclock_off (ng, model, 69, __line__, myfile)
3728# endif
3729
3730 RETURN
recursive subroutine wclock_off(ng, model, region, line, routine)
recursive subroutine wclock_on(ng, model, region, line, routine)