source: CPL/oasis3-mct/branches/OASIS3-MCT_2.0_branch/lib/mct/mct/m_SparseMatrixPlus.F90 @ 4775

Last change on this file since 4775 was 4775, checked in by aclsce, 4 years ago
  • Imported oasis3-mct from Cerfacs svn server (not suppotred anymore).

The version has been extracted from https://oasis3mct.cerfacs.fr/svn/branches/OASIS3-MCT_2.0_branch/oasis3-mct@1818

File size: 31.0 KB
Line 
1!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2!    Math and Computer Science Division, Argonne National Laboratory   !
3!BOP -------------------------------------------------------------------
4!
5! !MODULE: m_SparseMatrixPlus -- Class Parallel for Matrix-Vector Multiplication
6!
7! !DESCRIPTION:
8! Matrix-vector multiplication is one of the MCT's core services, and is
9! used primarily for the interpolation of data fields from one physical
10! grid to another.  Let ${\bf x} \in \Re^{N_x}$ and
11! ${\bf y} \in \Re^{N_y}$ represent data fields on physical grids $A$
12! and $B$, respectively.  Field data is interpolated from grid $A$ to grid
13! $B$ by
14! $$ {\bf y} = {\bf M} {\bf x} , $$
15! where {\bf M} is aa  ${N_y} \times {N_x}$ matrix.
16!
17! Within MCT, the {\tt SparseMatrix} data type is MCT's object for
18! storing sparse matrices such as {\bf M} , and the {\tt AttrVect} data
19! type is MCT's field data storage object.  That is, {\bf x} and {\bf y}
20! are each stored in {\tt AttrVect} form, and {\bf M} is stored as a
21! {\tt SparseMatrix}. 
22!
23! For global address spaces (uniprocessor or shared-memory parallel), this
24! picture of matrix-vector multiplication is sufficient.  If one wishes
25! to perform {\em distributed-memory parallel} matrix-vector multiplication,
26! however, in addition to computation, one must consider {\em communication}.
27!
28! There are three basic message-passing parallel strategies for computing
29! ${\bf y} = {\bf M} {\bf x}$:
30!
31!\begin{enumerate}
32! \item Decompose {\bf M} based on its {\em rows}, and corresponding to the
33! decomposition for the vector {\bf y}.  That is, if a given process owns
34! the $i^{\rm th}$ element of {\bf y}, then all the elements of row $i$ of
35! {\bf M} also reside on this process.  Then  ${\bf y} = {\bf M} {\bf x}$ is
36! implemented as follows:
37! \begin{enumerate}
38! \item Create an {\em intermediate vector} {\bf x'} that is the pre-image of
39! the elements of {\bf y} owned locally.
40! \item Comunnicate with the appropriate processes on the local communicator to
41! gather from {\bf x} the elements of {\bf x'}.
42! \item Compute ${\bf y} = {\bf M} {\bf x'}$.
43! \item Destroy the data structure holding {\bf x'}.
44! \end{enumerate}
45! \item Decompose {\bf M} based on its {\em columns}, and corresponding to the
46! decomposition for the vector {\bf x}.  That is, if a given process owns
47! the $j^{\rm th}$ element of {\bf x}, then all the elements of column $j$ of
48! {\bf M} also reside on this process.  Then  ${\bf y} = {\bf M} {\bf x}$ is
49! implemented as follows:
50! \begin{enumerate}
51! \item Create an {\em intermediate vector} {\bf y'} that holds {\em partial sums}
52! of elements of {\bf y} computed from {\bf x} and {\bf M}.
53! \item Compute ${\bf y'} = {\bf M} {\bf x}$.
54! \item Perform communications to route elements of {\bf y'} to their eventual
55! destinations in {\bf y}, where they will be summed, resulting in the distributed
56! vector {\bf y}.
57! \item Destroy the data structure holding {\bf y'}.
58! \end{enumerate}
59! \item Decompose {\bf M} based on some arbitrary, user-supplied scheme.  This will
60! necessitate two intermediate vectors {\bf x'} and {\bf y'}. Then 
61! ${\bf y} = {\bf M} {\bf x}$ is implemented as follows:
62! \begin{enumerate}
63! \item Create {\em intermediate vectors} {\bf x'} and {\bf y'}.  The numbers of
64! elements in {\bf x'} and {\bf y'} are based {\bf M}, specifically its numbers of
65! {\em distinct} row and column index values, respectively.
66! \item Comunnicate with the appropriate processes on the local communicator to
67! gather from {\bf x} the elements of {\bf x'}.
68! \item Compute ${\bf y'} = {\bf M} {\bf x'}$.
69! \item Perform communications to route elements of {\bf y'} to their eventual
70! destinations in {\bf y}, where they will be summed, resulting in the distributed
71! vector {\bf y}.
72! \item Destroy the data structures holding {\bf x'} and {\bf y'}.
73! \end{enumerate}
74! \end{enumerate}
75!
76! These operations require information about many aspects of the multiplication
77! process.  These data are:
78! \begin{itemize}
79! \item The matrix-vector parallelization strategy, which is one of the following:
80! \begin{enumerate}
81! \item Distributed in {\bf x}, purely data local in {\bf y}, labeled by the
82! public data member {\tt Xonly}
83! \item Purely data local {\bf x}, distributed in {\bf y}, labeled by the
84! public data member {\tt Yonly}
85! \item Distributed in both {\bf x} and {\bf y}, labeled by the public data
86! member {\tt XandY}
87! \end{enumerate}
88! \item A communications scheduler to create {\bf x'} from {\bf x};
89! \item A communications scheduler to deliver partial sums contained in {\bf y'} to
90! {\bf y}.
91! \item Lengths of the intermediate vectors {\bf x'} and {\bf y'}.
92! \end{itemize}
93!
94! In MCT, the above data are stored in a {\em master} class for {\tt SparseMatrix}-
95! {\tt AttrVect} multiplication.  This master class is called a
96! {\tt SparseMatrixPlus}.
97!
98! This module contains the definition of the {\tt SparseMatrixPlus}, and a variety
99! of methods to support it.  These include initialization, destruction, query, and
100! data import/export.
101!
102! !INTERFACE:
103
104 module m_SparseMatrixPlus
105
106! !USES:
107
108      use m_String, only : String
109      use m_SparseMatrix, only : SparseMatrix
110      use m_Rearranger, only : Rearranger
111
112! !PUBLIC TYPES:
113
114      public :: SparseMatrixPlus
115
116      Type SparseMatrixPlus
117#ifdef SEQUENCE
118        sequence
119#endif
120        type(String) :: Strategy
121        integer :: XPrimeLength
122        type(Rearranger) :: XToXPrime
123        integer :: YPrimeLength
124        type(Rearranger) :: YPrimeToY
125        type(SparseMatrix) :: Matrix
126        integer :: Tag
127      End Type SparseMatrixPlus
128
129! !PUBLIC MEMBER FUNCTIONS:
130
131      public :: init
132      public :: vecinit
133      public :: clean
134      public :: initialized
135      public :: exportStrategyToChar
136
137      interface init ; module procedure &
138        initFromRoot_, &
139        initDistributed_
140      end interface
141      interface vecinit ; module procedure vecinit_ ; end interface
142      interface clean ; module procedure clean_ ; end interface
143      interface initialized ; module procedure initialized_ ; end interface
144      interface exportStrategyToChar ; module procedure &
145        exportStrategyToChar_ 
146      end interface
147
148! !PUBLIC DATA MEMBERS:
149
150      public :: Xonly ! Matrix decomposed only by ROW (i.e., based
151                      ! on the decomposition of y); comms x->x'
152      public :: Yonly ! Matrix decomposed only by COLUMN (i.e., based
153                      ! on the decomposition of x); comms y'->y
154      public :: XandY ! Matrix has complex ROW/COLUMN decomposed
155
156! !DEFINED PARAMETERS:
157
158      integer,parameter                    :: DefaultTag = 700
159
160
161! !SEE ALSO:
162! The MCT module m_SparseMatrix for more information about Sparse Matrices.
163! The MCT module m_Rearranger for deatailed information about Communications
164! scheduling.
165! The MCT module m_AttrVect for details regarding the Attribute Vector.
166! The MCT module m_MatAttrVectMult for documentation of API's that use
167! the SparseMatrixPlus.
168!
169! !REVISION HISTORY:
170! 29August 2002 - J. Larson <larson@mcs.anl.gov> - API specification.
171!EOP -------------------------------------------------------------------
172
173      character(len=*), parameter :: Xonly = 'Xonly'
174      character(len=*), parameter :: Yonly = 'Yonly'
175      character(len=*), parameter :: XandY = 'XandY'
176
177      character(len=*), parameter :: myname = 'MCT::m_SparseMatrixPlus'
178
179 contains
180
181!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182!    Math and Computer Science Division, Argonne National Laboratory   !
183!BOP -------------------------------------------------------------------
184!
185! !IROUTINE: initFromRoot_ - Creation and Initializtion from the Root
186!
187! !DESCRIPTION: 
188! This routine creates an {\tt SparseMatrixPlus} {\tt sMatPlus} using
189! the following elements:
190! \begin{itemize}
191! \item A {\tt SparseMatrix} (the input argument {\tt sMat}), whose
192! elements all reside only on the {\tt root} process of the MPI
193! communicator with an integer handle defined by the input {\tt INTEGER}
194! argument {\tt comm};
195! \item A {\tt GlobalSegMap} (the input argument {\tt xGSMap}) describing
196! the domain decomposition of the vector {\bf x} on the communicator
197! {\tt comm};
198! \item A {\tt GlobalSegMap} (the input argument {\tt yGSMap}) describing
199! the domain decomposition of the vector {\bf y} on the communicator
200! {\tt comm};
201! \item The matrix-vector multiplication parallelization strategy.  This
202! is set by the input {\tt CHARACTER} argument {\tt strategy}, which must
203! have value corresponding to one of the following public data members
204! defined in the declaration section of this module.  Acceptable values
205! for use in this routine are: {\tt Xonly} and {\tt Yonly}.
206! \end{itemize}
207! The optional argument {\tt Tag} can be used to set the tag value used in
208! the call to {\tt Rearranger}.  DefaultTag will be used otherwise.
209!
210! !INTERFACE:
211
212 subroutine initFromRoot_(sMatPlus, sMat, xGSMap, yGSMap, strategy, &
213                          root, comm, ComponentID, Tag)
214
215! !USES:
216
217      use m_die
218      use m_stdio
219      use m_mpif90
220
221      use m_String, only : String
222      use m_String, only : String_init => init
223
224      use m_GlobalSegMap, only : GlobalSegMap
225      use m_GlobalSegMap, only : GlobalSegMap_gsize => gsize
226      use m_GlobalSegMap, only : GlobalSegMap_lsize => lsize
227      use m_GlobalSegMap, only : GlobalSegMap_clean => clean
228
229      use m_SparseMatrix, only : SparseMatrix
230      use m_SparseMatrix, only : SparseMatrix_nRows => nRows
231      use m_SparseMatrix, only : SparseMatrix_nCols => nCols
232
233      use m_SparseMatrixComms, only : SparseMatrix_ScatterByRow => ScatterByRow
234      use m_SparseMatrixComms, only : SparseMatrix_ScatterByColumn => &
235                                                                ScatterByColumn
236
237      use m_SparseMatrixToMaps, only : SparseMatrixToXGlobalSegMap
238      use m_SparseMatrixToMaps, only : SparseMatrixToYGlobalSegMap
239
240      use m_GlobalToLocal, only : GlobalToLocalMatrix
241
242      use m_Rearranger, only : Rearranger
243      use m_Rearranger, only : Rearranger_init => init
244
245      implicit none
246
247! !INPUT PARAMETERS:
248
249      type(GlobalSegMap),     intent(in)    :: xGSMap
250      type(GlobalSegMap),     intent(in)    :: yGSMap
251      character(len=*),       intent(in)    :: strategy
252      integer,                intent(in)    :: root
253      integer,                intent(in)    :: comm
254      integer,                intent(in)    :: ComponentID
255      integer,optional,       intent(in)    :: Tag
256
257! !INPUT/OUTPUT PARAMETERS:
258     
259      type(SparseMatrix),     intent(inout) :: sMat
260
261! !OUTPUT PARAMETERS:
262
263      type(SparseMatrixPlus), intent(out)   :: SMatPlus
264
265! !REVISION HISTORY:
266! 30Aug02 - Jay Larson <larson@mcs.anl.gov> - API Specification
267!EOP ___________________________________________________________________
268!
269  character(len=*),parameter :: myname_=myname//'::initFromRoot_'
270
271  type(GlobalSegMap) :: xPrimeGSMap, yPrimeGSMap
272
273  integer :: myID, ierr
274
275       ! Set tag used in Rearranger call
276
277  SMatPlus%Tag = DefaultTag
278  if(present(Tag)) SMatPlus%Tag = Tag
279
280       ! set vector flag
281  SMatPlus%Matrix%vecinit = .FALSE.
282
283       ! Get local process ID number
284
285  call MPI_COMM_RANK(comm, myID, ierr)
286  if(ierr /= 0) then
287     call MP_perr_die(myname_,'MPI_COMM_RANK() failed',ierr)
288  endif
289
290       ! Basic Input Argument Checks:
291
292       ! On the root, where the matrix is stored, do its number of
293       ! rows and columns match the global lengths ofthe vectors y
294       ! and x, respectively?
295
296  if(myID == root) then
297
298     if(GlobalSegMap_gsize(yGSMap) /= SparseMatrix_nRows(sMat)) then
299        write(stderr,'(3a,i8,2a,i8)') myname_, &
300             ':: FATAL--length of vector y different from row count of sMat.', &
301             'Length of y = ',GlobalSegMap_gsize(yGSMap),' Number of rows in ',&
302             'sMat = ',SparseMatrix_nRows(sMat)
303        call die(myname_)
304     endif
305
306     if(GlobalSegMap_gsize(xGSMap) /= SparseMatrix_nCols(sMat)) then
307        write(stderr,'(3a,i8,2a,i8)') myname_, &
308             ':: FATAL--length of vector x different from column count of sMat.', &
309             'Length of x = ',GlobalSegMap_gsize(xGSMap),' Number of columns in ',&
310             'sMat = ',SparseMatrix_nCols(sMat)
311        call die(myname_)
312     endif
313
314  endif ! if(myID == root) then...
315
316       ! Check desired parallelization strategy name for validity. 
317       ! If either of the strategies supported by this routine are
318       ! provided, initialize the appropriate component of sMatPlus.
319
320  select case(strategy)
321  case(Xonly) ! decompose sMat by rows following decomposition of y
322     call String_init(sMatPlus%Strategy, strategy)
323  case(Yonly) ! decompose sMat by columns following decomposition of x
324     call String_init(sMatPlus%Strategy, strategy)
325  case(XandY) ! User has called the wrong routine.  Try initDistributed()
326              ! instead.
327     write(stderr,'(4a)') myname_, &
328          ':: ERROR--Strategy name = ',strategy,' not supported by this routine.'
329  case default ! strategy name not recognized.
330     write(stderr,'(5a)') myname_, &
331          ':: ERROR--Invalid parallelization strategy name = ',strategy,' not ', &
332          'recognized by this module.'
333     call die(myname_)
334  end select
335
336       ! End Argument Sanity Checks.
337
338       ! Based on the parallelization strategy, scatter sMat into
339       ! sMatPlus%Matrix accordingly.
340
341  select case(strategy)
342  case(Xonly)
343       ! Scatter sMat by Row
344     call SparseMatrix_ScatterByRow(yGSMap, sMat, sMatPlus%Matrix, root, &
345                                    comm, ierr)
346       ! Compute GlobalSegMap associated with intermediate vector x'
347     call SparseMatrixToXGlobalSegMap(sMatPlus%Matrix, xPrimeGSMap, &
348                                      root, comm, ComponentID)
349       ! Determine length of x' from xPrimeGSMap:
350     sMatPlus%XPrimeLength = GlobalSegMap_lsize(xPrimeGSMap, comm)
351       ! Create Rearranger to assemble x' from x
352     call Rearranger_init(xGSMap, xPrimeGSMap, comm, sMatPlus%XToXPrime)
353       ! Create local column indices based on xPrimeGSMap
354     call GlobalToLocalMatrix(sMatPlus%Matrix, xPrimeGSMap, 'column', comm)
355       ! Create local row indices based on yGSMap
356     call GlobalToLocalMatrix(sMatPlus%Matrix, yGSMap, 'row', comm)
357       ! Destroy intermediate GlobalSegMap for x'
358     call GlobalSegMap_clean(xPrimeGSMap)
359  case(Yonly)
360       ! Scatter sMat by Column
361     call SparseMatrix_ScatterByColumn(xGSMap, sMat, sMatPlus%Matrix, root, &
362                                       comm, ierr)
363       ! Compute GlobalSegMap associated with intermediate vector y'
364     call SparseMatrixToYGlobalSegMap(sMatPlus%Matrix, yPrimeGSMap, &
365                                      root, comm, ComponentID)
366       ! Determine length of y' from yPrimeGSMap:
367     sMatPlus%YPrimeLength = GlobalSegMap_lsize(yPrimeGSMap, comm)
368       ! Create Rearranger to assemble y from partial sums in y'
369     call Rearranger_init(yPrimeGSMap, yGSMap, comm, sMatPlus%YPrimeToY)
370       ! Create local row indices based on yPrimeGSMap
371     call GlobalToLocalMatrix(sMatPlus%Matrix, yPrimeGSMap, 'row', comm)
372       ! Create local column indices based on xGSMap
373     call GlobalToLocalMatrix(sMatPlus%Matrix, xGSMap, 'column', comm)
374       ! Destroy intermediate GlobalSegMap for y'
375     call GlobalSegMap_clean(yPrimeGSMap)
376  case default ! do nothing
377  end select
378
379 end subroutine initFromRoot_
380
381!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382!    Math and Computer Science Division, Argonne National Laboratory   !
383!BOP -------------------------------------------------------------------
384!
385! !IROUTINE: initDistributed_ - Distributed Creation and Initializtion
386!
387! !DESCRIPTION: 
388! This routine creates an {\tt SparseMatrixPlus} {\tt sMatPlus} using
389! the following elements:
390! \begin{itemize}
391! \item A {\tt SparseMatrix} (the input argument {\tt sMat}), whose
392! elements have previously been destributed across the MPI communicator
393! with an integer handle defined by the input {\tt INTEGER} argument
394! {\tt comm};
395! \item A {\tt GlobalSegMap} (the input argument {\tt xGSMap}) describing
396! the domain decomposition of the vector {\bf x} on the communicator
397! {\tt comm}; and
398! \item A {\tt GlobalSegMap} (the input argument {\tt yGSMap}) describing
399! the domain decomposition of the vector {\bf y} on the communicator
400! {\tt comm};
401! \end{itemize}
402! The other input arguments required by this routine are the {\tt INTEGER}
403! arguments {\tt root} and {\tt ComponentID}, which define the communicator
404! root ID and MCT component ID, respectively.
405!
406! !INTERFACE:
407
408 subroutine initDistributed_(sMatPlus, sMat, xGSMap, yGSMap, root, comm, &
409                             ComponentID, Tag)
410
411! !USES:
412
413      use m_die
414      use m_stdio
415      use m_mpif90
416
417      use m_String, only : String
418      use m_String, only : String_init => init
419
420      use m_GlobalSegMap, only : GlobalSegMap
421      use m_GlobalSegMap, only : GlobalSegMap_gsize => gsize
422      use m_GlobalSegMap, only : GlobalSegMap_lsize => lsize
423      use m_GlobalSegMap, only : GlobalSegMap_clean => clean
424
425      use m_SparseMatrix, only : SparseMatrix
426      use m_SparseMatrix, only : SparseMatrix_nRows => nRows
427      use m_SparseMatrix, only : SparseMatrix_nCols => nCols
428      use m_SparseMatrix, only : SparseMatrix_Copy => Copy
429
430      use m_SparseMatrixComms, only : SparseMatrix_ScatterByRow => ScatterByRow
431      use m_SparseMatrixComms, only : SparseMatrix_ScatterByColumn => &
432                                                                ScatterByColumn
433
434      use m_SparseMatrixToMaps, only : SparseMatrixToXGlobalSegMap
435      use m_SparseMatrixToMaps, only : SparseMatrixToYGlobalSegMap
436
437      use m_GlobalToLocal, only : GlobalToLocalMatrix
438
439      use m_Rearranger, only : Rearranger
440      use m_Rearranger, only : Rearranger_init => init
441
442      implicit none
443
444! !INPUT PARAMETERS:
445
446      type(GlobalSegMap),     intent(in)    :: xGSMap
447      type(GlobalSegMap),     intent(in)    :: yGSMap
448      integer,                intent(in)    :: root
449      integer,                intent(in)    :: comm
450      integer,                intent(in)    :: ComponentID
451      integer,optional,       intent(in)    :: Tag
452
453! !INPUT/OUTPUT PARAMETERS:
454     
455      type(SparseMatrix),     intent(inout) :: sMat
456
457! !OUTPUT PARAMETERS:
458
459      type(SparseMatrixPlus), intent(out)   :: SMatPlus
460
461! !REVISION HISTORY:
462! 30Aug02 - Jay Larson <larson@mcs.anl.gov> - API Specification
463!EOP ___________________________________________________________________
464!
465  character(len=*),parameter :: myname_=myname//'::initDistributed_'
466
467  type(GlobalSegMap) :: xPrimeGSMap, yPrimeGSMap
468
469  integer :: myID, ierr
470
471       ! Set tag used in Rearranger call
472
473  SMatPlus%Tag = DefaultTag
474  if(present(Tag)) SMatPlus%Tag = Tag
475
476       ! Get local process ID number
477
478  call MPI_COMM_RANK(comm, myID, ierr)
479  if(ierr /= 0) then
480     call MP_perr_die(myname_,'MPI_COMM_RANK() failed',ierr)
481  endif
482       ! Basic Input Argument Checks:
483
484       ! A portion of sMat (even if there are no nonzero elements in
485       ! this local chunk) on each PE.  We must check to ensure the
486       ! number rows and columns match the global lengths ofthe
487       ! vectors y and x, respectively.
488
489  if(GlobalSegMap_gsize(yGSMap) /= SparseMatrix_nRows(sMat)) then
490     write(stderr,'(3a,i8,2a,i8)') myname, &
491          ':: FATAL--length of vector y different from row count of sMat.', &
492          'Length of y = ',GlobalSegMap_gsize(yGSMap),' Number of rows in ',&
493          'sMat = ',SparseMatrix_nRows(sMat)
494     call die(myname_)
495  endif
496
497  if(GlobalSegMap_gsize(xGSMap) /= SparseMatrix_nCols(sMat)) then
498     write(stderr,'(3a,i8,2a,i8)') myname, &
499          ':: FATAL--length of vector x different from column count of sMat.', &
500          'Length of x = ',GlobalSegMap_gsize(xGSMap),' Number of columns in ',&
501          'sMat = ',SparseMatrix_nCols(sMat)
502     call die(myname_)
503  endif
504
505       ! End Argument Sanity Checks.
506
507       ! Set parallelization strategy to XandY, since the work distribution
508       ! was previously determined and in principle can be *anything*
509
510  call String_init(sMatPlus%Strategy, XandY)
511
512       ! Based on the XandY parallelization strategy, build SMatPlus
513       ! First, copy Internals of sMat into sMatPlus%Matrix:
514  call SparseMatrix_Copy(sMat, sMatPlus%Matrix)
515       ! Compute GlobalSegMap associated with intermediate vector x'
516  call SparseMatrixToXGlobalSegMap(sMatPlus%Matrix, xPrimeGSMap, &
517                                   root, comm, ComponentID)
518       ! Determine length of x' from xPrimeGSMap:
519  sMatPlus%XPrimeLength = GlobalSegMap_lsize(xPrimeGSMap, comm)
520       ! Create Rearranger to assemble x' from x
521  call Rearranger_init(xGSMap, xPrimeGSMap, comm, sMatPlus%XToXPrime)
522       ! Create local column indices based on xPrimeGSMap
523  call GlobalToLocalMatrix(sMatPlus%Matrix, xPrimeGSMap, 'column', comm)
524       ! Destroy intermediate GlobalSegMap for x'
525  call GlobalSegMap_clean(xPrimeGSMap)
526       ! Compute GlobalSegMap associated with intermediate vector y'
527  call SparseMatrixToYGlobalSegMap(sMatPlus%Matrix, yPrimeGSMap, &
528                                   root, comm, ComponentID)
529       ! Determine length of y' from yPrimeGSMap:
530  sMatPlus%YPrimeLength = GlobalSegMap_lsize(yPrimeGSMap, comm)
531       ! Create Rearranger to assemble y from partial sums in y'
532  call Rearranger_init(yPrimeGSMap, yGSMap, comm, sMatPlus%YPrimeToY)
533       ! Create local row indices based on yPrimeGSMap
534  call GlobalToLocalMatrix(sMatPlus%Matrix, yPrimeGSMap, 'row', comm)
535       ! Destroy intermediate GlobalSegMap for y'
536  call GlobalSegMap_clean(yPrimeGSMap)
537
538 end subroutine initDistributed_
539
540!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
541!    Math and Computer Science Division, Argonne National Laboratory   !
542!BOP -------------------------------------------------------------------
543!
544! !IROUTINE: vecinit_ - Initialize vector parts of a SparseMatrixPlus
545!
546! !DESCRIPTION: 
547! This routine will initialize the parts of the SparseMatrix in
548! the SparseMatrixPlus object that are used in the vector-friendly
549! version of the sparse matrix multiply.
550!
551! !INTERFACE:
552
553 subroutine vecinit_(SMatP)
554!
555! !USES:
556!
557      use m_die
558      use m_SparseMatrix, only : SparseMatrix_vecinit => vecinit
559
560      implicit none
561
562! !INPUT/OUTPUT PARAMETERS:
563
564      type(SparseMatrixPlus), intent(inout)  :: SMatP
565
566! !REVISION HISTORY:
567! 29Oct03 - R. Jacob <jacob@mcs.anl.gov> - initial prototype
568!EOP ___________________________________________________________________
569!
570  character(len=*),parameter :: myname_=myname//'::vecinit_'
571
572  call SparseMatrix_vecinit(SMatP%Matrix)
573
574 end subroutine vecinit_
575
576!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
577!    Math and Computer Science Division, Argonne National Laboratory   !
578!BOP -------------------------------------------------------------------
579!
580! !IROUTINE: clean_ - Destruction of a SparseMatrixPlus Object
581!
582! !DESCRIPTION: 
583! This routine deallocates all allocated memory belonging to the
584! input/output {\tt SparseMatrixPlus} argument {\tt SMatP}, and sets
585! to zero its integer components describing intermediate vector length,
586! and sets its {\tt LOGICAL} flag signifying initialization to
587! {\tt .FALSE.}  The success (failure) of this operation is signified
588! by the zero (non-zero) value of the optional {\tt INTEGER} output
589! argument {\tt status}.  If the user does supply {\tt status} when
590! invoking this routine, failure of {\tt clean\_()} will lead to
591! termination of execution with an error message.
592!
593! !INTERFACE:
594
595 subroutine clean_(SMatP, status)
596
597! !USES:
598
599      use m_die
600      use m_stdio
601
602      use m_String, only : String
603      use m_String, only : String_init => init
604      use m_String, only : String_ToChar => toChar
605      use m_String, only : String_clean => clean
606
607      use m_SparseMatrix, only : SparseMatrix
608      use m_SparseMatrix, only : SparseMatrix_clean => clean
609
610      use m_Rearranger, only : Rearranger
611      use m_Rearranger, only : Rearranger_clean => clean
612
613      implicit none
614
615! !INPUT/OUTPUT PARAMETERS:
616
617      type(SparseMatrixPlus), intent(inout)  :: SMatP
618
619! !OUTPUT PARAMETERS:
620
621      integer, optional,  intent(out)   :: status
622
623! !REVISION HISTORY:
624! 30Aug02 - Jay Larson <larson@mcs.anl.gov> - API Specification
625!EOP ___________________________________________________________________
626!
627  character(len=*),parameter :: myname_=myname//'::clean_'
628
629  integer :: myStatus
630  type(String) :: dummyStrategy ! SGI IR->WHIRL work-around
631  character(len=5) :: myStrategy
632
633       ! If status was supplied, set it to zero (success)
634
635  if(present(status)) status = 0
636
637       ! The following string copy is superfluous. It is placed here
638       ! to outwit a compiler bug in the SGI and SunOS compilers.
639       ! It occurs when a component of a derived type is used as an
640       ! argument to String_ToChar. This bug crashes the compiler
641       ! with the error message:
642       ! Error: Signal Segmentation fault in phase IR->WHIRL Conversion
643
644  call String_init(dummyStrategy, SMatP%Strategy)
645  myStrategy = String_ToChar(dummyStrategy)
646
647       ! Use SMatP%Strategy to determine which Rearranger(s) need
648       ! to be destroyed.  The CHARACTER parameters Xonly, Yonly,
649       ! and XandY are inherited from the declaration section of
650       ! this module.
651
652
653  select case(myStrategy)
654  case(Xonly) ! destroy X-rearranger only
655
656     call Rearranger_clean(SMatP%XToXprime, myStatus)
657     if(myStatus /= 0) then ! something went wrong
658        if(present(status)) then
659           status = myStatus
660           return
661        else
662           write(stderr,'(3a,i8)') myname_, &
663             ':: ERROR - call to Rearranger_clean(SMatP%XToXprime) failed.', &
664             ' stat = ',myStatus
665        endif
666     endif
667
668  case(Yonly) ! destroy Y-rearranger only
669
670     call Rearranger_clean(SMatP%YprimeToY, myStatus)
671     if(myStatus /= 0) then ! something went wrong
672        if(present(status)) then
673           status = myStatus
674           return
675        else
676           write(stderr,'(3a,i8)') myname_, &
677             ':: ERROR - call to Rearranger_clean(SMatP%YPrimeToY) failed.', &
678             ' stat = ',myStatus
679        endif
680     endif
681
682  case(XandY) ! destroy both X- and Y-rearrangers
683
684     call Rearranger_clean(SMatP%XToXprime, myStatus)
685     if(myStatus /= 0) then ! something went wrong
686        if(present(status)) then
687           status = myStatus
688           return
689        else
690           write(stderr,'(3a,i8)') myname_, &
691             ':: ERROR - call to Rearranger_clean(SMatP%XToXprime) failed.', &
692             ' stat = ',myStatus
693        endif
694     endif
695
696     call Rearranger_clean(SMatP%YprimeToY, myStatus)
697     if(myStatus /= 0) then ! something went wrong
698        if(present(status)) then
699           status = myStatus
700           return
701        else
702           write(stderr,'(3a,i8)') myname_, &
703             ':: ERROR - call to Rearranger_clean(SMatP%YPrimeToY) failed.', &
704             ' stat = ',myStatus
705        endif
706     endif
707
708  case default ! do nothing--corresponds to purely data local case
709  end select
710
711       ! Zero out XPrimeLength and YPrimeLength
712
713  SMatP%XPrimeLength = 0
714  SMatP%YPrimeLength = 0
715
716       ! Destroy the SparseMatrix component SMatP%Matrix
717
718  call SparseMatrix_clean(SMatP%Matrix, myStatus)
719  if(myStatus /= 0) then ! something went wrong
720     if(present(status)) then
721        status = myStatus
722        return
723     else
724        write(stderr,'(2a,i8)') myname_, &
725          ':: ERROR - call to SparseMatrix_clean() failed with stat=',myStatus
726     endif
727  endif
728
729       ! Destroy the String SMatP%Strategy and its copy
730
731  call String_clean(SMatP%Strategy)
732  call String_clean(dummyStrategy)
733
734 end subroutine clean_
735
736!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
737!    Math and Computer Science Division, Argonne National Laboratory   !
738!BOP -------------------------------------------------------------------
739!
740! !IROUTINE: initialized_ - Confirmation of Initialization
741!
742! !DESCRIPTION:
743! This {\tt LOGICAL} query function tells the user if the input
744! {\tt SparseMatrixPlus} argument {\tt sMatPlus} has been initialized.
745! The return value of {\tt initialized\_} is {\tt .TRUE.} if
746! {\tt sMatPlus} has been previously initialized, {\tt .FALSE.} if it
747! has not.
748!
749! !INTERFACE:
750
751 logical function initialized_(sMatPlus)
752!
753! !USES:
754!
755! No external modules are used by this function.
756     
757      use m_String, only : String_len
758      use m_List,   only : List
759      use m_List,   only : List_init => init
760      use m_List,   only : List_identical => identical
761      use m_List,   only : List_clean => clean
762
763      use m_die
764
765      implicit none
766
767! !INPUT PARAMETERS:
768!
769      type(SparseMatrixPlus), intent(in)  :: sMatPlus
770
771! !REVISION HISTORY:
772! 26Sep02 - Jay Larson <larson@mcs.anl.gov> - Implementation
773!EOP ___________________________________________________________________
774!
775 character(len=*),parameter :: myname_=myname//'::initialized_'
776
777 integer :: XonlyLen, YonlyLen, XandYLen
778 type(List) :: XonlyList, YonlyList, XandYList, stratList
779
780  initialized_ = .FALSE.
781 
782  XonlyLen = len(trim(Xonly))
783  YonlyLen = len(trim(Yonly))
784  XandYLen = len(trim(XandY))
785 
786  if( (XonlyLen /= YonlyLen) .or. (XonlyLen /= XandYLen) ) then
787     call die(myname_,"The length of the strategies are unequal. &
788          &This routine needs to be rewritten.")
789  endif
790
791  if(associated(sMatPlus%strategy%c)) then
792     if(String_len(sMatPlus%strategy) == XonlyLen) then
793        call List_init(XonlyList,Xonly)
794        call List_init(YonlyList,Yonly)
795        call List_init(XandYList,XandY)
796        call List_init(stratList,sMatPlus%strategy)
797        if(List_identical(stratList,XonlyList)) initialized_ = .TRUE.
798        if(List_identical(stratList,YonlyList)) initialized_ = .TRUE.
799        if(List_identical(stratList,XandYList)) initialized_ = .TRUE.
800        call List_clean(XonlyList)
801        call List_clean(YonlyList)
802        call List_clean(XandYList)
803        call List_clean(stratList)
804     endif
805  endif
806
807 end function initialized_
808
809!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
810!    Math and Computer Science Division, Argonne National Laboratory   !
811!BOP -------------------------------------------------------------------
812!
813! !IROUTINE: exportStrategyToChar - Return Parallelization Strategy
814!
815! !DESCRIPTION:
816! This query subroutine returns the parallelization  strategy set in
817! the input {\tt SparseMatrixPlus} argument {\tt sMatPlus}.  The result
818! is returned in the output {\tt CHARACTER} argument {\tt StratChars}.
819!
820! !INTERFACE:
821
822 function exportStrategyToChar_(sMatPlus)
823!
824! !USES:
825!
826   use m_stdio
827   use m_die
828
829   use m_String, only : String_ToChar => toChar
830   use m_String, only : String_init => init
831   use m_String, only : String_clean => clean
832   use m_String, only : String
833
834   implicit none
835
836! !INPUT PARAMETERS:
837!
838      type(SparseMatrixPlus), intent(in)  :: sMatPlus
839
840! !OUTPUT PARAMETERS:
841!
842      character(len=size(sMatPlus%Strategy%c)) :: exportStrategyToChar_
843
844! !REVISION HISTORY:
845! 01Aug07 - Jay Larson <larson@mcs.anl.gov> - Implementation
846!EOP ___________________________________________________________________
847!
848 character(len=*),parameter :: myname_=myname//'::exportStrategyToChar_'
849 type(String) :: dummyStrategy ! SGI IR->WHIRL work-around
850
851   ! Check input argument to ensure it has been initialized.  If not,
852   ! signal an error and terminate execution.
853
854  if( .not. initialized_(sMatPlus) ) then
855     write(stderr,'(3a)') myname_,':: Warning, input argument not initialized, ', &
856          'returning empty character field for parallelization strategy.'
857     exportStrategyToChar_ = ' '
858     return
859  endif
860
861   ! Return in character form the parallelizaiton strategy
862  call String_init(dummyStrategy, SMatPlus%Strategy)
863
864  exportStrategyToChar_ = String_ToChar(dummyStrategy) 
865
866  call String_clean(dummyStrategy)
867
868 end function exportStrategyToChar_
869
870 end module m_SparseMatrixPlus
871
Note: See TracBrowser for help on using the repository browser.