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

Last change on this file since 4775 was 4775, checked in by aclsce, 5 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: 21.2 KB
Line 
1!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2!    Math and Computer Science Division, Argonne National Laboratory   !
3!-----------------------------------------------------------------------
4! CVS m_SparseMatrixComms.F90,v 1.16 2004-05-18 00:07:49 jacob Exp
5! CVS MCT_2_8_0
6!BOP -------------------------------------------------------------------
7!
8! !MODULE: m_SparseMatrixComms -- sparse matrix communications methods.
9!
10! !DESCRIPTION:
11! The {\tt SparseMatrix} datatype provides sparse matrix storage for
12! the parallel matrix-vector multiplication ${\bf y} = {\bf M} {\bf x}$.
13! This module provides communications services for the {\tt SparseMatrix}
14! type.  These services include scattering matrix elements based on row or
15! column decompositions, gathering of matrix elements to the root, and
16! broadcasting from the root.
17!
18! {\bf N.B.:}  These routines will not communicate the vector portion
19! of a {\tt SparseMatrix}, if it has been initialized.  A WARNING will
20! be issued in most cases.  In general, do communication first,  then
21! call {\tt vecinit}.
22!
23! !INTERFACE:
24
25 module m_SparseMatrixComms
26
27      private   ! except
28
29! !PUBLIC MEMBER FUNCTIONS:
30!
31      public :: ScatterByColumn
32      public :: ScatterByRow
33      public :: Gather
34      public :: Bcast
35
36    interface ScatterByColumn ; module procedure &
37         ScatterByColumnGSMap_
38    end interface
39
40    interface ScatterByRow ; module procedure &
41         ScatterByRowGSMap_
42    end interface
43
44    interface Gather ; module procedure &
45         GM_gather_, &
46         GSM_gather_
47    end interface
48
49    interface Bcast ; module procedure Bcast_ ; end interface
50
51! !REVISION HISTORY:
52! 13Apr01 - J.W. Larson <larson@mcs.anl.gov> - initial prototype
53!           and API specifications.
54! 10May01 - J.W. Larson <larson@mcs.anl.gov> - added GM_gather_
55!           and cleaned up prologues.
56!EOP ___________________________________________________________________
57
58  character(len=*),parameter :: myname='MCT::m_SparseMatrixComms'
59
60 contains
61
62!-------------------------------------------------------------------------
63!     Math + Computer Science Division / Argonne National Laboratory     !
64!-------------------------------------------------------------------------
65!BOP
66!
67! !IROUTINE:  ScatterByColumnGSMap_ - Column-based scatter for SparseMatrix.
68!
69! !DESCRIPTION: This routine scatters the input {\tt SparseMatrix}
70! argument {\tt GsMat} (valid only on the root) to a distributed
71! {\tt SparseMatrix} variable {\tt LsMat} across all the processes
72! present on the communicator associated with the integer handle
73! {\tt comm}.  The decomposition defining the scatter is supplied by the
74! input {\tt GlobalSegMap} argument {\tt columnGSMap}.  The optional
75! output {\tt INTEGER} flag {\tt stat} signifies a successful (failed)
76! operation if it is returned with value zero (nonzero).
77!
78! {\bf N.B.:}  This routine returns an allocated {\tt SparseMatrix}
79! variable {\tt LsMat}.  The user must destroy this variable when it
80! is no longer needed by invoking {\tt SparseMatrix\_Clean()}.
81!
82! !INTERFACE:
83
84 subroutine ScatterByColumnGSMap_(columnGSMap, GsMat, LsMat, root, comm, stat)
85!
86! !USES:
87!
88
89   use m_die, only : MP_perr_die,die
90   use m_stdio
91   use m_mpif90
92
93   use m_List, only: List
94   use m_List, only: List_init => init
95   use m_List, only: List_clean => clean
96
97   use m_GlobalSegMap, only : GlobalSegMap
98   use m_GlobalSegMap, only : GlobalSegMap_clean => clean
99
100   use m_SparseMatrix, only : SparseMatrix
101   use m_SparseMatrix, only : SparseMatrix_nRows => nRows
102   use m_SparseMatrix, only : SparseMatrix_nCols => nCols
103   use m_SparseMatrix, only : SparseMatrix_SortPermute => SortPermute
104
105   use m_SparseMatrixDecomp, only : SparseMatrixDecompByColumn => ByColumn
106
107   use m_AttrVectComms, only : AttrVect_Scatter => scatter
108
109   implicit none
110
111! !INPUT PARAMETERS:
112!
113   type(GlobalSegMap), intent(in)    :: columnGSMap
114   integer,            intent(in)    :: root
115   integer,            intent(in)    :: comm
116
117! !INPUT/OUTPUT PARAMETERS:
118!
119   type(SparseMatrix), intent(inout) :: GsMat
120
121! !OUTPUT PARAMETERS:
122!
123   type(SparseMatrix), intent(out) :: LsMat
124   integer, optional,  intent(out) :: stat
125
126! !REVISION HISTORY:
127!
128! 13Apr01 - J.W. Larson <larson@mcs.anl.gov> - initial API spec.
129! 10May01 - J.W. Larson <larson@mcs.anl.gov> - cleaned up prologue.
130! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Made status flag stat
131!           optional, and ititilaze it to zero if it is present.
132! 09Jul03 - E.T. Ong <eong@mcs.anl.gov> - added sorting to distributed
133!           matrix elements
134!EOP
135!-------------------------------------------------------------------------
136
137  character(len=*),parameter :: myname_=myname//'ScatterByColumnGSMap_'
138! GlobalSegMap used to create column decomposition of GsMat
139  type(GlobalSegMap) :: MatGSMap
140! Storage for the number of rows and columns in the SparseMatrix
141  integer :: NumRowsColumns(2)
142! List storage for sorting keys
143  type(List) :: sort_keys
144! Process ID
145  integer :: myID
146! Error flag
147  integer :: ierr
148
149       ! Initialize stat if present
150
151  if(present(stat)) stat = 0
152
153       ! Which process am I?
154
155  call MPI_COMM_RANK(comm, myID, ierr)
156  if(ierr /= 0) then
157        call MP_perr_die(myname_,"MPI_COMM_RANK() failed",ierr)
158  endif
159
160       ! can't scatter vector parts.
161  if((myID.eq.root) .and. GsMat%vecinit) then
162      write(stderr,*) myname_,&
163      "WARNING: will not scatter vector parts of GsMat"
164  endif
165
166       ! Create from columnGSMap the corresponding GlobalSegMap
167       ! that will decompose GsMat by column the same way.
168
169  call SparseMatrixDecompByColumn(columnGSMap, GsMat, MatGSMap, root, comm)
170
171       ! Broadcast the resulting GlobalSegMap across the communicator
172
173       ! Scatter the matrix element data GsMat%data accordingly
174
175  call AttrVect_Scatter(GsMat%data, LsMat%data, MatGSMap, root, comm, ierr)
176
177  if(ierr /= 0) then
178     if(present(stat)) then
179        write(stderr,*) myname_,"::  AttrVect_Scatter(GsMat%data) failed--stat=", &
180             ierr
181        stat = ierr
182        return
183     else
184        call die(myname_,"call AttrVect_Scatter(GsMat%data,..",ierr)
185     endif
186  endif
187
188       ! Now, distribute to all the processes the number of Rows and
189       ! columns in GsMat (which are valid on the root only at this point)
190
191  if(myID == root) then
192     NumRowsColumns(1) = SparseMatrix_nRows(GsMat)
193     NumRowsColumns(2) = SparseMatrix_nCols(GsMat)
194  endif
195
196  call MPI_Bcast(NumRowsColumns, 2, MP_INTEGER, root, comm, ierr)
197
198  if(ierr /= 0) then
199        call MP_perr_die(myname_,"MPI_Bcast(NumRowsColumns...",ierr)
200  endif
201
202       ! Unpack NumRowsColumns
203
204  LsMat%nrows = NumRowsColumns(1)
205  LsMat%ncols = NumRowsColumns(2)
206
207       ! Set the value of vecinit
208  LsMat%vecinit = .FALSE.
209
210       ! Finally, lets sort the distributed local matrix elements
211
212       ! Sort the matrix entries in sMat by column, then row. 
213       ! First, create the key list...
214
215  call List_init(sort_keys,'gcol:grow')
216
217       ! Now perform the sort/permute...
218  call SparseMatrix_SortPermute(LsMat, sort_keys)
219
220       ! Cleanup
221
222  call List_clean(sort_keys) 
223  call GlobalSegMap_clean(MatGSMap)
224
225 end subroutine ScatterByColumnGSMap_
226
227!-------------------------------------------------------------------------
228!     Math + Computer Science Division / Argonne National Laboratory     !
229!-------------------------------------------------------------------------
230!BOP
231!
232! !IROUTINE:  ScatterByRowGSMap_ -Row-based scatter for SparseMatrix.
233!
234! !DESCRIPTION: This routine scatters the input  {\tt SparseMatrix}
235! argument {\tt GsMat} (valid only on the root) to a distributed
236! {\tt SparseMatrix} variable {\tt LsMat} across all the processes
237! present on the communicator associated with the integer handle
238! {\tt comm}.  The decomposition defining the scatter is supplied by the
239! input {\tt GlobalSegMap} argument {\tt rowGSMap}.  The output integer
240! flag {\tt stat} signifies a successful (failed) operation if it is
241! returned with value zero (nonzero).
242!
243! {\bf N.B.:}  This routine returns an allocated {\tt SparseMatrix}
244! variable {\tt LsMat}.  The user must destroy this variable when it
245! is no longer needed by invoking {\tt SparseMatrix\_Clean()}.
246!
247! !INTERFACE:
248
249 subroutine ScatterByRowGSMap_(rowGSMap, GsMat, LsMat, root, comm, stat)
250!
251! !USES:
252!
253   use m_die, only : MP_perr_die,die
254   use m_stdio
255   use m_mpif90
256
257   use m_List, only: List
258   use m_List, only: List_init => init
259   use m_List, only: List_clean => clean
260
261   use m_GlobalSegMap, only : GlobalSegMap
262   use m_GlobalSegMap, only : GlobalSegMap_clean => clean
263
264   use m_SparseMatrix, only : SparseMatrix
265   use m_SparseMatrix, only : SparseMatrix_nRows => nRows
266   use m_SparseMatrix, only : SparseMatrix_nCols => nCols
267   use m_SparseMatrix, only : SparseMatrix_SortPermute => SortPermute
268
269   use m_SparseMatrixDecomp, only : SparseMatrixDecompByRow => ByRow
270
271   use m_AttrVectComms, only : AttrVect_Scatter => scatter
272
273   implicit none
274
275! !INPUT PARAMETERS:
276!
277   type(GlobalSegMap), intent(in)    :: rowGSMap
278   integer,            intent(in)    :: root
279   integer,            intent(in)    :: comm
280
281! !INPUT/OUTPUT PARAMETERS:
282!
283   type(SparseMatrix), intent(inout) :: GsMat
284
285! !OUTPUT PARAMETERS:
286!
287   type(SparseMatrix), intent(out) :: LsMat
288   integer, optional,  intent(out) :: stat
289
290! !REVISION HISTORY:
291!
292! 13Apr01 - J.W. Larson <larson@mcs.anl.gov> - initial API spec.
293! 26Apr01 - R.L. Jacob  <jacob@mcs.anl.gov> - fix use statement
294!           from SMDecomp so it points to ByRow
295! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Made status flag stat
296!           optional, and initialize it to zero if it is present.
297! 09Jul03 - E.T. Ong <eong@mcs.anl.gov> - Added sorting to distributed
298!           matrix elements.
299!EOP
300!-------------------------------------------------------------------------
301
302  character(len=*),parameter :: myname_=myname//'ScatterByRowGSMap_'
303! GlobalSegMap used to create row decomposition of GsMat
304  type(GlobalSegMap) :: MatGSMap
305! Storage for the number of rows and columns in the SparseMatrix
306  integer :: NumRowsColumns(2)
307! List storage for sorting keys
308  type(List) :: sort_keys
309! Process ID
310  integer :: myID
311! Error flag
312  integer :: ierr
313
314       ! Initialize stat to zero (if present)
315
316  if(present(stat)) stat = 0
317
318       ! Which process are we?
319
320  call MPI_COMM_RANK(comm, myID, ierr)
321  if(ierr /= 0) then
322     call MP_perr_die(myname_,"MPI_COMM_RANK() failed",ierr)
323  endif
324
325       ! can't scatter vector parts.
326  if((myID.eq.root) .and. GsMat%vecinit) then
327      write(stderr,*) myname_,&
328      "WARNING: will not scatter vector parts of GsMat."
329  endif
330
331       ! Create from rowGSMap the corresponding GlobalSegMap
332       ! that will decompose GsMat by row the same way.
333
334  call SparseMatrixDecompByRow(rowGSMap, GsMat, MatGSMap, root, comm)
335
336       ! Scatter the matrix element data GsMat%data accordingly
337
338  call AttrVect_Scatter(GsMat%data, LsMat%data, MatGSMap, root, comm, ierr)
339  if(ierr /= 0) then
340     if(present(stat)) then
341        write(stderr,*) myname_,"::  AttrVect_Scatter(GsMat%data) failed--stat=", &
342             ierr
343        stat = ierr
344        return
345     else
346        call die(myname_,"call AttrVect_Scatter(GsMat%data,..",ierr)
347     endif
348  endif
349
350       ! Now, distribute to all the processes the number of rows and
351       ! columns in GsMat (which are valid on the root only at this point)
352
353  if(myID == root) then
354     NumRowsColumns(1) = SparseMatrix_nRows(GsMat)
355     NumRowsColumns(2) = SparseMatrix_nCols(GsMat)
356  endif
357
358  call MPI_Bcast(NumRowsColumns, 2, MP_INTEGER, root, comm, ierr)
359  if(ierr /= 0) then
360     call MP_perr_die(myname_,"MPI_Bcast(NumRowsColumns...",ierr)
361  endif
362
363       ! Unpack NumRowsColumns
364
365  LsMat%nrows = NumRowsColumns(1)
366  LsMat%ncols = NumRowsColumns(2)
367
368       ! Set the value of vecinit
369  LsMat%vecinit = .FALSE.
370
371       ! Sort the matrix entries in sMat by row, then column. 
372       ! First, create the key list...
373
374  call List_init(sort_keys,'grow:gcol')
375
376       ! Now perform the sort/permute...
377  call SparseMatrix_SortPermute(LsMat, sort_keys)
378
379       ! Cleanup
380
381  call List_clean(sort_keys) 
382  call GlobalSegMap_clean(MatGSMap)
383
384 end subroutine ScatterByRowGSMap_
385
386!-------------------------------------------------------------------------
387!     Math + Computer Science Division / Argonne National Laboratory     !
388!-------------------------------------------------------------------------
389!BOP
390!
391! !IROUTINE:  GM_gather_ - Gather a distributed SparseMatrix to the root.
392!
393! !DESCRIPTION: This routine gathers the input distributed
394! {\tt SparseMatrix} argument {\tt LsMat} to the {\tt SparseMatrix}
395! variable {\tt GsMat} on the root.  The decomposition defining the gather
396! is supplied by the input {\tt GlobalMap} argument {\tt GMap}.  The
397! status flag {\tt stat} has value zero (nonzero) if the operation has
398! succeeded (failed).
399!
400! {\bf N.B.:}  This routine returns an allocated {\tt SparseMatrix}
401! variable {\tt GsMat}.  The user must destroy this variable when it
402! is no longer needed by invoking {\tt SparseMatrix\_Clean()}.
403!
404! !INTERFACE:
405
406 subroutine GM_gather_(LsMat, GsMat, GMap, root, comm, stat)
407!
408! !USES:
409!
410   use m_stdio
411   use m_die, only : die
412
413   use m_GlobalMap, only: GlobalMap
414
415   use m_SparseMatrix, only: SparseMatrix
416   use m_SparseMatrix, only: SparseMatrix_nRows => nRows
417   use m_SparseMatrix, only: SparseMatrix_nCols => nCols
418
419   use m_AttrVectComms, only : AttrVect_gather => gather
420
421   implicit none
422
423! !INPUT PARAMETERS:
424!
425   type(SparseMatrix), intent(in) :: LsMat
426   type(GlobalMap),    intent(in) :: GMap
427   integer,            intent(in) :: root
428   integer,            intent(in) :: comm
429
430! !OUTPUT PARAMETERS:
431!
432   type(SparseMatrix), intent(out) :: GsMat
433   integer, optional,  intent(out) :: stat
434
435! !REVISION HISTORY:
436!
437! 13Apr01 - J.W. Larson <larson@mcs.anl.gov> - initial API spec.
438! 10May01 - J.W. Larson <larson@mcs.anl.gov> - initial routine and
439!           prologue
440! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Made status flag stat
441!           optional, and ititilaze it to zero if it is present.
442!EOP
443!-------------------------------------------------------------------------
444
445  character(len=*),parameter :: myname_=myname//'GM_gather_'
446  integer :: ierr
447
448       ! if stat is present, initialize its value to zero (success)
449
450  if(present(stat))  stat = 0
451
452  if(LsMat%vecinit) then
453      write(stderr,*) myname_,&
454      "WARNING: will not gather vector parts of LsMat."
455  endif
456
457  call AttrVect_gather(LsMat%data, GsMat%data, GMap, root, comm, ierr)
458  if(ierr /= 0) then
459     if(present(stat)) then
460        write(stderr,*) myname_,"::  AttrVect_Gather(LsMat%data...) failed--stat=", &
461             ierr
462        stat = ierr
463        return
464     else
465        call die(myname_,"call AttrVect_Scatter(LsMat%data...) failed",ierr)
466     endif
467  endif
468
469       ! For now, the GsMat inherits the number of rows and columns from
470       ! the corresponding values of LsMat on the root (this should be
471       ! checked in future versions).
472
473  GsMat%nrows = SparseMatrix_nRows(LsMat)
474  GsMat%ncols = SparseMatrix_nCols(LsMat)
475
476  GsMat%vecinit = .FALSE.
477
478 end subroutine GM_gather_
479
480!-------------------------------------------------------------------------
481!     Math + Computer Science Division / Argonne National Laboratory     !
482!-------------------------------------------------------------------------
483!BOP
484!
485! !IROUTINE:  GSM_gather_ - Gather a distributed SparseMatrix to the root.
486!
487! !DESCRIPTION: This routine gathers the input distributed
488! {\tt SparseMatrix} argument {\tt LsMat} to the {\tt SparseMatrix}
489! variable {\tt GsMat} on the root.  The decomposition defining the gather
490! is supplied by the input {\tt GlobalSegMap} argument {\tt GSMap}.  The
491! status flag {\tt stat} has value zero (nonzero) if the operation has
492! succeeded (failed).
493!
494! {\bf N.B.:}  This routine returns an allocated {\tt SparseMatrix}
495! variable {\tt GsMat}.  The user must destroy this variable when it
496! is no longer needed by invoking {\tt SparseMatrix\_Clean()}.
497!
498! !INTERFACE:
499
500 subroutine GSM_gather_(LsMat, GsMat, GSMap, root, comm, stat)
501!
502! !USES:
503!
504   use m_stdio
505   use m_die, only : die
506
507   use m_GlobalSegMap, only: GlobalSegMap
508
509   use m_SparseMatrix, only: SparseMatrix
510   use m_SparseMatrix, only: SparseMatrix_nRows => nRows
511   use m_SparseMatrix, only: SparseMatrix_nCols => nCols
512
513   use m_AttrVectComms, only : AttrVect_gather => gather
514
515   implicit none
516
517! !INPUT PARAMETERS:
518!
519   type(SparseMatrix), intent(in) :: LsMat
520   type(GlobalSegMap), intent(in) :: GSMap
521   integer,            intent(in) :: root
522   integer,            intent(in) :: comm
523
524! !OUTPUT PARAMETERS:
525!
526   type(SparseMatrix), intent(out) :: GsMat
527   integer, optional,  intent(out) :: stat
528
529! !REVISION HISTORY:
530!
531! 13Apr01 - J.W. Larson <larson@mcs.anl.gov> - initial API spec.
532! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Made status flag stat
533!           optional, and ititilaze it to zero if it is present.
534!EOP
535!-------------------------------------------------------------------------
536
537  character(len=*),parameter :: myname_=myname//'GSM_gather_'
538  integer :: ierr
539
540       ! if stat is present, initialize its value to zero (success)
541
542  if(present(stat))  stat = 0
543
544  if(LsMat%vecinit) then
545      write(stderr,*) myname_,&
546      "WARNING: will not gather vector parts of LsMat."
547  endif
548
549       ! Gather the AttrVect component of LsMat to GsMat...
550
551  call AttrVect_gather(LsMat%data, GsMat%data, GSMap, root, comm, ierr)
552  if(ierr /= 0) then
553     if(present(stat)) then
554        write(stderr,*) myname_,"::  AttrVect_Gather(LsMat%data...) failed--stat=", &
555             ierr
556        stat = ierr
557        return
558     else
559        call die(myname_,"call AttrVect_Gather(LsMat%data...)",ierr)
560     endif
561  endif
562
563       ! For now, the GsMat inherits the number of rows and columns from
564       ! the corresponding values of LsMat on the root (this should be
565       ! checked in future versions).
566
567  GsMat%nrows = SparseMatrix_nRows(LsMat)
568  GsMat%ncols = SparseMatrix_nCols(LsMat)
569
570  GsMat%vecinit = .FALSE.
571
572 end subroutine GSM_gather_
573
574!-------------------------------------------------------------------------
575!     Math + Computer Science Division / Argonne National Laboratory     !
576!-------------------------------------------------------------------------
577!BOP
578!
579! !IROUTINE:  Bcast_ - Broadcast a SparseMatrix.
580!
581! !DESCRIPTION: This routine broadcasts the {\tt SparseMatrix} argument
582! {\tt sMat} from the root to all processes on the communicator associated
583! with the communicator handle {\tt comm}.  The status flag {\tt stat}
584! has value zero if the operation has succeeded.
585!
586! {\bf N.B.:}  This routine returns an allocated {\tt SparseMatrix}
587! variable {\tt sMat}.  The user must destroy this variable when it
588! is no longer needed by invoking {\tt SparseMatrix\_Clean()}.
589!
590! {\bf N.B.:}  This routine will exit with an error if the vector portion
591! of {\tt sMat} has been initialized prior to broadcast.
592!
593! !INTERFACE:
594
595 subroutine Bcast_(sMat, root, comm, stat)
596
597!
598! !USES:
599!
600
601   use m_die, only : MP_perr_die,die
602   use m_stdio
603   use m_mpif90
604
605   use m_GlobalSegMap, only: GlobalSegMap
606
607   use m_AttrVectComms, only : AttrVect_bcast => bcast
608
609   use m_SparseMatrix, only: SparseMatrix
610   use m_SparseMatrix, only: SparseMatrix_nRows => nRows
611   use m_SparseMatrix, only: SparseMatrix_nCols => nCols
612
613   implicit none
614
615! !INPUT PARAMETERS:
616!
617   integer,            intent(in) :: root
618   integer,            intent(in) :: comm
619
620! !INPUT/OUTPUT PARAMETERS:
621!
622   type(SparseMatrix), intent(inout) :: sMat
623
624! !OUTPUT PARAMETERS:
625!
626   integer, optional,  intent(out) :: stat
627
628! !REVISION HISTORY:
629!
630! 13Apr01 - J.W. Larson <larson@mcs.anl.gov> - initial API spec/code
631! 13Jun01 - J.W. Larson <larson@mcs.anl.gov> - Made status flag stat
632!           optional, and ititilaze it to zero if it is present.
633! 17Jul02 - J.W. Larson <larson@mcs.anl.gov> - Bug fix--local
634!           process ID myID was uninitialized.
635!EOP
636!-------------------------------------------------------------------------
637
638  character(len=*),parameter :: myname_=myname//'Bcast_'
639
640! Storage for the number of rows and columns in the SparseMatrix
641  integer :: NumRowsColumns(2)
642! Process ID number
643  integer :: myID
644! Error flag
645  integer :: ierr
646
647       ! Initialize stat if present
648
649  if(present(stat)) stat = 0
650
651       ! Determine local process ID myID:
652
653  call MPI_COMM_RANK(comm, myID, ierr)
654  if(ierr /= 0) then
655     call MP_perr_die(myname_,"MPI_COMM_RANK() failed",ierr)
656  endif
657
658  if((myID.eq.root) .and. sMat%vecinit) then
659      write(stderr,*) myname_,&
660      "Cannot broadcast SparseMatrix with initialized vector parts." 
661      call die(myname_,"Gather SparseMatrix with vecinit TRUE.") 
662  endif
663
664       ! Broadcast sMat%data from the root
665
666  call AttrVect_bcast(sMat%data, root, comm, ierr)
667  if(ierr /= 0) then
668     if(present(stat)) then
669        write(stderr,*) myname_,"::  AttrVect_bcast(sMat%data...failed--stat=", &
670             ierr
671        stat = ierr
672        return
673     else
674        call die(myname_,"call AttrVect_bcast(sMat%data...) failed",ierr)
675     endif
676  endif
677
678  if(myID == root) then
679     NumRowsColumns(1) = SparseMatrix_nRows(sMat)
680     NumRowsColumns(2) = SparseMatrix_nCols(sMat)
681  endif
682
683  call MPI_Bcast(NumRowsColumns, 2, MP_INTEGER, root, comm, ierr)
684  if(ierr /= 0) then
685     call MP_perr_die(myname_,"MPI_Bcast(NumRowsColumns...",ierr)
686  endif
687
688       ! Unpack NumRowsColumns on broadcast destination processes
689
690  if(myID /= root) then
691     sMat%nrows = NumRowsColumns(1)
692     sMat%ncols = NumRowsColumns(2)
693  endif
694
695  sMat%vecinit = .FALSE.
696
697 end subroutine Bcast_
698
699 end module m_SparseMatrixComms
Note: See TracBrowser for help on using the repository browser.