Merge branch 'development' into non-diag

non-diag
sfilippone 3 years ago
commit ae7fad95d4

@ -121,6 +121,9 @@ Salvatore Filippone
Contributors (roughly reverse cronological order):
Dimitri Walther
Andea Di Iorio
Stefano Petrilli
Soren Rasmussen
Zaak Beekman
Ambra Abdullahi Hassan

@ -58,10 +58,11 @@ subroutine psb_cgather_vect(globx, locx, desc_a, info, iroot)
! locals
type(psb_ctxt_type) :: ctxt
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank, loc_rows
integer(psb_ipk_) :: ierr(5), err_act, jlx, ilx, lda_locx, lda_globx, i
integer(psb_lpk_) :: m, n, k, ilocx, jlocx, idx, iglobx, jglobx
complex(psb_spk_), allocatable :: llocx(:)
integer(psb_mpk_), allocatable :: szs(:)
character(len=20) :: name, ch_err
name='psb_cgatherv'
@ -125,32 +126,34 @@ subroutine psb_cgather_vect(globx, locx, desc_a, info, iroot)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
globx(:) = czero
llocx = locx%get_vect()
do i=1,desc_a%get_local_rows()
call psb_loc_to_glob(i,idx,desc_a,info)
globx(idx) = llocx(i)
end do
llocx = locx%get_vect()
! adjust overlapped elements
do i=1, size(desc_a%ovrlap_elem,1)
if (me /= desc_a%ovrlap_elem(i,3)) then
idx = desc_a%ovrlap_elem(i,1)
call psb_loc_to_glob(idx,desc_a,info)
globx(idx) = czero
llocx(idx) = czero
end if
end do
call psb_sum(ctxt,globx(1:m),root=root)
allocate(szs(np))
loc_rows = desc_a%get_local_rows()
call psb_gather(ctxt,loc_rows,szs,root=root)
if ((me == root).or.(root == -1)) then
if (sum(szs) /= m) then
info=psb_err_internal_error_
call psb_errpush(info,name)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
end if
call psb_gatherv(ctxt,llocx(1:loc_rows),globx,szs,root=root)
call psb_erractionrestore(err_act)
return

@ -58,10 +58,11 @@ subroutine psb_dgather_vect(globx, locx, desc_a, info, iroot)
! locals
type(psb_ctxt_type) :: ctxt
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank, loc_rows
integer(psb_ipk_) :: ierr(5), err_act, jlx, ilx, lda_locx, lda_globx, i
integer(psb_lpk_) :: m, n, k, ilocx, jlocx, idx, iglobx, jglobx
real(psb_dpk_), allocatable :: llocx(:)
integer(psb_mpk_), allocatable :: szs(:)
character(len=20) :: name, ch_err
name='psb_dgatherv'
@ -125,32 +126,34 @@ subroutine psb_dgather_vect(globx, locx, desc_a, info, iroot)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
globx(:) = dzero
llocx = locx%get_vect()
do i=1,desc_a%get_local_rows()
call psb_loc_to_glob(i,idx,desc_a,info)
globx(idx) = llocx(i)
end do
llocx = locx%get_vect()
! adjust overlapped elements
do i=1, size(desc_a%ovrlap_elem,1)
if (me /= desc_a%ovrlap_elem(i,3)) then
idx = desc_a%ovrlap_elem(i,1)
call psb_loc_to_glob(idx,desc_a,info)
globx(idx) = dzero
llocx(idx) = dzero
end if
end do
call psb_sum(ctxt,globx(1:m),root=root)
allocate(szs(np))
loc_rows = desc_a%get_local_rows()
call psb_gather(ctxt,loc_rows,szs,root=root)
if ((me == root).or.(root == -1)) then
if (sum(szs) /= m) then
info=psb_err_internal_error_
call psb_errpush(info,name)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
end if
call psb_gatherv(ctxt,llocx(1:loc_rows),globx,szs,root=root)
call psb_erractionrestore(err_act)
return

@ -58,10 +58,11 @@ subroutine psb_igather_vect(globx, locx, desc_a, info, iroot)
! locals
type(psb_ctxt_type) :: ctxt
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank, loc_rows
integer(psb_ipk_) :: ierr(5), err_act, jlx, ilx, lda_locx, lda_globx, i
integer(psb_lpk_) :: m, n, k, ilocx, jlocx, idx, iglobx, jglobx
integer(psb_ipk_), allocatable :: llocx(:)
integer(psb_mpk_), allocatable :: szs(:)
character(len=20) :: name, ch_err
name='psb_igatherv'
@ -125,32 +126,34 @@ subroutine psb_igather_vect(globx, locx, desc_a, info, iroot)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
globx(:) = izero
llocx = locx%get_vect()
do i=1,desc_a%get_local_rows()
call psb_loc_to_glob(i,idx,desc_a,info)
globx(idx) = llocx(i)
end do
llocx = locx%get_vect()
! adjust overlapped elements
do i=1, size(desc_a%ovrlap_elem,1)
if (me /= desc_a%ovrlap_elem(i,3)) then
idx = desc_a%ovrlap_elem(i,1)
call psb_loc_to_glob(idx,desc_a,info)
globx(idx) = izero
llocx(idx) = izero
end if
end do
call psb_sum(ctxt,globx(1:m),root=root)
allocate(szs(np))
loc_rows = desc_a%get_local_rows()
call psb_gather(ctxt,loc_rows,szs,root=root)
if ((me == root).or.(root == -1)) then
if (sum(szs) /= m) then
info=psb_err_internal_error_
call psb_errpush(info,name)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
end if
call psb_gatherv(ctxt,llocx(1:loc_rows),globx,szs,root=root)
call psb_erractionrestore(err_act)
return

@ -58,10 +58,11 @@ subroutine psb_lgather_vect(globx, locx, desc_a, info, iroot)
! locals
type(psb_ctxt_type) :: ctxt
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank, loc_rows
integer(psb_ipk_) :: ierr(5), err_act, jlx, ilx, lda_locx, lda_globx, i
integer(psb_lpk_) :: m, n, k, ilocx, jlocx, idx, iglobx, jglobx
integer(psb_lpk_), allocatable :: llocx(:)
integer(psb_mpk_), allocatable :: szs(:)
character(len=20) :: name, ch_err
name='psb_lgatherv'
@ -125,32 +126,34 @@ subroutine psb_lgather_vect(globx, locx, desc_a, info, iroot)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
globx(:) = lzero
llocx = locx%get_vect()
do i=1,desc_a%get_local_rows()
call psb_loc_to_glob(i,idx,desc_a,info)
globx(idx) = llocx(i)
end do
llocx = locx%get_vect()
! adjust overlapped elements
do i=1, size(desc_a%ovrlap_elem,1)
if (me /= desc_a%ovrlap_elem(i,3)) then
idx = desc_a%ovrlap_elem(i,1)
call psb_loc_to_glob(idx,desc_a,info)
globx(idx) = lzero
llocx(idx) = lzero
end if
end do
call psb_sum(ctxt,globx(1:m),root=root)
allocate(szs(np))
loc_rows = desc_a%get_local_rows()
call psb_gather(ctxt,loc_rows,szs,root=root)
if ((me == root).or.(root == -1)) then
if (sum(szs) /= m) then
info=psb_err_internal_error_
call psb_errpush(info,name)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
end if
call psb_gatherv(ctxt,llocx(1:loc_rows),globx,szs,root=root)
call psb_erractionrestore(err_act)
return

@ -58,10 +58,11 @@ subroutine psb_sgather_vect(globx, locx, desc_a, info, iroot)
! locals
type(psb_ctxt_type) :: ctxt
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank, loc_rows
integer(psb_ipk_) :: ierr(5), err_act, jlx, ilx, lda_locx, lda_globx, i
integer(psb_lpk_) :: m, n, k, ilocx, jlocx, idx, iglobx, jglobx
real(psb_spk_), allocatable :: llocx(:)
integer(psb_mpk_), allocatable :: szs(:)
character(len=20) :: name, ch_err
name='psb_sgatherv'
@ -125,32 +126,34 @@ subroutine psb_sgather_vect(globx, locx, desc_a, info, iroot)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
globx(:) = szero
llocx = locx%get_vect()
do i=1,desc_a%get_local_rows()
call psb_loc_to_glob(i,idx,desc_a,info)
globx(idx) = llocx(i)
end do
llocx = locx%get_vect()
! adjust overlapped elements
do i=1, size(desc_a%ovrlap_elem,1)
if (me /= desc_a%ovrlap_elem(i,3)) then
idx = desc_a%ovrlap_elem(i,1)
call psb_loc_to_glob(idx,desc_a,info)
globx(idx) = szero
llocx(idx) = szero
end if
end do
call psb_sum(ctxt,globx(1:m),root=root)
allocate(szs(np))
loc_rows = desc_a%get_local_rows()
call psb_gather(ctxt,loc_rows,szs,root=root)
if ((me == root).or.(root == -1)) then
if (sum(szs) /= m) then
info=psb_err_internal_error_
call psb_errpush(info,name)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
end if
call psb_gatherv(ctxt,llocx(1:loc_rows),globx,szs,root=root)
call psb_erractionrestore(err_act)
return

@ -58,10 +58,11 @@ subroutine psb_zgather_vect(globx, locx, desc_a, info, iroot)
! locals
type(psb_ctxt_type) :: ctxt
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank
integer(psb_mpk_) :: np, me, root, iiroot, icomm, myrank, rootrank, loc_rows
integer(psb_ipk_) :: ierr(5), err_act, jlx, ilx, lda_locx, lda_globx, i
integer(psb_lpk_) :: m, n, k, ilocx, jlocx, idx, iglobx, jglobx
complex(psb_dpk_), allocatable :: llocx(:)
integer(psb_mpk_), allocatable :: szs(:)
character(len=20) :: name, ch_err
name='psb_zgatherv'
@ -125,32 +126,34 @@ subroutine psb_zgather_vect(globx, locx, desc_a, info, iroot)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
globx(:) = zzero
llocx = locx%get_vect()
do i=1,desc_a%get_local_rows()
call psb_loc_to_glob(i,idx,desc_a,info)
globx(idx) = llocx(i)
end do
llocx = locx%get_vect()
! adjust overlapped elements
do i=1, size(desc_a%ovrlap_elem,1)
if (me /= desc_a%ovrlap_elem(i,3)) then
idx = desc_a%ovrlap_elem(i,1)
call psb_loc_to_glob(idx,desc_a,info)
globx(idx) = zzero
llocx(idx) = zzero
end if
end do
call psb_sum(ctxt,globx(1:m),root=root)
allocate(szs(np))
loc_rows = desc_a%get_local_rows()
call psb_gather(ctxt,loc_rows,szs,root=root)
if ((me == root).or.(root == -1)) then
if (sum(szs) /= m) then
info=psb_err_internal_error_
call psb_errpush(info,name)
goto 9999
end if
call psb_realloc(m,globx,info)
if (info /= psb_success_) then
info=psb_err_alloc_dealloc_
call psb_errpush(info,name)
goto 9999
end if
end if
call psb_gatherv(ctxt,llocx(1:loc_rows),globx,szs,root=root)
call psb_erractionrestore(err_act)
return

@ -104,6 +104,7 @@ subroutine psi_bld_tmphalo(desc,info)
call desc%indxmap%l2gip(helem(1:nh),info)
if (info == psb_success_) call desc%indxmap%fnd_owner(helem(1:nh),hproc,info)
!write(0,*) 'bld_tmphalo calling set_owner',hproc(:)
if (info == psb_success_) call desc%indxmap%set_halo_owner(hproc,info)
if (info == psb_success_) call desc%indxmap%xtnd_p_adjcncy(hproc)

@ -39,6 +39,7 @@ SERIAL_MODS=serial/psb_s_serial_mod.o serial/psb_d_serial_mod.o \
auxil/psi_c_serial_mod.o auxil/psi_z_serial_mod.o \
psi_mod.o psi_i_mod.o psi_l_mod.o psi_s_mod.o psi_d_mod.o psi_c_mod.o psi_z_mod.o\
auxil/psb_ip_reord_mod.o\
auxil/psi_acx_mod.o auxil/psi_alcx_mod.o auxil/psi_lcx_mod.o \
auxil/psb_m_ip_reord_mod.o auxil/psb_e_ip_reord_mod.o \
auxil/psb_s_ip_reord_mod.o auxil/psb_d_ip_reord_mod.o \
auxil/psb_c_ip_reord_mod.o auxil/psb_z_ip_reord_mod.o \
@ -60,11 +61,16 @@ SERIAL_MODS=serial/psb_s_serial_mod.o serial/psb_d_serial_mod.o \
auxil/psb_d_hsort_x_mod.o \
auxil/psb_c_hsort_x_mod.o \
auxil/psb_z_hsort_x_mod.o \
auxil/psb_s_rb_idx_tree_mod.o \
auxil/psb_d_rb_idx_tree_mod.o \
auxil/psb_c_rb_idx_tree_mod.o \
auxil/psb_z_rb_idx_tree_mod.o \
auxil/psb_rb_idx_tree_mod.o \
serial/psb_base_mat_mod.o serial/psb_mat_mod.o\
serial/psb_s_base_mat_mod.o serial/psb_s_csr_mat_mod.o serial/psb_s_csc_mat_mod.o serial/psb_s_mat_mod.o \
serial/psb_d_base_mat_mod.o serial/psb_d_csr_mat_mod.o serial/psb_d_csc_mat_mod.o serial/psb_d_mat_mod.o \
serial/psb_c_base_mat_mod.o serial/psb_c_csr_mat_mod.o serial/psb_c_csc_mat_mod.o serial/psb_c_mat_mod.o \
serial/psb_z_base_mat_mod.o serial/psb_z_csr_mat_mod.o serial/psb_z_csc_mat_mod.o serial/psb_z_mat_mod.o
serial/psb_z_base_mat_mod.o serial/psb_z_csr_mat_mod.o serial/psb_z_csc_mat_mod.o serial/psb_z_mat_mod.o
#\
# serial/psb_ls_csr_mat_mod.o serial/psb_ld_csr_mat_mod.o serial/psb_lc_csr_mat_mod.o serial/psb_lz_csr_mat_mod.o
#\
@ -165,6 +171,7 @@ penv/psi_d_collective_mod.o penv/psi_c_collective_mod.o penv/psi_z_collective_m
penv/psi_d_p2p_mod.o penv/psi_c_p2p_mod.o penv/psi_z_p2p_mod.o
auxil/psi_acx_mod.o auxil/psi_alcx_mod.o auxil/psi_lcx_mod.o \
auxil/psb_string_mod.o auxil/psb_m_realloc_mod.o auxil/psb_e_realloc_mod.o auxil/psb_s_realloc_mod.o \
auxil/psb_d_realloc_mod.o auxil/psb_c_realloc_mod.o auxil/psb_z_realloc_mod.o \
desc/psb_desc_const_mod.o psi_penv_mod.o: psb_const_mod.o
@ -174,6 +181,7 @@ desc/psb_indx_map_mod.o desc/psb_hash_mod.o: psb_realloc_mod.o psb_const_mod.o
auxil/psb_i_sort_mod.o auxil/psb_s_sort_mod.o auxil/psb_d_sort_mod.o auxil/psb_c_sort_mod.o auxil/psb_z_sort_mod.o \
auxil/psb_ip_reord_mod.o auxil/psi_serial_mod.o auxil/psb_sort_mod.o: $(BASIC_MODS)
auxil/psb_sort_mod.o: auxil/psb_m_hsort_mod.o auxil/psb_m_isort_mod.o \
auxil/psb_m_msort_mod.o auxil/psb_m_qsort_mod.o \
auxil/psb_e_hsort_mod.o auxil/psb_e_isort_mod.o \
@ -192,7 +200,8 @@ auxil/psb_sort_mod.o: auxil/psb_m_hsort_mod.o auxil/psb_m_isort_mod.o \
auxil/psb_d_hsort_x_mod.o \
auxil/psb_c_hsort_x_mod.o \
auxil/psb_z_hsort_x_mod.o \
auxil/psb_ip_reord_mod.o auxil/psi_serial_mod.o
auxil/psb_ip_reord_mod.o \
auxil/psi_serial_mod.o
auxil/psb_m_hsort_mod.o auxil/psb_m_isort_mod.o \
auxil/psb_m_msort_mod.o auxil/psb_m_qsort_mod.o \
@ -225,7 +234,10 @@ auxil/psb_c_hsort_x_mod.o: auxil/psb_c_hsort_mod.o
auxil/psb_z_hsort_x_mod.o: auxil/psb_z_hsort_mod.o
auxil/psi_serial_mod.o: auxil/psi_m_serial_mod.o auxil/psi_e_serial_mod.o \
auxil/psi_s_serial_mod.o auxil/psi_d_serial_mod.o auxil/psi_c_serial_mod.o auxil/psi_z_serial_mod.o
auxil/psi_s_serial_mod.o auxil/psi_d_serial_mod.o\
auxil/psi_c_serial_mod.o auxil/psi_z_serial_mod.o \
auxil/psi_acx_mod.o auxil/psi_alcx_mod.o auxil/psi_lcx_mod.o
auxil/psi_m_serial_mod.o auxil/psi_e_serial_mod.o auxil/psi_s_serial_mod.o auxil/psi_d_serial_mod.o auxil/psi_c_serial_mod.o auxil/psi_z_serial_mod.o: psb_const_mod.o
auxil/psb_ip_reord_mod.o: auxil/psb_m_ip_reord_mod.o auxil/psb_e_ip_reord_mod.o \
@ -270,6 +282,12 @@ serial/psb_z_vect_mod.o: serial/psb_z_base_vect_mod.o serial/psb_i_vect_mod.o
serial/psb_s_serial_mod.o serial/psb_d_serial_mod.o serial/psb_c_serial_mod.o serial/psb_z_serial_mod.o: serial/psb_mat_mod.o auxil/psb_string_mod.o auxil/psb_sort_mod.o auxil/psi_serial_mod.o
serial/psb_vect_mod.o: serial/psb_i_vect_mod.o serial/psb_l_vect_mod.o serial/psb_d_vect_mod.o serial/psb_s_vect_mod.o serial/psb_c_vect_mod.o serial/psb_z_vect_mod.o
auxil/psb_s_rb_idx_tree_mod.o: serial/psb_s_csr_mat_mod.o psb_realloc_mod.o
auxil/psb_d_rb_idx_tree_mod.o: serial/psb_d_csr_mat_mod.o psb_realloc_mod.o
auxil/psb_c_rb_idx_tree_mod.o: serial/psb_c_csr_mat_mod.o psb_realloc_mod.o
auxil/psb_z_rb_idx_tree_mod.o: serial/psb_z_csr_mat_mod.o psb_realloc_mod.o
auxil/psb_rb_idx_tree_mod.o: auxil/psb_s_rb_idx_tree_mod.o auxil/psb_d_rb_idx_tree_mod.o auxil/psb_c_rb_idx_tree_mod.o auxil/psb_z_rb_idx_tree_mod.o
error.o psb_realloc_mod.o: psb_error_mod.o
psb_error_impl.o: psb_penv_mod.o
psb_timers_mod.o: psb_penv_mod.o psb_const_mod.o psb_realloc_mod.o psb_error_mod.o

@ -123,7 +123,7 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5
@ -236,9 +236,9 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info == psb_success_) &
& call psb_ensure_size(heap%last+1,heap%idxs,info,addsz=(1_psb_ipk_)*psb_heap_resize)
& call psb_ensure_size(heap%last+1,heap%idxs,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5

@ -44,7 +44,6 @@ module psb_c_qsort_mod
use psb_const_mod
interface psb_qsort
subroutine psb_cqsort(x,ix,dir,flag)
import

@ -0,0 +1,128 @@
!
! Parallel Sparse BLAS version 3.5
! (C) Copyright 2006-2018
! Salvatore Filippone
! Alfredo Buttari
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
! package: psb_c_rb_idx_tree_mod
!
! Red black tree implementation ordered by index
!
! Each node contains and index and a double precision value
!
! The tree should always be well balanced
!
! inserting a node with an existing index will
! add up the new value to the old one
! Contributed by Dimitri Walther
!
module psb_c_rb_idx_tree_mod
use psb_const_mod
implicit none
type :: psb_c_rb_idx_node
integer(psb_ipk_) :: idx
complex(psb_spk_) :: val
type(psb_c_rb_idx_node), pointer :: left, right, parent
logical :: is_red
end type psb_c_rb_idx_node
type :: psb_c_rb_idx_tree
type(psb_c_rb_idx_node), pointer :: root
integer(psb_ipk_) :: nnz
contains
procedure :: insert => psb_c_rb_idx_tree_insert
end type psb_c_rb_idx_tree
interface psb_rb_idx_tree_insert
subroutine psb_c_rb_idx_tree_insert(this, idx, val)
import :: psb_ipk_, psb_spk_, psb_c_rb_idx_tree
implicit none
class(psb_c_rb_idx_tree), intent(inout) :: this
integer(psb_ipk_), intent(in) :: idx
complex(psb_spk_), intent(in) :: val
end subroutine psb_c_rb_idx_tree_insert
end interface psb_rb_idx_tree_insert
interface psb_rb_idx_tree_scalar_sparse_row_mul
subroutine psb_c_rb_idx_tree_scalar_sparse_row_mul(tree, scalar, mat, row_num)
use psb_c_csr_mat_mod, only : psb_c_csr_sparse_mat
import :: psb_ipk_, psb_spk_, psb_c_rb_idx_tree
implicit none
type(psb_c_rb_idx_tree), intent(inout) :: tree
complex(psb_spk_), intent(in) :: scalar
type(psb_c_csr_sparse_mat), intent(in) :: mat
integer(psb_ipk_), intent(in) :: row_num
end subroutine psb_c_rb_idx_tree_scalar_sparse_row_mul
end interface psb_rb_idx_tree_scalar_sparse_row_mul
interface psb_rb_idx_tree_merge
subroutine psb_c_rb_idx_tree_merge(trees, mat)
use psb_c_csr_mat_mod, only : psb_c_csr_sparse_mat
import :: psb_c_rb_idx_tree
type(psb_c_rb_idx_tree), allocatable, intent(inout) :: trees(:)
type(psb_c_csr_sparse_mat), intent(inout) :: mat
end subroutine psb_c_rb_idx_tree_merge
end interface psb_rb_idx_tree_merge
interface psb_rb_idx_tree_fix_insertion
subroutine psb_c_rb_idx_tree_fix_insertion(this, node)
import :: psb_c_rb_idx_tree, psb_c_rb_idx_node
implicit none
class(psb_c_rb_idx_tree), intent(inout) :: this
type(psb_c_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_c_rb_idx_tree_fix_insertion
end interface psb_rb_idx_tree_fix_insertion
interface psb_rb_idx_tree_swap_colors
subroutine psb_c_rb_idx_tree_swap_colors(n1, n2)
import :: psb_c_rb_idx_node
implicit none
type(psb_c_rb_idx_node), pointer, intent(inout) :: n1, n2
end subroutine psb_c_rb_idx_tree_swap_colors
end interface psb_rb_idx_tree_swap_colors
interface psb_rb_idx_tree_rotate_right
subroutine psb_c_rb_idx_tree_rotate_right(node)
import :: psb_c_rb_idx_node
implicit none
type(psb_c_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_c_rb_idx_tree_rotate_right
end interface psb_rb_idx_tree_rotate_right
interface psb_rb_idx_tree_rotate_left
subroutine psb_c_rb_idx_tree_rotate_left(node)
import :: psb_c_rb_idx_node
implicit none
type(psb_c_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_c_rb_idx_tree_rotate_left
end interface psb_rb_idx_tree_rotate_left
end module psb_c_rb_idx_tree_mod

@ -768,7 +768,7 @@ Contains
integer(psb_ipk_) :: info
! ...Local Variables
integer(psb_ipk_) :: isz,err_act,lb
integer(psb_ipk_) :: isz,err_act,lb, i
character(len=30) :: name, char_err
logical, parameter :: debug=.false.
@ -790,7 +790,11 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
vout(:) = vin(:)
!$omp parallel do private(i)
do i=lb,lb+isz-1
vout(i) = vin(i)
end do
!$omp end parallel do
endif
endif
@ -836,7 +840,9 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
!$omp workshare
vout(:,:) = vin(:,:)
!$omp end workshare
endif
endif
@ -991,36 +997,17 @@ Contains
goto 9999
end if
!!$ If (len > psb_size(v)) Then
!!$ if (present(newsz)) then
!!$ isz = (max(len+1,newsz))
!!$ else
!!$ if (present(addsz)) then
!!$ isz = len+max(1,addsz)
!!$ else
!!$ isz = max(len+10, int(1.25*len))
!!$ endif
!!$ endif
!!$
!!$ call psb_realloc(isz,v,info,pad=pad)
!!$ if (info /= psb_success_) then
!!$ info=psb_err_from_subroutine_
!!$ call psb_errpush(info,name,a_err='psb_realloc')
!!$ goto 9999
!!$ End If
!!$ end If
If (len > psb_size(v)) Then
isz = psb_size(v)
If (len > isz) Then
#if defined(OPENMP)
!$OMP CRITICAL
if (len > psb_size(v)) then
if (len > isz) then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)
@ -1033,17 +1020,18 @@ Contains
goto 9999
end if
#else
if (present(newsz)) then
isz = (max(len+1,newsz))
else
if (present(addsz)) then
isz = len+max(1,addsz)
if (len > isz) then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
isz = max(len+10, int(1.25*len))
isz = max(len,1,int(1.25*isz))
endif
endif
call psb_realloc(isz,v,info,pad=pad)
call psb_realloc(isz,v,info,pad=pad)
end if
if (info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name,a_err='psb_realloc')
@ -1085,16 +1073,14 @@ Contains
info=psb_err_from_subroutine_
goto 9999
end if
If (len > psb_size(v)) Then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = psb_size(v)
If (len > isz) Then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)

@ -123,7 +123,7 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5
@ -236,9 +236,9 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info == psb_success_) &
& call psb_ensure_size(heap%last+1,heap%idxs,info,addsz=(1_psb_ipk_)*psb_heap_resize)
& call psb_ensure_size(heap%last+1,heap%idxs,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5

@ -43,14 +43,13 @@
module psb_d_qsort_mod
use psb_const_mod
interface psb_bsrch
function psb_dbsrch(key,n,v) result(ipos)
function psb_dbsrch(key,n,v,dir,find) result(ipos)
import
integer(psb_ipk_) :: ipos, n
real(psb_dpk_) :: key
real(psb_dpk_) :: v(:)
integer(psb_ipk_), optional :: dir, find
end function psb_dbsrch
end interface psb_bsrch

@ -0,0 +1,128 @@
!
! Parallel Sparse BLAS version 3.5
! (C) Copyright 2006-2018
! Salvatore Filippone
! Alfredo Buttari
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
! package: psb_d_rb_idx_tree_mod
!
! Red black tree implementation ordered by index
!
! Each node contains and index and a double precision value
!
! The tree should always be well balanced
!
! inserting a node with an existing index will
! add up the new value to the old one
! Contributed by Dimitri Walther
!
module psb_d_rb_idx_tree_mod
use psb_const_mod
implicit none
type :: psb_d_rb_idx_node
integer(psb_ipk_) :: idx
real(psb_dpk_) :: val
type(psb_d_rb_idx_node), pointer :: left, right, parent
logical :: is_red
end type psb_d_rb_idx_node
type :: psb_d_rb_idx_tree
type(psb_d_rb_idx_node), pointer :: root
integer(psb_ipk_) :: nnz
contains
procedure :: insert => psb_d_rb_idx_tree_insert
end type psb_d_rb_idx_tree
interface psb_rb_idx_tree_insert
subroutine psb_d_rb_idx_tree_insert(this, idx, val)
import :: psb_ipk_, psb_dpk_, psb_d_rb_idx_tree
implicit none
class(psb_d_rb_idx_tree), intent(inout) :: this
integer(psb_ipk_), intent(in) :: idx
real(psb_dpk_), intent(in) :: val
end subroutine psb_d_rb_idx_tree_insert
end interface psb_rb_idx_tree_insert
interface psb_rb_idx_tree_scalar_sparse_row_mul
subroutine psb_d_rb_idx_tree_scalar_sparse_row_mul(tree, scalar, mat, row_num)
use psb_d_csr_mat_mod, only : psb_d_csr_sparse_mat
import :: psb_ipk_, psb_dpk_, psb_d_rb_idx_tree
implicit none
type(psb_d_rb_idx_tree), intent(inout) :: tree
real(psb_dpk_), intent(in) :: scalar
type(psb_d_csr_sparse_mat), intent(in) :: mat
integer(psb_ipk_), intent(in) :: row_num
end subroutine psb_d_rb_idx_tree_scalar_sparse_row_mul
end interface psb_rb_idx_tree_scalar_sparse_row_mul
interface psb_rb_idx_tree_merge
subroutine psb_d_rb_idx_tree_merge(trees, mat)
use psb_d_csr_mat_mod, only : psb_d_csr_sparse_mat
import :: psb_d_rb_idx_tree
type(psb_d_rb_idx_tree), allocatable, intent(inout) :: trees(:)
type(psb_d_csr_sparse_mat), intent(inout) :: mat
end subroutine psb_d_rb_idx_tree_merge
end interface psb_rb_idx_tree_merge
interface psb_rb_idx_tree_fix_insertion
subroutine psb_d_rb_idx_tree_fix_insertion(this, node)
import :: psb_d_rb_idx_tree, psb_d_rb_idx_node
implicit none
class(psb_d_rb_idx_tree), intent(inout) :: this
type(psb_d_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_d_rb_idx_tree_fix_insertion
end interface psb_rb_idx_tree_fix_insertion
interface psb_rb_idx_tree_swap_colors
subroutine psb_d_rb_idx_tree_swap_colors(n1, n2)
import :: psb_d_rb_idx_node
implicit none
type(psb_d_rb_idx_node), pointer, intent(inout) :: n1, n2
end subroutine psb_d_rb_idx_tree_swap_colors
end interface psb_rb_idx_tree_swap_colors
interface psb_rb_idx_tree_rotate_right
subroutine psb_d_rb_idx_tree_rotate_right(node)
import :: psb_d_rb_idx_node
implicit none
type(psb_d_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_d_rb_idx_tree_rotate_right
end interface psb_rb_idx_tree_rotate_right
interface psb_rb_idx_tree_rotate_left
subroutine psb_d_rb_idx_tree_rotate_left(node)
import :: psb_d_rb_idx_node
implicit none
type(psb_d_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_d_rb_idx_tree_rotate_left
end interface psb_rb_idx_tree_rotate_left
end module psb_d_rb_idx_tree_mod

@ -768,7 +768,7 @@ Contains
integer(psb_ipk_) :: info
! ...Local Variables
integer(psb_ipk_) :: isz,err_act,lb
integer(psb_ipk_) :: isz,err_act,lb, i
character(len=30) :: name, char_err
logical, parameter :: debug=.false.
@ -790,7 +790,11 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
vout(:) = vin(:)
!$omp parallel do private(i)
do i=lb,lb+isz-1
vout(i) = vin(i)
end do
!$omp end parallel do
endif
endif
@ -836,7 +840,9 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
!$omp workshare
vout(:,:) = vin(:,:)
!$omp end workshare
endif
endif
@ -991,36 +997,17 @@ Contains
goto 9999
end if
!!$ If (len > psb_size(v)) Then
!!$ if (present(newsz)) then
!!$ isz = (max(len+1,newsz))
!!$ else
!!$ if (present(addsz)) then
!!$ isz = len+max(1,addsz)
!!$ else
!!$ isz = max(len+10, int(1.25*len))
!!$ endif
!!$ endif
!!$
!!$ call psb_realloc(isz,v,info,pad=pad)
!!$ if (info /= psb_success_) then
!!$ info=psb_err_from_subroutine_
!!$ call psb_errpush(info,name,a_err='psb_realloc')
!!$ goto 9999
!!$ End If
!!$ end If
If (len > psb_size(v)) Then
isz = psb_size(v)
If (len > isz) Then
#if defined(OPENMP)
!$OMP CRITICAL
if (len > psb_size(v)) then
if (len > isz) then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)
@ -1033,17 +1020,18 @@ Contains
goto 9999
end if
#else
if (present(newsz)) then
isz = (max(len+1,newsz))
else
if (present(addsz)) then
isz = len+max(1,addsz)
if (len > isz) then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
isz = max(len+10, int(1.25*len))
isz = max(len,1,int(1.25*isz))
endif
endif
call psb_realloc(isz,v,info,pad=pad)
call psb_realloc(isz,v,info,pad=pad)
end if
if (info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name,a_err='psb_realloc')
@ -1085,16 +1073,14 @@ Contains
info=psb_err_from_subroutine_
goto 9999
end if
If (len > psb_size(v)) Then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = psb_size(v)
If (len > isz) Then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)

@ -43,14 +43,13 @@
module psb_e_qsort_mod
use psb_const_mod
interface psb_bsrch
function psb_ebsrch(key,n,v) result(ipos)
function psb_ebsrch(key,n,v,dir,find) result(ipos)
import
integer(psb_ipk_) :: ipos, n
integer(psb_epk_) :: key
integer(psb_epk_) :: v(:)
integer(psb_ipk_), optional :: dir, find
end function psb_ebsrch
end interface psb_bsrch

@ -768,7 +768,7 @@ Contains
integer(psb_ipk_) :: info
! ...Local Variables
integer(psb_ipk_) :: isz,err_act,lb
integer(psb_ipk_) :: isz,err_act,lb, i
character(len=30) :: name, char_err
logical, parameter :: debug=.false.
@ -790,7 +790,11 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
vout(:) = vin(:)
!$omp parallel do private(i)
do i=lb,lb+isz-1
vout(i) = vin(i)
end do
!$omp end parallel do
endif
endif
@ -836,7 +840,9 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
!$omp workshare
vout(:,:) = vin(:,:)
!$omp end workshare
endif
endif
@ -991,36 +997,17 @@ Contains
goto 9999
end if
!!$ If (len > psb_size(v)) Then
!!$ if (present(newsz)) then
!!$ isz = (max(len+1,newsz))
!!$ else
!!$ if (present(addsz)) then
!!$ isz = len+max(1,addsz)
!!$ else
!!$ isz = max(len+10, int(1.25*len))
!!$ endif
!!$ endif
!!$
!!$ call psb_realloc(isz,v,info,pad=pad)
!!$ if (info /= psb_success_) then
!!$ info=psb_err_from_subroutine_
!!$ call psb_errpush(info,name,a_err='psb_realloc')
!!$ goto 9999
!!$ End If
!!$ end If
If (len > psb_size(v)) Then
isz = psb_size(v)
If (len > isz) Then
#if defined(OPENMP)
!$OMP CRITICAL
if (len > psb_size(v)) then
if (len > isz) then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)
@ -1033,17 +1020,18 @@ Contains
goto 9999
end if
#else
if (present(newsz)) then
isz = (max(len+1,newsz))
else
if (present(addsz)) then
isz = len+max(1,addsz)
if (len > isz) then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
isz = max(len+10, int(1.25*len))
isz = max(len,1,int(1.25*isz))
endif
endif
call psb_realloc(isz,v,info,pad=pad)
call psb_realloc(isz,v,info,pad=pad)
end if
if (info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name,a_err='psb_realloc')
@ -1085,16 +1073,14 @@ Contains
info=psb_err_from_subroutine_
goto 9999
end if
If (len > psb_size(v)) Then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = psb_size(v)
If (len > isz) Then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)

@ -43,14 +43,13 @@
module psb_i2_qsort_mod
use psb_const_mod
interface psb_bsrch
function psb_i2bsrch(key,n,v) result(ipos)
function psb_i2bsrch(key,n,v,dir,find) result(ipos)
import
integer(psb_ipk_) :: ipos, n
integer(psb_i2pk_) :: key
integer(psb_i2pk_) :: v(:)
integer(psb_ipk_), optional :: dir, find
end function psb_i2bsrch
end interface psb_bsrch

@ -768,7 +768,7 @@ Contains
integer(psb_ipk_) :: info
! ...Local Variables
integer(psb_ipk_) :: isz,err_act,lb
integer(psb_ipk_) :: isz,err_act,lb, i
character(len=30) :: name, char_err
logical, parameter :: debug=.false.
@ -790,7 +790,11 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
vout(:) = vin(:)
!$omp parallel do private(i)
do i=lb,lb+isz-1
vout(i) = vin(i)
end do
!$omp end parallel do
endif
endif
@ -836,7 +840,9 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
!$omp workshare
vout(:,:) = vin(:,:)
!$omp end workshare
endif
endif
@ -991,36 +997,17 @@ Contains
goto 9999
end if
!!$ If (len > psb_size(v)) Then
!!$ if (present(newsz)) then
!!$ isz = (max(len+1,newsz))
!!$ else
!!$ if (present(addsz)) then
!!$ isz = len+max(1,addsz)
!!$ else
!!$ isz = max(len+10, int(1.25*len))
!!$ endif
!!$ endif
!!$
!!$ call psb_realloc(isz,v,info,pad=pad)
!!$ if (info /= psb_success_) then
!!$ info=psb_err_from_subroutine_
!!$ call psb_errpush(info,name,a_err='psb_realloc')
!!$ goto 9999
!!$ End If
!!$ end If
If (len > psb_size(v)) Then
isz = psb_size(v)
If (len > isz) Then
#if defined(OPENMP)
!$OMP CRITICAL
if (len > psb_size(v)) then
if (len > isz) then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)
@ -1033,17 +1020,18 @@ Contains
goto 9999
end if
#else
if (present(newsz)) then
isz = (max(len+1,newsz))
else
if (present(addsz)) then
isz = len+max(1,addsz)
if (len > isz) then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
isz = max(len+10, int(1.25*len))
isz = max(len,1,int(1.25*isz))
endif
endif
call psb_realloc(isz,v,info,pad=pad)
call psb_realloc(isz,v,info,pad=pad)
end if
if (info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name,a_err='psb_realloc')
@ -1085,16 +1073,14 @@ Contains
info=psb_err_from_subroutine_
goto 9999
end if
If (len > psb_size(v)) Then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = psb_size(v)
If (len > isz) Then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)

