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.
psblas-3.4-maint
Salvatore Filippone 10 years ago
parent 22cfaaccab
commit f764fa2515

@ -1038,7 +1038,7 @@ subroutine psi_cswapdata_vect(flag,beta,y,desc_a,work,info,data)
class(psb_c_base_vect_type) :: y class(psb_c_base_vect_type) :: y
complex(psb_spk_) :: beta complex(psb_spk_) :: beta
complex(psb_spk_), target :: work(:) complex(psb_spk_), target :: work(:)
type(psb_desc_type),target :: desc_a type(psb_desc_type), target :: desc_a
integer(psb_ipk_), optional :: data integer(psb_ipk_), optional :: data
! locals ! locals
@ -1073,7 +1073,6 @@ subroutine psi_cswapdata_vect(flag,beta,y,desc_a,work,info,data)
data_ = psb_comm_halo_ data_ = psb_comm_halo_
end if 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) call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
if (info /= psb_success_) then if (info /= psb_success_) then
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list') 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) 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 psi_mod, psb_protect_name => psi_cswap_vidx_vect
use psb_error_mod use psb_error_mod
use psb_realloc_mod
use psb_desc_mod use psb_desc_mod
use psb_penv_mod use psb_penv_mod
use psb_c_base_vect_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 class(psb_c_base_vect_type) :: y
complex(psb_spk_) :: beta complex(psb_spk_) :: beta
complex(psb_spk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
! locals ! locals
integer(psb_mpik_) :: ictxt, icomm, np, me,& 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) integer(psb_ipk_) :: ierr(5)
logical :: swap_mpi, swap_sync, swap_send, swap_recv,& logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
& albf,do_send,do_recv & albf,do_send,do_recv
logical, parameter :: usersend=.false. logical, parameter :: usersend=.false., debug=.false.
complex(psb_spk_), pointer, dimension(:) :: sndbuf, rcvbuf complex(psb_spk_), pointer, dimension(:) :: sndbuf, rcvbuf
#ifdef HAVE_VOLATILE #ifdef HAVE_VOLATILE
@ -1541,159 +1170,65 @@ subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
totrcv_ = totrcv * n totrcv_ = totrcv * n
totsnd_ = totsnd * n totsnd_ = totsnd * n
call idx%sync()
if (swap_mpi) then if (debug) write(*,*) me,'Internal buffer'
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%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
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 if (do_send) then
if (allocated(y%comid)) then
! Pack send buffers !
pnti = 1 ! Unfinished communication? Something is wrong....
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))
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_ info=psb_err_mpi_error_
ierr(1) = -2
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if end if
if (debug) write(*,*) me,'do_send start'
else if (swap_sync) then 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 pnti = 1
snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (proc_to_comm < me) then rcv_pt = 1+pnti+psb_n_elem_recv_
if (nesd>0) call psb_snd(ictxt,& call psb_get_rank(prcid(i),ictxt,proc_to_comm)
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) if ((nerv>0).and.(proc_to_comm /= me)) then
if (nerv>0) call psb_rcv(ictxt,& if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) p2ptag = psb_complex_swap_tag
else if (proc_to_comm > me) then call mpi_irecv(y%combuf(rcv_pt),nerv,&
if (nerv>0) call psb_rcv(ictxt,& & psb_mpi_c_spk_,prcid(i),&
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) & p2ptag, icomm,y%comid(i,2),iret)
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 end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' Gather '
!
else if (swap_send .and. swap_recv) then ! Then gather for sending.
!
! First I post all the non blocking receives
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
idx_pt = 1+pnti+nerv+psb_n_elem_send_
call psb_get_rank(prcid(i),ictxt,proc_to_comm) call y%gth(idx_pt,nesd,idx)
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 snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
!
! Then wait
!
call y%device_wait()
! Then I post all the blocking sends if (debug) write(*,*) me,' isend'
if (usersend) call mpi_barrier(icomm,iret) !
! Then send
!
pnti = 1 pnti = 1
snd_pt = 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_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_complex_swap_tag
if ((nesd>0).and.(proc_to_comm /= me)) then if ((nesd>0).and.(proc_to_comm /= me)) then
if (usersend) then call mpi_isend(y%combuf(snd_pt),nesd,&
call mpi_rsend(sndbuf(snd_pt),nesd,& & psb_mpi_c_spk_,prcid(i),&
& psb_mpi_c_spk_,prcid(i),& & p2ptag,icomm,y%comid(i,1),iret)
& p2ptag,icomm,iret) end if
else
call mpi_send(sndbuf(snd_pt),nesd,&
& psb_mpi_c_spk_,prcid(i),&
& p2ptag,icomm,iret)
end if
if(iret /= mpi_success) then if(iret /= mpi_success) then
ierr(1) = iret ierr(1) = iret
info=psb_err_mpi_error_ info=psb_err_mpi_error_
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if
end if end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do 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 pnti = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_complex_swap_tag
if ((proc_to_comm /= me).and.(nerv>0)) then if (proc_to_comm /= me)then
call mpi_wait(rvhd(i),p2pstat,iret) if (nesd>0) then
if(iret /= mpi_success) then call mpi_wait(y%comid(i,1),p2pstat,iret)
ierr(1) = iret if(iret /= mpi_success) then
info=psb_err_mpi_error_ ierr(1) = iret
call psb_errpush(info,name,i_err=ierr) info=psb_err_mpi_error_
goto 9999 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 end if
else if (proc_to_comm == me) then else if (proc_to_comm == me) then
if (nesd /= nerv) then if (nesd /= nerv) then
@ -1751,14 +1308,12 @@ subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
& 'Fatal error in swapdata: mismatch on self send',& & 'Fatal error in swapdata: mismatch on self send',&
& nerv,nesd & nerv,nesd
end if 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 end if
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' scatter'
else if (swap_send) then
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1 rcv_pt = 1
@ -1766,71 +1321,37 @@ subroutine psi_cswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (nesd>0) call psb_snd(ictxt,& idx_pt = 1+pnti+psb_n_elem_recv_
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) snd_pt = 1+pnti+nerv+psb_n_elem_send_
rcv_pt = rcv_pt + nerv rcv_pt = 1+pnti+psb_n_elem_recv_
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3
end do
else if (swap_recv) then
pnti = 1 if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
snd_pt = 1 call y%sct(rcv_pt,nerv,idx,beta)
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 pnti = pnti + nerv + nesd + 3
end do end do
end if
if (do_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_)
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
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 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) call psb_erractionrestore(err_act)
return return
9999 call psb_error_handler(ictxt,err_act) 9999 call psb_error_handler(ictxt,err_act)
return return
end subroutine psi_cswap_vidx_vect end subroutine psi_cswap_vidx_vect

