Internal docs for fnd_owner variants.

merge-paraggr
Salvatore Filippone 5 years ago
parent e60e3c9d91
commit c57aa2ac5c

@ -30,21 +30,23 @@
! !
! !
! !
! File: psi_fnd_owner.f90 ! File: psi_a2a_fnd_owner.f90
! !
! Subroutine: psi_fnd_owner ! Subroutine: psi_a2a_fnd_owner
! Figure out who owns global indices. ! Figure out who owns global indices.
! !
! Arguments: ! Arguments:
! nv - integer Number of indices required on the calling
! process
! idx(:) - integer Required indices on the calling process. ! idx(:) - integer Required indices on the calling process.
! Note: the indices should be unique! ! Note: the indices should be unique!
! iprc(:) - integer(psb_ipk_), allocatable Output: process identifiers for the corresponding ! iprc(:) - integer(psb_ipk_), allocatable Output: process identifiers for the corresponding
! indices ! indices
! desc_a - type(psb_desc_type). The communication descriptor. ! idxmap - class(psb_indx_map). The index map
! info - integer. return code. ! info - integer. return code.
! !
! This version does not assume any prior knowledge about the process topology,
! so it goes for an all-to-all by building an auxiliary neighbours list and
! reusing the neighbour version.
!
subroutine psi_a2a_fnd_owner(idx,iprc,idxmap,info) subroutine psi_a2a_fnd_owner(idx,iprc,idxmap,info)
use psb_serial_mod use psb_serial_mod
use psb_const_mod use psb_const_mod
@ -99,7 +101,7 @@ subroutine psi_a2a_fnd_owner(idx,iprc,idxmap,info)
end if end if
! !
! Reuse the other version by tricking it with an adjcncy list ! Reuse the adjcncy version by tricking it with an adjcncy list
! that contains everybody but ME. ! that contains everybody but ME.
! !
nv = size(idx) nv = size(idx)

@ -30,12 +30,27 @@
! !
! !
! !
! File: psi_fnd_owner.f90
! !
! Subroutine: psi_fnd_owner ! File: psi_adjcncy_fnd_owner.f90
!
! Subroutine: psi_adjcncy_fnd_owner
! Figure out who owns global indices. ! Figure out who owns global indices.
! !
! Arguments: ! Arguments:
! idx(:) - integer Required indices on the calling process.
! Note: the indices should be unique!
! iprc(:) - integer(psb_ipk_), allocatable Output: process identifiers for the corresponding
! indices
! adj(:) - integer(psb_ipk_) Input: list of topological neighbours for current process.
!
! idxmap - class(psb_indx_map). The index map
! info - integer. return code.
!
! This version takes on input a list of processes that are assumed to
! be topological neighbours of the current one. Each process will send to all
! of its neighbours the list of indices for which it is trying to find the
! owner, prepare its own answers, and collect answers from others.
! There are
! !
subroutine psi_adjcncy_fnd_owner(idx,iprc,adj,idxmap,info) subroutine psi_adjcncy_fnd_owner(idx,iprc,adj,idxmap,info)
use psb_serial_mod use psb_serial_mod
@ -69,8 +84,10 @@ subroutine psi_adjcncy_fnd_owner(idx,iprc,adj,idxmap,info)
& last_ih, last_j, nidx, nrecv, nadj & last_ih, last_j, nidx, nrecv, nadj
integer(psb_lpk_) :: mglob, ih integer(psb_lpk_) :: mglob, ih
integer(psb_ipk_) :: ictxt,np,me integer(psb_ipk_) :: ictxt,np,me
logical, parameter :: gettime=.false., new_impl=.true. logical, parameter :: gettime=.false., debug=.false.
logical, parameter :: a2av_impl=.true., debug=.false. logical, parameter :: a2av_impl=.true.
logical, parameter :: mpi_irecv_impl=.false.
logical, parameter :: psb_rcv_impl=.false.
real(psb_dpk_) :: t0, t1, t2, t3, t4, tamx, tidx real(psb_dpk_) :: t0, t1, t2, t3, t4, tamx, tidx
character(len=20) :: name character(len=20) :: name
@ -175,6 +192,10 @@ subroutine psi_adjcncy_fnd_owner(idx,iprc,adj,idxmap,info)
call mpi_alltoallv(tproc,rvsz,rvidx,psb_mpi_ipk_,& call mpi_alltoallv(tproc,rvsz,rvidx,psb_mpi_ipk_,&
& lclidx,sdsz,sdidx,psb_mpi_ipk_,icomm,iret) & lclidx,sdsz,sdidx,psb_mpi_ipk_,icomm,iret)
!
! Because IPRC has been initialized to -1, the MAX operation selects
! the answers.
!
do i=0, np-1 do i=0, np-1
if (sdsz(i)>0) then if (sdsz(i)>0) then
! Must be nidx == sdsz(i) ! Must be nidx == sdsz(i)
@ -183,8 +204,7 @@ subroutine psi_adjcncy_fnd_owner(idx,iprc,adj,idxmap,info)
end do end do
if (debug) write(0,*) me,' End of adjcncy_fnd ',iprc(1:nidx) if (debug) write(0,*) me,' End of adjcncy_fnd ',iprc(1:nidx)
else else if (mpi_irecv_impl) then
if (new_impl) then
! !
! First simple minded version with auxiliary arrays ! First simple minded version with auxiliary arrays
! dimensioned on NP. ! dimensioned on NP.
@ -292,7 +312,7 @@ subroutine psi_adjcncy_fnd_owner(idx,iprc,adj,idxmap,info)
end do end do
if (debug) write(0,*) me,' End of adjcncy_fnd ',iprc(1:nidx) if (debug) write(0,*) me,' End of adjcncy_fnd ',iprc(1:nidx)
else else if (psb_rcv_impl) then
Allocate(hidx(0:np),hsz(np),& Allocate(hidx(0:np),hsz(np),&
& sdsz(0:np-1),rvsz(0:np-1),stat=info) & sdsz(0:np-1),rvsz(0:np-1),stat=info)
@ -360,7 +380,10 @@ subroutine psi_adjcncy_fnd_owner(idx,iprc,adj,idxmap,info)
if (nidx > 0) call psb_rcv(ictxt,tproc(1:nidx),adj(j)) if (nidx > 0) call psb_rcv(ictxt,tproc(1:nidx),adj(j))
iprc(1:nidx) = max(iprc(1:nidx), tproc(1:nidx)) iprc(1:nidx) = max(iprc(1:nidx), tproc(1:nidx))
end do end do
end if else
info = psb_err_internal_error_
call psb_errpush(info,name,a_err='invalid exchange alg choice')
goto 9999
end if end if
call psb_erractionrestore(err_act) call psb_erractionrestore(err_act)

