diff --git a/base/internals/psi_graph_fnd_owner.F90 b/base/internals/psi_graph_fnd_owner.F90
index 966af403..e5eed8c6 100644
--- a/base/internals/psi_graph_fnd_owner.F90
+++ b/base/internals/psi_graph_fnd_owner.F90
@@ -41,6 +41,8 @@
!
! iprc(:) - integer(psb_ipk_), allocatable Output: process identifiers
! for the corresponding indices
+! ladj(:) - integer(psb_ipk_), allocatable Output: A list of adjacent processes
+!
! idxmap - class(psb_indx_map). The index map
! info - integer. return code.
!
@@ -76,7 +78,7 @@
! thereby limiting the memory footprint to a predefined maximum
! (that the user can force with psb_cd_set_maxspace()).
!
-subroutine psi_graph_fnd_owner(idx,iprc,idxmap,info)
+subroutine psi_graph_fnd_owner(idx,iprc,ladj,idxmap,info)
use psb_serial_mod
use psb_const_mod
use psb_error_mod
@@ -93,13 +95,13 @@ subroutine psi_graph_fnd_owner(idx,iprc,idxmap,info)
include 'mpif.h'
#endif
integer(psb_lpk_), intent(in) :: idx(:)
- integer(psb_ipk_), allocatable, intent(out) :: iprc(:)
- class(psb_indx_map), intent(inout) :: idxmap
- integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), allocatable, intent(out) :: iprc(:), ladj(:)
+ class(psb_indx_map), intent(in) :: idxmap
+ integer(psb_ipk_), intent(out) :: info
integer(psb_lpk_), allocatable :: tidx(:)
- integer(psb_ipk_), allocatable :: tprc(:), tsmpl(:), ladj(:)
+ integer(psb_ipk_), allocatable :: tprc(:), tsmpl(:)
integer(psb_mpk_) :: icomm, minfo
integer(psb_ipk_) :: i,n_row,n_col,err_act,ip,j, nsampl_out,&
& nv, n_answers, nqries, nsampl_in, locr_max, ist, iend,&
@@ -208,7 +210,7 @@ subroutine psi_graph_fnd_owner(idx,iprc,idxmap,info)
if (trace.and.(me == 0)) write(0,*) ' Initial sweep on user-defined topology',&
& nsampl_in
call psi_adj_fnd_sweep(idx,iprc,ladj,idxmap,nsampl_in,n_answers)
- call idxmap%xtnd_p_adjcncy(ladj)
+
nqries = nv - n_answers
nqries_max = nqries
call psb_max(ctxt,nqries_max)
@@ -253,13 +255,12 @@ subroutine psi_graph_fnd_owner(idx,iprc,idxmap,info)
n_answers = n_answers + nlansw
nqries = nv - n_answers
!
- ! 3. Extract the resulting adjacency list and add it to the
- ! indxmap;
+ ! 3. Extract the resulting adjacency list ? AND ADD IT TO THE EXISTING ONE ?
!
ladj = tprc(1:nlansw)
call psb_msort_unique(ladj,nadj)
call psb_realloc(nadj,ladj,info)
- call idxmap%xtnd_p_adjcncy(ladj)
+ ! call idxmap%xtnd_p_adjcncy(ladj)
if (do_timings) call psb_toc(idx_loop_a2a)
if (do_timings) call psb_tic(idx_loop_neigh)
!
@@ -368,7 +369,7 @@ contains
integer(psb_ipk_), intent(in) :: n_samples
integer(psb_ipk_), intent(inout) :: iprc(:), n_answers
integer(psb_ipk_), intent(in) :: adj(:)
- class(psb_indx_map), intent(inout) :: idxmap
+ class(psb_indx_map), intent(in) :: idxmap
!
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: ipnt, ns_in, ns_out, n_rem, me, np, isw, n_reml,iend, nv
diff --git a/base/internals/psi_indx_map_fnd_owner.F90 b/base/internals/psi_indx_map_fnd_owner.F90
index 0ecade3d..157b73a1 100644
--- a/base/internals/psi_indx_map_fnd_owner.F90
+++ b/base/internals/psi_indx_map_fnd_owner.F90
@@ -51,7 +51,7 @@
! 2. Check if TEMPVG(:) is allocated, and use it; or
! 3. Call the general method PSI_GRAPH_FND_OWNER.
!
-subroutine psi_indx_map_fnd_owner(idx,iprc,idxmap,info)
+subroutine psi_indx_map_fnd_owner(idx,iprc,idxmap,info,adj)
use psb_serial_mod
use psb_const_mod
use psb_error_mod
@@ -66,15 +66,15 @@ subroutine psi_indx_map_fnd_owner(idx,iprc,idxmap,info)
#ifdef MPI_H
include 'mpif.h'
#endif
- integer(psb_lpk_), intent(in) :: idx(:)
+ integer(psb_lpk_), intent(in) :: idx(:)
integer(psb_ipk_), allocatable, intent(out) :: iprc(:)
- class(psb_indx_map), intent(inout) :: idxmap
+ class(psb_indx_map), intent(in) :: idxmap
integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, allocatable, intent(out) :: adj(:)
-
- integer(psb_ipk_), allocatable :: hhidx(:)
+ integer(psb_ipk_), allocatable :: hhidx(:), ladj(:)
integer(psb_mpk_) :: icomm, minfo
- integer(psb_ipk_) :: i, err_act, hsize
+ integer(psb_ipk_) :: i, err_act, hsize, nadj
integer(psb_lpk_) :: nv
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
@@ -131,7 +131,6 @@ subroutine psi_indx_map_fnd_owner(idx,iprc,idxmap,info)
iprc(i) = -1
end if
end do
-
else if (allocated(idxmap%tempvg)) then
!!$ write(0,*) me,trim(name),' indxmap%tempvg shortcut'
! Use temporary vector
@@ -183,7 +182,7 @@ subroutine psi_indx_map_fnd_owner(idx,iprc,idxmap,info)
tidx(k2) = idx(k1)
end if
end do
- call psi_graph_fnd_owner(tidx,tprc,idxmap,info)
+ call psi_graph_fnd_owner(tidx,tprc,ladj,idxmap,info)
k2 = 0
do k1 = 1, nv
if (iprc(k1) < 0) then
@@ -198,12 +197,15 @@ subroutine psi_indx_map_fnd_owner(idx,iprc,idxmap,info)
end do
end block
else
- call psi_graph_fnd_owner(idx,iprc,idxmap,info)
+ call psi_graph_fnd_owner(idx,iprc,ladj,idxmap,info)
end if
-
-
+
+ end if
+ if (present(adj)) then
+ adj = iprc
+ call psb_msort_unique(adj,nadj)
+ call psb_realloc(nadj,adj,info)
end if
-
if (gettime) then
call psb_barrier(ctxt)
t1 = psb_wtime()
diff --git a/base/modules/desc/psb_gen_block_map_mod.F90 b/base/modules/desc/psb_gen_block_map_mod.F90
index 8daa038f..dfb47b61 100644
--- a/base/modules/desc/psb_gen_block_map_mod.F90
+++ b/base/modules/desc/psb_gen_block_map_mod.F90
@@ -1050,15 +1050,18 @@ contains
end subroutine block_lg2lv2_ins
- subroutine block_fnd_owner(idx,iprc,idxmap,info)
+ subroutine block_fnd_owner(idx,iprc,idxmap,info,adj)
use psb_penv_mod
+ use psb_realloc_mod
+ use psb_sort_mod
implicit none
integer(psb_lpk_), intent(in) :: idx(:)
integer(psb_ipk_), allocatable, intent(out) :: iprc(:)
- class(psb_gen_block_map), intent(inout) :: idxmap
- integer(psb_ipk_), intent(out) :: info
+ class(psb_gen_block_map), intent(in) :: idxmap
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, allocatable, intent(out) :: adj(:)
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: iam, np, nv, ip, i
+ integer(psb_ipk_) :: iam, np, nv, ip, i, nadj
integer(psb_lpk_) :: tidx
ctxt = idxmap%get_ctxt()
@@ -1073,7 +1076,11 @@ contains
ip = gen_block_search(tidx-1,np+1,idxmap%vnl)
iprc(i) = ip - 1
end do
-
+ if (present(adj)) then
+ adj = iprc
+ call psb_msort_unique(adj,nadj)
+ call psb_realloc(nadj,adj,info)
+ end if
end subroutine block_fnd_owner
diff --git a/base/modules/desc/psb_glist_map_mod.f90 b/base/modules/desc/psb_glist_map_mod.f90
index c8ac8f99..4ddcdaca 100644
--- a/base/modules/desc/psb_glist_map_mod.f90
+++ b/base/modules/desc/psb_glist_map_mod.f90
@@ -150,16 +150,20 @@ contains
end subroutine glist_initvg
- subroutine glist_fnd_owner(idx,iprc,idxmap,info)
+ subroutine glist_fnd_owner(idx,iprc,idxmap,info,adj)
use psb_penv_mod
use psb_sort_mod
+ use psb_realloc_mod
implicit none
integer(psb_lpk_), intent(in) :: idx(:)
integer(psb_ipk_), allocatable, intent(out) :: iprc(:)
- class(psb_glist_map), intent(inout) :: idxmap
+ class(psb_glist_map), intent(in) :: idxmap
integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, allocatable, intent(out) :: adj(:)
+
type(psb_ctxt_type) :: ctxt
integer(psb_mpk_) :: iam, np
+ integer(psb_ipk_) :: nadj
integer(psb_lpk_) :: nv, i, ngp
ctxt = idxmap%get_ctxt()
@@ -180,6 +184,12 @@ contains
end if
end do
+ if (present(adj)) then
+ adj = iprc
+ call psb_msort_unique(adj,nadj)
+ call psb_realloc(nadj,adj,info)
+ end if
+
end subroutine glist_fnd_owner
function glist_get_fmt() result(res)
diff --git a/base/modules/desc/psb_indx_map_mod.f90 b/base/modules/desc/psb_indx_map_mod.f90
index 79526d59..7753db23 100644
--- a/base/modules/desc/psb_indx_map_mod.f90
+++ b/base/modules/desc/psb_indx_map_mod.f90
@@ -268,13 +268,14 @@ module psb_indx_map_mod
!!
interface
- subroutine psi_indx_map_fnd_owner(idx,iprc,idxmap,info)
+ subroutine psi_indx_map_fnd_owner(idx,iprc,idxmap,info,adj)
import :: psb_indx_map, psb_ipk_, psb_lpk_
implicit none
integer(psb_lpk_), intent(in) :: idx(:)
integer(psb_ipk_), allocatable, intent(out) :: iprc(:)
- class(psb_indx_map), intent(inout) :: idxmap
- integer(psb_ipk_), intent(out) :: info
+ class(psb_indx_map), intent(in) :: idxmap
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, allocatable, intent(out) :: adj(:)
end subroutine psi_indx_map_fnd_owner
end interface
@@ -303,13 +304,14 @@ module psb_indx_map_mod
end interface
interface
- subroutine psi_graph_fnd_owner(idx,iprc,idxmap,info)
+ subroutine psi_graph_fnd_owner(idx,iprc,ladj,idxmap,info)
import :: psb_indx_map, psb_ipk_, psb_lpk_
implicit none
integer(psb_lpk_), intent(in) :: idx(:)
integer(psb_ipk_), allocatable, intent(out) :: iprc(:)
- class(psb_indx_map), intent(inout) :: idxmap
- integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), allocatable, intent(out) :: ladj(:)
+ class(psb_indx_map), intent(in) :: idxmap
+ integer(psb_ipk_), intent(out) :: info
end subroutine psi_graph_fnd_owner
end interface
@@ -1519,7 +1521,7 @@ contains
use psb_error_mod
use psb_realloc_mod
implicit none
- class(psb_indx_map), intent(inout) :: idxmap
+ class(psb_indx_map), intent(in) :: idxmap
integer(psb_ipk_), intent(in) :: xin
integer(psb_ipk_), intent(out) :: xout
integer(psb_ipk_), intent(out) :: info
@@ -1548,7 +1550,7 @@ contains
use psb_error_mod
use psb_realloc_mod
implicit none
- class(psb_indx_map), intent(inout) :: idxmap
+ class(psb_indx_map), intent(in) :: idxmap
integer(psb_ipk_), intent(in) :: xin(:)
integer(psb_ipk_), intent(out) :: xout(:)
integer(psb_ipk_), intent(out) :: info
@@ -1557,6 +1559,11 @@ contains
nr = idxmap%local_rows
nc = min(idxmap%local_cols, (nr+psb_size(idxmap%halo_owner)))
sz = min(size(xin),size(xout))
+ if (.not.allocated(idxmap%halo_owner)) then
+ xout = -1
+ return
+ end if
+
do i = 1, sz
xout(i) = -1
if ((nr psb_c_is_repeatable_updates
procedure, pass(a) :: get_fmt => psb_c_get_fmt
procedure, pass(a) :: sizeof => psb_c_sizeof
+ procedure, pass(a) :: is_remote_build => psb_c_is_remote_build
+
! Setters
procedure, pass(a) :: set_nrows => psb_c_set_nrows
@@ -125,6 +129,7 @@ module psb_c_mat_mod
procedure, pass(a) :: set_symmetric => psb_c_set_symmetric
procedure, pass(a) :: set_unit => psb_c_set_unit
procedure, pass(a) :: set_repeatable_updates => psb_c_set_repeatable_updates
+ procedure, pass(a) :: set_remote_build => psb_c_set_remote_build
! Memory/data management
procedure, pass(a) :: csall => psb_c_csall
@@ -2292,7 +2297,25 @@ contains
end function c_mat_is_sync
+ function psb_c_is_remote_build(a) result(res)
+ implicit none
+ class(psb_cspmat_type), intent(in) :: a
+ logical :: res
+ res = (a%remote_build == psb_matbld_remote_)
+ end function psb_c_is_remote_build
+ subroutine psb_c_set_remote_build(a,val)
+ implicit none
+ class(psb_cspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ a%remote_build = val
+ else
+ a%remote_build = psb_matbld_remote_
+ end if
+ end subroutine psb_c_set_remote_build
+
function psb_c_is_repeatable_updates(a) result(res)
implicit none
class(psb_cspmat_type), intent(in) :: a
diff --git a/base/modules/serial/psb_c_vect_mod.F90 b/base/modules/serial/psb_c_vect_mod.F90
index ee6eef28..1a336d11 100644
--- a/base/modules/serial/psb_c_vect_mod.F90
+++ b/base/modules/serial/psb_c_vect_mod.F90
@@ -39,15 +39,27 @@
!
module psb_c_vect_mod
+ use psb_realloc_mod
use psb_c_base_vect_mod
use psb_i_vect_mod
type psb_c_vect_type
class(psb_c_base_vect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ complex(psb_spk_), allocatable :: rmtv(:)
+ integer(psb_lpk_), allocatable :: rmidx(:)
contains
procedure, pass(x) :: get_nrows => c_vect_get_nrows
procedure, pass(x) :: sizeof => c_vect_sizeof
procedure, pass(x) :: get_fmt => c_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => c_vect_is_remote_build
+ procedure, pass(x) :: set_remote_build => c_vect_set_remote_build
+ procedure, pass(x) :: get_dupl => c_vect_get_dupl
+ procedure, pass(x) :: set_dupl => c_vect_set_dupl
+ procedure, pass(x) :: get_nrmv => c_vect_get_nrmv
+ procedure, pass(x) :: set_nrmv => c_vect_set_nrmv
procedure, pass(x) :: all => c_vect_all
procedure, pass(x) :: reall => c_vect_reall
procedure, pass(x) :: zero => c_vect_zero
@@ -145,7 +157,9 @@ module psb_c_vect_mod
& c_vect_cnv, c_vect_set_scal, &
& c_vect_set_vect, c_vect_clone, c_vect_sync, c_vect_is_host, &
& c_vect_is_dev, c_vect_is_sync, c_vect_set_host, &
- & c_vect_set_dev, c_vect_set_sync
+ & c_vect_set_dev, c_vect_set_sync, &
+ & c_vect_set_remote_build, c_is_remote_build, &
+ & c_vect_set_dupl, c_get_dupl, c_vect_set_nrmv, c_get_nrmv
private :: c_vect_dot_v, c_vect_dot_a, c_vect_axpby_v, c_vect_axpby_a, &
& c_vect_mlt_v, c_vect_mlt_a, c_vect_mlt_a_2, c_vect_mlt_v_2, &
@@ -167,7 +181,60 @@ module psb_c_vect_mod
contains
+ function c_vect_get_dupl(x) result(res)
+ implicit none
+ class(psb_c_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function c_vect_get_dupl
+
+ subroutine c_vect_set_dupl(x,val)
+ implicit none
+ class(psb_c_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine c_vect_set_dupl
+
+ function c_vect_get_nrmv(x) result(res)
+ implicit none
+ class(psb_c_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%nrmv
+ end function c_vect_get_nrmv
+
+ subroutine c_vect_set_nrmv(x,val)
+ implicit none
+ class(psb_c_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in) :: val
+
+ x%nrmv = val
+ end subroutine c_vect_set_nrmv
+
+
+ function c_vect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_c_vect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function c_vect_is_remote_build
+ subroutine c_vect_set_remote_build(x,val)
+ implicit none
+ class(psb_c_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine c_vect_set_remote_build
+
subroutine psb_c_set_vect_default(v)
implicit none
class(psb_c_base_vect_type), intent(in) :: v
@@ -365,8 +432,8 @@ contains
implicit none
integer(psb_ipk_), intent(in) :: n
class(psb_c_vect_type), intent(inout) :: x
- class(psb_c_base_vect_type), intent(in), optional :: mold
integer(psb_ipk_), intent(out) :: info
+ class(psb_c_base_vect_type), intent(in), optional :: mold
if (allocated(x%v)) &
& call x%free(info)
@@ -381,7 +448,6 @@ contains
else
info = psb_err_alloc_dealloc_
end if
-
end subroutine c_vect_all
subroutine c_vect_reall(n, x, info)
@@ -412,13 +478,13 @@ contains
use psi_serial_mod
use psb_realloc_mod
implicit none
- integer(psb_ipk_), intent(in) :: n
+ integer(psb_ipk_), intent(in) :: n
class(psb_c_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(out) :: info
-
- if (allocated(x%v)) &
- & call x%v%asb(n,info)
+ integer(psb_ipk_), intent(out) :: info
+ if (allocated(x%v)) then
+ call x%v%asb(n,info)
+ end if
end subroutine c_vect_asb
subroutine c_vect_gthab(n,idx,alpha,x,beta,y)
@@ -469,44 +535,44 @@ contains
end subroutine c_vect_free
- subroutine c_vect_ins_a(n,irl,val,dupl,x,info)
+ subroutine c_vect_ins_a(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_c_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
complex(psb_spk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine c_vect_ins_a
- subroutine c_vect_ins_v(n,irl,val,dupl,x,info)
+ subroutine c_vect_ins_v(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_c_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
class(psb_i_vect_type), intent(inout) :: irl
class(psb_c_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl%v,val%v,dupl,info)
end subroutine c_vect_ins_v
@@ -1184,7 +1250,6 @@ contains
end module psb_c_vect_mod
-
module psb_c_multivect_mod
use psb_c_base_multivect_mod
@@ -1196,11 +1261,19 @@ module psb_c_multivect_mod
type psb_c_multivect_type
class(psb_c_base_multivect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ complex(psb_spk_), allocatable :: rmtv(:,:)
contains
procedure, pass(x) :: get_nrows => c_vect_get_nrows
procedure, pass(x) :: get_ncols => c_vect_get_ncols
procedure, pass(x) :: sizeof => c_vect_sizeof
procedure, pass(x) :: get_fmt => c_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => c_mvect_is_remote_build
+ procedure, pass(x) :: set_remote_build => c_mvect_set_remote_build
+ procedure, pass(x) :: get_dupl => c_mvect_get_dupl
+ procedure, pass(x) :: set_dupl => c_mvect_set_dupl
procedure, pass(x) :: all => c_vect_all
procedure, pass(x) :: reall => c_vect_reall
@@ -1268,6 +1341,46 @@ module psb_c_multivect_mod
contains
+
+ function c_mvect_get_dupl(x) result(res)
+ implicit none
+ class(psb_c_multivect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function c_mvect_get_dupl
+
+ subroutine c_mvect_set_dupl(x,val)
+ implicit none
+ class(psb_c_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine c_mvect_set_dupl
+
+
+ function c_mvect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_c_multivect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function c_mvect_is_remote_build
+
+ subroutine c_mvect_set_remote_build(x,val)
+ implicit none
+ class(psb_c_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine c_mvect_set_remote_build
+
subroutine psb_c_set_multivect_default(v)
implicit none
@@ -1572,23 +1685,23 @@ contains
end subroutine c_vect_free
- subroutine c_vect_ins(n,irl,val,dupl,x,info)
+ subroutine c_vect_ins(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_c_multivect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
complex(psb_spk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine c_vect_ins
diff --git a/base/modules/serial/psb_d_mat_mod.F90 b/base/modules/serial/psb_d_mat_mod.F90
index ff51d1cb..8f967ce1 100644
--- a/base/modules/serial/psb_d_mat_mod.F90
+++ b/base/modules/serial/psb_d_mat_mod.F90
@@ -84,7 +84,9 @@ module psb_d_mat_mod
type :: psb_dspmat_type
- class(psb_d_base_sparse_mat), allocatable :: a
+ class(psb_d_base_sparse_mat), allocatable :: a
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ type(psb_ld_coo_sparse_mat), allocatable :: rmta
contains
! Getters
@@ -109,6 +111,8 @@ module psb_d_mat_mod
procedure, pass(a) :: is_repeatable_updates => psb_d_is_repeatable_updates
procedure, pass(a) :: get_fmt => psb_d_get_fmt
procedure, pass(a) :: sizeof => psb_d_sizeof
+ procedure, pass(a) :: is_remote_build => psb_d_is_remote_build
+
! Setters
procedure, pass(a) :: set_nrows => psb_d_set_nrows
@@ -125,6 +129,7 @@ module psb_d_mat_mod
procedure, pass(a) :: set_symmetric => psb_d_set_symmetric
procedure, pass(a) :: set_unit => psb_d_set_unit
procedure, pass(a) :: set_repeatable_updates => psb_d_set_repeatable_updates
+ procedure, pass(a) :: set_remote_build => psb_d_set_remote_build
! Memory/data management
procedure, pass(a) :: csall => psb_d_csall
@@ -2292,7 +2297,25 @@ contains
end function d_mat_is_sync
+ function psb_d_is_remote_build(a) result(res)
+ implicit none
+ class(psb_dspmat_type), intent(in) :: a
+ logical :: res
+ res = (a%remote_build == psb_matbld_remote_)
+ end function psb_d_is_remote_build
+ subroutine psb_d_set_remote_build(a,val)
+ implicit none
+ class(psb_dspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ a%remote_build = val
+ else
+ a%remote_build = psb_matbld_remote_
+ end if
+ end subroutine psb_d_set_remote_build
+
function psb_d_is_repeatable_updates(a) result(res)
implicit none
class(psb_dspmat_type), intent(in) :: a
diff --git a/base/modules/serial/psb_d_vect_mod.F90 b/base/modules/serial/psb_d_vect_mod.F90
index c3cad97e..88fa3262 100644
--- a/base/modules/serial/psb_d_vect_mod.F90
+++ b/base/modules/serial/psb_d_vect_mod.F90
@@ -39,15 +39,27 @@
!
module psb_d_vect_mod
+ use psb_realloc_mod
use psb_d_base_vect_mod
use psb_i_vect_mod
type psb_d_vect_type
class(psb_d_base_vect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ real(psb_dpk_), allocatable :: rmtv(:)
+ integer(psb_lpk_), allocatable :: rmidx(:)
contains
procedure, pass(x) :: get_nrows => d_vect_get_nrows
procedure, pass(x) :: sizeof => d_vect_sizeof
procedure, pass(x) :: get_fmt => d_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => d_vect_is_remote_build
+ procedure, pass(x) :: set_remote_build => d_vect_set_remote_build
+ procedure, pass(x) :: get_dupl => d_vect_get_dupl
+ procedure, pass(x) :: set_dupl => d_vect_set_dupl
+ procedure, pass(x) :: get_nrmv => d_vect_get_nrmv
+ procedure, pass(x) :: set_nrmv => d_vect_set_nrmv
procedure, pass(x) :: all => d_vect_all
procedure, pass(x) :: reall => d_vect_reall
procedure, pass(x) :: zero => d_vect_zero
@@ -152,7 +164,9 @@ module psb_d_vect_mod
& d_vect_cnv, d_vect_set_scal, &
& d_vect_set_vect, d_vect_clone, d_vect_sync, d_vect_is_host, &
& d_vect_is_dev, d_vect_is_sync, d_vect_set_host, &
- & d_vect_set_dev, d_vect_set_sync
+ & d_vect_set_dev, d_vect_set_sync, &
+ & d_vect_set_remote_build, d_is_remote_build, &
+ & d_vect_set_dupl, d_get_dupl, d_vect_set_nrmv, d_get_nrmv
private :: d_vect_dot_v, d_vect_dot_a, d_vect_axpby_v, d_vect_axpby_a, &
& d_vect_mlt_v, d_vect_mlt_a, d_vect_mlt_a_2, d_vect_mlt_v_2, &
@@ -174,7 +188,60 @@ module psb_d_vect_mod
contains
+ function d_vect_get_dupl(x) result(res)
+ implicit none
+ class(psb_d_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function d_vect_get_dupl
+
+ subroutine d_vect_set_dupl(x,val)
+ implicit none
+ class(psb_d_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine d_vect_set_dupl
+
+ function d_vect_get_nrmv(x) result(res)
+ implicit none
+ class(psb_d_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%nrmv
+ end function d_vect_get_nrmv
+
+ subroutine d_vect_set_nrmv(x,val)
+ implicit none
+ class(psb_d_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in) :: val
+
+ x%nrmv = val
+ end subroutine d_vect_set_nrmv
+
+
+ function d_vect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_d_vect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function d_vect_is_remote_build
+ subroutine d_vect_set_remote_build(x,val)
+ implicit none
+ class(psb_d_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine d_vect_set_remote_build
+
subroutine psb_d_set_vect_default(v)
implicit none
class(psb_d_base_vect_type), intent(in) :: v
@@ -372,8 +439,8 @@ contains
implicit none
integer(psb_ipk_), intent(in) :: n
class(psb_d_vect_type), intent(inout) :: x
- class(psb_d_base_vect_type), intent(in), optional :: mold
integer(psb_ipk_), intent(out) :: info
+ class(psb_d_base_vect_type), intent(in), optional :: mold
if (allocated(x%v)) &
& call x%free(info)
@@ -388,7 +455,6 @@ contains
else
info = psb_err_alloc_dealloc_
end if
-
end subroutine d_vect_all
subroutine d_vect_reall(n, x, info)
@@ -419,13 +485,13 @@ contains
use psi_serial_mod
use psb_realloc_mod
implicit none
- integer(psb_ipk_), intent(in) :: n
+ integer(psb_ipk_), intent(in) :: n
class(psb_d_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(out) :: info
-
- if (allocated(x%v)) &
- & call x%v%asb(n,info)
+ integer(psb_ipk_), intent(out) :: info
+ if (allocated(x%v)) then
+ call x%v%asb(n,info)
+ end if
end subroutine d_vect_asb
subroutine d_vect_gthab(n,idx,alpha,x,beta,y)
@@ -476,44 +542,44 @@ contains
end subroutine d_vect_free
- subroutine d_vect_ins_a(n,irl,val,dupl,x,info)
+ subroutine d_vect_ins_a(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_d_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
real(psb_dpk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine d_vect_ins_a
- subroutine d_vect_ins_v(n,irl,val,dupl,x,info)
+ subroutine d_vect_ins_v(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_d_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
class(psb_i_vect_type), intent(inout) :: irl
class(psb_d_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl%v,val%v,dupl,info)
end subroutine d_vect_ins_v
@@ -1263,7 +1329,6 @@ contains
end module psb_d_vect_mod
-
module psb_d_multivect_mod
use psb_d_base_multivect_mod
@@ -1275,11 +1340,19 @@ module psb_d_multivect_mod
type psb_d_multivect_type
class(psb_d_base_multivect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ real(psb_dpk_), allocatable :: rmtv(:,:)
contains
procedure, pass(x) :: get_nrows => d_vect_get_nrows
procedure, pass(x) :: get_ncols => d_vect_get_ncols
procedure, pass(x) :: sizeof => d_vect_sizeof
procedure, pass(x) :: get_fmt => d_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => d_mvect_is_remote_build
+ procedure, pass(x) :: set_remote_build => d_mvect_set_remote_build
+ procedure, pass(x) :: get_dupl => d_mvect_get_dupl
+ procedure, pass(x) :: set_dupl => d_mvect_set_dupl
procedure, pass(x) :: all => d_vect_all
procedure, pass(x) :: reall => d_vect_reall
@@ -1347,6 +1420,46 @@ module psb_d_multivect_mod
contains
+
+ function d_mvect_get_dupl(x) result(res)
+ implicit none
+ class(psb_d_multivect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function d_mvect_get_dupl
+
+ subroutine d_mvect_set_dupl(x,val)
+ implicit none
+ class(psb_d_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine d_mvect_set_dupl
+
+
+ function d_mvect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_d_multivect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function d_mvect_is_remote_build
+
+ subroutine d_mvect_set_remote_build(x,val)
+ implicit none
+ class(psb_d_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine d_mvect_set_remote_build
+
subroutine psb_d_set_multivect_default(v)
implicit none
@@ -1651,23 +1764,23 @@ contains
end subroutine d_vect_free
- subroutine d_vect_ins(n,irl,val,dupl,x,info)
+ subroutine d_vect_ins(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_d_multivect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
real(psb_dpk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine d_vect_ins
diff --git a/base/modules/serial/psb_i_vect_mod.F90 b/base/modules/serial/psb_i_vect_mod.F90
index 369aca6d..ab371bd5 100644
--- a/base/modules/serial/psb_i_vect_mod.F90
+++ b/base/modules/serial/psb_i_vect_mod.F90
@@ -39,14 +39,26 @@
!
module psb_i_vect_mod
+ use psb_realloc_mod
use psb_i_base_vect_mod
type psb_i_vect_type
class(psb_i_base_vect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ integer(psb_ipk_), allocatable :: rmtv(:)
+ integer(psb_lpk_), allocatable :: rmidx(:)
contains
procedure, pass(x) :: get_nrows => i_vect_get_nrows
procedure, pass(x) :: sizeof => i_vect_sizeof
procedure, pass(x) :: get_fmt => i_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => i_vect_is_remote_build
+ procedure, pass(x) :: set_remote_build => i_vect_set_remote_build
+ procedure, pass(x) :: get_dupl => i_vect_get_dupl
+ procedure, pass(x) :: set_dupl => i_vect_set_dupl
+ procedure, pass(x) :: get_nrmv => i_vect_get_nrmv
+ procedure, pass(x) :: set_nrmv => i_vect_set_nrmv
procedure, pass(x) :: all => i_vect_all
procedure, pass(x) :: reall => i_vect_reall
procedure, pass(x) :: zero => i_vect_zero
@@ -97,7 +109,9 @@ module psb_i_vect_mod
& i_vect_cnv, i_vect_set_scal, &
& i_vect_set_vect, i_vect_clone, i_vect_sync, i_vect_is_host, &
& i_vect_is_dev, i_vect_is_sync, i_vect_set_host, &
- & i_vect_set_dev, i_vect_set_sync
+ & i_vect_set_dev, i_vect_set_sync, &
+ & i_vect_set_remote_build, i_is_remote_build, &
+ & i_vect_set_dupl, i_get_dupl, i_vect_set_nrmv, i_get_nrmv
class(psb_i_base_vect_type), allocatable, target,&
@@ -114,7 +128,60 @@ module psb_i_vect_mod
contains
+ function i_vect_get_dupl(x) result(res)
+ implicit none
+ class(psb_i_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function i_vect_get_dupl
+
+ subroutine i_vect_set_dupl(x,val)
+ implicit none
+ class(psb_i_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine i_vect_set_dupl
+
+ function i_vect_get_nrmv(x) result(res)
+ implicit none
+ class(psb_i_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%nrmv
+ end function i_vect_get_nrmv
+
+ subroutine i_vect_set_nrmv(x,val)
+ implicit none
+ class(psb_i_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in) :: val
+
+ x%nrmv = val
+ end subroutine i_vect_set_nrmv
+
+
+ function i_vect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_i_vect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function i_vect_is_remote_build
+ subroutine i_vect_set_remote_build(x,val)
+ implicit none
+ class(psb_i_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine i_vect_set_remote_build
+
subroutine psb_i_set_vect_default(v)
implicit none
class(psb_i_base_vect_type), intent(in) :: v
@@ -312,8 +379,8 @@ contains
implicit none
integer(psb_ipk_), intent(in) :: n
class(psb_i_vect_type), intent(inout) :: x
- class(psb_i_base_vect_type), intent(in), optional :: mold
integer(psb_ipk_), intent(out) :: info
+ class(psb_i_base_vect_type), intent(in), optional :: mold
if (allocated(x%v)) &
& call x%free(info)
@@ -328,7 +395,6 @@ contains
else
info = psb_err_alloc_dealloc_
end if
-
end subroutine i_vect_all
subroutine i_vect_reall(n, x, info)
@@ -359,13 +425,13 @@ contains
use psi_serial_mod
use psb_realloc_mod
implicit none
- integer(psb_ipk_), intent(in) :: n
+ integer(psb_ipk_), intent(in) :: n
class(psb_i_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(out) :: info
-
- if (allocated(x%v)) &
- & call x%v%asb(n,info)
+ integer(psb_ipk_), intent(out) :: info
+ if (allocated(x%v)) then
+ call x%v%asb(n,info)
+ end if
end subroutine i_vect_asb
subroutine i_vect_gthab(n,idx,alpha,x,beta,y)
@@ -416,44 +482,44 @@ contains
end subroutine i_vect_free
- subroutine i_vect_ins_a(n,irl,val,dupl,x,info)
+ subroutine i_vect_ins_a(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_i_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
integer(psb_ipk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine i_vect_ins_a
- subroutine i_vect_ins_v(n,irl,val,dupl,x,info)
+ subroutine i_vect_ins_v(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_i_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
class(psb_i_vect_type), intent(inout) :: irl
class(psb_i_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl%v,val%v,dupl,info)
end subroutine i_vect_ins_v
@@ -559,7 +625,6 @@ contains
end module psb_i_vect_mod
-
module psb_i_multivect_mod
use psb_i_base_multivect_mod
@@ -571,11 +636,19 @@ module psb_i_multivect_mod
type psb_i_multivect_type
class(psb_i_base_multivect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ integer(psb_ipk_), allocatable :: rmtv(:,:)
contains
procedure, pass(x) :: get_nrows => i_vect_get_nrows
procedure, pass(x) :: get_ncols => i_vect_get_ncols
procedure, pass(x) :: sizeof => i_vect_sizeof
procedure, pass(x) :: get_fmt => i_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => i_mvect_is_remote_build
+ procedure, pass(x) :: set_remote_build => i_mvect_set_remote_build
+ procedure, pass(x) :: get_dupl => i_mvect_get_dupl
+ procedure, pass(x) :: set_dupl => i_mvect_set_dupl
procedure, pass(x) :: all => i_vect_all
procedure, pass(x) :: reall => i_vect_reall
@@ -625,6 +698,46 @@ module psb_i_multivect_mod
contains
+
+ function i_mvect_get_dupl(x) result(res)
+ implicit none
+ class(psb_i_multivect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function i_mvect_get_dupl
+
+ subroutine i_mvect_set_dupl(x,val)
+ implicit none
+ class(psb_i_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine i_mvect_set_dupl
+
+
+ function i_mvect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_i_multivect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function i_mvect_is_remote_build
+
+ subroutine i_mvect_set_remote_build(x,val)
+ implicit none
+ class(psb_i_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine i_mvect_set_remote_build
+
subroutine psb_i_set_multivect_default(v)
implicit none
@@ -929,23 +1042,23 @@ contains
end subroutine i_vect_free
- subroutine i_vect_ins(n,irl,val,dupl,x,info)
+ subroutine i_vect_ins(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_i_multivect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
integer(psb_ipk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine i_vect_ins
diff --git a/base/modules/serial/psb_l_vect_mod.F90 b/base/modules/serial/psb_l_vect_mod.F90
index 0c36df14..779d4723 100644
--- a/base/modules/serial/psb_l_vect_mod.F90
+++ b/base/modules/serial/psb_l_vect_mod.F90
@@ -39,15 +39,27 @@
!
module psb_l_vect_mod
+ use psb_realloc_mod
use psb_l_base_vect_mod
use psb_i_vect_mod
type psb_l_vect_type
class(psb_l_base_vect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ integer(psb_lpk_), allocatable :: rmtv(:)
+ integer(psb_lpk_), allocatable :: rmidx(:)
contains
procedure, pass(x) :: get_nrows => l_vect_get_nrows
procedure, pass(x) :: sizeof => l_vect_sizeof
procedure, pass(x) :: get_fmt => l_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => l_vect_is_remote_build
+ procedure, pass(x) :: set_remote_build => l_vect_set_remote_build
+ procedure, pass(x) :: get_dupl => l_vect_get_dupl
+ procedure, pass(x) :: set_dupl => l_vect_set_dupl
+ procedure, pass(x) :: get_nrmv => l_vect_get_nrmv
+ procedure, pass(x) :: set_nrmv => l_vect_set_nrmv
procedure, pass(x) :: all => l_vect_all
procedure, pass(x) :: reall => l_vect_reall
procedure, pass(x) :: zero => l_vect_zero
@@ -98,7 +110,9 @@ module psb_l_vect_mod
& l_vect_cnv, l_vect_set_scal, &
& l_vect_set_vect, l_vect_clone, l_vect_sync, l_vect_is_host, &
& l_vect_is_dev, l_vect_is_sync, l_vect_set_host, &
- & l_vect_set_dev, l_vect_set_sync
+ & l_vect_set_dev, l_vect_set_sync, &
+ & l_vect_set_remote_build, l_is_remote_build, &
+ & l_vect_set_dupl, l_get_dupl, l_vect_set_nrmv, l_get_nrmv
class(psb_l_base_vect_type), allocatable, target,&
@@ -115,7 +129,60 @@ module psb_l_vect_mod
contains
+ function l_vect_get_dupl(x) result(res)
+ implicit none
+ class(psb_l_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function l_vect_get_dupl
+
+ subroutine l_vect_set_dupl(x,val)
+ implicit none
+ class(psb_l_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine l_vect_set_dupl
+
+ function l_vect_get_nrmv(x) result(res)
+ implicit none
+ class(psb_l_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%nrmv
+ end function l_vect_get_nrmv
+
+ subroutine l_vect_set_nrmv(x,val)
+ implicit none
+ class(psb_l_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in) :: val
+
+ x%nrmv = val
+ end subroutine l_vect_set_nrmv
+
+
+ function l_vect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_l_vect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function l_vect_is_remote_build
+ subroutine l_vect_set_remote_build(x,val)
+ implicit none
+ class(psb_l_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine l_vect_set_remote_build
+
subroutine psb_l_set_vect_default(v)
implicit none
class(psb_l_base_vect_type), intent(in) :: v
@@ -313,8 +380,8 @@ contains
implicit none
integer(psb_ipk_), intent(in) :: n
class(psb_l_vect_type), intent(inout) :: x
- class(psb_l_base_vect_type), intent(in), optional :: mold
integer(psb_ipk_), intent(out) :: info
+ class(psb_l_base_vect_type), intent(in), optional :: mold
if (allocated(x%v)) &
& call x%free(info)
@@ -329,7 +396,6 @@ contains
else
info = psb_err_alloc_dealloc_
end if
-
end subroutine l_vect_all
subroutine l_vect_reall(n, x, info)
@@ -360,13 +426,13 @@ contains
use psi_serial_mod
use psb_realloc_mod
implicit none
- integer(psb_ipk_), intent(in) :: n
+ integer(psb_ipk_), intent(in) :: n
class(psb_l_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(out) :: info
-
- if (allocated(x%v)) &
- & call x%v%asb(n,info)
+ integer(psb_ipk_), intent(out) :: info
+ if (allocated(x%v)) then
+ call x%v%asb(n,info)
+ end if
end subroutine l_vect_asb
subroutine l_vect_gthab(n,idx,alpha,x,beta,y)
@@ -417,44 +483,44 @@ contains
end subroutine l_vect_free
- subroutine l_vect_ins_a(n,irl,val,dupl,x,info)
+ subroutine l_vect_ins_a(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_l_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
integer(psb_lpk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine l_vect_ins_a
- subroutine l_vect_ins_v(n,irl,val,dupl,x,info)
+ subroutine l_vect_ins_v(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_l_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
class(psb_i_vect_type), intent(inout) :: irl
class(psb_l_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl%v,val%v,dupl,info)
end subroutine l_vect_ins_v
@@ -560,7 +626,6 @@ contains
end module psb_l_vect_mod
-
module psb_l_multivect_mod
use psb_l_base_multivect_mod
@@ -572,11 +637,19 @@ module psb_l_multivect_mod
type psb_l_multivect_type
class(psb_l_base_multivect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ integer(psb_lpk_), allocatable :: rmtv(:,:)
contains
procedure, pass(x) :: get_nrows => l_vect_get_nrows
procedure, pass(x) :: get_ncols => l_vect_get_ncols
procedure, pass(x) :: sizeof => l_vect_sizeof
procedure, pass(x) :: get_fmt => l_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => l_mvect_is_remote_build
+ procedure, pass(x) :: set_remote_build => l_mvect_set_remote_build
+ procedure, pass(x) :: get_dupl => l_mvect_get_dupl
+ procedure, pass(x) :: set_dupl => l_mvect_set_dupl
procedure, pass(x) :: all => l_vect_all
procedure, pass(x) :: reall => l_vect_reall
@@ -626,6 +699,46 @@ module psb_l_multivect_mod
contains
+
+ function l_mvect_get_dupl(x) result(res)
+ implicit none
+ class(psb_l_multivect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function l_mvect_get_dupl
+
+ subroutine l_mvect_set_dupl(x,val)
+ implicit none
+ class(psb_l_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine l_mvect_set_dupl
+
+
+ function l_mvect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_l_multivect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function l_mvect_is_remote_build
+
+ subroutine l_mvect_set_remote_build(x,val)
+ implicit none
+ class(psb_l_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine l_mvect_set_remote_build
+
subroutine psb_l_set_multivect_default(v)
implicit none
@@ -930,23 +1043,23 @@ contains
end subroutine l_vect_free
- subroutine l_vect_ins(n,irl,val,dupl,x,info)
+ subroutine l_vect_ins(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_l_multivect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
integer(psb_lpk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine l_vect_ins
diff --git a/base/modules/serial/psb_s_mat_mod.F90 b/base/modules/serial/psb_s_mat_mod.F90
index 849c64c3..43f1c619 100644
--- a/base/modules/serial/psb_s_mat_mod.F90
+++ b/base/modules/serial/psb_s_mat_mod.F90
@@ -84,7 +84,9 @@ module psb_s_mat_mod
type :: psb_sspmat_type
- class(psb_s_base_sparse_mat), allocatable :: a
+ class(psb_s_base_sparse_mat), allocatable :: a
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ type(psb_ls_coo_sparse_mat), allocatable :: rmta
contains
! Getters
@@ -109,6 +111,8 @@ module psb_s_mat_mod
procedure, pass(a) :: is_repeatable_updates => psb_s_is_repeatable_updates
procedure, pass(a) :: get_fmt => psb_s_get_fmt
procedure, pass(a) :: sizeof => psb_s_sizeof
+ procedure, pass(a) :: is_remote_build => psb_s_is_remote_build
+
! Setters
procedure, pass(a) :: set_nrows => psb_s_set_nrows
@@ -125,6 +129,7 @@ module psb_s_mat_mod
procedure, pass(a) :: set_symmetric => psb_s_set_symmetric
procedure, pass(a) :: set_unit => psb_s_set_unit
procedure, pass(a) :: set_repeatable_updates => psb_s_set_repeatable_updates
+ procedure, pass(a) :: set_remote_build => psb_s_set_remote_build
! Memory/data management
procedure, pass(a) :: csall => psb_s_csall
@@ -2292,7 +2297,25 @@ contains
end function s_mat_is_sync
+ function psb_s_is_remote_build(a) result(res)
+ implicit none
+ class(psb_sspmat_type), intent(in) :: a
+ logical :: res
+ res = (a%remote_build == psb_matbld_remote_)
+ end function psb_s_is_remote_build
+ subroutine psb_s_set_remote_build(a,val)
+ implicit none
+ class(psb_sspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ a%remote_build = val
+ else
+ a%remote_build = psb_matbld_remote_
+ end if
+ end subroutine psb_s_set_remote_build
+
function psb_s_is_repeatable_updates(a) result(res)
implicit none
class(psb_sspmat_type), intent(in) :: a
diff --git a/base/modules/serial/psb_s_vect_mod.F90 b/base/modules/serial/psb_s_vect_mod.F90
index 8da759fc..7a54ecf0 100644
--- a/base/modules/serial/psb_s_vect_mod.F90
+++ b/base/modules/serial/psb_s_vect_mod.F90
@@ -39,15 +39,27 @@
!
module psb_s_vect_mod
+ use psb_realloc_mod
use psb_s_base_vect_mod
use psb_i_vect_mod
type psb_s_vect_type
class(psb_s_base_vect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ real(psb_spk_), allocatable :: rmtv(:)
+ integer(psb_lpk_), allocatable :: rmidx(:)
contains
procedure, pass(x) :: get_nrows => s_vect_get_nrows
procedure, pass(x) :: sizeof => s_vect_sizeof
procedure, pass(x) :: get_fmt => s_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => s_vect_is_remote_build
+ procedure, pass(x) :: set_remote_build => s_vect_set_remote_build
+ procedure, pass(x) :: get_dupl => s_vect_get_dupl
+ procedure, pass(x) :: set_dupl => s_vect_set_dupl
+ procedure, pass(x) :: get_nrmv => s_vect_get_nrmv
+ procedure, pass(x) :: set_nrmv => s_vect_set_nrmv
procedure, pass(x) :: all => s_vect_all
procedure, pass(x) :: reall => s_vect_reall
procedure, pass(x) :: zero => s_vect_zero
@@ -152,7 +164,9 @@ module psb_s_vect_mod
& s_vect_cnv, s_vect_set_scal, &
& s_vect_set_vect, s_vect_clone, s_vect_sync, s_vect_is_host, &
& s_vect_is_dev, s_vect_is_sync, s_vect_set_host, &
- & s_vect_set_dev, s_vect_set_sync
+ & s_vect_set_dev, s_vect_set_sync, &
+ & s_vect_set_remote_build, s_is_remote_build, &
+ & s_vect_set_dupl, s_get_dupl, s_vect_set_nrmv, s_get_nrmv
private :: s_vect_dot_v, s_vect_dot_a, s_vect_axpby_v, s_vect_axpby_a, &
& s_vect_mlt_v, s_vect_mlt_a, s_vect_mlt_a_2, s_vect_mlt_v_2, &
@@ -174,7 +188,60 @@ module psb_s_vect_mod
contains
+ function s_vect_get_dupl(x) result(res)
+ implicit none
+ class(psb_s_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function s_vect_get_dupl
+
+ subroutine s_vect_set_dupl(x,val)
+ implicit none
+ class(psb_s_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine s_vect_set_dupl
+
+ function s_vect_get_nrmv(x) result(res)
+ implicit none
+ class(psb_s_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%nrmv
+ end function s_vect_get_nrmv
+
+ subroutine s_vect_set_nrmv(x,val)
+ implicit none
+ class(psb_s_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in) :: val
+
+ x%nrmv = val
+ end subroutine s_vect_set_nrmv
+
+
+ function s_vect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_s_vect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function s_vect_is_remote_build
+ subroutine s_vect_set_remote_build(x,val)
+ implicit none
+ class(psb_s_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine s_vect_set_remote_build
+
subroutine psb_s_set_vect_default(v)
implicit none
class(psb_s_base_vect_type), intent(in) :: v
@@ -372,8 +439,8 @@ contains
implicit none
integer(psb_ipk_), intent(in) :: n
class(psb_s_vect_type), intent(inout) :: x
- class(psb_s_base_vect_type), intent(in), optional :: mold
integer(psb_ipk_), intent(out) :: info
+ class(psb_s_base_vect_type), intent(in), optional :: mold
if (allocated(x%v)) &
& call x%free(info)
@@ -388,7 +455,6 @@ contains
else
info = psb_err_alloc_dealloc_
end if
-
end subroutine s_vect_all
subroutine s_vect_reall(n, x, info)
@@ -419,13 +485,13 @@ contains
use psi_serial_mod
use psb_realloc_mod
implicit none
- integer(psb_ipk_), intent(in) :: n
+ integer(psb_ipk_), intent(in) :: n
class(psb_s_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(out) :: info
-
- if (allocated(x%v)) &
- & call x%v%asb(n,info)
+ integer(psb_ipk_), intent(out) :: info
+ if (allocated(x%v)) then
+ call x%v%asb(n,info)
+ end if
end subroutine s_vect_asb
subroutine s_vect_gthab(n,idx,alpha,x,beta,y)
@@ -476,44 +542,44 @@ contains
end subroutine s_vect_free
- subroutine s_vect_ins_a(n,irl,val,dupl,x,info)
+ subroutine s_vect_ins_a(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_s_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
real(psb_spk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine s_vect_ins_a
- subroutine s_vect_ins_v(n,irl,val,dupl,x,info)
+ subroutine s_vect_ins_v(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_s_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
class(psb_i_vect_type), intent(inout) :: irl
class(psb_s_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl%v,val%v,dupl,info)
end subroutine s_vect_ins_v
@@ -1263,7 +1329,6 @@ contains
end module psb_s_vect_mod
-
module psb_s_multivect_mod
use psb_s_base_multivect_mod
@@ -1275,11 +1340,19 @@ module psb_s_multivect_mod
type psb_s_multivect_type
class(psb_s_base_multivect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ real(psb_spk_), allocatable :: rmtv(:,:)
contains
procedure, pass(x) :: get_nrows => s_vect_get_nrows
procedure, pass(x) :: get_ncols => s_vect_get_ncols
procedure, pass(x) :: sizeof => s_vect_sizeof
procedure, pass(x) :: get_fmt => s_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => s_mvect_is_remote_build
+ procedure, pass(x) :: set_remote_build => s_mvect_set_remote_build
+ procedure, pass(x) :: get_dupl => s_mvect_get_dupl
+ procedure, pass(x) :: set_dupl => s_mvect_set_dupl
procedure, pass(x) :: all => s_vect_all
procedure, pass(x) :: reall => s_vect_reall
@@ -1347,6 +1420,46 @@ module psb_s_multivect_mod
contains
+
+ function s_mvect_get_dupl(x) result(res)
+ implicit none
+ class(psb_s_multivect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function s_mvect_get_dupl
+
+ subroutine s_mvect_set_dupl(x,val)
+ implicit none
+ class(psb_s_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine s_mvect_set_dupl
+
+
+ function s_mvect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_s_multivect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function s_mvect_is_remote_build
+
+ subroutine s_mvect_set_remote_build(x,val)
+ implicit none
+ class(psb_s_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine s_mvect_set_remote_build
+
subroutine psb_s_set_multivect_default(v)
implicit none
@@ -1651,23 +1764,23 @@ contains
end subroutine s_vect_free
- subroutine s_vect_ins(n,irl,val,dupl,x,info)
+ subroutine s_vect_ins(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_s_multivect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
real(psb_spk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine s_vect_ins
diff --git a/base/modules/serial/psb_z_mat_mod.F90 b/base/modules/serial/psb_z_mat_mod.F90
index fc16ca80..c534cad5 100644
--- a/base/modules/serial/psb_z_mat_mod.F90
+++ b/base/modules/serial/psb_z_mat_mod.F90
@@ -84,7 +84,9 @@ module psb_z_mat_mod
type :: psb_zspmat_type
- class(psb_z_base_sparse_mat), allocatable :: a
+ class(psb_z_base_sparse_mat), allocatable :: a
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ type(psb_lz_coo_sparse_mat), allocatable :: rmta
contains
! Getters
@@ -109,6 +111,8 @@ module psb_z_mat_mod
procedure, pass(a) :: is_repeatable_updates => psb_z_is_repeatable_updates
procedure, pass(a) :: get_fmt => psb_z_get_fmt
procedure, pass(a) :: sizeof => psb_z_sizeof
+ procedure, pass(a) :: is_remote_build => psb_z_is_remote_build
+
! Setters
procedure, pass(a) :: set_nrows => psb_z_set_nrows
@@ -125,6 +129,7 @@ module psb_z_mat_mod
procedure, pass(a) :: set_symmetric => psb_z_set_symmetric
procedure, pass(a) :: set_unit => psb_z_set_unit
procedure, pass(a) :: set_repeatable_updates => psb_z_set_repeatable_updates
+ procedure, pass(a) :: set_remote_build => psb_z_set_remote_build
! Memory/data management
procedure, pass(a) :: csall => psb_z_csall
@@ -2292,7 +2297,25 @@ contains
end function z_mat_is_sync
+ function psb_z_is_remote_build(a) result(res)
+ implicit none
+ class(psb_zspmat_type), intent(in) :: a
+ logical :: res
+ res = (a%remote_build == psb_matbld_remote_)
+ end function psb_z_is_remote_build
+ subroutine psb_z_set_remote_build(a,val)
+ implicit none
+ class(psb_zspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ a%remote_build = val
+ else
+ a%remote_build = psb_matbld_remote_
+ end if
+ end subroutine psb_z_set_remote_build
+
function psb_z_is_repeatable_updates(a) result(res)
implicit none
class(psb_zspmat_type), intent(in) :: a
diff --git a/base/modules/serial/psb_z_vect_mod.F90 b/base/modules/serial/psb_z_vect_mod.F90
index 35327ace..e8a34859 100644
--- a/base/modules/serial/psb_z_vect_mod.F90
+++ b/base/modules/serial/psb_z_vect_mod.F90
@@ -39,15 +39,27 @@
!
module psb_z_vect_mod
+ use psb_realloc_mod
use psb_z_base_vect_mod
use psb_i_vect_mod
type psb_z_vect_type
class(psb_z_base_vect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ complex(psb_dpk_), allocatable :: rmtv(:)
+ integer(psb_lpk_), allocatable :: rmidx(:)
contains
procedure, pass(x) :: get_nrows => z_vect_get_nrows
procedure, pass(x) :: sizeof => z_vect_sizeof
procedure, pass(x) :: get_fmt => z_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => z_vect_is_remote_build
+ procedure, pass(x) :: set_remote_build => z_vect_set_remote_build
+ procedure, pass(x) :: get_dupl => z_vect_get_dupl
+ procedure, pass(x) :: set_dupl => z_vect_set_dupl
+ procedure, pass(x) :: get_nrmv => z_vect_get_nrmv
+ procedure, pass(x) :: set_nrmv => z_vect_set_nrmv
procedure, pass(x) :: all => z_vect_all
procedure, pass(x) :: reall => z_vect_reall
procedure, pass(x) :: zero => z_vect_zero
@@ -145,7 +157,9 @@ module psb_z_vect_mod
& z_vect_cnv, z_vect_set_scal, &
& z_vect_set_vect, z_vect_clone, z_vect_sync, z_vect_is_host, &
& z_vect_is_dev, z_vect_is_sync, z_vect_set_host, &
- & z_vect_set_dev, z_vect_set_sync
+ & z_vect_set_dev, z_vect_set_sync, &
+ & z_vect_set_remote_build, z_is_remote_build, &
+ & z_vect_set_dupl, z_get_dupl, z_vect_set_nrmv, z_get_nrmv
private :: z_vect_dot_v, z_vect_dot_a, z_vect_axpby_v, z_vect_axpby_a, &
& z_vect_mlt_v, z_vect_mlt_a, z_vect_mlt_a_2, z_vect_mlt_v_2, &
@@ -167,7 +181,60 @@ module psb_z_vect_mod
contains
+ function z_vect_get_dupl(x) result(res)
+ implicit none
+ class(psb_z_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function z_vect_get_dupl
+
+ subroutine z_vect_set_dupl(x,val)
+ implicit none
+ class(psb_z_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine z_vect_set_dupl
+
+ function z_vect_get_nrmv(x) result(res)
+ implicit none
+ class(psb_z_vect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%nrmv
+ end function z_vect_get_nrmv
+
+ subroutine z_vect_set_nrmv(x,val)
+ implicit none
+ class(psb_z_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in) :: val
+
+ x%nrmv = val
+ end subroutine z_vect_set_nrmv
+
+
+ function z_vect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_z_vect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function z_vect_is_remote_build
+ subroutine z_vect_set_remote_build(x,val)
+ implicit none
+ class(psb_z_vect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine z_vect_set_remote_build
+
subroutine psb_z_set_vect_default(v)
implicit none
class(psb_z_base_vect_type), intent(in) :: v
@@ -365,8 +432,8 @@ contains
implicit none
integer(psb_ipk_), intent(in) :: n
class(psb_z_vect_type), intent(inout) :: x
- class(psb_z_base_vect_type), intent(in), optional :: mold
integer(psb_ipk_), intent(out) :: info
+ class(psb_z_base_vect_type), intent(in), optional :: mold
if (allocated(x%v)) &
& call x%free(info)
@@ -381,7 +448,6 @@ contains
else
info = psb_err_alloc_dealloc_
end if
-
end subroutine z_vect_all
subroutine z_vect_reall(n, x, info)
@@ -412,13 +478,13 @@ contains
use psi_serial_mod
use psb_realloc_mod
implicit none
- integer(psb_ipk_), intent(in) :: n
+ integer(psb_ipk_), intent(in) :: n
class(psb_z_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(out) :: info
-
- if (allocated(x%v)) &
- & call x%v%asb(n,info)
+ integer(psb_ipk_), intent(out) :: info
+ if (allocated(x%v)) then
+ call x%v%asb(n,info)
+ end if
end subroutine z_vect_asb
subroutine z_vect_gthab(n,idx,alpha,x,beta,y)
@@ -469,44 +535,44 @@ contains
end subroutine z_vect_free
- subroutine z_vect_ins_a(n,irl,val,dupl,x,info)
+ subroutine z_vect_ins_a(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_z_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
complex(psb_dpk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine z_vect_ins_a
- subroutine z_vect_ins_v(n,irl,val,dupl,x,info)
+ subroutine z_vect_ins_v(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_z_vect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
class(psb_i_vect_type), intent(inout) :: irl
class(psb_z_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.(allocated(x%v).and.allocated(irl%v).and.allocated(val%v))) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl%v,val%v,dupl,info)
end subroutine z_vect_ins_v
@@ -1184,7 +1250,6 @@ contains
end module psb_z_vect_mod
-
module psb_z_multivect_mod
use psb_z_base_multivect_mod
@@ -1196,11 +1261,19 @@ module psb_z_multivect_mod
type psb_z_multivect_type
class(psb_z_base_multivect_type), allocatable :: v
+ integer(psb_ipk_) :: nrmv = 0
+ integer(psb_ipk_) :: remote_build=psb_matbld_noremote_
+ integer(psb_ipk_) :: dupl = psb_dupl_add_
+ complex(psb_dpk_), allocatable :: rmtv(:,:)
contains
procedure, pass(x) :: get_nrows => z_vect_get_nrows
procedure, pass(x) :: get_ncols => z_vect_get_ncols
procedure, pass(x) :: sizeof => z_vect_sizeof
procedure, pass(x) :: get_fmt => z_vect_get_fmt
+ procedure, pass(x) :: is_remote_build => z_mvect_is_remote_build
+ procedure, pass(x) :: set_remote_build => z_mvect_set_remote_build
+ procedure, pass(x) :: get_dupl => z_mvect_get_dupl
+ procedure, pass(x) :: set_dupl => z_mvect_set_dupl
procedure, pass(x) :: all => z_vect_all
procedure, pass(x) :: reall => z_vect_reall
@@ -1268,6 +1341,46 @@ module psb_z_multivect_mod
contains
+
+ function z_mvect_get_dupl(x) result(res)
+ implicit none
+ class(psb_z_multivect_type), intent(in) :: x
+ integer(psb_ipk_) :: res
+ res = x%dupl
+ end function z_mvect_get_dupl
+
+ subroutine z_mvect_set_dupl(x,val)
+ implicit none
+ class(psb_z_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%dupl = val
+ else
+ x%dupl = psb_dupl_def_
+ end if
+ end subroutine z_mvect_set_dupl
+
+
+ function z_mvect_is_remote_build(x) result(res)
+ implicit none
+ class(psb_z_multivect_type), intent(in) :: x
+ logical :: res
+ res = (x%remote_build == psb_matbld_remote_)
+ end function z_mvect_is_remote_build
+
+ subroutine z_mvect_set_remote_build(x,val)
+ implicit none
+ class(psb_z_multivect_type), intent(inout) :: x
+ integer(psb_ipk_), intent(in), optional :: val
+
+ if (present(val)) then
+ x%remote_build = val
+ else
+ x%remote_build = psb_matbld_remote_
+ end if
+ end subroutine z_mvect_set_remote_build
+
subroutine psb_z_set_multivect_default(v)
implicit none
@@ -1572,23 +1685,23 @@ contains
end subroutine z_vect_free
- subroutine z_vect_ins(n,irl,val,dupl,x,info)
+ subroutine z_vect_ins(n,irl,val,x,info)
use psi_serial_mod
implicit none
class(psb_z_multivect_type), intent(inout) :: x
- integer(psb_ipk_), intent(in) :: n, dupl
+ integer(psb_ipk_), intent(in) :: n
integer(psb_ipk_), intent(in) :: irl(:)
complex(psb_dpk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_) :: i
+ integer(psb_ipk_) :: i, dupl
info = 0
if (.not.allocated(x%v)) then
info = psb_err_invalid_vect_state_
return
end if
-
+ dupl = x%get_dupl()
call x%v%ins(n,irl,val,dupl,info)
end subroutine z_vect_ins
diff --git a/base/modules/tools/psb_c_tools_mod.F90 b/base/modules/tools/psb_c_tools_mod.F90
index 378e146b..78ec8518 100644
--- a/base/modules/tools/psb_c_tools_mod.F90
+++ b/base/modules/tools/psb_c_tools_mod.F90
@@ -40,28 +40,31 @@ Module psb_c_tools_mod
use psi_mod, only : psb_snd, psb_rcv ! Needed only for psb_getelem
interface psb_geall
- subroutine psb_calloc_vect(x, desc_a,info)
+ subroutine psb_calloc_vect(x, desc_a,info, dupl, bldmode)
import
implicit none
type(psb_c_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_calloc_vect
- subroutine psb_calloc_vect_r2(x, desc_a,info,n,lb)
+ subroutine psb_calloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
import
implicit none
type(psb_c_vect_type), allocatable, intent(out) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n, lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_calloc_vect_r2
- subroutine psb_calloc_multivect(x, desc_a,info,n)
+ subroutine psb_calloc_multivect(x, desc_a,info,n, dupl, bldmode)
import
implicit none
type(psb_c_multivect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_calloc_multivect
end interface
@@ -123,7 +126,7 @@ Module psb_c_tools_mod
interface psb_geins
- subroutine psb_cins_vect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_cins_vect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -132,10 +135,9 @@ Module psb_c_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
complex(psb_spk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_cins_vect
- subroutine psb_cins_vect_v(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_cins_vect_v(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -144,10 +146,9 @@ Module psb_c_tools_mod
type(psb_l_vect_type), intent(inout) :: irw
type(psb_c_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_cins_vect_v
- subroutine psb_cins_vect_r2(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_cins_vect_r2(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -156,10 +157,9 @@ Module psb_c_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
complex(psb_spk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_cins_vect_r2
- subroutine psb_cins_multivect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_cins_multivect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -168,7 +168,6 @@ Module psb_c_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
complex(psb_spk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_cins_multivect
end interface
@@ -239,29 +238,55 @@ Module psb_c_tools_mod
interface psb_spall
- subroutine psb_cspalloc(a, desc_a, info, nnz)
+ subroutine psb_cspalloc(a, desc_a, info, nnz, dupl, bldmode)
import
implicit none
- type(psb_desc_type), intent(in) :: desc_a
- type(psb_cspmat_type), intent(inout) :: a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: nnz
+ type(psb_desc_type), intent(in) :: desc_a
+ type(psb_cspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: nnz, bldmode
+ integer(psb_ipk_), optional, intent(in) :: dupl
end subroutine psb_cspalloc
end interface
interface psb_spasb
- subroutine psb_cspasb(a,desc_a, info, afmt, upd, dupl,mold)
+ subroutine psb_cspasb(a,desc_a, info, afmt, upd, mold)
import
implicit none
type(psb_cspmat_type), intent (inout) :: a
- type(psb_desc_type), intent(in) :: desc_a
+ type(psb_desc_type), intent(inout) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_),optional, intent(in) :: dupl, upd
+ integer(psb_ipk_),optional, intent(in) :: upd
character(len=*), optional, intent(in) :: afmt
class(psb_c_base_sparse_mat), intent(in), optional :: mold
end subroutine psb_cspasb
end interface
+ interface psb_remote_vect
+ subroutine psb_c_remote_vect(n,v,iv,desc_a,x,ix, info)
+ import
+ implicit none
+ integer(psb_ipk_), intent(in) :: n
+ complex(psb_spk_), intent(in) :: v(:)
+ integer(psb_lpk_), intent(in) :: iv(:)
+ type(psb_desc_type),intent(in) :: desc_a
+ complex(psb_spk_), allocatable, intent(out) :: x(:)
+ integer(psb_lpk_), allocatable, intent(out) :: ix(:)
+ integer(psb_ipk_), intent(out) :: info
+ end subroutine psb_c_remote_vect
+ end interface psb_remote_vect
+
+ interface psb_remote_mat
+ subroutine psb_lc_remote_mat(a,desc_a,b, info)
+ import
+ implicit none
+ type(psb_lc_coo_sparse_mat),Intent(inout) :: a
+ type(psb_desc_type),intent(inout) :: desc_a
+ type(psb_lc_coo_sparse_mat),Intent(inout) :: b
+ integer(psb_ipk_), intent(out) :: info
+ end subroutine psb_lc_remote_mat
+ end interface psb_remote_mat
+
interface psb_spfree
subroutine psb_cspfree(a, desc_a,info)
import
diff --git a/base/modules/tools/psb_d_tools_mod.F90 b/base/modules/tools/psb_d_tools_mod.F90
index 81c75ece..30510123 100644
--- a/base/modules/tools/psb_d_tools_mod.F90
+++ b/base/modules/tools/psb_d_tools_mod.F90
@@ -40,28 +40,31 @@ Module psb_d_tools_mod
use psi_mod, only : psb_snd, psb_rcv ! Needed only for psb_getelem
interface psb_geall
- subroutine psb_dalloc_vect(x, desc_a,info)
+ subroutine psb_dalloc_vect(x, desc_a,info, dupl, bldmode)
import
implicit none
type(psb_d_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_dalloc_vect
- subroutine psb_dalloc_vect_r2(x, desc_a,info,n,lb)
+ subroutine psb_dalloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
import
implicit none
type(psb_d_vect_type), allocatable, intent(out) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n, lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_dalloc_vect_r2
- subroutine psb_dalloc_multivect(x, desc_a,info,n)
+ subroutine psb_dalloc_multivect(x, desc_a,info,n, dupl, bldmode)
import
implicit none
type(psb_d_multivect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_dalloc_multivect
end interface
@@ -123,7 +126,7 @@ Module psb_d_tools_mod
interface psb_geins
- subroutine psb_dins_vect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_dins_vect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -132,10 +135,9 @@ Module psb_d_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
real(psb_dpk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_dins_vect
- subroutine psb_dins_vect_v(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_dins_vect_v(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -144,10 +146,9 @@ Module psb_d_tools_mod
type(psb_l_vect_type), intent(inout) :: irw
type(psb_d_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_dins_vect_v
- subroutine psb_dins_vect_r2(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_dins_vect_r2(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -156,10 +157,9 @@ Module psb_d_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
real(psb_dpk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_dins_vect_r2
- subroutine psb_dins_multivect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_dins_multivect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -168,7 +168,6 @@ Module psb_d_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
real(psb_dpk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_dins_multivect
end interface
@@ -239,29 +238,55 @@ Module psb_d_tools_mod
interface psb_spall
- subroutine psb_dspalloc(a, desc_a, info, nnz)
+ subroutine psb_dspalloc(a, desc_a, info, nnz, dupl, bldmode)
import
implicit none
- type(psb_desc_type), intent(in) :: desc_a
- type(psb_dspmat_type), intent(inout) :: a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: nnz
+ type(psb_desc_type), intent(in) :: desc_a
+ type(psb_dspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: nnz, bldmode
+ integer(psb_ipk_), optional, intent(in) :: dupl
end subroutine psb_dspalloc
end interface
interface psb_spasb
- subroutine psb_dspasb(a,desc_a, info, afmt, upd, dupl,mold)
+ subroutine psb_dspasb(a,desc_a, info, afmt, upd, mold)
import
implicit none
type(psb_dspmat_type), intent (inout) :: a
- type(psb_desc_type), intent(in) :: desc_a
+ type(psb_desc_type), intent(inout) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_),optional, intent(in) :: dupl, upd
+ integer(psb_ipk_),optional, intent(in) :: upd
character(len=*), optional, intent(in) :: afmt
class(psb_d_base_sparse_mat), intent(in), optional :: mold
end subroutine psb_dspasb
end interface
+ interface psb_remote_vect
+ subroutine psb_d_remote_vect(n,v,iv,desc_a,x,ix, info)
+ import
+ implicit none
+ integer(psb_ipk_), intent(in) :: n
+ real(psb_dpk_), intent(in) :: v(:)
+ integer(psb_lpk_), intent(in) :: iv(:)
+ type(psb_desc_type),intent(in) :: desc_a
+ real(psb_dpk_), allocatable, intent(out) :: x(:)
+ integer(psb_lpk_), allocatable, intent(out) :: ix(:)
+ integer(psb_ipk_), intent(out) :: info
+ end subroutine psb_d_remote_vect
+ end interface psb_remote_vect
+
+ interface psb_remote_mat
+ subroutine psb_ld_remote_mat(a,desc_a,b, info)
+ import
+ implicit none
+ type(psb_ld_coo_sparse_mat),Intent(inout) :: a
+ type(psb_desc_type),intent(inout) :: desc_a
+ type(psb_ld_coo_sparse_mat),Intent(inout) :: b
+ integer(psb_ipk_), intent(out) :: info
+ end subroutine psb_ld_remote_mat
+ end interface psb_remote_mat
+
interface psb_spfree
subroutine psb_dspfree(a, desc_a,info)
import
diff --git a/base/modules/tools/psb_i_tools_mod.F90 b/base/modules/tools/psb_i_tools_mod.F90
index 5cc6e836..94fb04bc 100644
--- a/base/modules/tools/psb_i_tools_mod.F90
+++ b/base/modules/tools/psb_i_tools_mod.F90
@@ -37,28 +37,31 @@ Module psb_i_tools_mod
use psi_mod, only : psb_snd, psb_rcv ! Needed only for psb_getelem
interface psb_geall
- subroutine psb_ialloc_vect(x, desc_a,info)
+ subroutine psb_ialloc_vect(x, desc_a,info, dupl, bldmode)
import
implicit none
type(psb_i_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_ialloc_vect
- subroutine psb_ialloc_vect_r2(x, desc_a,info,n,lb)
+ subroutine psb_ialloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
import
implicit none
type(psb_i_vect_type), allocatable, intent(out) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n, lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_ialloc_vect_r2
- subroutine psb_ialloc_multivect(x, desc_a,info,n)
+ subroutine psb_ialloc_multivect(x, desc_a,info,n, dupl, bldmode)
import
implicit none
type(psb_i_multivect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_ialloc_multivect
end interface
@@ -120,7 +123,7 @@ Module psb_i_tools_mod
interface psb_geins
- subroutine psb_iins_vect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_iins_vect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -129,10 +132,9 @@ Module psb_i_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
integer(psb_ipk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_iins_vect
- subroutine psb_iins_vect_v(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_iins_vect_v(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -141,10 +143,9 @@ Module psb_i_tools_mod
type(psb_l_vect_type), intent(inout) :: irw
type(psb_i_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_iins_vect_v
- subroutine psb_iins_vect_r2(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_iins_vect_r2(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -153,10 +154,9 @@ Module psb_i_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
integer(psb_ipk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_iins_vect_r2
- subroutine psb_iins_multivect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_iins_multivect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -165,7 +165,6 @@ Module psb_i_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
integer(psb_ipk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_iins_multivect
end interface
diff --git a/base/modules/tools/psb_l_tools_mod.F90 b/base/modules/tools/psb_l_tools_mod.F90
index 56617798..61840af6 100644
--- a/base/modules/tools/psb_l_tools_mod.F90
+++ b/base/modules/tools/psb_l_tools_mod.F90
@@ -37,28 +37,31 @@ Module psb_l_tools_mod
use psi_mod, only : psb_snd, psb_rcv ! Needed only for psb_getelem
interface psb_geall
- subroutine psb_lalloc_vect(x, desc_a,info)
+ subroutine psb_lalloc_vect(x, desc_a,info, dupl, bldmode)
import
implicit none
type(psb_l_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_lalloc_vect
- subroutine psb_lalloc_vect_r2(x, desc_a,info,n,lb)
+ subroutine psb_lalloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
import
implicit none
type(psb_l_vect_type), allocatable, intent(out) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n, lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_lalloc_vect_r2
- subroutine psb_lalloc_multivect(x, desc_a,info,n)
+ subroutine psb_lalloc_multivect(x, desc_a,info,n, dupl, bldmode)
import
implicit none
type(psb_l_multivect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_lalloc_multivect
end interface
@@ -120,7 +123,7 @@ Module psb_l_tools_mod
interface psb_geins
- subroutine psb_lins_vect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_lins_vect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -129,10 +132,9 @@ Module psb_l_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
integer(psb_lpk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_lins_vect
- subroutine psb_lins_vect_v(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_lins_vect_v(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -141,10 +143,9 @@ Module psb_l_tools_mod
type(psb_l_vect_type), intent(inout) :: irw
type(psb_l_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_lins_vect_v
- subroutine psb_lins_vect_r2(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_lins_vect_r2(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -153,10 +154,9 @@ Module psb_l_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
integer(psb_lpk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_lins_vect_r2
- subroutine psb_lins_multivect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_lins_multivect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -165,7 +165,6 @@ Module psb_l_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
integer(psb_lpk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_lins_multivect
end interface
diff --git a/base/modules/tools/psb_s_tools_mod.F90 b/base/modules/tools/psb_s_tools_mod.F90
index fa82a53e..72033781 100644
--- a/base/modules/tools/psb_s_tools_mod.F90
+++ b/base/modules/tools/psb_s_tools_mod.F90
@@ -40,28 +40,31 @@ Module psb_s_tools_mod
use psi_mod, only : psb_snd, psb_rcv ! Needed only for psb_getelem
interface psb_geall
- subroutine psb_salloc_vect(x, desc_a,info)
+ subroutine psb_salloc_vect(x, desc_a,info, dupl, bldmode)
import
implicit none
type(psb_s_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_salloc_vect
- subroutine psb_salloc_vect_r2(x, desc_a,info,n,lb)
+ subroutine psb_salloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
import
implicit none
type(psb_s_vect_type), allocatable, intent(out) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n, lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_salloc_vect_r2
- subroutine psb_salloc_multivect(x, desc_a,info,n)
+ subroutine psb_salloc_multivect(x, desc_a,info,n, dupl, bldmode)
import
implicit none
type(psb_s_multivect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_salloc_multivect
end interface
@@ -123,7 +126,7 @@ Module psb_s_tools_mod
interface psb_geins
- subroutine psb_sins_vect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_sins_vect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -132,10 +135,9 @@ Module psb_s_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
real(psb_spk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_sins_vect
- subroutine psb_sins_vect_v(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_sins_vect_v(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -144,10 +146,9 @@ Module psb_s_tools_mod
type(psb_l_vect_type), intent(inout) :: irw
type(psb_s_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_sins_vect_v
- subroutine psb_sins_vect_r2(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_sins_vect_r2(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -156,10 +157,9 @@ Module psb_s_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
real(psb_spk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_sins_vect_r2
- subroutine psb_sins_multivect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_sins_multivect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -168,7 +168,6 @@ Module psb_s_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
real(psb_spk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_sins_multivect
end interface
@@ -239,29 +238,55 @@ Module psb_s_tools_mod
interface psb_spall
- subroutine psb_sspalloc(a, desc_a, info, nnz)
+ subroutine psb_sspalloc(a, desc_a, info, nnz, dupl, bldmode)
import
implicit none
- type(psb_desc_type), intent(in) :: desc_a
- type(psb_sspmat_type), intent(inout) :: a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: nnz
+ type(psb_desc_type), intent(in) :: desc_a
+ type(psb_sspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: nnz, bldmode
+ integer(psb_ipk_), optional, intent(in) :: dupl
end subroutine psb_sspalloc
end interface
interface psb_spasb
- subroutine psb_sspasb(a,desc_a, info, afmt, upd, dupl,mold)
+ subroutine psb_sspasb(a,desc_a, info, afmt, upd, mold)
import
implicit none
type(psb_sspmat_type), intent (inout) :: a
- type(psb_desc_type), intent(in) :: desc_a
+ type(psb_desc_type), intent(inout) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_),optional, intent(in) :: dupl, upd
+ integer(psb_ipk_),optional, intent(in) :: upd
character(len=*), optional, intent(in) :: afmt
class(psb_s_base_sparse_mat), intent(in), optional :: mold
end subroutine psb_sspasb
end interface
+ interface psb_remote_vect
+ subroutine psb_s_remote_vect(n,v,iv,desc_a,x,ix, info)
+ import
+ implicit none
+ integer(psb_ipk_), intent(in) :: n
+ real(psb_spk_), intent(in) :: v(:)
+ integer(psb_lpk_), intent(in) :: iv(:)
+ type(psb_desc_type),intent(in) :: desc_a
+ real(psb_spk_), allocatable, intent(out) :: x(:)
+ integer(psb_lpk_), allocatable, intent(out) :: ix(:)
+ integer(psb_ipk_), intent(out) :: info
+ end subroutine psb_s_remote_vect
+ end interface psb_remote_vect
+
+ interface psb_remote_mat
+ subroutine psb_ls_remote_mat(a,desc_a,b, info)
+ import
+ implicit none
+ type(psb_ls_coo_sparse_mat),Intent(inout) :: a
+ type(psb_desc_type),intent(inout) :: desc_a
+ type(psb_ls_coo_sparse_mat),Intent(inout) :: b
+ integer(psb_ipk_), intent(out) :: info
+ end subroutine psb_ls_remote_mat
+ end interface psb_remote_mat
+
interface psb_spfree
subroutine psb_sspfree(a, desc_a,info)
import
diff --git a/base/modules/tools/psb_z_tools_mod.F90 b/base/modules/tools/psb_z_tools_mod.F90
index 233f2c20..c96737b1 100644
--- a/base/modules/tools/psb_z_tools_mod.F90
+++ b/base/modules/tools/psb_z_tools_mod.F90
@@ -40,28 +40,31 @@ Module psb_z_tools_mod
use psi_mod, only : psb_snd, psb_rcv ! Needed only for psb_getelem
interface psb_geall
- subroutine psb_zalloc_vect(x, desc_a,info)
+ subroutine psb_zalloc_vect(x, desc_a,info, dupl, bldmode)
import
implicit none
type(psb_z_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_zalloc_vect
- subroutine psb_zalloc_vect_r2(x, desc_a,info,n,lb)
+ subroutine psb_zalloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
import
implicit none
type(psb_z_vect_type), allocatable, intent(out) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n, lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_zalloc_vect_r2
- subroutine psb_zalloc_multivect(x, desc_a,info,n)
+ subroutine psb_zalloc_multivect(x, desc_a,info,n, dupl, bldmode)
import
implicit none
type(psb_z_multivect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
end subroutine psb_zalloc_multivect
end interface
@@ -123,7 +126,7 @@ Module psb_z_tools_mod
interface psb_geins
- subroutine psb_zins_vect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_zins_vect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -132,10 +135,9 @@ Module psb_z_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
complex(psb_dpk_), intent(in) :: val(:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_zins_vect
- subroutine psb_zins_vect_v(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_zins_vect_v(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -144,10 +146,9 @@ Module psb_z_tools_mod
type(psb_l_vect_type), intent(inout) :: irw
type(psb_z_vect_type), intent(inout) :: val
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_zins_vect_v
- subroutine psb_zins_vect_r2(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_zins_vect_r2(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -156,10 +157,9 @@ Module psb_z_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
complex(psb_dpk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_zins_vect_r2
- subroutine psb_zins_multivect(m,irw,val,x,desc_a,info,dupl,local)
+ subroutine psb_zins_multivect(m,irw,val,x,desc_a,info,local)
import
implicit none
integer(psb_ipk_), intent(in) :: m
@@ -168,7 +168,6 @@ Module psb_z_tools_mod
integer(psb_lpk_), intent(in) :: irw(:)
complex(psb_dpk_), intent(in) :: val(:,:)
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
end subroutine psb_zins_multivect
end interface
@@ -239,29 +238,55 @@ Module psb_z_tools_mod
interface psb_spall
- subroutine psb_zspalloc(a, desc_a, info, nnz)
+ subroutine psb_zspalloc(a, desc_a, info, nnz, dupl, bldmode)
import
implicit none
- type(psb_desc_type), intent(in) :: desc_a
- type(psb_zspmat_type), intent(inout) :: a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: nnz
+ type(psb_desc_type), intent(in) :: desc_a
+ type(psb_zspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: nnz, bldmode
+ integer(psb_ipk_), optional, intent(in) :: dupl
end subroutine psb_zspalloc
end interface
interface psb_spasb
- subroutine psb_zspasb(a,desc_a, info, afmt, upd, dupl,mold)
+ subroutine psb_zspasb(a,desc_a, info, afmt, upd, mold)
import
implicit none
type(psb_zspmat_type), intent (inout) :: a
- type(psb_desc_type), intent(in) :: desc_a
+ type(psb_desc_type), intent(inout) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_),optional, intent(in) :: dupl, upd
+ integer(psb_ipk_),optional, intent(in) :: upd
character(len=*), optional, intent(in) :: afmt
class(psb_z_base_sparse_mat), intent(in), optional :: mold
end subroutine psb_zspasb
end interface
+ interface psb_remote_vect
+ subroutine psb_z_remote_vect(n,v,iv,desc_a,x,ix, info)
+ import
+ implicit none
+ integer(psb_ipk_), intent(in) :: n
+ complex(psb_dpk_), intent(in) :: v(:)
+ integer(psb_lpk_), intent(in) :: iv(:)
+ type(psb_desc_type),intent(in) :: desc_a
+ complex(psb_dpk_), allocatable, intent(out) :: x(:)
+ integer(psb_lpk_), allocatable, intent(out) :: ix(:)
+ integer(psb_ipk_), intent(out) :: info
+ end subroutine psb_z_remote_vect
+ end interface psb_remote_vect
+
+ interface psb_remote_mat
+ subroutine psb_lz_remote_mat(a,desc_a,b, info)
+ import
+ implicit none
+ type(psb_lz_coo_sparse_mat),Intent(inout) :: a
+ type(psb_desc_type),intent(inout) :: desc_a
+ type(psb_lz_coo_sparse_mat),Intent(inout) :: b
+ integer(psb_ipk_), intent(out) :: info
+ end subroutine psb_lz_remote_mat
+ end interface psb_remote_mat
+
interface psb_spfree
subroutine psb_zspfree(a, desc_a,info)
import
diff --git a/base/serial/impl/psb_c_coo_impl.F90 b/base/serial/impl/psb_c_coo_impl.F90
index bd03b1b8..0127d00f 100644
--- a/base/serial/impl/psb_c_coo_impl.F90
+++ b/base/serial/impl/psb_c_coo_impl.F90
@@ -6121,7 +6121,6 @@ subroutine psb_lc_coo_csput_a(nz,ia,ja,val,a,imin,imax,jmin,jmax,info)
if (nz == 0) return
-
nza = a%get_nzeros()
isza = a%get_size()
if (a%is_bld()) then
diff --git a/base/serial/impl/psb_c_mat_impl.F90 b/base/serial/impl/psb_c_mat_impl.F90
index 088b012d..df5c4cd9 100644
--- a/base/serial/impl/psb_c_mat_impl.F90
+++ b/base/serial/impl/psb_c_mat_impl.F90
@@ -675,7 +675,12 @@ subroutine psb_c_free(a)
call a%a%free()
deallocate(a%a)
endif
-
+ if (allocated(a%rmta)) then
+ call a%rmta%free()
+ deallocate(a%rmta)
+ end if
+ a%remote_build = psb_matbld_noremote_
+
end subroutine psb_c_free
diff --git a/base/serial/impl/psb_d_coo_impl.F90 b/base/serial/impl/psb_d_coo_impl.F90
index d4d88027..7e835261 100644
--- a/base/serial/impl/psb_d_coo_impl.F90
+++ b/base/serial/impl/psb_d_coo_impl.F90
@@ -6121,7 +6121,6 @@ subroutine psb_ld_coo_csput_a(nz,ia,ja,val,a,imin,imax,jmin,jmax,info)
if (nz == 0) return
-
nza = a%get_nzeros()
isza = a%get_size()
if (a%is_bld()) then
diff --git a/base/serial/impl/psb_d_mat_impl.F90 b/base/serial/impl/psb_d_mat_impl.F90
index b21fa40f..2a6fb9a5 100644
--- a/base/serial/impl/psb_d_mat_impl.F90
+++ b/base/serial/impl/psb_d_mat_impl.F90
@@ -675,7 +675,12 @@ subroutine psb_d_free(a)
call a%a%free()
deallocate(a%a)
endif
-
+ if (allocated(a%rmta)) then
+ call a%rmta%free()
+ deallocate(a%rmta)
+ end if
+ a%remote_build = psb_matbld_noremote_
+
end subroutine psb_d_free
diff --git a/base/serial/impl/psb_s_coo_impl.F90 b/base/serial/impl/psb_s_coo_impl.F90
index 5ae9dd96..67725ffb 100644
--- a/base/serial/impl/psb_s_coo_impl.F90
+++ b/base/serial/impl/psb_s_coo_impl.F90
@@ -6121,7 +6121,6 @@ subroutine psb_ls_coo_csput_a(nz,ia,ja,val,a,imin,imax,jmin,jmax,info)
if (nz == 0) return
-
nza = a%get_nzeros()
isza = a%get_size()
if (a%is_bld()) then
diff --git a/base/serial/impl/psb_s_mat_impl.F90 b/base/serial/impl/psb_s_mat_impl.F90
index c624dc2f..ce7ce653 100644
--- a/base/serial/impl/psb_s_mat_impl.F90
+++ b/base/serial/impl/psb_s_mat_impl.F90
@@ -675,7 +675,12 @@ subroutine psb_s_free(a)
call a%a%free()
deallocate(a%a)
endif
-
+ if (allocated(a%rmta)) then
+ call a%rmta%free()
+ deallocate(a%rmta)
+ end if
+ a%remote_build = psb_matbld_noremote_
+
end subroutine psb_s_free
diff --git a/base/serial/impl/psb_z_coo_impl.F90 b/base/serial/impl/psb_z_coo_impl.F90
index 49e6c7fe..158f1ffe 100644
--- a/base/serial/impl/psb_z_coo_impl.F90
+++ b/base/serial/impl/psb_z_coo_impl.F90
@@ -6121,7 +6121,6 @@ subroutine psb_lz_coo_csput_a(nz,ia,ja,val,a,imin,imax,jmin,jmax,info)
if (nz == 0) return
-
nza = a%get_nzeros()
isza = a%get_size()
if (a%is_bld()) then
diff --git a/base/serial/impl/psb_z_mat_impl.F90 b/base/serial/impl/psb_z_mat_impl.F90
index e008dfdb..2cebf9e7 100644
--- a/base/serial/impl/psb_z_mat_impl.F90
+++ b/base/serial/impl/psb_z_mat_impl.F90
@@ -675,7 +675,12 @@ subroutine psb_z_free(a)
call a%a%free()
deallocate(a%a)
endif
-
+ if (allocated(a%rmta)) then
+ call a%rmta%free()
+ deallocate(a%rmta)
+ end if
+ a%remote_build = psb_matbld_noremote_
+
end subroutine psb_z_free
diff --git a/base/tools/Makefile b/base/tools/Makefile
index 2c160616..ce13caed 100644
--- a/base/tools/Makefile
+++ b/base/tools/Makefile
@@ -30,7 +30,8 @@ FOBJS = psb_cdall.o psb_cdals.o psb_cdalv.o psb_cd_inloc.o psb_cdins.o psb_cdprt
psb_cgetelem.o psb_dgetelem.o psb_sgetelem.o psb_zgetelem.o
MPFOBJS = psb_icdasb.o psb_ssphalo.o psb_dsphalo.o psb_csphalo.o psb_zsphalo.o \
- psb_dcdbldext.o psb_zcdbldext.o psb_scdbldext.o psb_ccdbldext.o
+ psb_dcdbldext.o psb_zcdbldext.o psb_scdbldext.o psb_ccdbldext.o \
+ psb_s_remote_mat.o psb_d_remote_mat.o psb_c_remote_mat.o psb_z_remote_mat.o
LIBDIR=..
INCDIR=..
diff --git a/base/tools/psb_c_remote_mat.F90 b/base/tools/psb_c_remote_mat.F90
new file mode 100644
index 00000000..18c7a91d
--- /dev/null
+++ b/base/tools/psb_c_remote_mat.F90
@@ -0,0 +1,436 @@
+!
+! 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.
+!
+!
+! File: psb_c_remote_mat.f90
+!
+! Subroutine:
+! This routine does the retrieval of remote matrix rows.
+! Retrieval is done through GETROW, therefore it should work
+! for any matrix format in A; as for the output, default is CSR.
+!
+! There is also a specialized version lc_CSR whose interface
+! is adapted for the needs of c_par_csr_spspmm.
+!
+! There are three possible exchange algorithms:
+! 1. Use MPI_Alltoallv
+! 2. Use psb_simple_a2av
+! 3. Use psb_simple_triad_a2av
+! Default choice is 3. The MPI variant has proved to be inefficient;
+! that is because it is not persistent, therefore you pay the initialization price
+! every time, and it is not optimized for a sparse communication pattern,
+! most MPI implementations assume that all communications are non-empty.
+! The PSB_SIMPLE variants reuse the same communicator, and go for a simplistic
+! sequence of sends/receive that is quite efficient for a sparse communication
+! pattern. To be refined/reviewed in the future to compare with neighbour
+! persistent collectives.
+!
+! Arguments:
+! a - type(psb_cspmat_type) The local part of input matrix A
+! desc_a - type(psb_desc_type). The communication descriptor.
+! blck - type(psb_cspmat_type) The local part of output matrix BLCK
+! info - integer. Return code
+! rowcnv - logical Should row/col indices be converted
+! colcnv - logical to/from global numbering when sent/received?
+! default is .TRUE.
+! rowscale - logical Should row/col indices on output be remapped
+! colscale - logical from MIN:MAX to 1:(MAX-MIN+1) ?
+! default is .FALSE.
+! (commmon use is ROWSCALE=.TRUE., COLSCALE=.FALSE.)
+! data - integer Which index list in desc_a should be used to retrieve
+! rows, default psb_comm_halo_
+! psb_comm_halo_ use halo_index
+! psb_comm_ext_ use ext_index
+! psb_comm_ovrl_ DISABLED for this routine.
+!
+Subroutine psb_lc_remote_mat(a,desc_a,b,info)
+ use psb_base_mod, psb_protect_name => psb_lc_remote_mat
+
+#ifdef MPI_MOD
+ use mpi
+#endif
+ Implicit None
+#ifdef MPI_H
+ include 'mpif.h'
+#endif
+
+ Type(psb_lc_coo_sparse_mat),Intent(inout) :: a
+ Type(psb_lc_coo_sparse_mat),Intent(inout) :: b
+ Type(psb_desc_type), Intent(inout) :: desc_a
+ integer(psb_ipk_), intent(out) :: info
+
+ ! ...local scalars....
+ type(psb_ctxt_type) :: ctxt
+ integer(psb_ipk_) :: np,me
+ integer(psb_ipk_) :: counter, proc, i, n_el_send,n_el_recv, &
+ & n_elem, j, ipx,idxs,idxr
+ integer(psb_lpk_) :: r, k, irmin, irmax, icmin, icmax, iszs, iszr, &
+ & lidx, l1, lnr, lnc, lnnz, idx, ngtz, tot_elem
+ integer(psb_lpk_) :: nz,nouth
+ integer(psb_ipk_) :: nrcvs, nsnds
+ integer(psb_mpk_) :: icomm, minfo
+ integer(psb_mpk_), allocatable :: brvindx(:), &
+ & rvsz(:), bsdindx(:),sdsz(:), sdsi(:), rvsi(:)
+ integer(psb_lpk_), allocatable :: iasnd(:), jasnd(:)
+ complex(psb_spk_), allocatable :: valsnd(:)
+ type(psb_lc_coo_sparse_mat), allocatable :: acoo
+ class(psb_i_base_vect_type), pointer :: pdxv
+ integer(psb_ipk_), allocatable :: ila(:), iprc(:)
+ logical :: rowcnv_,colcnv_,rowscale_,colscale_
+ character(len=5) :: outfmt_
+ integer(psb_ipk_) :: debug_level, debug_unit, err_act
+ character(len=20) :: name, ch_err
+
+ info=psb_success_
+ name='psb_c_remote_mat'
+ call psb_erractionsave(err_act)
+ if (psb_errstatus_fatal()) then
+ info = psb_err_internal_error_ ; goto 9999
+ end if
+ debug_unit = psb_get_debug_unit()
+ debug_level = psb_get_debug_level()
+
+ ctxt = desc_a%get_context()
+ icomm = desc_a%get_mpic()
+
+ Call psb_info(ctxt, me, np)
+
+ if (debug_level >= psb_debug_outer_) &
+ & write(debug_unit,*) me,' ',trim(name),': Start'
+
+
+ call b%free()
+
+ Allocate(rvsz(np),sdsz(np),sdsi(np),rvsi(np),brvindx(np+1),&
+ & bsdindx(np+1), acoo,stat=info)
+
+ if (info /= psb_success_) then
+ info=psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+
+
+ nz = a%get_nzeros()
+ !allocate(ila(nz))
+ !write(0,*) me,name,' size :',nz,size(ila)
+ !call desc_a%g2l(a%ia(1:nz),ila(1:nz),info,owned=.false.)
+ !nouth = count(ila(1:nz)<0)
+ !write(0,*) me,name,' Count out of halo :',nouth
+ !call psb_max(ctxt,nouth)
+ !if ((nouth/=0).and.(me==0)) &
+ ! & write(0,*) 'Warning: would require reinit of DESC_A'
+
+ call desc_a%indxmap%fnd_owner(a%ia(1:nz),iprc,info)
+
+ icomm = desc_a%get_mpic()
+ sdsz(:)=0
+ rvsz(:)=0
+ sdsi(:)=0
+ rvsi(:)=0
+ ipx = 1
+ brvindx(:) = 0
+ bsdindx(:) = 0
+ counter=1
+ idx = 0
+ idxs = 0
+ idxr = 0
+ do i=1,nz
+ if (iprc(i) >=0) then
+ sdsz(iprc(i)+1) = sdsz(iprc(i)+1) +1
+ else
+ write(0,*)me,name,' Error from fnd_owner: ',iprc(i)
+ end if
+ end do
+ call mpi_alltoall(sdsz,1,psb_mpi_mpk_,&
+ & rvsz,1,psb_mpi_mpk_,icomm,minfo)
+ if (minfo /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='mpi_alltoall')
+ goto 9999
+ end if
+ !write(0,*)me,name,' sdsz ',sdsz(:),' rvsz:',rvsz(:)
+ nsnds = count(sdsz /= 0)
+ nrcvs = count(rvsz /= 0)
+ idxs = 0
+ idxr = 0
+ counter = 1
+ Do proc=0,np-1
+ bsdindx(proc+1) = idxs
+ idxs = idxs + sdsz(proc+1)
+ brvindx(proc+1) = idxr
+ idxr = idxr + rvsz(proc+1)
+ Enddo
+
+ iszs = sum(sdsz)
+ iszr = sum(rvsz)
+ call acoo%allocate(desc_a%get_global_rows(),desc_a%get_global_cols(),iszr)
+ if (psb_errstatus_fatal()) then
+ write(0,*) 'Error from acoo%allocate '
+ info = 4010
+ goto 9999
+ end if
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Sizes:',acoo%get_size(),&
+ & ' Send:',sdsz(:),' Receive:',rvsz(:)
+ !write(debug_unit,*) me,' ',trim(name),': ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),iasnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' iasnd: ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),jasnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' jasnd: ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),valsnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' valsnd: ',info
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='ensure_size')
+ goto 9999
+ end if
+ do k=1, nz
+ proc = iprc(k)
+ sdsi(proc+1) = sdsi(proc+1) + 1
+ !rvsi(proc) = rvsi(proc) + 1
+ iasnd(bsdindx(proc+1)+sdsi(proc+1)) = a%ia(k)
+ jasnd(bsdindx(proc+1)+sdsi(proc+1)) = a%ja(k)
+ valsnd(bsdindx(proc+1)+sdsi(proc+1)) = a%val(k)
+ end do
+ do proc=0,np-1
+ if (sdsi(proc+1) /= sdsz(proc+1)) &
+ & write(0,*) me,name,'Send mismacth ',sdsi(proc+1),sdsz(proc+1)
+ end do
+
+ select case(psb_get_sp_a2av_alg())
+ case(psb_sp_a2av_smpl_triad_)
+ call psb_simple_triad_a2av(valsnd,iasnd,jasnd,sdsz,bsdindx,&
+ & acoo%val,acoo%ia,acoo%ja,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_smpl_v_)
+ call psb_simple_a2av(valsnd,sdsz,bsdindx,&
+ & acoo%val,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(iasnd,sdsz,bsdindx,&
+ & acoo%ia,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(jasnd,sdsz,bsdindx,&
+ & acoo%ja,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_mpi_)
+
+ call mpi_alltoallv(valsnd,sdsz,bsdindx,psb_mpi_c_spk_,&
+ & acoo%val,rvsz,brvindx,psb_mpi_c_spk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(iasnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & acoo%ia,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(jasnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & acoo%ja,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo /= mpi_success) info = minfo
+ case default
+ info = psb_err_internal_error_
+ call psb_errpush(info,name,a_err='wrong A2AV alg selector')
+ goto 9999
+ end select
+
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='alltoallv')
+ goto 9999
+ end if
+ call acoo%set_nzeros(iszr)
+ call acoo%mv_to_coo(b,info)
+
+ Deallocate(brvindx,bsdindx,rvsz,sdsz,&
+ & iasnd,jasnd,valsnd,stat=info)
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Done'
+
+ call psb_erractionrestore(err_act)
+ return
+
+9999 call psb_error_handler(ctxt,err_act)
+
+ return
+
+End Subroutine psb_lc_remote_mat
+
+
+subroutine psb_c_remote_vect(n,v,iv,desc_a,x,ix, info)
+ use psb_base_mod, psb_protect_name => psb_c_remote_vect
+
+#ifdef MPI_MOD
+ use mpi
+#endif
+ Implicit None
+#ifdef MPI_H
+ include 'mpif.h'
+#endif
+ integer(psb_ipk_), intent(in) :: n
+ complex(psb_spk_), Intent(in) :: v(:)
+ integer(psb_lpk_), Intent(in) :: iv(:)
+ type(psb_desc_type),intent(in) :: desc_a
+ complex(psb_spk_), allocatable, intent(out) :: x(:)
+ integer(psb_lpk_), allocatable, intent(out) :: ix(:)
+ integer(psb_ipk_), intent(out) :: info
+ ! ...local scalars....
+ type(psb_ctxt_type) :: ctxt
+ integer(psb_ipk_) :: np,me
+ integer(psb_ipk_) :: counter, proc, i, &
+ & j, idxs,idxr, k, iszs, iszr
+ integer(psb_ipk_) :: nrcvs, nsnds
+ integer(psb_mpk_) :: icomm, minfo
+ integer(psb_mpk_), allocatable :: brvindx(:), &
+ & rvsz(:), bsdindx(:), sdsz(:), sdsi(:), rvsi(:)
+ integer(psb_lpk_), allocatable :: lsnd(:)
+ complex(psb_spk_), allocatable :: valsnd(:)
+ integer(psb_ipk_), allocatable :: iprc(:)
+ integer(psb_ipk_) :: debug_level, debug_unit, err_act
+ character(len=20) :: name, ch_err
+
+ info=psb_success_
+ name='psb_c_remote_vect'
+ call psb_erractionsave(err_act)
+ if (psb_errstatus_fatal()) then
+ info = psb_err_internal_error_ ; goto 9999
+ end if
+ debug_unit = psb_get_debug_unit()
+ debug_level = psb_get_debug_level()
+
+ ctxt = desc_a%get_context()
+ icomm = desc_a%get_mpic()
+
+ Call psb_info(ctxt, me, np)
+
+ if (debug_level >= psb_debug_outer_) &
+ & write(debug_unit,*) me,' ',trim(name),': Start'
+
+ Allocate(rvsz(np),sdsz(np),sdsi(np),rvsi(np),brvindx(np+1),&
+ & bsdindx(np+1), stat=info)
+
+ if (info /= psb_success_) then
+ info=psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+
+ call desc_a%indxmap%fnd_owner(iv(1:n),iprc,info)
+
+ icomm = desc_a%get_mpic()
+ sdsz(:) = 0
+ rvsz(:) = 0
+ sdsi(:) = 0
+ rvsi(:) = 0
+ brvindx(:) = 0
+ bsdindx(:) = 0
+ counter = 1
+ idxs = 0
+ idxr = 0
+ do i=1,n
+ if (iprc(i) >=0) then
+ sdsz(iprc(i)+1) = sdsz(iprc(i)+1) +1
+ else
+ write(0,*)me,name,' Error from fnd_owner: ',iprc(i)
+ end if
+ end do
+ call mpi_alltoall(sdsz,1,psb_mpi_mpk_,&
+ & rvsz,1,psb_mpi_mpk_,icomm,minfo)
+ if (minfo /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='mpi_alltoall')
+ goto 9999
+ end if
+ !write(0,*)me,name,' sdsz ',sdsz(:),' rvsz:',rvsz(:)
+ nsnds = count(sdsz /= 0)
+ nrcvs = count(rvsz /= 0)
+ idxs = 0
+ idxr = 0
+ counter = 1
+ Do proc=0,np-1
+ bsdindx(proc+1) = idxs
+ idxs = idxs + sdsz(proc+1)
+ brvindx(proc+1) = idxr
+ idxr = idxr + rvsz(proc+1)
+ Enddo
+
+ iszs = sum(sdsz)
+ iszr = sum(rvsz)
+ call psb_realloc(iszs,lsnd,info)
+ if (info == 0) call psb_realloc(iszs,valsnd,info)
+ if (info == 0) call psb_realloc(iszr,x,info)
+ if (info == 0) call psb_realloc(iszr,ix,info)
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='realloc')
+ goto 9999
+ end if
+ do k=1, n
+ proc = iprc(k)
+ sdsi(proc+1) = sdsi(proc+1) + 1
+ lsnd(bsdindx(proc+1)+sdsi(proc+1)) = iv(k)
+ valsnd(bsdindx(proc+1)+sdsi(proc+1)) = v(k)
+ end do
+ do proc=0,np-1
+ if (sdsi(proc+1) /= sdsz(proc+1)) &
+ & write(0,*) me,name,'Send mismacth ',sdsi(proc+1),sdsz(proc+1)
+ end do
+
+ select case(psb_get_sp_a2av_alg())
+ case(psb_sp_a2av_smpl_triad_,psb_sp_a2av_smpl_v_)
+ call psb_simple_a2av(valsnd,sdsz,bsdindx,&
+ & x,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(lsnd,sdsz,bsdindx,&
+ & ix,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_mpi_)
+
+ call mpi_alltoallv(valsnd,sdsz,bsdindx,psb_mpi_c_spk_,&
+ & x,rvsz,brvindx,psb_mpi_c_spk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(lsnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & ix,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo /= mpi_success) info = minfo
+ case default
+ info = psb_err_internal_error_
+ call psb_errpush(info,name,a_err='wrong A2AV alg selector')
+ goto 9999
+ end select
+
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='alltoallv')
+ goto 9999
+ end if
+
+ Deallocate(brvindx,bsdindx,rvsz,sdsz,&
+ & lsnd,valsnd,stat=info)
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Done'
+
+ call psb_erractionrestore(err_act)
+ return
+
+9999 call psb_error_handler(ctxt,err_act)
+
+ return
+
+End Subroutine psb_c_remote_vect
diff --git a/base/tools/psb_callc.f90 b/base/tools/psb_callc.f90
index 530a43a2..272ece8b 100644
--- a/base/tools/psb_callc.f90
+++ b/base/tools/psb_callc.f90
@@ -40,7 +40,7 @@
! x - the vector to be allocated.
! desc_a - the communication descriptor.
! info - Return code
-subroutine psb_calloc_vect(x, desc_a,info)
+subroutine psb_calloc_vect(x, desc_a,info, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_calloc_vect
use psi_mod
implicit none
@@ -49,9 +49,11 @@ subroutine psb_calloc_vect(x, desc_a,info)
type(psb_c_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
integer(psb_ipk_) :: np,me,nr,i,err_act
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -102,6 +104,25 @@ subroutine psb_calloc_vect(x, desc_a,info)
endif
call x%zero()
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ call x%set_nrmv(0)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ call psb_ensure_size(nrmt_,x%rmtv,info)
+ call psb_ensure_size(nrmt_,x%rmidx,info)
+ end if
+
call psb_erractionrestore(err_act)
return
@@ -110,6 +131,7 @@ subroutine psb_calloc_vect(x, desc_a,info)
return
end subroutine psb_calloc_vect
+
! Function: psb_calloc_vect_r2
! Allocates a vector of dense vectors for PSBLAS routines.
! The descriptor may be in either the build or assembled state.
@@ -121,7 +143,7 @@ end subroutine psb_calloc_vect
! n - optional number of columns.
! lb - optional lower bound on column indices
-subroutine psb_calloc_vect_r2(x, desc_a,info,n,lb)
+subroutine psb_calloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_calloc_vect_r2
use psi_mod
implicit none
@@ -131,10 +153,12 @@ subroutine psb_calloc_vect_r2(x, desc_a,info,n,lb)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n,lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -208,6 +232,26 @@ subroutine psb_calloc_vect_r2(x, desc_a,info,n,lb)
if (info /= 0) exit
end do
end if
+
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+
+ do i=lb_, lb_+n_-1
+ call x(i)%set_dupl(dupl_)
+ call x(i)%set_remote_build(bldmode_)
+ if (x(i)%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x(i)%rmtv(nrmt_))
+ end if
+ end do
if (psb_errstatus_fatal()) then
info=psb_err_alloc_request_
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
@@ -224,7 +268,7 @@ subroutine psb_calloc_vect_r2(x, desc_a,info,n,lb)
end subroutine psb_calloc_vect_r2
-subroutine psb_calloc_multivect(x, desc_a,info,n)
+subroutine psb_calloc_multivect(x, desc_a,info,n, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_calloc_multivect
use psi_mod
implicit none
@@ -234,10 +278,12 @@ subroutine psb_calloc_multivect(x, desc_a,info,n)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -306,6 +352,23 @@ subroutine psb_calloc_multivect(x, desc_a,info,n)
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
goto 9999
endif
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x%rmtv(nrmt_,n_))
+ end if
+
call psb_erractionrestore(err_act)
return
diff --git a/base/tools/psb_casb.f90 b/base/tools/psb_casb.f90
index de2e3890..d43b062c 100644
--- a/base/tools/psb_casb.f90
+++ b/base/tools/psb_casb.f90
@@ -64,7 +64,7 @@ subroutine psb_casb_vect(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -83,7 +83,7 @@ subroutine psb_casb_vect(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
+ dupl_ = x%get_dupl()
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -104,6 +104,23 @@ subroutine psb_casb_vect(x, desc_a, info, mold, scratch)
call x%free(info)
call x%bld(ncol,mold=mold)
else
+
+ if (x%is_remote_build()) then
+ block
+ integer(psb_lpk_), allocatable :: lvx(:)
+ complex(psb_spk_), allocatable :: vx(:)
+ integer(psb_ipk_), allocatable :: ivx(:)
+ integer(psb_ipk_) :: nrmv, nx, i
+
+ nrmv = x%get_nrmv()
+ call psb_c_remote_vect(nrmv,x%rmtv,x%rmidx,desc_a,vx,lvx,info)
+ nx = size(vx)
+ call psb_realloc(nx,ivx,info)
+ call desc_a%g2l(lvx,ivx,info,owned=.true.)
+ call x%ins(nx,ivx,vx,info)
+ end block
+ end if
+
call x%asb(ncol,info)
! ..update halo elements..
call psb_halo(x,desc_a,info)
@@ -140,7 +157,7 @@ subroutine psb_casb_vect_r2(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, i, n
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -159,7 +176,6 @@ subroutine psb_casb_vect_r2(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -185,6 +201,7 @@ subroutine psb_casb_vect_r2(x, desc_a, info, mold, scratch)
else
do i=1, n
+ dupl_ = x(i)%get_dupl()
call x(i)%asb(ncol,info)
if (info /= 0) exit
! ..update halo elements..
@@ -225,7 +242,7 @@ subroutine psb_casb_multivect(x, desc_a, info, mold, scratch,n)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
@@ -271,6 +288,7 @@ subroutine psb_casb_multivect(x, desc_a, info, mold, scratch,n)
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': sizes: ',nrow,ncol
+ dupl_ = x%get_dupl()
if (scratch_) then
call x%free(info)
call x%bld(ncol,n_,mold=mold)
diff --git a/base/tools/psb_cins.f90 b/base/tools/psb_cins.f90
index e874c315..180520a3 100644
--- a/base/tools/psb_cins.f90
+++ b/base/tools/psb_cins.f90
@@ -42,10 +42,7 @@
! x - type(psb_c_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_cins_vect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_cins_vect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_cins_vect
use psi_mod
implicit none
@@ -57,14 +54,14 @@ subroutine psb_cins_vect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_c_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
+ integer(psb_ipk_) :: dupl_
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_,err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -112,7 +109,6 @@ subroutine psb_cins_vect(m, irw, val, x, desc_a, info, dupl,local)
endif
-
allocate(irl(m),stat=info)
if (info /= psb_success_) then
info = psb_err_alloc_dealloc_
@@ -120,11 +116,6 @@ subroutine psb_cins_vect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -136,11 +127,33 @@ subroutine psb_cins_vect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
end if
+ if (x%is_remote_build()) then
+ block
+ integer(psb_ipk_) :: j,k
+ k = x%get_nrmv()
+ do j=1,m
+ if (irl(j) < 0 ) then
+ k = k + 1
+ call psb_ensure_size(k,x%rmtv,info)
+ if (info == 0) call psb_ensure_size(k,x%rmidx,info)
+ if (info /= 0) then
+ info = psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+ x%rmtv(k) = val(j)
+ x%rmidx(k) = irw(j)
+ call x%set_nrmv(k)
+ end if
+ end do
+ end block
+ end if
+
deallocate(irl)
call psb_erractionrestore(err_act)
@@ -166,10 +179,7 @@ end subroutine psb_cins_vect
! x - type(psb_c_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_cins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_cins_vect_v(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_cins_vect_v
use psi_mod
implicit none
@@ -185,14 +195,13 @@ subroutine psb_cins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
type(psb_c_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols,err_act
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_
+ integer(psb_ipk_) :: np, me
integer(psb_ipk_), allocatable :: irl(:)
complex(psb_spk_), allocatable :: lval(:)
logical :: local_
@@ -239,14 +248,6 @@ subroutine psb_cins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call psb_errpush(info,name)
goto 9999
endif
-
-
-
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -260,7 +261,7 @@ subroutine psb_cins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call desc_a%indxmap%g2l(irw%v%v(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,lval,dupl_,info)
+ call x%ins(m,irl,lval,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
@@ -275,7 +276,7 @@ subroutine psb_cins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_cins_vect_v
-subroutine psb_cins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_cins_vect_r2(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_cins_vect_r2
use psi_mod
implicit none
@@ -291,14 +292,13 @@ subroutine psb_cins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
type(psb_c_vect_type), intent(inout) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols, n
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -353,11 +353,6 @@ subroutine psb_cins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -371,8 +366,9 @@ subroutine psb_cins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end if
do i=1,n
+
if (.not.allocated(x(i)%v)) info = psb_err_invalid_vect_state_
- if (info == 0) call x(i)%ins(m,irl,val(:,i),dupl_,info)
+ if (info == 0) call x(i)%ins(m,irl,val(:,i),info)
if (info /= 0) exit
end do
if (info /= 0) then
@@ -390,7 +386,7 @@ subroutine psb_cins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_cins_vect_r2
-subroutine psb_cins_multivect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_cins_multivect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_cins_multivect
use psi_mod
implicit none
@@ -406,14 +402,13 @@ subroutine psb_cins_multivect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_c_multivect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -469,11 +464,6 @@ subroutine psb_cins_multivect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -485,7 +475,7 @@ subroutine psb_cins_multivect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
diff --git a/base/tools/psb_cspalloc.f90 b/base/tools/psb_cspalloc.f90
index 69b9e1c2..7bec040c 100644
--- a/base/tools/psb_cspalloc.f90
+++ b/base/tools/psb_cspalloc.f90
@@ -41,21 +41,23 @@
! nnz - integer(optional). The number of nonzeroes in the matrix.
! (local, user estimate)
!
-subroutine psb_cspalloc(a, desc_a, info, nnz)
+subroutine psb_cspalloc(a, desc_a, info, nnz, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_cspalloc
implicit none
!....parameters...
- type(psb_desc_type), intent(in) :: desc_a
- type(psb_cspmat_type), intent(inout) :: a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: nnz
+ type(psb_desc_type), intent(in) :: desc_a
+ type(psb_cspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: nnz
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_) :: loc_row,loc_col, nnz_, dectype
- integer(psb_lpk_) :: m, n
+ integer(psb_ipk_) :: dupl_, bldmode_
+ integer(psb_lpk_) :: m, n, nnzrmt_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -96,7 +98,7 @@ subroutine psb_cspalloc(a, desc_a, info, nnz)
else
nnz_ = max(1,5*loc_row)
endif
-
+
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name), &
& ':allocating size:',loc_row,loc_col,nnz_
@@ -109,6 +111,24 @@ subroutine psb_cspalloc(a, desc_a, info, nnz)
goto 9999
end if
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call a%set_dupl(dupl_)
+ call a%set_remote_build(bldmode_)
+ if (a%is_remote_build()) then
+ allocate(a%rmta)
+ nnzrmt_ = max(100,(nnz_/100))
+ call a%rmta%allocate(m,n,nnzrmt_)
+ end if
+
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': ', &
& desc_a%get_dectype(),psb_desc_bld_
diff --git a/base/tools/psb_cspasb.f90 b/base/tools/psb_cspasb.f90
index 96ed7fe7..0c5f14ab 100644
--- a/base/tools/psb_cspasb.f90
+++ b/base/tools/psb_cspasb.f90
@@ -42,31 +42,29 @@
! upd - character(optional). How will the matrix be updated?
! psb_upd_srch_ Simple strategy
! psb_upd_perm_ Permutation(more memory)
-! dupl - integer(optional). Duplicate coefficient handling:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-! psb_dupl_err_ raise an error.
!
!
-subroutine psb_cspasb(a,desc_a, info, afmt, upd, dupl, mold)
+subroutine psb_cspasb(a,desc_a, info, afmt, upd, mold)
use psb_base_mod, psb_protect_name => psb_cspasb
+ use psb_sort_mod
use psi_mod
implicit none
!...Parameters....
- type(psb_cspmat_type), intent (inout) :: a
- type(psb_desc_type), intent(in) :: desc_a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_),optional, intent(in) :: dupl, upd
- character(len=*), optional, intent(in) :: afmt
+ type(psb_cspmat_type), intent (inout) :: a
+ type(psb_desc_type), intent(inout) :: desc_a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: upd
+ character(len=*), optional, intent(in) :: afmt
class(psb_c_base_sparse_mat), intent(in), optional :: mold
!....Locals....
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, err_act
- integer(psb_ipk_) :: n_row,n_col
+ integer(psb_ipk_) :: n_row,n_col, dupl_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name, ch_err
+ class(psb_i_base_vect_type), allocatable :: ivm
info = psb_success_
name = 'psb_spasb'
@@ -92,28 +90,79 @@ subroutine psb_cspasb(a,desc_a, info, afmt, upd, dupl, mold)
goto 9999
end if
-
if (debug_level >= psb_debug_ext_)&
& write(debug_unit, *) me,' ',trim(name),&
& ' Begin matrix assembly...'
!check on errors encountered in psdspins
-
- if (a%is_bld()) then
+ if (a%is_bld()) then
+ dupl_ = a%get_dupl()
!
! First case: we come from a fresh build.
!
-
- n_row = desc_a%get_local_rows()
- n_col = desc_a%get_local_cols()
- call a%set_nrows(n_row)
- call a%set_ncols(n_col)
- end if
-
- if (a%is_bld()) then
- call a%cscnv(info,type=afmt,dupl=dupl, mold=mold)
+ if (a%is_remote_build()) then
+ !write(0,*) me,name,' Size of rmta:',a%rmta%get_nzeros()
+ block
+ type(psb_lc_coo_sparse_mat) :: a_add
+ integer(psb_ipk_), allocatable :: ila(:), jla(:)
+ integer(psb_ipk_) :: nz, nzt,k
+ call psb_remote_mat(a%rmta,desc_a,a_add,info)
+ nz = a_add%get_nzeros()
+ nzt = nz
+ call psb_sum(ctxt,nzt)
+ if (nzt>0) then
+ allocate(ivm, mold=desc_a%v_halo_index%v)
+ call psb_cd_reinit(desc_a, info)
+ end if
+ if (nz > 0) then
+ !
+ ! Should we check for new indices here?
+ !
+ call psb_realloc(nz,ila,info)
+ call psb_realloc(nz,jla,info)
+ call desc_a%indxmap%g2l(a_add%ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l_ins(a_add%ja(1:nz),jla(1:nz),info)
+ !write(0,*) me,name,' Check before insert',a%get_nzeros()
+ n_row = desc_a%get_local_rows()
+ n_col = desc_a%get_local_cols()
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%csput(nz,ila,jla,a_add%val,ione,n_row,ione,n_col,info)
+ !write(0,*) me,name,' Check after insert',a%get_nzeros(),nz
+ end if
+ if (nzt > 0) call psb_cdasb(desc_a,info,mold=ivm)
+
+ end block
+ end if
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%cscnv(info,type=afmt,mold=mold,dupl=dupl_)
else if (a%is_upd()) then
+ if (a%is_remote_build()) then
+ !write(0,*) me,name,' Size of rmta:',a%rmta%get_nzeros()
+ block
+ type(psb_lc_coo_sparse_mat) :: a_add
+ integer(psb_ipk_), allocatable :: ila(:), jla(:)
+ integer(psb_ipk_) :: nz, nzt,k
+ call psb_remote_mat(a%rmta,desc_a,a_add,info)
+ nz = a_add%get_nzeros()
+!!$ write(0,*) me,name,' Nz to be added',nz
+ if (nz > 0) then
+ !
+ ! Should we check for new indices here?
+ !
+ call psb_realloc(nz,ila,info)
+ call psb_realloc(nz,jla,info)
+ call desc_a%indxmap%g2l(a_add%ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l_ins(a_add%ja(1:nz),jla(1:nz),info)
+ !write(0,*) me,name,' Check before insert',a%get_nzeros()
+ n_row = desc_a%get_local_rows()
+ n_col = desc_a%get_local_cols()
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%csput(nz,ila,jla,a_add%val,ione,n_row,ione,n_col,info)
+ !write(0,*) me,name,' Check after insert',a%get_nzeros(),nz
+ end if
+ end block
+ end if
call a%asb(mold=mold)
else
info = psb_err_invalid_mat_state_
diff --git a/base/tools/psb_cspins.F90 b/base/tools/psb_cspins.F90
index 15ea556f..27cfbd8e 100644
--- a/base/tools/psb_cspins.F90
+++ b/base/tools/psb_cspins.F90
@@ -70,6 +70,10 @@ subroutine psb_cspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
integer(psb_ipk_), parameter :: relocsz=200
logical :: rebuild_, local_
integer(psb_ipk_), allocatable :: ila(:),jla(:)
+ integer(psb_ipk_) :: i,k
+ integer(psb_lpk_) :: nnl
+ integer(psb_lpk_), allocatable :: lila(:),ljla(:)
+ complex(psb_spk_), allocatable :: lval(:)
character(len=20) :: name
info = psb_success_
@@ -147,6 +151,27 @@ subroutine psb_cspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
call psb_errpush(info,name,a_err='a%csput')
goto 9999
end if
+
+ if (a%is_remote_build()) then
+ nnl = count(ila(1:nz)<0)
+ if (nnl > 0) then
+ !write(0,*) 'Check on insert ',nnl
+ allocate(lila(nnl),ljla(nnl),lval(nnl))
+ k = 0
+ do i=1,nz
+ if (ila(i)<0) then
+ k=k+1
+ lila(k) = ia(i)
+ ljla(k) = ja(i)
+ lval(k) = val(i)
+ end if
+ end do
+ if (k /= nnl) write(0,*) name,' Wrong conversion?',k,nnl
+ call a%rmta%csput(nnl,lila,ljla,lval,1_psb_lpk_,desc_a%get_global_rows(),&
+ & 1_psb_lpk_,desc_a%get_global_rows(),info)
+ end if
+ end if
+
else
info = psb_err_invalid_a_and_cd_state_
call psb_errpush(info,name)
@@ -168,8 +193,9 @@ subroutine psb_cspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
ila(1:nz) = ia(1:nz)
jla(1:nz) = ja(1:nz)
else
- call desc_a%indxmap%g2l(ia(1:nz),ila(1:nz),info)
- if (info == 0) call desc_a%indxmap%g2l(ja(1:nz),jla(1:nz),info)
+ call desc_a%indxmap%g2l(ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l(ja(1:nz),jla(1:nz),info,&
+ & mask=(ila(1:nz)>0))
end if
call a%csput(nz,ila,jla,val,ione,nrow,ione,ncol,info)
if (info /= psb_success_) then
@@ -177,6 +203,25 @@ subroutine psb_cspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
call psb_errpush(info,name,a_err='a%csput')
goto 9999
end if
+ if (a%is_remote_build()) then
+ nnl = count(ila(1:nz)<0)
+ if (nnl > 0) then
+ !write(0,*) 'Check on insert ',nnl
+ allocate(lila(nnl),ljla(nnl),lval(nnl))
+ k = 0
+ do i=1,nz
+ if (ila(i)<0) then
+ k=k+1
+ lila(k) = ia(k)
+ ljla(k) = ja(k)
+ lval(k) = val(k)
+ end if
+ end do
+ if (k /= nnl) write(0,*) name,' Wrong conversion?',k,nnl
+ call a%rmta%csput(nnl,lila,ljla,lval,1_psb_lpk_,desc_a%get_global_rows(),&
+ & 1_psb_lpk_,desc_a%get_global_rows(),info)
+ end if
+ end if
else
info = psb_err_invalid_cd_state_
call psb_errpush(info,name)
diff --git a/base/tools/psb_d_remote_mat.F90 b/base/tools/psb_d_remote_mat.F90
new file mode 100644
index 00000000..a5f12755
--- /dev/null
+++ b/base/tools/psb_d_remote_mat.F90
@@ -0,0 +1,436 @@
+!
+! 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.
+!
+!
+! File: psb_d_remote_mat.f90
+!
+! Subroutine:
+! This routine does the retrieval of remote matrix rows.
+! Retrieval is done through GETROW, therefore it should work
+! for any matrix format in A; as for the output, default is CSR.
+!
+! There is also a specialized version ld_CSR whose interface
+! is adapted for the needs of d_par_csr_spspmm.
+!
+! There are three possible exchange algorithms:
+! 1. Use MPI_Alltoallv
+! 2. Use psb_simple_a2av
+! 3. Use psb_simple_triad_a2av
+! Default choice is 3. The MPI variant has proved to be inefficient;
+! that is because it is not persistent, therefore you pay the initialization price
+! every time, and it is not optimized for a sparse communication pattern,
+! most MPI implementations assume that all communications are non-empty.
+! The PSB_SIMPLE variants reuse the same communicator, and go for a simplistic
+! sequence of sends/receive that is quite efficient for a sparse communication
+! pattern. To be refined/reviewed in the future to compare with neighbour
+! persistent collectives.
+!
+! Arguments:
+! a - type(psb_dspmat_type) The local part of input matrix A
+! desc_a - type(psb_desc_type). The communication descriptor.
+! blck - type(psb_dspmat_type) The local part of output matrix BLCK
+! info - integer. Return code
+! rowcnv - logical Should row/col indices be converted
+! colcnv - logical to/from global numbering when sent/received?
+! default is .TRUE.
+! rowscale - logical Should row/col indices on output be remapped
+! colscale - logical from MIN:MAX to 1:(MAX-MIN+1) ?
+! default is .FALSE.
+! (commmon use is ROWSCALE=.TRUE., COLSCALE=.FALSE.)
+! data - integer Which index list in desc_a should be used to retrieve
+! rows, default psb_comm_halo_
+! psb_comm_halo_ use halo_index
+! psb_comm_ext_ use ext_index
+! psb_comm_ovrl_ DISABLED for this routine.
+!
+Subroutine psb_ld_remote_mat(a,desc_a,b,info)
+ use psb_base_mod, psb_protect_name => psb_ld_remote_mat
+
+#ifdef MPI_MOD
+ use mpi
+#endif
+ Implicit None
+#ifdef MPI_H
+ include 'mpif.h'
+#endif
+
+ Type(psb_ld_coo_sparse_mat),Intent(inout) :: a
+ Type(psb_ld_coo_sparse_mat),Intent(inout) :: b
+ Type(psb_desc_type), Intent(inout) :: desc_a
+ integer(psb_ipk_), intent(out) :: info
+
+ ! ...local scalars....
+ type(psb_ctxt_type) :: ctxt
+ integer(psb_ipk_) :: np,me
+ integer(psb_ipk_) :: counter, proc, i, n_el_send,n_el_recv, &
+ & n_elem, j, ipx,idxs,idxr
+ integer(psb_lpk_) :: r, k, irmin, irmax, icmin, icmax, iszs, iszr, &
+ & lidx, l1, lnr, lnc, lnnz, idx, ngtz, tot_elem
+ integer(psb_lpk_) :: nz,nouth
+ integer(psb_ipk_) :: nrcvs, nsnds
+ integer(psb_mpk_) :: icomm, minfo
+ integer(psb_mpk_), allocatable :: brvindx(:), &
+ & rvsz(:), bsdindx(:),sdsz(:), sdsi(:), rvsi(:)
+ integer(psb_lpk_), allocatable :: iasnd(:), jasnd(:)
+ real(psb_dpk_), allocatable :: valsnd(:)
+ type(psb_ld_coo_sparse_mat), allocatable :: acoo
+ class(psb_i_base_vect_type), pointer :: pdxv
+ integer(psb_ipk_), allocatable :: ila(:), iprc(:)
+ logical :: rowcnv_,colcnv_,rowscale_,colscale_
+ character(len=5) :: outfmt_
+ integer(psb_ipk_) :: debug_level, debug_unit, err_act
+ character(len=20) :: name, ch_err
+
+ info=psb_success_
+ name='psb_d_remote_mat'
+ call psb_erractionsave(err_act)
+ if (psb_errstatus_fatal()) then
+ info = psb_err_internal_error_ ; goto 9999
+ end if
+ debug_unit = psb_get_debug_unit()
+ debug_level = psb_get_debug_level()
+
+ ctxt = desc_a%get_context()
+ icomm = desc_a%get_mpic()
+
+ Call psb_info(ctxt, me, np)
+
+ if (debug_level >= psb_debug_outer_) &
+ & write(debug_unit,*) me,' ',trim(name),': Start'
+
+
+ call b%free()
+
+ Allocate(rvsz(np),sdsz(np),sdsi(np),rvsi(np),brvindx(np+1),&
+ & bsdindx(np+1), acoo,stat=info)
+
+ if (info /= psb_success_) then
+ info=psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+
+
+ nz = a%get_nzeros()
+ !allocate(ila(nz))
+ !write(0,*) me,name,' size :',nz,size(ila)
+ !call desc_a%g2l(a%ia(1:nz),ila(1:nz),info,owned=.false.)
+ !nouth = count(ila(1:nz)<0)
+ !write(0,*) me,name,' Count out of halo :',nouth
+ !call psb_max(ctxt,nouth)
+ !if ((nouth/=0).and.(me==0)) &
+ ! & write(0,*) 'Warning: would require reinit of DESC_A'
+
+ call desc_a%indxmap%fnd_owner(a%ia(1:nz),iprc,info)
+
+ icomm = desc_a%get_mpic()
+ sdsz(:)=0
+ rvsz(:)=0
+ sdsi(:)=0
+ rvsi(:)=0
+ ipx = 1
+ brvindx(:) = 0
+ bsdindx(:) = 0
+ counter=1
+ idx = 0
+ idxs = 0
+ idxr = 0
+ do i=1,nz
+ if (iprc(i) >=0) then
+ sdsz(iprc(i)+1) = sdsz(iprc(i)+1) +1
+ else
+ write(0,*)me,name,' Error from fnd_owner: ',iprc(i)
+ end if
+ end do
+ call mpi_alltoall(sdsz,1,psb_mpi_mpk_,&
+ & rvsz,1,psb_mpi_mpk_,icomm,minfo)
+ if (minfo /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='mpi_alltoall')
+ goto 9999
+ end if
+ !write(0,*)me,name,' sdsz ',sdsz(:),' rvsz:',rvsz(:)
+ nsnds = count(sdsz /= 0)
+ nrcvs = count(rvsz /= 0)
+ idxs = 0
+ idxr = 0
+ counter = 1
+ Do proc=0,np-1
+ bsdindx(proc+1) = idxs
+ idxs = idxs + sdsz(proc+1)
+ brvindx(proc+1) = idxr
+ idxr = idxr + rvsz(proc+1)
+ Enddo
+
+ iszs = sum(sdsz)
+ iszr = sum(rvsz)
+ call acoo%allocate(desc_a%get_global_rows(),desc_a%get_global_cols(),iszr)
+ if (psb_errstatus_fatal()) then
+ write(0,*) 'Error from acoo%allocate '
+ info = 4010
+ goto 9999
+ end if
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Sizes:',acoo%get_size(),&
+ & ' Send:',sdsz(:),' Receive:',rvsz(:)
+ !write(debug_unit,*) me,' ',trim(name),': ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),iasnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' iasnd: ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),jasnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' jasnd: ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),valsnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' valsnd: ',info
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='ensure_size')
+ goto 9999
+ end if
+ do k=1, nz
+ proc = iprc(k)
+ sdsi(proc+1) = sdsi(proc+1) + 1
+ !rvsi(proc) = rvsi(proc) + 1
+ iasnd(bsdindx(proc+1)+sdsi(proc+1)) = a%ia(k)
+ jasnd(bsdindx(proc+1)+sdsi(proc+1)) = a%ja(k)
+ valsnd(bsdindx(proc+1)+sdsi(proc+1)) = a%val(k)
+ end do
+ do proc=0,np-1
+ if (sdsi(proc+1) /= sdsz(proc+1)) &
+ & write(0,*) me,name,'Send mismacth ',sdsi(proc+1),sdsz(proc+1)
+ end do
+
+ select case(psb_get_sp_a2av_alg())
+ case(psb_sp_a2av_smpl_triad_)
+ call psb_simple_triad_a2av(valsnd,iasnd,jasnd,sdsz,bsdindx,&
+ & acoo%val,acoo%ia,acoo%ja,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_smpl_v_)
+ call psb_simple_a2av(valsnd,sdsz,bsdindx,&
+ & acoo%val,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(iasnd,sdsz,bsdindx,&
+ & acoo%ia,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(jasnd,sdsz,bsdindx,&
+ & acoo%ja,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_mpi_)
+
+ call mpi_alltoallv(valsnd,sdsz,bsdindx,psb_mpi_r_dpk_,&
+ & acoo%val,rvsz,brvindx,psb_mpi_r_dpk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(iasnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & acoo%ia,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(jasnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & acoo%ja,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo /= mpi_success) info = minfo
+ case default
+ info = psb_err_internal_error_
+ call psb_errpush(info,name,a_err='wrong A2AV alg selector')
+ goto 9999
+ end select
+
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='alltoallv')
+ goto 9999
+ end if
+ call acoo%set_nzeros(iszr)
+ call acoo%mv_to_coo(b,info)
+
+ Deallocate(brvindx,bsdindx,rvsz,sdsz,&
+ & iasnd,jasnd,valsnd,stat=info)
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Done'
+
+ call psb_erractionrestore(err_act)
+ return
+
+9999 call psb_error_handler(ctxt,err_act)
+
+ return
+
+End Subroutine psb_ld_remote_mat
+
+
+subroutine psb_d_remote_vect(n,v,iv,desc_a,x,ix, info)
+ use psb_base_mod, psb_protect_name => psb_d_remote_vect
+
+#ifdef MPI_MOD
+ use mpi
+#endif
+ Implicit None
+#ifdef MPI_H
+ include 'mpif.h'
+#endif
+ integer(psb_ipk_), intent(in) :: n
+ real(psb_dpk_), Intent(in) :: v(:)
+ integer(psb_lpk_), Intent(in) :: iv(:)
+ type(psb_desc_type),intent(in) :: desc_a
+ real(psb_dpk_), allocatable, intent(out) :: x(:)
+ integer(psb_lpk_), allocatable, intent(out) :: ix(:)
+ integer(psb_ipk_), intent(out) :: info
+ ! ...local scalars....
+ type(psb_ctxt_type) :: ctxt
+ integer(psb_ipk_) :: np,me
+ integer(psb_ipk_) :: counter, proc, i, &
+ & j, idxs,idxr, k, iszs, iszr
+ integer(psb_ipk_) :: nrcvs, nsnds
+ integer(psb_mpk_) :: icomm, minfo
+ integer(psb_mpk_), allocatable :: brvindx(:), &
+ & rvsz(:), bsdindx(:), sdsz(:), sdsi(:), rvsi(:)
+ integer(psb_lpk_), allocatable :: lsnd(:)
+ real(psb_dpk_), allocatable :: valsnd(:)
+ integer(psb_ipk_), allocatable :: iprc(:)
+ integer(psb_ipk_) :: debug_level, debug_unit, err_act
+ character(len=20) :: name, ch_err
+
+ info=psb_success_
+ name='psb_d_remote_vect'
+ call psb_erractionsave(err_act)
+ if (psb_errstatus_fatal()) then
+ info = psb_err_internal_error_ ; goto 9999
+ end if
+ debug_unit = psb_get_debug_unit()
+ debug_level = psb_get_debug_level()
+
+ ctxt = desc_a%get_context()
+ icomm = desc_a%get_mpic()
+
+ Call psb_info(ctxt, me, np)
+
+ if (debug_level >= psb_debug_outer_) &
+ & write(debug_unit,*) me,' ',trim(name),': Start'
+
+ Allocate(rvsz(np),sdsz(np),sdsi(np),rvsi(np),brvindx(np+1),&
+ & bsdindx(np+1), stat=info)
+
+ if (info /= psb_success_) then
+ info=psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+
+ call desc_a%indxmap%fnd_owner(iv(1:n),iprc,info)
+
+ icomm = desc_a%get_mpic()
+ sdsz(:) = 0
+ rvsz(:) = 0
+ sdsi(:) = 0
+ rvsi(:) = 0
+ brvindx(:) = 0
+ bsdindx(:) = 0
+ counter = 1
+ idxs = 0
+ idxr = 0
+ do i=1,n
+ if (iprc(i) >=0) then
+ sdsz(iprc(i)+1) = sdsz(iprc(i)+1) +1
+ else
+ write(0,*)me,name,' Error from fnd_owner: ',iprc(i)
+ end if
+ end do
+ call mpi_alltoall(sdsz,1,psb_mpi_mpk_,&
+ & rvsz,1,psb_mpi_mpk_,icomm,minfo)
+ if (minfo /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='mpi_alltoall')
+ goto 9999
+ end if
+ !write(0,*)me,name,' sdsz ',sdsz(:),' rvsz:',rvsz(:)
+ nsnds = count(sdsz /= 0)
+ nrcvs = count(rvsz /= 0)
+ idxs = 0
+ idxr = 0
+ counter = 1
+ Do proc=0,np-1
+ bsdindx(proc+1) = idxs
+ idxs = idxs + sdsz(proc+1)
+ brvindx(proc+1) = idxr
+ idxr = idxr + rvsz(proc+1)
+ Enddo
+
+ iszs = sum(sdsz)
+ iszr = sum(rvsz)
+ call psb_realloc(iszs,lsnd,info)
+ if (info == 0) call psb_realloc(iszs,valsnd,info)
+ if (info == 0) call psb_realloc(iszr,x,info)
+ if (info == 0) call psb_realloc(iszr,ix,info)
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='realloc')
+ goto 9999
+ end if
+ do k=1, n
+ proc = iprc(k)
+ sdsi(proc+1) = sdsi(proc+1) + 1
+ lsnd(bsdindx(proc+1)+sdsi(proc+1)) = iv(k)
+ valsnd(bsdindx(proc+1)+sdsi(proc+1)) = v(k)
+ end do
+ do proc=0,np-1
+ if (sdsi(proc+1) /= sdsz(proc+1)) &
+ & write(0,*) me,name,'Send mismacth ',sdsi(proc+1),sdsz(proc+1)
+ end do
+
+ select case(psb_get_sp_a2av_alg())
+ case(psb_sp_a2av_smpl_triad_,psb_sp_a2av_smpl_v_)
+ call psb_simple_a2av(valsnd,sdsz,bsdindx,&
+ & x,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(lsnd,sdsz,bsdindx,&
+ & ix,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_mpi_)
+
+ call mpi_alltoallv(valsnd,sdsz,bsdindx,psb_mpi_r_dpk_,&
+ & x,rvsz,brvindx,psb_mpi_r_dpk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(lsnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & ix,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo /= mpi_success) info = minfo
+ case default
+ info = psb_err_internal_error_
+ call psb_errpush(info,name,a_err='wrong A2AV alg selector')
+ goto 9999
+ end select
+
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='alltoallv')
+ goto 9999
+ end if
+
+ Deallocate(brvindx,bsdindx,rvsz,sdsz,&
+ & lsnd,valsnd,stat=info)
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Done'
+
+ call psb_erractionrestore(err_act)
+ return
+
+9999 call psb_error_handler(ctxt,err_act)
+
+ return
+
+End Subroutine psb_d_remote_vect
diff --git a/base/tools/psb_dallc.f90 b/base/tools/psb_dallc.f90
index 7989929b..108e2000 100644
--- a/base/tools/psb_dallc.f90
+++ b/base/tools/psb_dallc.f90
@@ -40,7 +40,7 @@
! x - the vector to be allocated.
! desc_a - the communication descriptor.
! info - Return code
-subroutine psb_dalloc_vect(x, desc_a,info)
+subroutine psb_dalloc_vect(x, desc_a,info, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_dalloc_vect
use psi_mod
implicit none
@@ -49,9 +49,11 @@ subroutine psb_dalloc_vect(x, desc_a,info)
type(psb_d_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
integer(psb_ipk_) :: np,me,nr,i,err_act
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -102,6 +104,25 @@ subroutine psb_dalloc_vect(x, desc_a,info)
endif
call x%zero()
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ call x%set_nrmv(0)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ call psb_ensure_size(nrmt_,x%rmtv,info)
+ call psb_ensure_size(nrmt_,x%rmidx,info)
+ end if
+
call psb_erractionrestore(err_act)
return
@@ -110,6 +131,7 @@ subroutine psb_dalloc_vect(x, desc_a,info)
return
end subroutine psb_dalloc_vect
+
! Function: psb_dalloc_vect_r2
! Allocates a vector of dense vectors for PSBLAS routines.
! The descriptor may be in either the build or assembled state.
@@ -121,7 +143,7 @@ end subroutine psb_dalloc_vect
! n - optional number of columns.
! lb - optional lower bound on column indices
-subroutine psb_dalloc_vect_r2(x, desc_a,info,n,lb)
+subroutine psb_dalloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_dalloc_vect_r2
use psi_mod
implicit none
@@ -131,10 +153,12 @@ subroutine psb_dalloc_vect_r2(x, desc_a,info,n,lb)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n,lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -208,6 +232,26 @@ subroutine psb_dalloc_vect_r2(x, desc_a,info,n,lb)
if (info /= 0) exit
end do
end if
+
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+
+ do i=lb_, lb_+n_-1
+ call x(i)%set_dupl(dupl_)
+ call x(i)%set_remote_build(bldmode_)
+ if (x(i)%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x(i)%rmtv(nrmt_))
+ end if
+ end do
if (psb_errstatus_fatal()) then
info=psb_err_alloc_request_
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
@@ -224,7 +268,7 @@ subroutine psb_dalloc_vect_r2(x, desc_a,info,n,lb)
end subroutine psb_dalloc_vect_r2
-subroutine psb_dalloc_multivect(x, desc_a,info,n)
+subroutine psb_dalloc_multivect(x, desc_a,info,n, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_dalloc_multivect
use psi_mod
implicit none
@@ -234,10 +278,12 @@ subroutine psb_dalloc_multivect(x, desc_a,info,n)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -306,6 +352,23 @@ subroutine psb_dalloc_multivect(x, desc_a,info,n)
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
goto 9999
endif
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x%rmtv(nrmt_,n_))
+ end if
+
call psb_erractionrestore(err_act)
return
diff --git a/base/tools/psb_dasb.f90 b/base/tools/psb_dasb.f90
index 5ebee093..f8225496 100644
--- a/base/tools/psb_dasb.f90
+++ b/base/tools/psb_dasb.f90
@@ -64,7 +64,7 @@ subroutine psb_dasb_vect(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -83,7 +83,7 @@ subroutine psb_dasb_vect(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
+ dupl_ = x%get_dupl()
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -104,6 +104,23 @@ subroutine psb_dasb_vect(x, desc_a, info, mold, scratch)
call x%free(info)
call x%bld(ncol,mold=mold)
else
+
+ if (x%is_remote_build()) then
+ block
+ integer(psb_lpk_), allocatable :: lvx(:)
+ real(psb_dpk_), allocatable :: vx(:)
+ integer(psb_ipk_), allocatable :: ivx(:)
+ integer(psb_ipk_) :: nrmv, nx, i
+
+ nrmv = x%get_nrmv()
+ call psb_d_remote_vect(nrmv,x%rmtv,x%rmidx,desc_a,vx,lvx,info)
+ nx = size(vx)
+ call psb_realloc(nx,ivx,info)
+ call desc_a%g2l(lvx,ivx,info,owned=.true.)
+ call x%ins(nx,ivx,vx,info)
+ end block
+ end if
+
call x%asb(ncol,info)
! ..update halo elements..
call psb_halo(x,desc_a,info)
@@ -140,7 +157,7 @@ subroutine psb_dasb_vect_r2(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, i, n
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -159,7 +176,6 @@ subroutine psb_dasb_vect_r2(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -185,6 +201,7 @@ subroutine psb_dasb_vect_r2(x, desc_a, info, mold, scratch)
else
do i=1, n
+ dupl_ = x(i)%get_dupl()
call x(i)%asb(ncol,info)
if (info /= 0) exit
! ..update halo elements..
@@ -225,7 +242,7 @@ subroutine psb_dasb_multivect(x, desc_a, info, mold, scratch,n)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
@@ -271,6 +288,7 @@ subroutine psb_dasb_multivect(x, desc_a, info, mold, scratch,n)
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': sizes: ',nrow,ncol
+ dupl_ = x%get_dupl()
if (scratch_) then
call x%free(info)
call x%bld(ncol,n_,mold=mold)
diff --git a/base/tools/psb_dins.f90 b/base/tools/psb_dins.f90
index 3e873ded..d3529229 100644
--- a/base/tools/psb_dins.f90
+++ b/base/tools/psb_dins.f90
@@ -42,10 +42,7 @@
! x - type(psb_d_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_dins_vect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_dins_vect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_dins_vect
use psi_mod
implicit none
@@ -57,14 +54,14 @@ subroutine psb_dins_vect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_d_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
+ integer(psb_ipk_) :: dupl_
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_,err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -112,7 +109,6 @@ subroutine psb_dins_vect(m, irw, val, x, desc_a, info, dupl,local)
endif
-
allocate(irl(m),stat=info)
if (info /= psb_success_) then
info = psb_err_alloc_dealloc_
@@ -120,11 +116,6 @@ subroutine psb_dins_vect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -136,11 +127,33 @@ subroutine psb_dins_vect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
end if
+ if (x%is_remote_build()) then
+ block
+ integer(psb_ipk_) :: j,k
+ k = x%get_nrmv()
+ do j=1,m
+ if (irl(j) < 0 ) then
+ k = k + 1
+ call psb_ensure_size(k,x%rmtv,info)
+ if (info == 0) call psb_ensure_size(k,x%rmidx,info)
+ if (info /= 0) then
+ info = psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+ x%rmtv(k) = val(j)
+ x%rmidx(k) = irw(j)
+ call x%set_nrmv(k)
+ end if
+ end do
+ end block
+ end if
+
deallocate(irl)
call psb_erractionrestore(err_act)
@@ -166,10 +179,7 @@ end subroutine psb_dins_vect
! x - type(psb_d_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_dins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_dins_vect_v(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_dins_vect_v
use psi_mod
implicit none
@@ -185,14 +195,13 @@ subroutine psb_dins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
type(psb_d_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols,err_act
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_
+ integer(psb_ipk_) :: np, me
integer(psb_ipk_), allocatable :: irl(:)
real(psb_dpk_), allocatable :: lval(:)
logical :: local_
@@ -239,14 +248,6 @@ subroutine psb_dins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call psb_errpush(info,name)
goto 9999
endif
-
-
-
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -260,7 +261,7 @@ subroutine psb_dins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call desc_a%indxmap%g2l(irw%v%v(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,lval,dupl_,info)
+ call x%ins(m,irl,lval,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
@@ -275,7 +276,7 @@ subroutine psb_dins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_dins_vect_v
-subroutine psb_dins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_dins_vect_r2(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_dins_vect_r2
use psi_mod
implicit none
@@ -291,14 +292,13 @@ subroutine psb_dins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
type(psb_d_vect_type), intent(inout) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols, n
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -353,11 +353,6 @@ subroutine psb_dins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -371,8 +366,9 @@ subroutine psb_dins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end if
do i=1,n
+
if (.not.allocated(x(i)%v)) info = psb_err_invalid_vect_state_
- if (info == 0) call x(i)%ins(m,irl,val(:,i),dupl_,info)
+ if (info == 0) call x(i)%ins(m,irl,val(:,i),info)
if (info /= 0) exit
end do
if (info /= 0) then
@@ -390,7 +386,7 @@ subroutine psb_dins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_dins_vect_r2
-subroutine psb_dins_multivect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_dins_multivect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_dins_multivect
use psi_mod
implicit none
@@ -406,14 +402,13 @@ subroutine psb_dins_multivect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_d_multivect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -469,11 +464,6 @@ subroutine psb_dins_multivect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -485,7 +475,7 @@ subroutine psb_dins_multivect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
diff --git a/base/tools/psb_dspalloc.f90 b/base/tools/psb_dspalloc.f90
index 56ad6c93..433d7129 100644
--- a/base/tools/psb_dspalloc.f90
+++ b/base/tools/psb_dspalloc.f90
@@ -41,21 +41,23 @@
! nnz - integer(optional). The number of nonzeroes in the matrix.
! (local, user estimate)
!
-subroutine psb_dspalloc(a, desc_a, info, nnz)
+subroutine psb_dspalloc(a, desc_a, info, nnz, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_dspalloc
implicit none
!....parameters...
- type(psb_desc_type), intent(in) :: desc_a
- type(psb_dspmat_type), intent(inout) :: a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: nnz
+ type(psb_desc_type), intent(in) :: desc_a
+ type(psb_dspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: nnz
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_) :: loc_row,loc_col, nnz_, dectype
- integer(psb_lpk_) :: m, n
+ integer(psb_ipk_) :: dupl_, bldmode_
+ integer(psb_lpk_) :: m, n, nnzrmt_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -96,7 +98,7 @@ subroutine psb_dspalloc(a, desc_a, info, nnz)
else
nnz_ = max(1,5*loc_row)
endif
-
+
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name), &
& ':allocating size:',loc_row,loc_col,nnz_
@@ -109,6 +111,24 @@ subroutine psb_dspalloc(a, desc_a, info, nnz)
goto 9999
end if
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call a%set_dupl(dupl_)
+ call a%set_remote_build(bldmode_)
+ if (a%is_remote_build()) then
+ allocate(a%rmta)
+ nnzrmt_ = max(100,(nnz_/100))
+ call a%rmta%allocate(m,n,nnzrmt_)
+ end if
+
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': ', &
& desc_a%get_dectype(),psb_desc_bld_
diff --git a/base/tools/psb_dspasb.f90 b/base/tools/psb_dspasb.f90
index 457553f7..3132f249 100644
--- a/base/tools/psb_dspasb.f90
+++ b/base/tools/psb_dspasb.f90
@@ -42,31 +42,29 @@
! upd - character(optional). How will the matrix be updated?
! psb_upd_srch_ Simple strategy
! psb_upd_perm_ Permutation(more memory)
-! dupl - integer(optional). Duplicate coefficient handling:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-! psb_dupl_err_ raise an error.
!
!
-subroutine psb_dspasb(a,desc_a, info, afmt, upd, dupl, mold)
+subroutine psb_dspasb(a,desc_a, info, afmt, upd, mold)
use psb_base_mod, psb_protect_name => psb_dspasb
+ use psb_sort_mod
use psi_mod
implicit none
!...Parameters....
- type(psb_dspmat_type), intent (inout) :: a
- type(psb_desc_type), intent(in) :: desc_a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_),optional, intent(in) :: dupl, upd
- character(len=*), optional, intent(in) :: afmt
+ type(psb_dspmat_type), intent (inout) :: a
+ type(psb_desc_type), intent(inout) :: desc_a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: upd
+ character(len=*), optional, intent(in) :: afmt
class(psb_d_base_sparse_mat), intent(in), optional :: mold
!....Locals....
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, err_act
- integer(psb_ipk_) :: n_row,n_col
+ integer(psb_ipk_) :: n_row,n_col, dupl_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name, ch_err
+ class(psb_i_base_vect_type), allocatable :: ivm
info = psb_success_
name = 'psb_spasb'
@@ -92,28 +90,79 @@ subroutine psb_dspasb(a,desc_a, info, afmt, upd, dupl, mold)
goto 9999
end if
-
if (debug_level >= psb_debug_ext_)&
& write(debug_unit, *) me,' ',trim(name),&
& ' Begin matrix assembly...'
!check on errors encountered in psdspins
-
- if (a%is_bld()) then
+ if (a%is_bld()) then
+ dupl_ = a%get_dupl()
!
! First case: we come from a fresh build.
!
-
- n_row = desc_a%get_local_rows()
- n_col = desc_a%get_local_cols()
- call a%set_nrows(n_row)
- call a%set_ncols(n_col)
- end if
-
- if (a%is_bld()) then
- call a%cscnv(info,type=afmt,dupl=dupl, mold=mold)
+ if (a%is_remote_build()) then
+ !write(0,*) me,name,' Size of rmta:',a%rmta%get_nzeros()
+ block
+ type(psb_ld_coo_sparse_mat) :: a_add
+ integer(psb_ipk_), allocatable :: ila(:), jla(:)
+ integer(psb_ipk_) :: nz, nzt,k
+ call psb_remote_mat(a%rmta,desc_a,a_add,info)
+ nz = a_add%get_nzeros()
+ nzt = nz
+ call psb_sum(ctxt,nzt)
+ if (nzt>0) then
+ allocate(ivm, mold=desc_a%v_halo_index%v)
+ call psb_cd_reinit(desc_a, info)
+ end if
+ if (nz > 0) then
+ !
+ ! Should we check for new indices here?
+ !
+ call psb_realloc(nz,ila,info)
+ call psb_realloc(nz,jla,info)
+ call desc_a%indxmap%g2l(a_add%ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l_ins(a_add%ja(1:nz),jla(1:nz),info)
+ !write(0,*) me,name,' Check before insert',a%get_nzeros()
+ n_row = desc_a%get_local_rows()
+ n_col = desc_a%get_local_cols()
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%csput(nz,ila,jla,a_add%val,ione,n_row,ione,n_col,info)
+ !write(0,*) me,name,' Check after insert',a%get_nzeros(),nz
+ end if
+ if (nzt > 0) call psb_cdasb(desc_a,info,mold=ivm)
+
+ end block
+ end if
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%cscnv(info,type=afmt,mold=mold,dupl=dupl_)
else if (a%is_upd()) then
+ if (a%is_remote_build()) then
+ !write(0,*) me,name,' Size of rmta:',a%rmta%get_nzeros()
+ block
+ type(psb_ld_coo_sparse_mat) :: a_add
+ integer(psb_ipk_), allocatable :: ila(:), jla(:)
+ integer(psb_ipk_) :: nz, nzt,k
+ call psb_remote_mat(a%rmta,desc_a,a_add,info)
+ nz = a_add%get_nzeros()
+!!$ write(0,*) me,name,' Nz to be added',nz
+ if (nz > 0) then
+ !
+ ! Should we check for new indices here?
+ !
+ call psb_realloc(nz,ila,info)
+ call psb_realloc(nz,jla,info)
+ call desc_a%indxmap%g2l(a_add%ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l_ins(a_add%ja(1:nz),jla(1:nz),info)
+ !write(0,*) me,name,' Check before insert',a%get_nzeros()
+ n_row = desc_a%get_local_rows()
+ n_col = desc_a%get_local_cols()
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%csput(nz,ila,jla,a_add%val,ione,n_row,ione,n_col,info)
+ !write(0,*) me,name,' Check after insert',a%get_nzeros(),nz
+ end if
+ end block
+ end if
call a%asb(mold=mold)
else
info = psb_err_invalid_mat_state_
diff --git a/base/tools/psb_dspins.F90 b/base/tools/psb_dspins.F90
index 3e9ef0cc..2a70ab83 100644
--- a/base/tools/psb_dspins.F90
+++ b/base/tools/psb_dspins.F90
@@ -70,6 +70,10 @@ subroutine psb_dspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
integer(psb_ipk_), parameter :: relocsz=200
logical :: rebuild_, local_
integer(psb_ipk_), allocatable :: ila(:),jla(:)
+ integer(psb_ipk_) :: i,k
+ integer(psb_lpk_) :: nnl
+ integer(psb_lpk_), allocatable :: lila(:),ljla(:)
+ real(psb_dpk_), allocatable :: lval(:)
character(len=20) :: name
info = psb_success_
@@ -147,6 +151,27 @@ subroutine psb_dspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
call psb_errpush(info,name,a_err='a%csput')
goto 9999
end if
+
+ if (a%is_remote_build()) then
+ nnl = count(ila(1:nz)<0)
+ if (nnl > 0) then
+ !write(0,*) 'Check on insert ',nnl
+ allocate(lila(nnl),ljla(nnl),lval(nnl))
+ k = 0
+ do i=1,nz
+ if (ila(i)<0) then
+ k=k+1
+ lila(k) = ia(i)
+ ljla(k) = ja(i)
+ lval(k) = val(i)
+ end if
+ end do
+ if (k /= nnl) write(0,*) name,' Wrong conversion?',k,nnl
+ call a%rmta%csput(nnl,lila,ljla,lval,1_psb_lpk_,desc_a%get_global_rows(),&
+ & 1_psb_lpk_,desc_a%get_global_rows(),info)
+ end if
+ end if
+
else
info = psb_err_invalid_a_and_cd_state_
call psb_errpush(info,name)
@@ -168,8 +193,9 @@ subroutine psb_dspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
ila(1:nz) = ia(1:nz)
jla(1:nz) = ja(1:nz)
else
- call desc_a%indxmap%g2l(ia(1:nz),ila(1:nz),info)
- if (info == 0) call desc_a%indxmap%g2l(ja(1:nz),jla(1:nz),info)
+ call desc_a%indxmap%g2l(ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l(ja(1:nz),jla(1:nz),info,&
+ & mask=(ila(1:nz)>0))
end if
call a%csput(nz,ila,jla,val,ione,nrow,ione,ncol,info)
if (info /= psb_success_) then
@@ -177,6 +203,25 @@ subroutine psb_dspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
call psb_errpush(info,name,a_err='a%csput')
goto 9999
end if
+ if (a%is_remote_build()) then
+ nnl = count(ila(1:nz)<0)
+ if (nnl > 0) then
+ !write(0,*) 'Check on insert ',nnl
+ allocate(lila(nnl),ljla(nnl),lval(nnl))
+ k = 0
+ do i=1,nz
+ if (ila(i)<0) then
+ k=k+1
+ lila(k) = ia(k)
+ ljla(k) = ja(k)
+ lval(k) = val(k)
+ end if
+ end do
+ if (k /= nnl) write(0,*) name,' Wrong conversion?',k,nnl
+ call a%rmta%csput(nnl,lila,ljla,lval,1_psb_lpk_,desc_a%get_global_rows(),&
+ & 1_psb_lpk_,desc_a%get_global_rows(),info)
+ end if
+ end if
else
info = psb_err_invalid_cd_state_
call psb_errpush(info,name)
diff --git a/base/tools/psb_iallc.f90 b/base/tools/psb_iallc.f90
index ac4ee840..7ed69ed6 100644
--- a/base/tools/psb_iallc.f90
+++ b/base/tools/psb_iallc.f90
@@ -40,7 +40,7 @@
! x - the vector to be allocated.
! desc_a - the communication descriptor.
! info - Return code
-subroutine psb_ialloc_vect(x, desc_a,info)
+subroutine psb_ialloc_vect(x, desc_a,info, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_ialloc_vect
use psi_mod
implicit none
@@ -49,9 +49,11 @@ subroutine psb_ialloc_vect(x, desc_a,info)
type(psb_i_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
integer(psb_ipk_) :: np,me,nr,i,err_act
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -102,6 +104,25 @@ subroutine psb_ialloc_vect(x, desc_a,info)
endif
call x%zero()
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ call x%set_nrmv(0)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ call psb_ensure_size(nrmt_,x%rmtv,info)
+ call psb_ensure_size(nrmt_,x%rmidx,info)
+ end if
+
call psb_erractionrestore(err_act)
return
@@ -110,6 +131,7 @@ subroutine psb_ialloc_vect(x, desc_a,info)
return
end subroutine psb_ialloc_vect
+
! Function: psb_ialloc_vect_r2
! Allocates a vector of dense vectors for PSBLAS routines.
! The descriptor may be in either the build or assembled state.
@@ -121,7 +143,7 @@ end subroutine psb_ialloc_vect
! n - optional number of columns.
! lb - optional lower bound on column indices
-subroutine psb_ialloc_vect_r2(x, desc_a,info,n,lb)
+subroutine psb_ialloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_ialloc_vect_r2
use psi_mod
implicit none
@@ -131,10 +153,12 @@ subroutine psb_ialloc_vect_r2(x, desc_a,info,n,lb)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n,lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -208,6 +232,26 @@ subroutine psb_ialloc_vect_r2(x, desc_a,info,n,lb)
if (info /= 0) exit
end do
end if
+
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+
+ do i=lb_, lb_+n_-1
+ call x(i)%set_dupl(dupl_)
+ call x(i)%set_remote_build(bldmode_)
+ if (x(i)%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x(i)%rmtv(nrmt_))
+ end if
+ end do
if (psb_errstatus_fatal()) then
info=psb_err_alloc_request_
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
@@ -224,7 +268,7 @@ subroutine psb_ialloc_vect_r2(x, desc_a,info,n,lb)
end subroutine psb_ialloc_vect_r2
-subroutine psb_ialloc_multivect(x, desc_a,info,n)
+subroutine psb_ialloc_multivect(x, desc_a,info,n, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_ialloc_multivect
use psi_mod
implicit none
@@ -234,10 +278,12 @@ subroutine psb_ialloc_multivect(x, desc_a,info,n)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -306,6 +352,23 @@ subroutine psb_ialloc_multivect(x, desc_a,info,n)
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
goto 9999
endif
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x%rmtv(nrmt_,n_))
+ end if
+
call psb_erractionrestore(err_act)
return
diff --git a/base/tools/psb_iasb.f90 b/base/tools/psb_iasb.f90
index d0cf2d83..5e09d331 100644
--- a/base/tools/psb_iasb.f90
+++ b/base/tools/psb_iasb.f90
@@ -64,7 +64,7 @@ subroutine psb_iasb_vect(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -83,7 +83,7 @@ subroutine psb_iasb_vect(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
+ dupl_ = x%get_dupl()
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -104,6 +104,23 @@ subroutine psb_iasb_vect(x, desc_a, info, mold, scratch)
call x%free(info)
call x%bld(ncol,mold=mold)
else
+
+ if (x%is_remote_build()) then
+ block
+ integer(psb_lpk_), allocatable :: lvx(:)
+ integer(psb_ipk_), allocatable :: vx(:)
+ integer(psb_ipk_), allocatable :: ivx(:)
+ integer(psb_ipk_) :: nrmv, nx, i
+
+ nrmv = x%get_nrmv()
+ call psb_i_remote_vect(nrmv,x%rmtv,x%rmidx,desc_a,vx,lvx,info)
+ nx = size(vx)
+ call psb_realloc(nx,ivx,info)
+ call desc_a%g2l(lvx,ivx,info,owned=.true.)
+ call x%ins(nx,ivx,vx,info)
+ end block
+ end if
+
call x%asb(ncol,info)
! ..update halo elements..
call psb_halo(x,desc_a,info)
@@ -140,7 +157,7 @@ subroutine psb_iasb_vect_r2(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, i, n
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -159,7 +176,6 @@ subroutine psb_iasb_vect_r2(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -185,6 +201,7 @@ subroutine psb_iasb_vect_r2(x, desc_a, info, mold, scratch)
else
do i=1, n
+ dupl_ = x(i)%get_dupl()
call x(i)%asb(ncol,info)
if (info /= 0) exit
! ..update halo elements..
@@ -225,7 +242,7 @@ subroutine psb_iasb_multivect(x, desc_a, info, mold, scratch,n)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
@@ -271,6 +288,7 @@ subroutine psb_iasb_multivect(x, desc_a, info, mold, scratch,n)
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': sizes: ',nrow,ncol
+ dupl_ = x%get_dupl()
if (scratch_) then
call x%free(info)
call x%bld(ncol,n_,mold=mold)
diff --git a/base/tools/psb_iins.f90 b/base/tools/psb_iins.f90
index c9c0ed9b..4fa53429 100644
--- a/base/tools/psb_iins.f90
+++ b/base/tools/psb_iins.f90
@@ -42,10 +42,7 @@
! x - type(psb_i_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_iins_vect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_iins_vect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_iins_vect
use psi_mod
implicit none
@@ -57,14 +54,14 @@ subroutine psb_iins_vect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_i_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
+ integer(psb_ipk_) :: dupl_
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_,err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -112,7 +109,6 @@ subroutine psb_iins_vect(m, irw, val, x, desc_a, info, dupl,local)
endif
-
allocate(irl(m),stat=info)
if (info /= psb_success_) then
info = psb_err_alloc_dealloc_
@@ -120,11 +116,6 @@ subroutine psb_iins_vect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -136,11 +127,33 @@ subroutine psb_iins_vect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
end if
+ if (x%is_remote_build()) then
+ block
+ integer(psb_ipk_) :: j,k
+ k = x%get_nrmv()
+ do j=1,m
+ if (irl(j) < 0 ) then
+ k = k + 1
+ call psb_ensure_size(k,x%rmtv,info)
+ if (info == 0) call psb_ensure_size(k,x%rmidx,info)
+ if (info /= 0) then
+ info = psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+ x%rmtv(k) = val(j)
+ x%rmidx(k) = irw(j)
+ call x%set_nrmv(k)
+ end if
+ end do
+ end block
+ end if
+
deallocate(irl)
call psb_erractionrestore(err_act)
@@ -166,10 +179,7 @@ end subroutine psb_iins_vect
! x - type(psb_i_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_iins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_iins_vect_v(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_iins_vect_v
use psi_mod
implicit none
@@ -185,14 +195,13 @@ subroutine psb_iins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
type(psb_i_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols,err_act
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_
+ integer(psb_ipk_) :: np, me
integer(psb_ipk_), allocatable :: irl(:)
integer(psb_ipk_), allocatable :: lval(:)
logical :: local_
@@ -239,14 +248,6 @@ subroutine psb_iins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call psb_errpush(info,name)
goto 9999
endif
-
-
-
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -260,7 +261,7 @@ subroutine psb_iins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call desc_a%indxmap%g2l(irw%v%v(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,lval,dupl_,info)
+ call x%ins(m,irl,lval,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
@@ -275,7 +276,7 @@ subroutine psb_iins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_iins_vect_v
-subroutine psb_iins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_iins_vect_r2(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_iins_vect_r2
use psi_mod
implicit none
@@ -291,14 +292,13 @@ subroutine psb_iins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
type(psb_i_vect_type), intent(inout) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols, n
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -353,11 +353,6 @@ subroutine psb_iins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -371,8 +366,9 @@ subroutine psb_iins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end if
do i=1,n
+
if (.not.allocated(x(i)%v)) info = psb_err_invalid_vect_state_
- if (info == 0) call x(i)%ins(m,irl,val(:,i),dupl_,info)
+ if (info == 0) call x(i)%ins(m,irl,val(:,i),info)
if (info /= 0) exit
end do
if (info /= 0) then
@@ -390,7 +386,7 @@ subroutine psb_iins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_iins_vect_r2
-subroutine psb_iins_multivect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_iins_multivect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_iins_multivect
use psi_mod
implicit none
@@ -406,14 +402,13 @@ subroutine psb_iins_multivect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_i_multivect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -469,11 +464,6 @@ subroutine psb_iins_multivect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -485,7 +475,7 @@ subroutine psb_iins_multivect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
diff --git a/base/tools/psb_lallc.f90 b/base/tools/psb_lallc.f90
index 85fd67e7..53857029 100644
--- a/base/tools/psb_lallc.f90
+++ b/base/tools/psb_lallc.f90
@@ -40,7 +40,7 @@
! x - the vector to be allocated.
! desc_a - the communication descriptor.
! info - Return code
-subroutine psb_lalloc_vect(x, desc_a,info)
+subroutine psb_lalloc_vect(x, desc_a,info, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_lalloc_vect
use psi_mod
implicit none
@@ -49,9 +49,11 @@ subroutine psb_lalloc_vect(x, desc_a,info)
type(psb_l_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
integer(psb_ipk_) :: np,me,nr,i,err_act
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -102,6 +104,25 @@ subroutine psb_lalloc_vect(x, desc_a,info)
endif
call x%zero()
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ call x%set_nrmv(0)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ call psb_ensure_size(nrmt_,x%rmtv,info)
+ call psb_ensure_size(nrmt_,x%rmidx,info)
+ end if
+
call psb_erractionrestore(err_act)
return
@@ -110,6 +131,7 @@ subroutine psb_lalloc_vect(x, desc_a,info)
return
end subroutine psb_lalloc_vect
+
! Function: psb_lalloc_vect_r2
! Allocates a vector of dense vectors for PSBLAS routines.
! The descriptor may be in either the build or assembled state.
@@ -121,7 +143,7 @@ end subroutine psb_lalloc_vect
! n - optional number of columns.
! lb - optional lower bound on column indices
-subroutine psb_lalloc_vect_r2(x, desc_a,info,n,lb)
+subroutine psb_lalloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_lalloc_vect_r2
use psi_mod
implicit none
@@ -131,10 +153,12 @@ subroutine psb_lalloc_vect_r2(x, desc_a,info,n,lb)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n,lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -208,6 +232,26 @@ subroutine psb_lalloc_vect_r2(x, desc_a,info,n,lb)
if (info /= 0) exit
end do
end if
+
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+
+ do i=lb_, lb_+n_-1
+ call x(i)%set_dupl(dupl_)
+ call x(i)%set_remote_build(bldmode_)
+ if (x(i)%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x(i)%rmtv(nrmt_))
+ end if
+ end do
if (psb_errstatus_fatal()) then
info=psb_err_alloc_request_
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
@@ -224,7 +268,7 @@ subroutine psb_lalloc_vect_r2(x, desc_a,info,n,lb)
end subroutine psb_lalloc_vect_r2
-subroutine psb_lalloc_multivect(x, desc_a,info,n)
+subroutine psb_lalloc_multivect(x, desc_a,info,n, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_lalloc_multivect
use psi_mod
implicit none
@@ -234,10 +278,12 @@ subroutine psb_lalloc_multivect(x, desc_a,info,n)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -306,6 +352,23 @@ subroutine psb_lalloc_multivect(x, desc_a,info,n)
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
goto 9999
endif
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x%rmtv(nrmt_,n_))
+ end if
+
call psb_erractionrestore(err_act)
return
diff --git a/base/tools/psb_lasb.f90 b/base/tools/psb_lasb.f90
index 1618abdb..1110ee11 100644
--- a/base/tools/psb_lasb.f90
+++ b/base/tools/psb_lasb.f90
@@ -64,7 +64,7 @@ subroutine psb_lasb_vect(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -83,7 +83,7 @@ subroutine psb_lasb_vect(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
+ dupl_ = x%get_dupl()
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -104,6 +104,23 @@ subroutine psb_lasb_vect(x, desc_a, info, mold, scratch)
call x%free(info)
call x%bld(ncol,mold=mold)
else
+
+ if (x%is_remote_build()) then
+ block
+ integer(psb_lpk_), allocatable :: lvx(:)
+ integer(psb_lpk_), allocatable :: vx(:)
+ integer(psb_ipk_), allocatable :: ivx(:)
+ integer(psb_ipk_) :: nrmv, nx, i
+
+ nrmv = x%get_nrmv()
+ call psb_l_remote_vect(nrmv,x%rmtv,x%rmidx,desc_a,vx,lvx,info)
+ nx = size(vx)
+ call psb_realloc(nx,ivx,info)
+ call desc_a%g2l(lvx,ivx,info,owned=.true.)
+ call x%ins(nx,ivx,vx,info)
+ end block
+ end if
+
call x%asb(ncol,info)
! ..update halo elements..
call psb_halo(x,desc_a,info)
@@ -140,7 +157,7 @@ subroutine psb_lasb_vect_r2(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, i, n
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -159,7 +176,6 @@ subroutine psb_lasb_vect_r2(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -185,6 +201,7 @@ subroutine psb_lasb_vect_r2(x, desc_a, info, mold, scratch)
else
do i=1, n
+ dupl_ = x(i)%get_dupl()
call x(i)%asb(ncol,info)
if (info /= 0) exit
! ..update halo elements..
@@ -225,7 +242,7 @@ subroutine psb_lasb_multivect(x, desc_a, info, mold, scratch,n)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
@@ -271,6 +288,7 @@ subroutine psb_lasb_multivect(x, desc_a, info, mold, scratch,n)
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': sizes: ',nrow,ncol
+ dupl_ = x%get_dupl()
if (scratch_) then
call x%free(info)
call x%bld(ncol,n_,mold=mold)
diff --git a/base/tools/psb_lins.f90 b/base/tools/psb_lins.f90
index 42559a94..90da8111 100644
--- a/base/tools/psb_lins.f90
+++ b/base/tools/psb_lins.f90
@@ -42,10 +42,7 @@
! x - type(psb_l_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_lins_vect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_lins_vect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_lins_vect
use psi_mod
implicit none
@@ -57,14 +54,14 @@ subroutine psb_lins_vect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_l_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
+ integer(psb_ipk_) :: dupl_
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_,err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -112,7 +109,6 @@ subroutine psb_lins_vect(m, irw, val, x, desc_a, info, dupl,local)
endif
-
allocate(irl(m),stat=info)
if (info /= psb_success_) then
info = psb_err_alloc_dealloc_
@@ -120,11 +116,6 @@ subroutine psb_lins_vect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -136,11 +127,33 @@ subroutine psb_lins_vect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
end if
+ if (x%is_remote_build()) then
+ block
+ integer(psb_ipk_) :: j,k
+ k = x%get_nrmv()
+ do j=1,m
+ if (irl(j) < 0 ) then
+ k = k + 1
+ call psb_ensure_size(k,x%rmtv,info)
+ if (info == 0) call psb_ensure_size(k,x%rmidx,info)
+ if (info /= 0) then
+ info = psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+ x%rmtv(k) = val(j)
+ x%rmidx(k) = irw(j)
+ call x%set_nrmv(k)
+ end if
+ end do
+ end block
+ end if
+
deallocate(irl)
call psb_erractionrestore(err_act)
@@ -166,10 +179,7 @@ end subroutine psb_lins_vect
! x - type(psb_l_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_lins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_lins_vect_v(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_lins_vect_v
use psi_mod
implicit none
@@ -185,14 +195,13 @@ subroutine psb_lins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
type(psb_l_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols,err_act
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_
+ integer(psb_ipk_) :: np, me
integer(psb_ipk_), allocatable :: irl(:)
integer(psb_lpk_), allocatable :: lval(:)
logical :: local_
@@ -239,14 +248,6 @@ subroutine psb_lins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call psb_errpush(info,name)
goto 9999
endif
-
-
-
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -260,7 +261,7 @@ subroutine psb_lins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call desc_a%indxmap%g2l(irw%v%v(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,lval,dupl_,info)
+ call x%ins(m,irl,lval,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
@@ -275,7 +276,7 @@ subroutine psb_lins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_lins_vect_v
-subroutine psb_lins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_lins_vect_r2(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_lins_vect_r2
use psi_mod
implicit none
@@ -291,14 +292,13 @@ subroutine psb_lins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
type(psb_l_vect_type), intent(inout) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols, n
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -353,11 +353,6 @@ subroutine psb_lins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -371,8 +366,9 @@ subroutine psb_lins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end if
do i=1,n
+
if (.not.allocated(x(i)%v)) info = psb_err_invalid_vect_state_
- if (info == 0) call x(i)%ins(m,irl,val(:,i),dupl_,info)
+ if (info == 0) call x(i)%ins(m,irl,val(:,i),info)
if (info /= 0) exit
end do
if (info /= 0) then
@@ -390,7 +386,7 @@ subroutine psb_lins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_lins_vect_r2
-subroutine psb_lins_multivect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_lins_multivect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_lins_multivect
use psi_mod
implicit none
@@ -406,14 +402,13 @@ subroutine psb_lins_multivect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_l_multivect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -469,11 +464,6 @@ subroutine psb_lins_multivect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -485,7 +475,7 @@ subroutine psb_lins_multivect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
diff --git a/base/tools/psb_s_remote_mat.F90 b/base/tools/psb_s_remote_mat.F90
new file mode 100644
index 00000000..d0886304
--- /dev/null
+++ b/base/tools/psb_s_remote_mat.F90
@@ -0,0 +1,436 @@
+!
+! 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.
+!
+!
+! File: psb_s_remote_mat.f90
+!
+! Subroutine:
+! This routine does the retrieval of remote matrix rows.
+! Retrieval is done through GETROW, therefore it should work
+! for any matrix format in A; as for the output, default is CSR.
+!
+! There is also a specialized version ls_CSR whose interface
+! is adapted for the needs of s_par_csr_spspmm.
+!
+! There are three possible exchange algorithms:
+! 1. Use MPI_Alltoallv
+! 2. Use psb_simple_a2av
+! 3. Use psb_simple_triad_a2av
+! Default choice is 3. The MPI variant has proved to be inefficient;
+! that is because it is not persistent, therefore you pay the initialization price
+! every time, and it is not optimized for a sparse communication pattern,
+! most MPI implementations assume that all communications are non-empty.
+! The PSB_SIMPLE variants reuse the same communicator, and go for a simplistic
+! sequence of sends/receive that is quite efficient for a sparse communication
+! pattern. To be refined/reviewed in the future to compare with neighbour
+! persistent collectives.
+!
+! Arguments:
+! a - type(psb_sspmat_type) The local part of input matrix A
+! desc_a - type(psb_desc_type). The communication descriptor.
+! blck - type(psb_sspmat_type) The local part of output matrix BLCK
+! info - integer. Return code
+! rowcnv - logical Should row/col indices be converted
+! colcnv - logical to/from global numbering when sent/received?
+! default is .TRUE.
+! rowscale - logical Should row/col indices on output be remapped
+! colscale - logical from MIN:MAX to 1:(MAX-MIN+1) ?
+! default is .FALSE.
+! (commmon use is ROWSCALE=.TRUE., COLSCALE=.FALSE.)
+! data - integer Which index list in desc_a should be used to retrieve
+! rows, default psb_comm_halo_
+! psb_comm_halo_ use halo_index
+! psb_comm_ext_ use ext_index
+! psb_comm_ovrl_ DISABLED for this routine.
+!
+Subroutine psb_ls_remote_mat(a,desc_a,b,info)
+ use psb_base_mod, psb_protect_name => psb_ls_remote_mat
+
+#ifdef MPI_MOD
+ use mpi
+#endif
+ Implicit None
+#ifdef MPI_H
+ include 'mpif.h'
+#endif
+
+ Type(psb_ls_coo_sparse_mat),Intent(inout) :: a
+ Type(psb_ls_coo_sparse_mat),Intent(inout) :: b
+ Type(psb_desc_type), Intent(inout) :: desc_a
+ integer(psb_ipk_), intent(out) :: info
+
+ ! ...local scalars....
+ type(psb_ctxt_type) :: ctxt
+ integer(psb_ipk_) :: np,me
+ integer(psb_ipk_) :: counter, proc, i, n_el_send,n_el_recv, &
+ & n_elem, j, ipx,idxs,idxr
+ integer(psb_lpk_) :: r, k, irmin, irmax, icmin, icmax, iszs, iszr, &
+ & lidx, l1, lnr, lnc, lnnz, idx, ngtz, tot_elem
+ integer(psb_lpk_) :: nz,nouth
+ integer(psb_ipk_) :: nrcvs, nsnds
+ integer(psb_mpk_) :: icomm, minfo
+ integer(psb_mpk_), allocatable :: brvindx(:), &
+ & rvsz(:), bsdindx(:),sdsz(:), sdsi(:), rvsi(:)
+ integer(psb_lpk_), allocatable :: iasnd(:), jasnd(:)
+ real(psb_spk_), allocatable :: valsnd(:)
+ type(psb_ls_coo_sparse_mat), allocatable :: acoo
+ class(psb_i_base_vect_type), pointer :: pdxv
+ integer(psb_ipk_), allocatable :: ila(:), iprc(:)
+ logical :: rowcnv_,colcnv_,rowscale_,colscale_
+ character(len=5) :: outfmt_
+ integer(psb_ipk_) :: debug_level, debug_unit, err_act
+ character(len=20) :: name, ch_err
+
+ info=psb_success_
+ name='psb_s_remote_mat'
+ call psb_erractionsave(err_act)
+ if (psb_errstatus_fatal()) then
+ info = psb_err_internal_error_ ; goto 9999
+ end if
+ debug_unit = psb_get_debug_unit()
+ debug_level = psb_get_debug_level()
+
+ ctxt = desc_a%get_context()
+ icomm = desc_a%get_mpic()
+
+ Call psb_info(ctxt, me, np)
+
+ if (debug_level >= psb_debug_outer_) &
+ & write(debug_unit,*) me,' ',trim(name),': Start'
+
+
+ call b%free()
+
+ Allocate(rvsz(np),sdsz(np),sdsi(np),rvsi(np),brvindx(np+1),&
+ & bsdindx(np+1), acoo,stat=info)
+
+ if (info /= psb_success_) then
+ info=psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+
+
+ nz = a%get_nzeros()
+ !allocate(ila(nz))
+ !write(0,*) me,name,' size :',nz,size(ila)
+ !call desc_a%g2l(a%ia(1:nz),ila(1:nz),info,owned=.false.)
+ !nouth = count(ila(1:nz)<0)
+ !write(0,*) me,name,' Count out of halo :',nouth
+ !call psb_max(ctxt,nouth)
+ !if ((nouth/=0).and.(me==0)) &
+ ! & write(0,*) 'Warning: would require reinit of DESC_A'
+
+ call desc_a%indxmap%fnd_owner(a%ia(1:nz),iprc,info)
+
+ icomm = desc_a%get_mpic()
+ sdsz(:)=0
+ rvsz(:)=0
+ sdsi(:)=0
+ rvsi(:)=0
+ ipx = 1
+ brvindx(:) = 0
+ bsdindx(:) = 0
+ counter=1
+ idx = 0
+ idxs = 0
+ idxr = 0
+ do i=1,nz
+ if (iprc(i) >=0) then
+ sdsz(iprc(i)+1) = sdsz(iprc(i)+1) +1
+ else
+ write(0,*)me,name,' Error from fnd_owner: ',iprc(i)
+ end if
+ end do
+ call mpi_alltoall(sdsz,1,psb_mpi_mpk_,&
+ & rvsz,1,psb_mpi_mpk_,icomm,minfo)
+ if (minfo /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='mpi_alltoall')
+ goto 9999
+ end if
+ !write(0,*)me,name,' sdsz ',sdsz(:),' rvsz:',rvsz(:)
+ nsnds = count(sdsz /= 0)
+ nrcvs = count(rvsz /= 0)
+ idxs = 0
+ idxr = 0
+ counter = 1
+ Do proc=0,np-1
+ bsdindx(proc+1) = idxs
+ idxs = idxs + sdsz(proc+1)
+ brvindx(proc+1) = idxr
+ idxr = idxr + rvsz(proc+1)
+ Enddo
+
+ iszs = sum(sdsz)
+ iszr = sum(rvsz)
+ call acoo%allocate(desc_a%get_global_rows(),desc_a%get_global_cols(),iszr)
+ if (psb_errstatus_fatal()) then
+ write(0,*) 'Error from acoo%allocate '
+ info = 4010
+ goto 9999
+ end if
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Sizes:',acoo%get_size(),&
+ & ' Send:',sdsz(:),' Receive:',rvsz(:)
+ !write(debug_unit,*) me,' ',trim(name),': ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),iasnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' iasnd: ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),jasnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' jasnd: ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),valsnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' valsnd: ',info
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='ensure_size')
+ goto 9999
+ end if
+ do k=1, nz
+ proc = iprc(k)
+ sdsi(proc+1) = sdsi(proc+1) + 1
+ !rvsi(proc) = rvsi(proc) + 1
+ iasnd(bsdindx(proc+1)+sdsi(proc+1)) = a%ia(k)
+ jasnd(bsdindx(proc+1)+sdsi(proc+1)) = a%ja(k)
+ valsnd(bsdindx(proc+1)+sdsi(proc+1)) = a%val(k)
+ end do
+ do proc=0,np-1
+ if (sdsi(proc+1) /= sdsz(proc+1)) &
+ & write(0,*) me,name,'Send mismacth ',sdsi(proc+1),sdsz(proc+1)
+ end do
+
+ select case(psb_get_sp_a2av_alg())
+ case(psb_sp_a2av_smpl_triad_)
+ call psb_simple_triad_a2av(valsnd,iasnd,jasnd,sdsz,bsdindx,&
+ & acoo%val,acoo%ia,acoo%ja,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_smpl_v_)
+ call psb_simple_a2av(valsnd,sdsz,bsdindx,&
+ & acoo%val,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(iasnd,sdsz,bsdindx,&
+ & acoo%ia,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(jasnd,sdsz,bsdindx,&
+ & acoo%ja,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_mpi_)
+
+ call mpi_alltoallv(valsnd,sdsz,bsdindx,psb_mpi_r_spk_,&
+ & acoo%val,rvsz,brvindx,psb_mpi_r_spk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(iasnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & acoo%ia,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(jasnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & acoo%ja,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo /= mpi_success) info = minfo
+ case default
+ info = psb_err_internal_error_
+ call psb_errpush(info,name,a_err='wrong A2AV alg selector')
+ goto 9999
+ end select
+
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='alltoallv')
+ goto 9999
+ end if
+ call acoo%set_nzeros(iszr)
+ call acoo%mv_to_coo(b,info)
+
+ Deallocate(brvindx,bsdindx,rvsz,sdsz,&
+ & iasnd,jasnd,valsnd,stat=info)
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Done'
+
+ call psb_erractionrestore(err_act)
+ return
+
+9999 call psb_error_handler(ctxt,err_act)
+
+ return
+
+End Subroutine psb_ls_remote_mat
+
+
+subroutine psb_s_remote_vect(n,v,iv,desc_a,x,ix, info)
+ use psb_base_mod, psb_protect_name => psb_s_remote_vect
+
+#ifdef MPI_MOD
+ use mpi
+#endif
+ Implicit None
+#ifdef MPI_H
+ include 'mpif.h'
+#endif
+ integer(psb_ipk_), intent(in) :: n
+ real(psb_spk_), Intent(in) :: v(:)
+ integer(psb_lpk_), Intent(in) :: iv(:)
+ type(psb_desc_type),intent(in) :: desc_a
+ real(psb_spk_), allocatable, intent(out) :: x(:)
+ integer(psb_lpk_), allocatable, intent(out) :: ix(:)
+ integer(psb_ipk_), intent(out) :: info
+ ! ...local scalars....
+ type(psb_ctxt_type) :: ctxt
+ integer(psb_ipk_) :: np,me
+ integer(psb_ipk_) :: counter, proc, i, &
+ & j, idxs,idxr, k, iszs, iszr
+ integer(psb_ipk_) :: nrcvs, nsnds
+ integer(psb_mpk_) :: icomm, minfo
+ integer(psb_mpk_), allocatable :: brvindx(:), &
+ & rvsz(:), bsdindx(:), sdsz(:), sdsi(:), rvsi(:)
+ integer(psb_lpk_), allocatable :: lsnd(:)
+ real(psb_spk_), allocatable :: valsnd(:)
+ integer(psb_ipk_), allocatable :: iprc(:)
+ integer(psb_ipk_) :: debug_level, debug_unit, err_act
+ character(len=20) :: name, ch_err
+
+ info=psb_success_
+ name='psb_s_remote_vect'
+ call psb_erractionsave(err_act)
+ if (psb_errstatus_fatal()) then
+ info = psb_err_internal_error_ ; goto 9999
+ end if
+ debug_unit = psb_get_debug_unit()
+ debug_level = psb_get_debug_level()
+
+ ctxt = desc_a%get_context()
+ icomm = desc_a%get_mpic()
+
+ Call psb_info(ctxt, me, np)
+
+ if (debug_level >= psb_debug_outer_) &
+ & write(debug_unit,*) me,' ',trim(name),': Start'
+
+ Allocate(rvsz(np),sdsz(np),sdsi(np),rvsi(np),brvindx(np+1),&
+ & bsdindx(np+1), stat=info)
+
+ if (info /= psb_success_) then
+ info=psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+
+ call desc_a%indxmap%fnd_owner(iv(1:n),iprc,info)
+
+ icomm = desc_a%get_mpic()
+ sdsz(:) = 0
+ rvsz(:) = 0
+ sdsi(:) = 0
+ rvsi(:) = 0
+ brvindx(:) = 0
+ bsdindx(:) = 0
+ counter = 1
+ idxs = 0
+ idxr = 0
+ do i=1,n
+ if (iprc(i) >=0) then
+ sdsz(iprc(i)+1) = sdsz(iprc(i)+1) +1
+ else
+ write(0,*)me,name,' Error from fnd_owner: ',iprc(i)
+ end if
+ end do
+ call mpi_alltoall(sdsz,1,psb_mpi_mpk_,&
+ & rvsz,1,psb_mpi_mpk_,icomm,minfo)
+ if (minfo /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='mpi_alltoall')
+ goto 9999
+ end if
+ !write(0,*)me,name,' sdsz ',sdsz(:),' rvsz:',rvsz(:)
+ nsnds = count(sdsz /= 0)
+ nrcvs = count(rvsz /= 0)
+ idxs = 0
+ idxr = 0
+ counter = 1
+ Do proc=0,np-1
+ bsdindx(proc+1) = idxs
+ idxs = idxs + sdsz(proc+1)
+ brvindx(proc+1) = idxr
+ idxr = idxr + rvsz(proc+1)
+ Enddo
+
+ iszs = sum(sdsz)
+ iszr = sum(rvsz)
+ call psb_realloc(iszs,lsnd,info)
+ if (info == 0) call psb_realloc(iszs,valsnd,info)
+ if (info == 0) call psb_realloc(iszr,x,info)
+ if (info == 0) call psb_realloc(iszr,ix,info)
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='realloc')
+ goto 9999
+ end if
+ do k=1, n
+ proc = iprc(k)
+ sdsi(proc+1) = sdsi(proc+1) + 1
+ lsnd(bsdindx(proc+1)+sdsi(proc+1)) = iv(k)
+ valsnd(bsdindx(proc+1)+sdsi(proc+1)) = v(k)
+ end do
+ do proc=0,np-1
+ if (sdsi(proc+1) /= sdsz(proc+1)) &
+ & write(0,*) me,name,'Send mismacth ',sdsi(proc+1),sdsz(proc+1)
+ end do
+
+ select case(psb_get_sp_a2av_alg())
+ case(psb_sp_a2av_smpl_triad_,psb_sp_a2av_smpl_v_)
+ call psb_simple_a2av(valsnd,sdsz,bsdindx,&
+ & x,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(lsnd,sdsz,bsdindx,&
+ & ix,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_mpi_)
+
+ call mpi_alltoallv(valsnd,sdsz,bsdindx,psb_mpi_r_spk_,&
+ & x,rvsz,brvindx,psb_mpi_r_spk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(lsnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & ix,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo /= mpi_success) info = minfo
+ case default
+ info = psb_err_internal_error_
+ call psb_errpush(info,name,a_err='wrong A2AV alg selector')
+ goto 9999
+ end select
+
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='alltoallv')
+ goto 9999
+ end if
+
+ Deallocate(brvindx,bsdindx,rvsz,sdsz,&
+ & lsnd,valsnd,stat=info)
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Done'
+
+ call psb_erractionrestore(err_act)
+ return
+
+9999 call psb_error_handler(ctxt,err_act)
+
+ return
+
+End Subroutine psb_s_remote_vect
diff --git a/base/tools/psb_sallc.f90 b/base/tools/psb_sallc.f90
index 941ce917..951d8128 100644
--- a/base/tools/psb_sallc.f90
+++ b/base/tools/psb_sallc.f90
@@ -40,7 +40,7 @@
! x - the vector to be allocated.
! desc_a - the communication descriptor.
! info - Return code
-subroutine psb_salloc_vect(x, desc_a,info)
+subroutine psb_salloc_vect(x, desc_a,info, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_salloc_vect
use psi_mod
implicit none
@@ -49,9 +49,11 @@ subroutine psb_salloc_vect(x, desc_a,info)
type(psb_s_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
integer(psb_ipk_) :: np,me,nr,i,err_act
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -102,6 +104,25 @@ subroutine psb_salloc_vect(x, desc_a,info)
endif
call x%zero()
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ call x%set_nrmv(0)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ call psb_ensure_size(nrmt_,x%rmtv,info)
+ call psb_ensure_size(nrmt_,x%rmidx,info)
+ end if
+
call psb_erractionrestore(err_act)
return
@@ -110,6 +131,7 @@ subroutine psb_salloc_vect(x, desc_a,info)
return
end subroutine psb_salloc_vect
+
! Function: psb_salloc_vect_r2
! Allocates a vector of dense vectors for PSBLAS routines.
! The descriptor may be in either the build or assembled state.
@@ -121,7 +143,7 @@ end subroutine psb_salloc_vect
! n - optional number of columns.
! lb - optional lower bound on column indices
-subroutine psb_salloc_vect_r2(x, desc_a,info,n,lb)
+subroutine psb_salloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_salloc_vect_r2
use psi_mod
implicit none
@@ -131,10 +153,12 @@ subroutine psb_salloc_vect_r2(x, desc_a,info,n,lb)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n,lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -208,6 +232,26 @@ subroutine psb_salloc_vect_r2(x, desc_a,info,n,lb)
if (info /= 0) exit
end do
end if
+
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+
+ do i=lb_, lb_+n_-1
+ call x(i)%set_dupl(dupl_)
+ call x(i)%set_remote_build(bldmode_)
+ if (x(i)%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x(i)%rmtv(nrmt_))
+ end if
+ end do
if (psb_errstatus_fatal()) then
info=psb_err_alloc_request_
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
@@ -224,7 +268,7 @@ subroutine psb_salloc_vect_r2(x, desc_a,info,n,lb)
end subroutine psb_salloc_vect_r2
-subroutine psb_salloc_multivect(x, desc_a,info,n)
+subroutine psb_salloc_multivect(x, desc_a,info,n, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_salloc_multivect
use psi_mod
implicit none
@@ -234,10 +278,12 @@ subroutine psb_salloc_multivect(x, desc_a,info,n)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -306,6 +352,23 @@ subroutine psb_salloc_multivect(x, desc_a,info,n)
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
goto 9999
endif
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x%rmtv(nrmt_,n_))
+ end if
+
call psb_erractionrestore(err_act)
return
diff --git a/base/tools/psb_sasb.f90 b/base/tools/psb_sasb.f90
index ac3a0684..7238fecf 100644
--- a/base/tools/psb_sasb.f90
+++ b/base/tools/psb_sasb.f90
@@ -64,7 +64,7 @@ subroutine psb_sasb_vect(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -83,7 +83,7 @@ subroutine psb_sasb_vect(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
+ dupl_ = x%get_dupl()
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -104,6 +104,23 @@ subroutine psb_sasb_vect(x, desc_a, info, mold, scratch)
call x%free(info)
call x%bld(ncol,mold=mold)
else
+
+ if (x%is_remote_build()) then
+ block
+ integer(psb_lpk_), allocatable :: lvx(:)
+ real(psb_spk_), allocatable :: vx(:)
+ integer(psb_ipk_), allocatable :: ivx(:)
+ integer(psb_ipk_) :: nrmv, nx, i
+
+ nrmv = x%get_nrmv()
+ call psb_s_remote_vect(nrmv,x%rmtv,x%rmidx,desc_a,vx,lvx,info)
+ nx = size(vx)
+ call psb_realloc(nx,ivx,info)
+ call desc_a%g2l(lvx,ivx,info,owned=.true.)
+ call x%ins(nx,ivx,vx,info)
+ end block
+ end if
+
call x%asb(ncol,info)
! ..update halo elements..
call psb_halo(x,desc_a,info)
@@ -140,7 +157,7 @@ subroutine psb_sasb_vect_r2(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, i, n
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -159,7 +176,6 @@ subroutine psb_sasb_vect_r2(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -185,6 +201,7 @@ subroutine psb_sasb_vect_r2(x, desc_a, info, mold, scratch)
else
do i=1, n
+ dupl_ = x(i)%get_dupl()
call x(i)%asb(ncol,info)
if (info /= 0) exit
! ..update halo elements..
@@ -225,7 +242,7 @@ subroutine psb_sasb_multivect(x, desc_a, info, mold, scratch,n)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
@@ -271,6 +288,7 @@ subroutine psb_sasb_multivect(x, desc_a, info, mold, scratch,n)
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': sizes: ',nrow,ncol
+ dupl_ = x%get_dupl()
if (scratch_) then
call x%free(info)
call x%bld(ncol,n_,mold=mold)
diff --git a/base/tools/psb_sins.f90 b/base/tools/psb_sins.f90
index cb878c64..ddead81f 100644
--- a/base/tools/psb_sins.f90
+++ b/base/tools/psb_sins.f90
@@ -42,10 +42,7 @@
! x - type(psb_s_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_sins_vect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_sins_vect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_sins_vect
use psi_mod
implicit none
@@ -57,14 +54,14 @@ subroutine psb_sins_vect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_s_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
+ integer(psb_ipk_) :: dupl_
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_,err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -112,7 +109,6 @@ subroutine psb_sins_vect(m, irw, val, x, desc_a, info, dupl,local)
endif
-
allocate(irl(m),stat=info)
if (info /= psb_success_) then
info = psb_err_alloc_dealloc_
@@ -120,11 +116,6 @@ subroutine psb_sins_vect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -136,11 +127,33 @@ subroutine psb_sins_vect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
end if
+ if (x%is_remote_build()) then
+ block
+ integer(psb_ipk_) :: j,k
+ k = x%get_nrmv()
+ do j=1,m
+ if (irl(j) < 0 ) then
+ k = k + 1
+ call psb_ensure_size(k,x%rmtv,info)
+ if (info == 0) call psb_ensure_size(k,x%rmidx,info)
+ if (info /= 0) then
+ info = psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+ x%rmtv(k) = val(j)
+ x%rmidx(k) = irw(j)
+ call x%set_nrmv(k)
+ end if
+ end do
+ end block
+ end if
+
deallocate(irl)
call psb_erractionrestore(err_act)
@@ -166,10 +179,7 @@ end subroutine psb_sins_vect
! x - type(psb_s_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_sins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_sins_vect_v(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_sins_vect_v
use psi_mod
implicit none
@@ -185,14 +195,13 @@ subroutine psb_sins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
type(psb_s_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols,err_act
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_
+ integer(psb_ipk_) :: np, me
integer(psb_ipk_), allocatable :: irl(:)
real(psb_spk_), allocatable :: lval(:)
logical :: local_
@@ -239,14 +248,6 @@ subroutine psb_sins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call psb_errpush(info,name)
goto 9999
endif
-
-
-
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -260,7 +261,7 @@ subroutine psb_sins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call desc_a%indxmap%g2l(irw%v%v(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,lval,dupl_,info)
+ call x%ins(m,irl,lval,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
@@ -275,7 +276,7 @@ subroutine psb_sins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_sins_vect_v
-subroutine psb_sins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_sins_vect_r2(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_sins_vect_r2
use psi_mod
implicit none
@@ -291,14 +292,13 @@ subroutine psb_sins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
type(psb_s_vect_type), intent(inout) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols, n
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -353,11 +353,6 @@ subroutine psb_sins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -371,8 +366,9 @@ subroutine psb_sins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end if
do i=1,n
+
if (.not.allocated(x(i)%v)) info = psb_err_invalid_vect_state_
- if (info == 0) call x(i)%ins(m,irl,val(:,i),dupl_,info)
+ if (info == 0) call x(i)%ins(m,irl,val(:,i),info)
if (info /= 0) exit
end do
if (info /= 0) then
@@ -390,7 +386,7 @@ subroutine psb_sins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_sins_vect_r2
-subroutine psb_sins_multivect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_sins_multivect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_sins_multivect
use psi_mod
implicit none
@@ -406,14 +402,13 @@ subroutine psb_sins_multivect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_s_multivect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -469,11 +464,6 @@ subroutine psb_sins_multivect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -485,7 +475,7 @@ subroutine psb_sins_multivect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
diff --git a/base/tools/psb_sspalloc.f90 b/base/tools/psb_sspalloc.f90
index 15c3c538..8004e742 100644
--- a/base/tools/psb_sspalloc.f90
+++ b/base/tools/psb_sspalloc.f90
@@ -41,21 +41,23 @@
! nnz - integer(optional). The number of nonzeroes in the matrix.
! (local, user estimate)
!
-subroutine psb_sspalloc(a, desc_a, info, nnz)
+subroutine psb_sspalloc(a, desc_a, info, nnz, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_sspalloc
implicit none
!....parameters...
- type(psb_desc_type), intent(in) :: desc_a
- type(psb_sspmat_type), intent(inout) :: a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: nnz
+ type(psb_desc_type), intent(in) :: desc_a
+ type(psb_sspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: nnz
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_) :: loc_row,loc_col, nnz_, dectype
- integer(psb_lpk_) :: m, n
+ integer(psb_ipk_) :: dupl_, bldmode_
+ integer(psb_lpk_) :: m, n, nnzrmt_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -96,7 +98,7 @@ subroutine psb_sspalloc(a, desc_a, info, nnz)
else
nnz_ = max(1,5*loc_row)
endif
-
+
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name), &
& ':allocating size:',loc_row,loc_col,nnz_
@@ -109,6 +111,24 @@ subroutine psb_sspalloc(a, desc_a, info, nnz)
goto 9999
end if
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call a%set_dupl(dupl_)
+ call a%set_remote_build(bldmode_)
+ if (a%is_remote_build()) then
+ allocate(a%rmta)
+ nnzrmt_ = max(100,(nnz_/100))
+ call a%rmta%allocate(m,n,nnzrmt_)
+ end if
+
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': ', &
& desc_a%get_dectype(),psb_desc_bld_
diff --git a/base/tools/psb_sspasb.f90 b/base/tools/psb_sspasb.f90
index f4e6169d..cfa316eb 100644
--- a/base/tools/psb_sspasb.f90
+++ b/base/tools/psb_sspasb.f90
@@ -42,31 +42,29 @@
! upd - character(optional). How will the matrix be updated?
! psb_upd_srch_ Simple strategy
! psb_upd_perm_ Permutation(more memory)
-! dupl - integer(optional). Duplicate coefficient handling:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-! psb_dupl_err_ raise an error.
!
!
-subroutine psb_sspasb(a,desc_a, info, afmt, upd, dupl, mold)
+subroutine psb_sspasb(a,desc_a, info, afmt, upd, mold)
use psb_base_mod, psb_protect_name => psb_sspasb
+ use psb_sort_mod
use psi_mod
implicit none
!...Parameters....
- type(psb_sspmat_type), intent (inout) :: a
- type(psb_desc_type), intent(in) :: desc_a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_),optional, intent(in) :: dupl, upd
- character(len=*), optional, intent(in) :: afmt
+ type(psb_sspmat_type), intent (inout) :: a
+ type(psb_desc_type), intent(inout) :: desc_a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: upd
+ character(len=*), optional, intent(in) :: afmt
class(psb_s_base_sparse_mat), intent(in), optional :: mold
!....Locals....
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, err_act
- integer(psb_ipk_) :: n_row,n_col
+ integer(psb_ipk_) :: n_row,n_col, dupl_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name, ch_err
+ class(psb_i_base_vect_type), allocatable :: ivm
info = psb_success_
name = 'psb_spasb'
@@ -92,28 +90,79 @@ subroutine psb_sspasb(a,desc_a, info, afmt, upd, dupl, mold)
goto 9999
end if
-
if (debug_level >= psb_debug_ext_)&
& write(debug_unit, *) me,' ',trim(name),&
& ' Begin matrix assembly...'
!check on errors encountered in psdspins
-
- if (a%is_bld()) then
+ if (a%is_bld()) then
+ dupl_ = a%get_dupl()
!
! First case: we come from a fresh build.
!
-
- n_row = desc_a%get_local_rows()
- n_col = desc_a%get_local_cols()
- call a%set_nrows(n_row)
- call a%set_ncols(n_col)
- end if
-
- if (a%is_bld()) then
- call a%cscnv(info,type=afmt,dupl=dupl, mold=mold)
+ if (a%is_remote_build()) then
+ !write(0,*) me,name,' Size of rmta:',a%rmta%get_nzeros()
+ block
+ type(psb_ls_coo_sparse_mat) :: a_add
+ integer(psb_ipk_), allocatable :: ila(:), jla(:)
+ integer(psb_ipk_) :: nz, nzt,k
+ call psb_remote_mat(a%rmta,desc_a,a_add,info)
+ nz = a_add%get_nzeros()
+ nzt = nz
+ call psb_sum(ctxt,nzt)
+ if (nzt>0) then
+ allocate(ivm, mold=desc_a%v_halo_index%v)
+ call psb_cd_reinit(desc_a, info)
+ end if
+ if (nz > 0) then
+ !
+ ! Should we check for new indices here?
+ !
+ call psb_realloc(nz,ila,info)
+ call psb_realloc(nz,jla,info)
+ call desc_a%indxmap%g2l(a_add%ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l_ins(a_add%ja(1:nz),jla(1:nz),info)
+ !write(0,*) me,name,' Check before insert',a%get_nzeros()
+ n_row = desc_a%get_local_rows()
+ n_col = desc_a%get_local_cols()
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%csput(nz,ila,jla,a_add%val,ione,n_row,ione,n_col,info)
+ !write(0,*) me,name,' Check after insert',a%get_nzeros(),nz
+ end if
+ if (nzt > 0) call psb_cdasb(desc_a,info,mold=ivm)
+
+ end block
+ end if
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%cscnv(info,type=afmt,mold=mold,dupl=dupl_)
else if (a%is_upd()) then
+ if (a%is_remote_build()) then
+ !write(0,*) me,name,' Size of rmta:',a%rmta%get_nzeros()
+ block
+ type(psb_ls_coo_sparse_mat) :: a_add
+ integer(psb_ipk_), allocatable :: ila(:), jla(:)
+ integer(psb_ipk_) :: nz, nzt,k
+ call psb_remote_mat(a%rmta,desc_a,a_add,info)
+ nz = a_add%get_nzeros()
+!!$ write(0,*) me,name,' Nz to be added',nz
+ if (nz > 0) then
+ !
+ ! Should we check for new indices here?
+ !
+ call psb_realloc(nz,ila,info)
+ call psb_realloc(nz,jla,info)
+ call desc_a%indxmap%g2l(a_add%ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l_ins(a_add%ja(1:nz),jla(1:nz),info)
+ !write(0,*) me,name,' Check before insert',a%get_nzeros()
+ n_row = desc_a%get_local_rows()
+ n_col = desc_a%get_local_cols()
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%csput(nz,ila,jla,a_add%val,ione,n_row,ione,n_col,info)
+ !write(0,*) me,name,' Check after insert',a%get_nzeros(),nz
+ end if
+ end block
+ end if
call a%asb(mold=mold)
else
info = psb_err_invalid_mat_state_
diff --git a/base/tools/psb_sspins.F90 b/base/tools/psb_sspins.F90
index 1fd6eed0..aee7a900 100644
--- a/base/tools/psb_sspins.F90
+++ b/base/tools/psb_sspins.F90
@@ -70,6 +70,10 @@ subroutine psb_sspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
integer(psb_ipk_), parameter :: relocsz=200
logical :: rebuild_, local_
integer(psb_ipk_), allocatable :: ila(:),jla(:)
+ integer(psb_ipk_) :: i,k
+ integer(psb_lpk_) :: nnl
+ integer(psb_lpk_), allocatable :: lila(:),ljla(:)
+ real(psb_spk_), allocatable :: lval(:)
character(len=20) :: name
info = psb_success_
@@ -147,6 +151,27 @@ subroutine psb_sspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
call psb_errpush(info,name,a_err='a%csput')
goto 9999
end if
+
+ if (a%is_remote_build()) then
+ nnl = count(ila(1:nz)<0)
+ if (nnl > 0) then
+ !write(0,*) 'Check on insert ',nnl
+ allocate(lila(nnl),ljla(nnl),lval(nnl))
+ k = 0
+ do i=1,nz
+ if (ila(i)<0) then
+ k=k+1
+ lila(k) = ia(i)
+ ljla(k) = ja(i)
+ lval(k) = val(i)
+ end if
+ end do
+ if (k /= nnl) write(0,*) name,' Wrong conversion?',k,nnl
+ call a%rmta%csput(nnl,lila,ljla,lval,1_psb_lpk_,desc_a%get_global_rows(),&
+ & 1_psb_lpk_,desc_a%get_global_rows(),info)
+ end if
+ end if
+
else
info = psb_err_invalid_a_and_cd_state_
call psb_errpush(info,name)
@@ -168,8 +193,9 @@ subroutine psb_sspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
ila(1:nz) = ia(1:nz)
jla(1:nz) = ja(1:nz)
else
- call desc_a%indxmap%g2l(ia(1:nz),ila(1:nz),info)
- if (info == 0) call desc_a%indxmap%g2l(ja(1:nz),jla(1:nz),info)
+ call desc_a%indxmap%g2l(ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l(ja(1:nz),jla(1:nz),info,&
+ & mask=(ila(1:nz)>0))
end if
call a%csput(nz,ila,jla,val,ione,nrow,ione,ncol,info)
if (info /= psb_success_) then
@@ -177,6 +203,25 @@ subroutine psb_sspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
call psb_errpush(info,name,a_err='a%csput')
goto 9999
end if
+ if (a%is_remote_build()) then
+ nnl = count(ila(1:nz)<0)
+ if (nnl > 0) then
+ !write(0,*) 'Check on insert ',nnl
+ allocate(lila(nnl),ljla(nnl),lval(nnl))
+ k = 0
+ do i=1,nz
+ if (ila(i)<0) then
+ k=k+1
+ lila(k) = ia(k)
+ ljla(k) = ja(k)
+ lval(k) = val(k)
+ end if
+ end do
+ if (k /= nnl) write(0,*) name,' Wrong conversion?',k,nnl
+ call a%rmta%csput(nnl,lila,ljla,lval,1_psb_lpk_,desc_a%get_global_rows(),&
+ & 1_psb_lpk_,desc_a%get_global_rows(),info)
+ end if
+ end if
else
info = psb_err_invalid_cd_state_
call psb_errpush(info,name)
diff --git a/base/tools/psb_z_remote_mat.F90 b/base/tools/psb_z_remote_mat.F90
new file mode 100644
index 00000000..fc23bd4a
--- /dev/null
+++ b/base/tools/psb_z_remote_mat.F90
@@ -0,0 +1,436 @@
+!
+! 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.
+!
+!
+! File: psb_z_remote_mat.f90
+!
+! Subroutine:
+! This routine does the retrieval of remote matrix rows.
+! Retrieval is done through GETROW, therefore it should work
+! for any matrix format in A; as for the output, default is CSR.
+!
+! There is also a specialized version lz_CSR whose interface
+! is adapted for the needs of z_par_csr_spspmm.
+!
+! There are three possible exchange algorithms:
+! 1. Use MPI_Alltoallv
+! 2. Use psb_simple_a2av
+! 3. Use psb_simple_triad_a2av
+! Default choice is 3. The MPI variant has proved to be inefficient;
+! that is because it is not persistent, therefore you pay the initialization price
+! every time, and it is not optimized for a sparse communication pattern,
+! most MPI implementations assume that all communications are non-empty.
+! The PSB_SIMPLE variants reuse the same communicator, and go for a simplistic
+! sequence of sends/receive that is quite efficient for a sparse communication
+! pattern. To be refined/reviewed in the future to compare with neighbour
+! persistent collectives.
+!
+! Arguments:
+! a - type(psb_zspmat_type) The local part of input matrix A
+! desc_a - type(psb_desc_type). The communication descriptor.
+! blck - type(psb_zspmat_type) The local part of output matrix BLCK
+! info - integer. Return code
+! rowcnv - logical Should row/col indices be converted
+! colcnv - logical to/from global numbering when sent/received?
+! default is .TRUE.
+! rowscale - logical Should row/col indices on output be remapped
+! colscale - logical from MIN:MAX to 1:(MAX-MIN+1) ?
+! default is .FALSE.
+! (commmon use is ROWSCALE=.TRUE., COLSCALE=.FALSE.)
+! data - integer Which index list in desc_a should be used to retrieve
+! rows, default psb_comm_halo_
+! psb_comm_halo_ use halo_index
+! psb_comm_ext_ use ext_index
+! psb_comm_ovrl_ DISABLED for this routine.
+!
+Subroutine psb_lz_remote_mat(a,desc_a,b,info)
+ use psb_base_mod, psb_protect_name => psb_lz_remote_mat
+
+#ifdef MPI_MOD
+ use mpi
+#endif
+ Implicit None
+#ifdef MPI_H
+ include 'mpif.h'
+#endif
+
+ Type(psb_lz_coo_sparse_mat),Intent(inout) :: a
+ Type(psb_lz_coo_sparse_mat),Intent(inout) :: b
+ Type(psb_desc_type), Intent(inout) :: desc_a
+ integer(psb_ipk_), intent(out) :: info
+
+ ! ...local scalars....
+ type(psb_ctxt_type) :: ctxt
+ integer(psb_ipk_) :: np,me
+ integer(psb_ipk_) :: counter, proc, i, n_el_send,n_el_recv, &
+ & n_elem, j, ipx,idxs,idxr
+ integer(psb_lpk_) :: r, k, irmin, irmax, icmin, icmax, iszs, iszr, &
+ & lidx, l1, lnr, lnc, lnnz, idx, ngtz, tot_elem
+ integer(psb_lpk_) :: nz,nouth
+ integer(psb_ipk_) :: nrcvs, nsnds
+ integer(psb_mpk_) :: icomm, minfo
+ integer(psb_mpk_), allocatable :: brvindx(:), &
+ & rvsz(:), bsdindx(:),sdsz(:), sdsi(:), rvsi(:)
+ integer(psb_lpk_), allocatable :: iasnd(:), jasnd(:)
+ complex(psb_dpk_), allocatable :: valsnd(:)
+ type(psb_lz_coo_sparse_mat), allocatable :: acoo
+ class(psb_i_base_vect_type), pointer :: pdxv
+ integer(psb_ipk_), allocatable :: ila(:), iprc(:)
+ logical :: rowcnv_,colcnv_,rowscale_,colscale_
+ character(len=5) :: outfmt_
+ integer(psb_ipk_) :: debug_level, debug_unit, err_act
+ character(len=20) :: name, ch_err
+
+ info=psb_success_
+ name='psb_z_remote_mat'
+ call psb_erractionsave(err_act)
+ if (psb_errstatus_fatal()) then
+ info = psb_err_internal_error_ ; goto 9999
+ end if
+ debug_unit = psb_get_debug_unit()
+ debug_level = psb_get_debug_level()
+
+ ctxt = desc_a%get_context()
+ icomm = desc_a%get_mpic()
+
+ Call psb_info(ctxt, me, np)
+
+ if (debug_level >= psb_debug_outer_) &
+ & write(debug_unit,*) me,' ',trim(name),': Start'
+
+
+ call b%free()
+
+ Allocate(rvsz(np),sdsz(np),sdsi(np),rvsi(np),brvindx(np+1),&
+ & bsdindx(np+1), acoo,stat=info)
+
+ if (info /= psb_success_) then
+ info=psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+
+
+ nz = a%get_nzeros()
+ !allocate(ila(nz))
+ !write(0,*) me,name,' size :',nz,size(ila)
+ !call desc_a%g2l(a%ia(1:nz),ila(1:nz),info,owned=.false.)
+ !nouth = count(ila(1:nz)<0)
+ !write(0,*) me,name,' Count out of halo :',nouth
+ !call psb_max(ctxt,nouth)
+ !if ((nouth/=0).and.(me==0)) &
+ ! & write(0,*) 'Warning: would require reinit of DESC_A'
+
+ call desc_a%indxmap%fnd_owner(a%ia(1:nz),iprc,info)
+
+ icomm = desc_a%get_mpic()
+ sdsz(:)=0
+ rvsz(:)=0
+ sdsi(:)=0
+ rvsi(:)=0
+ ipx = 1
+ brvindx(:) = 0
+ bsdindx(:) = 0
+ counter=1
+ idx = 0
+ idxs = 0
+ idxr = 0
+ do i=1,nz
+ if (iprc(i) >=0) then
+ sdsz(iprc(i)+1) = sdsz(iprc(i)+1) +1
+ else
+ write(0,*)me,name,' Error from fnd_owner: ',iprc(i)
+ end if
+ end do
+ call mpi_alltoall(sdsz,1,psb_mpi_mpk_,&
+ & rvsz,1,psb_mpi_mpk_,icomm,minfo)
+ if (minfo /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='mpi_alltoall')
+ goto 9999
+ end if
+ !write(0,*)me,name,' sdsz ',sdsz(:),' rvsz:',rvsz(:)
+ nsnds = count(sdsz /= 0)
+ nrcvs = count(rvsz /= 0)
+ idxs = 0
+ idxr = 0
+ counter = 1
+ Do proc=0,np-1
+ bsdindx(proc+1) = idxs
+ idxs = idxs + sdsz(proc+1)
+ brvindx(proc+1) = idxr
+ idxr = idxr + rvsz(proc+1)
+ Enddo
+
+ iszs = sum(sdsz)
+ iszr = sum(rvsz)
+ call acoo%allocate(desc_a%get_global_rows(),desc_a%get_global_cols(),iszr)
+ if (psb_errstatus_fatal()) then
+ write(0,*) 'Error from acoo%allocate '
+ info = 4010
+ goto 9999
+ end if
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Sizes:',acoo%get_size(),&
+ & ' Send:',sdsz(:),' Receive:',rvsz(:)
+ !write(debug_unit,*) me,' ',trim(name),': ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),iasnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' iasnd: ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),jasnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' jasnd: ',info
+ if (info == psb_success_) call psb_ensure_size(max(iszs,1),valsnd,info)
+ !write(debug_unit,*) me,' ',trim(name),' valsnd: ',info
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='ensure_size')
+ goto 9999
+ end if
+ do k=1, nz
+ proc = iprc(k)
+ sdsi(proc+1) = sdsi(proc+1) + 1
+ !rvsi(proc) = rvsi(proc) + 1
+ iasnd(bsdindx(proc+1)+sdsi(proc+1)) = a%ia(k)
+ jasnd(bsdindx(proc+1)+sdsi(proc+1)) = a%ja(k)
+ valsnd(bsdindx(proc+1)+sdsi(proc+1)) = a%val(k)
+ end do
+ do proc=0,np-1
+ if (sdsi(proc+1) /= sdsz(proc+1)) &
+ & write(0,*) me,name,'Send mismacth ',sdsi(proc+1),sdsz(proc+1)
+ end do
+
+ select case(psb_get_sp_a2av_alg())
+ case(psb_sp_a2av_smpl_triad_)
+ call psb_simple_triad_a2av(valsnd,iasnd,jasnd,sdsz,bsdindx,&
+ & acoo%val,acoo%ia,acoo%ja,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_smpl_v_)
+ call psb_simple_a2av(valsnd,sdsz,bsdindx,&
+ & acoo%val,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(iasnd,sdsz,bsdindx,&
+ & acoo%ia,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(jasnd,sdsz,bsdindx,&
+ & acoo%ja,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_mpi_)
+
+ call mpi_alltoallv(valsnd,sdsz,bsdindx,psb_mpi_c_dpk_,&
+ & acoo%val,rvsz,brvindx,psb_mpi_c_dpk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(iasnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & acoo%ia,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(jasnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & acoo%ja,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo /= mpi_success) info = minfo
+ case default
+ info = psb_err_internal_error_
+ call psb_errpush(info,name,a_err='wrong A2AV alg selector')
+ goto 9999
+ end select
+
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='alltoallv')
+ goto 9999
+ end if
+ call acoo%set_nzeros(iszr)
+ call acoo%mv_to_coo(b,info)
+
+ Deallocate(brvindx,bsdindx,rvsz,sdsz,&
+ & iasnd,jasnd,valsnd,stat=info)
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Done'
+
+ call psb_erractionrestore(err_act)
+ return
+
+9999 call psb_error_handler(ctxt,err_act)
+
+ return
+
+End Subroutine psb_lz_remote_mat
+
+
+subroutine psb_z_remote_vect(n,v,iv,desc_a,x,ix, info)
+ use psb_base_mod, psb_protect_name => psb_z_remote_vect
+
+#ifdef MPI_MOD
+ use mpi
+#endif
+ Implicit None
+#ifdef MPI_H
+ include 'mpif.h'
+#endif
+ integer(psb_ipk_), intent(in) :: n
+ complex(psb_dpk_), Intent(in) :: v(:)
+ integer(psb_lpk_), Intent(in) :: iv(:)
+ type(psb_desc_type),intent(in) :: desc_a
+ complex(psb_dpk_), allocatable, intent(out) :: x(:)
+ integer(psb_lpk_), allocatable, intent(out) :: ix(:)
+ integer(psb_ipk_), intent(out) :: info
+ ! ...local scalars....
+ type(psb_ctxt_type) :: ctxt
+ integer(psb_ipk_) :: np,me
+ integer(psb_ipk_) :: counter, proc, i, &
+ & j, idxs,idxr, k, iszs, iszr
+ integer(psb_ipk_) :: nrcvs, nsnds
+ integer(psb_mpk_) :: icomm, minfo
+ integer(psb_mpk_), allocatable :: brvindx(:), &
+ & rvsz(:), bsdindx(:), sdsz(:), sdsi(:), rvsi(:)
+ integer(psb_lpk_), allocatable :: lsnd(:)
+ complex(psb_dpk_), allocatable :: valsnd(:)
+ integer(psb_ipk_), allocatable :: iprc(:)
+ integer(psb_ipk_) :: debug_level, debug_unit, err_act
+ character(len=20) :: name, ch_err
+
+ info=psb_success_
+ name='psb_z_remote_vect'
+ call psb_erractionsave(err_act)
+ if (psb_errstatus_fatal()) then
+ info = psb_err_internal_error_ ; goto 9999
+ end if
+ debug_unit = psb_get_debug_unit()
+ debug_level = psb_get_debug_level()
+
+ ctxt = desc_a%get_context()
+ icomm = desc_a%get_mpic()
+
+ Call psb_info(ctxt, me, np)
+
+ if (debug_level >= psb_debug_outer_) &
+ & write(debug_unit,*) me,' ',trim(name),': Start'
+
+ Allocate(rvsz(np),sdsz(np),sdsi(np),rvsi(np),brvindx(np+1),&
+ & bsdindx(np+1), stat=info)
+
+ if (info /= psb_success_) then
+ info=psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+
+ call desc_a%indxmap%fnd_owner(iv(1:n),iprc,info)
+
+ icomm = desc_a%get_mpic()
+ sdsz(:) = 0
+ rvsz(:) = 0
+ sdsi(:) = 0
+ rvsi(:) = 0
+ brvindx(:) = 0
+ bsdindx(:) = 0
+ counter = 1
+ idxs = 0
+ idxr = 0
+ do i=1,n
+ if (iprc(i) >=0) then
+ sdsz(iprc(i)+1) = sdsz(iprc(i)+1) +1
+ else
+ write(0,*)me,name,' Error from fnd_owner: ',iprc(i)
+ end if
+ end do
+ call mpi_alltoall(sdsz,1,psb_mpi_mpk_,&
+ & rvsz,1,psb_mpi_mpk_,icomm,minfo)
+ if (minfo /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='mpi_alltoall')
+ goto 9999
+ end if
+ !write(0,*)me,name,' sdsz ',sdsz(:),' rvsz:',rvsz(:)
+ nsnds = count(sdsz /= 0)
+ nrcvs = count(rvsz /= 0)
+ idxs = 0
+ idxr = 0
+ counter = 1
+ Do proc=0,np-1
+ bsdindx(proc+1) = idxs
+ idxs = idxs + sdsz(proc+1)
+ brvindx(proc+1) = idxr
+ idxr = idxr + rvsz(proc+1)
+ Enddo
+
+ iszs = sum(sdsz)
+ iszr = sum(rvsz)
+ call psb_realloc(iszs,lsnd,info)
+ if (info == 0) call psb_realloc(iszs,valsnd,info)
+ if (info == 0) call psb_realloc(iszr,x,info)
+ if (info == 0) call psb_realloc(iszr,ix,info)
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='realloc')
+ goto 9999
+ end if
+ do k=1, n
+ proc = iprc(k)
+ sdsi(proc+1) = sdsi(proc+1) + 1
+ lsnd(bsdindx(proc+1)+sdsi(proc+1)) = iv(k)
+ valsnd(bsdindx(proc+1)+sdsi(proc+1)) = v(k)
+ end do
+ do proc=0,np-1
+ if (sdsi(proc+1) /= sdsz(proc+1)) &
+ & write(0,*) me,name,'Send mismacth ',sdsi(proc+1),sdsz(proc+1)
+ end do
+
+ select case(psb_get_sp_a2av_alg())
+ case(psb_sp_a2av_smpl_triad_,psb_sp_a2av_smpl_v_)
+ call psb_simple_a2av(valsnd,sdsz,bsdindx,&
+ & x,rvsz,brvindx,ctxt,info)
+ if (info == psb_success_) call psb_simple_a2av(lsnd,sdsz,bsdindx,&
+ & ix,rvsz,brvindx,ctxt,info)
+ case(psb_sp_a2av_mpi_)
+
+ call mpi_alltoallv(valsnd,sdsz,bsdindx,psb_mpi_c_dpk_,&
+ & x,rvsz,brvindx,psb_mpi_c_dpk_,icomm,minfo)
+ if (minfo == mpi_success) &
+ & call mpi_alltoallv(lsnd,sdsz,bsdindx,psb_mpi_lpk_,&
+ & ix,rvsz,brvindx,psb_mpi_lpk_,icomm,minfo)
+ if (minfo /= mpi_success) info = minfo
+ case default
+ info = psb_err_internal_error_
+ call psb_errpush(info,name,a_err='wrong A2AV alg selector')
+ goto 9999
+ end select
+
+ if (info /= psb_success_) then
+ info=psb_err_from_subroutine_
+ call psb_errpush(info,name,a_err='alltoallv')
+ goto 9999
+ end if
+
+ Deallocate(brvindx,bsdindx,rvsz,sdsz,&
+ & lsnd,valsnd,stat=info)
+ if (debug_level >= psb_debug_outer_)&
+ & write(debug_unit,*) me,' ',trim(name),': Done'
+
+ call psb_erractionrestore(err_act)
+ return
+
+9999 call psb_error_handler(ctxt,err_act)
+
+ return
+
+End Subroutine psb_z_remote_vect
diff --git a/base/tools/psb_zallc.f90 b/base/tools/psb_zallc.f90
index fa84827e..be4d9089 100644
--- a/base/tools/psb_zallc.f90
+++ b/base/tools/psb_zallc.f90
@@ -40,7 +40,7 @@
! x - the vector to be allocated.
! desc_a - the communication descriptor.
! info - Return code
-subroutine psb_zalloc_vect(x, desc_a,info)
+subroutine psb_zalloc_vect(x, desc_a,info, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_zalloc_vect
use psi_mod
implicit none
@@ -49,9 +49,11 @@ subroutine psb_zalloc_vect(x, desc_a,info)
type(psb_z_vect_type), intent(out) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
integer(psb_ipk_) :: np,me,nr,i,err_act
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -102,6 +104,25 @@ subroutine psb_zalloc_vect(x, desc_a,info)
endif
call x%zero()
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ call x%set_nrmv(0)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ call psb_ensure_size(nrmt_,x%rmtv,info)
+ call psb_ensure_size(nrmt_,x%rmidx,info)
+ end if
+
call psb_erractionrestore(err_act)
return
@@ -110,6 +131,7 @@ subroutine psb_zalloc_vect(x, desc_a,info)
return
end subroutine psb_zalloc_vect
+
! Function: psb_zalloc_vect_r2
! Allocates a vector of dense vectors for PSBLAS routines.
! The descriptor may be in either the build or assembled state.
@@ -121,7 +143,7 @@ end subroutine psb_zalloc_vect
! n - optional number of columns.
! lb - optional lower bound on column indices
-subroutine psb_zalloc_vect_r2(x, desc_a,info,n,lb)
+subroutine psb_zalloc_vect_r2(x, desc_a,info,n,lb, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_zalloc_vect_r2
use psi_mod
implicit none
@@ -131,10 +153,12 @@ subroutine psb_zalloc_vect_r2(x, desc_a,info,n,lb)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n,lb
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -208,6 +232,26 @@ subroutine psb_zalloc_vect_r2(x, desc_a,info,n,lb)
if (info /= 0) exit
end do
end if
+
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+
+ do i=lb_, lb_+n_-1
+ call x(i)%set_dupl(dupl_)
+ call x(i)%set_remote_build(bldmode_)
+ if (x(i)%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x(i)%rmtv(nrmt_))
+ end if
+ end do
if (psb_errstatus_fatal()) then
info=psb_err_alloc_request_
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
@@ -224,7 +268,7 @@ subroutine psb_zalloc_vect_r2(x, desc_a,info,n,lb)
end subroutine psb_zalloc_vect_r2
-subroutine psb_zalloc_multivect(x, desc_a,info,n)
+subroutine psb_zalloc_multivect(x, desc_a,info,n, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_zalloc_multivect
use psi_mod
implicit none
@@ -234,10 +278,12 @@ subroutine psb_zalloc_multivect(x, desc_a,info,n)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_),intent(out) :: info
integer(psb_ipk_), optional, intent(in) :: n
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me,nr,i,err_act, n_, lb_
+ integer(psb_ipk_) :: dupl_, bldmode_, nrmt_
integer(psb_ipk_) :: exch(1)
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -306,6 +352,23 @@ subroutine psb_zalloc_multivect(x, desc_a,info,n)
call psb_errpush(info,name,i_err=(/nr/),a_err='real(psb_spk_)')
goto 9999
endif
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call x%set_dupl(dupl_)
+ call x%set_remote_build(bldmode_)
+ if (x%is_remote_build()) then
+ nrmt_ = max(100,(desc_a%get_local_cols()-desc_a%get_local_rows()))
+ allocate(x%rmtv(nrmt_,n_))
+ end if
+
call psb_erractionrestore(err_act)
return
diff --git a/base/tools/psb_zasb.f90 b/base/tools/psb_zasb.f90
index 34706841..11c08d6d 100644
--- a/base/tools/psb_zasb.f90
+++ b/base/tools/psb_zasb.f90
@@ -64,7 +64,7 @@ subroutine psb_zasb_vect(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -83,7 +83,7 @@ subroutine psb_zasb_vect(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
+ dupl_ = x%get_dupl()
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -104,6 +104,23 @@ subroutine psb_zasb_vect(x, desc_a, info, mold, scratch)
call x%free(info)
call x%bld(ncol,mold=mold)
else
+
+ if (x%is_remote_build()) then
+ block
+ integer(psb_lpk_), allocatable :: lvx(:)
+ complex(psb_dpk_), allocatable :: vx(:)
+ integer(psb_ipk_), allocatable :: ivx(:)
+ integer(psb_ipk_) :: nrmv, nx, i
+
+ nrmv = x%get_nrmv()
+ call psb_z_remote_vect(nrmv,x%rmtv,x%rmidx,desc_a,vx,lvx,info)
+ nx = size(vx)
+ call psb_realloc(nx,ivx,info)
+ call desc_a%g2l(lvx,ivx,info,owned=.true.)
+ call x%ins(nx,ivx,vx,info)
+ end block
+ end if
+
call x%asb(ncol,info)
! ..update halo elements..
call psb_halo(x,desc_a,info)
@@ -140,7 +157,7 @@ subroutine psb_zasb_vect_r2(x, desc_a, info, mold, scratch)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, i, n
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name,ch_err
@@ -159,7 +176,6 @@ subroutine psb_zasb_vect_r2(x, desc_a, info, mold, scratch)
scratch_ = .false.
if (present(scratch)) scratch_ = scratch
call psb_info(ctxt, me, np)
-
! ....verify blacs grid correctness..
if (np == -1) then
info = psb_err_context_error_
@@ -185,6 +201,7 @@ subroutine psb_zasb_vect_r2(x, desc_a, info, mold, scratch)
else
do i=1, n
+ dupl_ = x(i)%get_dupl()
call x(i)%asb(ncol,info)
if (info /= 0) exit
! ..update halo elements..
@@ -225,7 +242,7 @@ subroutine psb_zasb_multivect(x, desc_a, info, mold, scratch,n)
! local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me
- integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_
+ integer(psb_ipk_) :: i1sz,nrow,ncol, err_act, n_, dupl_
logical :: scratch_
integer(psb_ipk_) :: debug_level, debug_unit
@@ -271,6 +288,7 @@ subroutine psb_zasb_multivect(x, desc_a, info, mold, scratch,n)
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': sizes: ',nrow,ncol
+ dupl_ = x%get_dupl()
if (scratch_) then
call x%free(info)
call x%bld(ncol,n_,mold=mold)
diff --git a/base/tools/psb_zins.f90 b/base/tools/psb_zins.f90
index 19020379..43e5d5cd 100644
--- a/base/tools/psb_zins.f90
+++ b/base/tools/psb_zins.f90
@@ -42,10 +42,7 @@
! x - type(psb_z_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_zins_vect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_zins_vect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_zins_vect
use psi_mod
implicit none
@@ -57,14 +54,14 @@ subroutine psb_zins_vect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_z_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
+ integer(psb_ipk_) :: dupl_
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_,err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -112,7 +109,6 @@ subroutine psb_zins_vect(m, irw, val, x, desc_a, info, dupl,local)
endif
-
allocate(irl(m),stat=info)
if (info /= psb_success_) then
info = psb_err_alloc_dealloc_
@@ -120,11 +116,6 @@ subroutine psb_zins_vect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -136,11 +127,33 @@ subroutine psb_zins_vect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
end if
+ if (x%is_remote_build()) then
+ block
+ integer(psb_ipk_) :: j,k
+ k = x%get_nrmv()
+ do j=1,m
+ if (irl(j) < 0 ) then
+ k = k + 1
+ call psb_ensure_size(k,x%rmtv,info)
+ if (info == 0) call psb_ensure_size(k,x%rmidx,info)
+ if (info /= 0) then
+ info = psb_err_alloc_dealloc_
+ call psb_errpush(info,name)
+ goto 9999
+ end if
+ x%rmtv(k) = val(j)
+ x%rmidx(k) = irw(j)
+ call x%set_nrmv(k)
+ end if
+ end do
+ end block
+ end if
+
deallocate(irl)
call psb_erractionrestore(err_act)
@@ -166,10 +179,7 @@ end subroutine psb_zins_vect
! x - type(psb_z_vect_type) The destination vector
! desc_a - type(psb_desc_type). The communication descriptor.
! info - integer. return code
-! dupl - integer What to do with duplicates:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-subroutine psb_zins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_zins_vect_v(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_zins_vect_v
use psi_mod
implicit none
@@ -185,14 +195,13 @@ subroutine psb_zins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
type(psb_z_vect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols,err_act
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_
+ integer(psb_ipk_) :: np, me
integer(psb_ipk_), allocatable :: irl(:)
complex(psb_dpk_), allocatable :: lval(:)
logical :: local_
@@ -239,14 +248,6 @@ subroutine psb_zins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call psb_errpush(info,name)
goto 9999
endif
-
-
-
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -260,7 +261,7 @@ subroutine psb_zins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
call desc_a%indxmap%g2l(irw%v%v(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,lval,dupl_,info)
+ call x%ins(m,irl,lval,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
@@ -275,7 +276,7 @@ subroutine psb_zins_vect_v(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_zins_vect_v
-subroutine psb_zins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_zins_vect_r2(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_zins_vect_r2
use psi_mod
implicit none
@@ -291,14 +292,13 @@ subroutine psb_zins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
type(psb_z_vect_type), intent(inout) :: x(:)
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols, n
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -353,11 +353,6 @@ subroutine psb_zins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -371,8 +366,9 @@ subroutine psb_zins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end if
do i=1,n
+
if (.not.allocated(x(i)%v)) info = psb_err_invalid_vect_state_
- if (info == 0) call x(i)%ins(m,irl,val(:,i),dupl_,info)
+ if (info == 0) call x(i)%ins(m,irl,val(:,i),info)
if (info /= 0) exit
end do
if (info /= 0) then
@@ -390,7 +386,7 @@ subroutine psb_zins_vect_r2(m, irw, val, x, desc_a, info, dupl,local)
end subroutine psb_zins_vect_r2
-subroutine psb_zins_multivect(m, irw, val, x, desc_a, info, dupl,local)
+subroutine psb_zins_multivect(m, irw, val, x, desc_a, info, local)
use psb_base_mod, psb_protect_name => psb_zins_multivect
use psi_mod
implicit none
@@ -406,14 +402,13 @@ subroutine psb_zins_multivect(m, irw, val, x, desc_a, info, dupl,local)
type(psb_z_multivect_type), intent(inout) :: x
type(psb_desc_type), intent(in) :: desc_a
integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: dupl
logical, intent(in), optional :: local
!locals.....
integer(psb_ipk_) :: i, loc_rows,loc_cols
integer(psb_lpk_) :: mglob
type(psb_ctxt_type) :: ctxt
- integer(psb_ipk_) :: np, me, dupl_, err_act
+ integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_), allocatable :: irl(:)
logical :: local_
character(len=20) :: name
@@ -469,11 +464,6 @@ subroutine psb_zins_multivect(m, irw, val, x, desc_a, info, dupl,local)
goto 9999
endif
- if (present(dupl)) then
- dupl_ = dupl
- else
- dupl_ = psb_dupl_ovwrt_
- endif
if (present(local)) then
local_ = local
else
@@ -485,7 +475,7 @@ subroutine psb_zins_multivect(m, irw, val, x, desc_a, info, dupl,local)
else
call desc_a%indxmap%g2l(irw(1:m),irl(1:m),info,owned=.true.)
end if
- call x%ins(m,irl,val,dupl_,info)
+ call x%ins(m,irl,val,info)
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
diff --git a/base/tools/psb_zspalloc.f90 b/base/tools/psb_zspalloc.f90
index 16d48734..308774ef 100644
--- a/base/tools/psb_zspalloc.f90
+++ b/base/tools/psb_zspalloc.f90
@@ -41,21 +41,23 @@
! nnz - integer(optional). The number of nonzeroes in the matrix.
! (local, user estimate)
!
-subroutine psb_zspalloc(a, desc_a, info, nnz)
+subroutine psb_zspalloc(a, desc_a, info, nnz, dupl, bldmode)
use psb_base_mod, psb_protect_name => psb_zspalloc
implicit none
!....parameters...
- type(psb_desc_type), intent(in) :: desc_a
- type(psb_zspmat_type), intent(inout) :: a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_), optional, intent(in) :: nnz
+ type(psb_desc_type), intent(in) :: desc_a
+ type(psb_zspmat_type), intent(inout) :: a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: nnz
+ integer(psb_ipk_), optional, intent(in) :: dupl, bldmode
!locals
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, err_act
integer(psb_ipk_) :: loc_row,loc_col, nnz_, dectype
- integer(psb_lpk_) :: m, n
+ integer(psb_ipk_) :: dupl_, bldmode_
+ integer(psb_lpk_) :: m, n, nnzrmt_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name
@@ -96,7 +98,7 @@ subroutine psb_zspalloc(a, desc_a, info, nnz)
else
nnz_ = max(1,5*loc_row)
endif
-
+
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name), &
& ':allocating size:',loc_row,loc_col,nnz_
@@ -109,6 +111,24 @@ subroutine psb_zspalloc(a, desc_a, info, nnz)
goto 9999
end if
+ if (present(bldmode)) then
+ bldmode_ = bldmode
+ else
+ bldmode_ = psb_matbld_noremote_
+ end if
+ if (present(dupl)) then
+ dupl_ = dupl
+ else
+ dupl_ = psb_dupl_def_
+ end if
+ call a%set_dupl(dupl_)
+ call a%set_remote_build(bldmode_)
+ if (a%is_remote_build()) then
+ allocate(a%rmta)
+ nnzrmt_ = max(100,(nnz_/100))
+ call a%rmta%allocate(m,n,nnzrmt_)
+ end if
+
if (debug_level >= psb_debug_ext_) &
& write(debug_unit,*) me,' ',trim(name),': ', &
& desc_a%get_dectype(),psb_desc_bld_
diff --git a/base/tools/psb_zspasb.f90 b/base/tools/psb_zspasb.f90
index b5966110..aeeef94d 100644
--- a/base/tools/psb_zspasb.f90
+++ b/base/tools/psb_zspasb.f90
@@ -42,31 +42,29 @@
! upd - character(optional). How will the matrix be updated?
! psb_upd_srch_ Simple strategy
! psb_upd_perm_ Permutation(more memory)
-! dupl - integer(optional). Duplicate coefficient handling:
-! psb_dupl_ovwrt_ overwrite
-! psb_dupl_add_ add
-! psb_dupl_err_ raise an error.
!
!
-subroutine psb_zspasb(a,desc_a, info, afmt, upd, dupl, mold)
+subroutine psb_zspasb(a,desc_a, info, afmt, upd, mold)
use psb_base_mod, psb_protect_name => psb_zspasb
+ use psb_sort_mod
use psi_mod
implicit none
!...Parameters....
- type(psb_zspmat_type), intent (inout) :: a
- type(psb_desc_type), intent(in) :: desc_a
- integer(psb_ipk_), intent(out) :: info
- integer(psb_ipk_),optional, intent(in) :: dupl, upd
- character(len=*), optional, intent(in) :: afmt
+ type(psb_zspmat_type), intent (inout) :: a
+ type(psb_desc_type), intent(inout) :: desc_a
+ integer(psb_ipk_), intent(out) :: info
+ integer(psb_ipk_), optional, intent(in) :: upd
+ character(len=*), optional, intent(in) :: afmt
class(psb_z_base_sparse_mat), intent(in), optional :: mold
!....Locals....
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np,me, err_act
- integer(psb_ipk_) :: n_row,n_col
+ integer(psb_ipk_) :: n_row,n_col, dupl_
integer(psb_ipk_) :: debug_level, debug_unit
character(len=20) :: name, ch_err
+ class(psb_i_base_vect_type), allocatable :: ivm
info = psb_success_
name = 'psb_spasb'
@@ -92,28 +90,79 @@ subroutine psb_zspasb(a,desc_a, info, afmt, upd, dupl, mold)
goto 9999
end if
-
if (debug_level >= psb_debug_ext_)&
& write(debug_unit, *) me,' ',trim(name),&
& ' Begin matrix assembly...'
!check on errors encountered in psdspins
-
- if (a%is_bld()) then
+ if (a%is_bld()) then
+ dupl_ = a%get_dupl()
!
! First case: we come from a fresh build.
!
-
- n_row = desc_a%get_local_rows()
- n_col = desc_a%get_local_cols()
- call a%set_nrows(n_row)
- call a%set_ncols(n_col)
- end if
-
- if (a%is_bld()) then
- call a%cscnv(info,type=afmt,dupl=dupl, mold=mold)
+ if (a%is_remote_build()) then
+ !write(0,*) me,name,' Size of rmta:',a%rmta%get_nzeros()
+ block
+ type(psb_lz_coo_sparse_mat) :: a_add
+ integer(psb_ipk_), allocatable :: ila(:), jla(:)
+ integer(psb_ipk_) :: nz, nzt,k
+ call psb_remote_mat(a%rmta,desc_a,a_add,info)
+ nz = a_add%get_nzeros()
+ nzt = nz
+ call psb_sum(ctxt,nzt)
+ if (nzt>0) then
+ allocate(ivm, mold=desc_a%v_halo_index%v)
+ call psb_cd_reinit(desc_a, info)
+ end if
+ if (nz > 0) then
+ !
+ ! Should we check for new indices here?
+ !
+ call psb_realloc(nz,ila,info)
+ call psb_realloc(nz,jla,info)
+ call desc_a%indxmap%g2l(a_add%ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l_ins(a_add%ja(1:nz),jla(1:nz),info)
+ !write(0,*) me,name,' Check before insert',a%get_nzeros()
+ n_row = desc_a%get_local_rows()
+ n_col = desc_a%get_local_cols()
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%csput(nz,ila,jla,a_add%val,ione,n_row,ione,n_col,info)
+ !write(0,*) me,name,' Check after insert',a%get_nzeros(),nz
+ end if
+ if (nzt > 0) call psb_cdasb(desc_a,info,mold=ivm)
+
+ end block
+ end if
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%cscnv(info,type=afmt,mold=mold,dupl=dupl_)
else if (a%is_upd()) then
+ if (a%is_remote_build()) then
+ !write(0,*) me,name,' Size of rmta:',a%rmta%get_nzeros()
+ block
+ type(psb_lz_coo_sparse_mat) :: a_add
+ integer(psb_ipk_), allocatable :: ila(:), jla(:)
+ integer(psb_ipk_) :: nz, nzt,k
+ call psb_remote_mat(a%rmta,desc_a,a_add,info)
+ nz = a_add%get_nzeros()
+!!$ write(0,*) me,name,' Nz to be added',nz
+ if (nz > 0) then
+ !
+ ! Should we check for new indices here?
+ !
+ call psb_realloc(nz,ila,info)
+ call psb_realloc(nz,jla,info)
+ call desc_a%indxmap%g2l(a_add%ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l_ins(a_add%ja(1:nz),jla(1:nz),info)
+ !write(0,*) me,name,' Check before insert',a%get_nzeros()
+ n_row = desc_a%get_local_rows()
+ n_col = desc_a%get_local_cols()
+ call a%set_ncols(desc_a%get_local_cols())
+ call a%csput(nz,ila,jla,a_add%val,ione,n_row,ione,n_col,info)
+ !write(0,*) me,name,' Check after insert',a%get_nzeros(),nz
+ end if
+ end block
+ end if
call a%asb(mold=mold)
else
info = psb_err_invalid_mat_state_
diff --git a/base/tools/psb_zspins.F90 b/base/tools/psb_zspins.F90
index 525ed415..abe64251 100644
--- a/base/tools/psb_zspins.F90
+++ b/base/tools/psb_zspins.F90
@@ -70,6 +70,10 @@ subroutine psb_zspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
integer(psb_ipk_), parameter :: relocsz=200
logical :: rebuild_, local_
integer(psb_ipk_), allocatable :: ila(:),jla(:)
+ integer(psb_ipk_) :: i,k
+ integer(psb_lpk_) :: nnl
+ integer(psb_lpk_), allocatable :: lila(:),ljla(:)
+ complex(psb_dpk_), allocatable :: lval(:)
character(len=20) :: name
info = psb_success_
@@ -147,6 +151,27 @@ subroutine psb_zspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
call psb_errpush(info,name,a_err='a%csput')
goto 9999
end if
+
+ if (a%is_remote_build()) then
+ nnl = count(ila(1:nz)<0)
+ if (nnl > 0) then
+ !write(0,*) 'Check on insert ',nnl
+ allocate(lila(nnl),ljla(nnl),lval(nnl))
+ k = 0
+ do i=1,nz
+ if (ila(i)<0) then
+ k=k+1
+ lila(k) = ia(i)
+ ljla(k) = ja(i)
+ lval(k) = val(i)
+ end if
+ end do
+ if (k /= nnl) write(0,*) name,' Wrong conversion?',k,nnl
+ call a%rmta%csput(nnl,lila,ljla,lval,1_psb_lpk_,desc_a%get_global_rows(),&
+ & 1_psb_lpk_,desc_a%get_global_rows(),info)
+ end if
+ end if
+
else
info = psb_err_invalid_a_and_cd_state_
call psb_errpush(info,name)
@@ -168,8 +193,9 @@ subroutine psb_zspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
ila(1:nz) = ia(1:nz)
jla(1:nz) = ja(1:nz)
else
- call desc_a%indxmap%g2l(ia(1:nz),ila(1:nz),info)
- if (info == 0) call desc_a%indxmap%g2l(ja(1:nz),jla(1:nz),info)
+ call desc_a%indxmap%g2l(ia(1:nz),ila(1:nz),info,owned=.true.)
+ if (info == 0) call desc_a%indxmap%g2l(ja(1:nz),jla(1:nz),info,&
+ & mask=(ila(1:nz)>0))
end if
call a%csput(nz,ila,jla,val,ione,nrow,ione,ncol,info)
if (info /= psb_success_) then
@@ -177,6 +203,25 @@ subroutine psb_zspins(nz,ia,ja,val,a,desc_a,info,rebuild,local)
call psb_errpush(info,name,a_err='a%csput')
goto 9999
end if
+ if (a%is_remote_build()) then
+ nnl = count(ila(1:nz)<0)
+ if (nnl > 0) then
+ !write(0,*) 'Check on insert ',nnl
+ allocate(lila(nnl),ljla(nnl),lval(nnl))
+ k = 0
+ do i=1,nz
+ if (ila(i)<0) then
+ k=k+1
+ lila(k) = ia(k)
+ ljla(k) = ja(k)
+ lval(k) = val(k)
+ end if
+ end do
+ if (k /= nnl) write(0,*) name,' Wrong conversion?',k,nnl
+ call a%rmta%csput(nnl,lila,ljla,lval,1_psb_lpk_,desc_a%get_global_rows(),&
+ & 1_psb_lpk_,desc_a%get_global_rows(),info)
+ end if
+ end if
else
info = psb_err_invalid_cd_state_
call psb_errpush(info,name)
diff --git a/cbind/base/psb_base_tools_cbind_mod.F90 b/cbind/base/psb_base_tools_cbind_mod.F90
index dc05fd66..7126ced8 100644
--- a/cbind/base/psb_base_tools_cbind_mod.F90
+++ b/cbind/base/psb_base_tools_cbind_mod.F90
@@ -100,6 +100,47 @@ contains
end function psb_c_cdall_vl
+ function psb_c_cdall_vl_opt(nl,vl,cctxt,cdh) bind(c,name='psb_c_cdall_vl_opt') result(res)
+ implicit none
+
+ integer(psb_c_ipk_) :: res
+ type(psb_c_object_type), value :: cctxt
+ integer(psb_c_ipk_), value :: nl
+ integer(psb_c_lpk_) :: vl(*)
+ type(psb_c_object_type) :: cdh
+ type(psb_desc_type), pointer :: descp
+ integer(psb_c_ipk_) :: info, ixb
+ type(psb_ctxt_type) :: ctxt
+ ctxt = psb_c2f_ctxt(cctxt)
+
+ res = -1
+ if (nl <=0) then
+ write(0,*) 'Invalid size'
+ return
+ end if
+
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ call descp%free(info)
+ if (info == 0) deallocate(descp,stat=info)
+ if (info /= 0) return
+ end if
+
+ allocate(descp,stat=info)
+ if (info < 0) return
+
+ ixb = psb_c_get_index_base()
+
+ if (ixb == 1) then
+ call psb_cdall(ctxt,descp,info,vl=vl(1:nl),globalcheck=.true.)
+ else
+ call psb_cdall(ctxt,descp,info,vl=(vl(1:nl)+(1-ixb)),globalcheck=.true.)
+ end if
+ cdh%item = c_loc(descp)
+ res = info
+
+ end function psb_c_cdall_vl_opt
+
function psb_c_cdall_nl(nl,cctxt,cdh) bind(c,name='psb_c_cdall_nl') result(res)
implicit none
diff --git a/cbind/base/psb_c_cbase.h b/cbind/base/psb_c_cbase.h
index dd64d6e2..bff9633a 100644
--- a/cbind/base/psb_c_cbase.h
+++ b/cbind/base/psb_c_cbase.h
@@ -24,6 +24,7 @@ psb_i_t psb_c_cvect_zero(psb_c_cvector *xh);
psb_i_t *psb_c_cvect_f_get_pnt(psb_c_cvector *xh);
psb_i_t psb_c_cgeall(psb_c_cvector *xh, psb_c_descriptor *cdh);
+psb_i_t psb_c_cgeall_remote(psb_c_cvector *xh, psb_c_descriptor *cdh);
psb_i_t psb_c_cgeins(psb_i_t nz, const psb_l_t *irw, const psb_c_t *val,
psb_c_cvector *xh, psb_c_descriptor *cdh);
psb_i_t psb_c_cgeins_add(psb_i_t nz, const psb_l_t *irw, const psb_c_t *val,
@@ -35,6 +36,7 @@ psb_c_t psb_c_cgetelem(psb_c_cvector *xh,psb_l_t index,psb_c_descriptor *cd);
/* sparse matrices*/
psb_c_cspmat* psb_c_new_cspmat();
psb_i_t psb_c_cspall(psb_c_cspmat *mh, psb_c_descriptor *cdh);
+psb_i_t psb_c_cspall_remote(psb_c_cspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_cspasb(psb_c_cspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_cspfree(psb_c_cspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_cspins(psb_i_t nz, const psb_l_t *irw, const psb_l_t *icl,
diff --git a/cbind/base/psb_c_dbase.h b/cbind/base/psb_c_dbase.h
index 8c2c6a61..591f885b 100644
--- a/cbind/base/psb_c_dbase.h
+++ b/cbind/base/psb_c_dbase.h
@@ -24,6 +24,7 @@ psb_i_t psb_c_dvect_zero(psb_c_dvector *xh);
psb_d_t *psb_c_dvect_f_get_pnt( psb_c_dvector *xh);
psb_i_t psb_c_dgeall(psb_c_dvector *xh, psb_c_descriptor *cdh);
+psb_i_t psb_c_dgeall_remote(psb_c_dvector *xh, psb_c_descriptor *cdh);
psb_i_t psb_c_dgeins(psb_i_t nz, const psb_l_t *irw, const psb_d_t *val,
psb_c_dvector *xh, psb_c_descriptor *cdh);
psb_i_t psb_c_dgeins_add(psb_i_t nz, const psb_l_t *irw, const psb_d_t *val,
@@ -35,6 +36,7 @@ psb_d_t psb_c_dgetelem(psb_c_dvector *xh,psb_l_t index,psb_c_descriptor *cd);
/* sparse matrices*/
psb_c_dspmat* psb_c_new_dspmat();
psb_i_t psb_c_dspall(psb_c_dspmat *mh, psb_c_descriptor *cdh);
+psb_i_t psb_c_dspall_remote(psb_c_dspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_dspasb(psb_c_dspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_dspfree(psb_c_dspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_dspins(psb_i_t nz, const psb_l_t *irw, const psb_l_t *icl,
diff --git a/cbind/base/psb_c_sbase.h b/cbind/base/psb_c_sbase.h
index b2e18ba5..68abefdd 100644
--- a/cbind/base/psb_c_sbase.h
+++ b/cbind/base/psb_c_sbase.h
@@ -24,6 +24,7 @@ psb_i_t psb_c_svect_zero(psb_c_svector *xh);
psb_s_t *psb_c_svect_f_get_pnt( psb_c_svector *xh);
psb_i_t psb_c_sgeall(psb_c_svector *xh, psb_c_descriptor *cdh);
+psb_i_t psb_c_sgeall_remote(psb_c_svector *xh, psb_c_descriptor *cdh);
psb_i_t psb_c_sgeins(psb_i_t nz, const psb_l_t *irw, const psb_s_t *val,
psb_c_svector *xh, psb_c_descriptor *cdh);
psb_i_t psb_c_sgeins_add(psb_i_t nz, const psb_l_t *irw, const psb_s_t *val,
@@ -35,6 +36,7 @@ psb_s_t psb_c_sgetelem(psb_c_svector *xh,psb_l_t index,psb_c_descriptor *cd);
/* sparse matrices*/
psb_c_sspmat* psb_c_new_sspmat();
psb_i_t psb_c_sspall(psb_c_sspmat *mh, psb_c_descriptor *cdh);
+psb_i_t psb_c_sspall_remote(psb_c_sspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_sspasb(psb_c_sspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_sspfree(psb_c_sspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_sspins(psb_i_t nz, const psb_l_t *irw, const psb_l_t *icl,
diff --git a/cbind/base/psb_c_tools_cbind_mod.F90 b/cbind/base/psb_c_tools_cbind_mod.F90
index 84fea6d7..8f64cbb0 100644
--- a/cbind/base/psb_c_tools_cbind_mod.F90
+++ b/cbind/base/psb_c_tools_cbind_mod.F90
@@ -5,10 +5,11 @@ module psb_c_tools_cbind_mod
use psb_objhandle_mod
use psb_base_string_cbind_mod
use psb_base_tools_cbind_mod
-
+
contains
- function psb_c_cgeall(xh,cdh) bind(c) result(res)
+ ! Should define geall_opt with DUPL argument
+ function psb_c_cgeall(xh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -37,6 +38,35 @@ contains
return
end function psb_c_cgeall
+ function psb_c_cgeall_remote(xh,cdh) bind(c) result(res)
+
+ implicit none
+ integer(psb_c_ipk_) :: res
+ type(psb_c_cvector) :: xh
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_desc_type), pointer :: descp
+ type(psb_c_vect_type), pointer :: xp
+ integer(psb_c_ipk_) :: info
+
+ res = -1
+
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(xh%item)) then
+ return
+ end if
+ allocate(xp)
+ call psb_geall(xp,descp,info,bldmode=psb_matbld_remote_,dupl=psb_dupl_add_)
+ xh%item = c_loc(xp)
+ res = min(0,info)
+
+ return
+ end function psb_c_cgeall_remote
+
function psb_c_cgeasb(xh,cdh) bind(c) result(res)
implicit none
@@ -101,7 +131,7 @@ contains
end function psb_c_cgefree
- function psb_c_cgeins(nz,irw,val,xh,cdh) bind(c) result(res)
+ function psb_c_cgeins(nz,irw,val,xh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -131,10 +161,10 @@ contains
ixb = psb_c_get_index_base()
if (ixb == 1) then
call psb_geins(nz,irw(1:nz),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_ovwrt_)
+ & xp,descp,info)
else
call psb_geins(nz,(irw(1:nz)+(1-ixb)),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_ovwrt_)
+ & xp,descp,info)
end if
res = min(0,info)
@@ -142,20 +172,16 @@ contains
return
end function psb_c_cgeins
-
- function psb_c_cgeins_add(nz,irw,val,xh,cdh) bind(c) result(res)
+ function psb_c_cspall(mh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
- integer(psb_c_ipk_), value :: nz
- integer(psb_c_lpk_) :: irw(*)
- complex(c_float_complex) :: val(*)
- type(psb_c_cvector) :: xh
+ type(psb_c_cspmat) :: mh
type(psb_c_descriptor) :: cdh
type(psb_desc_type), pointer :: descp
- type(psb_c_vect_type), pointer :: xp
- integer(psb_c_ipk_) :: ixb, info
+ type(psb_cspmat_type), pointer :: ap
+ integer(psb_c_ipk_) :: info,n
res = -1
if (c_associated(cdh%item)) then
@@ -163,27 +189,19 @@ contains
else
return
end if
- if (c_associated(xh%item)) then
- call c_f_pointer(xh%item,xp)
- else
+ if (c_associated(mh%item)) then
return
end if
-
- ixb = psb_c_get_index_base()
- if (ixb == 1) then
- call psb_geins(nz,irw(1:nz),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_add_)
- else
- call psb_geins(nz,(irw(1:nz)+(1-ixb)),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_add_)
- end if
+ allocate(ap)
+ call psb_spall(ap,descp,info)
+ mh%item = c_loc(ap)
res = min(0,info)
return
- end function psb_c_cgeins_add
+ end function psb_c_cspall
- function psb_c_cspall(mh,cdh) bind(c) result(res)
+ function psb_c_cspall_remote(mh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -204,14 +222,12 @@ contains
return
end if
allocate(ap)
- call psb_spall(ap,descp,info)
+ call psb_spall(ap,descp,info,bldmode=psb_matbld_remote_,dupl=psb_dupl_add_)
mh%item = c_loc(ap)
res = min(0,info)
return
- end function psb_c_cspall
-
-
+ end function psb_c_cspall_remote
function psb_c_cspasb(mh,cdh) bind(c) result(res)
@@ -241,7 +257,6 @@ contains
return
end function psb_c_cspasb
-
function psb_c_cspfree(mh,cdh) bind(c) result(res)
implicit none
@@ -275,7 +290,7 @@ contains
#if 0
- function psb_c_cspasb_opt(mh,cdh,afmt,upd,dupl) bind(c) result(res)
+ function psb_c_cspasb_opt(mh,cdh,afmt,upd) bind(c) result(res)
#ifdef HAVE_LIBRSB
use psb_c_rsb_mat_mod
@@ -284,7 +299,7 @@ contains
integer(psb_c_ipk_) :: res
integer(psb_c_ipk_), value :: cdh, mh,upd,dupl
character(c_char) :: afmt(*)
- integer(psb_c_ipk_) :: info,n, fdupl
+ integer(psb_c_ipk_) :: info,n
character(len=5) :: fafmt
#ifdef HAVE_LIBRSB
type(psb_c_rsb_sparse_mat) :: arsb
@@ -301,11 +316,11 @@ contains
#ifdef HAVE_LIBRSB
case('RSB')
call psb_spasb(double_spmat_pool(mh)%item,descriptor_pool(cdh)%item,info,&
- & upd=upd,dupl=dupl,mold=arsb)
+ & upd=upd,mold=arsb)
#endif
case default
call psb_spasb(double_spmat_pool(mh)%item,descriptor_pool(cdh)%item,info,&
- & afmt=fafmt,upd=upd,dupl=dupl)
+ & afmt=fafmt,upd=upd)
end select
res = min(0,info)
diff --git a/cbind/base/psb_c_zbase.h b/cbind/base/psb_c_zbase.h
index 16ee1ac4..9a27e9c0 100644
--- a/cbind/base/psb_c_zbase.h
+++ b/cbind/base/psb_c_zbase.h
@@ -24,6 +24,7 @@ psb_i_t psb_c_zvect_zero(psb_c_zvector *xh);
psb_z_t *psb_c_zvect_f_get_pnt( psb_c_zvector *xh);
psb_i_t psb_c_zgeall(psb_c_zvector *xh, psb_c_descriptor *cdh);
+psb_i_t psb_c_zgeall_remote(psb_c_zvector *xh, psb_c_descriptor *cdh);
psb_i_t psb_c_zgeins(psb_i_t nz, const psb_l_t *irw, const psb_z_t *val,
psb_c_zvector *xh, psb_c_descriptor *cdh);
psb_i_t psb_c_zgeins_add(psb_i_t nz, const psb_l_t *irw, const psb_z_t *val,
@@ -35,6 +36,7 @@ psb_z_t psb_c_zgetelem(psb_c_zvector *xh,psb_l_t index,psb_c_descriptor *cd);
/* sparse matrices*/
psb_c_zspmat* psb_c_new_zspmat();
psb_i_t psb_c_zspall(psb_c_zspmat *mh, psb_c_descriptor *cdh);
+psb_i_t psb_c_zspall_remote(psb_c_zspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_zspasb(psb_c_zspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_zspfree(psb_c_zspmat *mh, psb_c_descriptor *cdh);
psb_i_t psb_c_zspins(psb_i_t nz, const psb_l_t *irw, const psb_l_t *icl,
diff --git a/cbind/base/psb_d_tools_cbind_mod.F90 b/cbind/base/psb_d_tools_cbind_mod.F90
index 08e214a5..67ae8b86 100644
--- a/cbind/base/psb_d_tools_cbind_mod.F90
+++ b/cbind/base/psb_d_tools_cbind_mod.F90
@@ -5,10 +5,11 @@ module psb_d_tools_cbind_mod
use psb_objhandle_mod
use psb_base_string_cbind_mod
use psb_base_tools_cbind_mod
-
+
contains
- function psb_c_dgeall(xh,cdh) bind(c) result(res)
+ ! Should define geall_opt with DUPL argument
+ function psb_c_dgeall(xh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -37,6 +38,35 @@ contains
return
end function psb_c_dgeall
+ function psb_c_dgeall_remote(xh,cdh) bind(c) result(res)
+
+ implicit none
+ integer(psb_c_ipk_) :: res
+ type(psb_c_dvector) :: xh
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_desc_type), pointer :: descp
+ type(psb_d_vect_type), pointer :: xp
+ integer(psb_c_ipk_) :: info
+
+ res = -1
+
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(xh%item)) then
+ return
+ end if
+ allocate(xp)
+ call psb_geall(xp,descp,info,bldmode=psb_matbld_remote_,dupl=psb_dupl_add_)
+ xh%item = c_loc(xp)
+ res = min(0,info)
+
+ return
+ end function psb_c_dgeall_remote
+
function psb_c_dgeasb(xh,cdh) bind(c) result(res)
implicit none
@@ -101,7 +131,7 @@ contains
end function psb_c_dgefree
- function psb_c_dgeins(nz,irw,val,xh,cdh) bind(c) result(res)
+ function psb_c_dgeins(nz,irw,val,xh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -131,10 +161,10 @@ contains
ixb = psb_c_get_index_base()
if (ixb == 1) then
call psb_geins(nz,irw(1:nz),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_ovwrt_)
+ & xp,descp,info)
else
call psb_geins(nz,(irw(1:nz)+(1-ixb)),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_ovwrt_)
+ & xp,descp,info)
end if
res = min(0,info)
@@ -142,20 +172,16 @@ contains
return
end function psb_c_dgeins
-
- function psb_c_dgeins_add(nz,irw,val,xh,cdh) bind(c) result(res)
+ function psb_c_dspall(mh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
- integer(psb_c_ipk_), value :: nz
- integer(psb_c_lpk_) :: irw(*)
- real(c_double) :: val(*)
- type(psb_c_dvector) :: xh
+ type(psb_c_dspmat) :: mh
type(psb_c_descriptor) :: cdh
type(psb_desc_type), pointer :: descp
- type(psb_d_vect_type), pointer :: xp
- integer(psb_c_ipk_) :: ixb, info
+ type(psb_dspmat_type), pointer :: ap
+ integer(psb_c_ipk_) :: info,n
res = -1
if (c_associated(cdh%item)) then
@@ -163,27 +189,19 @@ contains
else
return
end if
- if (c_associated(xh%item)) then
- call c_f_pointer(xh%item,xp)
- else
+ if (c_associated(mh%item)) then
return
end if
-
- ixb = psb_c_get_index_base()
- if (ixb == 1) then
- call psb_geins(nz,irw(1:nz),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_add_)
- else
- call psb_geins(nz,(irw(1:nz)+(1-ixb)),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_add_)
- end if
+ allocate(ap)
+ call psb_spall(ap,descp,info)
+ mh%item = c_loc(ap)
res = min(0,info)
return
- end function psb_c_dgeins_add
+ end function psb_c_dspall
- function psb_c_dspall(mh,cdh) bind(c) result(res)
+ function psb_c_dspall_remote(mh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -204,14 +222,12 @@ contains
return
end if
allocate(ap)
- call psb_spall(ap,descp,info)
+ call psb_spall(ap,descp,info,bldmode=psb_matbld_remote_,dupl=psb_dupl_add_)
mh%item = c_loc(ap)
res = min(0,info)
return
- end function psb_c_dspall
-
-
+ end function psb_c_dspall_remote
function psb_c_dspasb(mh,cdh) bind(c) result(res)
@@ -241,7 +257,6 @@ contains
return
end function psb_c_dspasb
-
function psb_c_dspfree(mh,cdh) bind(c) result(res)
implicit none
@@ -275,7 +290,7 @@ contains
#if 0
- function psb_c_dspasb_opt(mh,cdh,afmt,upd,dupl) bind(c) result(res)
+ function psb_c_dspasb_opt(mh,cdh,afmt,upd) bind(c) result(res)
#ifdef HAVE_LIBRSB
use psb_d_rsb_mat_mod
@@ -284,7 +299,7 @@ contains
integer(psb_c_ipk_) :: res
integer(psb_c_ipk_), value :: cdh, mh,upd,dupl
character(c_char) :: afmt(*)
- integer(psb_c_ipk_) :: info,n, fdupl
+ integer(psb_c_ipk_) :: info,n
character(len=5) :: fafmt
#ifdef HAVE_LIBRSB
type(psb_d_rsb_sparse_mat) :: arsb
@@ -301,11 +316,11 @@ contains
#ifdef HAVE_LIBRSB
case('RSB')
call psb_spasb(double_spmat_pool(mh)%item,descriptor_pool(cdh)%item,info,&
- & upd=upd,dupl=dupl,mold=arsb)
+ & upd=upd,mold=arsb)
#endif
case default
call psb_spasb(double_spmat_pool(mh)%item,descriptor_pool(cdh)%item,info,&
- & afmt=fafmt,upd=upd,dupl=dupl)
+ & afmt=fafmt,upd=upd)
end select
res = min(0,info)
diff --git a/cbind/base/psb_s_tools_cbind_mod.F90 b/cbind/base/psb_s_tools_cbind_mod.F90
index d9584338..91d9b322 100644
--- a/cbind/base/psb_s_tools_cbind_mod.F90
+++ b/cbind/base/psb_s_tools_cbind_mod.F90
@@ -5,10 +5,11 @@ module psb_s_tools_cbind_mod
use psb_objhandle_mod
use psb_base_string_cbind_mod
use psb_base_tools_cbind_mod
-
+
contains
- function psb_c_sgeall(xh,cdh) bind(c) result(res)
+ ! Should define geall_opt with DUPL argument
+ function psb_c_sgeall(xh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -37,6 +38,35 @@ contains
return
end function psb_c_sgeall
+ function psb_c_sgeall_remote(xh,cdh) bind(c) result(res)
+
+ implicit none
+ integer(psb_c_ipk_) :: res
+ type(psb_c_svector) :: xh
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_desc_type), pointer :: descp
+ type(psb_s_vect_type), pointer :: xp
+ integer(psb_c_ipk_) :: info
+
+ res = -1
+
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(xh%item)) then
+ return
+ end if
+ allocate(xp)
+ call psb_geall(xp,descp,info,bldmode=psb_matbld_remote_,dupl=psb_dupl_add_)
+ xh%item = c_loc(xp)
+ res = min(0,info)
+
+ return
+ end function psb_c_sgeall_remote
+
function psb_c_sgeasb(xh,cdh) bind(c) result(res)
implicit none
@@ -101,7 +131,7 @@ contains
end function psb_c_sgefree
- function psb_c_sgeins(nz,irw,val,xh,cdh) bind(c) result(res)
+ function psb_c_sgeins(nz,irw,val,xh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -131,10 +161,10 @@ contains
ixb = psb_c_get_index_base()
if (ixb == 1) then
call psb_geins(nz,irw(1:nz),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_ovwrt_)
+ & xp,descp,info)
else
call psb_geins(nz,(irw(1:nz)+(1-ixb)),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_ovwrt_)
+ & xp,descp,info)
end if
res = min(0,info)
@@ -142,20 +172,16 @@ contains
return
end function psb_c_sgeins
-
- function psb_c_sgeins_add(nz,irw,val,xh,cdh) bind(c) result(res)
+ function psb_c_sspall(mh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
- integer(psb_c_ipk_), value :: nz
- integer(psb_c_lpk_) :: irw(*)
- real(c_float) :: val(*)
- type(psb_c_svector) :: xh
+ type(psb_c_sspmat) :: mh
type(psb_c_descriptor) :: cdh
type(psb_desc_type), pointer :: descp
- type(psb_s_vect_type), pointer :: xp
- integer(psb_c_ipk_) :: ixb, info
+ type(psb_sspmat_type), pointer :: ap
+ integer(psb_c_ipk_) :: info,n
res = -1
if (c_associated(cdh%item)) then
@@ -163,27 +189,19 @@ contains
else
return
end if
- if (c_associated(xh%item)) then
- call c_f_pointer(xh%item,xp)
- else
+ if (c_associated(mh%item)) then
return
end if
-
- ixb = psb_c_get_index_base()
- if (ixb == 1) then
- call psb_geins(nz,irw(1:nz),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_add_)
- else
- call psb_geins(nz,(irw(1:nz)+(1-ixb)),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_add_)
- end if
+ allocate(ap)
+ call psb_spall(ap,descp,info)
+ mh%item = c_loc(ap)
res = min(0,info)
return
- end function psb_c_sgeins_add
+ end function psb_c_sspall
- function psb_c_sspall(mh,cdh) bind(c) result(res)
+ function psb_c_sspall_remote(mh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -204,14 +222,12 @@ contains
return
end if
allocate(ap)
- call psb_spall(ap,descp,info)
+ call psb_spall(ap,descp,info,bldmode=psb_matbld_remote_,dupl=psb_dupl_add_)
mh%item = c_loc(ap)
res = min(0,info)
return
- end function psb_c_sspall
-
-
+ end function psb_c_sspall_remote
function psb_c_sspasb(mh,cdh) bind(c) result(res)
@@ -241,7 +257,6 @@ contains
return
end function psb_c_sspasb
-
function psb_c_sspfree(mh,cdh) bind(c) result(res)
implicit none
@@ -275,7 +290,7 @@ contains
#if 0
- function psb_c_sspasb_opt(mh,cdh,afmt,upd,dupl) bind(c) result(res)
+ function psb_c_sspasb_opt(mh,cdh,afmt,upd) bind(c) result(res)
#ifdef HAVE_LIBRSB
use psb_s_rsb_mat_mod
@@ -284,7 +299,7 @@ contains
integer(psb_c_ipk_) :: res
integer(psb_c_ipk_), value :: cdh, mh,upd,dupl
character(c_char) :: afmt(*)
- integer(psb_c_ipk_) :: info,n, fdupl
+ integer(psb_c_ipk_) :: info,n
character(len=5) :: fafmt
#ifdef HAVE_LIBRSB
type(psb_s_rsb_sparse_mat) :: arsb
@@ -301,11 +316,11 @@ contains
#ifdef HAVE_LIBRSB
case('RSB')
call psb_spasb(double_spmat_pool(mh)%item,descriptor_pool(cdh)%item,info,&
- & upd=upd,dupl=dupl,mold=arsb)
+ & upd=upd,mold=arsb)
#endif
case default
call psb_spasb(double_spmat_pool(mh)%item,descriptor_pool(cdh)%item,info,&
- & afmt=fafmt,upd=upd,dupl=dupl)
+ & afmt=fafmt,upd=upd)
end select
res = min(0,info)
diff --git a/cbind/base/psb_z_tools_cbind_mod.F90 b/cbind/base/psb_z_tools_cbind_mod.F90
index 572eeb95..59d4cca8 100644
--- a/cbind/base/psb_z_tools_cbind_mod.F90
+++ b/cbind/base/psb_z_tools_cbind_mod.F90
@@ -5,10 +5,11 @@ module psb_z_tools_cbind_mod
use psb_objhandle_mod
use psb_base_string_cbind_mod
use psb_base_tools_cbind_mod
-
+
contains
- function psb_c_zgeall(xh,cdh) bind(c) result(res)
+ ! Should define geall_opt with DUPL argument
+ function psb_c_zgeall(xh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -37,6 +38,35 @@ contains
return
end function psb_c_zgeall
+ function psb_c_zgeall_remote(xh,cdh) bind(c) result(res)
+
+ implicit none
+ integer(psb_c_ipk_) :: res
+ type(psb_c_zvector) :: xh
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_desc_type), pointer :: descp
+ type(psb_z_vect_type), pointer :: xp
+ integer(psb_c_ipk_) :: info
+
+ res = -1
+
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(xh%item)) then
+ return
+ end if
+ allocate(xp)
+ call psb_geall(xp,descp,info,bldmode=psb_matbld_remote_,dupl=psb_dupl_add_)
+ xh%item = c_loc(xp)
+ res = min(0,info)
+
+ return
+ end function psb_c_zgeall_remote
+
function psb_c_zgeasb(xh,cdh) bind(c) result(res)
implicit none
@@ -101,7 +131,7 @@ contains
end function psb_c_zgefree
- function psb_c_zgeins(nz,irw,val,xh,cdh) bind(c) result(res)
+ function psb_c_zgeins(nz,irw,val,xh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -131,10 +161,10 @@ contains
ixb = psb_c_get_index_base()
if (ixb == 1) then
call psb_geins(nz,irw(1:nz),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_ovwrt_)
+ & xp,descp,info)
else
call psb_geins(nz,(irw(1:nz)+(1-ixb)),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_ovwrt_)
+ & xp,descp,info)
end if
res = min(0,info)
@@ -142,20 +172,16 @@ contains
return
end function psb_c_zgeins
-
- function psb_c_zgeins_add(nz,irw,val,xh,cdh) bind(c) result(res)
+ function psb_c_zspall(mh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
- integer(psb_c_ipk_), value :: nz
- integer(psb_c_lpk_) :: irw(*)
- complex(c_double_complex) :: val(*)
- type(psb_c_zvector) :: xh
+ type(psb_c_zspmat) :: mh
type(psb_c_descriptor) :: cdh
type(psb_desc_type), pointer :: descp
- type(psb_z_vect_type), pointer :: xp
- integer(psb_c_ipk_) :: ixb, info
+ type(psb_zspmat_type), pointer :: ap
+ integer(psb_c_ipk_) :: info,n
res = -1
if (c_associated(cdh%item)) then
@@ -163,27 +189,19 @@ contains
else
return
end if
- if (c_associated(xh%item)) then
- call c_f_pointer(xh%item,xp)
- else
+ if (c_associated(mh%item)) then
return
end if
-
- ixb = psb_c_get_index_base()
- if (ixb == 1) then
- call psb_geins(nz,irw(1:nz),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_add_)
- else
- call psb_geins(nz,(irw(1:nz)+(1-ixb)),val(1:nz),&
- & xp,descp,info, dupl=psb_dupl_add_)
- end if
+ allocate(ap)
+ call psb_spall(ap,descp,info)
+ mh%item = c_loc(ap)
res = min(0,info)
return
- end function psb_c_zgeins_add
+ end function psb_c_zspall
- function psb_c_zspall(mh,cdh) bind(c) result(res)
+ function psb_c_zspall_remote(mh,cdh) bind(c) result(res)
implicit none
integer(psb_c_ipk_) :: res
@@ -204,14 +222,12 @@ contains
return
end if
allocate(ap)
- call psb_spall(ap,descp,info)
+ call psb_spall(ap,descp,info,bldmode=psb_matbld_remote_,dupl=psb_dupl_add_)
mh%item = c_loc(ap)
res = min(0,info)
return
- end function psb_c_zspall
-
-
+ end function psb_c_zspall_remote
function psb_c_zspasb(mh,cdh) bind(c) result(res)
@@ -241,7 +257,6 @@ contains
return
end function psb_c_zspasb
-
function psb_c_zspfree(mh,cdh) bind(c) result(res)
implicit none
@@ -275,7 +290,7 @@ contains
#if 0
- function psb_c_zspasb_opt(mh,cdh,afmt,upd,dupl) bind(c) result(res)
+ function psb_c_zspasb_opt(mh,cdh,afmt,upd) bind(c) result(res)
#ifdef HAVE_LIBRSB
use psb_z_rsb_mat_mod
@@ -284,7 +299,7 @@ contains
integer(psb_c_ipk_) :: res
integer(psb_c_ipk_), value :: cdh, mh,upd,dupl
character(c_char) :: afmt(*)
- integer(psb_c_ipk_) :: info,n, fdupl
+ integer(psb_c_ipk_) :: info,n
character(len=5) :: fafmt
#ifdef HAVE_LIBRSB
type(psb_z_rsb_sparse_mat) :: arsb
@@ -301,11 +316,11 @@ contains
#ifdef HAVE_LIBRSB
case('RSB')
call psb_spasb(double_spmat_pool(mh)%item,descriptor_pool(cdh)%item,info,&
- & upd=upd,dupl=dupl,mold=arsb)
+ & upd=upd,mold=arsb)
#endif
case default
call psb_spasb(double_spmat_pool(mh)%item,descriptor_pool(cdh)%item,info,&
- & afmt=fafmt,upd=upd,dupl=dupl)
+ & afmt=fafmt,upd=upd)
end select
res = min(0,info)
diff --git a/cbind/util/psb_c_cutil.h b/cbind/util/psb_c_cutil.h
index 4d2755d6..9da81aa1 100644
--- a/cbind/util/psb_c_cutil.h
+++ b/cbind/util/psb_c_cutil.h
@@ -8,6 +8,8 @@ extern "C" {
/* I/O Routine */
psb_i_t psb_c_cmm_mat_write(psb_c_cspmat *ah, char *matrixtitle, char *filename);
+psb_i_t psb_c_cglobal_mat_write(psb_c_cspmat *ah,psb_c_descriptor *cdh);
+psb_i_t psb_c_cglobal_vec_write(psb_c_cvector *vh,psb_c_descriptor *cdh);
#ifdef __cplusplus
}
diff --git a/cbind/util/psb_c_dutil.h b/cbind/util/psb_c_dutil.h
index 306d7310..144e156d 100644
--- a/cbind/util/psb_c_dutil.h
+++ b/cbind/util/psb_c_dutil.h
@@ -8,6 +8,8 @@ extern "C" {
/* I/O Routine */
psb_i_t psb_c_dmm_mat_write(psb_c_dspmat *ah, char *matrixtitle, char *filename);
+psb_i_t psb_c_dglobal_mat_write(psb_c_dspmat *ah,psb_c_descriptor *cdh);
+psb_i_t psb_c_dglobal_vec_write(psb_c_dvector *vh,psb_c_descriptor *cdh);
#ifdef __cplusplus
}
diff --git a/cbind/util/psb_c_sutil.h b/cbind/util/psb_c_sutil.h
index 9dd1ed54..a70097ed 100644
--- a/cbind/util/psb_c_sutil.h
+++ b/cbind/util/psb_c_sutil.h
@@ -8,6 +8,8 @@ extern "C" {
/* I/O Routine */
psb_i_t psb_c_smm_mat_write(psb_c_sspmat *ah, char *matrixtitle, char *filename);
+psb_i_t psb_c_sglobal_mat_write(psb_c_sspmat *ah,psb_c_descriptor *cdh);
+psb_i_t psb_c_sglobal_vec_write(psb_c_svector *vh,psb_c_descriptor *cdh);
#ifdef __cplusplus
}
diff --git a/cbind/util/psb_c_util_cbind_mod.f90 b/cbind/util/psb_c_util_cbind_mod.f90
index 3761cd08..ae3f6cf8 100644
--- a/cbind/util/psb_c_util_cbind_mod.f90
+++ b/cbind/util/psb_c_util_cbind_mod.f90
@@ -41,4 +41,91 @@ contains
end function psb_c_cmm_mat_write
+ function psb_c_cglobal_mat_write(ah,cdh) bind(c) result(res)
+ use psb_base_mod
+ use psb_util_mod
+ use psb_base_string_cbind_mod
+ implicit none
+ integer(psb_c_ipk_) :: res
+
+ type(psb_c_cspmat) :: ah
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_cspmat_type), pointer :: ap
+ type(psb_desc_type), pointer :: descp
+ ! Local variables
+ type(psb_cspmat_type) :: aglobal
+ integer(psb_ipk_) :: info, iam, np
+ type(psb_ctxt_type) :: ctxt
+ character(len=40) :: matrixname
+
+ res = -1
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(ah%item)) then
+ call c_f_pointer(ah%item,ap)
+ else
+ return
+ end if
+
+ ctxt = descp%get_ctxt()
+ call psb_info(ctxt,iam,np)
+ call psb_gather(aglobal,ap,descp,info)
+ if (iam == psb_root_) then
+ write(matrixname,'("A-np-",I1,".mtx")') np
+ call mm_mat_write(aglobal,"Global matrix",info,filename=trim(matrixname))
+ end if
+
+ call psb_spfree(aglobal,descp,info)
+ res = info
+
+ end function psb_c_cglobal_mat_write
+
+ function psb_c_cglobal_vec_write(vh,cdh) bind(c) result(res)
+ use psb_base_mod
+ use psb_util_mod
+ use psb_base_string_cbind_mod
+ implicit none
+ integer(psb_c_ipk_) :: res
+
+ type(psb_c_cvector) :: vh
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_c_vect_type), pointer :: vp
+ type(psb_desc_type), pointer :: descp
+ ! Local variables
+ complex(psb_spk_), allocatable :: vglobal(:)
+ integer(psb_ipk_) :: info, iam, np
+ type(psb_ctxt_type) :: ctxt
+ character(len=40) :: vecname
+
+ res = -1
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(vh%item)) then
+ call c_f_pointer(vh%item,vp)
+ else
+ return
+ end if
+
+ ctxt = descp%get_ctxt()
+ call psb_info(ctxt,iam,np)
+ call psb_gather(vglobal,vp,descp,info)
+ if (iam == psb_root_) then
+ write(vecname,'("v-np-",I1,".mtx")') np
+ call mm_array_write(vglobal,"Global vector",info,filename=trim(vecname))
+ end if
+
+ deallocate(vglobal,stat=info)
+ res = info
+
+ end function psb_c_cglobal_vec_write
+
+
end module psb_cutil_cbind_mod
diff --git a/cbind/util/psb_c_zutil.h b/cbind/util/psb_c_zutil.h
index f5d0f225..4e308c36 100644
--- a/cbind/util/psb_c_zutil.h
+++ b/cbind/util/psb_c_zutil.h
@@ -8,6 +8,8 @@ extern "C" {
/* I/O Routine */
psb_i_t psb_c_zmm_mat_write(psb_c_zspmat *ah, char *matrixtitle, char *filename);
+psb_i_t psb_c_zglobal_mat_write(psb_c_zspmat *ah,psb_c_descriptor *cdh);
+psb_i_t psb_c_zglobal_vec_write(psb_c_zvector *vh,psb_c_descriptor *cdh);
#ifdef __cplusplus
}
diff --git a/cbind/util/psb_d_util_cbind_mod.f90 b/cbind/util/psb_d_util_cbind_mod.f90
index 245cff5e..29fec75b 100644
--- a/cbind/util/psb_d_util_cbind_mod.f90
+++ b/cbind/util/psb_d_util_cbind_mod.f90
@@ -41,4 +41,91 @@ contains
end function psb_c_dmm_mat_write
+ function psb_c_dglobal_mat_write(ah,cdh) bind(c) result(res)
+ use psb_base_mod
+ use psb_util_mod
+ use psb_base_string_cbind_mod
+ implicit none
+ integer(psb_c_ipk_) :: res
+
+ type(psb_c_dspmat) :: ah
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_dspmat_type), pointer :: ap
+ type(psb_desc_type), pointer :: descp
+ ! Local variables
+ type(psb_dspmat_type) :: aglobal
+ integer(psb_ipk_) :: info, iam, np
+ type(psb_ctxt_type) :: ctxt
+ character(len=40) :: matrixname
+
+ res = -1
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(ah%item)) then
+ call c_f_pointer(ah%item,ap)
+ else
+ return
+ end if
+
+ ctxt = descp%get_ctxt()
+ call psb_info(ctxt,iam,np)
+ call psb_gather(aglobal,ap,descp,info)
+ if (iam == psb_root_) then
+ write(matrixname,'("A-np-",I1,".mtx")') np
+ call mm_mat_write(aglobal,"Global matrix",info,filename=trim(matrixname))
+ end if
+
+ call psb_spfree(aglobal,descp,info)
+ res = info
+
+ end function psb_c_dglobal_mat_write
+
+ function psb_c_dglobal_vec_write(vh,cdh) bind(c) result(res)
+ use psb_base_mod
+ use psb_util_mod
+ use psb_base_string_cbind_mod
+ implicit none
+ integer(psb_c_ipk_) :: res
+
+ type(psb_c_dvector) :: vh
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_d_vect_type), pointer :: vp
+ type(psb_desc_type), pointer :: descp
+ ! Local variables
+ real(psb_dpk_), allocatable :: vglobal(:)
+ integer(psb_ipk_) :: info, iam, np
+ type(psb_ctxt_type) :: ctxt
+ character(len=40) :: vecname
+
+ res = -1
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(vh%item)) then
+ call c_f_pointer(vh%item,vp)
+ else
+ return
+ end if
+
+ ctxt = descp%get_ctxt()
+ call psb_info(ctxt,iam,np)
+ call psb_gather(vglobal,vp,descp,info)
+ if (iam == psb_root_) then
+ write(vecname,'("v-np-",I1,".mtx")') np
+ call mm_array_write(vglobal,"Global vector",info,filename=trim(vecname))
+ end if
+
+ deallocate(vglobal,stat=info)
+ res = info
+
+ end function psb_c_dglobal_vec_write
+
+
end module psb_dutil_cbind_mod
diff --git a/cbind/util/psb_s_util_cbind_mod.f90 b/cbind/util/psb_s_util_cbind_mod.f90
index e857cde9..0dfe3ddc 100644
--- a/cbind/util/psb_s_util_cbind_mod.f90
+++ b/cbind/util/psb_s_util_cbind_mod.f90
@@ -41,4 +41,91 @@ contains
end function psb_c_smm_mat_write
+ function psb_c_sglobal_mat_write(ah,cdh) bind(c) result(res)
+ use psb_base_mod
+ use psb_util_mod
+ use psb_base_string_cbind_mod
+ implicit none
+ integer(psb_c_ipk_) :: res
+
+ type(psb_c_sspmat) :: ah
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_sspmat_type), pointer :: ap
+ type(psb_desc_type), pointer :: descp
+ ! Local variables
+ type(psb_sspmat_type) :: aglobal
+ integer(psb_ipk_) :: info, iam, np
+ type(psb_ctxt_type) :: ctxt
+ character(len=40) :: matrixname
+
+ res = -1
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(ah%item)) then
+ call c_f_pointer(ah%item,ap)
+ else
+ return
+ end if
+
+ ctxt = descp%get_ctxt()
+ call psb_info(ctxt,iam,np)
+ call psb_gather(aglobal,ap,descp,info)
+ if (iam == psb_root_) then
+ write(matrixname,'("A-np-",I1,".mtx")') np
+ call mm_mat_write(aglobal,"Global matrix",info,filename=trim(matrixname))
+ end if
+
+ call psb_spfree(aglobal,descp,info)
+ res = info
+
+ end function psb_c_sglobal_mat_write
+
+ function psb_c_sglobal_vec_write(vh,cdh) bind(c) result(res)
+ use psb_base_mod
+ use psb_util_mod
+ use psb_base_string_cbind_mod
+ implicit none
+ integer(psb_c_ipk_) :: res
+
+ type(psb_c_svector) :: vh
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_s_vect_type), pointer :: vp
+ type(psb_desc_type), pointer :: descp
+ ! Local variables
+ real(psb_spk_), allocatable :: vglobal(:)
+ integer(psb_ipk_) :: info, iam, np
+ type(psb_ctxt_type) :: ctxt
+ character(len=40) :: vecname
+
+ res = -1
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(vh%item)) then
+ call c_f_pointer(vh%item,vp)
+ else
+ return
+ end if
+
+ ctxt = descp%get_ctxt()
+ call psb_info(ctxt,iam,np)
+ call psb_gather(vglobal,vp,descp,info)
+ if (iam == psb_root_) then
+ write(vecname,'("v-np-",I1,".mtx")') np
+ call mm_array_write(vglobal,"Global vector",info,filename=trim(vecname))
+ end if
+
+ deallocate(vglobal,stat=info)
+ res = info
+
+ end function psb_c_sglobal_vec_write
+
+
end module psb_sutil_cbind_mod
diff --git a/cbind/util/psb_z_util_cbind_mod.f90 b/cbind/util/psb_z_util_cbind_mod.f90
index e0b60005..792f836f 100644
--- a/cbind/util/psb_z_util_cbind_mod.f90
+++ b/cbind/util/psb_z_util_cbind_mod.f90
@@ -41,4 +41,91 @@ contains
end function psb_c_zmm_mat_write
+ function psb_c_zglobal_mat_write(ah,cdh) bind(c) result(res)
+ use psb_base_mod
+ use psb_util_mod
+ use psb_base_string_cbind_mod
+ implicit none
+ integer(psb_c_ipk_) :: res
+
+ type(psb_c_zspmat) :: ah
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_zspmat_type), pointer :: ap
+ type(psb_desc_type), pointer :: descp
+ ! Local variables
+ type(psb_zspmat_type) :: aglobal
+ integer(psb_ipk_) :: info, iam, np
+ type(psb_ctxt_type) :: ctxt
+ character(len=40) :: matrixname
+
+ res = -1
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(ah%item)) then
+ call c_f_pointer(ah%item,ap)
+ else
+ return
+ end if
+
+ ctxt = descp%get_ctxt()
+ call psb_info(ctxt,iam,np)
+ call psb_gather(aglobal,ap,descp,info)
+ if (iam == psb_root_) then
+ write(matrixname,'("A-np-",I1,".mtx")') np
+ call mm_mat_write(aglobal,"Global matrix",info,filename=trim(matrixname))
+ end if
+
+ call psb_spfree(aglobal,descp,info)
+ res = info
+
+ end function psb_c_zglobal_mat_write
+
+ function psb_c_zglobal_vec_write(vh,cdh) bind(c) result(res)
+ use psb_base_mod
+ use psb_util_mod
+ use psb_base_string_cbind_mod
+ implicit none
+ integer(psb_c_ipk_) :: res
+
+ type(psb_c_zvector) :: vh
+ type(psb_c_descriptor) :: cdh
+
+ type(psb_z_vect_type), pointer :: vp
+ type(psb_desc_type), pointer :: descp
+ ! Local variables
+ complex(psb_dpk_), allocatable :: vglobal(:)
+ integer(psb_ipk_) :: info, iam, np
+ type(psb_ctxt_type) :: ctxt
+ character(len=40) :: vecname
+
+ res = -1
+ if (c_associated(cdh%item)) then
+ call c_f_pointer(cdh%item,descp)
+ else
+ return
+ end if
+ if (c_associated(vh%item)) then
+ call c_f_pointer(vh%item,vp)
+ else
+ return
+ end if
+
+ ctxt = descp%get_ctxt()
+ call psb_info(ctxt,iam,np)
+ call psb_gather(vglobal,vp,descp,info)
+ if (iam == psb_root_) then
+ write(vecname,'("v-np-",I1,".mtx")') np
+ call mm_array_write(vglobal,"Global vector",info,filename=trim(vecname))
+ end if
+
+ deallocate(vglobal,stat=info)
+ res = info
+
+ end function psb_c_zglobal_vec_write
+
+
end module psb_zutil_cbind_mod
diff --git a/docs/html/index.html b/docs/html/index.html
index 2906d9ce..c4f777e4 100644
--- a/docs/html/index.html
+++ b/docs/html/index.html
@@ -20,8 +20,8 @@ class="newline" /> Salvatore Filippone
Alfredo Buttari
Software version: 3.7.0.1
May 11th, 2021
+class="newline" />Software version: 3.8.0
May 1st, 2022
diff --git a/docs/html/userhtml.html b/docs/html/userhtml.html
index 2906d9ce..c4f777e4 100644
--- a/docs/html/userhtml.html
+++ b/docs/html/userhtml.html
@@ -20,8 +20,8 @@ class="newline" /> Salvatore Filippone
Alfredo Buttari
Software version: 3.7.0.1
May 11th, 2021
+class="newline" />Software version: 3.8.0
May 1st, 2022
diff --git a/docs/html/userhtmlsu36.html b/docs/html/userhtmlsu36.html
index 9616adcb..d9cadf8e 100644
--- a/docs/html/userhtmlsu36.html
+++ b/docs/html/userhtmlsu36.html
@@ -22,7 +22,7 @@ href="userhtmlsu32.html#userhtmlsu39.html" >up]
-call psb_spall(a, desc_a, info, nnz)
+call psb_spall(a, desc_a, info [, nnz, dupl, bldmode])
@@ -61,12 +61,47 @@ class="newline" />Type: optional.
Intent: in.
Specified as: an integer value.
-
+class="newline" />Specified as: an integer value.
+
+dupl How to handle duplicate coefficients.
Scope: global.
Type: optional.
Intent: in.
Specified as: integer, possible values: psb_dupl_ovwrt_, psb_dupl_add_,
+ psb_dupl_err_.
+
+bldmode Whether to keep track of matrix entries that do not belong to the
+ current process.
Scope: global.
Type: optional.
Intent: in.
Specified as:
+ an integer value psb_matbld_noremote_, psb_matbld_remote_. Default:
+ psb_matbld_noremote_.
+
-
On Return
-
+
+
+
-
a
- required
Intent: out.
An integer value; 0 means no error has been detected.
-Notes
- On exit from this routine the sparse matrix is in the build state.
-
-
-
- The descriptor may be in either the build or assembled state.
@@ -110,19 +142,24 @@ class="cmbx-12">Notes
class="cmmi-10">nnz in the
assembled matrix may substantially improve performance in the matrix
build phase, as it will reduce or eliminate the need for (potentially
- multiple) data reallocations.
+ multiple) data reallocations;
+
+
Using psb_matbld_remote_ is likely to cause a runtime overhead at
+ assembly time;
-