@ -1038,7 +1038,7 @@ subroutine psi_dswapdata_vect(flag,beta,y,desc_a,work,info,data)
class(psb_d_base_vect_type) :: y class(psb_d_base_vect_type) :: y
real(psb_dpk_) :: beta real(psb_dpk_) :: beta
real(psb_dpk_), target :: work(:) real(psb_dpk_), target :: work(:)
type(psb_desc_type),target :: desc_a type(psb_desc_type), target :: desc_a
integer(psb_ipk_), optional :: data integer(psb_ipk_), optional :: data
! locals ! locals
@ -1073,7 +1073,6 @@ subroutine psi_dswapdata_vect(flag,beta,y,desc_a,work,info,data)
data_ = psb_comm_halo_ data_ = psb_comm_halo_
end if 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) call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
if (info /= psb_success_) then if (info /= psb_success_) then
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list') 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) 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 psi_mod, psb_protect_name => psi_dswap_vidx_vect
use psb_error_mod use psb_error_mod
use psb_realloc_mod
use psb_desc_mod use psb_desc_mod
use psb_penv_mod use psb_penv_mod
use psb_d_base_vect_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 class(psb_d_base_vect_type) :: y
real(psb_dpk_) :: beta real(psb_dpk_) :: beta
real(psb_dpk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
! locals ! locals
integer(psb_mpik_) :: ictxt, icomm, np, me,& 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) integer(psb_ipk_) :: ierr(5)
logical :: swap_mpi, swap_sync, swap_send, swap_recv,& logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
& albf,do_send,do_recv & albf,do_send,do_recv
logical, parameter :: usersend=.false. logical, parameter :: usersend=.false., debug=.false.
real(psb_dpk_), pointer, dimension(:) :: sndbuf, rcvbuf real(psb_dpk_), pointer, dimension(:) :: sndbuf, rcvbuf
#ifdef HAVE_VOLATILE #ifdef HAVE_VOLATILE
@ -1541,159 +1170,65 @@ subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
totrcv_ = totrcv * n totrcv_ = totrcv * n
totsnd_ = totsnd * n totsnd_ = totsnd * n
call idx%sync()
if (swap_mpi) then if (debug) write(*,*) me,'Internal buffer'
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%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
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 if (do_send) then
if (allocated(y%comid)) then
! Pack send buffers !
pnti = 1 ! Unfinished communication? Something is wrong....
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))
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_ info=psb_err_mpi_error_
ierr(1) = -2
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if end if
if (debug) write(*,*) me,'do_send start'
else if (swap_sync) then 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 pnti = 1
snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (proc_to_comm < me) then rcv_pt = 1+pnti+psb_n_elem_recv_
if (nesd>0) call psb_snd(ictxt,& call psb_get_rank(prcid(i),ictxt,proc_to_comm)
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) if ((nerv>0).and.(proc_to_comm /= me)) then
if (nerv>0) call psb_rcv(ictxt,& if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) p2ptag = psb_double_swap_tag
else if (proc_to_comm > me) then call mpi_irecv(y%combuf(rcv_pt),nerv,&
if (nerv>0) call psb_rcv(ictxt,& & psb_mpi_r_dpk_,prcid(i),&
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) & p2ptag, icomm,y%comid(i,2),iret)
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 end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' Gather '
!
else if (swap_send .and. swap_recv) then ! Then gather for sending.
!
! First I post all the non blocking receives
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
idx_pt = 1+pnti+nerv+psb_n_elem_send_
call psb_get_rank(prcid(i),ictxt,proc_to_comm) call y%gth(idx_pt,nesd,idx)
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 snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
!
! Then wait
!
call y%device_wait()
! Then I post all the blocking sends if (debug) write(*,*) me,' isend'
if (usersend) call mpi_barrier(icomm,iret) !
! Then send
!
pnti = 1 pnti = 1
snd_pt = 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_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_double_swap_tag
if ((nesd>0).and.(proc_to_comm /= me)) then if ((nesd>0).and.(proc_to_comm /= me)) then
if (usersend) then call mpi_isend(y%combuf(snd_pt),nesd,&
call mpi_rsend(sndbuf(snd_pt),nesd,& & psb_mpi_r_dpk_,prcid(i),&
& psb_mpi_r_dpk_,prcid(i),& & p2ptag,icomm,y%comid(i,1),iret)
& p2ptag,icomm,iret) end if
else
call mpi_send(sndbuf(snd_pt),nesd,&
& psb_mpi_r_dpk_,prcid(i),&
& p2ptag,icomm,iret)
end if
if(iret /= mpi_success) then if(iret /= mpi_success) then
ierr(1) = iret ierr(1) = iret
info=psb_err_mpi_error_ info=psb_err_mpi_error_
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if
end if end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do 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 pnti = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_double_swap_tag
if ((proc_to_comm /= me).and.(nerv>0)) then if (proc_to_comm /= me)then
call mpi_wait(rvhd(i),p2pstat,iret) if (nesd>0) then
if(iret /= mpi_success) then call mpi_wait(y%comid(i,1),p2pstat,iret)
ierr(1) = iret if(iret /= mpi_success) then
info=psb_err_mpi_error_ ierr(1) = iret
call psb_errpush(info,name,i_err=ierr) info=psb_err_mpi_error_
goto 9999 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 end if
else if (proc_to_comm == me) then else if (proc_to_comm == me) then
if (nesd /= nerv) then if (nesd /= nerv) then
@ -1751,14 +1308,12 @@ subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
& 'Fatal error in swapdata: mismatch on self send',& & 'Fatal error in swapdata: mismatch on self send',&
& nerv,nesd & nerv,nesd
end if 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 end if
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' scatter'
else if (swap_send) then
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1 rcv_pt = 1
@ -1766,71 +1321,37 @@ subroutine psi_dswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (nesd>0) call psb_snd(ictxt,& idx_pt = 1+pnti+psb_n_elem_recv_
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) snd_pt = 1+pnti+nerv+psb_n_elem_send_
rcv_pt = rcv_pt + nerv rcv_pt = 1+pnti+psb_n_elem_recv_
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3
end do
else if (swap_recv) then
pnti = 1 if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
snd_pt = 1 call y%sct(rcv_pt,nerv,idx,beta)
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 pnti = pnti + nerv + nesd + 3
end do end do
end if
if (do_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_)
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
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 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) call psb_erractionrestore(err_act)
return return
9999 call psb_error_handler(ictxt,err_act) 9999 call psb_error_handler(ictxt,err_act)
return return
end subroutine psi_dswap_vidx_vect end subroutine psi_dswap_vidx_vect

