3
4
5
6
7
8
9
10 CHARACTER UPLO
11 INTEGER IA, IB, IBTYPE, INFO, JA, JB, LWORK, N
12 REAL SCALE
13
14
15 INTEGER DESCA( * ), DESCB( * )
16 REAL A( * ), B( * ), WORK( * )
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208 REAL ONEHALF, ONE, MONE
209 parameter( onehalf = 0.5e0, one = 1.0e0, mone = -1.0e0 )
210 INTEGER DLEN_, CTXT_, MB_, NB_, RSRC_, CSRC_, LLD_
211 parameter( dlen_ = 9, ctxt_ = 2, mb_ = 5, nb_ = 6,
212 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
213
214
215 LOGICAL LQUERY, UPPER
216 INTEGER I, IACOL, IAROW, IBCOL, IBROW, ICOFFA, ICOFFB,
217 $ ICTXT, INDAA, INDG, INDR, INDRT, IROFFA,
218 $ IROFFB, J, K, KB, LWMIN, LWOPT, MYCOL, MYROW,
219 $ NB, NP0, NPCOL, NPK, NPROW, NQ0, POSTK
220
221
222 INTEGER DESCAA( DLEN_ ), DESCG( DLEN_ ),
223 $ DESCR( DLEN_ ), DESCRT( DLEN_ ), IDUM1( 2 ),
224 $ IDUM2( 2 )
225
226
227 LOGICAL LSAME
228 INTEGER INDXG2P, NUMROC
230
231
235
236
237 INTRINSIC ichar,
max,
min, mod, real
238
239
240 ictxt = desca( ctxt_ )
241 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
242 scale = 1.0e0
243
244 nb = desca( mb_ )
245
246
247
248
249 info = 0
250 IF( nprow.EQ.-1 ) THEN
251 info = -( 700+ctxt_ )
252 ELSE
253 upper =
lsame( uplo,
'U' )
254 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 7, info )
255 CALL chk1mat( n, 3, n, 3, ib, jb, descb, 11, info )
256 IF( info.EQ.0 ) THEN
257 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
258 $ nprow )
259 ibrow =
indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
260 $ nprow )
261 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
262 $ npcol )
263 ibcol =
indxg2p( jb, descb( nb_ ), mycol, descb( csrc_ ),
264 $ npcol )
265 iroffa = mod( ia-1, desca( mb_ ) )
266 icoffa = mod( ja-1, desca( nb_ ) )
267 iroffb = mod( ib-1, descb( mb_ ) )
268 icoffb = mod( jb-1, descb( nb_ ) )
269 np0 =
numroc( n, nb, 0, 0, nprow )
270 nq0 =
numroc( n, nb, 0, 0, npcol )
271 lwmin =
max( nb*( np0+1 ), 3*nb )
272 IF( ibtype.EQ.1 .AND. .NOT.upper ) THEN
273 lwopt = 2*np0*nb + nq0*nb + nb*nb
274 ELSE
275 lwopt = lwmin
276 END IF
277 work( 1 ) = real( lwopt )
278 lquery = ( lwork.EQ.-1 )
279 IF( ibtype.LT.1 .OR. ibtype.GT.3 ) THEN
280 info = -1
281 ELSE IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
282 info = -2
283 ELSE IF( n.LT.0 ) THEN
284 info = -3
285 ELSE IF( iroffa.NE.0 ) THEN
286 info = -5
287 ELSE IF( icoffa.NE.0 ) THEN
288 info = -6
289 ELSE IF( desca( mb_ ).NE.desca( nb_ ) ) THEN
290 info = -( 700+nb_ )
291 ELSE IF( iroffb.NE.0 .OR. ibrow.NE.iarow ) THEN
292 info = -9
293 ELSE IF( icoffb.NE.0 .OR. ibcol.NE.iacol ) THEN
294 info = -10
295 ELSE IF( descb( mb_ ).NE.desca( mb_ ) ) THEN
296 info = -( 1100+mb_ )
297 ELSE IF( descb( nb_ ).NE.desca( nb_ ) ) THEN
298 info = -( 1100+nb_ )
299 ELSE IF( ictxt.NE.descb( ctxt_ ) ) THEN
300 info = -( 1100+ctxt_ )
301 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
302 info = -13
303 END IF
304 END IF
305 idum1( 1 ) = ibtype
306 idum2( 1 ) = 1
307 IF( upper ) THEN
308 idum1( 2 ) = ichar( 'U' )
309 ELSE
310 idum1( 2 ) = ichar( 'L' )
311 END IF
312 idum2( 2 ) = 2
313 CALL pchk2mat( n, 3, n, 3, ia, ja, desca, 7, n, 3, n, 3, ib,
314 $ jb, descb, 11, 2, idum1, idum2, info )
315 END IF
316
317 IF( info.NE.0 ) THEN
318 CALL pxerbla( ictxt,
'PSSYNGST', -info )
319 RETURN
320 ELSE IF( lquery ) THEN
321 RETURN
322 END IF
323
324
325
326 IF( n.EQ.0 )
327 $ RETURN
328
329
330 IF( ibtype.NE.1 .OR. upper .OR. lwork.LT.lwopt ) THEN
331 CALL pssygst( ibtype, uplo, n, a, ia, ja, desca, b, ib, jb,
332 $ descb, scale, info )
333 RETURN
334 END IF
335
336 CALL descset( descg, n, nb, nb, nb, iarow, iacol, ictxt, np0 )
337 CALL descset( descr, n, nb, nb, nb, iarow, iacol, ictxt, np0 )
338 CALL descset( descrt, nb, n, nb, nb, iarow, iacol, ictxt, nb )
339 CALL descset( descaa, nb, nb, nb, nb, iarow, iacol, ictxt, nb )
340
341 indg = 1
342 indr = indg + descg( lld_ )*nb
343 indaa = indr + descr( lld_ )*nb
344 indrt = indaa + descaa( lld_ )*nb
345
346 DO 30 k = 1, n, nb
347
348 kb =
min( n-k+1, nb )
349 postk = k + kb
350 npk = n - postk + 1
351
352
353 CALL pslacpy(
'A', n-postk+1, kb, b, postk+ib-1, k+jb-1, descb,
354 $ work( indg ), postk, 1, descg )
355 CALL pslacpy(
'A', n-postk+1, kb, a, postk+ia-1, k+ja-1, desca,
356 $ work( indr ), postk, 1, descr )
357 CALL pslacpy(
'A', kb, k-1, a, k+ia-1, ja, desca,
358 $ work( indrt ), 1, 1, descrt )
359
360 CALL pslacpy(
'L', kb, kb, a, k+ia-1, k+ja-1, desca,
361 $ work( indr ), k, 1, descr )
362 CALL pstrsm( 'Right', 'L', 'N', 'N', npk, kb, mone, b, k+ib-1,
363 $ k+jb-1, descb, work( indg ), postk, 1, descg )
364
365 CALL pssymm( 'Right', 'L', npk, kb, onehalf, a, k+ia-1, k+ja-1,
366 $ desca, work( indg ), postk, 1, descg, one,
367 $ work( indr ), postk, 1, descr )
368
369 CALL pssyr2k( 'Lower', 'No T', npk, kb, one, work( indg ),
370 $ postk, 1, descg, work( indr ), postk, 1, descr,
371 $ one, a, postk+ia-1, postk+ja-1, desca )
372
373 CALL psgemm( 'No T', 'No Conj', npk, k-1, kb, one,
374 $ work( indg ), postk, 1, descg, work( indrt ), 1,
375 $ 1, descrt, one, a, postk+ia-1, ja, desca )
376
377 CALL pssymm( 'Right', 'L', npk, kb, one, work( indr ), k, 1,
378 $ descr, work( indg ), postk, 1, descg, one, a,
379 $ postk+ia-1, k+ja-1, desca )
380
381 CALL pstrsm( 'Left', 'Lower', 'No Conj', 'Non-unit', kb, k-1,
382 $ one, b, k+ib-1, k+jb-1, descb, a, k+ia-1, ja,
383 $ desca )
384
385 CALL pslacpy(
'L', kb, kb, a, k+ia-1, k+ja-1, desca,
386 $ work( indaa ), 1, 1, descaa )
387
388 IF( myrow.EQ.descaa( rsrc_ ) .AND. mycol.EQ.descaa( csrc_ ) )
389 $ THEN
390 DO 20 i = 1, kb
391 DO 10 j = 1, i
392 work( indaa+j-1+( i-1 )*descaa( lld_ ) )
393 $ = work( indaa+i-1+( j-1 )*descaa( lld_ ) )
394 10 CONTINUE
395 20 CONTINUE
396 END IF
397
398 CALL pstrsm( 'Left', 'Lower', 'No Conj', 'Non-unit', kb, kb,
399 $ one, b, k+ib-1, k+jb-1, descb, work( indaa ), 1,
400 $ 1, descaa )
401
402 CALL pstrsm( 'Right', 'Lower', 'Conj', 'Non-unit', kb, kb, one,
403 $ b, k+ib-1, k+jb-1, descb, work( indaa ), 1, 1,
404 $ descaa )
405
406 CALL pslacpy(
'L', kb, kb, work( indaa ), 1, 1, descaa, a,
407 $ k+ia-1, k+ja-1, desca )
408
409 CALL pstrsm( 'Right', 'Lower', 'Conj', 'Non-unit', npk, kb,
410 $ one, b, k+ib-1, k+jb-1, descb, a, postk+ia-1,
411 $ k+ja-1, desca )
412
413 descr( csrc_ ) = mod( descr( csrc_ )+1, npcol )
414 descg( csrc_ ) = mod( descg( csrc_ )+1, npcol )
415 descrt( rsrc_ ) = mod( descrt( rsrc_ )+1, nprow )
416 descaa( rsrc_ ) = mod( descaa( rsrc_ )+1, nprow )
417 descaa( csrc_ ) = mod( descaa( csrc_ )+1, npcol )
418 30 CONTINUE
419
420 work( 1 ) = real( lwopt )
421
422 RETURN
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
subroutine pslacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
subroutine pssygst(ibtype, uplo, n, a, ia, ja, desca, b, ib, jb, descb, scale, info)
subroutine pxerbla(ictxt, srname, info)