@ -124,7 +124,7 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5
@ -237,9 +237,9 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info == psb_success_) &
& call psb_ensure_size(heap%last+1,heap%idxs,info,addsz=(1_psb_ipk_)*psb_heap_resize)
& call psb_ensure_size(heap%last+1,heap%idxs,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5

@ -124,7 +124,7 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_lpk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5
@ -237,9 +237,9 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_lpk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info == psb_success_) &
& call psb_ensure_size(heap%last+1,heap%idxs,info,addsz=(1_psb_lpk_)*psb_heap_resize)
& call psb_ensure_size(heap%last+1,heap%idxs,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5

@ -43,14 +43,13 @@
module psb_m_qsort_mod
use psb_const_mod
interface psb_bsrch
function psb_mbsrch(key,n,v) result(ipos)
function psb_mbsrch(key,n,v,dir,find) result(ipos)
import
integer(psb_ipk_) :: ipos, n
integer(psb_mpk_) :: key
integer(psb_mpk_) :: v(:)
integer(psb_ipk_), optional :: dir, find
end function psb_mbsrch
end interface psb_bsrch

@ -768,7 +768,7 @@ Contains
integer(psb_ipk_) :: info
! ...Local Variables
integer(psb_ipk_) :: isz,err_act,lb
integer(psb_ipk_) :: isz,err_act,lb, i
character(len=30) :: name, char_err
logical, parameter :: debug=.false.
@ -790,7 +790,11 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
vout(:) = vin(:)
!$omp parallel do private(i)
do i=lb,lb+isz-1
vout(i) = vin(i)
end do
!$omp end parallel do
endif
endif
@ -836,7 +840,9 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
!$omp workshare
vout(:,:) = vin(:,:)
!$omp end workshare
endif
endif
@ -991,36 +997,17 @@ Contains
goto 9999
end if
!!$ If (len > psb_size(v)) Then
!!$ if (present(newsz)) then
!!$ isz = (max(len+1,newsz))
!!$ else
!!$ if (present(addsz)) then
!!$ isz = len+max(1,addsz)
!!$ else
!!$ isz = max(len+10, int(1.25*len))
!!$ endif
!!$ endif
!!$
!!$ call psb_realloc(isz,v,info,pad=pad)
!!$ if (info /= psb_success_) then
!!$ info=psb_err_from_subroutine_
!!$ call psb_errpush(info,name,a_err='psb_realloc')
!!$ goto 9999
!!$ End If
!!$ end If
If (len > psb_size(v)) Then
isz = psb_size(v)
If (len > isz) Then
#if defined(OPENMP)
!$OMP CRITICAL
if (len > psb_size(v)) then
if (len > isz) then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)
@ -1033,17 +1020,18 @@ Contains
goto 9999
end if
#else
if (present(newsz)) then
isz = (max(len+1,newsz))
else
if (present(addsz)) then
isz = len+max(1,addsz)
if (len > isz) then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
isz = max(len+10, int(1.25*len))
isz = max(len,1,int(1.25*isz))
endif
endif
call psb_realloc(isz,v,info,pad=pad)
call psb_realloc(isz,v,info,pad=pad)
end if
if (info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name,a_err='psb_realloc')
@ -1085,16 +1073,14 @@ Contains
info=psb_err_from_subroutine_
goto 9999
end if
If (len > psb_size(v)) Then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = psb_size(v)
If (len > isz) Then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)

@ -0,0 +1,52 @@
!
! Parallel Sparse BLAS version 3.5
! (C) Copyright 2006-2018
! Salvatore Filippone
! Alfredo Buttari
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
! package: psb_rb_idx_tree_mod
!
! Red black tree implementation ordered by index
!
! Each node contains and index and a double precision value
!
! The tree should always be well balanced
!
! inserting a node with an existing index will
! add up the new value to the old one
! Contributed by Dimitri Walther
!
module psb_rb_idx_tree_mod
use psb_const_mod
use psb_s_rb_idx_tree_mod
use psb_d_rb_idx_tree_mod
use psb_c_rb_idx_tree_mod
use psb_z_rb_idx_tree_mod
end module psb_rb_idx_tree_mod

