source: CPL/oasis3-mct/branches/OASIS3-MCT_2.0_branch/lib/mct/mct/m_MatAttrVectMul.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.4 KB
Line 
1!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2!     Math + Computer Science Division / Argonne National Laboratory   !
3!-----------------------------------------------------------------------
4! CVS m_MatAttrVectMul.F90,v 1.30 2008-01-11 22:54:04 jacob Exp
5! CVS MCT_2_8_0
6!BOP -------------------------------------------------------------------
7!
8! !MODULE: m_MatAttrVectMul - Sparse Matrix AttrVect Multipication.
9!
10! !DESCRIPTION:
11!
12! This module contains routines supporting the sparse matrix-vector
13! multiplication
14! $${\bf y} = {\bf M} {\bf x},$$
15! where the vectors {\bf x} and {\bf y} are stored using the MCT
16! {\tt AttrVect} datatype, and {\bf M} is stored using either the MCT
17! {\tt SparseMatrix} or {\tt SparseMatrixPlus} type.  The {\tt SparseMatrix}
18! type is used to represent {\bf M} if the multiplication process is
19! purely data-local (e.g., in a global address space, or if the process
20! has been rendered embarrasingly parallel by earlier or subsequent
21! vector data redistributions).  If the multiplication process is to
22! be explicitly distributed-memory parallel, then the {\tt SparseMatrixPlus}
23! type is used to store the elements of {\bf M} and all information needed
24! to coordinate data redistribution and reduction of partial sums.
25!
26! {\bf N.B.:} The matrix-vector multiplication routines in this module
27! process only the {\bf real} attributes of the {\tt AttrVect} arguments
28! corresponding to {\bf x} and {\bf y}.  They ignore the integer attributes.
29!
30! !INTERFACE:
31
32 module m_MatAttrVectMul
33
34      private   ! except
35
36      public :: sMatAvMult        ! The master Sparse Matrix -
37                                  ! Attribute Vector multipy API
38
39    interface sMatAvMult   ; module procedure &
40        sMatAvMult_DataLocal_, &
41        sMatAvMult_sMPlus_
42    end interface
43
44! !SEE ALSO:
45! The MCT module m_AttrVect for more information about the AttrVect type.
46! The MCT module m_SparseMatrix for more information about the SparseMatrix
47! type.
48! The MCT module m_SparseMatrixPlus for more details about the master class
49! for parallel sparse matrix-vector multiplication, the SparseMatrixPlus.
50
51! !REVISION HISTORY:
52! 12Jan01 - J.W. Larson <larson@mcs.anl.gov> - initial module.
53! 26Sep02 - J.W. Larson <larson@mcs.anl.gov> - added high-level, distributed
54!           matrix-vector multiply routine using the SparseMatrixPlus class.
55!
56!EOP ___________________________________________________________________
57
58  character(len=*),parameter :: myname='MCT::m_MatAttrVectMul'
59
60 contains
61
62!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63!     Math + Computer Science Division / Argonne National Laboratory   !
64!BOP -------------------------------------------------------------------
65!
66! !IROUTINE: sMatAvMult_DataLocal -- Purely local matrix-vector multiply
67!
68! !DESCRIPTION:
69!
70! The sparse matrix-vector multiplication routine {\tt sMatAvMult\_DataLocal\_()}
71! operates on the assumption of total data locality, which is equivalent
72! to the following two conditions:
73! \begin{enumerate}
74! \item The input {\tt AttrVect} {\tt xAV} contains all the values referenced
75! by the local column indices stored in the input {\tt SparsMatrix} argument
76! {\tt sMat}; and
77! \item The output {\tt AttrVect} {\tt yAV} contains all the values referenced
78! by the local row indices stored in the input {\tt SparsMatrix} argument
79! {\tt sMat}.
80! \end{enumerate}
81! By default, the multiplication occurs for each of the common {\tt REAL} attributes
82! shared by {\tt xAV} and {\tt yAV}.  This routine is capable of
83! cross-indexing the attributes and performing the necessary multiplications.
84!
85! If the optional argument {\tt rList} is present, only the attributes listed will
86! be multiplied.  If the attributes have different names in {\tt yAV}, the optional
87! {\tt TrList} argument can be used to provide the translation.
88!
89! If the optional argument {\tt Vector} is present and true, the vector
90! architecture-friendly portions of this routine will be invoked.  It
91! will also cause the vector parts of {\\ sMat} to be initialized if they
92! have not been already.
93!
94! !INTERFACE:
95
96 subroutine sMatAvMult_DataLocal_(xAV, sMat, yAV, Vector, rList, TrList)
97!
98! !USES:
99!
100      use m_realkinds, only : FP 
101      use m_stdio,     only : stderr
102      use m_die,       only : MP_perr_die, die, warn
103
104      use m_List, only : List_identical => identical
105      use m_List, only : List_nitem => nitem
106      use m_List, only : GetIndices => get_indices
107
108      use m_AttrVect, only : AttrVect
109      use m_AttrVect, only : AttrVect_lsize => lsize
110      use m_AttrVect, only : AttrVect_zero => zero
111      use m_AttrVect, only : AttrVect_nRAttr => nRAttr
112      use m_AttrVect, only : AttrVect_indexRA => indexRA
113      use m_AttrVect, only : SharedAttrIndexList
114
115      use m_SparseMatrix, only : SparseMatrix
116      use m_SparseMatrix, only : SparseMatrix_lsize => lsize
117      use m_SparseMatrix, only : SparseMatrix_indexIA => indexIA
118      use m_SparseMatrix, only : SparseMatrix_indexRA => indexRA
119      use m_SparseMatrix, only : SparseMatrix_vecinit => vecinit
120
121      implicit none
122
123! !INPUT PARAMETERS:
124
125      type(AttrVect),     intent(in)    :: xAV
126      logical,optional,   intent(in)    :: Vector
127      character(len=*),optional, intent(in)    :: rList
128      character(len=*),optional, intent(in)    :: TrList
129
130
131! !INPUT/OUTPUT PARAMETERS:
132
133      type(SparseMatrix), intent(inout)    :: sMat
134      type(AttrVect),     intent(inout) :: yAV
135
136! !REVISION HISTORY:
137! 15Jan01 - J.W. Larson <larson@mcs.anl.gov> - API specification.
138! 10Feb01 - J.W. Larson <larson@mcs.anl.gov> - Prototype code.
139! 24Apr01 - J.W. Larson <larson@mcs.anl.gov> - Modified to accomodate
140!           changes to the SparseMatrix datatype.
141! 25Apr01 - J.W. Larson <larson@mcs.anl.gov> - Reversed loop order
142!           for cache-friendliness
143! 17May01 - R. Jacob <jacob@mcs.anl.gov> - Zero the output
144!           attribute vector
145! 10Oct01 - J. Larson <larson@mcs.anl.gov> - Added optional LOGICAL
146!           input argument InterpInts to make application of the
147!           multiply to INTEGER attributes optional
148! 15Oct01 - J. Larson <larson@mcs.anl.gov> - Added feature to
149!           detect when attribute lists are identical, and cross-
150!           indexing of attributes is not needed.
151! 29Nov01 - E.T. Ong <eong@mcs.anl.gov> - Removed MP_PERR_DIE if
152!           there are zero elements in sMat. This allows for
153!           decompositions where a process may own zero points.
154! 29Oct03 - R. Jacob <jacob@mcs.anl.gov> - add Vector argument to
155!           optionally use the vector-friendly version provided by
156!           Fujitsu
157! 21Nov06 - R. Jacob <jacob@mcs.anl.gov> - Allow attributes to be
158!           to be multiplied to be specified with rList and TrList.
159!EOP ___________________________________________________________________
160
161  character(len=*),parameter :: myname_=myname//'::sMatAvMult_DataLocal_'
162
163! Matrix element count:
164  integer :: num_elements
165
166! Matrix row, column, and weight indices:
167  integer :: icol, irow, iwgt
168
169! Overlapping attribute index number
170  integer :: num_indices
171
172! Overlapping attribute index storage arrays:
173  integer, dimension(:), pointer :: xAVindices, yAVindices
174
175! Temporary variables for multiply do-loop
176  integer :: row, col
177  real(FP) :: wgt
178
179! Error flag and loop indices
180  integer :: ierr, i, m, n, l,ier
181  integer :: inxmin,outxmin
182  integer :: ysize, numav,j
183
184! Character variable used as a data type flag:
185  character*7 :: data_flag
186
187! logical flag
188  logical :: usevector,TrListIsPresent,rListIsPresent
189  logical :: contiguous,ycontiguous
190
191  usevector = .false.
192  if(present(Vector)) then
193    if(Vector) usevector = .true.
194  endif
195
196  rListIsPresent = .false.
197  if(present(rList)) then
198    rListIsPresent = .true.
199  endif
200
201!  TrList is present if it is provided and its length>0
202  TrListIsPresent = .false.
203  if(present(TrList)) then
204     if(.not.present(rList)) then
205       call die(myname_,'MCTERROR: TrList provided without rList',2)
206     endif
207     if(len_trim(TrList) > 0) then
208       TrListIsPresent = .true.
209     endif
210  endif
211
212
213       ! Retrieve the number of elements in sMat:
214
215  num_elements = SparseMatrix_lsize(sMat)
216
217       ! Indexing the sparse matrix sMat:
218
219  irow = SparseMatrix_indexIA(sMat,'lrow')    ! local row index
220  icol = SparseMatrix_indexIA(sMat,'lcol')    ! local column index
221  iwgt = SparseMatrix_indexRA(sMat,'weight')  ! weight index
222
223
224       ! Multiplication sMat by REAL attributes in xAV:
225
226  if(List_identical(xAV%rList, yAV%rList).and.   &
227    .not.rListIsPresent) then                  ! no cross-indexing
228
229       ! zero the output AttributeVector
230     call AttrVect_zero(yAV, zeroInts=.FALSE.)
231
232     num_indices = List_nitem(xAV%rList)
233
234     if(usevector) then
235
236       if(.not.sMat%vecinit) then
237            call SparseMatrix_vecinit(sMat)
238       endif
239
240!DIR$ CONCURRENT
241       do m=1,num_indices
242          do l=1,sMat%tbl_end
243!CDIR NOLOOPCHG
244!DIR$ CONCURRENT
245             do i=sMat%row_s(l),sMat%row_e(l)
246               col = sMat%tcol(i,l)
247               wgt = sMat%twgt(i,l)
248               if (col < 0) cycle
249               yAV%rAttr(m,i) = yAV%rAttr(m,i) + wgt * xAV%rAttr(m,col)
250             enddo
251          enddo
252       enddo
253 
254     else
255
256       do n=1,num_elements
257
258          row = sMat%data%iAttr(irow,n)
259          col = sMat%data%iAttr(icol,n)
260          wgt = sMat%data%rAttr(iwgt,n)
261
262         ! loop over attributes being regridded.
263
264!DIR$ CONCURRENT
265          do m=1,num_indices
266
267             yAV%rAttr(m,row) = yAV%rAttr(m,row) + wgt * xAV%rAttr(m,col)
268
269          end do ! m=1,num_indices
270
271       end do ! n=1,num_elements
272
273     endif
274
275! lists are not identical or only want to do part.
276  else
277
278   if(rListIsPresent) then
279     call GetIndices(xAVindices,xAV%rList,trim(rList))
280
281     if(TrListIsPresent) then
282       call GetIndices(yAVindices,yAV%rList,trim(TrList))
283
284       if(size(xAVindices) /= size(yAVindices)) then
285         call die(myname_,"Arguments rList and TrList do not&
286             &contain the same number of items") 
287       endif   
288
289     else
290       call GetIndices(yAVindices,yAV%rList,trim(rList))
291     endif
292
293     num_indices=size(yAVindices)
294
295     ! nothing to do if num_indices <=0
296     if (num_indices <= 0) then
297       deallocate(xaVindices, yAVindices, stat=ier)
298       if(ier/=0) call die(myname_,"deallocate(xAVindices...)",ier)
299       return 
300     endif
301
302   else
303
304     data_flag = 'REAL'
305     call SharedAttrIndexList(xAV, yAV, data_flag, num_indices, &
306                              xAVindices, yAVindices)
307
308     ! nothing to do if num_indices <=0
309     if (num_indices <= 0) then
310       deallocate(xaVindices, yAVindices, stat=ier)
311       call warn(myname_,"No matching indicies found, returning.")
312       if(ier/=0) call die(myname_,"deallocate(xaVinindices...)",ier)
313       return
314     endif
315   endif
316
317! Check if the indices are contiguous in memory for faster copy
318   contiguous=.true.
319   ycontiguous=.true.
320   do i=2,num_indices
321      if(xaVindices(i) /= xAVindices(i-1)+1) contiguous = .false. 
322   enddo
323   if(contiguous) then
324      do i=2,num_indices
325          if(yAVindices(i) /= yAVindices(i-1)+1) then
326            contiguous=.false.
327            ycontiguous=.false.
328          endif
329      enddo   
330   endif
331
332       ! zero the right parts of the output AttributeVector
333   ysize = AttrVect_lsize(yAV)
334   numav=size(yAVindices)
335
336   if(ycontiguous) then
337     outxmin=yaVindices(1)-1
338     do j=1,ysize
339       do i=1,numav
340         yAV%rAttr(outxmin+i,j)=0._FP
341       enddo
342     enddo
343   else
344     do j=1,ysize
345       do i=1,numav
346         yAV%rAttr(yaVindices(i),j)=0._FP
347       enddo
348     enddo
349   endif
350
351       ! loop over matrix elements
352
353   if(contiguous) then
354     outxmin=yaVindices(1)-1
355     inxmin=xaVindices(1)-1
356     do n=1,num_elements
357
358        row = sMat%data%iAttr(irow,n)
359        col = sMat%data%iAttr(icol,n)
360        wgt = sMat%data%rAttr(iwgt,n)
361
362       ! loop over attributes being regridded.
363!DIR$ CONCURRENT
364        do m=1,num_indices
365            yAV%rAttr(outxmin+m,row) = &
366               yAV%rAttr(outxmin+m,row) + &
367               wgt * xAV%rAttr(inxmin+m,col)
368        end do ! m=1,num_indices
369     end do ! n=1,num_elements
370
371   else
372     do n=1,num_elements
373
374        row = sMat%data%iAttr(irow,n)
375        col = sMat%data%iAttr(icol,n)
376        wgt = sMat%data%rAttr(iwgt,n)
377
378       ! loop over attributes being regridded.
379!DIR$ CONCURRENT
380        do m=1,num_indices
381            yAV%rAttr(yAVindices(m),row) = &
382               yAV%rAttr(yAVindices(m),row) + &
383               wgt * xAV%rAttr(xAVindices(m),col)
384        end do ! m=1,num_indices
385     end do ! n=1,num_elements
386   endif
387
388
389   deallocate(xAVindices, yAVindices, stat=ierr)
390   if(ierr /= 0) call die(myname_,'first deallocate(xAVindices...',ierr)
391
392  endif ! if(List_identical(xAV%rAttr, yAV%rAttr))...
393        ! And we are finished!
394
395 end subroutine sMatAvMult_DataLocal_
396
397!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
398!     Math + Computer Science Division / Argonne National Laboratory   !
399!BOP -------------------------------------------------------------------
400!
401! !IROUTINE: sMatAvMult_SMPlus_ - Parallel Multiply Using SparseMatrixPlus
402!
403! !DESCRIPTION:
404! This routine performs distributed parallel sparse matrix-vector
405! multiplication ${\bf y} = {\bf M} {\bf x}$, where {\bf y} and
406! {\bf x} are represented by the {\tt AttrVect} arguments {\tt yAV} and
407! {\tt xAV}, respectively.  The matrix {\bf M} is stored in the input
408! {\tt SparseMatrixPlus} argument {\tt sMatPlus}, which also contains
409! all the information needed to coordinate the communications required to
410! gather intermediate vectors used in the multiplication process, and to
411! reduce partial sums as needed.
412! By default, the multiplication occurs for each of the common {\tt REAL} attributes
413! shared by {\tt xAV} and {\tt yAV}.  This routine is capable of
414! cross-indexing the attributes and performing the necessary multiplications.
415!
416! If the optional argument {\tt rList} is present, only the attributes listed will
417! be multiplied.  If the attributes have different names in {\tt yAV}, the optional
418! {\tt TrList} argument can be used to provide the translation.
419!
420! If the optional argument {\tt Vector} is present and true, the vector
421! architecture-friendly portions of this routine will be invoked.  It
422! will also cause the vector parts of {\tt sMatPlus} to be initialized if they
423! have not been already.
424!
425! !INTERFACE:
426
427 subroutine sMatAvMult_SMPlus_(xAV, sMatPlus, yAV, Vector, rList, TrList)
428!
429! !USES:
430!
431      use m_stdio
432      use m_die
433      use m_mpif90
434
435      use m_String, only : String
436      use m_String, only : String_ToChar => ToChar
437
438      use m_AttrVect, only : AttrVect
439      use m_AttrVect, only : AttrVect_init => init
440      use m_AttrVect, only : AttrVect_lsize => lsize
441      use m_AttrVect, only : AttrVect_clean => clean
442      use m_AttrVect, only : AttrVect_Rcopy => Rcopy
443      use m_AttrVect, only : AttrVect_zero  => zero
444
445      use m_Rearranger, only : Rearranger
446      use m_Rearranger, only : Rearrange
447
448      use m_SparseMatrixPlus, only : SparseMatrixPlus
449      use m_SparseMatrixPlus, only : Xonly
450      use m_SparseMatrixPlus, only : Yonly
451      use m_SparseMatrixPlus, only : XandY
452
453      implicit none
454
455! !INPUT PARAMETERS:
456
457      type(AttrVect),         intent(in)    :: xAV
458      logical, optional,      intent(in)    :: Vector
459      character(len=*),optional, intent(in)    :: rList
460      character(len=*),optional, intent(in)    :: TrList
461
462! !INPUT/OUTPUT PARAMETERS:
463
464      type(AttrVect),         intent(inout) :: yAV
465      type(SparseMatrixPlus), intent(inout) :: sMatPlus
466
467! !SEE ALSO:
468! The MCT module m_AttrVect for more information about the AttrVect type.
469! The MCT module m_SparseMatrixPlus for more information about the
470! SparseMatrixPlus type.
471
472! !REVISION HISTORY:
473! 26Sep02 - J.W. Larson <larson@mcs.anl.gov> - API specification and
474!           implementation.
475! 29Oct03 - R. Jacob <jacob@mcs.anl.gov> - add vector argument to all
476!           calls to Rearrange and DataLocal_.  Add optional input
477!           argument to change value (assumed false)
478! 22Nov06 - R. Jacob <jacob@mcs.anl.gov> - add rList,TrList arguments
479! 10Jan08 - T. Craig <tcraig@ucar.edu> - zero out intermediate aVs before
480!           they are used
481!EOP ___________________________________________________________________
482
483  character(len=*),parameter :: myname_=myname//'::sMatAvMult_SMPlus_'
484  type(AttrVect) :: xPrimeAV, yPrimeAV
485  type(AttrVect) :: yAVre
486  integer :: ierr
487  logical ::  usevector
488  character(len=5) :: strat
489
490  ! check arguments
491  if(present(TrList)) then
492     if(.not.present(rList)) then
493       call die(myname_,'MCTERROR: TrList provided without rList',2)
494     endif
495  endif
496
497  usevector = .FALSE.
498  if(present(Vector)) then
499   if(Vector)usevector = .TRUE.
500  endif
501       ! Examine the parallelization strategy, and act accordingly
502
503  strat = String_ToChar(sMatPlus%Strategy)
504  select case( strat )
505  case('Xonly')
506       ! Create intermediate AttrVect for x'
507     call AttrVect_init(xPrimeAV, xAV, sMatPlus%XPrimeLength)
508     call AttrVect_zero(xPrimeAV)
509       ! Rearrange data from x to get x'
510     call Rearrange(xAV, xPrimeAV, sMatPlus%XToXPrime, &
511                    sMatPlus%Tag ,vector=usevector)
512
513       ! Perform perfectly data-local multiply y = Mx'
514     if (present(TrList).and.present(rList)) then
515       call sMatAvMult_DataLocal_(xPrimeAV, sMatPlus%Matrix, yaV, &
516              Vector=usevector,rList=rList,TrList=TrList)
517     else if(.not.present(TrList) .and. present(rList)) then
518       call sMatAvMult_DataLocal_(xPrimeAV, sMatPlus%Matrix, yaV, &
519               Vector=usevector,rList=rList)
520     else
521       call sMatAvMult_DataLocal_(xPrimeAV, sMatPlus%Matrix, yaV, &
522               Vector=usevector)
523     endif
524
525       ! Clean up space occupied by x'
526     call AttrVect_clean(xPrimeAV, ierr)
527  case('Yonly')
528       ! Create intermediate AttrVect for y'
529     if (present(TrList).and.present(rList)) then
530        call AttrVect_init(yPrimeAV, rList=TrList, lsize=sMatPlus%YPrimeLength)
531     else if(.not.present(TrList) .and. present(rList)) then
532        call AttrVect_init(yPrimeAV, rList=rList, lsize=sMatPlus%YPrimeLength)
533     else
534        call AttrVect_init(yPrimeAV, yAV, sMatPlus%YPrimeLength)
535     endif
536     call AttrVect_zero(yPrimeAV)
537
538     if (present(TrList).or.present(rList)) then
539        call AttrVect_init(yAVre, yPrimeAV , lsize=AttrVect_lsize(yAV))
540        call AttrVect_zero(yAVre)
541     endif
542
543       ! Perform perfectly data-local multiply y' = Mx
544     if (present(TrList).and.present(rList)) then
545        call sMatAvMult_DataLocal_(xAV, sMatPlus%Matrix, yPrimeAV, &
546               Vector=usevector,rList=rList,TrList=TrList)
547     else if(.not.present(TrList) .and. present(rList)) then
548        call sMatAvMult_DataLocal_(xAV, sMatPlus%Matrix, yPrimeAV, &
549               Vector=usevector,rList=rList)
550     else
551        call sMatAvMult_DataLocal_(xAV, sMatPlus%Matrix, yPrimeAV, &
552               Vector=usevector)
553     endif
554     
555       ! Rearrange/reduce partial sums in y' to get y
556     if (present(TrList).or.present(rList)) then
557       call Rearrange(yPrimeAV, yAVre, sMatPlus%YPrimeToY, sMatPlus%Tag, &
558                    .TRUE., Vector=usevector)
559       call AttrVect_Rcopy(yAVre,yAV,vector=usevector)
560       call AttrVect_clean(yAVre, ierr)
561     else
562       call Rearrange(yPrimeAV, yAV, sMatPlus%YPrimeToY, sMatPlus%Tag, &
563                    .TRUE., Vector=usevector)
564     endif
565       ! Clean up space occupied by y'
566     call AttrVect_clean(yPrimeAV, ierr)
567
568  case('XandY')
569       ! Create intermediate AttrVect for x'
570     call AttrVect_init(xPrimeAV, xAV, sMatPlus%XPrimeLength)
571     call AttrVect_zero(xPrimeAV)
572
573       ! Create intermediate AttrVect for y'
574     if (present(TrList).and.present(rList)) then
575        call AttrVect_init(yPrimeAV, rList=TrList, lsize=sMatPlus%YPrimeLength)
576     else if(.not.present(TrList) .and. present(rList)) then
577        call AttrVect_init(yPrimeAV, rList=rList, lsize=sMatPlus%YPrimeLength)
578     else
579        call AttrVect_init(yPrimeAV, yAV, sMatPlus%YPrimeLength)
580     endif
581     call AttrVect_zero(yPrimeAV)
582
583     if (present(TrList).or.present(rList)) then
584        call AttrVect_init(yAVre, yPrimeAV , lsize=AttrVect_lsize(yAV))
585        call AttrVect_zero(yAVre)
586     endif
587
588       ! Rearrange data from x to get x'
589     call Rearrange(xAV, xPrimeAV, sMatPlus%XToXPrime, sMatPlus%Tag, &
590                       Vector=usevector)
591
592       ! Perform perfectly data-local multiply y' = Mx'
593     if (present(TrList).and.present(rList)) then
594         call sMatAvMult_DataLocal_(xPrimeAV, sMatPlus%Matrix, yPrimeAV, &
595                             Vector=usevector,rList=rList,TrList=TrList)
596     else if(.not.present(TrList) .and. present(rList)) then
597         call sMatAvMult_DataLocal_(xPrimeAV, sMatPlus%Matrix, yPrimeAV, &
598                             Vector=usevector,rList=rList)
599     else
600         call sMatAvMult_DataLocal_(xPrimeAV, sMatPlus%Matrix, yPrimeAV, &
601                             Vector=usevector)
602     endif
603
604       ! Rearrange/reduce partial sums in y' to get y
605     if (present(TrList).or.present(rList)) then
606       call Rearrange(yPrimeAV, yAVre, sMatPlus%YPrimeToY, sMatPlus%Tag, &
607                    .TRUE., Vector=usevector)
608       call AttrVect_Rcopy(yAVre,yAV,vector=usevector)
609       call AttrVect_clean(yAVre, ierr)
610     else
611       call Rearrange(yPrimeAV, yAV, sMatPlus%YPrimeToY, sMatPlus%Tag, &
612                    .TRUE., Vector=usevector)
613     endif
614
615       ! Clean up space occupied by x'
616     call AttrVect_clean(xPrimeAV, ierr)
617       ! Clean up space occupied by y'
618     call AttrVect_clean(yPrimeAV, ierr)
619  case default
620     write(stderr,'(4a)') myname_, &
621          ':: FATAL ERROR--parallelization strategy name ',&
622          String_ToChar(sMatPlus%Strategy),' not supported.'
623     call die(myname_)
624  end select
625
626 end subroutine sMatAvMult_SMPlus_
627
628 end module m_MatAttrVectMul
629
630
631
632
Note: See TracBrowser for help on using the repository browser.