| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !-----------------------------------------------------------------------
- ! CVS m_SparseMatrixToMaps.F90,v 1.13 2007-05-11 02:09:48 rloy Exp
- ! CVS MCT_2_8_0
- !BOP -------------------------------------------------------------------
- !
- ! !MODULE: m_SparseMatrixToMaps -- Maps from the Sparse Matrix
- !
- ! !DESCRIPTION:
- ! The {\tt SparseMatrix} provides consolidated (on one process) or
- ! distributed sparse matrix storage for the operation
- ! ${\bf y} = {\bf M} {\bf x}$, where {\bf x} and {\bf y} are vectors,
- ! and {\bf M} is a matrix. In performing parallel matrix-vector
- ! multiplication, one has numerous options regarding the decomposition
- ! of the matrix {\bf M}, and the vectors {\bf y} and {\bf x}.
- ! This module provides services to generate mct mapping components---the
- ! {\tt GlobalMap} and {\tt GlobalSegMap} for the vectors {\bf y} and/or
- ! {\bf x} based on the decomposition of the sparse matrix {\bf M}.
- !
- ! !INTERFACE:
- module m_SparseMatrixToMaps
- !
- ! !USES:
- !
- use m_SparseMatrix, only : SparseMatrix
- implicit none
- private ! except
- public :: SparseMatrixToXGlobalSegMap
- public :: SparseMatrixToYGlobalSegMap
- interface SparseMatrixToXGlobalSegMap ; module procedure &
- SparseMatrixToXGlobalSegMap_
- end interface
- interface SparseMatrixToYGlobalSegMap ; module procedure &
- SparseMatrixToYGlobalSegMap_
- end interface
- ! !REVISION HISTORY:
- ! 13Apr01 - J.W. Larson <larson@mcs.anl.gov> - initial prototype
- ! and API specifications.
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname='MCT::m_SparseMatrixToMaps'
- contains
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: SparseMatrixToXGlobalSegMap_ - Generate X GlobalSegmap.
- !
- ! !DESCRIPTION: Given an input {\tt SparseMatrix} argument {\tt sMat},
- ! this routine generates an output {\tt GlobalSegMap} variable
- ! {\tt xGSMap}, which describes the domain decomposition of the vector
- ! {\bf x} in the distributed matrix-vector multiplication
- ! $${\bf y} = {\bf M} {\bf x}.$$
- !
- ! !INTERFACE:
- subroutine SparseMatrixToXGlobalSegMap_(sMat, xGSMap, root, comm, comp_id)
- !
- ! !USES:
- !
- use m_stdio, only : stderr
- use m_die, only : die
- use m_mpif90
- use m_List, only : List
- use m_List, only : List_init => init
- use m_List, only : List_clean => clean
- use m_SparseMatrix, only : SparseMatrix
- use m_SparseMatrix, only : SparseMatrix_nCols => nCols
- use m_SparseMatrix, only : SparseMatrix_lsize => lsize
- use m_SparseMatrix, only : SparseMatrix_indexIA => indexIA
- use m_SparseMatrix, only : SparseMatrix_SortPermute => SortPermute
- use m_GlobalSegMap, only : GlobalSegMap
- use m_GlobalSegMap, only : GlobalSegMap_init => init
- implicit none
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: root ! communicator root
- integer, intent(in) :: comm ! communicator handle
- integer, intent(in) :: comp_id ! component id
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(SparseMatrix), intent(inout) :: sMat ! input SparseMatrix
- ! !OUTPUT PARAMETERS:
- !
- type(GlobalSegMap), intent(out) :: xGSMap ! segmented decomposition
- ! for x
- ! !REVISION HISTORY:
- ! 13Apr01 - J.W. Larson <larson@mcs.anl.gov> - API specification.
- ! 25Apr01 - J.W. Larson <larson@mcs.anl.gov> - First version.
- ! 27Apr01 - J.W. Larson <larson@mcs.anl.gov> - Bug fix--intent of
- ! argument sMat changed from (IN) to (INOUT)
- ! 27Apr01 - R.L. Jacob <jacob@mcs.anl.gov> - bug fix-- add use
- ! statement for SortPermute
- ! 01May01 - R.L. Jacob <jacob@mcs.anl.gov> - make comp_id an
- ! input argument
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_=myname//'::SparseMatrixToXGlobalSegMap_'
- ! SparseMatrix attributes:
- integer :: lsize
- ! GlobalSegMap input attributes:
- integer :: gsize, ngseg
- integer, dimension(:), pointer :: starts, lengths
- ! Temporary array for identifying each matrix element column and
- ! process ID destination
- integer, dimension(:), allocatable :: gCol, element_pe_locs
- ! Index to identify the gcol attribute in sMat:
- integer :: igCol
- ! Matrix element sorting keys list:
- type(List) :: sort_keys
- ! Loop index and error flag:
- integer :: i, ierr
- ! Determine he local number of matrix elements lsize
- lsize = SparseMatrix_lsize(sMat)
- ! The value of gsize is taken from the number of columns in sMat:
- gsize = SparseMatrix_nCols(sMat)
- ! Sort SparseMatrix entries by global column index gcol, then
- ! global row index.
- ! Create Sort keys list
- call List_init(sort_keys,'gcol:grow')
- ! Sort and permute the entries of sMat into lexicographic order
- ! by global column, then global row.
- call SparseMatrix_SortPermute(sMat, sort_keys)
- ! Clean up sort keys list
- call List_clean(sort_keys)
- ! Allocate storage space for matrix element column indices and
- ! process ID destinations
- allocate(gCol(lsize), stat=ierr)
- if(ierr /= 0) then
- call die(myname_,'allocate(gCol...',ierr)
- endif
- ! Extract global column information and place in array gCol
- igCol = SparseMatrix_indexIA(sMat, 'gcol', dieWith=myname_)
- do i=1, lsize
- gCol(i) = sMat%data%iAttr(igCol,i)
- end do
- ! Scan sorted entries of gCol to count segments (ngseg), and
- ! their starting indices and lengths (returned in the arrays
- ! starts(:) and lengths(:), respectively)
- call ComputeSegments_(gCol, lsize, ngseg, starts, lengths)
- ! Now we have sufficient data to call the GlobalSegMap
- ! initialization using distributed data:
- call GlobalSegMap_init(xGSMap, starts, lengths, root, comm, &
- comp_id, gsize=gsize)
-
- ! clean up temporary arrays gCol(:), starts(:) and lengths(:),
- ! (the latter two were allocated in the call to the routine
- ! ComputeSegments_())
- deallocate(gCol, starts, lengths, stat=ierr)
- if(ierr /= 0) then
- call die(myname_,'deallocate(gCol...',ierr)
- endif
- end subroutine SparseMatrixToXGlobalSegMap_
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: SparseMatrixToYGlobalSegMap_ - Generate Y GlobalSegmap.
- !
- ! !DESCRIPTION: Given an input {\tt SparseMatrix} argument {\tt sMat},
- ! this routine generates an output {\tt GlobalSegMap} variable
- ! {\tt yGSMap}, which describes the domain decomposition of the vector
- ! {\bf y} in the distributed matrix-vector multiplication
- ! ${\bf y} = {\bf M} {\bf x}$.
- !
- ! !INTERFACE:
- subroutine SparseMatrixToYGlobalSegMap_(sMat, yGSMap, root, comm, comp_id)
- !
- ! !USES:
- !
- use m_stdio, only : stderr
- use m_die, only : die
- use m_List, only : List
- use m_List, only : List_init => init
- use m_List, only : List_clean => clean
- use m_SparseMatrix, only : SparseMatrix
- use m_SparseMatrix, only : SparseMatrix_nRows => nRows
- use m_SparseMatrix, only : SparseMatrix_lsize => lsize
- use m_SparseMatrix, only : SparseMatrix_indexIA => indexIA
- use m_SparseMatrix, only : SparseMatrix_SortPermute => SortPermute
- use m_GlobalSegMap, only : GlobalSegMap
- use m_GlobalSegMap, only : GlobalSegMap_init => init
- implicit none
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: root ! communicator root
- integer, intent(in) :: comm ! communicator handle
- integer, intent(in) :: comp_id ! component id
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(SparseMatrix), intent(inout) :: sMat ! input SparseMatrix
- ! !OUTPUT PARAMETERS:
- !
- type(GlobalSegMap), intent(out) :: yGSMap ! segmented decomposition
- ! for y
- ! !REVISION HISTORY:
- ! 13Apr01 - J.W. Larson <larson@mcs.anl.gov> - API specification.
- ! 25Apr01 - J.W. Larson <larson@mcs.anl.gov> - initial code.
- ! 27Apr01 - J.W. Larson <larson@mcs.anl.gov> - Bug fix--intent of
- ! argument sMat changed from (IN) to (INOUT)
- ! 27Apr01 - R.L. Jacob <jacob@mcs.anl.gov> - bug fix-- add use
- ! statement for SortPermute
- ! 01May01 - R.L. Jacob <jacob@mcs.anl.gov> - make comp_id an
- ! input argument
- ! 07May02 - J.W. Larson <larson@mcs.anl.gov> - Changed interface to
- ! make it consistent with SparseMatrixToXGlobalSegMap_().
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_=myname//'::SparseMatrixToYGlobalSegMap_'
- ! SparseMatrix attributes:
- integer :: lsize
- ! GlobalSegMap input attributes:
- integer :: gsize, ngseg
- integer, dimension(:), pointer :: starts, lengths
- ! Temporary array for identifying each matrix element column and
- ! process ID destination
- integer, dimension(:), allocatable :: gRow, element_pe_locs
- ! Index to identify the gRow attribute in sMat:
- integer :: igRow
- ! Matrix element sorting keys list:
- type(List) :: sort_keys
- ! Loop index and error flag:
- integer :: i, ierr
- ! Determine he local number of matrix elements lsize
- lsize = SparseMatrix_lsize(sMat)
- ! The value of gsize is taken from the number of columns in sMat:
- gsize = SparseMatrix_nRows(sMat)
- ! Sort SparseMatrix entries by global column index grow, then
- ! global row index.
- ! Create Sort keys list
- call List_init(sort_keys,'grow:gcol')
- ! Sort and permute the entries of sMat into lexicographic order
- ! by global column, then global row.
- call SparseMatrix_SortPermute(sMat, sort_keys)
- ! Clean up sort keys list
- call List_clean(sort_keys)
- ! Allocate storage space for matrix element column indices and
- ! process ID destinations
- allocate(gRow(lsize), stat=ierr)
- if(ierr /= 0) then
- call die(myname_,'allocate(gRow...',ierr)
- endif
- ! Extract global column information and place in array gRow
- igRow = SparseMatrix_indexIA(sMat,'grow', dieWith=myname_)
- do i=1, lsize
- gRow(i) = sMat%data%iAttr(igRow,i)
- end do
- ! Scan sorted entries of gRow to count segments (ngseg), and
- ! their starting indices and lengths (returned in the arrays
- ! starts(:) and lengths(:), respectively)
- call ComputeSegments_(gRow, lsize, ngseg, starts, lengths)
- ! Now we have sufficient data to call the GlobalSegMap
- ! initialization using distributed data:
- call GlobalSegMap_init(yGSMap, starts, lengths, root, comm, &
- comp_id, gsize=gsize)
-
- ! clean up temporary arrays gRow(:), starts(:) and lengths(:),
- ! (the latter two were allocated in the call to the routine
- ! ComputeSegments_())
- deallocate(gRow, starts, lengths, stat=ierr)
- if(ierr /= 0) then
- call die(myname_,'deallocate(gRow...',ierr)
- endif
- end subroutine SparseMatrixToYGlobalSegMap_
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: CreateSegments_ - Generate segment information.
- !
- ! !DESCRIPTION: This routine examines an input {\tt INTEGER} list of
- ! numbers {\tt indices} (of length {\tt num\_indices}), determines the
- ! number of segments of consecutive numbers (or runs) {\tt nsegs}. The
- ! starting indices for each run, and their lengths are returned in the
- ! {\tt INTEGER} arrays {\tt starts(:)} and {\tt lengths(:)}, respectively.
- !
- ! !INTERFACE:
- subroutine ComputeSegments_(indices, num_indices, nsegs, starts, lengths)
- !
- ! !USES:
- !
- use m_stdio, only : stderr
- use m_die, only : die
- implicit none
- !
- ! !INPUT PARAMETERS:
- !
- integer, dimension(:), intent(in) :: indices
- integer, intent(in) :: num_indices
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: nsegs
- integer, dimension(:), pointer :: starts
- integer, dimension(:), pointer :: lengths
- ! !REVISION HISTORY:
- ! 19Apr01 - J.W. Larson <larson@mcs.anl.gov> - API specification.
- ! 25Apr01 - J.W. Larson <larson@mcs.anl.gov> - Initial code.
- ! 27Apr01 - J.W. Larson <larson@mcs.anl.gov> - Bug fix--error in
- ! computation of segment starts/lengths.
- ! 27Nov01 - E.T. Ong <eong@mcs.anl.gov> - Bug fix--initialize
- ! nsegs=0 in case num_indices=0.
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_=myname//'::ComputeSegments_'
- integer :: i, ierr
- ! First pass: count the segments
- nsegs = 0
- do i=1,num_indices
- if(i == 1) then ! bootstrap segment counting process
- nsegs = 1
- else
- if(indices(i) > indices(i-1) + 1) then ! new segment
- nsegs = nsegs + 1
- endif
- endif ! if(i==1)
- end do ! do i=1, num_indices
- ! Allocate storage space for starts(:) and lengths(:)
- allocate(starts(nsegs), lengths(nsegs), stat=ierr)
- if(ierr /= 0) then
- call die(myname_,'allocate(starts...',ierr)
- endif
- ! Second pass: compute segment start/length info
- do i=1,num_indices
- select case(i)
- case(1) ! bootstrap segment counting process
- nsegs = 1
- starts(nsegs) = indices(i)
- ! rml patch
- lengths(nsegs) = 1
- case default
- if(i == num_indices) then ! last point
- if(indices(i) > indices(i-1) + 1) then ! new segment with 1 pt.
- ! first, close the books on the penultimate segment:
- lengths(nsegs) = indices(i-1) - starts(nsegs) + 1
- nsegs = nsegs + 1
- starts(nsegs) = indices(i)
- lengths(nsegs) = 1 ! (just one point)
- else
- lengths(nsegs) = indices(i) - starts(nsegs) + 1
- endif
- else
- if(indices(i) > indices(i-1) + 1) then ! new segment
- lengths(nsegs) = indices(i-1) - starts(nsegs) + 1
- nsegs = nsegs + 1
- starts(nsegs) = indices(i)
- endif
- endif
- end select ! select case(i)
- end do ! do i=1, num_indices
- end subroutine ComputeSegments_
- end module m_SparseMatrixToMaps
|