@ -1038,7 +1038,7 @@ subroutine psi_iswapdata_vect(flag,beta,y,desc_a,work,info,data)
class(psb_i_base_vect_type) :: y class(psb_i_base_vect_type) :: y
integer(psb_ipk_) :: beta integer(psb_ipk_) :: beta
integer(psb_ipk_), target :: work(:) integer(psb_ipk_), target :: work(:)
type(psb_desc_type),target :: desc_a type(psb_desc_type), target :: desc_a
integer(psb_ipk_), optional :: data integer(psb_ipk_), optional :: data
! locals ! locals
@ -1073,7 +1073,6 @@ subroutine psi_iswapdata_vect(flag,beta,y,desc_a,work,info,data)
data_ = psb_comm_halo_ data_ = psb_comm_halo_
end if 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) call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
if (info /= psb_success_) then if (info /= psb_success_) then
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list') 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) 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 psi_mod, psb_protect_name => psi_iswap_vidx_vect
use psb_error_mod use psb_error_mod
use psb_realloc_mod
use psb_desc_mod use psb_desc_mod
use psb_penv_mod use psb_penv_mod
use psb_i_base_vect_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 class(psb_i_base_vect_type) :: y
integer(psb_ipk_) :: beta integer(psb_ipk_) :: beta
integer(psb_ipk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
! locals ! locals
integer(psb_mpik_) :: ictxt, icomm, np, me,& 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) integer(psb_ipk_) :: ierr(5)
logical :: swap_mpi, swap_sync, swap_send, swap_recv,& logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
& albf,do_send,do_recv & albf,do_send,do_recv
logical, parameter :: usersend=.false. logical, parameter :: usersend=.false., debug=.false.
integer(psb_ipk_), pointer, dimension(:) :: sndbuf, rcvbuf integer(psb_ipk_), pointer, dimension(:) :: sndbuf, rcvbuf
#ifdef HAVE_VOLATILE #ifdef HAVE_VOLATILE
@ -1541,159 +1170,65 @@ subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
totrcv_ = totrcv * n totrcv_ = totrcv * n
totsnd_ = totsnd * n totsnd_ = totsnd * n
call idx%sync()
if (swap_mpi) then if (debug) write(*,*) me,'Internal buffer'
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%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
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 if (do_send) then
if (allocated(y%comid)) then
! Pack send buffers !
pnti = 1 ! Unfinished communication? Something is wrong....
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))
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_ info=psb_err_mpi_error_
ierr(1) = -2
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if end if
if (debug) write(*,*) me,'do_send start'
else if (swap_sync) then 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 pnti = 1
snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (proc_to_comm < me) then rcv_pt = 1+pnti+psb_n_elem_recv_
if (nesd>0) call psb_snd(ictxt,& call psb_get_rank(prcid(i),ictxt,proc_to_comm)
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) if ((nerv>0).and.(proc_to_comm /= me)) then
if (nerv>0) call psb_rcv(ictxt,& if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) p2ptag = psb_int_swap_tag
else if (proc_to_comm > me) then call mpi_irecv(y%combuf(rcv_pt),nerv,&
if (nerv>0) call psb_rcv(ictxt,& & psb_mpi_ipk_integer,prcid(i),&
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) & p2ptag, icomm,y%comid(i,2),iret)
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 end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' Gather '
!
else if (swap_send .and. swap_recv) then ! Then gather for sending.
!
! First I post all the non blocking receives
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
idx_pt = 1+pnti+nerv+psb_n_elem_send_
call psb_get_rank(prcid(i),ictxt,proc_to_comm) call y%gth(idx_pt,nesd,idx)
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 snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
!
! Then wait
!
call y%device_wait()
! Then I post all the blocking sends if (debug) write(*,*) me,' isend'
if (usersend) call mpi_barrier(icomm,iret) !
! Then send
!
pnti = 1 pnti = 1
snd_pt = 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_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_int_swap_tag
if ((nesd>0).and.(proc_to_comm /= me)) then if ((nesd>0).and.(proc_to_comm /= me)) then
if (usersend) then call mpi_isend(y%combuf(snd_pt),nesd,&
call mpi_rsend(sndbuf(snd_pt),nesd,& & psb_mpi_ipk_integer,prcid(i),&
& psb_mpi_ipk_integer,prcid(i),& & p2ptag,icomm,y%comid(i,1),iret)
& p2ptag,icomm,iret) end if
else
call mpi_send(sndbuf(snd_pt),nesd,&
& psb_mpi_ipk_integer,prcid(i),&
& p2ptag,icomm,iret)
end if
if(iret /= mpi_success) then if(iret /= mpi_success) then
ierr(1) = iret ierr(1) = iret
info=psb_err_mpi_error_ info=psb_err_mpi_error_
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if
end if end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do 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 pnti = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_int_swap_tag
if ((proc_to_comm /= me).and.(nerv>0)) then if (proc_to_comm /= me)then
call mpi_wait(rvhd(i),p2pstat,iret) if (nesd>0) then
if(iret /= mpi_success) then call mpi_wait(y%comid(i,1),p2pstat,iret)
ierr(1) = iret if(iret /= mpi_success) then
info=psb_err_mpi_error_ ierr(1) = iret
call psb_errpush(info,name,i_err=ierr) info=psb_err_mpi_error_
goto 9999 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 end if
else if (proc_to_comm == me) then else if (proc_to_comm == me) then
if (nesd /= nerv) then if (nesd /= nerv) then
@ -1751,14 +1308,12 @@ subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
& 'Fatal error in swapdata: mismatch on self send',& & 'Fatal error in swapdata: mismatch on self send',&
& nerv,nesd & nerv,nesd
end if 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 end if
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' scatter'
else if (swap_send) then
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1 rcv_pt = 1
@ -1766,71 +1321,37 @@ subroutine psi_iswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (nesd>0) call psb_snd(ictxt,& idx_pt = 1+pnti+psb_n_elem_recv_
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) snd_pt = 1+pnti+nerv+psb_n_elem_send_
rcv_pt = rcv_pt + nerv rcv_pt = 1+pnti+psb_n_elem_recv_
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3
end do
else if (swap_recv) then
pnti = 1 if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
snd_pt = 1 call y%sct(rcv_pt,nerv,idx,beta)
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 pnti = pnti + nerv + nesd + 3
end do end do
end if
if (do_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_)
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
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 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) call psb_erractionrestore(err_act)
return return
9999 call psb_error_handler(ictxt,err_act) 9999 call psb_error_handler(ictxt,err_act)
return return
end subroutine psi_iswap_vidx_vect end subroutine psi_iswap_vidx_vect

