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 | |
---|