@ -30,21 +30,51 @@
! !
! !
! !
! File: psi_fnd_owner.f90
! !
! Subroutine: psi_fnd_owner ! File: psi_graph_fnd_owner.f90
!
! Subroutine: psi_graph_fnd_owner
! Figure out who owns global indices. ! Figure out who owns global indices.
! !
! Arguments: ! Arguments:
! nv - integer Number of indices required on the calling
! process
! idx(:) - integer Required indices on the calling process. ! idx(:) - integer Required indices on the calling process.
! Note: the indices should be unique! !
! iprc(:) - integer(psb_ipk_), allocatable Output: process identifiers for the corresponding ! iprc(:) - integer(psb_ipk_), allocatable Output: process identifiers for the corresponding
! indices ! indices
! desc_a - type(psb_desc_type). The communication descriptor. ! idxmap - class(psb_indx_map). The index map
! info - integer. return code. ! info - integer. return code.
! !
! This is the method to find out who owns a set of indices.
! In principle we could do the following:
! 1. Do an allgatherv of IDX
! 2. For each of the collected indices figure if current proces owns it
! 3. Scatter the results
! 4. Loop through the answers
! This method is guaranteed to find the owner, unless an input index has
! an invalid value, however it could easily require too much additional space
! because each block of indices is replicated to all processes.
! Therefore the current routine takes a different approach:
! -1. Figure out a maximum size for a buffer to collect the IDX; the buffer
! should allow for at least one index from each process (i.e. min size NP); also
! check if we have an adjacency list of processes on input;
! 0. If the initial adjacency list is not empty, use psi_adj_fnd_sweep to go
! through all indices and use multiple calls to psi_adjcncy_fnd_owner
! (up to the buffer size) to see if the owning processes are in the
! initial neighbours list;
! 1. Extract a sample from IDX, up to the buffer size, and do a call
! to psi_a2a_fnd_owner. This is guaranteed to find the owners of all indices
! in the sample;
! 2. Build the list of processes that own the sample indices; these are
! (a subset of) the topological neighbours, and store the list in IDXMAP
! 3. Use psi_adj_fnd_sweep to go through all remaining indices and use
! multiple calls to psi_adjcncy_fnd_owner (up to the buffer size)
! to see if the owning processes are in the current neighbours list;
! 4. If the input indices IDX have not been exhausted, cycle to 1.
!
! Thus, we are alternating between asking all processes for a subset of indices, and
! asking a subset of processes for all the indices, 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,idxmap,info)
use psb_serial_mod use psb_serial_mod
use psb_const_mod use psb_const_mod
@ -76,7 +106,7 @@ subroutine psi_graph_fnd_owner(idx,iprc,idxmap,info)
integer(psb_lpk_) :: mglob, ih integer(psb_lpk_) :: mglob, ih
integer(psb_ipk_) :: ictxt,np,me, nresp integer(psb_ipk_) :: ictxt,np,me, nresp
integer(psb_ipk_), parameter :: nt=4 integer(psb_ipk_), parameter :: nt=4
integer(psb_ipk_) :: tmpv(2) integer(psb_ipk_) :: tmpv(4)
logical, parameter :: do_timings=.false., trace=.false. logical, parameter :: do_timings=.false., trace=.false.
integer(psb_ipk_), save :: idx_sweep0=-1, idx_loop_a2a=-1, idx_loop_neigh=-1 integer(psb_ipk_), save :: idx_sweep0=-1, idx_loop_a2a=-1, idx_loop_neigh=-1
real(psb_dpk_) :: t0, t1, t2, t3, t4 real(psb_dpk_) :: t0, t1, t2, t3, t4
@ -113,17 +143,6 @@ subroutine psi_graph_fnd_owner(idx,iprc,idxmap,info)
goto 9999 goto 9999
end if end if
!
! Choice of maxspace should be adjusted to account for a default
! "sensible" size and/or a user-specified value
!
tmpv(1) = n_row
tmpv(2) = psb_cd_get_maxspace()
call psb_max(ictxt,tmpv)
locr_max = tmpv(1)
maxspace = min(nt*locr_max,tmpv(2))
maxspace = max(maxspace,np)
if (trace.and.(me == 0)) write(0,*) ' Through graph_fnd_owner with maxspace:',maxspace
! !
! !
! !
@ -148,9 +167,20 @@ subroutine psi_graph_fnd_owner(idx,iprc,idxmap,info)
n_rest = nv - n_answers n_rest = nv - n_answers
nrest_max = n_rest nrest_max = n_rest
!
! Choice of maxspace should be adjusted to account for a default
! "sensible" size and/or a user-specified value
!
tmpv(1) = nadj tmpv(1) = nadj
tmpv(2) = nrest_max tmpv(2) = nrest_max
tmpv(3) = n_row
tmpv(4) = psb_cd_get_maxspace()
call psb_max(ictxt,tmpv) call psb_max(ictxt,tmpv)
locr_max = tmpv(3)
maxspace = nt*locr_max
if (tmpv(4) > 0) maxspace = min(maxspace,tmpv(4))
maxspace = max(maxspace,np)
if (trace.and.(me == 0)) write(0,*) ' Through graph_fnd_owner with maxspace:',maxspace
if (do_timings) call psb_tic(idx_sweep0) if (do_timings) call psb_tic(idx_sweep0)
if ((tmpv(1) > 0).and.(tmpv(2) >0)) then if ((tmpv(1) > 0).and.(tmpv(2) >0)) then
! !