@ -1038,7 +1038,7 @@ subroutine psi_sswapdata_vect(flag,beta,y,desc_a,work,info,data)
class(psb_s_base_vect_type) :: y class(psb_s_base_vect_type) :: y
real(psb_spk_) :: beta real(psb_spk_) :: beta
real(psb_spk_), target :: work(:) real(psb_spk_), target :: work(:)
type(psb_desc_type),target :: desc_a type(psb_desc_type), target :: desc_a
integer(psb_ipk_), optional :: data integer(psb_ipk_), optional :: data
! locals ! locals
@ -1073,7 +1073,6 @@ subroutine psi_sswapdata_vect(flag,beta,y,desc_a,work,info,data)
data_ = psb_comm_halo_ data_ = psb_comm_halo_
end if 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) call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
if (info /= psb_success_) then if (info /= psb_success_) then
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list') 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) 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 psi_mod, psb_protect_name => psi_sswap_vidx_vect
use psb_error_mod use psb_error_mod
use psb_realloc_mod
use psb_desc_mod use psb_desc_mod
use psb_penv_mod use psb_penv_mod
use psb_s_base_vect_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 class(psb_s_base_vect_type) :: y
real(psb_spk_) :: beta real(psb_spk_) :: beta
real(psb_spk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
! locals ! locals
integer(psb_mpik_) :: ictxt, icomm, np, me,& 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) integer(psb_ipk_) :: ierr(5)
logical :: swap_mpi, swap_sync, swap_send, swap_recv,& logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
& albf,do_send,do_recv & albf,do_send,do_recv
logical, parameter :: usersend=.false. logical, parameter :: usersend=.false., debug=.false.
real(psb_spk_), pointer, dimension(:) :: sndbuf, rcvbuf real(psb_spk_), pointer, dimension(:) :: sndbuf, rcvbuf
#ifdef HAVE_VOLATILE #ifdef HAVE_VOLATILE
@ -1541,159 +1170,65 @@ subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
totrcv_ = totrcv * n totrcv_ = totrcv * n
totsnd_ = totsnd * n totsnd_ = totsnd * n
call idx%sync()
if (swap_mpi) then if (debug) write(*,*) me,'Internal buffer'
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%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
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 if (do_send) then
if (allocated(y%comid)) then
! Pack send buffers !
pnti = 1 ! Unfinished communication? Something is wrong....
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))
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_ info=psb_err_mpi_error_
ierr(1) = -2
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if end if
if (debug) write(*,*) me,'do_send start'
else if (swap_sync) then 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 pnti = 1
snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (proc_to_comm < me) then rcv_pt = 1+pnti+psb_n_elem_recv_
if (nesd>0) call psb_snd(ictxt,& call psb_get_rank(prcid(i),ictxt,proc_to_comm)
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) if ((nerv>0).and.(proc_to_comm /= me)) then
if (nerv>0) call psb_rcv(ictxt,& if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) p2ptag = psb_real_swap_tag
else if (proc_to_comm > me) then call mpi_irecv(y%combuf(rcv_pt),nerv,&
if (nerv>0) call psb_rcv(ictxt,& & psb_mpi_r_spk_,prcid(i),&
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) & p2ptag, icomm,y%comid(i,2),iret)
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 end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' Gather '
!
else if (swap_send .and. swap_recv) then ! Then gather for sending.
!
! First I post all the non blocking receives
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
idx_pt = 1+pnti+nerv+psb_n_elem_send_
call psb_get_rank(prcid(i),ictxt,proc_to_comm) call y%gth(idx_pt,nesd,idx)
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 snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
!
! Then wait
!
call y%device_wait()
! Then I post all the blocking sends if (debug) write(*,*) me,' isend'
if (usersend) call mpi_barrier(icomm,iret) !
! Then send
!
pnti = 1 pnti = 1
snd_pt = 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_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_real_swap_tag
if ((nesd>0).and.(proc_to_comm /= me)) then if ((nesd>0).and.(proc_to_comm /= me)) then
if (usersend) then call mpi_isend(y%combuf(snd_pt),nesd,&
call mpi_rsend(sndbuf(snd_pt),nesd,& & psb_mpi_r_spk_,prcid(i),&
& psb_mpi_r_spk_,prcid(i),& & p2ptag,icomm,y%comid(i,1),iret)
& p2ptag,icomm,iret) end if
else
call mpi_send(sndbuf(snd_pt),nesd,&
& psb_mpi_r_spk_,prcid(i),&
& p2ptag,icomm,iret)
end if
if(iret /= mpi_success) then if(iret /= mpi_success) then
ierr(1) = iret ierr(1) = iret
info=psb_err_mpi_error_ info=psb_err_mpi_error_
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if
end if end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do 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 pnti = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_real_swap_tag
if ((proc_to_comm /= me).and.(nerv>0)) then if (proc_to_comm /= me)then
call mpi_wait(rvhd(i),p2pstat,iret) if (nesd>0) then
if(iret /= mpi_success) then call mpi_wait(y%comid(i,1),p2pstat,iret)
ierr(1) = iret if(iret /= mpi_success) then
info=psb_err_mpi_error_ ierr(1) = iret
call psb_errpush(info,name,i_err=ierr) info=psb_err_mpi_error_
goto 9999 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 end if
else if (proc_to_comm == me) then else if (proc_to_comm == me) then
if (nesd /= nerv) then if (nesd /= nerv) then
@ -1751,14 +1308,12 @@ subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
& 'Fatal error in swapdata: mismatch on self send',& & 'Fatal error in swapdata: mismatch on self send',&
& nerv,nesd & nerv,nesd
end if 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 end if
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' scatter'
else if (swap_send) then
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1 rcv_pt = 1
@ -1766,71 +1321,37 @@ subroutine psi_sswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (nesd>0) call psb_snd(ictxt,& idx_pt = 1+pnti+psb_n_elem_recv_
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) snd_pt = 1+pnti+nerv+psb_n_elem_send_
rcv_pt = rcv_pt + nerv rcv_pt = 1+pnti+psb_n_elem_recv_
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3
end do
else if (swap_recv) then
pnti = 1 if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
snd_pt = 1 call y%sct(rcv_pt,nerv,idx,beta)
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 pnti = pnti + nerv + nesd + 3
end do end do
end if
if (do_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_)
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
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 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) call psb_erractionrestore(err_act)
return return
9999 call psb_error_handler(ictxt,err_act) 9999 call psb_error_handler(ictxt,err_act)
return return
end subroutine psi_sswap_vidx_vect end subroutine psi_sswap_vidx_vect