@ -123,7 +123,7 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5
@ -236,9 +236,9 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info == psb_success_) &
& call psb_ensure_size(heap%last+1,heap%idxs,info,addsz=(1_psb_ipk_)*psb_heap_resize)
& call psb_ensure_size(heap%last+1,heap%idxs,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5

@ -43,14 +43,13 @@
module psb_s_qsort_mod
use psb_const_mod
interface psb_bsrch
function psb_sbsrch(key,n,v) result(ipos)
function psb_sbsrch(key,n,v,dir,find) result(ipos)
import
integer(psb_ipk_) :: ipos, n
real(psb_spk_) :: key
real(psb_spk_) :: v(:)
integer(psb_ipk_), optional :: dir, find
end function psb_sbsrch
end interface psb_bsrch

@ -0,0 +1,128 @@
!
! Parallel Sparse BLAS version 3.5
! (C) Copyright 2006-2018
! Salvatore Filippone
! Alfredo Buttari
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
! package: psb_s_rb_idx_tree_mod
!
! Red black tree implementation ordered by index
!
! Each node contains and index and a double precision value
!
! The tree should always be well balanced
!
! inserting a node with an existing index will
! add up the new value to the old one
! Contributed by Dimitri Walther
!
module psb_s_rb_idx_tree_mod
use psb_const_mod
implicit none
type :: psb_s_rb_idx_node
integer(psb_ipk_) :: idx
real(psb_spk_) :: val
type(psb_s_rb_idx_node), pointer :: left, right, parent
logical :: is_red
end type psb_s_rb_idx_node
type :: psb_s_rb_idx_tree
type(psb_s_rb_idx_node), pointer :: root
integer(psb_ipk_) :: nnz
contains
procedure :: insert => psb_s_rb_idx_tree_insert
end type psb_s_rb_idx_tree
interface psb_rb_idx_tree_insert
subroutine psb_s_rb_idx_tree_insert(this, idx, val)
import :: psb_ipk_, psb_spk_, psb_s_rb_idx_tree
implicit none
class(psb_s_rb_idx_tree), intent(inout) :: this
integer(psb_ipk_), intent(in) :: idx
real(psb_spk_), intent(in) :: val
end subroutine psb_s_rb_idx_tree_insert
end interface psb_rb_idx_tree_insert
interface psb_rb_idx_tree_scalar_sparse_row_mul
subroutine psb_s_rb_idx_tree_scalar_sparse_row_mul(tree, scalar, mat, row_num)
use psb_s_csr_mat_mod, only : psb_s_csr_sparse_mat
import :: psb_ipk_, psb_spk_, psb_s_rb_idx_tree
implicit none
type(psb_s_rb_idx_tree), intent(inout) :: tree
real(psb_spk_), intent(in) :: scalar
type(psb_s_csr_sparse_mat), intent(in) :: mat
integer(psb_ipk_), intent(in) :: row_num
end subroutine psb_s_rb_idx_tree_scalar_sparse_row_mul
end interface psb_rb_idx_tree_scalar_sparse_row_mul
interface psb_rb_idx_tree_merge
subroutine psb_s_rb_idx_tree_merge(trees, mat)
use psb_s_csr_mat_mod, only : psb_s_csr_sparse_mat
import :: psb_s_rb_idx_tree
type(psb_s_rb_idx_tree), allocatable, intent(inout) :: trees(:)
type(psb_s_csr_sparse_mat), intent(inout) :: mat
end subroutine psb_s_rb_idx_tree_merge
end interface psb_rb_idx_tree_merge
interface psb_rb_idx_tree_fix_insertion
subroutine psb_s_rb_idx_tree_fix_insertion(this, node)
import :: psb_s_rb_idx_tree, psb_s_rb_idx_node
implicit none
class(psb_s_rb_idx_tree), intent(inout) :: this
type(psb_s_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_s_rb_idx_tree_fix_insertion
end interface psb_rb_idx_tree_fix_insertion
interface psb_rb_idx_tree_swap_colors
subroutine psb_s_rb_idx_tree_swap_colors(n1, n2)
import :: psb_s_rb_idx_node
implicit none
type(psb_s_rb_idx_node), pointer, intent(inout) :: n1, n2
end subroutine psb_s_rb_idx_tree_swap_colors
end interface psb_rb_idx_tree_swap_colors
interface psb_rb_idx_tree_rotate_right
subroutine psb_s_rb_idx_tree_rotate_right(node)
import :: psb_s_rb_idx_node
implicit none
type(psb_s_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_s_rb_idx_tree_rotate_right
end interface psb_rb_idx_tree_rotate_right
interface psb_rb_idx_tree_rotate_left
subroutine psb_s_rb_idx_tree_rotate_left(node)
import :: psb_s_rb_idx_node
implicit none
type(psb_s_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_s_rb_idx_tree_rotate_left
end interface psb_rb_idx_tree_rotate_left
end module psb_s_rb_idx_tree_mod

@ -768,7 +768,7 @@ Contains
integer(psb_ipk_) :: info
! ...Local Variables
integer(psb_ipk_) :: isz,err_act,lb
integer(psb_ipk_) :: isz,err_act,lb, i
character(len=30) :: name, char_err
logical, parameter :: debug=.false.
@ -790,7 +790,11 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
vout(:) = vin(:)
!$omp parallel do private(i)
do i=lb,lb+isz-1
vout(i) = vin(i)
end do
!$omp end parallel do
endif
endif
@ -836,7 +840,9 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
!$omp workshare
vout(:,:) = vin(:,:)
!$omp end workshare
endif
endif
@ -991,36 +997,17 @@ Contains
goto 9999
end if
!!$ If (len > psb_size(v)) Then
!!$ if (present(newsz)) then
!!$ isz = (max(len+1,newsz))
!!$ else
!!$ if (present(addsz)) then
!!$ isz = len+max(1,addsz)
!!$ else
!!$ isz = max(len+10, int(1.25*len))
!!$ endif
!!$ endif
!!$
!!$ call psb_realloc(isz,v,info,pad=pad)
!!$ if (info /= psb_success_) then
!!$ info=psb_err_from_subroutine_
!!$ call psb_errpush(info,name,a_err='psb_realloc')
!!$ goto 9999
!!$ End If
!!$ end If
If (len > psb_size(v)) Then
isz = psb_size(v)
If (len > isz) Then
#if defined(OPENMP)
!$OMP CRITICAL
if (len > psb_size(v)) then
if (len > isz) then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)
@ -1033,17 +1020,18 @@ Contains
goto 9999
end if
#else
if (present(newsz)) then
isz = (max(len+1,newsz))
else
if (present(addsz)) then
isz = len+max(1,addsz)
if (len > isz) then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
isz = max(len+10, int(1.25*len))
isz = max(len,1,int(1.25*isz))
endif
endif
call psb_realloc(isz,v,info,pad=pad)
call psb_realloc(isz,v,info,pad=pad)
end if
if (info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name,a_err='psb_realloc')
@ -1085,16 +1073,14 @@ Contains
info=psb_err_from_subroutine_
goto 9999
end if
If (len > psb_size(v)) Then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = psb_size(v)
If (len > isz) Then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)

@ -45,7 +45,8 @@
module psb_sort_mod
use psb_const_mod
use psb_ip_reord_mod
use psi_serial_mod
use psb_m_hsort_mod
use psb_m_isort_mod
use psb_m_msort_mod

@ -123,7 +123,7 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5
@ -236,9 +236,9 @@ contains
return
endif
call psb_ensure_size(heap%last+1,heap%keys,info,addsz=(1_psb_ipk_)*psb_heap_resize)
call psb_ensure_size(heap%last+1,heap%keys,info)
if (info == psb_success_) &
& call psb_ensure_size(heap%last+1,heap%idxs,info,addsz=(1_psb_ipk_)*psb_heap_resize)
& call psb_ensure_size(heap%last+1,heap%idxs,info)
if (info /= psb_success_) then
write(psb_err_unit,*) 'Memory allocation failure in heap_insert'
info = -5

@ -44,7 +44,6 @@ module psb_z_qsort_mod
use psb_const_mod
interface psb_qsort
subroutine psb_zqsort(x,ix,dir,flag)
import

@ -0,0 +1,128 @@
!
! Parallel Sparse BLAS version 3.5
! (C) Copyright 2006-2018
! Salvatore Filippone
! Alfredo Buttari
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
! package: psb_z_rb_idx_tree_mod
!
! Red black tree implementation ordered by index
!
! Each node contains and index and a double precision value
!
! The tree should always be well balanced
!
! inserting a node with an existing index will
! add up the new value to the old one
! Contributed by Dimitri Walther
!
module psb_z_rb_idx_tree_mod
use psb_const_mod
implicit none
type :: psb_z_rb_idx_node
integer(psb_ipk_) :: idx
complex(psb_dpk_) :: val
type(psb_z_rb_idx_node), pointer :: left, right, parent
logical :: is_red
end type psb_z_rb_idx_node
type :: psb_z_rb_idx_tree
type(psb_z_rb_idx_node), pointer :: root
integer(psb_ipk_) :: nnz
contains
procedure :: insert => psb_z_rb_idx_tree_insert
end type psb_z_rb_idx_tree
interface psb_rb_idx_tree_insert
subroutine psb_z_rb_idx_tree_insert(this, idx, val)
import :: psb_ipk_, psb_dpk_, psb_z_rb_idx_tree
implicit none
class(psb_z_rb_idx_tree), intent(inout) :: this
integer(psb_ipk_), intent(in) :: idx
complex(psb_dpk_), intent(in) :: val
end subroutine psb_z_rb_idx_tree_insert
end interface psb_rb_idx_tree_insert
interface psb_rb_idx_tree_scalar_sparse_row_mul
subroutine psb_z_rb_idx_tree_scalar_sparse_row_mul(tree, scalar, mat, row_num)
use psb_z_csr_mat_mod, only : psb_z_csr_sparse_mat
import :: psb_ipk_, psb_dpk_, psb_z_rb_idx_tree
implicit none
type(psb_z_rb_idx_tree), intent(inout) :: tree
complex(psb_dpk_), intent(in) :: scalar
type(psb_z_csr_sparse_mat), intent(in) :: mat
integer(psb_ipk_), intent(in) :: row_num
end subroutine psb_z_rb_idx_tree_scalar_sparse_row_mul
end interface psb_rb_idx_tree_scalar_sparse_row_mul
interface psb_rb_idx_tree_merge
subroutine psb_z_rb_idx_tree_merge(trees, mat)
use psb_z_csr_mat_mod, only : psb_z_csr_sparse_mat
import :: psb_z_rb_idx_tree
type(psb_z_rb_idx_tree), allocatable, intent(inout) :: trees(:)
type(psb_z_csr_sparse_mat), intent(inout) :: mat
end subroutine psb_z_rb_idx_tree_merge
end interface psb_rb_idx_tree_merge
interface psb_rb_idx_tree_fix_insertion
subroutine psb_z_rb_idx_tree_fix_insertion(this, node)
import :: psb_z_rb_idx_tree, psb_z_rb_idx_node
implicit none
class(psb_z_rb_idx_tree), intent(inout) :: this
type(psb_z_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_z_rb_idx_tree_fix_insertion
end interface psb_rb_idx_tree_fix_insertion
interface psb_rb_idx_tree_swap_colors
subroutine psb_z_rb_idx_tree_swap_colors(n1, n2)
import :: psb_z_rb_idx_node
implicit none
type(psb_z_rb_idx_node), pointer, intent(inout) :: n1, n2
end subroutine psb_z_rb_idx_tree_swap_colors
end interface psb_rb_idx_tree_swap_colors
interface psb_rb_idx_tree_rotate_right
subroutine psb_z_rb_idx_tree_rotate_right(node)
import :: psb_z_rb_idx_node
implicit none
type(psb_z_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_z_rb_idx_tree_rotate_right
end interface psb_rb_idx_tree_rotate_right
interface psb_rb_idx_tree_rotate_left
subroutine psb_z_rb_idx_tree_rotate_left(node)
import :: psb_z_rb_idx_node
implicit none
type(psb_z_rb_idx_node), pointer, intent(inout) :: node
end subroutine psb_z_rb_idx_tree_rotate_left
end interface psb_rb_idx_tree_rotate_left
end module psb_z_rb_idx_tree_mod

@ -768,7 +768,7 @@ Contains
integer(psb_ipk_) :: info
! ...Local Variables
integer(psb_ipk_) :: isz,err_act,lb
integer(psb_ipk_) :: isz,err_act,lb, i
character(len=30) :: name, char_err
logical, parameter :: debug=.false.
@ -790,7 +790,11 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
vout(:) = vin(:)
!$omp parallel do private(i)
do i=lb,lb+isz-1
vout(i) = vin(i)
end do
!$omp end parallel do
endif
endif
@ -836,7 +840,9 @@ Contains
call psb_errpush(info,name,a_err=char_err)
goto 9999
else
!$omp workshare
vout(:,:) = vin(:,:)
!$omp end workshare
endif
endif
@ -991,36 +997,17 @@ Contains
goto 9999
end if
!!$ If (len > psb_size(v)) Then
!!$ if (present(newsz)) then
!!$ isz = (max(len+1,newsz))
!!$ else
!!$ if (present(addsz)) then
!!$ isz = len+max(1,addsz)
!!$ else
!!$ isz = max(len+10, int(1.25*len))
!!$ endif
!!$ endif
!!$
!!$ call psb_realloc(isz,v,info,pad=pad)
!!$ if (info /= psb_success_) then
!!$ info=psb_err_from_subroutine_
!!$ call psb_errpush(info,name,a_err='psb_realloc')
!!$ goto 9999
!!$ End If
!!$ end If
If (len > psb_size(v)) Then
isz = psb_size(v)
If (len > isz) Then
#if defined(OPENMP)
!$OMP CRITICAL
if (len > psb_size(v)) then
if (len > isz) then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)
@ -1033,17 +1020,18 @@ Contains
goto 9999
end if
#else
if (present(newsz)) then
isz = (max(len+1,newsz))
else
if (present(addsz)) then
isz = len+max(1,addsz)
if (len > isz) then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
isz = max(len+10, int(1.25*len))
isz = max(len,1,int(1.25*isz))
endif
endif
call psb_realloc(isz,v,info,pad=pad)
call psb_realloc(isz,v,info,pad=pad)
end if
if (info /= psb_success_) then
info=psb_err_from_subroutine_
call psb_errpush(info,name,a_err='psb_realloc')
@ -1085,16 +1073,14 @@ Contains
info=psb_err_from_subroutine_
goto 9999
end if
If (len > psb_size(v)) Then
if (present(newsz)) then
isz = (max(len+1,newsz))
isz = psb_size(v)
If (len > isz) Then
if (present(newsz)) then
isz = max(len+1,1,newsz)
else if (present(addsz)) then
isz = max(len,1,isz+addsz)
else
if (present(addsz)) then
isz = len+max(1,addsz)
else
isz = max(len+10, int(1.25*len))
endif
isz = max(len,1,int(1.25*isz))
endif
call psb_realloc(isz,v,info,pad=pad)

@ -156,4 +156,15 @@ module psi_c_serial_mod
end subroutine psi_csctv
end interface psi_sct
interface psi_exscan
subroutine psi_c_exscanv(n,x,info,shift)
import :: psb_ipk_, psb_spk_
implicit none
integer(psb_ipk_), intent(in) :: n
complex(psb_spk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
complex(psb_spk_), intent(in), optional :: shift
end subroutine psi_c_exscanv
end interface psi_exscan
end module psi_c_serial_mod

@ -156,4 +156,15 @@ module psi_d_serial_mod
end subroutine psi_dsctv
end interface psi_sct
interface psi_exscan
subroutine psi_d_exscanv(n,x,info,shift)
import :: psb_ipk_, psb_dpk_
implicit none
integer(psb_ipk_), intent(in) :: n
real(psb_dpk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
real(psb_dpk_), intent(in), optional :: shift
end subroutine psi_d_exscanv
end interface psi_exscan
end module psi_d_serial_mod

@ -156,4 +156,15 @@ module psi_e_serial_mod
end subroutine psi_esctv
end interface psi_sct
interface psi_exscan
subroutine psi_e_exscanv(n,x,info,shift)
import :: psb_ipk_, psb_lpk_,psb_mpk_, psb_epk_
implicit none
integer(psb_ipk_), intent(in) :: n
integer(psb_epk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
integer(psb_epk_), intent(in), optional :: shift
end subroutine psi_e_exscanv
end interface psi_exscan
end module psi_e_serial_mod

@ -156,4 +156,15 @@ module psi_i2_serial_mod
end subroutine psi_i2sctv
end interface psi_sct
interface psi_exscan
subroutine psi_i2_exscanv(n,x,info,shift)
import :: psb_ipk_, psb_lpk_,psb_mpk_, psb_epk_
implicit none
integer(psb_ipk_), intent(in) :: n
integer(psb_i2pk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
integer(psb_i2pk_), intent(in), optional :: shift
end subroutine psi_i2_exscanv
end interface psi_exscan
end module psi_i2_serial_mod

@ -156,4 +156,15 @@ module psi_m_serial_mod
end subroutine psi_msctv
end interface psi_sct
interface psi_exscan
subroutine psi_m_exscanv(n,x,info,shift)
import :: psb_ipk_, psb_lpk_,psb_mpk_, psb_epk_
implicit none
integer(psb_ipk_), intent(in) :: n
integer(psb_mpk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
integer(psb_mpk_), intent(in), optional :: shift
end subroutine psi_m_exscanv
end interface psi_exscan
end module psi_m_serial_mod

@ -156,4 +156,15 @@ module psi_s_serial_mod
end subroutine psi_ssctv
end interface psi_sct
interface psi_exscan
subroutine psi_s_exscanv(n,x,info,shift)
import :: psb_ipk_, psb_spk_
implicit none
integer(psb_ipk_), intent(in) :: n
real(psb_spk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
real(psb_spk_), intent(in), optional :: shift
end subroutine psi_s_exscanv
end interface psi_exscan
end module psi_s_serial_mod

@ -156,4 +156,15 @@ module psi_z_serial_mod
end subroutine psi_zsctv
end interface psi_sct
interface psi_exscan
subroutine psi_z_exscanv(n,x,info,shift)
import :: psb_ipk_, psb_dpk_
implicit none
integer(psb_ipk_), intent(in) :: n
complex(psb_dpk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
complex(psb_dpk_), intent(in), optional :: shift
end subroutine psi_z_exscanv
end interface psi_exscan
end module psi_z_serial_mod

@ -488,6 +488,7 @@ contains
integer(psb_ipk_) :: iam, np
logical :: owned_
!write(0,*) 'block_g2lv2'
info = 0
ctxt = idxmap%get_ctxt()
call psb_info(ctxt,iam,np)

@ -388,7 +388,7 @@ contains
info = HashOK
hsize = hash%hsize
hmask = hash%hmask
val = -1
hk = iand(psb_hashval(key),hmask)
if (hk == 0) then
hd = 1
@ -407,35 +407,49 @@ contains
if (hash%table(hk,1) == key) then
val = hash%table(hk,2)
info = HashDuplicate
!write(0,*) 'In searchinskey 1 : ', info, HashDuplicate
return
end if
if (hash%table(hk,1) == HashFreeEntry) then
if (hash%nk == hash%hsize -1) then
!
! Note: because of the way we allocate things at CDALL
! time this is really unlikely; if we get here, we
! have at least as many halo indices as internals, which
! means we're already in trouble. But we try to keep going.
!
call psb_hash_realloc(hash,info)
if (info /= HashOk) then
info = HashOutOfMemory
return
!$omp critical(hashsearchins)
if (hash%table(hk,1) == key) then
val = hash%table(hk,2)
info = HashDuplicate
else
if (hash%table(hk,1) == HashFreeEntry) then
if (hash%nk == hash%hsize -1) then
!
! Note: because of the way we allocate things at CDALL
! time this is really unlikely; if we get here, we
! have at least as many halo indices as internals, which
! means we're already in trouble. But we try to keep going.
!
call psb_hash_realloc(hash,info)
if (info /= HashOk) then
info = HashOutOfMemory
!return
else
call psb_hash_searchinskey(key,val,nextval,hash,info)
!return
end if
else
call psb_hash_searchinskey(key,val,nextval,hash,info)
return
hash%nk = hash%nk + 1
hash%table(hk,1) = key
hash%table(hk,2) = nextval
val = nextval
!return
end if
else
hash%nk = hash%nk + 1
hash%table(hk,1) = key
hash%table(hk,2) = nextval
val = nextval
return
end if
end if
!$omp end critical(hashsearchins)
if (info /= HashOk) then
write(0,*) 'In searchinskey 2: ', info
return
end if
if (val > 0) return
hk = hk - hd
if (hk < 0) hk = hk + hsize
end do
!write(0,*) 'In searchinskey 3: ', info
end subroutine psb_hash_lsearchinskey
recursive subroutine psb_hash_isearchinskey(key,val,nextval,hash,info)
@ -444,11 +458,11 @@ contains
integer(psb_ipk_), intent(out) :: val, info
integer(psb_ipk_) :: hsize,hmask, hk, hd
logical :: redo
info = HashOK
hsize = hash%hsize
hmask = hash%hmask
hk = iand(psb_hashval(key),hmask)
if (hk == 0) then
hd = 1
@ -460,7 +474,7 @@ contains
info = HashOutOfMemory
return
end if
val = -1
hash%nsrch = hash%nsrch + 1
do
hash%nacc = hash%nacc + 1
@ -469,6 +483,8 @@ contains
info = HashDuplicate
return
end if
redo = .false.
!$OMP CRITICAL
if (hash%table(hk,1) == HashFreeEntry) then
if (hash%nk == hash%hsize -1) then
!
@ -480,19 +496,24 @@ contains
call psb_hash_realloc(hash,info)
if (info /= HashOk) then
info = HashOutOfMemory
return
!return
else
call psb_hash_searchinskey(key,val,nextval,hash,info)
return
redo = .true.
!!$ call psb_hash_searchinskey(key,val,nextval,hash,info)
!!$ return
end if
else
hash%nk = hash%nk + 1
hash%table(hk,1) = key
hash%table(hk,2) = nextval
val = nextval
return
!return
end if
end if
!$OMP END CRITICAL
if (redo) call psb_hash_searchinskey(key,val,nextval,hash,info)
if (info /= HashOk) return
if (val > 0) return
hk = hk - hd
if (hk < 0) hk = hk + hsize
end do

@ -349,7 +349,6 @@ contains
logical :: owned_
info = 0
if (present(mask)) then
if (size(mask) < size(idxin)) then
info = -1
@ -501,19 +500,37 @@ contains
if (present(lidx)) then
if (present(mask)) then
do i=1, is
if (info /= 0) cycle
if (mask(i)) then
if ((1<= idx(i)).and.(idx(i) <= idxmap%global_rows)) then
ix = idxmap%glob_to_loc(idx(i))
if (ix < 0) then
#if defined(OPENMP)
!$OMP CRITICAL(LISTINS)
ix = idxmap%glob_to_loc(idx(i))
if (ix < 0) then
ix = lidx(i)
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if ((ix <= idxmap%local_rows).or.(info /= 0)) then
info = -4
else
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
end if
end if
!$OMP END CRITICAL(LISTINS)
#else
ix = lidx(i)
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if ((ix <= idxmap%local_rows).or.(info /= 0)) then
if ((ix <= idxmap%local_rows).or.(info /= 0)) then
info = -4
return
else
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
end if
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
#endif
end if
idx(i) = ix
else
@ -525,18 +542,37 @@ contains
else if (.not.present(mask)) then
do i=1, is
if (info /= 0) cycle
if ((1<= idx(i)).and.(idx(i) <= idxmap%global_rows)) then
ix = idxmap%glob_to_loc(idx(i))
if (ix < 0) then
#if defined(OPENMP)
!$OMP CRITICAL(LISTINS)
ix = idxmap%glob_to_loc(idx(i))
if (ix < 0) then
ix = lidx(i)
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if ((ix <= idxmap%local_rows).or.(info /= 0)) then
info = -4
else
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
end if
end if
!$OMP END CRITICAL(LISTINS)
#else
ix = lidx(i)
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if ((ix <= idxmap%local_rows).or.(info /= 0)) then
if ((ix <= idxmap%local_rows).or.(info /= 0)) then
info = -4
return
else
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
end if
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
#endif
end if
idx(i) = ix
else
@ -549,19 +585,37 @@ contains
if (present(mask)) then
do i=1, is
if (info /= 0) cycle
if (mask(i)) then
if ((1<= idx(i)).and.(idx(i) <= idxmap%global_rows)) then
ix = idxmap%glob_to_loc(idx(i))
if (ix < 0) then
#if defined(OPENMP)
!$OMP CRITICAL(LISTINS)
ix = idxmap%glob_to_loc(idx(i))
if (ix < 0) then
ix = idxmap%local_cols + 1
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
info = -4
else
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
end if
end if
!$OMP END CRITICAL(LISTINS)
#else
ix = idxmap%local_cols + 1
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
if (info /= 0) then
info = -4
return
else
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
end if
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
#endif
end if
idx(i) = ix
else
@ -573,18 +627,36 @@ contains
else if (.not.present(mask)) then
do i=1, is
if (info /= 0) cycle
if ((1<= idx(i)).and.(idx(i) <= idxmap%global_rows)) then
ix = idxmap%glob_to_loc(idx(i))
if (ix < 0) then
#if defined(OPENMP)
!$OMP CRITICAL(LISTINS)
ix = idxmap%glob_to_loc(idx(i))
if (ix < 0) then
ix = idxmap%local_cols + 1
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
info = -4
else
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
end if
end if
!$OMP END CRITICAL(LISTINS)
#else
ix = idxmap%local_cols + 1
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
info = -4
return
else
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
end if
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idx(i)
idxmap%glob_to_loc(idx(i)) = ix
#endif
end if
idx(i) = ix
else
@ -641,19 +713,37 @@ contains
if (present(lidx)) then
if (present(mask)) then
do i=1, is
if (info /= 0) cycle
if (mask(i)) then
if ((1<= idxin(i)).and.(idxin(i) <= idxmap%global_rows)) then
ix = idxmap%glob_to_loc(idxin(i))
if (ix < 0) then
if (ix < 0) then
#if defined(OPENMP)
!$OMP CRITICAL(LISTINS)
ix = idxmap%glob_to_loc(idxin(i))
if (ix < 0) then
ix = lidx(i)
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
info = -4
else
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
end if
end if
!$OMP END CRITICAL(LISTINS)
#else
ix = lidx(i)
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if ((ix <= idxmap%local_rows).or.(info /= 0)) then
info = -4
return
else
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
end if
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
#endif
end if
idxout(i) = ix
else
@ -665,18 +755,36 @@ contains
else if (.not.present(mask)) then
do i=1, is
if (info /= 0) cycle
if ((1<= idxin(i)).and.(idxin(i) <= idxmap%global_rows)) then
ix = idxmap%glob_to_loc(idxin(i))
if (ix < 0) then
#if defined(OPENMP)
!$OMP CRITICAL(LISTINS)
ix = idxmap%glob_to_loc(idxin(i))
if (ix < 0) then
ix = lidx(i)
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
info = -4
else
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
end if
end if
!$OMP END CRITICAL(LISTINS)
#else
ix = lidx(i)
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if ((ix <= idxmap%local_rows).or.(info /= 0)) then
info = -4
return
else
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
end if
idxmap%local_cols = max(ix,idxmap%local_cols)
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
#endif
end if
idxout(i) = ix
else
@ -689,19 +797,37 @@ contains
if (present(mask)) then
do i=1, is
if (info /= 0) cycle
if (mask(i)) then
if ((1<= idxin(i)).and.(idxin(i) <= idxmap%global_rows)) then
ix = idxmap%glob_to_loc(idxin(i))
if (ix < 0) then
if (ix < 0) then
#if defined(OPENMP)
!$OMP CRITICAL(LISTINS)
ix = idxmap%glob_to_loc(idxin(i))
if (ix < 0) then
ix = idxmap%local_cols + 1
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
info = -4
else
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
end if
end if
!$OMP END CRITICAL(LISTINS)
#else
ix = idxmap%local_cols + 1
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
info = -4
return
else
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
end if
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
#endif
end if
idxout(i) = ix
else
@ -713,18 +839,36 @@ contains
else if (.not.present(mask)) then
do i=1, is
if (info /= 0) cycle
if ((1<= idxin(i)).and.(idxin(i) <= idxmap%global_rows)) then
ix = idxmap%glob_to_loc(idxin(i))
if (ix < 0) then
#if defined(OPENMP)
!$OMP CRITICAL(LISTINS)
ix = idxmap%glob_to_loc(idxin(i))
if (ix < 0) then
ix = idxmap%local_cols + 1
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
info = -4
else
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
end if
end if
!$OMP END CRITICAL(LISTINS)
#else
ix = idxmap%local_cols + 1
call psb_ensure_size(ix,idxmap%loc_to_glob,info,addsz=laddsz)
if (info /= 0) then
info = -4
return
end if
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
else
idxmap%local_cols = ix
idxmap%loc_to_glob(ix) = idxin(i)
idxmap%glob_to_loc(idxin(i)) = ix
end if
#endif
end if
idxout(i) = ix
else

@ -34,6 +34,14 @@ module psi_c_collective_mod
use psb_desc_const_mod
interface psb_gather
module procedure psb_cgather_s, psb_cgather_v
end interface psb_gather
interface psb_gatherv
module procedure psb_cgatherv_v
end interface
interface psb_sum
module procedure psb_csums, psb_csumv, psb_csumm
end interface
@ -76,6 +84,250 @@ contains
!
! gather
!
subroutine psb_cgather_s(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
complex(psb_spk_), intent(inout) :: dat, resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,1,psb_mpi_c_spk_,&
& resv,1,psb_mpi_c_spk_,icomm,info)
else
call mpi_gather(dat,1,psb_mpi_c_spk_,&
& resv,1,psb_mpi_c_spk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,1,psb_mpi_c_spk_,&
& resv,1,psb_mpi_c_spk_,icomm,request,info)
else
call mpi_igather(dat,1,psb_mpi_c_spk_,&
& resv,1,psb_mpi_c_spk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_cgather_s
subroutine psb_cgather_v(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
complex(psb_spk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,size(dat),psb_mpi_c_spk_,&
& resv,size(dat),psb_mpi_c_spk_,icomm,info)
else
call mpi_gather(dat,size(dat),psb_mpi_c_spk_,&
& resv,size(dat),psb_mpi_c_spk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,size(dat),psb_mpi_c_spk_,&
& resv,size(dat),psb_mpi_c_spk_,icomm,request,info)
else
call mpi_igather(dat,size(dat),psb_mpi_c_spk_,&
& resv,size(dat),psb_mpi_c_spk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_cgather_v
subroutine psb_cgatherv_v(ctxt,dat,resv,szs,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
complex(psb_spk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_mpk_), intent(in), optional :: szs(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info,i
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
integer(psb_mpk_), allocatable :: displs(:)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_allgatherv(dat,size(dat),psb_mpi_c_spk_,&
& resv,szs,displs,psb_mpi_c_spk_,icomm,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_gatherv(dat,size(dat),psb_mpi_c_spk_,&
& resv,szs,displs,psb_mpi_c_spk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_iallgatherv(dat,size(dat),psb_mpi_c_spk_,&
& resv,szs,displs,psb_mpi_c_spk_,icomm,request,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_igatherv(dat,size(dat),psb_mpi_c_spk_,&
& resv,szs,displs,psb_mpi_c_spk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_cgatherv_v
!
! SUM
!
@ -124,20 +376,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -190,20 +452,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -258,20 +530,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_, icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_, icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,root_, icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -328,20 +610,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_camx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_camx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -395,20 +687,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
psb_mpi_c_spk_,mpi_camx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -463,20 +765,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -532,20 +844,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_camn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_camn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -599,20 +921,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -667,20 +999,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_spk_,mpi_camn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -901,12 +1243,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,1,&
call mpi_scan(dat_,dat,1,&
& psb_mpi_c_spk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,1,&
call mpi_iscan(dat_,dat,1,&
& psb_mpi_c_spk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -952,12 +1295,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,1,&
call mpi_exscan(dat_,dat,1,&
& psb_mpi_c_spk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,1,&
call mpi_iexscan(dat_,dat,1,&
& psb_mpi_c_spk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -980,12 +1324,13 @@ contains
complex(psb_spk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
complex(psb_spk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
icomm = psb_get_mpi_comm(ctxt)
@ -1003,12 +1348,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,size(dat),&
call mpi_scan(dat_,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iscan(dat_,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1029,12 +1375,13 @@ contains
complex(psb_spk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
complex(psb_spk_), allocatable :: dat_(:)
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
complex(psb_spk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -1053,12 +1400,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_exscan(dat_,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iexscan(dat_,dat,size(dat),&
& psb_mpi_c_spk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1271,6 +1619,5 @@ contains
Enddo
end subroutine psb_c_e_simple_triad_a2av
end module psi_c_collective_mod

@ -45,6 +45,14 @@ module psi_d_collective_mod
module procedure psb_d_nrm2s, psb_d_nrm2v
end interface psb_nrm2
interface psb_gather
module procedure psb_dgather_s, psb_dgather_v
end interface psb_gather
interface psb_gatherv
module procedure psb_dgatherv_v
end interface
interface psb_sum
module procedure psb_dsums, psb_dsumv, psb_dsumm
end interface
@ -110,6 +118,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_dpk_) :: dat_
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -134,20 +143,29 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_r_dpk_,mpi_max,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_r_dpk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_r_dpk_,mpi_max,root_,icomm,info)
if (iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_r_dpk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_r_dpk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,request,info)
if (iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -174,6 +192,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_dpk_) :: dat_(1) ! This is a dummy
#if !defined(SERIAL_MPI)
@ -200,21 +219,31 @@ contains
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
if (root_ == -1) then
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -242,6 +271,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_dpk_) :: dat_(1,1) ! this is a dummy
#if !defined(SERIAL_MPI)
@ -268,28 +298,37 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,info)
endif
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,info)
endif
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_dmaxm
@ -340,18 +379,27 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_r_dpk_,mpi_min,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_r_dpk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_r_dpk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_r_dpk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_r_dpk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -405,20 +453,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -473,20 +531,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -545,20 +613,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_dnrm2_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_dnrm2_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_dnrm2_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_dnrm2_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_dnrm2_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_dnrm2_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_dnrm2_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_dnrm2_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -612,20 +690,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),psb_mpi_r_dpk_,&
call mpi_allreduce(mpi_in_place,dat,size(dat),psb_mpi_r_dpk_,&
& mpi_dnrm2_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),psb_mpi_r_dpk_,&
& mpi_dnrm2_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),psb_mpi_r_dpk_,&
& mpi_dnrm2_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),psb_mpi_r_dpk_,&
& mpi_dnrm2_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_dnrm2_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_dnrm2_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_dnrm2_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_dnrm2_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -636,6 +724,250 @@ contains
end subroutine psb_d_nrm2v
!
! gather
!
subroutine psb_dgather_s(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
real(psb_dpk_), intent(inout) :: dat, resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,1,psb_mpi_r_dpk_,&
& resv,1,psb_mpi_r_dpk_,icomm,info)
else
call mpi_gather(dat,1,psb_mpi_r_dpk_,&
& resv,1,psb_mpi_r_dpk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,1,psb_mpi_r_dpk_,&
& resv,1,psb_mpi_r_dpk_,icomm,request,info)
else
call mpi_igather(dat,1,psb_mpi_r_dpk_,&
& resv,1,psb_mpi_r_dpk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_dgather_s
subroutine psb_dgather_v(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
real(psb_dpk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,size(dat),psb_mpi_r_dpk_,&
& resv,size(dat),psb_mpi_r_dpk_,icomm,info)
else
call mpi_gather(dat,size(dat),psb_mpi_r_dpk_,&
& resv,size(dat),psb_mpi_r_dpk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,size(dat),psb_mpi_r_dpk_,&
& resv,size(dat),psb_mpi_r_dpk_,icomm,request,info)
else
call mpi_igather(dat,size(dat),psb_mpi_r_dpk_,&
& resv,size(dat),psb_mpi_r_dpk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_dgather_v
subroutine psb_dgatherv_v(ctxt,dat,resv,szs,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
real(psb_dpk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_mpk_), intent(in), optional :: szs(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info,i
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
integer(psb_mpk_), allocatable :: displs(:)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_allgatherv(dat,size(dat),psb_mpi_r_dpk_,&
& resv,szs,displs,psb_mpi_r_dpk_,icomm,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_gatherv(dat,size(dat),psb_mpi_r_dpk_,&
& resv,szs,displs,psb_mpi_r_dpk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_iallgatherv(dat,size(dat),psb_mpi_r_dpk_,&
& resv,szs,displs,psb_mpi_r_dpk_,icomm,request,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_igatherv(dat,size(dat),psb_mpi_r_dpk_,&
& resv,szs,displs,psb_mpi_r_dpk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_dgatherv_v
!
! SUM
!
@ -684,20 +1016,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -750,20 +1092,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -818,20 +1170,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_, icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_, icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,root_, icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -888,20 +1250,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_damx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_damx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -955,20 +1327,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
psb_mpi_r_dpk_,mpi_damx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1023,20 +1405,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1092,20 +1484,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_damn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_damn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1159,20 +1561,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1227,20 +1639,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_damn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1461,12 +1883,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,1,&
call mpi_scan(dat_,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,1,&
call mpi_iscan(dat_,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1512,12 +1935,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,1,&
call mpi_exscan(dat_,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,1,&
call mpi_iexscan(dat_,dat,1,&
& psb_mpi_r_dpk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1540,12 +1964,13 @@ contains
real(psb_dpk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_dpk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
icomm = psb_get_mpi_comm(ctxt)
@ -1563,12 +1988,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,size(dat),&
call mpi_scan(dat_,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iscan(dat_,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1589,12 +2015,13 @@ contains
real(psb_dpk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
real(psb_dpk_), allocatable :: dat_(:)
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_dpk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -1613,12 +2040,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_exscan(dat_,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iexscan(dat_,dat,size(dat),&
& psb_mpi_r_dpk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1831,6 +2259,5 @@ contains
Enddo
end subroutine psb_d_e_simple_triad_a2av
end module psi_d_collective_mod

@ -42,6 +42,14 @@ module psi_e_collective_mod
end interface psb_min
interface psb_gather
module procedure psb_egather_s, psb_egather_v
end interface psb_gather
interface psb_gatherv
module procedure psb_egatherv_v
end interface
interface psb_sum
module procedure psb_esums, psb_esumv, psb_esumm
end interface
@ -107,6 +115,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_epk_) :: dat_
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -131,20 +140,29 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_epk_,mpi_max,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_epk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_epk_,mpi_max,root_,icomm,info)
if (iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_epk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_epk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_epk_,mpi_max,root_,icomm,request,info)
if (iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_epk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -171,6 +189,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_epk_) :: dat_(1) ! This is a dummy
#if !defined(SERIAL_MPI)
@ -197,21 +216,31 @@ contains
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
if (root_ == -1) then
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -239,6 +268,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_epk_) :: dat_(1,1) ! this is a dummy
#if !defined(SERIAL_MPI)
@ -265,28 +295,37 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,info)
endif
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,info)
endif
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_emaxm
@ -337,18 +376,27 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_epk_,mpi_min,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_epk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_epk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_epk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_epk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_epk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_epk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -402,20 +450,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -470,20 +528,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -494,6 +562,250 @@ contains
!
! gather
!
subroutine psb_egather_s(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
integer(psb_epk_), intent(inout) :: dat, resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,1,psb_mpi_epk_,&
& resv,1,psb_mpi_epk_,icomm,info)
else
call mpi_gather(dat,1,psb_mpi_epk_,&
& resv,1,psb_mpi_epk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,1,psb_mpi_epk_,&
& resv,1,psb_mpi_epk_,icomm,request,info)
else
call mpi_igather(dat,1,psb_mpi_epk_,&
& resv,1,psb_mpi_epk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_egather_s
subroutine psb_egather_v(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
integer(psb_epk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,size(dat),psb_mpi_epk_,&
& resv,size(dat),psb_mpi_epk_,icomm,info)
else
call mpi_gather(dat,size(dat),psb_mpi_epk_,&
& resv,size(dat),psb_mpi_epk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,size(dat),psb_mpi_epk_,&
& resv,size(dat),psb_mpi_epk_,icomm,request,info)
else
call mpi_igather(dat,size(dat),psb_mpi_epk_,&
& resv,size(dat),psb_mpi_epk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_egather_v
subroutine psb_egatherv_v(ctxt,dat,resv,szs,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
integer(psb_epk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_mpk_), intent(in), optional :: szs(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info,i
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
integer(psb_mpk_), allocatable :: displs(:)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_allgatherv(dat,size(dat),psb_mpi_epk_,&
& resv,szs,displs,psb_mpi_epk_,icomm,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_gatherv(dat,size(dat),psb_mpi_epk_,&
& resv,szs,displs,psb_mpi_epk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_iallgatherv(dat,size(dat),psb_mpi_epk_,&
& resv,szs,displs,psb_mpi_epk_,icomm,request,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_igatherv(dat,size(dat),psb_mpi_epk_,&
& resv,szs,displs,psb_mpi_epk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_egatherv_v
!
! SUM
!
@ -542,20 +854,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_epk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_epk_,mpi_sum,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_epk_,mpi_sum,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_epk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -608,20 +930,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -676,20 +1008,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_, icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_, icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,root_, icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -746,20 +1088,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_eamx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_eamx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -813,20 +1165,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
psb_mpi_epk_,mpi_eamx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -881,20 +1243,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_eamx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -950,20 +1322,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_eamn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_eamn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1017,20 +1399,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1085,20 +1477,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_epk_,mpi_eamn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1319,12 +1721,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,1,&
call mpi_scan(dat_,dat,1,&
& psb_mpi_epk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,1,&
call mpi_iscan(dat_,dat,1,&
& psb_mpi_epk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1370,12 +1773,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,1,&
call mpi_exscan(dat_,dat,1,&
& psb_mpi_epk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,1,&
call mpi_iexscan(dat_,dat,1,&
& psb_mpi_epk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1398,12 +1802,13 @@ contains
integer(psb_epk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_epk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
icomm = psb_get_mpi_comm(ctxt)
@ -1421,12 +1826,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,size(dat),&
call mpi_scan(dat_,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iscan(dat_,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1447,12 +1853,13 @@ contains
integer(psb_epk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_epk_), allocatable :: dat_(:)
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_epk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -1471,12 +1878,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_exscan(dat_,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iexscan(dat_,dat,size(dat),&
& psb_mpi_epk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1689,6 +2097,5 @@ contains
Enddo
end subroutine psb_e_e_simple_triad_a2av
end module psi_e_collective_mod

@ -42,6 +42,14 @@ module psi_i2_collective_mod
end interface psb_min
interface psb_gather
module procedure psb_i2gather_s, psb_i2gather_v
end interface psb_gather
interface psb_gatherv
module procedure psb_i2gatherv_v
end interface
interface psb_sum
module procedure psb_i2sums, psb_i2sumv, psb_i2summ
end interface
@ -107,6 +115,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_i2pk_) :: dat_
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -131,20 +140,29 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_i2pk_,mpi_max,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_i2pk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_i2pk_,mpi_max,root_,icomm,info)
if (iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_i2pk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_i2pk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_i2pk_,mpi_max,root_,icomm,request,info)
if (iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_i2pk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -171,6 +189,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_i2pk_) :: dat_(1) ! This is a dummy
#if !defined(SERIAL_MPI)
@ -197,21 +216,31 @@ contains
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
if (root_ == -1) then
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -239,6 +268,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_i2pk_) :: dat_(1,1) ! this is a dummy
#if !defined(SERIAL_MPI)
@ -265,28 +295,37 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,info)
endif
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,info)
endif
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_i2maxm
@ -337,18 +376,27 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_i2pk_,mpi_min,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_i2pk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_i2pk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_i2pk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_i2pk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_i2pk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_i2pk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -402,20 +450,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -470,20 +528,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -494,6 +562,250 @@ contains
!
! gather
!
subroutine psb_i2gather_s(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
integer(psb_i2pk_), intent(inout) :: dat, resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,1,psb_mpi_i2pk_,&
& resv,1,psb_mpi_i2pk_,icomm,info)
else
call mpi_gather(dat,1,psb_mpi_i2pk_,&
& resv,1,psb_mpi_i2pk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,1,psb_mpi_i2pk_,&
& resv,1,psb_mpi_i2pk_,icomm,request,info)
else
call mpi_igather(dat,1,psb_mpi_i2pk_,&
& resv,1,psb_mpi_i2pk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_i2gather_s
subroutine psb_i2gather_v(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
integer(psb_i2pk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,size(dat),psb_mpi_i2pk_,&
& resv,size(dat),psb_mpi_i2pk_,icomm,info)
else
call mpi_gather(dat,size(dat),psb_mpi_i2pk_,&
& resv,size(dat),psb_mpi_i2pk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,size(dat),psb_mpi_i2pk_,&
& resv,size(dat),psb_mpi_i2pk_,icomm,request,info)
else
call mpi_igather(dat,size(dat),psb_mpi_i2pk_,&
& resv,size(dat),psb_mpi_i2pk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_i2gather_v
subroutine psb_i2gatherv_v(ctxt,dat,resv,szs,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
integer(psb_i2pk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_mpk_), intent(in), optional :: szs(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info,i
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
integer(psb_mpk_), allocatable :: displs(:)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_allgatherv(dat,size(dat),psb_mpi_i2pk_,&
& resv,szs,displs,psb_mpi_i2pk_,icomm,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_gatherv(dat,size(dat),psb_mpi_i2pk_,&
& resv,szs,displs,psb_mpi_i2pk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_iallgatherv(dat,size(dat),psb_mpi_i2pk_,&
& resv,szs,displs,psb_mpi_i2pk_,icomm,request,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_igatherv(dat,size(dat),psb_mpi_i2pk_,&
& resv,szs,displs,psb_mpi_i2pk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_i2gatherv_v
!
! SUM
!
@ -542,20 +854,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -608,20 +930,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -676,20 +1008,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_, icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_, icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,root_, icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -746,20 +1088,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_i2amx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_i2amx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -813,20 +1165,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
psb_mpi_i2pk_,mpi_i2amx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -881,20 +1243,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -950,20 +1322,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_i2amn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_i2amn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1017,20 +1399,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1085,20 +1477,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_i2pk_,mpi_i2amn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1319,12 +1721,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,1,&
call mpi_scan(dat_,dat,1,&
& psb_mpi_i2pk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,1,&
call mpi_iscan(dat_,dat,1,&
& psb_mpi_i2pk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1370,12 +1773,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,1,&
call mpi_exscan(dat_,dat,1,&
& psb_mpi_i2pk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,1,&
call mpi_iexscan(dat_,dat,1,&
& psb_mpi_i2pk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1398,12 +1802,13 @@ contains
integer(psb_i2pk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_i2pk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
icomm = psb_get_mpi_comm(ctxt)
@ -1421,12 +1826,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,size(dat),&
call mpi_scan(dat_,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iscan(dat_,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1447,12 +1853,13 @@ contains
integer(psb_i2pk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_i2pk_), allocatable :: dat_(:)
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_i2pk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -1471,12 +1878,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_exscan(dat_,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iexscan(dat_,dat,size(dat),&
& psb_mpi_i2pk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1689,6 +2097,5 @@ contains
Enddo
end subroutine psb_i2_e_simple_triad_a2av
end module psi_i2_collective_mod

@ -42,6 +42,14 @@ module psi_m_collective_mod
end interface psb_min
interface psb_gather
module procedure psb_mgather_s, psb_mgather_v
end interface psb_gather
interface psb_gatherv
module procedure psb_mgatherv_v
end interface
interface psb_sum
module procedure psb_msums, psb_msumv, psb_msumm
end interface
@ -107,6 +115,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_mpk_) :: dat_
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -131,20 +140,29 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_mpk_,mpi_max,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_mpk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_mpk_,mpi_max,root_,icomm,info)
if (iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_mpk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_mpk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_mpk_,mpi_max,root_,icomm,request,info)
if (iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_mpk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -171,6 +189,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_mpk_) :: dat_(1) ! This is a dummy
#if !defined(SERIAL_MPI)
@ -197,21 +216,31 @@ contains
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
if (root_ == -1) then
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -239,6 +268,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_mpk_) :: dat_(1,1) ! this is a dummy
#if !defined(SERIAL_MPI)
@ -265,28 +295,37 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,info)
endif
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,info)
endif
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_mmaxm
@ -337,18 +376,27 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_mpk_,mpi_min,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_mpk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_mpk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_mpk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_mpk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_mpk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_mpk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -402,20 +450,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -470,20 +528,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -494,6 +562,250 @@ contains
!
! gather
!
subroutine psb_mgather_s(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
integer(psb_mpk_), intent(inout) :: dat, resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,1,psb_mpi_mpk_,&
& resv,1,psb_mpi_mpk_,icomm,info)
else
call mpi_gather(dat,1,psb_mpi_mpk_,&
& resv,1,psb_mpi_mpk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,1,psb_mpi_mpk_,&
& resv,1,psb_mpi_mpk_,icomm,request,info)
else
call mpi_igather(dat,1,psb_mpi_mpk_,&
& resv,1,psb_mpi_mpk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_mgather_s
subroutine psb_mgather_v(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
integer(psb_mpk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,size(dat),psb_mpi_mpk_,&
& resv,size(dat),psb_mpi_mpk_,icomm,info)
else
call mpi_gather(dat,size(dat),psb_mpi_mpk_,&
& resv,size(dat),psb_mpi_mpk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,size(dat),psb_mpi_mpk_,&
& resv,size(dat),psb_mpi_mpk_,icomm,request,info)
else
call mpi_igather(dat,size(dat),psb_mpi_mpk_,&
& resv,size(dat),psb_mpi_mpk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_mgather_v
subroutine psb_mgatherv_v(ctxt,dat,resv,szs,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
integer(psb_mpk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_mpk_), intent(in), optional :: szs(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info,i
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
integer(psb_mpk_), allocatable :: displs(:)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_allgatherv(dat,size(dat),psb_mpi_mpk_,&
& resv,szs,displs,psb_mpi_mpk_,icomm,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_gatherv(dat,size(dat),psb_mpi_mpk_,&
& resv,szs,displs,psb_mpi_mpk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_iallgatherv(dat,size(dat),psb_mpi_mpk_,&
& resv,szs,displs,psb_mpi_mpk_,icomm,request,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_igatherv(dat,size(dat),psb_mpi_mpk_,&
& resv,szs,displs,psb_mpi_mpk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_mgatherv_v
!
! SUM
!
@ -542,20 +854,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_mpk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_mpk_,mpi_sum,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_mpk_,mpi_sum,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_mpk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -608,20 +930,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -676,20 +1008,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_, icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_, icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,root_, icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -746,20 +1088,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_mamx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_mamx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -813,20 +1165,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
psb_mpi_mpk_,mpi_mamx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -881,20 +1243,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -950,20 +1322,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_mamn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_mamn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1017,20 +1399,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1085,20 +1477,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_mpk_,mpi_mamn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1319,12 +1721,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,1,&
call mpi_scan(dat_,dat,1,&
& psb_mpi_mpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,1,&
call mpi_iscan(dat_,dat,1,&
& psb_mpi_mpk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1370,12 +1773,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,1,&
call mpi_exscan(dat_,dat,1,&
& psb_mpi_mpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,1,&
call mpi_iexscan(dat_,dat,1,&
& psb_mpi_mpk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1398,12 +1802,13 @@ contains
integer(psb_mpk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_mpk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
icomm = psb_get_mpi_comm(ctxt)
@ -1421,12 +1826,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,size(dat),&
call mpi_scan(dat_,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iscan(dat_,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1447,12 +1853,13 @@ contains
integer(psb_mpk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_), allocatable :: dat_(:)
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
integer(psb_mpk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -1471,12 +1878,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_exscan(dat_,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iexscan(dat_,dat,size(dat),&
& psb_mpi_mpk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1689,6 +2097,5 @@ contains
Enddo
end subroutine psb_m_e_simple_triad_a2av
end module psi_m_collective_mod

@ -45,6 +45,14 @@ module psi_s_collective_mod
module procedure psb_s_nrm2s, psb_s_nrm2v
end interface psb_nrm2
interface psb_gather
module procedure psb_sgather_s, psb_sgather_v
end interface psb_gather
interface psb_gatherv
module procedure psb_sgatherv_v
end interface
interface psb_sum
module procedure psb_ssums, psb_ssumv, psb_ssumm
end interface
@ -110,6 +118,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_spk_) :: dat_
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -134,20 +143,29 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_r_spk_,mpi_max,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_r_spk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_r_spk_,mpi_max,root_,icomm,info)
if (iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_r_spk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_r_spk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_max,root_,icomm,request,info)
if (iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -174,6 +192,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_spk_) :: dat_(1) ! This is a dummy
#if !defined(SERIAL_MPI)
@ -200,21 +219,31 @@ contains
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
if (root_ == -1) then
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -242,6 +271,7 @@ contains
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_spk_) :: dat_(1,1) ! this is a dummy
#if !defined(SERIAL_MPI)
@ -268,28 +298,37 @@ contains
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,info)
endif
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,info)
endif
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_max,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_smaxm
@ -340,18 +379,27 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,psb_mpi_r_spk_,mpi_min,icomm,info)
call mpi_allreduce(mpi_in_place,dat,1,psb_mpi_r_spk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,psb_mpi_r_spk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,psb_mpi_r_spk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,psb_mpi_r_spk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -405,20 +453,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -473,20 +531,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_min,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -545,20 +613,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_snrm2_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_snrm2_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_snrm2_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_snrm2_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_snrm2_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_snrm2_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_snrm2_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_snrm2_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -612,20 +690,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),psb_mpi_r_spk_,&
call mpi_allreduce(mpi_in_place,dat,size(dat),psb_mpi_r_spk_,&
& mpi_snrm2_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),psb_mpi_r_spk_,&
& mpi_snrm2_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),psb_mpi_r_spk_,&
& mpi_snrm2_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),psb_mpi_r_spk_,&
& mpi_snrm2_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_snrm2_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_snrm2_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_snrm2_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_snrm2_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -636,6 +724,250 @@ contains
end subroutine psb_s_nrm2v
!
! gather
!
subroutine psb_sgather_s(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
real(psb_spk_), intent(inout) :: dat, resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,1,psb_mpi_r_spk_,&
& resv,1,psb_mpi_r_spk_,icomm,info)
else
call mpi_gather(dat,1,psb_mpi_r_spk_,&
& resv,1,psb_mpi_r_spk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,1,psb_mpi_r_spk_,&
& resv,1,psb_mpi_r_spk_,icomm,request,info)
else
call mpi_igather(dat,1,psb_mpi_r_spk_,&
& resv,1,psb_mpi_r_spk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_sgather_s
subroutine psb_sgather_v(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
real(psb_spk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,size(dat),psb_mpi_r_spk_,&
& resv,size(dat),psb_mpi_r_spk_,icomm,info)
else
call mpi_gather(dat,size(dat),psb_mpi_r_spk_,&
& resv,size(dat),psb_mpi_r_spk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,size(dat),psb_mpi_r_spk_,&
& resv,size(dat),psb_mpi_r_spk_,icomm,request,info)
else
call mpi_igather(dat,size(dat),psb_mpi_r_spk_,&
& resv,size(dat),psb_mpi_r_spk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_sgather_v
subroutine psb_sgatherv_v(ctxt,dat,resv,szs,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
real(psb_spk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_mpk_), intent(in), optional :: szs(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info,i
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
integer(psb_mpk_), allocatable :: displs(:)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_allgatherv(dat,size(dat),psb_mpi_r_spk_,&
& resv,szs,displs,psb_mpi_r_spk_,icomm,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_gatherv(dat,size(dat),psb_mpi_r_spk_,&
& resv,szs,displs,psb_mpi_r_spk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_iallgatherv(dat,size(dat),psb_mpi_r_spk_,&
& resv,szs,displs,psb_mpi_r_spk_,icomm,request,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_igatherv(dat,size(dat),psb_mpi_r_spk_,&
& resv,szs,displs,psb_mpi_r_spk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_sgatherv_v
!
! SUM
!
@ -684,20 +1016,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -750,20 +1092,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -818,20 +1170,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_, icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_, icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,root_, icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -888,20 +1250,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_samx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_samx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -955,20 +1327,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
psb_mpi_r_spk_,mpi_samx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1023,20 +1405,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1092,20 +1484,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_samn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_samn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1159,20 +1561,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1227,20 +1639,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_r_spk_,mpi_samn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1461,12 +1883,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,1,&
call mpi_scan(dat_,dat,1,&
& psb_mpi_r_spk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,1,&
call mpi_iscan(dat_,dat,1,&
& psb_mpi_r_spk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1512,12 +1935,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,1,&
call mpi_exscan(dat_,dat,1,&
& psb_mpi_r_spk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,1,&
call mpi_iexscan(dat_,dat,1,&
& psb_mpi_r_spk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -1540,12 +1964,13 @@ contains
real(psb_spk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_spk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
icomm = psb_get_mpi_comm(ctxt)
@ -1563,12 +1988,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,size(dat),&
call mpi_scan(dat_,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iscan(dat_,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1589,12 +2015,13 @@ contains
real(psb_spk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
real(psb_spk_), allocatable :: dat_(:)
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
real(psb_spk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -1613,12 +2040,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_exscan(dat_,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iexscan(dat_,dat,size(dat),&
& psb_mpi_r_spk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1831,6 +2259,5 @@ contains
Enddo
end subroutine psb_s_e_simple_triad_a2av
end module psi_s_collective_mod

@ -34,6 +34,14 @@ module psi_z_collective_mod
use psb_desc_const_mod
interface psb_gather
module procedure psb_zgather_s, psb_zgather_v
end interface psb_gather
interface psb_gatherv
module procedure psb_zgatherv_v
end interface
interface psb_sum
module procedure psb_zsums, psb_zsumv, psb_zsumm
end interface
@ -76,6 +84,250 @@ contains
!
! gather
!
subroutine psb_zgather_s(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
complex(psb_dpk_), intent(inout) :: dat, resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,1,psb_mpi_c_dpk_,&
& resv,1,psb_mpi_c_dpk_,icomm,info)
else
call mpi_gather(dat,1,psb_mpi_c_dpk_,&
& resv,1,psb_mpi_c_dpk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,1,psb_mpi_c_dpk_,&
& resv,1,psb_mpi_c_dpk_,icomm,request,info)
else
call mpi_igather(dat,1,psb_mpi_c_dpk_,&
& resv,1,psb_mpi_c_dpk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_zgather_s
subroutine psb_zgather_v(ctxt,dat,resv,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
complex(psb_dpk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allgather(dat,size(dat),psb_mpi_c_dpk_,&
& resv,size(dat),psb_mpi_c_dpk_,icomm,info)
else
call mpi_gather(dat,size(dat),psb_mpi_c_dpk_,&
& resv,size(dat),psb_mpi_c_dpk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallgather(dat,size(dat),psb_mpi_c_dpk_,&
& resv,size(dat),psb_mpi_c_dpk_,icomm,request,info)
else
call mpi_igather(dat,size(dat),psb_mpi_c_dpk_,&
& resv,size(dat),psb_mpi_c_dpk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_zgather_v
subroutine psb_zgatherv_v(ctxt,dat,resv,szs,root,mode,request)
#ifdef MPI_MOD
use mpi
#endif
implicit none
#ifdef MPI_H
include 'mpif.h'
#endif
type(psb_ctxt_type), intent(in) :: ctxt
complex(psb_dpk_), intent(inout) :: dat(:), resv(:)
integer(psb_mpk_), intent(in), optional :: root
integer(psb_mpk_), intent(in), optional :: szs(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_mpk_) :: root_
integer(psb_mpk_) :: iam, np, info,i
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
integer(psb_mpk_), allocatable :: displs(:)
logical :: collective_start, collective_end, collective_sync
#if defined(SERIAL_MPI)
resv(0) = dat
#else
call psb_info(ctxt,iam,np)
if (present(root)) then
root_ = root
else
root_ = -1
endif
icomm = psb_get_mpi_comm(ctxt)
if (present(mode)) then
collective_sync = .false.
collective_start = iand(mode,psb_collective_start_) /= 0
collective_end = iand(mode,psb_collective_end_) /= 0
if (.not.present(request)) then
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
else
collective_sync = .true.
collective_start = .false.
collective_end = .false.
end if
if (collective_sync) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_allgatherv(dat,size(dat),psb_mpi_c_dpk_,&
& resv,szs,displs,psb_mpi_c_dpk_,icomm,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_gatherv(dat,size(dat),psb_mpi_c_dpk_,&
& resv,szs,displs,psb_mpi_c_dpk_,root_,icomm,info)
endif
else
if (collective_start) then
if (root_ == -1) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
call mpi_iallgatherv(dat,size(dat),psb_mpi_c_dpk_,&
& resv,szs,displs,psb_mpi_c_dpk_,icomm,request,info)
else
if (iam == root_) then
if (size(szs) < np) write(0,*) 'Error: bad input sizes'
allocate(displs(np))
displs(1) = 0
do i=2, np
displs(i) = displs(i-1) + szs(i-1)
end do
else
allocate(displs(0))
end if
call mpi_igatherv(dat,size(dat),psb_mpi_c_dpk_,&
& resv,szs,displs,psb_mpi_c_dpk_,root_,icomm,request,info)
endif
else if (collective_end) then
call mpi_wait(request,status,info)
end if
end if
#endif
end subroutine psb_zgatherv_v
!
! SUM
!
@ -124,20 +376,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -190,20 +452,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -258,20 +530,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_,icomm,info)
end if
end if
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_, icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_, icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,root_, icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -328,20 +610,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_zamx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_zamx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -395,20 +687,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
psb_mpi_c_dpk_,mpi_zamx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -463,20 +765,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamx_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -532,20 +844,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,1,&
call mpi_allreduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_zamn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,1,&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,1,&
call mpi_iallreduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_zamn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,1,&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,1,&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,1,&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -599,20 +921,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -667,20 +999,30 @@ contains
end if
if (collective_sync) then
if (root_ == -1) then
call mpi_allreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_allreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,icomm,info)
else
call mpi_reduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,info)
if(iam==root_) then
call mpi_reduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,info)
else
call mpi_reduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,info)
end if
endif
else
if (collective_start) then
if (root_ == -1) then
call mpi_iallreduce(MPI_IN_PLACE,dat,size(dat),&
call mpi_iallreduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,icomm,request,info)
else
call mpi_ireduce(MPI_IN_PLACE,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,request,info)
if(iam==root_) then
call mpi_ireduce(mpi_in_place,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,request,info)
else
call mpi_ireduce(dat,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_zamn_op,root_,icomm,request,info)
end if
end if
else if (collective_end) then
call mpi_wait(request,status,info)
@ -901,12 +1243,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,1,&
call mpi_scan(dat_,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,1,&
call mpi_iscan(dat_,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -952,12 +1295,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,1,&
call mpi_exscan(dat_,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,1,&
call mpi_iexscan(dat_,dat,1,&
& psb_mpi_c_dpk_,mpi_sum,icomm,request,minfo)
else if (collective_end) then
call mpi_wait(request,status,minfo)
@ -980,12 +1324,13 @@ contains
complex(psb_dpk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
complex(psb_dpk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
icomm = psb_get_mpi_comm(ctxt)
@ -1003,12 +1348,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_scan(MPI_IN_PLACE,dat,size(dat),&
call mpi_scan(dat_,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iscan(dat_,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1029,12 +1375,13 @@ contains
complex(psb_dpk_), intent(inout) :: dat(:)
integer(psb_ipk_), intent(in), optional :: mode
integer(psb_mpk_), intent(inout), optional :: request
complex(psb_dpk_), allocatable :: dat_(:)
integer(psb_ipk_) :: iam, np, info
integer(psb_mpk_) :: minfo
integer(psb_mpk_) :: icomm
integer(psb_mpk_) :: status(mpi_status_size)
logical :: collective_start, collective_end, collective_sync
complex(psb_dpk_), allocatable :: dat_(:)
#if !defined(SERIAL_MPI)
call psb_info(ctxt,iam,np)
@ -1053,12 +1400,13 @@ contains
collective_start = .false.
collective_end = .false.
end if
dat_ = dat
if (collective_sync) then
call mpi_exscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_exscan(dat_,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,icomm,minfo)
else
if (collective_start) then
call mpi_iexscan(MPI_IN_PLACE,dat,size(dat),&
call mpi_iexscan(dat_,dat,size(dat),&
& psb_mpi_c_dpk_,mpi_sum,icomm,request,info)
else if (collective_end) then
call mpi_wait(request,status,info)
@ -1271,6 +1619,5 @@ contains
Enddo
end subroutine psb_z_e_simple_triad_a2av
end module psi_z_collective_mod

@ -185,13 +185,17 @@ module psb_const_mod
! The up/down constant are defined in pairs having
! opposite values. We make use of this fact in the heapsort routine.
!
integer(psb_ipk_), parameter :: psb_sort_up_ = 1, psb_sort_down_ = -1
integer(psb_ipk_), parameter :: psb_lsort_up_ = 2, psb_lsort_down_ = -2
integer(psb_ipk_), parameter :: psb_asort_up_ = 3, psb_asort_down_ = -3
integer(psb_ipk_), parameter :: psb_alsort_up_ = 4, psb_alsort_down_ = -4
integer(psb_ipk_), parameter :: psb_sort_ovw_idx_ = 0, psb_sort_keep_idx_ = 1
integer(psb_ipk_), parameter :: psb_heap_resize = 200
integer(psb_ipk_), parameter :: psb_sort_up_ = 1, psb_sort_down_ = -1
integer(psb_ipk_), parameter :: psb_lsort_up_ = 2, psb_lsort_down_ = -2
integer(psb_ipk_), parameter :: psb_asort_up_ = 3, psb_asort_down_ = -3
integer(psb_ipk_), parameter :: psb_alsort_up_ = 4, psb_alsort_down_ = -4
integer(psb_ipk_), parameter :: psb_sort_ovw_idx_ = 0, psb_sort_keep_idx_ = 1
integer(psb_ipk_), parameter :: psb_heap_resize = 200
integer(psb_ipk_), parameter :: psb_find_any_ = 0
integer(psb_ipk_), parameter :: psb_find_first_ge_ = 1
integer(psb_ipk_), parameter :: psb_find_last_le_ = 2
!
! Sparse matrix constants

@ -73,6 +73,19 @@ module psb_base_mat_mod
use psb_const_mod
use psi_serial_mod
! Algs for SPSPMM
integer(psb_ipk_), parameter :: spspmm_serial = 0
integer(psb_ipk_), parameter :: spspmm_omp_gustavson = 1
integer(psb_ipk_), parameter :: spspmm_omp_gustavson_1d = 2
integer(psb_ipk_), parameter :: spspmm_serial_rb_tree = 3
integer(psb_ipk_), parameter :: spspmm_omp_rb_tree = 4
integer(psb_ipk_), parameter :: spspmm_omp_two_pass = 5
#if defined(OPENMP)
integer(psb_ipk_), save :: spspmm_impl = spspmm_omp_gustavson
#else
integer(psb_ipk_), save :: spspmm_impl = spspmm_serial
#endif
!
!> \namespace psb_base_mod \class psb_base_sparse_mat
!! The basic data about your matrix.
@ -1904,4 +1917,22 @@ contains
end subroutine psb_base_from_lbase
function psb_get_spspmm_impl() result(impl_id)
integer(psb_ipk_) :: impl_id
impl_id = spspmm_impl
end function psb_get_spspmm_impl
subroutine psb_set_spspmm_impl(impl_id)
integer(psb_ipk_), intent(in) :: impl_id
select case(impl_id)
case (spspmm_serial,spspmm_omp_gustavson,spspmm_omp_gustavson_1d,&
& spspmm_serial_rb_tree,spspmm_omp_rb_tree, spspmm_omp_two_pass)
spspmm_impl = impl_id
case default
write (*,*) "Invalid implementation id",impl_id
end select
end subroutine psb_set_spspmm_impl
end module psb_base_mat_mod

@ -168,6 +168,8 @@ module psb_c_base_mat_mod
procedure, pass(a) :: reallocate_nz => psb_c_coo_reallocate_nz
procedure, pass(a) :: allocate_mnnz => psb_c_coo_allocate_mnnz
procedure, pass(a) :: ensure_size => psb_c_coo_ensure_size
procedure, pass(a) :: tril => psb_c_coo_tril
procedure, pass(a) :: triu => psb_c_coo_triu
procedure, pass(a) :: cp_to_coo => psb_c_cp_coo_to_coo
procedure, pass(a) :: cp_from_coo => psb_c_cp_coo_from_coo
procedure, pass(a) :: cp_to_fmt => psb_c_cp_coo_to_fmt
@ -1866,18 +1868,6 @@ module psb_c_base_mat_mod
end subroutine psb_c_fix_coo_inner
end interface
interface
subroutine psb_c_fix_coo_inner_colmajor(nr,nc,nzin,dupl,&
& ia,ja,val,iaux,nzout,info)
import
integer(psb_ipk_), intent(in) :: nr,nc,nzin,dupl
integer(psb_ipk_), intent(inout) :: ia(:), ja(:), iaux(:)
complex(psb_spk_), intent(inout) :: val(:)
integer(psb_ipk_), intent(out) :: nzout
integer(psb_ipk_), intent(out) :: info
end subroutine psb_c_fix_coo_inner_colmajor
end interface
interface
subroutine psb_c_fix_coo_inner_rowmajor(nr,nc,nzin,dupl,&
& ia,ja,val,iaux,nzout,info)
@ -1906,6 +1896,93 @@ module psb_c_base_mat_mod
integer(psb_ipk_), intent(in), optional :: idir
end subroutine psb_c_fix_coo
end interface
!
!> Function tril:
!! \memberof psb_c_coo_sparse_mat
!! \brief Copy the lower triangle, i.e. all entries
!! A(I,J) such that J-I <= DIAG
!! default value is DIAG=0, i.e. lower triangle up to
!! the main diagonal.
!! DIAG=-1 means copy the strictly lower triangle
!! DIAG= 1 means copy the lower triangle plus the first diagonal
!! of the upper triangle.
!! Moreover, apply a clipping by copying entries A(I,J) only if
!! IMIN<=I<=IMAX
!! JMIN<=J<=JMAX
!!
!! \param l the output (sub)matrix
!! \param info return code
!! \param diag [0] the last diagonal (J-I) to be considered.
!! \param imin [1] the minimum row index we are interested in
!! \param imax [a\%get_nrows()] the minimum row index we are interested in
!! \param jmin [1] minimum col index
!! \param jmax [a\%get_ncols()] maximum col index
!! \param iren(:) [none] an array to return renumbered indices (iren(ia(:)),iren(ja(:))
!! \param rscale [false] map [min(ia(:)):max(ia(:))] onto [1:max(ia(:))-min(ia(:))+1]
!! \param cscale [false] map [min(ja(:)):max(ja(:))] onto [1:max(ja(:))-min(ja(:))+1]
!! ( iren cannot be specified with rscale/cscale)
!! \param append [false] append to ia,ja
!! \param nzin [none] if append, then first new entry should go in entry nzin+1
!! \param u [none] copy of the complementary triangle
!!
!
interface
subroutine psb_c_coo_tril(a,l,info,diag,imin,imax,&
& jmin,jmax,rscale,cscale,u)
import
class(psb_c_coo_sparse_mat), intent(in) :: a
class(psb_c_coo_sparse_mat), intent(out) :: l
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), intent(in), optional :: diag,imin,imax,jmin,jmax
logical, intent(in), optional :: rscale,cscale
class(psb_c_coo_sparse_mat), optional, intent(out) :: u
end subroutine psb_c_coo_tril
end interface
!
!> Function triu:
!! \memberof psb_c_coo_sparse_mat
!! \brief Copy the upper triangle, i.e. all entries
!! A(I,J) such that DIAG <= J-I
!! default value is DIAG=0, i.e. upper triangle from
!! the main diagonal up.
!! DIAG= 1 means copy the strictly upper triangle
!! DIAG=-1 means copy the upper triangle plus the first diagonal
!! of the lower triangle.
!! Moreover, apply a clipping by copying entries A(I,J) only if
!! IMIN<=I<=IMAX
!! JMIN<=J<=JMAX
!! Optionally copies the lower triangle at the same time
!!
!! \param u the output (sub)matrix
!! \param info return code
!! \param diag [0] the last diagonal (J-I) to be considered.
!! \param imin [1] the minimum row index we are interested in
!! \param imax [a\%get_nrows()] the minimum row index we are interested in
!! \param jmin [1] minimum col index
!! \param jmax [a\%get_ncols()] maximum col index
!! \param iren(:) [none] an array to return renumbered indices (iren(ia(:)),iren(ja(:))
!! \param rscale [false] map [min(ia(:)):max(ia(:))] onto [1:max(ia(:))-min(ia(:))+1]
!! \param cscale [false] map [min(ja(:)):max(ja(:))] onto [1:max(ja(:))-min(ja(:))+1]
!! ( iren cannot be specified with rscale/cscale)
!! \param append [false] append to ia,ja
!! \param nzin [none] if append, then first new entry should go in entry nzin+1
!! \param l [none] copy of the complementary triangle
!!
!
interface
subroutine psb_c_coo_triu(a,u,info,diag,imin,imax,&
& jmin,jmax,rscale,cscale,l)
import
class(psb_c_coo_sparse_mat), intent(in) :: a
class(psb_c_coo_sparse_mat), intent(out) :: u
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), intent(in), optional :: diag,imin,imax,jmin,jmax
logical, intent(in), optional :: rscale,cscale
class(psb_c_coo_sparse_mat), optional, intent(out) :: l
end subroutine psb_c_coo_triu
end interface
!>
!! \memberof psb_c_coo_sparse_mat

@ -481,7 +481,11 @@ contains
implicit none
class(psb_c_base_vect_type), intent(inout) :: x
if (allocated(x%v)) x%v=czero
if (allocated(x%v)) then
!$omp workshare
x%v(:)=czero
!$omp end workshare
end if
call x%set_host()
end subroutine c_base_zero

@ -168,6 +168,8 @@ module psb_d_base_mat_mod
procedure, pass(a) :: reallocate_nz => psb_d_coo_reallocate_nz
procedure, pass(a) :: allocate_mnnz => psb_d_coo_allocate_mnnz
procedure, pass(a) :: ensure_size => psb_d_coo_ensure_size
procedure, pass(a) :: tril => psb_d_coo_tril
procedure, pass(a) :: triu => psb_d_coo_triu
procedure, pass(a) :: cp_to_coo => psb_d_cp_coo_to_coo
procedure, pass(a) :: cp_from_coo => psb_d_cp_coo_from_coo
procedure, pass(a) :: cp_to_fmt => psb_d_cp_coo_to_fmt
@ -1866,18 +1868,6 @@ module psb_d_base_mat_mod
end subroutine psb_d_fix_coo_inner
end interface
interface
subroutine psb_d_fix_coo_inner_colmajor(nr,nc,nzin,dupl,&
& ia,ja,val,iaux,nzout,info)
import
integer(psb_ipk_), intent(in) :: nr,nc,nzin,dupl
integer(psb_ipk_), intent(inout) :: ia(:), ja(:), iaux(:)
real(psb_dpk_), intent(inout) :: val(:)
integer(psb_ipk_), intent(out) :: nzout
integer(psb_ipk_), intent(out) :: info
end subroutine psb_d_fix_coo_inner_colmajor
end interface
interface
subroutine psb_d_fix_coo_inner_rowmajor(nr,nc,nzin,dupl,&
& ia,ja,val,iaux,nzout,info)
@ -1906,6 +1896,93 @@ module psb_d_base_mat_mod
integer(psb_ipk_), intent(in), optional :: idir
end subroutine psb_d_fix_coo
end interface
!
!> Function tril:
!! \memberof psb_d_coo_sparse_mat
!! \brief Copy the lower triangle, i.e. all entries
!! A(I,J) such that J-I <= DIAG
!! default value is DIAG=0, i.e. lower triangle up to
!! the main diagonal.
!! DIAG=-1 means copy the strictly lower triangle
!! DIAG= 1 means copy the lower triangle plus the first diagonal
!! of the upper triangle.
!! Moreover, apply a clipping by copying entries A(I,J) only if
!! IMIN<=I<=IMAX
!! JMIN<=J<=JMAX
!!
!! \param l the output (sub)matrix
!! \param info return code
!! \param diag [0] the last diagonal (J-I) to be considered.
!! \param imin [1] the minimum row index we are interested in
!! \param imax [a\%get_nrows()] the minimum row index we are interested in
!! \param jmin [1] minimum col index
!! \param jmax [a\%get_ncols()] maximum col index
!! \param iren(:) [none] an array to return renumbered indices (iren(ia(:)),iren(ja(:))
!! \param rscale [false] map [min(ia(:)):max(ia(:))] onto [1:max(ia(:))-min(ia(:))+1]
!! \param cscale [false] map [min(ja(:)):max(ja(:))] onto [1:max(ja(:))-min(ja(:))+1]
!! ( iren cannot be specified with rscale/cscale)
!! \param append [false] append to ia,ja
!! \param nzin [none] if append, then first new entry should go in entry nzin+1
!! \param u [none] copy of the complementary triangle
!!
!
interface
subroutine psb_d_coo_tril(a,l,info,diag,imin,imax,&
& jmin,jmax,rscale,cscale,u)
import
class(psb_d_coo_sparse_mat), intent(in) :: a
class(psb_d_coo_sparse_mat), intent(out) :: l
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), intent(in), optional :: diag,imin,imax,jmin,jmax
logical, intent(in), optional :: rscale,cscale
class(psb_d_coo_sparse_mat), optional, intent(out) :: u
end subroutine psb_d_coo_tril
end interface
!
!> Function triu:
!! \memberof psb_d_coo_sparse_mat
!! \brief Copy the upper triangle, i.e. all entries
!! A(I,J) such that DIAG <= J-I
!! default value is DIAG=0, i.e. upper triangle from
!! the main diagonal up.
!! DIAG= 1 means copy the strictly upper triangle
!! DIAG=-1 means copy the upper triangle plus the first diagonal
!! of the lower triangle.
!! Moreover, apply a clipping by copying entries A(I,J) only if
!! IMIN<=I<=IMAX
!! JMIN<=J<=JMAX
!! Optionally copies the lower triangle at the same time
!!
!! \param u the output (sub)matrix
!! \param info return code
!! \param diag [0] the last diagonal (J-I) to be considered.
!! \param imin [1] the minimum row index we are interested in
!! \param imax [a\%get_nrows()] the minimum row index we are interested in
!! \param jmin [1] minimum col index
!! \param jmax [a\%get_ncols()] maximum col index
!! \param iren(:) [none] an array to return renumbered indices (iren(ia(:)),iren(ja(:))
!! \param rscale [false] map [min(ia(:)):max(ia(:))] onto [1:max(ia(:))-min(ia(:))+1]
!! \param cscale [false] map [min(ja(:)):max(ja(:))] onto [1:max(ja(:))-min(ja(:))+1]
!! ( iren cannot be specified with rscale/cscale)
!! \param append [false] append to ia,ja
!! \param nzin [none] if append, then first new entry should go in entry nzin+1
!! \param l [none] copy of the complementary triangle
!!
!
interface
subroutine psb_d_coo_triu(a,u,info,diag,imin,imax,&
& jmin,jmax,rscale,cscale,l)
import
class(psb_d_coo_sparse_mat), intent(in) :: a
class(psb_d_coo_sparse_mat), intent(out) :: u
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), intent(in), optional :: diag,imin,imax,jmin,jmax
logical, intent(in), optional :: rscale,cscale
class(psb_d_coo_sparse_mat), optional, intent(out) :: l
end subroutine psb_d_coo_triu
end interface
!>
!! \memberof psb_d_coo_sparse_mat

@ -488,7 +488,11 @@ contains
implicit none
class(psb_d_base_vect_type), intent(inout) :: x
if (allocated(x%v)) x%v=dzero
if (allocated(x%v)) then
!$omp workshare
x%v(:)=dzero
!$omp end workshare
end if
call x%set_host()
end subroutine d_base_zero

@ -417,7 +417,11 @@ contains
implicit none
class(psb_i_base_vect_type), intent(inout) :: x
if (allocated(x%v)) x%v=izero
if (allocated(x%v)) then
!$omp workshare
x%v(:)=izero
!$omp end workshare
end if
call x%set_host()
end subroutine i_base_zero

@ -418,7 +418,11 @@ contains
implicit none
class(psb_l_base_vect_type), intent(inout) :: x
if (allocated(x%v)) x%v=lzero
if (allocated(x%v)) then
!$omp workshare
x%v(:)=lzero
!$omp end workshare
end if
call x%set_host()
end subroutine l_base_zero

@ -168,6 +168,8 @@ module psb_s_base_mat_mod
procedure, pass(a) :: reallocate_nz => psb_s_coo_reallocate_nz
procedure, pass(a) :: allocate_mnnz => psb_s_coo_allocate_mnnz
procedure, pass(a) :: ensure_size => psb_s_coo_ensure_size
procedure, pass(a) :: tril => psb_s_coo_tril
procedure, pass(a) :: triu => psb_s_coo_triu
procedure, pass(a) :: cp_to_coo => psb_s_cp_coo_to_coo
procedure, pass(a) :: cp_from_coo => psb_s_cp_coo_from_coo
procedure, pass(a) :: cp_to_fmt => psb_s_cp_coo_to_fmt
@ -1866,18 +1868,6 @@ module psb_s_base_mat_mod
end subroutine psb_s_fix_coo_inner
end interface
interface
subroutine psb_s_fix_coo_inner_colmajor(nr,nc,nzin,dupl,&
& ia,ja,val,iaux,nzout,info)
import
integer(psb_ipk_), intent(in) :: nr,nc,nzin,dupl
integer(psb_ipk_), intent(inout) :: ia(:), ja(:), iaux(:)
real(psb_spk_), intent(inout) :: val(:)
integer(psb_ipk_), intent(out) :: nzout
integer(psb_ipk_), intent(out) :: info
end subroutine psb_s_fix_coo_inner_colmajor
end interface
interface
subroutine psb_s_fix_coo_inner_rowmajor(nr,nc,nzin,dupl,&
& ia,ja,val,iaux,nzout,info)
@ -1906,6 +1896,93 @@ module psb_s_base_mat_mod
integer(psb_ipk_), intent(in), optional :: idir
end subroutine psb_s_fix_coo
end interface
!
!> Function tril:
!! \memberof psb_s_coo_sparse_mat
!! \brief Copy the lower triangle, i.e. all entries
!! A(I,J) such that J-I <= DIAG
!! default value is DIAG=0, i.e. lower triangle up to
!! the main diagonal.
!! DIAG=-1 means copy the strictly lower triangle
!! DIAG= 1 means copy the lower triangle plus the first diagonal
!! of the upper triangle.
!! Moreover, apply a clipping by copying entries A(I,J) only if
!! IMIN<=I<=IMAX
!! JMIN<=J<=JMAX
!!
!! \param l the output (sub)matrix
!! \param info return code
!! \param diag [0] the last diagonal (J-I) to be considered.
!! \param imin [1] the minimum row index we are interested in
!! \param imax [a\%get_nrows()] the minimum row index we are interested in
!! \param jmin [1] minimum col index
!! \param jmax [a\%get_ncols()] maximum col index
!! \param iren(:) [none] an array to return renumbered indices (iren(ia(:)),iren(ja(:))
!! \param rscale [false] map [min(ia(:)):max(ia(:))] onto [1:max(ia(:))-min(ia(:))+1]
!! \param cscale [false] map [min(ja(:)):max(ja(:))] onto [1:max(ja(:))-min(ja(:))+1]
!! ( iren cannot be specified with rscale/cscale)
!! \param append [false] append to ia,ja
!! \param nzin [none] if append, then first new entry should go in entry nzin+1
!! \param u [none] copy of the complementary triangle
!!
!
interface
subroutine psb_s_coo_tril(a,l,info,diag,imin,imax,&
& jmin,jmax,rscale,cscale,u)
import
class(psb_s_coo_sparse_mat), intent(in) :: a
class(psb_s_coo_sparse_mat), intent(out) :: l
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), intent(in), optional :: diag,imin,imax,jmin,jmax
logical, intent(in), optional :: rscale,cscale
class(psb_s_coo_sparse_mat), optional, intent(out) :: u
end subroutine psb_s_coo_tril
end interface
!
!> Function triu:
!! \memberof psb_s_coo_sparse_mat
!! \brief Copy the upper triangle, i.e. all entries
!! A(I,J) such that DIAG <= J-I
!! default value is DIAG=0, i.e. upper triangle from
!! the main diagonal up.
!! DIAG= 1 means copy the strictly upper triangle
!! DIAG=-1 means copy the upper triangle plus the first diagonal
!! of the lower triangle.
!! Moreover, apply a clipping by copying entries A(I,J) only if
!! IMIN<=I<=IMAX
!! JMIN<=J<=JMAX
!! Optionally copies the lower triangle at the same time
!!
!! \param u the output (sub)matrix
!! \param info return code
!! \param diag [0] the last diagonal (J-I) to be considered.
!! \param imin [1] the minimum row index we are interested in
!! \param imax [a\%get_nrows()] the minimum row index we are interested in
!! \param jmin [1] minimum col index
!! \param jmax [a\%get_ncols()] maximum col index
!! \param iren(:) [none] an array to return renumbered indices (iren(ia(:)),iren(ja(:))
!! \param rscale [false] map [min(ia(:)):max(ia(:))] onto [1:max(ia(:))-min(ia(:))+1]
!! \param cscale [false] map [min(ja(:)):max(ja(:))] onto [1:max(ja(:))-min(ja(:))+1]
!! ( iren cannot be specified with rscale/cscale)
!! \param append [false] append to ia,ja
!! \param nzin [none] if append, then first new entry should go in entry nzin+1
!! \param l [none] copy of the complementary triangle
!!
!
interface
subroutine psb_s_coo_triu(a,u,info,diag,imin,imax,&
& jmin,jmax,rscale,cscale,l)
import
class(psb_s_coo_sparse_mat), intent(in) :: a
class(psb_s_coo_sparse_mat), intent(out) :: u
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), intent(in), optional :: diag,imin,imax,jmin,jmax
logical, intent(in), optional :: rscale,cscale
class(psb_s_coo_sparse_mat), optional, intent(out) :: l
end subroutine psb_s_coo_triu
end interface
!>
!! \memberof psb_s_coo_sparse_mat

@ -488,7 +488,11 @@ contains
implicit none
class(psb_s_base_vect_type), intent(inout) :: x
if (allocated(x%v)) x%v=szero
if (allocated(x%v)) then
!$omp workshare
x%v(:)=szero
!$omp end workshare
end if
call x%set_host()
end subroutine s_base_zero

@ -168,6 +168,8 @@ module psb_z_base_mat_mod
procedure, pass(a) :: reallocate_nz => psb_z_coo_reallocate_nz
procedure, pass(a) :: allocate_mnnz => psb_z_coo_allocate_mnnz
procedure, pass(a) :: ensure_size => psb_z_coo_ensure_size
procedure, pass(a) :: tril => psb_z_coo_tril
procedure, pass(a) :: triu => psb_z_coo_triu
procedure, pass(a) :: cp_to_coo => psb_z_cp_coo_to_coo
procedure, pass(a) :: cp_from_coo => psb_z_cp_coo_from_coo
procedure, pass(a) :: cp_to_fmt => psb_z_cp_coo_to_fmt
@ -1866,18 +1868,6 @@ module psb_z_base_mat_mod
end subroutine psb_z_fix_coo_inner
end interface
interface
subroutine psb_z_fix_coo_inner_colmajor(nr,nc,nzin,dupl,&
& ia,ja,val,iaux,nzout,info)
import
integer(psb_ipk_), intent(in) :: nr,nc,nzin,dupl
integer(psb_ipk_), intent(inout) :: ia(:), ja(:), iaux(:)
complex(psb_dpk_), intent(inout) :: val(:)
integer(psb_ipk_), intent(out) :: nzout
integer(psb_ipk_), intent(out) :: info
end subroutine psb_z_fix_coo_inner_colmajor
end interface
interface
subroutine psb_z_fix_coo_inner_rowmajor(nr,nc,nzin,dupl,&
& ia,ja,val,iaux,nzout,info)
@ -1906,6 +1896,93 @@ module psb_z_base_mat_mod
integer(psb_ipk_), intent(in), optional :: idir
end subroutine psb_z_fix_coo
end interface
!
!> Function tril:
!! \memberof psb_z_coo_sparse_mat
!! \brief Copy the lower triangle, i.e. all entries
!! A(I,J) such that J-I <= DIAG
!! default value is DIAG=0, i.e. lower triangle up to
!! the main diagonal.
!! DIAG=-1 means copy the strictly lower triangle
!! DIAG= 1 means copy the lower triangle plus the first diagonal
!! of the upper triangle.
!! Moreover, apply a clipping by copying entries A(I,J) only if
!! IMIN<=I<=IMAX
!! JMIN<=J<=JMAX
!!
!! \param l the output (sub)matrix
!! \param info return code
!! \param diag [0] the last diagonal (J-I) to be considered.
!! \param imin [1] the minimum row index we are interested in
!! \param imax [a\%get_nrows()] the minimum row index we are interested in
!! \param jmin [1] minimum col index
!! \param jmax [a\%get_ncols()] maximum col index
!! \param iren(:) [none] an array to return renumbered indices (iren(ia(:)),iren(ja(:))
!! \param rscale [false] map [min(ia(:)):max(ia(:))] onto [1:max(ia(:))-min(ia(:))+1]
!! \param cscale [false] map [min(ja(:)):max(ja(:))] onto [1:max(ja(:))-min(ja(:))+1]
!! ( iren cannot be specified with rscale/cscale)
!! \param append [false] append to ia,ja
!! \param nzin [none] if append, then first new entry should go in entry nzin+1
!! \param u [none] copy of the complementary triangle
!!
!
interface
subroutine psb_z_coo_tril(a,l,info,diag,imin,imax,&
& jmin,jmax,rscale,cscale,u)
import
class(psb_z_coo_sparse_mat), intent(in) :: a
class(psb_z_coo_sparse_mat), intent(out) :: l
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), intent(in), optional :: diag,imin,imax,jmin,jmax
logical, intent(in), optional :: rscale,cscale
class(psb_z_coo_sparse_mat), optional, intent(out) :: u
end subroutine psb_z_coo_tril
end interface
!
!> Function triu:
!! \memberof psb_z_coo_sparse_mat
!! \brief Copy the upper triangle, i.e. all entries
!! A(I,J) such that DIAG <= J-I
!! default value is DIAG=0, i.e. upper triangle from
!! the main diagonal up.
!! DIAG= 1 means copy the strictly upper triangle
!! DIAG=-1 means copy the upper triangle plus the first diagonal
!! of the lower triangle.
!! Moreover, apply a clipping by copying entries A(I,J) only if
!! IMIN<=I<=IMAX
!! JMIN<=J<=JMAX
!! Optionally copies the lower triangle at the same time
!!
!! \param u the output (sub)matrix
!! \param info return code
!! \param diag [0] the last diagonal (J-I) to be considered.
!! \param imin [1] the minimum row index we are interested in
!! \param imax [a\%get_nrows()] the minimum row index we are interested in
!! \param jmin [1] minimum col index
!! \param jmax [a\%get_ncols()] maximum col index
!! \param iren(:) [none] an array to return renumbered indices (iren(ia(:)),iren(ja(:))
!! \param rscale [false] map [min(ia(:)):max(ia(:))] onto [1:max(ia(:))-min(ia(:))+1]
!! \param cscale [false] map [min(ja(:)):max(ja(:))] onto [1:max(ja(:))-min(ja(:))+1]
!! ( iren cannot be specified with rscale/cscale)
!! \param append [false] append to ia,ja
!! \param nzin [none] if append, then first new entry should go in entry nzin+1
!! \param l [none] copy of the complementary triangle
!!
!
interface
subroutine psb_z_coo_triu(a,u,info,diag,imin,imax,&
& jmin,jmax,rscale,cscale,l)
import
class(psb_z_coo_sparse_mat), intent(in) :: a
class(psb_z_coo_sparse_mat), intent(out) :: u
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), intent(in), optional :: diag,imin,imax,jmin,jmax
logical, intent(in), optional :: rscale,cscale
class(psb_z_coo_sparse_mat), optional, intent(out) :: l
end subroutine psb_z_coo_triu
end interface
!>
!! \memberof psb_z_coo_sparse_mat

@ -481,7 +481,11 @@ contains
implicit none
class(psb_z_base_vect_type), intent(inout) :: x
if (allocated(x%v)) x%v=zzero
if (allocated(x%v)) then
!$omp workshare
x%v(:)=zzero
!$omp end workshare
end if
call x%set_host()
end subroutine z_base_zero

@ -356,7 +356,7 @@ function psb_cnrm2_vect(x, desc_a, info,global) result(res)
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(cone - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(sone - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else
@ -465,7 +465,7 @@ function psb_cnrm2_weight_vect(x,w, desc_a, info,global,aux) result(res)
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(cone - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(sone - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else
@ -577,7 +577,7 @@ function psb_cnrm2_weightmask_vect(x,w,idv, desc_a, info,global, aux) result(re
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(cone - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(sone - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else

@ -356,7 +356,7 @@ function psb_dnrm2_vect(x, desc_a, info,global) result(res)
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(done - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(done - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else
@ -465,7 +465,7 @@ function psb_dnrm2_weight_vect(x,w, desc_a, info,global,aux) result(res)
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(done - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(done - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else
@ -577,7 +577,7 @@ function psb_dnrm2_weightmask_vect(x,w,idv, desc_a, info,global, aux) result(re
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(done - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(done - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else

@ -356,7 +356,7 @@ function psb_snrm2_vect(x, desc_a, info,global) result(res)
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(sone - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(sone - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else
@ -465,7 +465,7 @@ function psb_snrm2_weight_vect(x,w, desc_a, info,global,aux) result(res)
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(sone - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(sone - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else
@ -577,7 +577,7 @@ function psb_snrm2_weightmask_vect(x,w,idv, desc_a, info,global, aux) result(re
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(sone - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(sone - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else

@ -356,7 +356,7 @@ function psb_znrm2_vect(x, desc_a, info,global) result(res)
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(zone - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(done - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else
@ -465,7 +465,7 @@ function psb_znrm2_weight_vect(x,w, desc_a, info,global,aux) result(res)
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(zone - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(done - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else
@ -577,7 +577,7 @@ function psb_znrm2_weightmask_vect(x,w,idv, desc_a, info,global, aux) result(re
idx = desc_a%ovrlap_elem(i,1)
ndm = desc_a%ovrlap_elem(i,2)
dd = dble(ndm-1)/dble(ndm)
res = res - sqrt(zone - dd*(abs(x%v%v(idx))/res)**2)
res = res * sqrt(done - dd*(abs(x%v%v(idx))/res)**2)
end do
end if
else

@ -7,16 +7,20 @@ BOBJS=psb_base_mat_impl.o \
psb_s_base_mat_impl.o psb_d_base_mat_impl.o psb_c_base_mat_impl.o psb_z_base_mat_impl.o
#\
psb_s_lbase_mat_impl.o psb_d_lbase_mat_impl.o psb_c_lbase_mat_impl.o psb_z_lbase_mat_impl.o
SOBJS=psb_s_csr_impl.o psb_s_coo_impl.o psb_s_csc_impl.o psb_s_mat_impl.o
SOBJS=psb_s_csr_impl.o psb_s_coo_impl.o psb_s_csc_impl.o psb_s_mat_impl.o\
psb_s_rb_idx_tree_impl.o
#\
psb_s_lcoo_impl.o psb_s_lcsr_impl.o
DOBJS=psb_d_csr_impl.o psb_d_coo_impl.o psb_d_csc_impl.o psb_d_mat_impl.o
DOBJS=psb_d_csr_impl.o psb_d_coo_impl.o psb_d_csc_impl.o psb_d_mat_impl.o\
psb_d_rb_idx_tree_impl.o
#\
psb_d_lcoo_impl.o psb_d_lcsr_impl.o
COBJS=psb_c_csr_impl.o psb_c_coo_impl.o psb_c_csc_impl.o psb_c_mat_impl.o
COBJS=psb_c_csr_impl.o psb_c_coo_impl.o psb_c_csc_impl.o psb_c_mat_impl.o\
psb_c_rb_idx_tree_impl.o
#\
psb_c_lcoo_impl.o psb_c_lcsr_impl.o
ZOBJS=psb_z_csr_impl.o psb_z_coo_impl.o psb_z_csc_impl.o psb_z_mat_impl.o
ZOBJS=psb_z_csr_impl.o psb_z_coo_impl.o psb_z_csc_impl.o psb_z_mat_impl.o\
psb_z_rb_idx_tree_impl.o
#\
psb_z_lcoo_impl.o psb_z_lcsr_impl.o

File diff suppressed because it is too large Load Diff

@ -2189,6 +2189,9 @@ subroutine psb_c_mv_csc_from_coo(a,b,info)
use psb_error_mod
use psb_c_base_mat_mod
use psb_c_csc_mat_mod, psb_protect_name => psb_c_mv_csc_from_coo
#if defined(OPENMP)
use omp_lib
#endif
implicit none
class(psb_c_csc_sparse_mat), intent(inout) :: a
@ -2223,18 +2226,33 @@ subroutine psb_c_mv_csc_from_coo(a,b,info)
call psb_realloc(nc+1,a%icp,info)
call b%free()
#if defined(OPENMP)
!$OMP PARALLEL default(shared)
!$OMP WORKSHARE
a%icp(:) = 0
!$OMP END WORKSHARE
!$OMP DO schedule(STATIC) &
!$OMP private(k,i)
do k=1,nza
i = itemp(k)
a%icp(i) = a%icp(i) + 1
!$OMP ATOMIC UPDATE
a%icp(i+1) = a%icp(i+1) + 1
!$OMP END ATOMIC
end do
ip = 1
do i=1,nc
nrl = a%icp(i)
a%icp(i) = ip
ip = ip + nrl
!$OMP END DO
call psi_exscan(nc+1,a%icp,info,shift=ione)
!$OMP END PARALLEL
#else
a%icp(:) = 0
do k=1,nza
i = itemp(k)
a%icp(i) = a%icp(i) + 1
end do
a%icp(nc+1) = ip
call psi_exscan(nc+1,a%icp,info,shift=ione)
#endif
call a%set_host()
@ -2311,9 +2329,28 @@ subroutine psb_c_cp_csc_to_fmt(a,b,info)
b%psb_c_base_sparse_mat = a%psb_c_base_sparse_mat
nc = a%get_ncols()
nz = a%get_nzeros()
if (info == 0) call psb_safe_cpy( a%icp(1:nc+1), b%icp , info)
if (info == 0) call psb_safe_cpy( a%ia(1:nz), b%ia , info)
if (info == 0) call psb_safe_cpy( a%val(1:nz), b%val , info)
if (.false.) then
if (info == 0) call psb_safe_cpy( a%icp(1:nc+1), b%icp , info)
if (info == 0) call psb_safe_cpy( a%ia(1:nz), b%ia , info)
if (info == 0) call psb_safe_cpy( a%val(1:nz), b%val , info)
else
! Despite the implementation in safe_cpy, it seems better this way
call psb_realloc(nc+1,b%icp,info)
call psb_realloc(nz,b%ia,info)
call psb_realloc(nz,b%val,info)
!$omp parallel do private(i) schedule(static)
do i=1,nc+1
b%icp(i)=a%icp(i)
end do
!$omp end parallel do
!$omp parallel do private(j) schedule(static)
do j=1,nz
b%ia(j) = a%ia(j)
b%val(j) = a%val(j)
end do
!$omp end parallel do
end if
call b%set_host()
class default
@ -2425,9 +2462,27 @@ subroutine psb_c_cp_csc_from_fmt(a,b,info)
a%psb_c_base_sparse_mat = b%psb_c_base_sparse_mat
nc = b%get_ncols()
nz = b%get_nzeros()
if (info == 0) call psb_safe_cpy( b%icp(1:nc+1), a%icp , info)
if (info == 0) call psb_safe_cpy( b%ia(1:nz), a%ia , info)
if (info == 0) call psb_safe_cpy( b%val(1:nz), a%val , info)
if (.false.) then
if (info == 0) call psb_safe_cpy( b%icp(1:nc+1), a%icp , info)
if (info == 0) call psb_safe_cpy( b%ia(1:nz), a%ia , info)
if (info == 0) call psb_safe_cpy( b%val(1:nz), a%val , info)
else
! Despite the implementation in safe_cpy, it seems better this way
call psb_realloc(nc+1,a%icp,info)
call psb_realloc(nz,a%ia,info)
call psb_realloc(nz,a%val,info)
!$omp parallel do private(i) schedule(static)
do i=1,nc+1
a%icp(i)=b%icp(i)
end do
!$omp end parallel do
!$omp parallel do private(j) schedule(static)
do j=1,nz
a%ia(j)=b%ia(j)
a%val(j)=b%val(j)
end do
!$omp end parallel do
end if
call a%set_host()
class default

File diff suppressed because it is too large Load Diff

@ -0,0 +1,329 @@
!
! Parallel Sparse BLAS version 3.5
! (C) Copyright 2006-2018
! Salvatore Filippone
! Alfredo Buttari
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
! package: psb_c_rb_idx_tree_impl
!
! Red black tree implementation ordered by index
!
! Each node contains and index and a double precision value
!
! The tree should always be well balanced
!
! inserting a node with an existing index will
! add up the new value to the old one
! Contributed by Dimitri Walther
!
subroutine psb_c_rb_idx_tree_insert(this, idx, val)
use psb_c_rb_idx_tree_mod, psb_protect_name => psb_c_rb_idx_tree_insert
implicit none
class(psb_c_rb_idx_tree), intent(inout) :: this
integer(psb_ipk_), intent(in) :: idx
complex(psb_spk_), intent(in) :: val
character(len=22) :: name
type(psb_c_rb_idx_node), pointer :: new_node
type(psb_c_rb_idx_node), pointer :: current, previous
name='psb_rb_idx_tree_insert'
allocate(new_node)
new_node%idx = idx
new_node%val = val
nullify(new_node%left)
nullify(new_node%right)
nullify(new_node%parent)
new_node%is_red = .true.
if (.not. associated(this%root)) then
this%root => new_node
this%nnz = 1
new_node%is_red = .false.
return
end if
current => this%root
do while (associated(current))
previous => current
if (idx == current%idx) then
current%val = current%val + val
deallocate(new_node)
return
else if (idx < current%idx) then
current => current%left
else
current => current%right
end if
end do
if (idx < previous%idx) then
new_node%parent => previous
previous%left => new_node
else
new_node%parent => previous
previous%right => new_node
end if
call psb_c_rb_idx_tree_fix_insertion(this, new_node)
this%nnz = this%nnz + 1
end subroutine psb_c_rb_idx_tree_insert
subroutine psb_c_rb_idx_tree_fix_insertion(this, node)
use psb_c_rb_idx_tree_mod, psb_protect_name => psb_c_rb_idx_tree_fix_insertion
implicit none
class(psb_c_rb_idx_tree), intent(inout) :: this
type(psb_c_rb_idx_node), pointer, intent(inout) :: node
character(len=29) :: name
type(psb_c_rb_idx_node), pointer :: current, parent, grand_parent, uncle
name = 'psb_rb_idx_tree_fix_insertion'
current => node
parent => current%parent
do while(associated(parent) .and. parent%is_red)
! grand parent exist because root can't be red
grand_parent => parent%parent
if (parent%idx < grand_parent%idx) then
uncle => grand_parent%right
else
uncle => grand_parent%left
end if
if (associated(uncle) .and. uncle%is_red) then
parent%is_red = .false.
uncle%is_red = .false.
grand_parent%is_red = .true.
current => grand_parent
parent => current%parent
! Left-Left case
else if (current%idx < parent%idx .and. &
parent%idx < grand_parent%idx) then
call psb_c_rb_idx_tree_rotate_right(grand_parent)
call psb_c_rb_idx_tree_swap_colors(parent, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => parent
return
! Left-Right case
else if (current%idx > parent%idx .and. &
parent%idx < grand_parent%idx) then
call psb_c_rb_idx_tree_rotate_left(parent)
call psb_c_rb_idx_tree_rotate_right(grand_parent)
call psb_c_rb_idx_tree_swap_colors(current, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => current
return
! Right-Right case
else if (current%idx > parent%idx .and. &
parent%idx > grand_parent%idx) then
call psb_c_rb_idx_tree_rotate_left(grand_parent)
call psb_c_rb_idx_tree_swap_colors(parent, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => parent
return
! Right-Left case
else
call psb_c_rb_idx_tree_rotate_right(parent)
call psb_c_rb_idx_tree_rotate_left(grand_parent)
call psb_c_rb_idx_tree_swap_colors(current, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => current
return
end if
end do
this%root%is_red = .false.
end subroutine psb_c_rb_idx_tree_fix_insertion
subroutine psb_c_rb_idx_tree_swap_colors(n1, n2)
use psb_c_rb_idx_tree_mod, psb_protect_name => psb_c_rb_idx_tree_swap_colors
implicit none
type(psb_c_rb_idx_node), pointer, intent(inout) :: n1, n2
character(len=27) :: name
logical :: tmp
name='psb_rb_idx_tree_swap_colors'
tmp = n1%is_red
n1%is_red = n2%is_red
n2%is_red = tmp
end subroutine psb_c_rb_idx_tree_swap_colors
subroutine psb_c_rb_idx_tree_rotate_right(node)
use psb_c_rb_idx_tree_mod, psb_protect_name => psb_c_rb_idx_tree_rotate_right
implicit none
type(psb_c_rb_idx_node), pointer, intent(inout) :: node
character(len=28) :: name
type(psb_c_rb_idx_node), pointer :: l, lr
name='psb_rb_idx_tree_rotate_right'
if (.not. associated(node%left)) return
l => node%left
lr => l%right
node%left => lr
if (associated(lr)) lr%parent => node
if (associated(node%parent)) then
if (node%idx < node%parent%idx) then
node%parent%left => l
else
node%parent%right => l
end if
end if
l%parent => node%parent
node%parent => l
l%right => node
end subroutine psb_c_rb_idx_tree_rotate_right
subroutine psb_c_rb_idx_tree_rotate_left(node)
use psb_c_rb_idx_tree_mod, psb_protect_name => psb_c_rb_idx_tree_rotate_left
implicit none
type(psb_c_rb_idx_node), pointer, intent(inout) :: node
character(len=27) :: name
type(psb_c_rb_idx_node), pointer :: r, rl
name='psb_rb_idx_tree_rotate_left'
if (.not. associated(node%right)) return
r => node%right
rl => r%left
node%right => rl
if (associated(rl)) rl%parent => node
if (associated(node%parent)) then
if (node%idx < node%parent%idx) then
node%parent%left => r
else
node%parent%right => r
end if
end if
r%parent => node%parent
node%parent => r
r%left => node
end subroutine psb_c_rb_idx_tree_rotate_left
subroutine psb_c_rb_idx_tree_scalar_sparse_row_mul(tree, scalar, mat, row_num)
use psb_c_rb_idx_tree_mod, psb_protect_name => psb_c_rb_idx_tree_scalar_sparse_row_mul
use psb_c_csr_mat_mod, only : psb_c_csr_sparse_mat
implicit none
type(psb_c_rb_idx_tree), intent(inout) :: tree
complex(psb_spk_), intent(in) :: scalar
type(psb_c_csr_sparse_mat), intent(in) :: mat
integer(psb_ipk_), intent(in) :: row_num
character(len=37) :: name
integer(psb_ipk_) :: i
name='psb_rb_idx_tree_scalar_sparse_row_mul'
do i = mat%irp(row_num), mat%irp(row_num + 1) - 1
call tree%insert(mat%ja(i),scalar * mat%val(i))
end do
end subroutine psb_c_rb_idx_tree_scalar_sparse_row_mul
subroutine psb_c_rb_idx_tree_merge(trees, mat)
#if defined(OPENMP)
use omp_lib
#endif
use psb_realloc_mod
use psb_c_rb_idx_tree_mod, psb_protect_name => psb_c_rb_idx_tree_merge
use psb_c_csr_mat_mod, only : psb_c_csr_sparse_mat
implicit none
type(psb_c_rb_idx_tree), allocatable, intent(inout) :: trees(:)
type(psb_c_csr_sparse_mat), intent(inout) :: mat
character(len=21) :: name
integer(psb_ipk_) :: i, j, rows, info, nnz
type(psb_c_rb_idx_node), pointer :: current, previous
name='psb_rb_idx_tree_merge'
rows = size(trees)
mat%irp(1) = 1
do i=1, rows
mat%irp(i + 1) = mat%irp(i) + trees(i)%nnz
end do
nnz = mat%irp(rows + 1)
call psb_realloc(nnz, mat%val, info)
call psb_realloc(nnz, mat%ja, info)
#if defined(OPENMP)
!$omp parallel do schedule(static), private(current, previous, j)
#endif
do i = 1, size(trees)
j = 0
current => trees(i)%root
do while(associated(current))
! go to the left-most node
do while(associated(current%left))
current => current%left
end do
mat%val(j + mat%irp(i)) = current%val
mat%ja(j + mat%irp(i)) = current%idx
j = j + 1
previous => current
if (associated(current%right)) then
if (associated(current%parent)) then
current%parent%left => current%right
end if
current%right%parent => current%parent
current => current%right
else
current => current%parent
if (associated(current)) nullify(current%left)
end if
deallocate(previous)
end do
end do
#if defined(OPENMP)
!$omp end parallel do
#endif
end subroutine psb_c_rb_idx_tree_merge

File diff suppressed because it is too large Load Diff

@ -2189,6 +2189,9 @@ subroutine psb_d_mv_csc_from_coo(a,b,info)
use psb_error_mod
use psb_d_base_mat_mod
use psb_d_csc_mat_mod, psb_protect_name => psb_d_mv_csc_from_coo
#if defined(OPENMP)
use omp_lib
#endif
implicit none
class(psb_d_csc_sparse_mat), intent(inout) :: a
@ -2223,18 +2226,33 @@ subroutine psb_d_mv_csc_from_coo(a,b,info)
call psb_realloc(nc+1,a%icp,info)
call b%free()
#if defined(OPENMP)
!$OMP PARALLEL default(shared)
!$OMP WORKSHARE
a%icp(:) = 0
!$OMP END WORKSHARE
!$OMP DO schedule(STATIC) &
!$OMP private(k,i)
do k=1,nza
i = itemp(k)
a%icp(i) = a%icp(i) + 1
!$OMP ATOMIC UPDATE
a%icp(i+1) = a%icp(i+1) + 1
!$OMP END ATOMIC
end do
ip = 1
do i=1,nc
nrl = a%icp(i)
a%icp(i) = ip
ip = ip + nrl
!$OMP END DO
call psi_exscan(nc+1,a%icp,info,shift=ione)
!$OMP END PARALLEL
#else
a%icp(:) = 0
do k=1,nza
i = itemp(k)
a%icp(i) = a%icp(i) + 1
end do
a%icp(nc+1) = ip
call psi_exscan(nc+1,a%icp,info,shift=ione)
#endif
call a%set_host()
@ -2311,9 +2329,28 @@ subroutine psb_d_cp_csc_to_fmt(a,b,info)
b%psb_d_base_sparse_mat = a%psb_d_base_sparse_mat
nc = a%get_ncols()
nz = a%get_nzeros()
if (info == 0) call psb_safe_cpy( a%icp(1:nc+1), b%icp , info)
if (info == 0) call psb_safe_cpy( a%ia(1:nz), b%ia , info)
if (info == 0) call psb_safe_cpy( a%val(1:nz), b%val , info)
if (.false.) then
if (info == 0) call psb_safe_cpy( a%icp(1:nc+1), b%icp , info)
if (info == 0) call psb_safe_cpy( a%ia(1:nz), b%ia , info)
if (info == 0) call psb_safe_cpy( a%val(1:nz), b%val , info)
else
! Despite the implementation in safe_cpy, it seems better this way
call psb_realloc(nc+1,b%icp,info)
call psb_realloc(nz,b%ia,info)
call psb_realloc(nz,b%val,info)
!$omp parallel do private(i) schedule(static)
do i=1,nc+1
b%icp(i)=a%icp(i)
end do
!$omp end parallel do
!$omp parallel do private(j) schedule(static)
do j=1,nz
b%ia(j) = a%ia(j)
b%val(j) = a%val(j)
end do
!$omp end parallel do
end if
call b%set_host()
class default
@ -2425,9 +2462,27 @@ subroutine psb_d_cp_csc_from_fmt(a,b,info)
a%psb_d_base_sparse_mat = b%psb_d_base_sparse_mat
nc = b%get_ncols()
nz = b%get_nzeros()
if (info == 0) call psb_safe_cpy( b%icp(1:nc+1), a%icp , info)
if (info == 0) call psb_safe_cpy( b%ia(1:nz), a%ia , info)
if (info == 0) call psb_safe_cpy( b%val(1:nz), a%val , info)
if (.false.) then
if (info == 0) call psb_safe_cpy( b%icp(1:nc+1), a%icp , info)
if (info == 0) call psb_safe_cpy( b%ia(1:nz), a%ia , info)
if (info == 0) call psb_safe_cpy( b%val(1:nz), a%val , info)
else
! Despite the implementation in safe_cpy, it seems better this way
call psb_realloc(nc+1,a%icp,info)
call psb_realloc(nz,a%ia,info)
call psb_realloc(nz,a%val,info)
!$omp parallel do private(i) schedule(static)
do i=1,nc+1
a%icp(i)=b%icp(i)
end do
!$omp end parallel do
!$omp parallel do private(j) schedule(static)
do j=1,nz
a%ia(j)=b%ia(j)
a%val(j)=b%val(j)
end do
!$omp end parallel do
end if
call a%set_host()
class default

File diff suppressed because it is too large Load Diff

@ -0,0 +1,329 @@
!
! Parallel Sparse BLAS version 3.5
! (C) Copyright 2006-2018
! Salvatore Filippone
! Alfredo Buttari
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
! package: psb_d_rb_idx_tree_impl
!
! Red black tree implementation ordered by index
!
! Each node contains and index and a double precision value
!
! The tree should always be well balanced
!
! inserting a node with an existing index will
! add up the new value to the old one
! Contributed by Dimitri Walther
!
subroutine psb_d_rb_idx_tree_insert(this, idx, val)
use psb_d_rb_idx_tree_mod, psb_protect_name => psb_d_rb_idx_tree_insert
implicit none
class(psb_d_rb_idx_tree), intent(inout) :: this
integer(psb_ipk_), intent(in) :: idx
real(psb_dpk_), intent(in) :: val
character(len=22) :: name
type(psb_d_rb_idx_node), pointer :: new_node
type(psb_d_rb_idx_node), pointer :: current, previous
name='psb_rb_idx_tree_insert'
allocate(new_node)
new_node%idx = idx
new_node%val = val
nullify(new_node%left)
nullify(new_node%right)
nullify(new_node%parent)
new_node%is_red = .true.
if (.not. associated(this%root)) then
this%root => new_node
this%nnz = 1
new_node%is_red = .false.
return
end if
current => this%root
do while (associated(current))
previous => current
if (idx == current%idx) then
current%val = current%val + val
deallocate(new_node)
return
else if (idx < current%idx) then
current => current%left
else
current => current%right
end if
end do
if (idx < previous%idx) then
new_node%parent => previous
previous%left => new_node
else
new_node%parent => previous
previous%right => new_node
end if
call psb_d_rb_idx_tree_fix_insertion(this, new_node)
this%nnz = this%nnz + 1
end subroutine psb_d_rb_idx_tree_insert
subroutine psb_d_rb_idx_tree_fix_insertion(this, node)
use psb_d_rb_idx_tree_mod, psb_protect_name => psb_d_rb_idx_tree_fix_insertion
implicit none
class(psb_d_rb_idx_tree), intent(inout) :: this
type(psb_d_rb_idx_node), pointer, intent(inout) :: node
character(len=29) :: name
type(psb_d_rb_idx_node), pointer :: current, parent, grand_parent, uncle
name = 'psb_rb_idx_tree_fix_insertion'
current => node
parent => current%parent
do while(associated(parent) .and. parent%is_red)
! grand parent exist because root can't be red
grand_parent => parent%parent
if (parent%idx < grand_parent%idx) then
uncle => grand_parent%right
else
uncle => grand_parent%left
end if
if (associated(uncle) .and. uncle%is_red) then
parent%is_red = .false.
uncle%is_red = .false.
grand_parent%is_red = .true.
current => grand_parent
parent => current%parent
! Left-Left case
else if (current%idx < parent%idx .and. &
parent%idx < grand_parent%idx) then
call psb_d_rb_idx_tree_rotate_right(grand_parent)
call psb_d_rb_idx_tree_swap_colors(parent, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => parent
return
! Left-Right case
else if (current%idx > parent%idx .and. &
parent%idx < grand_parent%idx) then
call psb_d_rb_idx_tree_rotate_left(parent)
call psb_d_rb_idx_tree_rotate_right(grand_parent)
call psb_d_rb_idx_tree_swap_colors(current, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => current
return
! Right-Right case
else if (current%idx > parent%idx .and. &
parent%idx > grand_parent%idx) then
call psb_d_rb_idx_tree_rotate_left(grand_parent)
call psb_d_rb_idx_tree_swap_colors(parent, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => parent
return
! Right-Left case
else
call psb_d_rb_idx_tree_rotate_right(parent)
call psb_d_rb_idx_tree_rotate_left(grand_parent)
call psb_d_rb_idx_tree_swap_colors(current, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => current
return
end if
end do
this%root%is_red = .false.
end subroutine psb_d_rb_idx_tree_fix_insertion
subroutine psb_d_rb_idx_tree_swap_colors(n1, n2)
use psb_d_rb_idx_tree_mod, psb_protect_name => psb_d_rb_idx_tree_swap_colors
implicit none
type(psb_d_rb_idx_node), pointer, intent(inout) :: n1, n2
character(len=27) :: name
logical :: tmp
name='psb_rb_idx_tree_swap_colors'
tmp = n1%is_red
n1%is_red = n2%is_red
n2%is_red = tmp
end subroutine psb_d_rb_idx_tree_swap_colors
subroutine psb_d_rb_idx_tree_rotate_right(node)
use psb_d_rb_idx_tree_mod, psb_protect_name => psb_d_rb_idx_tree_rotate_right
implicit none
type(psb_d_rb_idx_node), pointer, intent(inout) :: node
character(len=28) :: name
type(psb_d_rb_idx_node), pointer :: l, lr
name='psb_rb_idx_tree_rotate_right'
if (.not. associated(node%left)) return
l => node%left
lr => l%right
node%left => lr
if (associated(lr)) lr%parent => node
if (associated(node%parent)) then
if (node%idx < node%parent%idx) then
node%parent%left => l
else
node%parent%right => l
end if
end if
l%parent => node%parent
node%parent => l
l%right => node
end subroutine psb_d_rb_idx_tree_rotate_right
subroutine psb_d_rb_idx_tree_rotate_left(node)
use psb_d_rb_idx_tree_mod, psb_protect_name => psb_d_rb_idx_tree_rotate_left
implicit none
type(psb_d_rb_idx_node), pointer, intent(inout) :: node
character(len=27) :: name
type(psb_d_rb_idx_node), pointer :: r, rl
name='psb_rb_idx_tree_rotate_left'
if (.not. associated(node%right)) return
r => node%right
rl => r%left
node%right => rl
if (associated(rl)) rl%parent => node
if (associated(node%parent)) then
if (node%idx < node%parent%idx) then
node%parent%left => r
else
node%parent%right => r
end if
end if
r%parent => node%parent
node%parent => r
r%left => node
end subroutine psb_d_rb_idx_tree_rotate_left
subroutine psb_d_rb_idx_tree_scalar_sparse_row_mul(tree, scalar, mat, row_num)
use psb_d_rb_idx_tree_mod, psb_protect_name => psb_d_rb_idx_tree_scalar_sparse_row_mul
use psb_d_csr_mat_mod, only : psb_d_csr_sparse_mat
implicit none
type(psb_d_rb_idx_tree), intent(inout) :: tree
real(psb_dpk_), intent(in) :: scalar
type(psb_d_csr_sparse_mat), intent(in) :: mat
integer(psb_ipk_), intent(in) :: row_num
character(len=37) :: name
integer(psb_ipk_) :: i
name='psb_rb_idx_tree_scalar_sparse_row_mul'
do i = mat%irp(row_num), mat%irp(row_num + 1) - 1
call tree%insert(mat%ja(i),scalar * mat%val(i))
end do
end subroutine psb_d_rb_idx_tree_scalar_sparse_row_mul
subroutine psb_d_rb_idx_tree_merge(trees, mat)
#if defined(OPENMP)
use omp_lib
#endif
use psb_realloc_mod
use psb_d_rb_idx_tree_mod, psb_protect_name => psb_d_rb_idx_tree_merge
use psb_d_csr_mat_mod, only : psb_d_csr_sparse_mat
implicit none
type(psb_d_rb_idx_tree), allocatable, intent(inout) :: trees(:)
type(psb_d_csr_sparse_mat), intent(inout) :: mat
character(len=21) :: name
integer(psb_ipk_) :: i, j, rows, info, nnz
type(psb_d_rb_idx_node), pointer :: current, previous
name='psb_rb_idx_tree_merge'
rows = size(trees)
mat%irp(1) = 1
do i=1, rows
mat%irp(i + 1) = mat%irp(i) + trees(i)%nnz
end do
nnz = mat%irp(rows + 1)
call psb_realloc(nnz, mat%val, info)
call psb_realloc(nnz, mat%ja, info)
#if defined(OPENMP)
!$omp parallel do schedule(static), private(current, previous, j)
#endif
do i = 1, size(trees)
j = 0
current => trees(i)%root
do while(associated(current))
! go to the left-most node
do while(associated(current%left))
current => current%left
end do
mat%val(j + mat%irp(i)) = current%val
mat%ja(j + mat%irp(i)) = current%idx
j = j + 1
previous => current
if (associated(current%right)) then
if (associated(current%parent)) then
current%parent%left => current%right
end if
current%right%parent => current%parent
current => current%right
else
current => current%parent
if (associated(current)) nullify(current%left)
end if
deallocate(previous)
end do
end do
#if defined(OPENMP)
!$omp end parallel do
#endif
end subroutine psb_d_rb_idx_tree_merge

File diff suppressed because it is too large Load Diff

@ -2189,6 +2189,9 @@ subroutine psb_s_mv_csc_from_coo(a,b,info)
use psb_error_mod
use psb_s_base_mat_mod
use psb_s_csc_mat_mod, psb_protect_name => psb_s_mv_csc_from_coo
#if defined(OPENMP)
use omp_lib
#endif
implicit none
class(psb_s_csc_sparse_mat), intent(inout) :: a
@ -2223,18 +2226,33 @@ subroutine psb_s_mv_csc_from_coo(a,b,info)
call psb_realloc(nc+1,a%icp,info)
call b%free()
#if defined(OPENMP)
!$OMP PARALLEL default(shared)
!$OMP WORKSHARE
a%icp(:) = 0
!$OMP END WORKSHARE
!$OMP DO schedule(STATIC) &
!$OMP private(k,i)
do k=1,nza
i = itemp(k)
a%icp(i) = a%icp(i) + 1
!$OMP ATOMIC UPDATE
a%icp(i+1) = a%icp(i+1) + 1
!$OMP END ATOMIC
end do
ip = 1
do i=1,nc
nrl = a%icp(i)
a%icp(i) = ip
ip = ip + nrl
!$OMP END DO
call psi_exscan(nc+1,a%icp,info,shift=ione)
!$OMP END PARALLEL
#else
a%icp(:) = 0
do k=1,nza
i = itemp(k)
a%icp(i) = a%icp(i) + 1
end do
a%icp(nc+1) = ip
call psi_exscan(nc+1,a%icp,info,shift=ione)
#endif
call a%set_host()
@ -2311,9 +2329,28 @@ subroutine psb_s_cp_csc_to_fmt(a,b,info)
b%psb_s_base_sparse_mat = a%psb_s_base_sparse_mat
nc = a%get_ncols()
nz = a%get_nzeros()
if (info == 0) call psb_safe_cpy( a%icp(1:nc+1), b%icp , info)
if (info == 0) call psb_safe_cpy( a%ia(1:nz), b%ia , info)
if (info == 0) call psb_safe_cpy( a%val(1:nz), b%val , info)
if (.false.) then
if (info == 0) call psb_safe_cpy( a%icp(1:nc+1), b%icp , info)
if (info == 0) call psb_safe_cpy( a%ia(1:nz), b%ia , info)
if (info == 0) call psb_safe_cpy( a%val(1:nz), b%val , info)
else
! Despite the implementation in safe_cpy, it seems better this way
call psb_realloc(nc+1,b%icp,info)
call psb_realloc(nz,b%ia,info)
call psb_realloc(nz,b%val,info)
!$omp parallel do private(i) schedule(static)
do i=1,nc+1
b%icp(i)=a%icp(i)
end do
!$omp end parallel do
!$omp parallel do private(j) schedule(static)
do j=1,nz
b%ia(j) = a%ia(j)
b%val(j) = a%val(j)
end do
!$omp end parallel do
end if
call b%set_host()
class default
@ -2425,9 +2462,27 @@ subroutine psb_s_cp_csc_from_fmt(a,b,info)
a%psb_s_base_sparse_mat = b%psb_s_base_sparse_mat
nc = b%get_ncols()
nz = b%get_nzeros()
if (info == 0) call psb_safe_cpy( b%icp(1:nc+1), a%icp , info)
if (info == 0) call psb_safe_cpy( b%ia(1:nz), a%ia , info)
if (info == 0) call psb_safe_cpy( b%val(1:nz), a%val , info)
if (.false.) then
if (info == 0) call psb_safe_cpy( b%icp(1:nc+1), a%icp , info)
if (info == 0) call psb_safe_cpy( b%ia(1:nz), a%ia , info)
if (info == 0) call psb_safe_cpy( b%val(1:nz), a%val , info)
else
! Despite the implementation in safe_cpy, it seems better this way
call psb_realloc(nc+1,a%icp,info)
call psb_realloc(nz,a%ia,info)
call psb_realloc(nz,a%val,info)
!$omp parallel do private(i) schedule(static)
do i=1,nc+1
a%icp(i)=b%icp(i)
end do
!$omp end parallel do
!$omp parallel do private(j) schedule(static)
do j=1,nz
a%ia(j)=b%ia(j)
a%val(j)=b%val(j)
end do
!$omp end parallel do
end if
call a%set_host()
class default

File diff suppressed because it is too large Load Diff

@ -0,0 +1,329 @@
!
! Parallel Sparse BLAS version 3.5
! (C) Copyright 2006-2018
! Salvatore Filippone
! Alfredo Buttari
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
! package: psb_s_rb_idx_tree_impl
!
! Red black tree implementation ordered by index
!
! Each node contains and index and a double precision value
!
! The tree should always be well balanced
!
! inserting a node with an existing index will
! add up the new value to the old one
! Contributed by Dimitri Walther
!
subroutine psb_s_rb_idx_tree_insert(this, idx, val)
use psb_s_rb_idx_tree_mod, psb_protect_name => psb_s_rb_idx_tree_insert
implicit none
class(psb_s_rb_idx_tree), intent(inout) :: this
integer(psb_ipk_), intent(in) :: idx
real(psb_spk_), intent(in) :: val
character(len=22) :: name
type(psb_s_rb_idx_node), pointer :: new_node
type(psb_s_rb_idx_node), pointer :: current, previous
name='psb_rb_idx_tree_insert'
allocate(new_node)
new_node%idx = idx
new_node%val = val
nullify(new_node%left)
nullify(new_node%right)
nullify(new_node%parent)
new_node%is_red = .true.
if (.not. associated(this%root)) then
this%root => new_node
this%nnz = 1
new_node%is_red = .false.
return
end if
current => this%root
do while (associated(current))
previous => current
if (idx == current%idx) then
current%val = current%val + val
deallocate(new_node)
return
else if (idx < current%idx) then
current => current%left
else
current => current%right
end if
end do
if (idx < previous%idx) then
new_node%parent => previous
previous%left => new_node
else
new_node%parent => previous
previous%right => new_node
end if
call psb_s_rb_idx_tree_fix_insertion(this, new_node)
this%nnz = this%nnz + 1
end subroutine psb_s_rb_idx_tree_insert
subroutine psb_s_rb_idx_tree_fix_insertion(this, node)
use psb_s_rb_idx_tree_mod, psb_protect_name => psb_s_rb_idx_tree_fix_insertion
implicit none
class(psb_s_rb_idx_tree), intent(inout) :: this
type(psb_s_rb_idx_node), pointer, intent(inout) :: node
character(len=29) :: name
type(psb_s_rb_idx_node), pointer :: current, parent, grand_parent, uncle
name = 'psb_rb_idx_tree_fix_insertion'
current => node
parent => current%parent
do while(associated(parent) .and. parent%is_red)
! grand parent exist because root can't be red
grand_parent => parent%parent
if (parent%idx < grand_parent%idx) then
uncle => grand_parent%right
else
uncle => grand_parent%left
end if
if (associated(uncle) .and. uncle%is_red) then
parent%is_red = .false.
uncle%is_red = .false.
grand_parent%is_red = .true.
current => grand_parent
parent => current%parent
! Left-Left case
else if (current%idx < parent%idx .and. &
parent%idx < grand_parent%idx) then
call psb_s_rb_idx_tree_rotate_right(grand_parent)
call psb_s_rb_idx_tree_swap_colors(parent, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => parent
return
! Left-Right case
else if (current%idx > parent%idx .and. &
parent%idx < grand_parent%idx) then
call psb_s_rb_idx_tree_rotate_left(parent)
call psb_s_rb_idx_tree_rotate_right(grand_parent)
call psb_s_rb_idx_tree_swap_colors(current, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => current
return
! Right-Right case
else if (current%idx > parent%idx .and. &
parent%idx > grand_parent%idx) then
call psb_s_rb_idx_tree_rotate_left(grand_parent)
call psb_s_rb_idx_tree_swap_colors(parent, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => parent
return
! Right-Left case
else
call psb_s_rb_idx_tree_rotate_right(parent)
call psb_s_rb_idx_tree_rotate_left(grand_parent)
call psb_s_rb_idx_tree_swap_colors(current, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => current
return
end if
end do
this%root%is_red = .false.
end subroutine psb_s_rb_idx_tree_fix_insertion
subroutine psb_s_rb_idx_tree_swap_colors(n1, n2)
use psb_s_rb_idx_tree_mod, psb_protect_name => psb_s_rb_idx_tree_swap_colors
implicit none
type(psb_s_rb_idx_node), pointer, intent(inout) :: n1, n2
character(len=27) :: name
logical :: tmp
name='psb_rb_idx_tree_swap_colors'
tmp = n1%is_red
n1%is_red = n2%is_red
n2%is_red = tmp
end subroutine psb_s_rb_idx_tree_swap_colors
subroutine psb_s_rb_idx_tree_rotate_right(node)
use psb_s_rb_idx_tree_mod, psb_protect_name => psb_s_rb_idx_tree_rotate_right
implicit none
type(psb_s_rb_idx_node), pointer, intent(inout) :: node
character(len=28) :: name
type(psb_s_rb_idx_node), pointer :: l, lr
name='psb_rb_idx_tree_rotate_right'
if (.not. associated(node%left)) return
l => node%left
lr => l%right
node%left => lr
if (associated(lr)) lr%parent => node
if (associated(node%parent)) then
if (node%idx < node%parent%idx) then
node%parent%left => l
else
node%parent%right => l
end if
end if
l%parent => node%parent
node%parent => l
l%right => node
end subroutine psb_s_rb_idx_tree_rotate_right
subroutine psb_s_rb_idx_tree_rotate_left(node)
use psb_s_rb_idx_tree_mod, psb_protect_name => psb_s_rb_idx_tree_rotate_left
implicit none
type(psb_s_rb_idx_node), pointer, intent(inout) :: node
character(len=27) :: name
type(psb_s_rb_idx_node), pointer :: r, rl
name='psb_rb_idx_tree_rotate_left'
if (.not. associated(node%right)) return
r => node%right
rl => r%left
node%right => rl
if (associated(rl)) rl%parent => node
if (associated(node%parent)) then
if (node%idx < node%parent%idx) then
node%parent%left => r
else
node%parent%right => r
end if
end if
r%parent => node%parent
node%parent => r
r%left => node
end subroutine psb_s_rb_idx_tree_rotate_left
subroutine psb_s_rb_idx_tree_scalar_sparse_row_mul(tree, scalar, mat, row_num)
use psb_s_rb_idx_tree_mod, psb_protect_name => psb_s_rb_idx_tree_scalar_sparse_row_mul
use psb_s_csr_mat_mod, only : psb_s_csr_sparse_mat
implicit none
type(psb_s_rb_idx_tree), intent(inout) :: tree
real(psb_spk_), intent(in) :: scalar
type(psb_s_csr_sparse_mat), intent(in) :: mat
integer(psb_ipk_), intent(in) :: row_num
character(len=37) :: name
integer(psb_ipk_) :: i
name='psb_rb_idx_tree_scalar_sparse_row_mul'
do i = mat%irp(row_num), mat%irp(row_num + 1) - 1
call tree%insert(mat%ja(i),scalar * mat%val(i))
end do
end subroutine psb_s_rb_idx_tree_scalar_sparse_row_mul
subroutine psb_s_rb_idx_tree_merge(trees, mat)
#if defined(OPENMP)
use omp_lib
#endif
use psb_realloc_mod
use psb_s_rb_idx_tree_mod, psb_protect_name => psb_s_rb_idx_tree_merge
use psb_s_csr_mat_mod, only : psb_s_csr_sparse_mat
implicit none
type(psb_s_rb_idx_tree), allocatable, intent(inout) :: trees(:)
type(psb_s_csr_sparse_mat), intent(inout) :: mat
character(len=21) :: name
integer(psb_ipk_) :: i, j, rows, info, nnz
type(psb_s_rb_idx_node), pointer :: current, previous
name='psb_rb_idx_tree_merge'
rows = size(trees)
mat%irp(1) = 1
do i=1, rows
mat%irp(i + 1) = mat%irp(i) + trees(i)%nnz
end do
nnz = mat%irp(rows + 1)
call psb_realloc(nnz, mat%val, info)
call psb_realloc(nnz, mat%ja, info)
#if defined(OPENMP)
!$omp parallel do schedule(static), private(current, previous, j)
#endif
do i = 1, size(trees)
j = 0
current => trees(i)%root
do while(associated(current))
! go to the left-most node
do while(associated(current%left))
current => current%left
end do
mat%val(j + mat%irp(i)) = current%val
mat%ja(j + mat%irp(i)) = current%idx
j = j + 1
previous => current
if (associated(current%right)) then
if (associated(current%parent)) then
current%parent%left => current%right
end if
current%right%parent => current%parent
current => current%right
else
current => current%parent
if (associated(current)) nullify(current%left)
end if
deallocate(previous)
end do
end do
#if defined(OPENMP)
!$omp end parallel do
#endif
end subroutine psb_s_rb_idx_tree_merge

File diff suppressed because it is too large Load Diff

@ -2189,6 +2189,9 @@ subroutine psb_z_mv_csc_from_coo(a,b,info)
use psb_error_mod
use psb_z_base_mat_mod
use psb_z_csc_mat_mod, psb_protect_name => psb_z_mv_csc_from_coo
#if defined(OPENMP)
use omp_lib
#endif
implicit none
class(psb_z_csc_sparse_mat), intent(inout) :: a
@ -2223,18 +2226,33 @@ subroutine psb_z_mv_csc_from_coo(a,b,info)
call psb_realloc(nc+1,a%icp,info)
call b%free()
#if defined(OPENMP)
!$OMP PARALLEL default(shared)
!$OMP WORKSHARE
a%icp(:) = 0
!$OMP END WORKSHARE
!$OMP DO schedule(STATIC) &
!$OMP private(k,i)
do k=1,nza
i = itemp(k)
a%icp(i) = a%icp(i) + 1
!$OMP ATOMIC UPDATE
a%icp(i+1) = a%icp(i+1) + 1
!$OMP END ATOMIC
end do
ip = 1
do i=1,nc
nrl = a%icp(i)
a%icp(i) = ip
ip = ip + nrl
!$OMP END DO
call psi_exscan(nc+1,a%icp,info,shift=ione)
!$OMP END PARALLEL
#else
a%icp(:) = 0
do k=1,nza
i = itemp(k)
a%icp(i) = a%icp(i) + 1
end do
a%icp(nc+1) = ip
call psi_exscan(nc+1,a%icp,info,shift=ione)
#endif
call a%set_host()
@ -2311,9 +2329,28 @@ subroutine psb_z_cp_csc_to_fmt(a,b,info)
b%psb_z_base_sparse_mat = a%psb_z_base_sparse_mat
nc = a%get_ncols()
nz = a%get_nzeros()
if (info == 0) call psb_safe_cpy( a%icp(1:nc+1), b%icp , info)
if (info == 0) call psb_safe_cpy( a%ia(1:nz), b%ia , info)
if (info == 0) call psb_safe_cpy( a%val(1:nz), b%val , info)
if (.false.) then
if (info == 0) call psb_safe_cpy( a%icp(1:nc+1), b%icp , info)
if (info == 0) call psb_safe_cpy( a%ia(1:nz), b%ia , info)
if (info == 0) call psb_safe_cpy( a%val(1:nz), b%val , info)
else
! Despite the implementation in safe_cpy, it seems better this way
call psb_realloc(nc+1,b%icp,info)
call psb_realloc(nz,b%ia,info)
call psb_realloc(nz,b%val,info)
!$omp parallel do private(i) schedule(static)
do i=1,nc+1
b%icp(i)=a%icp(i)
end do
!$omp end parallel do
!$omp parallel do private(j) schedule(static)
do j=1,nz
b%ia(j) = a%ia(j)
b%val(j) = a%val(j)
end do
!$omp end parallel do
end if
call b%set_host()
class default
@ -2425,9 +2462,27 @@ subroutine psb_z_cp_csc_from_fmt(a,b,info)
a%psb_z_base_sparse_mat = b%psb_z_base_sparse_mat
nc = b%get_ncols()
nz = b%get_nzeros()
if (info == 0) call psb_safe_cpy( b%icp(1:nc+1), a%icp , info)
if (info == 0) call psb_safe_cpy( b%ia(1:nz), a%ia , info)
if (info == 0) call psb_safe_cpy( b%val(1:nz), a%val , info)
if (.false.) then
if (info == 0) call psb_safe_cpy( b%icp(1:nc+1), a%icp , info)
if (info == 0) call psb_safe_cpy( b%ia(1:nz), a%ia , info)
if (info == 0) call psb_safe_cpy( b%val(1:nz), a%val , info)
else
! Despite the implementation in safe_cpy, it seems better this way
call psb_realloc(nc+1,a%icp,info)
call psb_realloc(nz,a%ia,info)
call psb_realloc(nz,a%val,info)
!$omp parallel do private(i) schedule(static)
do i=1,nc+1
a%icp(i)=b%icp(i)
end do
!$omp end parallel do
!$omp parallel do private(j) schedule(static)
do j=1,nz
a%ia(j)=b%ia(j)
a%val(j)=b%val(j)
end do
!$omp end parallel do
end if
call a%set_host()
class default

File diff suppressed because it is too large Load Diff

@ -0,0 +1,329 @@
!
! Parallel Sparse BLAS version 3.5
! (C) Copyright 2006-2018
! Salvatore Filippone
! Alfredo Buttari
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
! package: psb_z_rb_idx_tree_impl
!
! Red black tree implementation ordered by index
!
! Each node contains and index and a double precision value
!
! The tree should always be well balanced
!
! inserting a node with an existing index will
! add up the new value to the old one
! Contributed by Dimitri Walther
!
subroutine psb_z_rb_idx_tree_insert(this, idx, val)
use psb_z_rb_idx_tree_mod, psb_protect_name => psb_z_rb_idx_tree_insert
implicit none
class(psb_z_rb_idx_tree), intent(inout) :: this
integer(psb_ipk_), intent(in) :: idx
complex(psb_dpk_), intent(in) :: val
character(len=22) :: name
type(psb_z_rb_idx_node), pointer :: new_node
type(psb_z_rb_idx_node), pointer :: current, previous
name='psb_rb_idx_tree_insert'
allocate(new_node)
new_node%idx = idx
new_node%val = val
nullify(new_node%left)
nullify(new_node%right)
nullify(new_node%parent)
new_node%is_red = .true.
if (.not. associated(this%root)) then
this%root => new_node
this%nnz = 1
new_node%is_red = .false.
return
end if
current => this%root
do while (associated(current))
previous => current
if (idx == current%idx) then
current%val = current%val + val
deallocate(new_node)
return
else if (idx < current%idx) then
current => current%left
else
current => current%right
end if
end do
if (idx < previous%idx) then
new_node%parent => previous
previous%left => new_node
else
new_node%parent => previous
previous%right => new_node
end if
call psb_z_rb_idx_tree_fix_insertion(this, new_node)
this%nnz = this%nnz + 1
end subroutine psb_z_rb_idx_tree_insert
subroutine psb_z_rb_idx_tree_fix_insertion(this, node)
use psb_z_rb_idx_tree_mod, psb_protect_name => psb_z_rb_idx_tree_fix_insertion
implicit none
class(psb_z_rb_idx_tree), intent(inout) :: this
type(psb_z_rb_idx_node), pointer, intent(inout) :: node
character(len=29) :: name
type(psb_z_rb_idx_node), pointer :: current, parent, grand_parent, uncle
name = 'psb_rb_idx_tree_fix_insertion'
current => node
parent => current%parent
do while(associated(parent) .and. parent%is_red)
! grand parent exist because root can't be red
grand_parent => parent%parent
if (parent%idx < grand_parent%idx) then
uncle => grand_parent%right
else
uncle => grand_parent%left
end if
if (associated(uncle) .and. uncle%is_red) then
parent%is_red = .false.
uncle%is_red = .false.
grand_parent%is_red = .true.
current => grand_parent
parent => current%parent
! Left-Left case
else if (current%idx < parent%idx .and. &
parent%idx < grand_parent%idx) then
call psb_z_rb_idx_tree_rotate_right(grand_parent)
call psb_z_rb_idx_tree_swap_colors(parent, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => parent
return
! Left-Right case
else if (current%idx > parent%idx .and. &
parent%idx < grand_parent%idx) then
call psb_z_rb_idx_tree_rotate_left(parent)
call psb_z_rb_idx_tree_rotate_right(grand_parent)
call psb_z_rb_idx_tree_swap_colors(current, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => current
return
! Right-Right case
else if (current%idx > parent%idx .and. &
parent%idx > grand_parent%idx) then
call psb_z_rb_idx_tree_rotate_left(grand_parent)
call psb_z_rb_idx_tree_swap_colors(parent, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => parent
return
! Right-Left case
else
call psb_z_rb_idx_tree_rotate_right(parent)
call psb_z_rb_idx_tree_rotate_left(grand_parent)
call psb_z_rb_idx_tree_swap_colors(current, grand_parent)
if (this%root%idx == grand_parent%idx) this%root => current
return
end if
end do
this%root%is_red = .false.
end subroutine psb_z_rb_idx_tree_fix_insertion
subroutine psb_z_rb_idx_tree_swap_colors(n1, n2)
use psb_z_rb_idx_tree_mod, psb_protect_name => psb_z_rb_idx_tree_swap_colors
implicit none
type(psb_z_rb_idx_node), pointer, intent(inout) :: n1, n2
character(len=27) :: name
logical :: tmp
name='psb_rb_idx_tree_swap_colors'
tmp = n1%is_red
n1%is_red = n2%is_red
n2%is_red = tmp
end subroutine psb_z_rb_idx_tree_swap_colors
subroutine psb_z_rb_idx_tree_rotate_right(node)
use psb_z_rb_idx_tree_mod, psb_protect_name => psb_z_rb_idx_tree_rotate_right
implicit none
type(psb_z_rb_idx_node), pointer, intent(inout) :: node
character(len=28) :: name
type(psb_z_rb_idx_node), pointer :: l, lr
name='psb_rb_idx_tree_rotate_right'
if (.not. associated(node%left)) return
l => node%left
lr => l%right
node%left => lr
if (associated(lr)) lr%parent => node
if (associated(node%parent)) then
if (node%idx < node%parent%idx) then
node%parent%left => l
else
node%parent%right => l
end if
end if
l%parent => node%parent
node%parent => l
l%right => node
end subroutine psb_z_rb_idx_tree_rotate_right
subroutine psb_z_rb_idx_tree_rotate_left(node)
use psb_z_rb_idx_tree_mod, psb_protect_name => psb_z_rb_idx_tree_rotate_left
implicit none
type(psb_z_rb_idx_node), pointer, intent(inout) :: node
character(len=27) :: name
type(psb_z_rb_idx_node), pointer :: r, rl
name='psb_rb_idx_tree_rotate_left'
if (.not. associated(node%right)) return
r => node%right
rl => r%left
node%right => rl
if (associated(rl)) rl%parent => node
if (associated(node%parent)) then
if (node%idx < node%parent%idx) then
node%parent%left => r
else
node%parent%right => r
end if
end if
r%parent => node%parent
node%parent => r
r%left => node
end subroutine psb_z_rb_idx_tree_rotate_left
subroutine psb_z_rb_idx_tree_scalar_sparse_row_mul(tree, scalar, mat, row_num)
use psb_z_rb_idx_tree_mod, psb_protect_name => psb_z_rb_idx_tree_scalar_sparse_row_mul
use psb_z_csr_mat_mod, only : psb_z_csr_sparse_mat
implicit none
type(psb_z_rb_idx_tree), intent(inout) :: tree
complex(psb_dpk_), intent(in) :: scalar
type(psb_z_csr_sparse_mat), intent(in) :: mat
integer(psb_ipk_), intent(in) :: row_num
character(len=37) :: name
integer(psb_ipk_) :: i
name='psb_rb_idx_tree_scalar_sparse_row_mul'
do i = mat%irp(row_num), mat%irp(row_num + 1) - 1
call tree%insert(mat%ja(i),scalar * mat%val(i))
end do
end subroutine psb_z_rb_idx_tree_scalar_sparse_row_mul
subroutine psb_z_rb_idx_tree_merge(trees, mat)
#if defined(OPENMP)
use omp_lib
#endif
use psb_realloc_mod
use psb_z_rb_idx_tree_mod, psb_protect_name => psb_z_rb_idx_tree_merge
use psb_z_csr_mat_mod, only : psb_z_csr_sparse_mat
implicit none
type(psb_z_rb_idx_tree), allocatable, intent(inout) :: trees(:)
type(psb_z_csr_sparse_mat), intent(inout) :: mat
character(len=21) :: name
integer(psb_ipk_) :: i, j, rows, info, nnz
type(psb_z_rb_idx_node), pointer :: current, previous
name='psb_rb_idx_tree_merge'
rows = size(trees)
mat%irp(1) = 1
do i=1, rows
mat%irp(i + 1) = mat%irp(i) + trees(i)%nnz
end do
nnz = mat%irp(rows + 1)
call psb_realloc(nnz, mat%val, info)
call psb_realloc(nnz, mat%ja, info)
#if defined(OPENMP)
!$omp parallel do schedule(static), private(current, previous, j)
#endif
do i = 1, size(trees)
j = 0
current => trees(i)%root
do while(associated(current))
! go to the left-most node
do while(associated(current%left))
current => current%left
end do
mat%val(j + mat%irp(i)) = current%val
mat%ja(j + mat%irp(i)) = current%idx
j = j + 1
previous => current
if (associated(current%right)) then
if (associated(current%parent)) then
current%parent%left => current%right
end if
current%right%parent => current%parent
current => current%right
else
current => current%parent
if (associated(current)) nullify(current%left)
end if
deallocate(previous)
end do
end do
#if defined(OPENMP)
!$omp end parallel do
#endif
end subroutine psb_z_rb_idx_tree_merge

@ -29,6 +29,107 @@
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine psi_c_exscanv(n,x,info,shift)
use psi_c_serial_mod, psb_protect_name => psi_c_exscanv
use psb_const_mod
use psb_error_mod
#if defined(OPENMP)
use omp_lib
#endif
implicit none
integer(psb_ipk_), intent(in) :: n
complex(psb_spk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
complex(psb_spk_), intent(in), optional :: shift
complex(psb_spk_) :: shift_, tp, ts
integer(psb_ipk_) :: i
logical is_nested, is_parallel
if (present(shift)) then
shift_ = shift
else
shift_ = czero
end if
#if defined(OPENMP)
is_parallel = omp_in_parallel()
if (is_parallel) then
call inner_c_exscan()
else
!$OMP PARALLEL default(shared)
call inner_c_exscan()
!$OMP END PARALLEL
end if
#else
tp = shift_
do i=1,n
ts = x(i)
x(i) = tp
tp = tp + ts
end do
#endif
#if defined(OPENMP)
contains
subroutine inner_c_exscan()
! Note: all these variables are private, but SUMB should *really* be
! a pointer. The semantics of COPYPRIVATE is that the POINTER is copied
! so effectively we are recovering a SHARED SUMB which is what
! we need in this case. If it was an ALLOCATABLE, then it would be the contents
! that would get copied, and the SHARED effect would no longer be there.
! Simple parallel version of EXSCAN
integer(psb_ipk_) :: i,ithread,nthreads,idxstart,idxend,wrk
complex(psb_spk_), pointer :: sumb(:)
complex(psb_spk_) :: tp, ts
nthreads = omp_get_num_threads()
ithread = omp_get_thread_num()
!$OMP SINGLE
allocate(sumb(nthreads+1))
sumb(:) = 0
!$OMP END SINGLE COPYPRIVATE(sumb)
wrk = (n)/nthreads
if (ithread < MOD((n),nthreads)) then
wrk = wrk + 1
idxstart = ithread*wrk + 1
else
idxstart = ithread*wrk + MOD((n),nthreads) + 1
end if
idxend = min(idxstart + wrk - 1,n )
tp = czero
if (idxstart<=idxend) then
do i=idxstart,idxend
ts = x(i)
x(i) = tp
tp = tp + ts
end do
end if
sumb(ithread+2) = tp
!$OMP BARRIER
!$OMP SINGLE
do i=2,nthreads+1
sumb(i) = sumb(i) + sumb(i-1)
end do
!$OMP END SINGLE
!$OMP BARRIER
!$OMP DO SCHEDULE(STATIC)
do i=1,n
x(i) = x(i) + sumb(ithread+1) + shift_
end do
!$OMP END DO
!$OMP SINGLE
deallocate(sumb)
!$OMP END SINGLE
end subroutine inner_c_exscan
#endif
end subroutine psi_c_exscanv
subroutine psb_m_cgelp(trans,iperm,x,info)
use psb_serial_mod, psb_protect_name => psb_m_cgelp
use psb_const_mod

@ -29,6 +29,107 @@
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine psi_d_exscanv(n,x,info,shift)
use psi_d_serial_mod, psb_protect_name => psi_d_exscanv
use psb_const_mod
use psb_error_mod
#if defined(OPENMP)
use omp_lib
#endif
implicit none
integer(psb_ipk_), intent(in) :: n
real(psb_dpk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
real(psb_dpk_), intent(in), optional :: shift
real(psb_dpk_) :: shift_, tp, ts
integer(psb_ipk_) :: i
logical is_nested, is_parallel
if (present(shift)) then
shift_ = shift
else
shift_ = dzero
end if
#if defined(OPENMP)
is_parallel = omp_in_parallel()
if (is_parallel) then
call inner_d_exscan()
else
!$OMP PARALLEL default(shared)
call inner_d_exscan()
!$OMP END PARALLEL
end if
#else
tp = shift_
do i=1,n
ts = x(i)
x(i) = tp
tp = tp + ts
end do
#endif
#if defined(OPENMP)
contains
subroutine inner_d_exscan()
! Note: all these variables are private, but SUMB should *really* be
! a pointer. The semantics of COPYPRIVATE is that the POINTER is copied
! so effectively we are recovering a SHARED SUMB which is what
! we need in this case. If it was an ALLOCATABLE, then it would be the contents
! that would get copied, and the SHARED effect would no longer be there.
! Simple parallel version of EXSCAN
integer(psb_ipk_) :: i,ithread,nthreads,idxstart,idxend,wrk
real(psb_dpk_), pointer :: sumb(:)
real(psb_dpk_) :: tp, ts
nthreads = omp_get_num_threads()
ithread = omp_get_thread_num()
!$OMP SINGLE
allocate(sumb(nthreads+1))
sumb(:) = 0
!$OMP END SINGLE COPYPRIVATE(sumb)
wrk = (n)/nthreads
if (ithread < MOD((n),nthreads)) then
wrk = wrk + 1
idxstart = ithread*wrk + 1
else
idxstart = ithread*wrk + MOD((n),nthreads) + 1
end if
idxend = min(idxstart + wrk - 1,n )
tp = dzero
if (idxstart<=idxend) then
do i=idxstart,idxend
ts = x(i)
x(i) = tp
tp = tp + ts
end do
end if
sumb(ithread+2) = tp
!$OMP BARRIER
!$OMP SINGLE
do i=2,nthreads+1
sumb(i) = sumb(i) + sumb(i-1)
end do
!$OMP END SINGLE
!$OMP BARRIER
!$OMP DO SCHEDULE(STATIC)
do i=1,n
x(i) = x(i) + sumb(ithread+1) + shift_
end do
!$OMP END DO
!$OMP SINGLE
deallocate(sumb)
!$OMP END SINGLE
end subroutine inner_d_exscan
#endif
end subroutine psi_d_exscanv
subroutine psb_m_dgelp(trans,iperm,x,info)
use psb_serial_mod, psb_protect_name => psb_m_dgelp
use psb_const_mod

@ -29,6 +29,107 @@
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine psi_e_exscanv(n,x,info,shift)
use psi_e_serial_mod, psb_protect_name => psi_e_exscanv
use psb_const_mod
use psb_error_mod
#if defined(OPENMP)
use omp_lib
#endif
implicit none
integer(psb_ipk_), intent(in) :: n
integer(psb_epk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
integer(psb_epk_), intent(in), optional :: shift
integer(psb_epk_) :: shift_, tp, ts
integer(psb_ipk_) :: i
logical is_nested, is_parallel
if (present(shift)) then
shift_ = shift
else
shift_ = ezero
end if
#if defined(OPENMP)
is_parallel = omp_in_parallel()
if (is_parallel) then
call inner_e_exscan()
else
!$OMP PARALLEL default(shared)
call inner_e_exscan()
!$OMP END PARALLEL
end if
#else
tp = shift_
do i=1,n
ts = x(i)
x(i) = tp
tp = tp + ts
end do
#endif
#if defined(OPENMP)
contains
subroutine inner_e_exscan()
! Note: all these variables are private, but SUMB should *really* be
! a pointer. The semantics of COPYPRIVATE is that the POINTER is copied
! so effectively we are recovering a SHARED SUMB which is what
! we need in this case. If it was an ALLOCATABLE, then it would be the contents
! that would get copied, and the SHARED effect would no longer be there.
! Simple parallel version of EXSCAN
integer(psb_ipk_) :: i,ithread,nthreads,idxstart,idxend,wrk
integer(psb_epk_), pointer :: sumb(:)
integer(psb_epk_) :: tp, ts
nthreads = omp_get_num_threads()
ithread = omp_get_thread_num()
!$OMP SINGLE
allocate(sumb(nthreads+1))
sumb(:) = 0
!$OMP END SINGLE COPYPRIVATE(sumb)
wrk = (n)/nthreads
if (ithread < MOD((n),nthreads)) then
wrk = wrk + 1
idxstart = ithread*wrk + 1
else
idxstart = ithread*wrk + MOD((n),nthreads) + 1
end if
idxend = min(idxstart + wrk - 1,n )
tp = ezero
if (idxstart<=idxend) then
do i=idxstart,idxend
ts = x(i)
x(i) = tp
tp = tp + ts
end do
end if
sumb(ithread+2) = tp
!$OMP BARRIER
!$OMP SINGLE
do i=2,nthreads+1
sumb(i) = sumb(i) + sumb(i-1)
end do
!$OMP END SINGLE
!$OMP BARRIER
!$OMP DO SCHEDULE(STATIC)
do i=1,n
x(i) = x(i) + sumb(ithread+1) + shift_
end do
!$OMP END DO
!$OMP SINGLE
deallocate(sumb)
!$OMP END SINGLE
end subroutine inner_e_exscan
#endif
end subroutine psi_e_exscanv
subroutine psb_m_egelp(trans,iperm,x,info)
use psb_serial_mod, psb_protect_name => psb_m_egelp
use psb_const_mod
@ -441,9 +542,9 @@ subroutine psi_eaxpby(m,n,alpha, x, beta, y, info)
integer(psb_epk_), intent (in) :: alpha, beta
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
integer(psb_ipk_) :: lx, ly
integer(psb_ipk_) :: lx, ly, i
integer(psb_ipk_) :: ierr(5)
character(len=20) :: name, ch_err
character(len=20) :: name, ch_err
name='psb_geaxpby'
info=psb_success_
@ -502,7 +603,8 @@ subroutine psi_eaxpbyv(m,alpha, x, beta, y, info)
integer(psb_ipk_) :: err_act
integer(psb_ipk_) :: lx, ly
integer(psb_ipk_) :: ierr(5)
character(len=20) :: name, ch_err
integer(psb_ipk_) :: i
character(len=20) :: name, ch_err
name='psb_geaxpby'
info=psb_success_
@ -532,7 +634,106 @@ subroutine psi_eaxpbyv(m,alpha, x, beta, y, info)
goto 9999
end if
if (m>0) call eaxpby(m,ione,alpha,x,lx,beta,y,ly,info)
! if (m>0) call eaxpby(m,ione,alpha,x,lx,beta,y,ly,info)
if (alpha.eq.ezero) then
if (beta.eq.ezero) then
!$omp parallel do private(i)
do i=1,m
y(i) = ezero
enddo
else if (beta.eq.eone) then
!
! Do nothing!
!
else if (beta.eq.-eone) then
!$omp parallel do private(i)
do i=1,m
y(i) = - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = beta*y(i)
enddo
endif
else if (alpha.eq.eone) then
if (beta.eq.ezero) then
!$omp parallel do private(i)
do i=1,m
y(i) = x(i)
enddo
else if (beta.eq.eone) then
!$omp parallel do private(i)
do i=1,m
y(i) = x(i) + y(i)
enddo
else if (beta.eq.-eone) then
!$omp parallel do private(i)
do i=1,m
y(i) = x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = x(i) + beta*y(i)
enddo
endif
else if (alpha.eq.-eone) then
if (beta.eq.ezero) then
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i)
enddo
else if (beta.eq.eone) then
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i) + y(i)
enddo
else if (beta.eq.-eone) then
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i) + beta*y(i)
enddo
endif
else
if (beta.eq.ezero) then
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i)
enddo
else if (beta.eq.eone) then
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i) + y(i)
enddo
else if (beta.eq.-eone) then
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i) + beta*y(i)
enddo
endif
endif
call psb_erractionrestore(err_act)
return
@ -555,7 +756,7 @@ subroutine psi_eaxpbyv2(m,alpha, x, beta, y, z, info)
integer(psb_epk_), intent (in) :: alpha, beta
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
integer(psb_ipk_) :: lx, ly, lz
integer(psb_ipk_) :: lx, ly, lz, i
integer(psb_ipk_) :: ierr(5)
character(len=20) :: name, ch_err
@ -594,7 +795,105 @@ subroutine psi_eaxpbyv2(m,alpha, x, beta, y, z, info)
goto 9999
end if
if (m>0) call eaxpbyv2(m,ione,alpha,x,lx,beta,y,ly,z,lz,info)
if (alpha.eq.ezero) then
if (beta.eq.ezero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = ezero
enddo
else if (beta.eq.eone) then
!
! Do nothing!
!
else if (beta.eq.-eone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = beta*y(i)
enddo
endif
else if (alpha.eq.eone) then
if (beta.eq.ezero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i)
enddo
else if (beta.eq.eone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i) + y(i)
enddo
else if (beta.eq.-eone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i) + beta*y(i)
enddo
endif
else if (alpha.eq.-eone) then
if (beta.eq.ezero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i)
enddo
else if (beta.eq.eone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i) + y(i)
enddo
else if (beta.eq.-eone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i) + beta*y(i)
enddo
endif
else
if (beta.eq.ezero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i)
enddo
else if (beta.eq.eone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i) + y(i)
enddo
else if (beta.eq.-eone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i) + beta*y(i)
enddo
endif
endif
call psb_erractionrestore(err_act)
return
@ -942,6 +1241,7 @@ subroutine eaxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (alpha.eq.ezero) then
if (beta.eq.ezero) then
do j=1, n
!$omp parallel do private(i)
do i=1,m
y(i,j) = ezero
enddo
@ -953,12 +1253,14 @@ subroutine eaxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = beta*y(i,j)
enddo
@ -969,12 +1271,14 @@ subroutine eaxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (beta.eq.ezero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j)
enddo
enddo
else if (beta.eq.eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j) + y(i,j)
enddo
@ -982,12 +1286,14 @@ subroutine eaxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j) + beta*y(i,j)
enddo
@ -998,12 +1304,14 @@ subroutine eaxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (beta.eq.ezero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j)
enddo
enddo
else if (beta.eq.eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j) + y(i,j)
enddo
@ -1011,12 +1319,14 @@ subroutine eaxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j) + beta*y(i,j)
enddo
@ -1027,12 +1337,14 @@ subroutine eaxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (beta.eq.ezero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j)
enddo
enddo
else if (beta.eq.eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j) + y(i,j)
enddo
@ -1040,12 +1352,14 @@ subroutine eaxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j) + beta*y(i,j)
enddo
@ -1131,12 +1445,14 @@ subroutine eaxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = beta*y(i,j)
enddo
@ -1147,12 +1463,14 @@ subroutine eaxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
if (beta.eq.ezero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j)
enddo
enddo
else if (beta.eq.eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j) + y(i,j)
enddo
@ -1160,12 +1478,14 @@ subroutine eaxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j) + beta*y(i,j)
enddo
@ -1176,12 +1496,14 @@ subroutine eaxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
if (beta.eq.ezero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j)
enddo
enddo
else if (beta.eq.eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j) + y(i,j)
enddo
@ -1189,12 +1511,14 @@ subroutine eaxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j) + beta*y(i,j)
enddo
@ -1205,12 +1529,14 @@ subroutine eaxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
if (beta.eq.ezero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j)
enddo
enddo
else if (beta.eq.eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j) + y(i,j)
enddo
@ -1218,12 +1544,14 @@ subroutine eaxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-eone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j) + beta*y(i,j)
enddo

@ -29,6 +29,107 @@
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine psi_i2_exscanv(n,x,info,shift)
use psi_i2_serial_mod, psb_protect_name => psi_i2_exscanv
use psb_const_mod
use psb_error_mod
#if defined(OPENMP)
use omp_lib
#endif
implicit none
integer(psb_ipk_), intent(in) :: n
integer(psb_i2pk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
integer(psb_i2pk_), intent(in), optional :: shift
integer(psb_i2pk_) :: shift_, tp, ts
integer(psb_ipk_) :: i
logical is_nested, is_parallel
if (present(shift)) then
shift_ = shift
else
shift_ = i2zero
end if
#if defined(OPENMP)
is_parallel = omp_in_parallel()
if (is_parallel) then
call inner_i2_exscan()
else
!$OMP PARALLEL default(shared)
call inner_i2_exscan()
!$OMP END PARALLEL
end if
#else
tp = shift_
do i=1,n
ts = x(i)
x(i) = tp
tp = tp + ts
end do
#endif
#if defined(OPENMP)
contains
subroutine inner_i2_exscan()
! Note: all these variables are private, but SUMB should *really* be
! a pointer. The semantics of COPYPRIVATE is that the POINTER is copied
! so effectively we are recovering a SHARED SUMB which is what
! we need in this case. If it was an ALLOCATABLE, then it would be the contents
! that would get copied, and the SHARED effect would no longer be there.
! Simple parallel version of EXSCAN
integer(psb_ipk_) :: i,ithread,nthreads,idxstart,idxend,wrk
integer(psb_i2pk_), pointer :: sumb(:)
integer(psb_i2pk_) :: tp, ts
nthreads = omp_get_num_threads()
ithread = omp_get_thread_num()
!$OMP SINGLE
allocate(sumb(nthreads+1))
sumb(:) = 0
!$OMP END SINGLE COPYPRIVATE(sumb)
wrk = (n)/nthreads
if (ithread < MOD((n),nthreads)) then
wrk = wrk + 1
idxstart = ithread*wrk + 1
else
idxstart = ithread*wrk + MOD((n),nthreads) + 1
end if
idxend = min(idxstart + wrk - 1,n )
tp = i2zero
if (idxstart<=idxend) then
do i=idxstart,idxend
ts = x(i)
x(i) = tp
tp = tp + ts
end do
end if
sumb(ithread+2) = tp
!$OMP BARRIER
!$OMP SINGLE
do i=2,nthreads+1
sumb(i) = sumb(i) + sumb(i-1)
end do
!$OMP END SINGLE
!$OMP BARRIER
!$OMP DO SCHEDULE(STATIC)
do i=1,n
x(i) = x(i) + sumb(ithread+1) + shift_
end do
!$OMP END DO
!$OMP SINGLE
deallocate(sumb)
!$OMP END SINGLE
end subroutine inner_i2_exscan
#endif
end subroutine psi_i2_exscanv
subroutine psb_m_i2gelp(trans,iperm,x,info)
use psb_serial_mod, psb_protect_name => psb_m_i2gelp
use psb_const_mod
@ -441,9 +542,9 @@ subroutine psi_i2axpby(m,n,alpha, x, beta, y, info)
integer(psb_i2pk_), intent (in) :: alpha, beta
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
integer(psb_ipk_) :: lx, ly
integer(psb_ipk_) :: lx, ly, i
integer(psb_ipk_) :: ierr(5)
character(len=20) :: name, ch_err
character(len=20) :: name, ch_err
name='psb_geaxpby'
info=psb_success_
@ -502,7 +603,8 @@ subroutine psi_i2axpbyv(m,alpha, x, beta, y, info)
integer(psb_ipk_) :: err_act
integer(psb_ipk_) :: lx, ly
integer(psb_ipk_) :: ierr(5)
character(len=20) :: name, ch_err
integer(psb_ipk_) :: i
character(len=20) :: name, ch_err
name='psb_geaxpby'
info=psb_success_
@ -532,7 +634,106 @@ subroutine psi_i2axpbyv(m,alpha, x, beta, y, info)
goto 9999
end if
if (m>0) call i2axpby(m,ione,alpha,x,lx,beta,y,ly,info)
! if (m>0) call i2axpby(m,ione,alpha,x,lx,beta,y,ly,info)
if (alpha.eq.i2zero) then
if (beta.eq.i2zero) then
!$omp parallel do private(i)
do i=1,m
y(i) = i2zero
enddo
else if (beta.eq.i2one) then
!
! Do nothing!
!
else if (beta.eq.-i2one) then
!$omp parallel do private(i)
do i=1,m
y(i) = - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = beta*y(i)
enddo
endif
else if (alpha.eq.i2one) then
if (beta.eq.i2zero) then
!$omp parallel do private(i)
do i=1,m
y(i) = x(i)
enddo
else if (beta.eq.i2one) then
!$omp parallel do private(i)
do i=1,m
y(i) = x(i) + y(i)
enddo
else if (beta.eq.-i2one) then
!$omp parallel do private(i)
do i=1,m
y(i) = x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = x(i) + beta*y(i)
enddo
endif
else if (alpha.eq.-i2one) then
if (beta.eq.i2zero) then
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i)
enddo
else if (beta.eq.i2one) then
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i) + y(i)
enddo
else if (beta.eq.-i2one) then
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i) + beta*y(i)
enddo
endif
else
if (beta.eq.i2zero) then
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i)
enddo
else if (beta.eq.i2one) then
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i) + y(i)
enddo
else if (beta.eq.-i2one) then
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i) + beta*y(i)
enddo
endif
endif
call psb_erractionrestore(err_act)
return
@ -555,7 +756,7 @@ subroutine psi_i2axpbyv2(m,alpha, x, beta, y, z, info)
integer(psb_i2pk_), intent (in) :: alpha, beta
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
integer(psb_ipk_) :: lx, ly, lz
integer(psb_ipk_) :: lx, ly, lz, i
integer(psb_ipk_) :: ierr(5)
character(len=20) :: name, ch_err
@ -594,7 +795,105 @@ subroutine psi_i2axpbyv2(m,alpha, x, beta, y, z, info)
goto 9999
end if
if (m>0) call i2axpbyv2(m,ione,alpha,x,lx,beta,y,ly,z,lz,info)
if (alpha.eq.i2zero) then
if (beta.eq.i2zero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = i2zero
enddo
else if (beta.eq.i2one) then
!
! Do nothing!
!
else if (beta.eq.-i2one) then
!$omp parallel do private(i)
do i=1,m
Z(i) = - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = beta*y(i)
enddo
endif
else if (alpha.eq.i2one) then
if (beta.eq.i2zero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i)
enddo
else if (beta.eq.i2one) then
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i) + y(i)
enddo
else if (beta.eq.-i2one) then
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i) + beta*y(i)
enddo
endif
else if (alpha.eq.-i2one) then
if (beta.eq.i2zero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i)
enddo
else if (beta.eq.i2one) then
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i) + y(i)
enddo
else if (beta.eq.-i2one) then
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i) + beta*y(i)
enddo
endif
else
if (beta.eq.i2zero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i)
enddo
else if (beta.eq.i2one) then
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i) + y(i)
enddo
else if (beta.eq.-i2one) then
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i) + beta*y(i)
enddo
endif
endif
call psb_erractionrestore(err_act)
return
@ -942,6 +1241,7 @@ subroutine i2axpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (alpha.eq.i2zero) then
if (beta.eq.i2zero) then
do j=1, n
!$omp parallel do private(i)
do i=1,m
y(i,j) = i2zero
enddo
@ -953,12 +1253,14 @@ subroutine i2axpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = beta*y(i,j)
enddo
@ -969,12 +1271,14 @@ subroutine i2axpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (beta.eq.i2zero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j)
enddo
enddo
else if (beta.eq.i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j) + y(i,j)
enddo
@ -982,12 +1286,14 @@ subroutine i2axpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j) + beta*y(i,j)
enddo
@ -998,12 +1304,14 @@ subroutine i2axpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (beta.eq.i2zero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j)
enddo
enddo
else if (beta.eq.i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j) + y(i,j)
enddo
@ -1011,12 +1319,14 @@ subroutine i2axpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j) + beta*y(i,j)
enddo
@ -1027,12 +1337,14 @@ subroutine i2axpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (beta.eq.i2zero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j)
enddo
enddo
else if (beta.eq.i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j) + y(i,j)
enddo
@ -1040,12 +1352,14 @@ subroutine i2axpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j) + beta*y(i,j)
enddo
@ -1131,12 +1445,14 @@ subroutine i2axpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = beta*y(i,j)
enddo
@ -1147,12 +1463,14 @@ subroutine i2axpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
if (beta.eq.i2zero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j)
enddo
enddo
else if (beta.eq.i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j) + y(i,j)
enddo
@ -1160,12 +1478,14 @@ subroutine i2axpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j) + beta*y(i,j)
enddo
@ -1176,12 +1496,14 @@ subroutine i2axpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
if (beta.eq.i2zero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j)
enddo
enddo
else if (beta.eq.i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j) + y(i,j)
enddo
@ -1189,12 +1511,14 @@ subroutine i2axpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j) + beta*y(i,j)
enddo
@ -1205,12 +1529,14 @@ subroutine i2axpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
if (beta.eq.i2zero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j)
enddo
enddo
else if (beta.eq.i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j) + y(i,j)
enddo
@ -1218,12 +1544,14 @@ subroutine i2axpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-i2one) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j) + beta*y(i,j)
enddo

@ -29,6 +29,107 @@
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine psi_m_exscanv(n,x,info,shift)
use psi_m_serial_mod, psb_protect_name => psi_m_exscanv
use psb_const_mod
use psb_error_mod
#if defined(OPENMP)
use omp_lib
#endif
implicit none
integer(psb_ipk_), intent(in) :: n
integer(psb_mpk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
integer(psb_mpk_), intent(in), optional :: shift
integer(psb_mpk_) :: shift_, tp, ts
integer(psb_ipk_) :: i
logical is_nested, is_parallel
if (present(shift)) then
shift_ = shift
else
shift_ = mzero
end if
#if defined(OPENMP)
is_parallel = omp_in_parallel()
if (is_parallel) then
call inner_m_exscan()
else
!$OMP PARALLEL default(shared)
call inner_m_exscan()
!$OMP END PARALLEL
end if
#else
tp = shift_
do i=1,n
ts = x(i)
x(i) = tp
tp = tp + ts
end do
#endif
#if defined(OPENMP)
contains
subroutine inner_m_exscan()
! Note: all these variables are private, but SUMB should *really* be
! a pointer. The semantics of COPYPRIVATE is that the POINTER is copied
! so effectively we are recovering a SHARED SUMB which is what
! we need in this case. If it was an ALLOCATABLE, then it would be the contents
! that would get copied, and the SHARED effect would no longer be there.
! Simple parallel version of EXSCAN
integer(psb_ipk_) :: i,ithread,nthreads,idxstart,idxend,wrk
integer(psb_mpk_), pointer :: sumb(:)
integer(psb_mpk_) :: tp, ts
nthreads = omp_get_num_threads()
ithread = omp_get_thread_num()
!$OMP SINGLE
allocate(sumb(nthreads+1))
sumb(:) = 0
!$OMP END SINGLE COPYPRIVATE(sumb)
wrk = (n)/nthreads
if (ithread < MOD((n),nthreads)) then
wrk = wrk + 1
idxstart = ithread*wrk + 1
else
idxstart = ithread*wrk + MOD((n),nthreads) + 1
end if
idxend = min(idxstart + wrk - 1,n )
tp = mzero
if (idxstart<=idxend) then
do i=idxstart,idxend
ts = x(i)
x(i) = tp
tp = tp + ts
end do
end if
sumb(ithread+2) = tp
!$OMP BARRIER
!$OMP SINGLE
do i=2,nthreads+1
sumb(i) = sumb(i) + sumb(i-1)
end do
!$OMP END SINGLE
!$OMP BARRIER
!$OMP DO SCHEDULE(STATIC)
do i=1,n
x(i) = x(i) + sumb(ithread+1) + shift_
end do
!$OMP END DO
!$OMP SINGLE
deallocate(sumb)
!$OMP END SINGLE
end subroutine inner_m_exscan
#endif
end subroutine psi_m_exscanv
subroutine psb_m_mgelp(trans,iperm,x,info)
use psb_serial_mod, psb_protect_name => psb_m_mgelp
use psb_const_mod
@ -441,9 +542,9 @@ subroutine psi_maxpby(m,n,alpha, x, beta, y, info)
integer(psb_mpk_), intent (in) :: alpha, beta
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
integer(psb_ipk_) :: lx, ly
integer(psb_ipk_) :: lx, ly, i
integer(psb_ipk_) :: ierr(5)
character(len=20) :: name, ch_err
character(len=20) :: name, ch_err
name='psb_geaxpby'
info=psb_success_
@ -502,7 +603,8 @@ subroutine psi_maxpbyv(m,alpha, x, beta, y, info)
integer(psb_ipk_) :: err_act
integer(psb_ipk_) :: lx, ly
integer(psb_ipk_) :: ierr(5)
character(len=20) :: name, ch_err
integer(psb_ipk_) :: i
character(len=20) :: name, ch_err
name='psb_geaxpby'
info=psb_success_
@ -532,7 +634,106 @@ subroutine psi_maxpbyv(m,alpha, x, beta, y, info)
goto 9999
end if
if (m>0) call maxpby(m,ione,alpha,x,lx,beta,y,ly,info)
! if (m>0) call maxpby(m,ione,alpha,x,lx,beta,y,ly,info)
if (alpha.eq.mzero) then
if (beta.eq.mzero) then
!$omp parallel do private(i)
do i=1,m
y(i) = mzero
enddo
else if (beta.eq.mone) then
!
! Do nothing!
!
else if (beta.eq.-mone) then
!$omp parallel do private(i)
do i=1,m
y(i) = - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = beta*y(i)
enddo
endif
else if (alpha.eq.mone) then
if (beta.eq.mzero) then
!$omp parallel do private(i)
do i=1,m
y(i) = x(i)
enddo
else if (beta.eq.mone) then
!$omp parallel do private(i)
do i=1,m
y(i) = x(i) + y(i)
enddo
else if (beta.eq.-mone) then
!$omp parallel do private(i)
do i=1,m
y(i) = x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = x(i) + beta*y(i)
enddo
endif
else if (alpha.eq.-mone) then
if (beta.eq.mzero) then
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i)
enddo
else if (beta.eq.mone) then
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i) + y(i)
enddo
else if (beta.eq.-mone) then
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = -x(i) + beta*y(i)
enddo
endif
else
if (beta.eq.mzero) then
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i)
enddo
else if (beta.eq.mone) then
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i) + y(i)
enddo
else if (beta.eq.-mone) then
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
y(i) = alpha*x(i) + beta*y(i)
enddo
endif
endif
call psb_erractionrestore(err_act)
return
@ -555,7 +756,7 @@ subroutine psi_maxpbyv2(m,alpha, x, beta, y, z, info)
integer(psb_mpk_), intent (in) :: alpha, beta
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
integer(psb_ipk_) :: lx, ly, lz
integer(psb_ipk_) :: lx, ly, lz, i
integer(psb_ipk_) :: ierr(5)
character(len=20) :: name, ch_err
@ -594,7 +795,105 @@ subroutine psi_maxpbyv2(m,alpha, x, beta, y, z, info)
goto 9999
end if
if (m>0) call maxpbyv2(m,ione,alpha,x,lx,beta,y,ly,z,lz,info)
if (alpha.eq.mzero) then
if (beta.eq.mzero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = mzero
enddo
else if (beta.eq.mone) then
!
! Do nothing!
!
else if (beta.eq.-mone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = beta*y(i)
enddo
endif
else if (alpha.eq.mone) then
if (beta.eq.mzero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i)
enddo
else if (beta.eq.mone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i) + y(i)
enddo
else if (beta.eq.-mone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = x(i) + beta*y(i)
enddo
endif
else if (alpha.eq.-mone) then
if (beta.eq.mzero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i)
enddo
else if (beta.eq.mone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i) + y(i)
enddo
else if (beta.eq.-mone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = -x(i) + beta*y(i)
enddo
endif
else
if (beta.eq.mzero) then
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i)
enddo
else if (beta.eq.mone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i) + y(i)
enddo
else if (beta.eq.-mone) then
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i) - y(i)
enddo
else
!$omp parallel do private(i)
do i=1,m
Z(i) = alpha*x(i) + beta*y(i)
enddo
endif
endif
call psb_erractionrestore(err_act)
return
@ -942,6 +1241,7 @@ subroutine maxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (alpha.eq.mzero) then
if (beta.eq.mzero) then
do j=1, n
!$omp parallel do private(i)
do i=1,m
y(i,j) = mzero
enddo
@ -953,12 +1253,14 @@ subroutine maxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = beta*y(i,j)
enddo
@ -969,12 +1271,14 @@ subroutine maxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (beta.eq.mzero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j)
enddo
enddo
else if (beta.eq.mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j) + y(i,j)
enddo
@ -982,12 +1286,14 @@ subroutine maxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = x(i,j) + beta*y(i,j)
enddo
@ -998,12 +1304,14 @@ subroutine maxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (beta.eq.mzero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j)
enddo
enddo
else if (beta.eq.mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j) + y(i,j)
enddo
@ -1011,12 +1319,14 @@ subroutine maxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = -x(i,j) + beta*y(i,j)
enddo
@ -1027,12 +1337,14 @@ subroutine maxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
if (beta.eq.mzero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j)
enddo
enddo
else if (beta.eq.mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j) + y(i,j)
enddo
@ -1040,12 +1352,14 @@ subroutine maxpby(m, n, alpha, X, lldx, beta, Y, lldy, info)
else if (beta.eq.-mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
y(i,j) = alpha*x(i,j) + beta*y(i,j)
enddo
@ -1131,12 +1445,14 @@ subroutine maxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = beta*y(i,j)
enddo
@ -1147,12 +1463,14 @@ subroutine maxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
if (beta.eq.mzero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j)
enddo
enddo
else if (beta.eq.mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j) + y(i,j)
enddo
@ -1160,12 +1478,14 @@ subroutine maxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = x(i,j) + beta*y(i,j)
enddo
@ -1176,12 +1496,14 @@ subroutine maxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
if (beta.eq.mzero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j)
enddo
enddo
else if (beta.eq.mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j) + y(i,j)
enddo
@ -1189,12 +1511,14 @@ subroutine maxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = -x(i,j) + beta*y(i,j)
enddo
@ -1205,12 +1529,14 @@ subroutine maxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
if (beta.eq.mzero) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j)
enddo
enddo
else if (beta.eq.mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j) + y(i,j)
enddo
@ -1218,12 +1544,14 @@ subroutine maxpbyv2(m, n, alpha, X, lldx, beta, Y, lldy, Z, lldz, info)
else if (beta.eq.-mone) then
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j) - y(i,j)
enddo
enddo
else
do j=1,n
!$omp parallel do private(i)
do i=1,m
Z(i,j) = alpha*x(i,j) + beta*y(i,j)
enddo

@ -29,6 +29,107 @@
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine psi_s_exscanv(n,x,info,shift)
use psi_s_serial_mod, psb_protect_name => psi_s_exscanv
use psb_const_mod
use psb_error_mod
#if defined(OPENMP)
use omp_lib
#endif
implicit none
integer(psb_ipk_), intent(in) :: n
real(psb_spk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
real(psb_spk_), intent(in), optional :: shift
real(psb_spk_) :: shift_, tp, ts
integer(psb_ipk_) :: i
logical is_nested, is_parallel
if (present(shift)) then
shift_ = shift
else
shift_ = szero
end if
#if defined(OPENMP)
is_parallel = omp_in_parallel()
if (is_parallel) then
call inner_s_exscan()
else
!$OMP PARALLEL default(shared)
call inner_s_exscan()
!$OMP END PARALLEL
end if
#else
tp = shift_
do i=1,n
ts = x(i)
x(i) = tp
tp = tp + ts
end do
#endif
#if defined(OPENMP)
contains
subroutine inner_s_exscan()
! Note: all these variables are private, but SUMB should *really* be
! a pointer. The semantics of COPYPRIVATE is that the POINTER is copied
! so effectively we are recovering a SHARED SUMB which is what
! we need in this case. If it was an ALLOCATABLE, then it would be the contents
! that would get copied, and the SHARED effect would no longer be there.
! Simple parallel version of EXSCAN
integer(psb_ipk_) :: i,ithread,nthreads,idxstart,idxend,wrk
real(psb_spk_), pointer :: sumb(:)
real(psb_spk_) :: tp, ts
nthreads = omp_get_num_threads()
ithread = omp_get_thread_num()
!$OMP SINGLE
allocate(sumb(nthreads+1))
sumb(:) = 0
!$OMP END SINGLE COPYPRIVATE(sumb)
wrk = (n)/nthreads
if (ithread < MOD((n),nthreads)) then
wrk = wrk + 1
idxstart = ithread*wrk + 1
else
idxstart = ithread*wrk + MOD((n),nthreads) + 1
end if
idxend = min(idxstart + wrk - 1,n )
tp = szero
if (idxstart<=idxend) then
do i=idxstart,idxend
ts = x(i)
x(i) = tp
tp = tp + ts
end do
end if
sumb(ithread+2) = tp
!$OMP BARRIER
!$OMP SINGLE
do i=2,nthreads+1
sumb(i) = sumb(i) + sumb(i-1)
end do
!$OMP END SINGLE
!$OMP BARRIER
!$OMP DO SCHEDULE(STATIC)
do i=1,n
x(i) = x(i) + sumb(ithread+1) + shift_
end do
!$OMP END DO
!$OMP SINGLE
deallocate(sumb)
!$OMP END SINGLE
end subroutine inner_s_exscan
#endif
end subroutine psi_s_exscanv
subroutine psb_m_sgelp(trans,iperm,x,info)
use psb_serial_mod, psb_protect_name => psb_m_sgelp
use psb_const_mod

@ -29,6 +29,107 @@
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine psi_z_exscanv(n,x,info,shift)
use psi_z_serial_mod, psb_protect_name => psi_z_exscanv
use psb_const_mod
use psb_error_mod
#if defined(OPENMP)
use omp_lib
#endif
implicit none
integer(psb_ipk_), intent(in) :: n
complex(psb_dpk_), intent (inout) :: x(:)
integer(psb_ipk_), intent(out) :: info
complex(psb_dpk_), intent(in), optional :: shift
complex(psb_dpk_) :: shift_, tp, ts
integer(psb_ipk_) :: i
logical is_nested, is_parallel
if (present(shift)) then
shift_ = shift
else
shift_ = zzero
end if
#if defined(OPENMP)
is_parallel = omp_in_parallel()
if (is_parallel) then
call inner_z_exscan()
else
!$OMP PARALLEL default(shared)
call inner_z_exscan()
!$OMP END PARALLEL
end if
#else
tp = shift_
do i=1,n
ts = x(i)
x(i) = tp
tp = tp + ts
end do
#endif
#if defined(OPENMP)
contains
subroutine inner_z_exscan()
! Note: all these variables are private, but SUMB should *really* be
! a pointer. The semantics of COPYPRIVATE is that the POINTER is copied
! so effectively we are recovering a SHARED SUMB which is what
! we need in this case. If it was an ALLOCATABLE, then it would be the contents
! that would get copied, and the SHARED effect would no longer be there.
! Simple parallel version of EXSCAN
integer(psb_ipk_) :: i,ithread,nthreads,idxstart,idxend,wrk
complex(psb_dpk_), pointer :: sumb(:)
complex(psb_dpk_) :: tp, ts
nthreads = omp_get_num_threads()
ithread = omp_get_thread_num()
!$OMP SINGLE
allocate(sumb(nthreads+1))
sumb(:) = 0
!$OMP END SINGLE COPYPRIVATE(sumb)
wrk = (n)/nthreads
if (ithread < MOD((n),nthreads)) then
wrk = wrk + 1
idxstart = ithread*wrk + 1
else
idxstart = ithread*wrk + MOD((n),nthreads) + 1
end if
idxend = min(idxstart + wrk - 1,n )
tp = zzero
if (idxstart<=idxend) then
do i=idxstart,idxend
ts = x(i)
x(i) = tp
tp = tp + ts
end do
end if
sumb(ithread+2) = tp
!$OMP BARRIER
!$OMP SINGLE
do i=2,nthreads+1
sumb(i) = sumb(i) + sumb(i-1)
end do
!$OMP END SINGLE
!$OMP BARRIER
!$OMP DO SCHEDULE(STATIC)
do i=1,n
x(i) = x(i) + sumb(ithread+1) + shift_
end do
!$OMP END DO
!$OMP SINGLE
deallocate(sumb)
!$OMP END SINGLE
end subroutine inner_z_exscan
#endif
end subroutine psi_z_exscanv
subroutine psb_m_zgelp(trans,iperm,x,info)
use psb_serial_mod, psb_protect_name => psb_m_zgelp
use psb_const_mod

@ -3,7 +3,6 @@ include ../../../Make.inc
#
# The object files
#
BOBJS=psi_lcx_mod.o psi_alcx_mod.o psi_acx_mod.o
IOBJS=psb_m_hsort_impl.o psb_m_isort_impl.o psb_m_msort_impl.o psb_m_qsort_impl.o
LOBJS=psb_e_hsort_impl.o psb_e_isort_impl.o psb_e_msort_impl.o psb_e_qsort_impl.o
SOBJS=psb_s_hsort_impl.o psb_s_isort_impl.o psb_s_msort_impl.o psb_s_qsort_impl.o
@ -11,7 +10,7 @@ DOBJS=psb_d_hsort_impl.o psb_d_isort_impl.o psb_d_msort_impl.o psb_d_qsort_impl.
COBJS=psb_c_hsort_impl.o psb_c_isort_impl.o psb_c_msort_impl.o psb_c_qsort_impl.o
ZOBJS=psb_z_hsort_impl.o psb_z_isort_impl.o psb_z_msort_impl.o psb_z_qsort_impl.o
OBJS=$(BOBJS) $(SOBJS) $(DOBJS) $(COBJS) $(ZOBJS) $(IOBJS) $(LOBJS)
OBJS=$(SOBJS) $(DOBJS) $(COBJS) $(ZOBJS) $(IOBJS) $(LOBJS)
#
# Where the library should go, and how it is called.
@ -35,7 +34,6 @@ lib: objs
# A bit excessive, but safe
$(OBJS): $(MODDIR)/psb_base_mod.o
$(IOBJS) $(LOBJS) $(SOBJS) $(DOBJS) $(COBJS) $(ZOBJS): $(BOBJS)
clean: cleanobjs
veryclean: cleanobjs

@ -40,6 +40,7 @@
! Data Structures and Algorithms
! Addison-Wesley
!
subroutine psb_cqsort(x,ix,dir,flag)
use psb_sort_mod, psb_protect_name => psb_cqsort
use psb_error_mod

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save