|
|
|
@ -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.
|
|
|
|
|
!
|
|
|
|
|
! Arguments:
|
|
|
|
|
! nv - integer Number of indices required 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
|
|
|
|
|
! indices
|
|
|
|
|
! desc_a - type(psb_desc_type). The communication descriptor.
|
|
|
|
|
! idxmap - class(psb_indx_map). The index map
|
|
|
|
|
! 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)
|
|
|
|
|
use psb_serial_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_ipk_) :: ictxt,np,me, nresp
|
|
|
|
|
integer(psb_ipk_), parameter :: nt=4
|
|
|
|
|
integer(psb_ipk_) :: tmpv(2)
|
|
|
|
|
integer(psb_ipk_) :: tmpv(4)
|
|
|
|
|
logical, parameter :: do_timings=.false., trace=.false.
|
|
|
|
|
integer(psb_ipk_), save :: idx_sweep0=-1, idx_loop_a2a=-1, idx_loop_neigh=-1
|
|
|
|
|
real(psb_dpk_) :: t0, t1, t2, t3, t4
|
|
|
|
@ -113,17 +143,6 @@ subroutine psi_graph_fnd_owner(idx,iprc,idxmap,info)
|
|
|
|
|
goto 9999
|
|
|
|
|
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
|
|
|
|
|
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(2) = nrest_max
|
|
|
|
|
tmpv(3) = n_row
|
|
|
|
|
tmpv(4) = psb_cd_get_maxspace()
|
|
|
|
|
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 ((tmpv(1) > 0).and.(tmpv(2) >0)) then
|
|
|
|
|
!
|
|
|
|
|