@ -30,21 +30,27 @@
! !
! !
! !
! File: psi_fnd_owner.f90 ! File: psi_indx_map_fnd_owner.f90
! !
! Subroutine: psi_fnd_owner ! Subroutine: psi_indx_map_fnd_owner
! Figure out who owns global indices. ! Figure out who owns global indices.
! !
! Arguments: ! Arguments:
! nv - integer Number of indices required on the calling
! process
! idx(:) - integer Required indices on the calling process. ! idx(:) - integer Required indices on the calling process.
! Note: the indices should be unique! ! Note: the indices should be unique!
! iprc(:) - integer(psb_ipk_), allocatable Output: process identifiers for the corresponding ! iprc(:) - integer(psb_ipk_), allocatable Output: process identifiers for the corresponding
! indices ! indices
! desc_a - type(psb_desc_type). The communication descriptor. ! idxmap - class(psb_indx_map). The index map
! info - integer. return code. ! info - integer. return code.
! !
! This is the default implementation of the FND_OWNER method.
! If a particular index map class has additional information, it can override it
! (see e.g. the GEN_BLOCK_MAP class).
!
! 1. Check if IDXM%PARTS is available, and use it; or
! 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)
use psb_serial_mod use psb_serial_mod
use psb_const_mod use psb_const_mod

Loading…
Cancel
Save