@ -1038,7 +1038,7 @@ subroutine psi_zswapdata_vect(flag,beta,y,desc_a,work,info,data)
class(psb_z_base_vect_type) :: y class(psb_z_base_vect_type) :: y
complex(psb_dpk_) :: beta complex(psb_dpk_) :: beta
complex(psb_dpk_), target :: work(:) complex(psb_dpk_), target :: work(:)
type(psb_desc_type),target :: desc_a type(psb_desc_type), target :: desc_a
integer(psb_ipk_), optional :: data integer(psb_ipk_), optional :: data
! locals ! locals
@ -1073,7 +1073,6 @@ subroutine psi_zswapdata_vect(flag,beta,y,desc_a,work,info,data)
data_ = psb_comm_halo_ data_ = psb_comm_halo_
end if 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) call desc_a%get_list(data_,d_vidx,totxch,idxr,idxs,info)
if (info /= psb_success_) then if (info /= psb_success_) then
call psb_errpush(psb_err_internal_error_,name,a_err='psb_cd_get_list') 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) 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 psi_mod, psb_protect_name => psi_zswap_vidx_vect
use psb_error_mod use psb_error_mod
use psb_realloc_mod
use psb_desc_mod use psb_desc_mod
use psb_penv_mod use psb_penv_mod
use psb_z_base_vect_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 class(psb_z_base_vect_type) :: y
complex(psb_dpk_) :: beta complex(psb_dpk_) :: beta
complex(psb_dpk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
! locals ! locals
integer(psb_mpik_) :: ictxt, icomm, np, me,& 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) integer(psb_ipk_) :: ierr(5)
logical :: swap_mpi, swap_sync, swap_send, swap_recv,& logical :: swap_mpi, swap_sync, swap_send, swap_recv,&
& albf,do_send,do_recv & albf,do_send,do_recv
logical, parameter :: usersend=.false. logical, parameter :: usersend=.false., debug=.false.
complex(psb_dpk_), pointer, dimension(:) :: sndbuf, rcvbuf complex(psb_dpk_), pointer, dimension(:) :: sndbuf, rcvbuf
#ifdef HAVE_VOLATILE #ifdef HAVE_VOLATILE
@ -1541,159 +1170,65 @@ subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
totrcv_ = totrcv * n totrcv_ = totrcv * n
totsnd_ = totsnd * n totsnd_ = totsnd * n
call idx%sync()
if (swap_mpi) then if (debug) write(*,*) me,'Internal buffer'
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%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
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 if (do_send) then
if (allocated(y%comid)) then
! Pack send buffers !
pnti = 1 ! Unfinished communication? Something is wrong....
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))
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_ info=psb_err_mpi_error_
ierr(1) = -2
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if end if
if (debug) write(*,*) me,'do_send start'
else if (swap_sync) then 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 pnti = 1
snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (proc_to_comm < me) then rcv_pt = 1+pnti+psb_n_elem_recv_
if (nesd>0) call psb_snd(ictxt,& call psb_get_rank(prcid(i),ictxt,proc_to_comm)
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) if ((nerv>0).and.(proc_to_comm /= me)) then
if (nerv>0) call psb_rcv(ictxt,& if (debug) write(*,*) me,'Posting receive from',prcid(i),rcv_pt
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) p2ptag = psb_dcomplex_swap_tag
else if (proc_to_comm > me) then call mpi_irecv(y%combuf(rcv_pt),nerv,&
if (nerv>0) call psb_rcv(ictxt,& & psb_mpi_c_dpk_,prcid(i),&
& rcvbuf(rcv_pt:rcv_pt+nerv-1), proc_to_comm) & p2ptag, icomm,y%comid(i,2),iret)
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 end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' Gather '
!
else if (swap_send .and. swap_recv) then ! Then gather for sending.
!
! First I post all the non blocking receives
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
idx_pt = 1+pnti+nerv+psb_n_elem_send_
call psb_get_rank(prcid(i),ictxt,proc_to_comm) call y%gth(idx_pt,nesd,idx)
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 snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
!
! Then wait
!
call y%device_wait()
! Then I post all the blocking sends if (debug) write(*,*) me,' isend'
if (usersend) call mpi_barrier(icomm,iret) !
! Then send
!
pnti = 1 pnti = 1
snd_pt = 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_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_dcomplex_swap_tag
if ((nesd>0).and.(proc_to_comm /= me)) then if ((nesd>0).and.(proc_to_comm /= me)) then
if (usersend) then call mpi_isend(y%combuf(snd_pt),nesd,&
call mpi_rsend(sndbuf(snd_pt),nesd,& & psb_mpi_c_dpk_,prcid(i),&
& psb_mpi_c_dpk_,prcid(i),& & p2ptag,icomm,y%comid(i,1),iret)
& p2ptag,icomm,iret) end if
else
call mpi_send(sndbuf(snd_pt),nesd,&
& psb_mpi_c_dpk_,prcid(i),&
& p2ptag,icomm,iret)
end if
if(iret /= mpi_success) then if(iret /= mpi_success) then
ierr(1) = iret ierr(1) = iret
info=psb_err_mpi_error_ info=psb_err_mpi_error_
call psb_errpush(info,name,i_err=ierr) call psb_errpush(info,name,i_err=ierr)
goto 9999 goto 9999
end if
end if end if
rcv_pt = rcv_pt + nerv
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do 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 pnti = 1
do i=1, totxch do i=1, totxch
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) 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 p2ptag = psb_dcomplex_swap_tag
if ((proc_to_comm /= me).and.(nerv>0)) then if (proc_to_comm /= me)then
call mpi_wait(rvhd(i),p2pstat,iret) if (nesd>0) then
if(iret /= mpi_success) then call mpi_wait(y%comid(i,1),p2pstat,iret)
ierr(1) = iret if(iret /= mpi_success) then
info=psb_err_mpi_error_ ierr(1) = iret
call psb_errpush(info,name,i_err=ierr) info=psb_err_mpi_error_
goto 9999 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 end if
else if (proc_to_comm == me) then else if (proc_to_comm == me) then
if (nesd /= nerv) then if (nesd /= nerv) then
@ -1751,14 +1308,12 @@ subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
& 'Fatal error in swapdata: mismatch on self send',& & 'Fatal error in swapdata: mismatch on self send',&
& nerv,nesd & nerv,nesd
end if 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 end if
pnti = pnti + nerv + nesd + 3 pnti = pnti + nerv + nesd + 3
end do end do
if (debug) write(*,*) me,' scatter'
else if (swap_send) then
pnti = 1 pnti = 1
snd_pt = 1 snd_pt = 1
rcv_pt = 1 rcv_pt = 1
@ -1766,71 +1321,37 @@ subroutine psi_zswap_vidx_vect(iictxt,iicomm,flag,beta,y,idx,totxch,totsnd,totrc
proc_to_comm = idx%v(pnti+psb_proc_id_) proc_to_comm = idx%v(pnti+psb_proc_id_)
nerv = idx%v(pnti+psb_n_elem_recv_) nerv = idx%v(pnti+psb_n_elem_recv_)
nesd = idx%v(pnti+nerv+psb_n_elem_send_) nesd = idx%v(pnti+nerv+psb_n_elem_send_)
if (nesd>0) call psb_snd(ictxt,& idx_pt = 1+pnti+psb_n_elem_recv_
& sndbuf(snd_pt:snd_pt+nesd-1), proc_to_comm) snd_pt = 1+pnti+nerv+psb_n_elem_send_
rcv_pt = rcv_pt + nerv rcv_pt = 1+pnti+psb_n_elem_recv_
snd_pt = snd_pt + nesd
pnti = pnti + nerv + nesd + 3
end do
else if (swap_recv) then
pnti = 1 if (debug) write(0,*)me,' Received from: ',prcid(i),y%combuf(rcv_pt:rcv_pt+nerv-1)
snd_pt = 1 call y%sct(rcv_pt,nerv,idx,beta)
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 pnti = pnti + nerv + nesd + 3
end do end do
end if
if (do_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_)
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
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 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) call psb_erractionrestore(err_act)
return return
9999 call psb_error_handler(ictxt,err_act) 9999 call psb_error_handler(ictxt,err_act)
return return
end subroutine psi_zswap_vidx_vect end subroutine psi_zswap_vidx_vect

