mirror of
https://github.com/sfilippone/psblas3.git
synced 2026-10-16 10:52:08 +00:00
psblas3:
base/internals/psi_cswapdata.F90 base/internals/psi_dswapdata.F90 base/internals/psi_iswapdata.F90 base/internals/psi_sswapdata.F90 base/internals/psi_zswapdata.F90 base/modules/psb_i_base_vect_mod.f90 base/modules/psi_c_mod.f90 base/modules/psi_d_mod.f90 base/modules/psi_i_mod.f90 base/modules/psi_s_mod.f90 base/modules/psi_z_mod.f90 New swapdata.
This commit is contained in:
+111
-590
@@ -1038,7 +1038,7 @@ subroutine psi_cswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
class(psb_c_base_vect_type) :: y
|
||||
complex(psb_spk_) :: beta
|
||||
complex(psb_spk_), target :: work(:)
|
||||
type(psb_desc_type),target :: desc_a
|
||||
type(psb_desc_type), target :: desc_a
|
||||
integer(psb_ipk_), optional :: data
|
||||
|
||||
! locals
|
||||
@@ -1073,7 +1073,6 @@ subroutine psi_cswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
data_ = psb_comm_halo_
|
||||
end if
|
||||
|
||||
!!$ call desc_a%get_list(data_,d_idx,totxch,idxr,idxs,info)
|
||||
call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
|
||||
if (info /= psb_success_) then
|
||||
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list')
|
||||
@@ -1105,381 +1104,11 @@ end subroutine psi_cswapdata_vect
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_cswapidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_cswapidx_vect
|
||||
use psb_error_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_c_base_vect_mod
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
implicit none
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
|
||||
integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
class(psb_c_base_vect_type) :: y
|
||||
complex(psb_spk_) :: beta
|
||||
complex(psb_spk_), target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
& proc_to_comm, p2ptag, p2pstat(mpi_status_size), iret
|
||||
integer(psb_mpik_), allocatable, dimension(:) :: bsdidx, brvidx,&
|
||||
& sdsz, rvsz, prcid, rvhd, sdhd
|
||||
integer(psb_ipk_) :: nesd, nerv,&
|
||||
& err_act, i, idx_pt, totsnd_, totrcv_,&
|
||||
& snd_pt, rcv_pt, pnti, n
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
|
||||
complex(psb_spk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
volatile :: sndbuf, rcvbuf
|
||||
#endif
|
||||
character(len=20) :: name
|
||||
|
||||
info=psb_success_
|
||||
name='psi_swap_datav'
|
||||
call psb_erractionsave(err_act)
|
||||
ictxt = iictxt
|
||||
icomm = iicomm
|
||||
call psb_info(ictxt,me,np)
|
||||
if (np == -1) then
|
||||
info=psb_err_context_error_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
n=1
|
||||
|
||||
swap_mpi = iand(flag,psb_swap_mpi_) /= 0
|
||||
swap_sync = iand(flag,psb_swap_sync_) /= 0
|
||||
swap_send = iand(flag,psb_swap_send_) /= 0
|
||||
swap_recv = iand(flag,psb_swap_recv_) /= 0
|
||||
do_send = swap_mpi .or. swap_sync .or. swap_send
|
||||
do_recv = swap_mpi .or. swap_sync .or. swap_recv
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(nesd,idx(idx_pt:idx_pt+nesd-1),&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_c_spk_,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_c_spk_,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_complex_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_c_spk_,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_complex_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_spk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_spk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_complex_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(nerv,idx(idx_pt:idx_pt+nerv-1),&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
end subroutine psi_cswapidx_vect
|
||||
|
||||
|
||||
|
||||
!
|
||||
!
|
||||
! Subroutine: psi_cswapvidx_vect
|
||||
! Data exchange among processes.
|
||||
!
|
||||
! Case where the index vector is also encapsulated.
|
||||
!
|
||||
! The real workhorse: the outer routines will only choose the index list
|
||||
! this one takes the index list and does the actual exchange.
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_cswap_vidx_vect
|
||||
use psb_error_mod
|
||||
use psb_realloc_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_c_base_vect_mod
|
||||
@@ -1496,8 +1125,8 @@ subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
class(psb_c_base_vect_type) :: y
|
||||
complex(psb_spk_) :: beta
|
||||
complex(psb_spk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
@@ -1510,7 +1139,7 @@ subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
logical, parameter :: usersend=.false., debug=.false.
|
||||
|
||||
complex(psb_spk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
@@ -1541,159 +1170,65 @@ subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
call idx%sync()
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
if (debug) write(*,*) me,'Internal buffer'
|
||||
if (do_send) then
|
||||
if (allocated(y%comid)) then
|
||||
!
|
||||
! Unfinished communication? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
if (debug) write(*,*) me,'do_send start'
|
||||
call y%new_buffer(size(idx%v),info)
|
||||
call y%new_comid(totxch,info)
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
|
||||
p2ptag = psb_complex_swap_tag
|
||||
call mpi_irecv(y%combuf(rcv_pt),nerv,&
|
||||
& psb_mpi_c_spk_,prcid(i),&
|
||||
& p2ptag, icomm,y%comid(i,2),iret)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
if (debug) write(*,*) me,' Gather '
|
||||
!
|
||||
! Then gather for sending.
|
||||
!
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(idx_pt,nesd,idx,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
call y%gth(idx_pt,nesd,idx)
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
call y%device_wait()
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_c_spk_,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_c_spk_,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_complex_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_c_spk_,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
if (debug) write(*,*) me,' isend'
|
||||
!
|
||||
! Then send
|
||||
!
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
@@ -1702,48 +1237,70 @@ subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_complex_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_spk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_spk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call mpi_isend(y%combuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_spk_,prcid(i),&
|
||||
& p2ptag,icomm,y%comid(i,1),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
if (debug) write(*,*) me,' do_Recv'
|
||||
if (.not.allocated(y%comid)) then
|
||||
!
|
||||
! No matching send? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
|
||||
if (debug) write(*,*) me,' wait'
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_complex_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
if (proc_to_comm /= me)then
|
||||
if (nesd>0) then
|
||||
call mpi_wait(y%comid(i,1),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
if (nerv>0) then
|
||||
call mpi_wait(y%comid(i,2),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
@@ -1751,48 +1308,12 @@ subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
y%combuf(rcv_pt:rcv_pt+nerv-1) = y%combuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
if (debug) write(*,*) me,' scatter'
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
@@ -1801,36 +1322,36 @@ subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(idx_pt,nerv,idx,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
|
||||
call y%sct(rcv_pt,nerv,idx,beta)
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
if (debug) write(*,*) me,' wait'
|
||||
call y%device_wait()
|
||||
if (debug) write(*,*) me,' free buffer'
|
||||
call y%free_buffer(info)
|
||||
if (info == 0) call y%free_comid(info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug) write(*,*) me,' done'
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
return
|
||||
end subroutine psi_cswap_vidx_vect
|
||||
|
||||
|
||||
+111
-590
@@ -1038,7 +1038,7 @@ subroutine psi_dswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
class(psb_d_base_vect_type) :: y
|
||||
real(psb_dpk_) :: beta
|
||||
real(psb_dpk_), target :: work(:)
|
||||
type(psb_desc_type),target :: desc_a
|
||||
type(psb_desc_type), target :: desc_a
|
||||
integer(psb_ipk_), optional :: data
|
||||
|
||||
! locals
|
||||
@@ -1073,7 +1073,6 @@ subroutine psi_dswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
data_ = psb_comm_halo_
|
||||
end if
|
||||
|
||||
!!$ call desc_a%get_list(data_,d_idx,totxch,idxr,idxs,info)
|
||||
call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
|
||||
if (info /= psb_success_) then
|
||||
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list')
|
||||
@@ -1105,381 +1104,11 @@ end subroutine psi_dswapdata_vect
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_dswapidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_dswapidx_vect
|
||||
use psb_error_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_d_base_vect_mod
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
implicit none
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
|
||||
integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
class(psb_d_base_vect_type) :: y
|
||||
real(psb_dpk_) :: beta
|
||||
real(psb_dpk_), target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
& proc_to_comm, p2ptag, p2pstat(mpi_status_size), iret
|
||||
integer(psb_mpik_), allocatable, dimension(:) :: bsdidx, brvidx,&
|
||||
& sdsz, rvsz, prcid, rvhd, sdhd
|
||||
integer(psb_ipk_) :: nesd, nerv,&
|
||||
& err_act, i, idx_pt, totsnd_, totrcv_,&
|
||||
& snd_pt, rcv_pt, pnti, n
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
|
||||
real(psb_dpk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
volatile :: sndbuf, rcvbuf
|
||||
#endif
|
||||
character(len=20) :: name
|
||||
|
||||
info=psb_success_
|
||||
name='psi_swap_datav'
|
||||
call psb_erractionsave(err_act)
|
||||
ictxt = iictxt
|
||||
icomm = iicomm
|
||||
call psb_info(ictxt,me,np)
|
||||
if (np == -1) then
|
||||
info=psb_err_context_error_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
n=1
|
||||
|
||||
swap_mpi = iand(flag,psb_swap_mpi_) /= 0
|
||||
swap_sync = iand(flag,psb_swap_sync_) /= 0
|
||||
swap_send = iand(flag,psb_swap_send_) /= 0
|
||||
swap_recv = iand(flag,psb_swap_recv_) /= 0
|
||||
do_send = swap_mpi .or. swap_sync .or. swap_send
|
||||
do_recv = swap_mpi .or. swap_sync .or. swap_recv
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(nesd,idx(idx_pt:idx_pt+nesd-1),&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_r_dpk_,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_r_dpk_,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_double_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_r_dpk_,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_double_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_double_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(nerv,idx(idx_pt:idx_pt+nerv-1),&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
end subroutine psi_dswapidx_vect
|
||||
|
||||
|
||||
|
||||
!
|
||||
!
|
||||
! Subroutine: psi_dswapvidx_vect
|
||||
! Data exchange among processes.
|
||||
!
|
||||
! Case where the index vector is also encapsulated.
|
||||
!
|
||||
! The real workhorse: the outer routines will only choose the index list
|
||||
! this one takes the index list and does the actual exchange.
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_dswap_vidx_vect
|
||||
use psb_error_mod
|
||||
use psb_realloc_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_d_base_vect_mod
|
||||
@@ -1496,8 +1125,8 @@ subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
class(psb_d_base_vect_type) :: y
|
||||
real(psb_dpk_) :: beta
|
||||
real(psb_dpk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
@@ -1510,7 +1139,7 @@ subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
logical, parameter :: usersend=.false., debug=.false.
|
||||
|
||||
real(psb_dpk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
@@ -1541,159 +1170,65 @@ subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
call idx%sync()
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
if (debug) write(*,*) me,'Internal buffer'
|
||||
if (do_send) then
|
||||
if (allocated(y%comid)) then
|
||||
!
|
||||
! Unfinished communication? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
if (debug) write(*,*) me,'do_send start'
|
||||
call y%new_buffer(size(idx%v),info)
|
||||
call y%new_comid(totxch,info)
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
|
||||
p2ptag = psb_double_swap_tag
|
||||
call mpi_irecv(y%combuf(rcv_pt),nerv,&
|
||||
& psb_mpi_r_dpk_,prcid(i),&
|
||||
& p2ptag, icomm,y%comid(i,2),iret)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
if (debug) write(*,*) me,' Gather '
|
||||
!
|
||||
! Then gather for sending.
|
||||
!
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(idx_pt,nesd,idx,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
call y%gth(idx_pt,nesd,idx)
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
call y%device_wait()
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_r_dpk_,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_r_dpk_,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_double_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_r_dpk_,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
if (debug) write(*,*) me,' isend'
|
||||
!
|
||||
! Then send
|
||||
!
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
@@ -1702,48 +1237,70 @@ subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_double_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call mpi_isend(y%combuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,y%comid(i,1),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
if (debug) write(*,*) me,' do_Recv'
|
||||
if (.not.allocated(y%comid)) then
|
||||
!
|
||||
! No matching send? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
|
||||
if (debug) write(*,*) me,' wait'
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_double_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
if (proc_to_comm /= me)then
|
||||
if (nesd>0) then
|
||||
call mpi_wait(y%comid(i,1),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
if (nerv>0) then
|
||||
call mpi_wait(y%comid(i,2),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
@@ -1751,48 +1308,12 @@ subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
y%combuf(rcv_pt:rcv_pt+nerv-1) = y%combuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
if (debug) write(*,*) me,' scatter'
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
@@ -1801,36 +1322,36 @@ subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(idx_pt,nerv,idx,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
|
||||
call y%sct(rcv_pt,nerv,idx,beta)
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
if (debug) write(*,*) me,' wait'
|
||||
call y%device_wait()
|
||||
if (debug) write(*,*) me,' free buffer'
|
||||
call y%free_buffer(info)
|
||||
if (info == 0) call y%free_comid(info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug) write(*,*) me,' done'
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
return
|
||||
end subroutine psi_dswap_vidx_vect
|
||||
|
||||
|
||||
+111
-590
@@ -1038,7 +1038,7 @@ subroutine psi_iswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
class(psb_i_base_vect_type) :: y
|
||||
integer(psb_ipk_) :: beta
|
||||
integer(psb_ipk_), target :: work(:)
|
||||
type(psb_desc_type),target :: desc_a
|
||||
type(psb_desc_type), target :: desc_a
|
||||
integer(psb_ipk_), optional :: data
|
||||
|
||||
! locals
|
||||
@@ -1073,7 +1073,6 @@ subroutine psi_iswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
data_ = psb_comm_halo_
|
||||
end if
|
||||
|
||||
!!$ call desc_a%get_list(data_,d_idx,totxch,idxr,idxs,info)
|
||||
call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
|
||||
if (info /= psb_success_) then
|
||||
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list')
|
||||
@@ -1105,381 +1104,11 @@ end subroutine psi_iswapdata_vect
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_iswapidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_iswapidx_vect
|
||||
use psb_error_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_i_base_vect_mod
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
implicit none
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
|
||||
integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
class(psb_i_base_vect_type) :: y
|
||||
integer(psb_ipk_) :: beta
|
||||
integer(psb_ipk_), target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
& proc_to_comm, p2ptag, p2pstat(mpi_status_size), iret
|
||||
integer(psb_mpik_), allocatable, dimension(:) :: bsdidx, brvidx,&
|
||||
& sdsz, rvsz, prcid, rvhd, sdhd
|
||||
integer(psb_ipk_) :: nesd, nerv,&
|
||||
& err_act, i, idx_pt, totsnd_, totrcv_,&
|
||||
& snd_pt, rcv_pt, pnti, n
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
|
||||
integer(psb_ipk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
volatile :: sndbuf, rcvbuf
|
||||
#endif
|
||||
character(len=20) :: name
|
||||
|
||||
info=psb_success_
|
||||
name='psi_swap_datav'
|
||||
call psb_erractionsave(err_act)
|
||||
ictxt = iictxt
|
||||
icomm = iicomm
|
||||
call psb_info(ictxt,me,np)
|
||||
if (np == -1) then
|
||||
info=psb_err_context_error_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
n=1
|
||||
|
||||
swap_mpi = iand(flag,psb_swap_mpi_) /= 0
|
||||
swap_sync = iand(flag,psb_swap_sync_) /= 0
|
||||
swap_send = iand(flag,psb_swap_send_) /= 0
|
||||
swap_recv = iand(flag,psb_swap_recv_) /= 0
|
||||
do_send = swap_mpi .or. swap_sync .or. swap_send
|
||||
do_recv = swap_mpi .or. swap_sync .or. swap_recv
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(nesd,idx(idx_pt:idx_pt+nesd-1),&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_ipk_integer,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_ipk_integer,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_int_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_ipk_integer,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_int_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_ipk_integer,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_ipk_integer,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_int_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(nerv,idx(idx_pt:idx_pt+nerv-1),&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
end subroutine psi_iswapidx_vect
|
||||
|
||||
|
||||
|
||||
!
|
||||
!
|
||||
! Subroutine: psi_iswapvidx_vect
|
||||
! Data exchange among processes.
|
||||
!
|
||||
! Case where the index vector is also encapsulated.
|
||||
!
|
||||
! The real workhorse: the outer routines will only choose the index list
|
||||
! this one takes the index list and does the actual exchange.
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_iswap_vidx_vect
|
||||
use psb_error_mod
|
||||
use psb_realloc_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_i_base_vect_mod
|
||||
@@ -1496,8 +1125,8 @@ subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
class(psb_i_base_vect_type) :: y
|
||||
integer(psb_ipk_) :: beta
|
||||
integer(psb_ipk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
@@ -1510,7 +1139,7 @@ subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
logical, parameter :: usersend=.false., debug=.false.
|
||||
|
||||
integer(psb_ipk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
@@ -1541,159 +1170,65 @@ subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
call idx%sync()
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
if (debug) write(*,*) me,'Internal buffer'
|
||||
if (do_send) then
|
||||
if (allocated(y%comid)) then
|
||||
!
|
||||
! Unfinished communication? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
if (debug) write(*,*) me,'do_send start'
|
||||
call y%new_buffer(size(idx%v),info)
|
||||
call y%new_comid(totxch,info)
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
|
||||
p2ptag = psb_int_swap_tag
|
||||
call mpi_irecv(y%combuf(rcv_pt),nerv,&
|
||||
& psb_mpi_ipk_integer,prcid(i),&
|
||||
& p2ptag, icomm,y%comid(i,2),iret)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
if (debug) write(*,*) me,' Gather '
|
||||
!
|
||||
! Then gather for sending.
|
||||
!
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(idx_pt,nesd,idx,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
call y%gth(idx_pt,nesd,idx)
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
call y%device_wait()
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_ipk_integer,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_ipk_integer,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_int_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_ipk_integer,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
if (debug) write(*,*) me,' isend'
|
||||
!
|
||||
! Then send
|
||||
!
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
@@ -1702,48 +1237,70 @@ subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_int_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_ipk_integer,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_ipk_integer,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call mpi_isend(y%combuf(snd_pt),nesd,&
|
||||
& psb_mpi_ipk_integer,prcid(i),&
|
||||
& p2ptag,icomm,y%comid(i,1),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
if (debug) write(*,*) me,' do_Recv'
|
||||
if (.not.allocated(y%comid)) then
|
||||
!
|
||||
! No matching send? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
|
||||
if (debug) write(*,*) me,' wait'
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_int_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
if (proc_to_comm /= me)then
|
||||
if (nesd>0) then
|
||||
call mpi_wait(y%comid(i,1),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
if (nerv>0) then
|
||||
call mpi_wait(y%comid(i,2),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
@@ -1751,48 +1308,12 @@ subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
y%combuf(rcv_pt:rcv_pt+nerv-1) = y%combuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
if (debug) write(*,*) me,' scatter'
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
@@ -1801,36 +1322,36 @@ subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(idx_pt,nerv,idx,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
|
||||
call y%sct(rcv_pt,nerv,idx,beta)
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
if (debug) write(*,*) me,' wait'
|
||||
call y%device_wait()
|
||||
if (debug) write(*,*) me,' free buffer'
|
||||
call y%free_buffer(info)
|
||||
if (info == 0) call y%free_comid(info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug) write(*,*) me,' done'
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
return
|
||||
end subroutine psi_iswap_vidx_vect
|
||||
|
||||
|
||||
+111
-590
@@ -1038,7 +1038,7 @@ subroutine psi_sswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
class(psb_s_base_vect_type) :: y
|
||||
real(psb_spk_) :: beta
|
||||
real(psb_spk_), target :: work(:)
|
||||
type(psb_desc_type),target :: desc_a
|
||||
type(psb_desc_type), target :: desc_a
|
||||
integer(psb_ipk_), optional :: data
|
||||
|
||||
! locals
|
||||
@@ -1073,7 +1073,6 @@ subroutine psi_sswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
data_ = psb_comm_halo_
|
||||
end if
|
||||
|
||||
!!$ call desc_a%get_list(data_,d_idx,totxch,idxr,idxs,info)
|
||||
call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
|
||||
if (info /= psb_success_) then
|
||||
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list')
|
||||
@@ -1105,381 +1104,11 @@ end subroutine psi_sswapdata_vect
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_sswapidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_sswapidx_vect
|
||||
use psb_error_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_s_base_vect_mod
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
implicit none
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
|
||||
integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
class(psb_s_base_vect_type) :: y
|
||||
real(psb_spk_) :: beta
|
||||
real(psb_spk_), target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
& proc_to_comm, p2ptag, p2pstat(mpi_status_size), iret
|
||||
integer(psb_mpik_), allocatable, dimension(:) :: bsdidx, brvidx,&
|
||||
& sdsz, rvsz, prcid, rvhd, sdhd
|
||||
integer(psb_ipk_) :: nesd, nerv,&
|
||||
& err_act, i, idx_pt, totsnd_, totrcv_,&
|
||||
& snd_pt, rcv_pt, pnti, n
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
|
||||
real(psb_spk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
volatile :: sndbuf, rcvbuf
|
||||
#endif
|
||||
character(len=20) :: name
|
||||
|
||||
info=psb_success_
|
||||
name='psi_swap_datav'
|
||||
call psb_erractionsave(err_act)
|
||||
ictxt = iictxt
|
||||
icomm = iicomm
|
||||
call psb_info(ictxt,me,np)
|
||||
if (np == -1) then
|
||||
info=psb_err_context_error_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
n=1
|
||||
|
||||
swap_mpi = iand(flag,psb_swap_mpi_) /= 0
|
||||
swap_sync = iand(flag,psb_swap_sync_) /= 0
|
||||
swap_send = iand(flag,psb_swap_send_) /= 0
|
||||
swap_recv = iand(flag,psb_swap_recv_) /= 0
|
||||
do_send = swap_mpi .or. swap_sync .or. swap_send
|
||||
do_recv = swap_mpi .or. swap_sync .or. swap_recv
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(nesd,idx(idx_pt:idx_pt+nesd-1),&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_r_spk_,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_r_spk_,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_real_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_r_spk_,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_real_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_spk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_spk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_real_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(nerv,idx(idx_pt:idx_pt+nerv-1),&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
end subroutine psi_sswapidx_vect
|
||||
|
||||
|
||||
|
||||
!
|
||||
!
|
||||
! Subroutine: psi_sswapvidx_vect
|
||||
! Data exchange among processes.
|
||||
!
|
||||
! Case where the index vector is also encapsulated.
|
||||
!
|
||||
! The real workhorse: the outer routines will only choose the index list
|
||||
! this one takes the index list and does the actual exchange.
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_sswap_vidx_vect
|
||||
use psb_error_mod
|
||||
use psb_realloc_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_s_base_vect_mod
|
||||
@@ -1496,8 +1125,8 @@ subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
class(psb_s_base_vect_type) :: y
|
||||
real(psb_spk_) :: beta
|
||||
real(psb_spk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
@@ -1510,7 +1139,7 @@ subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
logical, parameter :: usersend=.false., debug=.false.
|
||||
|
||||
real(psb_spk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
@@ -1541,159 +1170,65 @@ subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
call idx%sync()
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
if (debug) write(*,*) me,'Internal buffer'
|
||||
if (do_send) then
|
||||
if (allocated(y%comid)) then
|
||||
!
|
||||
! Unfinished communication? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
if (debug) write(*,*) me,'do_send start'
|
||||
call y%new_buffer(size(idx%v),info)
|
||||
call y%new_comid(totxch,info)
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
|
||||
p2ptag = psb_real_swap_tag
|
||||
call mpi_irecv(y%combuf(rcv_pt),nerv,&
|
||||
& psb_mpi_r_spk_,prcid(i),&
|
||||
& p2ptag, icomm,y%comid(i,2),iret)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
if (debug) write(*,*) me,' Gather '
|
||||
!
|
||||
! Then gather for sending.
|
||||
!
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(idx_pt,nesd,idx,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
call y%gth(idx_pt,nesd,idx)
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
call y%device_wait()
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_r_spk_,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_r_spk_,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_real_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_r_spk_,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
if (debug) write(*,*) me,' isend'
|
||||
!
|
||||
! Then send
|
||||
!
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
@@ -1702,48 +1237,70 @@ subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_real_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_spk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_spk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call mpi_isend(y%combuf(snd_pt),nesd,&
|
||||
& psb_mpi_r_spk_,prcid(i),&
|
||||
& p2ptag,icomm,y%comid(i,1),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
if (debug) write(*,*) me,' do_Recv'
|
||||
if (.not.allocated(y%comid)) then
|
||||
!
|
||||
! No matching send? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
|
||||
if (debug) write(*,*) me,' wait'
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_real_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
if (proc_to_comm /= me)then
|
||||
if (nesd>0) then
|
||||
call mpi_wait(y%comid(i,1),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
if (nerv>0) then
|
||||
call mpi_wait(y%comid(i,2),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
@@ -1751,48 +1308,12 @@ subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
y%combuf(rcv_pt:rcv_pt+nerv-1) = y%combuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
if (debug) write(*,*) me,' scatter'
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
@@ -1801,36 +1322,36 @@ subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(idx_pt,nerv,idx,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
|
||||
call y%sct(rcv_pt,nerv,idx,beta)
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
if (debug) write(*,*) me,' wait'
|
||||
call y%device_wait()
|
||||
if (debug) write(*,*) me,' free buffer'
|
||||
call y%free_buffer(info)
|
||||
if (info == 0) call y%free_comid(info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug) write(*,*) me,' done'
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
return
|
||||
end subroutine psi_sswap_vidx_vect
|
||||
|
||||
|
||||
+111
-590
@@ -1038,7 +1038,7 @@ subroutine psi_zswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
class(psb_z_base_vect_type) :: y
|
||||
complex(psb_dpk_) :: beta
|
||||
complex(psb_dpk_), target :: work(:)
|
||||
type(psb_desc_type),target :: desc_a
|
||||
type(psb_desc_type), target :: desc_a
|
||||
integer(psb_ipk_), optional :: data
|
||||
|
||||
! locals
|
||||
@@ -1073,7 +1073,6 @@ subroutine psi_zswapdata_vect(flag,beta,y,desc_a,work,info,data)
|
||||
data_ = psb_comm_halo_
|
||||
end if
|
||||
|
||||
!!$ call desc_a%get_list(data_,d_idx,totxch,idxr,idxs,info)
|
||||
call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
|
||||
if (info /= psb_success_) then
|
||||
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list')
|
||||
@@ -1105,381 +1104,11 @@ end subroutine psi_zswapdata_vect
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_zswapidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_zswapidx_vect
|
||||
use psb_error_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_z_base_vect_mod
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
implicit none
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
|
||||
integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
class(psb_z_base_vect_type) :: y
|
||||
complex(psb_dpk_) :: beta
|
||||
complex(psb_dpk_), target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
& proc_to_comm, p2ptag, p2pstat(mpi_status_size), iret
|
||||
integer(psb_mpik_), allocatable, dimension(:) :: bsdidx, brvidx,&
|
||||
& sdsz, rvsz, prcid, rvhd, sdhd
|
||||
integer(psb_ipk_) :: nesd, nerv,&
|
||||
& err_act, i, idx_pt, totsnd_, totrcv_,&
|
||||
& snd_pt, rcv_pt, pnti, n
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
|
||||
complex(psb_dpk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
volatile :: sndbuf, rcvbuf
|
||||
#endif
|
||||
character(len=20) :: name
|
||||
|
||||
info=psb_success_
|
||||
name='psi_swap_datav'
|
||||
call psb_erractionsave(err_act)
|
||||
ictxt = iictxt
|
||||
icomm = iicomm
|
||||
call psb_info(ictxt,me,np)
|
||||
if (np == -1) then
|
||||
info=psb_err_context_error_
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
n=1
|
||||
|
||||
swap_mpi = iand(flag,psb_swap_mpi_) /= 0
|
||||
swap_sync = iand(flag,psb_swap_sync_) /= 0
|
||||
swap_send = iand(flag,psb_swap_send_) /= 0
|
||||
swap_recv = iand(flag,psb_swap_recv_) /= 0
|
||||
do_send = swap_mpi .or. swap_sync .or. swap_send
|
||||
do_recv = swap_mpi .or. swap_sync .or. swap_recv
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(nesd,idx(idx_pt:idx_pt+nesd-1),&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_c_dpk_,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_c_dpk_,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_dcomplex_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_c_dpk_,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_dcomplex_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
p2ptag = psb_dcomplex_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx(pnti+psb_proc_id_)
|
||||
nerv = idx(pnti+psb_n_elem_recv_)
|
||||
nesd = idx(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(nerv,idx(idx_pt:idx_pt+nerv-1),&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
end subroutine psi_zswapidx_vect
|
||||
|
||||
|
||||
|
||||
!
|
||||
!
|
||||
! Subroutine: psi_zswapvidx_vect
|
||||
! Data exchange among processes.
|
||||
!
|
||||
! Case where the index vector is also encapsulated.
|
||||
!
|
||||
! The real workhorse: the outer routines will only choose the index list
|
||||
! this one takes the index list and does the actual exchange.
|
||||
!
|
||||
!
|
||||
!
|
||||
subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_zswap_vidx_vect
|
||||
use psb_error_mod
|
||||
use psb_realloc_mod
|
||||
use psb_desc_mod
|
||||
use psb_penv_mod
|
||||
use psb_z_base_vect_mod
|
||||
@@ -1496,8 +1125,8 @@ subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
class(psb_z_base_vect_type) :: y
|
||||
complex(psb_dpk_) :: beta
|
||||
complex(psb_dpk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
|
||||
! locals
|
||||
integer(psb_mpik_) :: ictxt, icomm, np, me,&
|
||||
@@ -1510,7 +1139,7 @@ subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
integer(psb_ipk_) :: ierr(5)
|
||||
logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
|
||||
& albf,do_send,do_recv
|
||||
logical, parameter :: usersend=.false.
|
||||
logical, parameter :: usersend=.false., debug=.false.
|
||||
|
||||
complex(psb_dpk_), pointer, dimension(:) :: sndbuf, rcvbuf
|
||||
#ifdef HAVE_VOLATILE
|
||||
@@ -1541,159 +1170,65 @@ subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
|
||||
totrcv_ = totrcv * n
|
||||
totsnd_ = totsnd * n
|
||||
call idx%sync()
|
||||
|
||||
if (swap_mpi) then
|
||||
allocate(sdsz(0:np-1), rvsz(0:np-1), bsdidx(0:np-1),&
|
||||
& brvidx(0:np-1), rvhd(0:np-1), sdhd(0:np-1), prcid(0:np-1),&
|
||||
& stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
if (debug) write(*,*) me,'Internal buffer'
|
||||
if (do_send) then
|
||||
if (allocated(y%comid)) then
|
||||
!
|
||||
! Unfinished communication? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
rvhd(:) = mpi_request_null
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
|
||||
! prepare info for communications
|
||||
|
||||
if (debug) write(*,*) me,'do_send start'
|
||||
call y%new_buffer(size(idx%v),info)
|
||||
call y%new_comid(totxch,info)
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
call psb_get_rank(prcid(proc_to_comm),ictxt,proc_to_comm)
|
||||
|
||||
brvidx(proc_to_comm) = rcv_pt
|
||||
rvsz(proc_to_comm) = nerv
|
||||
|
||||
bsdidx(proc_to_comm) = snd_pt
|
||||
sdsz(proc_to_comm) = nesd
|
||||
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
|
||||
p2ptag = psb_dcomplex_swap_tag
|
||||
call mpi_irecv(y%combuf(rcv_pt),nerv,&
|
||||
& psb_mpi_c_dpk_,prcid(i),&
|
||||
& p2ptag, icomm,y%comid(i,2),iret)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
|
||||
end do
|
||||
|
||||
else
|
||||
allocate(rvhd(totxch),prcid(totxch),stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
totrcv_ = max(totrcv_,1)
|
||||
totsnd_ = max(totsnd_,1)
|
||||
if((totrcv_+totsnd_) < size(work)) then
|
||||
sndbuf => work(1:totsnd_)
|
||||
rcvbuf => work(totsnd_+1:totsnd_+totrcv_)
|
||||
albf=.false.
|
||||
else
|
||||
allocate(sndbuf(totsnd_),rcvbuf(totrcv_), stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
albf=.true.
|
||||
end if
|
||||
|
||||
|
||||
if (do_send) then
|
||||
|
||||
! Pack send buffers
|
||||
if (debug) write(*,*) me,' Gather '
|
||||
!
|
||||
! Then gather for sending.
|
||||
!
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
do i=1, totxch
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
call y%gth(idx_pt,nesd,idx,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1))
|
||||
call y%gth(idx_pt,nesd,idx)
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
call y%device_wait()
|
||||
|
||||
! Case SWAP_MPI
|
||||
if (swap_mpi) then
|
||||
|
||||
! swap elements using mpi_alltoallv
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdidx,&
|
||||
& psb_mpi_c_dpk_,rcvbuf,rvsz,&
|
||||
& brvidx,psb_mpi_c_dpk_,icomm,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
else if (swap_sync) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
if (proc_to_comm < me) then
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
else if (proc_to_comm > me) then
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
write(psb_err_unit,*) &
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send .and. swap_recv) then
|
||||
|
||||
! First I post all the non blocking receives
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
|
||||
call psb_get_rank(prcid(i),ictxt,proc_to_comm)
|
||||
if ((nerv>0).and.(proc_to_comm /= me)) then
|
||||
p2ptag = psb_dcomplex_swap_tag
|
||||
call mpi_irecv(rcvbuf(rcv_pt),nerv,&
|
||||
& psb_mpi_c_dpk_,prcid(i),&
|
||||
& p2ptag, icomm,rvhd(i),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
! Then I post all the blocking sends
|
||||
if (usersend) call mpi_barrier(icomm,iret)
|
||||
if (debug) write(*,*) me,' isend'
|
||||
!
|
||||
! Then send
|
||||
!
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
@@ -1702,48 +1237,70 @@ subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_dcomplex_swap_tag
|
||||
|
||||
if ((nesd>0).and.(proc_to_comm /= me)) then
|
||||
if (usersend) then
|
||||
call mpi_rsend(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
else
|
||||
call mpi_send(sndbuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,iret)
|
||||
end if
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call mpi_isend(y%combuf(snd_pt),nesd,&
|
||||
& psb_mpi_c_dpk_,prcid(i),&
|
||||
& p2ptag,icomm,y%comid(i,1),iret)
|
||||
end if
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
if (debug) write(*,*) me,' do_Recv'
|
||||
if (.not.allocated(y%comid)) then
|
||||
!
|
||||
! No matching send? Something is wrong....
|
||||
!
|
||||
info=psb_err_mpi_error_
|
||||
ierr(1) = -2
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
call psb_realloc(totxch,prcid,info)
|
||||
|
||||
if (debug) write(*,*) me,' wait'
|
||||
pnti = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
p2ptag = psb_dcomplex_swap_tag
|
||||
|
||||
if ((proc_to_comm /= me).and.(nerv>0)) then
|
||||
call mpi_wait(rvhd(i),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
if (proc_to_comm /= me)then
|
||||
if (nesd>0) then
|
||||
call mpi_wait(y%comid(i,1),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
if (nerv>0) then
|
||||
call mpi_wait(y%comid(i,2),p2pstat,iret)
|
||||
if(iret /= mpi_success) then
|
||||
ierr(1) = iret
|
||||
info=psb_err_mpi_error_
|
||||
call psb_errpush(info,name,i_err=ierr)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
else if (proc_to_comm == me) then
|
||||
if (nesd /= nerv) then
|
||||
@@ -1751,48 +1308,12 @@ subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
& 'Fatal error in swapdata: mismatch on self send',&
|
||||
& nerv,nesd
|
||||
end if
|
||||
rcvbuf(rcv_pt:rcv_pt+nerv-1) = sndbuf(snd_pt:snd_pt+nesd-1)
|
||||
y%combuf(rcv_pt:rcv_pt+nerv-1) = y%combuf(snd_pt:snd_pt+nesd-1)
|
||||
end if
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
else if (swap_send) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nesd>0) call psb_snd(ictxt,&
|
||||
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
else if (swap_recv) then
|
||||
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
do i=1, totxch
|
||||
proc_to_comm = idx%v(pnti+psb_proc_id_)
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
if (nerv>0) call psb_rcv(ictxt,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
end if
|
||||
|
||||
if (do_recv) then
|
||||
|
||||
if (debug) write(*,*) me,' scatter'
|
||||
pnti = 1
|
||||
snd_pt = 1
|
||||
rcv_pt = 1
|
||||
@@ -1801,36 +1322,36 @@ subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
|
||||
nerv = idx%v(pnti+psb_n_elem_recv_)
|
||||
nesd = idx%v(pnti+nerv+psb_n_elem_send_)
|
||||
idx_pt = 1+pnti+psb_n_elem_recv_
|
||||
call y%sct(idx_pt,nerv,idx,&
|
||||
& rcvbuf(rcv_pt:rcv_pt+nerv-1),beta)
|
||||
rcv_pt = rcv_pt + nerv
|
||||
snd_pt = snd_pt + nesd
|
||||
snd_pt = 1+pnti+nerv+psb_n_elem_send_
|
||||
rcv_pt = 1+pnti+psb_n_elem_recv_
|
||||
|
||||
if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
|
||||
call y%sct(rcv_pt,nerv,idx,beta)
|
||||
pnti = pnti + nerv + nesd + 3
|
||||
end do
|
||||
|
||||
|
||||
!
|
||||
! Then wait
|
||||
!
|
||||
if (debug) write(*,*) me,' wait'
|
||||
call y%device_wait()
|
||||
if (debug) write(*,*) me,' free buffer'
|
||||
call y%free_buffer(info)
|
||||
if (info == 0) call y%free_comid(info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug) write(*,*) me,' done'
|
||||
end if
|
||||
|
||||
if (swap_mpi) then
|
||||
deallocate(sdsz,rvsz,bsdidx,brvidx,rvhd,prcid,sdhd,&
|
||||
& stat=info)
|
||||
else
|
||||
deallocate(rvhd,prcid,stat=info)
|
||||
end if
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
if(albf) deallocate(sndbuf,rcvbuf,stat=info)
|
||||
if(info /= psb_success_) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 call psb_error_handler(ictxt,err_act)
|
||||
|
||||
return
|
||||
return
|
||||
end subroutine psi_zswap_vidx_vect
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ module psb_i_base_vect_mod
|
||||
type psb_i_base_vect_type
|
||||
!> Values.
|
||||
integer(psb_ipk_), allocatable :: v(:)
|
||||
integer(psb_ipk_), allocatable :: combuf(:)
|
||||
integer(psb_ipk_), allocatable :: comid(:,:)
|
||||
contains
|
||||
!
|
||||
! Constructors/allocators
|
||||
@@ -96,6 +98,17 @@ module psb_i_base_vect_mod
|
||||
procedure, pass(x) :: set_dev => i_base_set_dev
|
||||
procedure, pass(x) :: set_sync => i_base_set_sync
|
||||
|
||||
!
|
||||
! These are for handling gather/scatter in new
|
||||
! comm internals implementation.
|
||||
!
|
||||
procedure, nopass :: use_buffer => i_base_use_buffer
|
||||
procedure, pass(x) :: new_buffer => i_base_new_buffer
|
||||
procedure, nopass :: device_wait => i_base_device_wait
|
||||
procedure, pass(x) :: free_buffer => i_base_free_buffer
|
||||
procedure, pass(x) :: new_comid => i_base_new_comid
|
||||
procedure, pass(x) :: free_comid => i_base_free_comid
|
||||
|
||||
!
|
||||
! Basic info
|
||||
procedure, pass(x) :: get_nrows => i_base_get_nrows
|
||||
@@ -134,6 +147,9 @@ module psb_i_base_vect_mod
|
||||
! Scaling and norms
|
||||
!
|
||||
procedure, pass(x) :: scal => i_base_scal
|
||||
procedure, pass(x) :: absval1 => i_base_absval1
|
||||
procedure, pass(x) :: absval2 => i_base_absval2
|
||||
generic, public :: absval => absval1, absval2
|
||||
procedure, pass(x) :: nrm2 => i_base_nrm2
|
||||
procedure, pass(x) :: amax => i_base_amax
|
||||
procedure, pass(x) :: asum => i_base_asum
|
||||
@@ -144,10 +160,12 @@ module psb_i_base_vect_mod
|
||||
procedure, pass(x) :: gthab => i_base_gthab
|
||||
procedure, pass(x) :: gthzv => i_base_gthzv
|
||||
procedure, pass(x) :: gthzv_x => i_base_gthzv_x
|
||||
generic, public :: gth => gthab, gthzv, gthzv_x
|
||||
procedure, pass(x) :: gthzbuf => i_base_gthzbuf
|
||||
generic, public :: gth => gthab, gthzv, gthzv_x, gthzbuf
|
||||
procedure, pass(y) :: sctb => i_base_sctb
|
||||
procedure, pass(y) :: sctb_x => i_base_sctb_x
|
||||
generic, public :: sct => sctb, sctb_x
|
||||
procedure, pass(y) :: sctb_buf => i_base_sctb_buf
|
||||
generic, public :: sct => sctb, sctb_x, sctb_buf
|
||||
end type psb_i_base_vect_type
|
||||
|
||||
public :: psb_i_base_vect
|
||||
@@ -344,8 +362,8 @@ contains
|
||||
|
||||
case default
|
||||
info = 321
|
||||
! !$ call psb_errpush(info,name)
|
||||
! !$ goto 9999
|
||||
! !$ call psb_errpush(info,name)
|
||||
! !$ goto 9999
|
||||
end select
|
||||
end if
|
||||
call x%set_host()
|
||||
@@ -356,7 +374,6 @@ contains
|
||||
|
||||
end subroutine i_base_ins_a
|
||||
|
||||
|
||||
subroutine i_base_ins_v(n,irl,val,dupl,x,info)
|
||||
use psi_serial_mod
|
||||
implicit none
|
||||
@@ -396,7 +413,7 @@ contains
|
||||
class(psb_i_base_vect_type), intent(inout) :: x
|
||||
|
||||
if (allocated(x%v)) x%v=izero
|
||||
|
||||
call x%set_host()
|
||||
end subroutine i_base_zero
|
||||
|
||||
|
||||
@@ -422,11 +439,12 @@ contains
|
||||
class(psb_i_base_vect_type), intent(inout) :: x
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
|
||||
info = 0
|
||||
if (x%get_nrows() < n) &
|
||||
& call psb_realloc(n,x%v,info)
|
||||
if (info /= 0) &
|
||||
& call psb_errpush(psb_err_alloc_dealloc_,'vect_asb')
|
||||
|
||||
call x%sync()
|
||||
end subroutine i_base_asb
|
||||
|
||||
|
||||
@@ -447,6 +465,8 @@ contains
|
||||
|
||||
info = 0
|
||||
if (allocated(x%v)) deallocate(x%v, stat=info)
|
||||
if (info == 0) call x%free_buffer(info)
|
||||
if (info == 0) call x%free_comid(info)
|
||||
if (info /= 0) call &
|
||||
& psb_errpush(psb_err_alloc_dealloc_,'vect_free')
|
||||
|
||||
@@ -611,7 +631,7 @@ contains
|
||||
integer(psb_ipk_) :: info
|
||||
|
||||
if (.not.allocated(x%v)) return
|
||||
call x%sync()
|
||||
if (.not.x%is_host()) call x%sync()
|
||||
allocate(res(x%get_nrows()),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,'base_get_vect')
|
||||
@@ -634,10 +654,44 @@ contains
|
||||
integer(psb_ipk_), intent(in) :: val
|
||||
|
||||
integer(psb_ipk_) :: info
|
||||
|
||||
x%v = val
|
||||
|
||||
call x%set_host()
|
||||
|
||||
end subroutine i_base_set_scal
|
||||
|
||||
!
|
||||
! Overwrite with absolute value
|
||||
!
|
||||
!
|
||||
!> Function base_set_scal
|
||||
!! \memberof psb_i_base_vect_type
|
||||
!! \brief Set all entries to their respective absolute values.
|
||||
!!
|
||||
subroutine i_base_absval1(x)
|
||||
class(psb_i_base_vect_type), intent(inout) :: x
|
||||
|
||||
if (allocated(x%v)) then
|
||||
if (.not.x%is_host()) call x%sync()
|
||||
x%v = abs(x%v)
|
||||
call x%set_host()
|
||||
end if
|
||||
|
||||
end subroutine i_base_absval1
|
||||
|
||||
subroutine i_base_absval2(x,y)
|
||||
class(psb_i_base_vect_type), intent(inout) :: x
|
||||
class(psb_i_base_vect_type), intent(inout) :: y
|
||||
|
||||
if (.not.x%is_host()) call x%sync()
|
||||
if (allocated(x%v)) then
|
||||
call y%bld(x%v)
|
||||
call y%absval()
|
||||
call y%set_host()
|
||||
end if
|
||||
|
||||
end subroutine i_base_absval2
|
||||
|
||||
!
|
||||
!> Function base_set_vect
|
||||
!! \memberof psb_i_base_vect_type
|
||||
@@ -656,6 +710,7 @@ contains
|
||||
else
|
||||
x%v = val
|
||||
end if
|
||||
call x%set_host()
|
||||
|
||||
end subroutine i_base_set_vect
|
||||
|
||||
@@ -738,12 +793,9 @@ contains
|
||||
integer(psb_ipk_), intent (in) :: alpha, beta
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
|
||||
select type(xx => x)
|
||||
type is (psb_i_base_vect_type)
|
||||
call psb_geaxpby(m,alpha,x%v,beta,y%v,info)
|
||||
class default
|
||||
call y%axpby(m,alpha,x%v,beta,info)
|
||||
end select
|
||||
if (x%is_dev()) call x%sync()
|
||||
|
||||
call y%axpby(m,alpha,x%v,beta,info)
|
||||
|
||||
end subroutine i_base_axpby_v
|
||||
|
||||
@@ -769,7 +821,9 @@ contains
|
||||
integer(psb_ipk_), intent (in) :: alpha, beta
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
|
||||
if (y%is_dev()) call y%sync()
|
||||
call psb_geaxpby(m,alpha,x,beta,y%v,info)
|
||||
call y%set_host()
|
||||
|
||||
end subroutine i_base_axpby_a
|
||||
|
||||
@@ -798,15 +852,8 @@ contains
|
||||
integer(psb_ipk_) :: i, n
|
||||
|
||||
info = 0
|
||||
select type(xx => x)
|
||||
type is (psb_i_base_vect_type)
|
||||
n = min(size(y%v), size(xx%v))
|
||||
do i=1, n
|
||||
y%v(i) = y%v(i)*xx%v(i)
|
||||
end do
|
||||
class default
|
||||
call y%mlt(x%v,info)
|
||||
end select
|
||||
if (x%is_dev()) call x%sync()
|
||||
call y%mlt(x%v,info)
|
||||
|
||||
end subroutine i_base_mlt_v
|
||||
|
||||
@@ -826,11 +873,13 @@ contains
|
||||
integer(psb_ipk_) :: i, n
|
||||
|
||||
info = 0
|
||||
if (y%is_dev()) call y%sync()
|
||||
n = min(size(y%v), size(x))
|
||||
do i=1, n
|
||||
y%v(i) = y%v(i)*x(i)
|
||||
end do
|
||||
|
||||
call y%set_host()
|
||||
|
||||
end subroutine i_base_mlt_a
|
||||
|
||||
|
||||
@@ -856,6 +905,8 @@ contains
|
||||
integer(psb_ipk_) :: i, n
|
||||
|
||||
info = 0
|
||||
if (z%is_dev()) call z%sync()
|
||||
|
||||
n = min(size(z%v), size(x), size(y))
|
||||
!!$ write(0,*) 'Mlt_a_2: ',n
|
||||
if (alpha == izero) then
|
||||
@@ -911,6 +962,8 @@ contains
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
call z%set_host()
|
||||
|
||||
end subroutine i_base_mlt_a_2
|
||||
|
||||
!
|
||||
@@ -938,6 +991,8 @@ contains
|
||||
logical :: conjgx_, conjgy_
|
||||
|
||||
info = 0
|
||||
if (y%is_dev()) call y%sync()
|
||||
if (x%is_dev()) call x%sync()
|
||||
if (.not.psb_i_is_complex_) then
|
||||
call z%mlt(alpha,x%v,y%v,beta,info)
|
||||
else
|
||||
@@ -964,7 +1019,7 @@ contains
|
||||
integer(psb_ipk_) :: i, n
|
||||
|
||||
info = 0
|
||||
|
||||
if (y%is_dev()) call y%sync()
|
||||
call z%mlt(alpha,x,y%v,beta,info)
|
||||
|
||||
end subroutine i_base_mlt_av
|
||||
@@ -980,7 +1035,7 @@ contains
|
||||
integer(psb_ipk_) :: i, n
|
||||
|
||||
info = 0
|
||||
|
||||
if (x%is_dev()) call x%sync()
|
||||
call z%mlt(alpha,y,x,beta,info)
|
||||
|
||||
end subroutine i_base_mlt_va
|
||||
@@ -1000,7 +1055,10 @@ contains
|
||||
class(psb_i_base_vect_type), intent(inout) :: x
|
||||
integer(psb_ipk_), intent (in) :: alpha
|
||||
|
||||
if (allocated(x%v)) x%v = alpha*x%v
|
||||
if (allocated(x%v)) then
|
||||
x%v = alpha*x%v
|
||||
call x%set_host()
|
||||
end if
|
||||
|
||||
end subroutine i_base_scal
|
||||
|
||||
@@ -1018,6 +1076,7 @@ contains
|
||||
integer(psb_ipk_) :: res
|
||||
integer(psb_ipk_), external :: inrm2
|
||||
|
||||
if (x%is_dev()) call x%sync()
|
||||
res = inrm2(n,x%v,1)
|
||||
|
||||
end function i_base_nrm2
|
||||
@@ -1033,6 +1092,7 @@ contains
|
||||
integer(psb_ipk_), intent(in) :: n
|
||||
integer(psb_ipk_) :: res
|
||||
|
||||
if (x%is_dev()) call x%sync()
|
||||
res = maxval(abs(x%v(1:n)))
|
||||
|
||||
end function i_base_amax
|
||||
@@ -1048,6 +1108,7 @@ contains
|
||||
integer(psb_ipk_), intent(in) :: n
|
||||
integer(psb_ipk_) :: res
|
||||
|
||||
if (x%is_dev()) call x%sync()
|
||||
res = sum(abs(x%v(1:n)))
|
||||
|
||||
end function i_base_asum
|
||||
@@ -1071,7 +1132,7 @@ contains
|
||||
integer(psb_ipk_) :: alpha, beta, y(:)
|
||||
class(psb_i_base_vect_type) :: x
|
||||
|
||||
call x%sync()
|
||||
if (x%is_dev()) call x%sync()
|
||||
call psi_gth(n,idx,alpha,x%v,beta,y)
|
||||
|
||||
end subroutine i_base_gthab
|
||||
@@ -1091,10 +1152,108 @@ contains
|
||||
integer(psb_ipk_) :: y(:)
|
||||
class(psb_i_base_vect_type) :: x
|
||||
|
||||
if (idx%is_dev()) call idx%sync()
|
||||
call x%gth(n,idx%v(i:),y)
|
||||
|
||||
end subroutine i_base_gthzv_x
|
||||
|
||||
!
|
||||
! New comm internals impl.
|
||||
!
|
||||
subroutine i_base_gthzbuf(i,n,idx,x)
|
||||
use psi_serial_mod
|
||||
integer(psb_ipk_) :: i,n
|
||||
class(psb_i_base_vect_type) :: idx
|
||||
class(psb_i_base_vect_type) :: x
|
||||
|
||||
if (.not.allocated(x%combuf)) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,'gthzbuf')
|
||||
return
|
||||
end if
|
||||
if (idx%is_dev()) call idx%sync()
|
||||
if (x%is_dev()) call x%sync()
|
||||
call x%gth(n,idx%v(i:),x%combuf(i:))
|
||||
|
||||
end subroutine i_base_gthzbuf
|
||||
|
||||
subroutine i_base_sctb_buf(i,n,idx,beta,y)
|
||||
use psi_serial_mod
|
||||
integer(psb_ipk_) :: i, n
|
||||
class(psb_i_base_vect_type) :: idx
|
||||
integer(psb_ipk_) :: beta
|
||||
class(psb_i_base_vect_type) :: y
|
||||
|
||||
|
||||
if (.not.allocated(y%combuf)) then
|
||||
call psb_errpush(psb_err_alloc_dealloc_,'sctb_buf')
|
||||
return
|
||||
end if
|
||||
if (y%is_dev()) call y%sync()
|
||||
if (idx%is_dev()) call idx%sync()
|
||||
call y%sct(n,idx%v(i:),y%combuf(i:),beta)
|
||||
call y%set_host()
|
||||
|
||||
end subroutine i_base_sctb_buf
|
||||
|
||||
!
|
||||
!> Function base_device_wait:
|
||||
!! \memberof psb_i_base_vect_type
|
||||
!! \brief device_wait: base version is a no-op.
|
||||
!!
|
||||
!
|
||||
subroutine i_base_device_wait()
|
||||
implicit none
|
||||
|
||||
end subroutine i_base_device_wait
|
||||
|
||||
function i_base_use_buffer() result(res)
|
||||
logical :: res
|
||||
|
||||
res = .true.
|
||||
end function i_base_use_buffer
|
||||
|
||||
subroutine i_base_new_buffer(n,x,info)
|
||||
use psb_realloc_mod
|
||||
implicit none
|
||||
class(psb_i_base_vect_type), intent(inout) :: x
|
||||
integer(psb_ipk_), intent(in) :: n
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
|
||||
call psb_realloc(n,x%combuf,info)
|
||||
end subroutine i_base_new_buffer
|
||||
|
||||
subroutine i_base_new_comid(n,x,info)
|
||||
use psb_realloc_mod
|
||||
implicit none
|
||||
class(psb_i_base_vect_type), intent(inout) :: x
|
||||
integer(psb_ipk_), intent(in) :: n
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
|
||||
call psb_realloc(n,2,x%comid,info)
|
||||
end subroutine i_base_new_comid
|
||||
|
||||
|
||||
subroutine i_base_free_buffer(x,info)
|
||||
use psb_realloc_mod
|
||||
implicit none
|
||||
class(psb_i_base_vect_type), intent(inout) :: x
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
|
||||
if (allocated(x%combuf)) &
|
||||
& deallocate(x%combuf,stat=info)
|
||||
end subroutine i_base_free_buffer
|
||||
|
||||
subroutine i_base_free_comid(x,info)
|
||||
use psb_realloc_mod
|
||||
implicit none
|
||||
class(psb_i_base_vect_type), intent(inout) :: x
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
|
||||
if (allocated(x%comid)) &
|
||||
& deallocate(x%comid,stat=info)
|
||||
end subroutine i_base_free_comid
|
||||
|
||||
|
||||
!
|
||||
! shortcut alpha=1 beta=0
|
||||
!
|
||||
@@ -1110,7 +1269,7 @@ contains
|
||||
integer(psb_ipk_) :: y(:)
|
||||
class(psb_i_base_vect_type) :: x
|
||||
|
||||
call x%sync()
|
||||
if (x%is_dev()) call x%sync()
|
||||
call psi_gth(n,idx,x%v,y)
|
||||
|
||||
end subroutine i_base_gthzv
|
||||
@@ -1134,7 +1293,7 @@ contains
|
||||
integer(psb_ipk_) :: beta, x(:)
|
||||
class(psb_i_base_vect_type) :: y
|
||||
|
||||
call y%sync()
|
||||
if (y%is_dev()) call y%sync()
|
||||
call psi_sct(n,idx,x,beta,y%v)
|
||||
call y%set_host()
|
||||
|
||||
@@ -1147,13 +1306,18 @@ contains
|
||||
integer(psb_ipk_) :: beta, x(:)
|
||||
class(psb_i_base_vect_type) :: y
|
||||
|
||||
if (idx%is_dev()) call idx%sync()
|
||||
call y%sct(n,idx%v(i:),x,beta)
|
||||
call y%set_host()
|
||||
|
||||
end subroutine i_base_sctb_x
|
||||
|
||||
end module psb_i_base_vect_mod
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
module psb_i_base_multivect_mod
|
||||
|
||||
use psb_const_mod
|
||||
@@ -1701,8 +1865,7 @@ contains
|
||||
function i_base_mv_get_vect(x) result(res)
|
||||
class(psb_i_base_multivect_type), intent(inout) :: x
|
||||
integer(psb_ipk_), allocatable :: res(:,:)
|
||||
integer(psb_ipk_) :: info, m, n
|
||||
|
||||
integer(psb_ipk_) :: info,m,n
|
||||
m = x%get_nrows()
|
||||
n = x%get_ncols()
|
||||
if (.not.allocated(x%v)) return
|
||||
@@ -1713,7 +1876,6 @@ contains
|
||||
return
|
||||
end if
|
||||
res(1:m,1:n) = x%v(1:m,1:n)
|
||||
|
||||
end function i_base_mv_get_vect
|
||||
|
||||
!
|
||||
@@ -1772,7 +1934,7 @@ contains
|
||||
!!$ class(psb_i_base_multivect_type), intent(inout) :: x, y
|
||||
!!$ integer(psb_ipk_), intent(in) :: n
|
||||
!!$ integer(psb_ipk_) :: res
|
||||
!!$ integer(psb_ipk_), external :: idot
|
||||
!!$ integer(psb_ipk_), external :: ddot
|
||||
!!$
|
||||
!!$ res = izero
|
||||
!!$ !
|
||||
@@ -1784,7 +1946,7 @@ contains
|
||||
!!$ !
|
||||
!!$ select type(yy => y)
|
||||
!!$ type is (psb_i_base_multivect_type)
|
||||
!!$ res = idot(n,x%v,1,y%v,1)
|
||||
!!$ res = ddot(n,x%v,1,y%v,1)
|
||||
!!$ class default
|
||||
!!$ res = y%dot(n,x%v)
|
||||
!!$ end select
|
||||
@@ -1807,9 +1969,9 @@ contains
|
||||
!!$ integer(psb_ipk_), intent(in) :: y(:)
|
||||
!!$ integer(psb_ipk_), intent(in) :: n
|
||||
!!$ integer(psb_ipk_) :: res
|
||||
!!$ integer(psb_ipk_), external :: idot
|
||||
!!$ integer(psb_ipk_), external :: ddot
|
||||
!!$
|
||||
!!$ res = idot(n,y,1,x%v,1)
|
||||
!!$ res = ddot(n,y,1,x%v,1)
|
||||
!!$
|
||||
!!$ end function i_base_mv_dot_a
|
||||
|
||||
@@ -2113,9 +2275,9 @@ contains
|
||||
!!$ class(psb_i_base_multivect_type), intent(inout) :: x
|
||||
!!$ integer(psb_ipk_), intent(in) :: n
|
||||
!!$ integer(psb_ipk_) :: res
|
||||
!!$ integer(psb_ipk_), external :: inrm2
|
||||
!!$ integer(psb_ipk_), external :: dnrm2
|
||||
!!$
|
||||
!!$ res = inrm2(n,x%v,1)
|
||||
!!$ res = dnrm2(n,x%v,1)
|
||||
!!$
|
||||
!!$ end function i_base_mv_nrm2
|
||||
!!$
|
||||
@@ -2241,7 +2403,7 @@ contains
|
||||
!!$ use psi_serial_mod
|
||||
!!$ integer(psb_ipk_) :: i, n
|
||||
!!$ class(psb_i_base_multivect_type) :: idx
|
||||
!!$ integer(psb_ipk_) :: beta, x(:)
|
||||
!!$ integer( psb_ipk_) :: beta, x(:)
|
||||
!!$ class(psb_i_base_multivect_type) :: y
|
||||
!!$
|
||||
!!$ call y%sct(n,idx%v(i:),x,beta)
|
||||
@@ -2249,3 +2411,4 @@ contains
|
||||
!!$ end subroutine i_base_mv_sctb_x
|
||||
|
||||
end module psb_i_base_multivect_mod
|
||||
|
||||
|
||||
@@ -80,16 +80,6 @@ module psi_c_mod
|
||||
complex(psb_spk_),target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
|
||||
end subroutine psi_cswapidxv
|
||||
subroutine psi_cswapidx_vect(ictxt,icomm,flag,beta,y,idx,&
|
||||
& totxch,totsnd,totrcv,work,info)
|
||||
import :: psb_desc_type, psb_ipk_, psb_spk_, psb_c_base_vect_type
|
||||
integer(psb_ipk_), intent(in) :: ictxt,icomm,flag
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
class(psb_c_base_vect_type) :: y
|
||||
complex(psb_spk_) :: beta
|
||||
complex(psb_spk_),target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
|
||||
end subroutine psi_cswapidx_vect
|
||||
subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
import :: psb_desc_type, psb_ipk_, psb_spk_, psb_c_base_vect_type, psb_i_base_vect_type
|
||||
integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
|
||||
@@ -97,7 +87,7 @@ module psi_c_mod
|
||||
class(psb_c_base_vect_type) :: y
|
||||
complex(psb_spk_) :: beta
|
||||
complex(psb_spk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
end subroutine psi_cswap_vidx_vect
|
||||
end interface
|
||||
|
||||
@@ -80,16 +80,6 @@ module psi_d_mod
|
||||
real(psb_dpk_),target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
|
||||
end subroutine psi_dswapidxv
|
||||
subroutine psi_dswapidx_vect(ictxt,icomm,flag,beta,y,idx,&
|
||||
& totxch,totsnd,totrcv,work,info)
|
||||
import :: psb_desc_type, psb_ipk_, psb_dpk_, psb_d_base_vect_type
|
||||
integer(psb_ipk_), intent(in) :: ictxt,icomm,flag
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
class(psb_d_base_vect_type) :: y
|
||||
real(psb_dpk_) :: beta
|
||||
real(psb_dpk_),target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
|
||||
end subroutine psi_dswapidx_vect
|
||||
subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
import :: psb_desc_type, psb_ipk_, psb_dpk_, psb_d_base_vect_type, psb_i_base_vect_type
|
||||
integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
|
||||
@@ -97,7 +87,7 @@ module psi_d_mod
|
||||
class(psb_d_base_vect_type) :: y
|
||||
real(psb_dpk_) :: beta
|
||||
real(psb_dpk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
end subroutine psi_dswap_vidx_vect
|
||||
end interface
|
||||
|
||||
@@ -258,7 +258,7 @@ module psi_i_mod
|
||||
class(psb_i_base_vect_type) :: y
|
||||
integer(psb_ipk_) :: beta
|
||||
integer(psb_ipk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
end subroutine psi_iswap_vidx_vect
|
||||
end interface
|
||||
|
||||
@@ -80,16 +80,6 @@ module psi_s_mod
|
||||
real(psb_spk_),target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
|
||||
end subroutine psi_sswapidxv
|
||||
subroutine psi_sswapidx_vect(ictxt,icomm,flag,beta,y,idx,&
|
||||
& totxch,totsnd,totrcv,work,info)
|
||||
import :: psb_desc_type, psb_ipk_, psb_spk_, psb_s_base_vect_type
|
||||
integer(psb_ipk_), intent(in) :: ictxt,icomm,flag
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
class(psb_s_base_vect_type) :: y
|
||||
real(psb_spk_) :: beta
|
||||
real(psb_spk_),target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
|
||||
end subroutine psi_sswapidx_vect
|
||||
subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
import :: psb_desc_type, psb_ipk_, psb_spk_, psb_s_base_vect_type, psb_i_base_vect_type
|
||||
integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
|
||||
@@ -97,7 +87,7 @@ module psi_s_mod
|
||||
class(psb_s_base_vect_type) :: y
|
||||
real(psb_spk_) :: beta
|
||||
real(psb_spk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
end subroutine psi_sswap_vidx_vect
|
||||
end interface
|
||||
|
||||
@@ -80,16 +80,6 @@ module psi_z_mod
|
||||
complex(psb_dpk_),target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
|
||||
end subroutine psi_zswapidxv
|
||||
subroutine psi_zswapidx_vect(ictxt,icomm,flag,beta,y,idx,&
|
||||
& totxch,totsnd,totrcv,work,info)
|
||||
import :: psb_desc_type, psb_ipk_, psb_dpk_, psb_z_base_vect_type
|
||||
integer(psb_ipk_), intent(in) :: ictxt,icomm,flag
|
||||
integer(psb_ipk_), intent(out) :: info
|
||||
class(psb_z_base_vect_type) :: y
|
||||
complex(psb_dpk_) :: beta
|
||||
complex(psb_dpk_),target :: work(:)
|
||||
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
|
||||
end subroutine psi_zswapidx_vect
|
||||
subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrcv,work,info)
|
||||
import :: psb_desc_type, psb_ipk_, psb_dpk_, psb_z_base_vect_type, psb_i_base_vect_type
|
||||
integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
|
||||
@@ -97,7 +87,7 @@ module psi_z_mod
|
||||
class(psb_z_base_vect_type) :: y
|
||||
complex(psb_dpk_) :: beta
|
||||
complex(psb_dpk_), target :: work(:)
|
||||
class(psb_i_base_vect_type), intent(in) :: idx
|
||||
class(psb_i_base_vect_type), intent(inout) :: idx
|
||||
integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
|
||||
end subroutine psi_zswap_vidx_vect
|
||||
end interface
|
||||
|
||||
Reference in New Issue
Block a user