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

  1. On exit from this routine the sparse matrix is in the build state. - - -
  2. 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;
  • -