@ -61,6 +61,8 @@ module psb_i_base_vect_mod
type psb_i_base_vect_type type psb_i_base_vect_type
!> Values. !> Values.
integer(psb_ipk_), allocatable :: v(:) integer(psb_ipk_), allocatable :: v(:)
integer(psb_ipk_), allocatable :: combuf(:)
integer(psb_ipk_), allocatable :: comid(:,:)
contains contains
! !
! Constructors/allocators ! 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_dev => i_base_set_dev
procedure, pass(x) :: set_sync => i_base_set_sync 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 ! Basic info
procedure, pass(x) :: get_nrows => i_base_get_nrows procedure, pass(x) :: get_nrows => i_base_get_nrows
@ -134,6 +147,9 @@ module psb_i_base_vect_mod
! Scaling and norms ! Scaling and norms
! !
procedure, pass(x) :: scal => i_base_scal 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) :: nrm2 => i_base_nrm2
procedure, pass(x) :: amax => i_base_amax procedure, pass(x) :: amax => i_base_amax
procedure, pass(x) :: asum => i_base_asum 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) :: gthab => i_base_gthab
procedure, pass(x) :: gthzv => i_base_gthzv procedure, pass(x) :: gthzv => i_base_gthzv
procedure, pass(x) :: gthzv_x => i_base_gthzv_x 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 => i_base_sctb
procedure, pass(y) :: sctb_x => i_base_sctb_x 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 end type psb_i_base_vect_type
public :: psb_i_base_vect public :: psb_i_base_vect
@ -344,8 +362,8 @@ contains
case default case default
info = 321 info = 321
! !$ call psb_errpush(info,name) ! !$ call psb_errpush(info,name)
! !$ goto 9999 ! !$ goto 9999
end select end select
end if end if
call x%set_host() call x%set_host()
@ -356,7 +374,6 @@ contains
end subroutine i_base_ins_a end subroutine i_base_ins_a
subroutine i_base_ins_v(n,irl,val,dupl,x,info) subroutine i_base_ins_v(n,irl,val,dupl,x,info)
use psi_serial_mod use psi_serial_mod
implicit none implicit none
@ -396,7 +413,7 @@ contains
class(psb_i_base_vect_type), intent(inout) :: x class(psb_i_base_vect_type), intent(inout) :: x
if (allocated(x%v)) x%v=izero if (allocated(x%v)) x%v=izero
call x%set_host()
end subroutine i_base_zero end subroutine i_base_zero
@ -422,11 +439,12 @@ contains
class(psb_i_base_vect_type), intent(inout) :: x class(psb_i_base_vect_type), intent(inout) :: x
integer(psb_ipk_), intent(out) :: info integer(psb_ipk_), intent(out) :: info
info = 0
if (x%get_nrows() < n) & if (x%get_nrows() < n) &
& call psb_realloc(n,x%v,info) & call psb_realloc(n,x%v,info)
if (info /= 0) & if (info /= 0) &
& call psb_errpush(psb_err_alloc_dealloc_,'vect_asb') & call psb_errpush(psb_err_alloc_dealloc_,'vect_asb')
call x%sync()
end subroutine i_base_asb end subroutine i_base_asb
@ -447,6 +465,8 @@ contains
info = 0 info = 0
if (allocated(x%v)) deallocate(x%v, stat=info) 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 & if (info /= 0) call &
& psb_errpush(psb_err_alloc_dealloc_,'vect_free') & psb_errpush(psb_err_alloc_dealloc_,'vect_free')
@ -611,7 +631,7 @@ contains
integer(psb_ipk_) :: info integer(psb_ipk_) :: info
if (.not.allocated(x%v)) return if (.not.allocated(x%v)) return
call x%sync() if (.not.x%is_host()) call x%sync()
allocate(res(x%get_nrows()),stat=info) allocate(res(x%get_nrows()),stat=info)
if (info /= 0) then if (info /= 0) then
call psb_errpush(psb_err_alloc_dealloc_,'base_get_vect') call psb_errpush(psb_err_alloc_dealloc_,'base_get_vect')
@ -634,10 +654,44 @@ contains
integer(psb_ipk_), intent(in) :: val integer(psb_ipk_), intent(in) :: val
integer(psb_ipk_) :: info integer(psb_ipk_) :: info
x%v = val x%v = val
call x%set_host()
end subroutine i_base_set_scal 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 !> Function base_set_vect
!! \memberof psb_i_base_vect_type !! \memberof psb_i_base_vect_type
@ -656,6 +710,7 @@ contains
else else
x%v = val x%v = val
end if end if
call x%set_host()
end subroutine i_base_set_vect end subroutine i_base_set_vect
@ -738,12 +793,9 @@ contains
integer(psb_ipk_), intent (in) :: alpha, beta integer(psb_ipk_), intent (in) :: alpha, beta
integer(psb_ipk_), intent(out) :: info integer(psb_ipk_), intent(out) :: info
select type(xx => x) if (x%is_dev()) call x%sync()
type is (psb_i_base_vect_type)
call psb_geaxpby(m,alpha,x%v,beta,y%v,info) call y%axpby(m,alpha,x%v,beta,info)
class default
call y%axpby(m,alpha,x%v,beta,info)
end select
end subroutine i_base_axpby_v end subroutine i_base_axpby_v
@ -769,7 +821,9 @@ contains
integer(psb_ipk_), intent (in) :: alpha, beta integer(psb_ipk_), intent (in) :: alpha, beta
integer(psb_ipk_), intent(out) :: info integer(psb_ipk_), intent(out) :: info
if (y%is_dev()) call y%sync()
call psb_geaxpby(m,alpha,x,beta,y%v,info) call psb_geaxpby(m,alpha,x,beta,y%v,info)
call y%set_host()
end subroutine i_base_axpby_a end subroutine i_base_axpby_a
@ -798,15 +852,8 @@ contains
integer(psb_ipk_) :: i, n integer(psb_ipk_) :: i, n
info = 0 info = 0
select type(xx => x) if (x%is_dev()) call x%sync()
type is (psb_i_base_vect_type) call y%mlt(x%v,info)
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
end subroutine i_base_mlt_v end subroutine i_base_mlt_v
@ -826,10 +873,12 @@ contains
integer(psb_ipk_) :: i, n integer(psb_ipk_) :: i, n
info = 0 info = 0
if (y%is_dev()) call y%sync()
n = min(size(y%v), size(x)) n = min(size(y%v), size(x))
do i=1, n do i=1, n
y%v(i) = y%v(i)*x(i) y%v(i) = y%v(i)*x(i)
end do end do
call y%set_host()
end subroutine i_base_mlt_a end subroutine i_base_mlt_a
@ -856,6 +905,8 @@ contains
integer(psb_ipk_) :: i, n integer(psb_ipk_) :: i, n
info = 0 info = 0
if (z%is_dev()) call z%sync()
n = min(size(z%v), size(x), size(y)) n = min(size(z%v), size(x), size(y))
!!$ write(0,*) 'Mlt_a_2: ',n !!$ write(0,*) 'Mlt_a_2: ',n
if (alpha == izero) then if (alpha == izero) then
@ -911,6 +962,8 @@ contains
end if end if
end if end if
end if end if
call z%set_host()
end subroutine i_base_mlt_a_2 end subroutine i_base_mlt_a_2
! !
@ -938,6 +991,8 @@ contains
logical :: conjgx_, conjgy_ logical :: conjgx_, conjgy_
info = 0 info = 0
if (y%is_dev()) call y%sync()
if (x%is_dev()) call x%sync()
if (.not.psb_i_is_complex_) then if (.not.psb_i_is_complex_) then
call z%mlt(alpha,x%v,y%v,beta,info) call z%mlt(alpha,x%v,y%v,beta,info)
else else
@ -964,7 +1019,7 @@ contains
integer(psb_ipk_) :: i, n integer(psb_ipk_) :: i, n
info = 0 info = 0
if (y%is_dev()) call y%sync()
call z%mlt(alpha,x,y%v,beta,info) call z%mlt(alpha,x,y%v,beta,info)
end subroutine i_base_mlt_av end subroutine i_base_mlt_av
@ -980,7 +1035,7 @@ contains
integer(psb_ipk_) :: i, n integer(psb_ipk_) :: i, n
info = 0 info = 0
if (x%is_dev()) call x%sync()
call z%mlt(alpha,y,x,beta,info) call z%mlt(alpha,y,x,beta,info)
end subroutine i_base_mlt_va end subroutine i_base_mlt_va
@ -1000,7 +1055,10 @@ contains
class(psb_i_base_vect_type), intent(inout) :: x class(psb_i_base_vect_type), intent(inout) :: x
integer(psb_ipk_), intent (in) :: alpha 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 end subroutine i_base_scal
@ -1018,6 +1076,7 @@ contains
integer(psb_ipk_) :: res integer(psb_ipk_) :: res
integer(psb_ipk_), external :: inrm2 integer(psb_ipk_), external :: inrm2
if (x%is_dev()) call x%sync()
res = inrm2(n,x%v,1) res = inrm2(n,x%v,1)
end function i_base_nrm2 end function i_base_nrm2
@ -1033,6 +1092,7 @@ contains
integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_) :: res integer(psb_ipk_) :: res
if (x%is_dev()) call x%sync()
res = maxval(abs(x%v(1:n))) res = maxval(abs(x%v(1:n)))
end function i_base_amax end function i_base_amax
@ -1048,6 +1108,7 @@ contains
integer(psb_ipk_), intent(in) :: n integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_) :: res integer(psb_ipk_) :: res
if (x%is_dev()) call x%sync()
res = sum(abs(x%v(1:n))) res = sum(abs(x%v(1:n)))
end function i_base_asum end function i_base_asum
@ -1071,7 +1132,7 @@ contains
integer(psb_ipk_) :: alpha, beta, y(:) integer(psb_ipk_) :: alpha, beta, y(:)
class(psb_i_base_vect_type) :: x 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) call psi_gth(n,idx,alpha,x%v,beta,y)
end subroutine i_base_gthab end subroutine i_base_gthab
@ -1091,10 +1152,108 @@ contains
integer(psb_ipk_) :: y(:) integer(psb_ipk_) :: y(:)
class(psb_i_base_vect_type) :: x class(psb_i_base_vect_type) :: x
if (idx%is_dev()) call idx%sync()
call x%gth(n,idx%v(i:),y) call x%gth(n,idx%v(i:),y)
end subroutine i_base_gthzv_x 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 ! shortcut alpha=1 beta=0
! !
@ -1110,7 +1269,7 @@ contains
integer(psb_ipk_) :: y(:) integer(psb_ipk_) :: y(:)
class(psb_i_base_vect_type) :: x 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) call psi_gth(n,idx,x%v,y)
end subroutine i_base_gthzv end subroutine i_base_gthzv
@ -1134,7 +1293,7 @@ contains
integer(psb_ipk_) :: beta, x(:) integer(psb_ipk_) :: beta, x(:)
class(psb_i_base_vect_type) :: y 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 psi_sct(n,idx,x,beta,y%v)
call y%set_host() call y%set_host()
@ -1147,13 +1306,18 @@ contains
integer(psb_ipk_) :: beta, x(:) integer(psb_ipk_) :: beta, x(:)
class(psb_i_base_vect_type) :: y 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%sct(n,idx%v(i:),x,beta)
call y%set_host()
end subroutine i_base_sctb_x end subroutine i_base_sctb_x
end module psb_i_base_vect_mod end module psb_i_base_vect_mod
module psb_i_base_multivect_mod module psb_i_base_multivect_mod
use psb_const_mod use psb_const_mod
@ -1701,8 +1865,7 @@ contains
function i_base_mv_get_vect(x) result(res) function i_base_mv_get_vect(x) result(res)
class(psb_i_base_multivect_type), intent(inout) :: x class(psb_i_base_multivect_type), intent(inout) :: x
integer(psb_ipk_), allocatable :: res(:,:) integer(psb_ipk_), allocatable :: res(:,:)
integer(psb_ipk_) :: info, m, n integer(psb_ipk_) :: info,m,n
m = x%get_nrows() m = x%get_nrows()
n = x%get_ncols() n = x%get_ncols()
if (.not.allocated(x%v)) return if (.not.allocated(x%v)) return
@ -1713,7 +1876,6 @@ contains
return return
end if end if
res(1:m,1:n) = x%v(1:m,1:n) res(1:m,1:n) = x%v(1:m,1:n)
end function i_base_mv_get_vect end function i_base_mv_get_vect
! !
@ -1772,7 +1934,7 @@ contains
!!$ class(psb_i_base_multivect_type), intent(inout) :: x, y !!$ class(psb_i_base_multivect_type), intent(inout) :: x, y
!!$ integer(psb_ipk_), intent(in) :: n !!$ integer(psb_ipk_), intent(in) :: n
!!$ integer(psb_ipk_) :: res !!$ integer(psb_ipk_) :: res
!!$ integer(psb_ipk_), external :: idot !!$ integer(psb_ipk_), external :: ddot
!!$ !!$
!!$ res = izero !!$ res = izero
!!$ ! !!$ !
@ -1784,7 +1946,7 @@ contains
!!$ ! !!$ !
!!$ select type(yy => y) !!$ select type(yy => y)
!!$ type is (psb_i_base_multivect_type) !!$ 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 !!$ class default
!!$ res = y%dot(n,x%v) !!$ res = y%dot(n,x%v)
!!$ end select !!$ end select
@ -1807,9 +1969,9 @@ contains
!!$ integer(psb_ipk_), intent(in) :: y(:) !!$ integer(psb_ipk_), intent(in) :: y(:)
!!$ integer(psb_ipk_), intent(in) :: n !!$ integer(psb_ipk_), intent(in) :: n
!!$ integer(psb_ipk_) :: res !!$ 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 !!$ end function i_base_mv_dot_a
@ -2113,9 +2275,9 @@ contains
!!$ class(psb_i_base_multivect_type), intent(inout) :: x !!$ class(psb_i_base_multivect_type), intent(inout) :: x
!!$ integer(psb_ipk_), intent(in) :: n !!$ integer(psb_ipk_), intent(in) :: n
!!$ integer(psb_ipk_) :: res !!$ 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 !!$ end function i_base_mv_nrm2
!!$ !!$
@ -2241,7 +2403,7 @@ contains
!!$ use psi_serial_mod !!$ use psi_serial_mod
!!$ integer(psb_ipk_) :: i, n !!$ integer(psb_ipk_) :: i, n
!!$ class(psb_i_base_multivect_type) :: idx !!$ class(psb_i_base_multivect_type) :: idx
!!$ integer(psb_ipk_) :: beta, x(:) !!$ integer( psb_ipk_) :: beta, x(:)
!!$ class(psb_i_base_multivect_type) :: y !!$ class(psb_i_base_multivect_type) :: y
!!$ !!$
!!$ call y%sct(n,idx%v(i:),x,beta) !!$ call y%sct(n,idx%v(i:),x,beta)
@ -2249,3 +2411,4 @@ contains
!!$ end subroutine i_base_mv_sctb_x !!$ end subroutine i_base_mv_sctb_x
end module psb_i_base_multivect_mod end module psb_i_base_multivect_mod

@ -80,16 +80,6 @@ module psi_c_mod
complex(psb_spk_),target :: work(:) complex(psb_spk_),target :: work(:)
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
end subroutine psi_cswapidxv 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) 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 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 integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
@ -97,7 +87,7 @@ module psi_c_mod
class(psb_c_base_vect_type) :: y class(psb_c_base_vect_type) :: y
complex(psb_spk_) :: beta complex(psb_spk_) :: beta
complex(psb_spk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
end subroutine psi_cswap_vidx_vect end subroutine psi_cswap_vidx_vect
end interface end interface

@ -80,16 +80,6 @@ module psi_d_mod
real(psb_dpk_),target :: work(:) real(psb_dpk_),target :: work(:)
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
end subroutine psi_dswapidxv 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) 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 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 integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
@ -97,7 +87,7 @@ module psi_d_mod
class(psb_d_base_vect_type) :: y class(psb_d_base_vect_type) :: y
real(psb_dpk_) :: beta real(psb_dpk_) :: beta
real(psb_dpk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
end subroutine psi_dswap_vidx_vect end subroutine psi_dswap_vidx_vect
end interface end interface

@ -258,7 +258,7 @@ module psi_i_mod
class(psb_i_base_vect_type) :: y class(psb_i_base_vect_type) :: y
integer(psb_ipk_) :: beta integer(psb_ipk_) :: beta
integer(psb_ipk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
end subroutine psi_iswap_vidx_vect end subroutine psi_iswap_vidx_vect
end interface end interface

@ -80,16 +80,6 @@ module psi_s_mod
real(psb_spk_),target :: work(:) real(psb_spk_),target :: work(:)
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
end subroutine psi_sswapidxv 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) 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 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 integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
@ -97,7 +87,7 @@ module psi_s_mod
class(psb_s_base_vect_type) :: y class(psb_s_base_vect_type) :: y
real(psb_spk_) :: beta real(psb_spk_) :: beta
real(psb_spk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
end subroutine psi_sswap_vidx_vect end subroutine psi_sswap_vidx_vect
end interface end interface

@ -80,16 +80,6 @@ module psi_z_mod
complex(psb_dpk_),target :: work(:) complex(psb_dpk_),target :: work(:)
integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv integer(psb_ipk_), intent(in) :: idx(:),totxch,totsnd,totrcv
end subroutine psi_zswapidxv 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) 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 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 integer(psb_ipk_), intent(in) :: iictxt,iicomm,flag
@ -97,7 +87,7 @@ module psi_z_mod
class(psb_z_base_vect_type) :: y class(psb_z_base_vect_type) :: y
complex(psb_dpk_) :: beta complex(psb_dpk_) :: beta
complex(psb_dpk_), target :: work(:) 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 integer(psb_ipk_), intent(in) :: totxch,totsnd, totrcv
end subroutine psi_zswap_vidx_vect end subroutine psi_zswap_vidx_vect
end interface end interface

Loading…
Cancel
Save