3
4
5
6
7
8
9
10 CHARACTER UPLO
11 INTEGER IA, INFO, JA, LWORK, N
12
13
14 INTEGER DESCA( * )
15 REAL A( * ), D( * ), E( * ), TAU( * ), WORK( * )
16
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
252 $ MB_, NB_, RSRC_, CSRC_, LLD_
253 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
254 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
255 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
256 REAL ONE
257 parameter( one = 1.0e+0 )
258
259
260 LOGICAL LQUERY, UPPER
261 CHARACTER COLCTOP, ROWCTOP
262 INTEGER ANB, CTXTB, I, IACOL, IAROW, ICOFFA, ICTXT,
263 $ IINFO, INDB, INDD, INDE, INDTAU, INDW, IPW,
264 $ IROFFA, J, JB, JX, K, KK, LLWORK, LWMIN, MINSZ,
265 $ MYCOL, MYCOLB, MYROW, MYROWB, NB, NP, NPCOL,
266 $ NPCOLB, NPROW, NPROWB, NPS, NQ, ONEPMIN, SQNPC,
267 $ TTLWMIN
268
269
270 INTEGER DESCB( DLEN_ ), DESCW( DLEN_ ), IDUM1( 2 ),
271 $ IDUM2( 2 )
272
273
274 EXTERNAL blacs_get, blacs_gridexit, blacs_gridinfo,
279
280
281 LOGICAL LSAME
282 INTEGER INDXG2L, INDXG2P, NUMROC, PJLAENV
284
285
286 INTRINSIC ichar, int,
max,
min, mod, real, sqrt
287
288
289
290
291 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
292 $ rsrc_.LT.0 )RETURN
293
294
295 ictxt = desca( ctxt_ )
296 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
297
298
299
300 info = 0
301 IF( nprow.EQ.-1 ) THEN
302 info = -( 600+ctxt_ )
303 ELSE
304 CALL chk1mat( n, 2, n, 2, ia, ja, desca, 6, info )
305 upper =
lsame( uplo,
'U' )
306 IF( info.EQ.0 ) THEN
307 nb = desca( nb_ )
308 iroffa = mod( ia-1, desca( mb_ ) )
309 icoffa = mod( ja-1, desca( nb_ ) )
310 iarow =
indxg2p( ia, nb, myrow, desca( rsrc_ ), nprow )
311 iacol =
indxg2p( ja, nb, mycol, desca( csrc_ ), npcol )
312 np =
numroc( n, nb, myrow, iarow, nprow )
313 nq =
max( 1,
numroc( n+ja-1, nb, mycol, desca( csrc_ ),
314 $ npcol ) )
315 lwmin =
max( ( np+1 )*nb, 3*nb )
316 anb =
pjlaenv( ictxt, 3,
'PSSYTTRD',
'L', 0, 0, 0, 0 )
317 minsz =
pjlaenv( ictxt, 5,
'PSSYTTRD',
'L', 0, 0, 0, 0 )
318 sqnpc = int( sqrt( real( nprow*npcol ) ) )
319 nps =
max(
numroc( n, 1, 0, 0, sqnpc ), 2*anb )
320 ttlwmin = 2*( anb+1 )*( 4*nps+2 ) + ( nps+4 )*nps
321
322 work( 1 ) = real( ttlwmin )
323 lquery = ( lwork.EQ.-1 )
324 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
325 info = -1
326
327
328
329
330 ELSE IF( iroffa.NE.icoffa .OR. icoffa.NE.0 ) THEN
331 info = -5
332 ELSE IF( desca( mb_ ).NE.desca( nb_ ) ) THEN
333 info = -( 600+nb_ )
334 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
335 info = -11
336 END IF
337 END IF
338 IF( upper ) THEN
339 idum1( 1 ) = ichar( 'U' )
340 ELSE
341 idum1( 1 ) = ichar( 'L' )
342 END IF
343 idum2( 1 ) = 1
344 IF( lwork.EQ.-1 ) THEN
345 idum1( 2 ) = -1
346 ELSE
347 idum1( 2 ) = 1
348 END IF
349 idum2( 2 ) = 11
350 CALL pchk1mat( n, 2, n, 2, ia, ja, desca, 6, 2, idum1, idum2,
351 $ info )
352 END IF
353
354 IF( info.NE.0 ) THEN
355 CALL pxerbla( ictxt,
'PSSYNTRD', -info )
356 RETURN
357 ELSE IF( lquery ) THEN
358 RETURN
359 END IF
360
361
362
363 IF( n.EQ.0 )
364 $ RETURN
365
366
367 onepmin = n*n + 3*n + 1
368 llwork = lwork
369 CALL igamn2d( ictxt, 'A', ' ', 1, 1, llwork, 1, 1, -1, -1, -1,
370 $ -1 )
371
372
373
374
375
376
377 nprowb = 0
378 IF( ( n.LT.minsz .OR. sqnpc.EQ.1 ) .AND. llwork.GE.onepmin .AND.
379 $ .NOT.upper ) THEN
380 nprowb = 1
381 nps = n
382 ELSE
383 IF( llwork.GE.ttlwmin .AND. .NOT.upper ) THEN
384 nprowb = sqnpc
385 END IF
386 END IF
387
388 IF( nprowb.GE.1 ) THEN
389 npcolb = nprowb
390 sqnpc = nprowb
391 indb = 1
392 indd = indb + nps*nps
393 inde = indd + nps
394 indtau = inde + nps
395 indw = indtau + nps
396 llwork = llwork - indw + 1
397
398 CALL blacs_get( ictxt, 10, ctxtb )
399 CALL blacs_gridinit( ctxtb, 'Row major', sqnpc, sqnpc )
400 CALL blacs_gridinfo( ctxtb, nprowb, npcolb, myrowb, mycolb )
401 CALL descset( descb, n, n, 1, 1, 0, 0, ctxtb, nps )
402
403 CALL pstrmr2d( uplo, 'N', n, n, a, ia, ja, desca, work( indb ),
404 $ 1, 1, descb, ictxt )
405
406
407
408
409 IF( nprowb.GT.0 ) THEN
410
411 IF( nprowb.EQ.1 ) THEN
412 CALL ssytrd( uplo, n, work( indb ), nps, work( indd ),
413 $ work( inde ), work( indtau ), work( indw ),
414 $ llwork, info )
415 ELSE
416
417 CALL pssyttrd(
'L', n, work( indb ), 1, 1, descb,
418 $ work( indd ), work( inde ),
419 $ work( indtau ), work( indw ), llwork,
420 $ info )
421
422 END IF
423 END IF
424
425
426
427
428 CALL pslamr1d( n-1, work( inde ), 1, 1, descb, e, 1, ja,
429 $ desca )
430
431 CALL pslamr1d( n, work( indd ), 1, 1, descb, d, 1, ja, desca )
432
433 CALL pslamr1d( n, work( indtau ), 1, 1, descb, tau, 1, ja,
434 $ desca )
435
436 CALL pstrmr2d( uplo, 'N', n, n, work( indb ), 1, 1, descb, a,
437 $ ia, ja, desca, ictxt )
438
439 IF( myrowb.GE.0 )
440 $ CALL blacs_gridexit( ctxtb )
441
442 ELSE
443
444 CALL pb_topget( ictxt, 'Combine', 'Columnwise', colctop )
445 CALL pb_topget( ictxt, 'Combine', 'Rowwise', rowctop )
446 CALL pb_topset( ictxt, 'Combine', 'Columnwise', '1-tree' )
447 CALL pb_topset( ictxt, 'Combine', 'Rowwise', '1-tree' )
448
449 ipw = np*nb + 1
450
451 IF( upper ) THEN
452
453
454
455 kk = mod( ja+n-1, nb )
456 IF( kk.EQ.0 )
457 $ kk = nb
458 CALL descset( descw, n, nb, nb, nb, iarow,
459 $
indxg2p( ja+n-kk, nb, mycol, desca( csrc_ ),
460 $ npcol ), ictxt,
max( 1, np ) )
461
462 DO 10 k = n - kk + 1, nb + 1, -nb
463 jb =
min( n-k+1, nb )
464 i = ia + k - 1
465 j = ja + k - 1
466
467
468
469
470
471 CALL pslatrd( uplo, k+jb-1, jb, a, ia, ja, desca, d, e,
472 $ tau, work, 1, 1, descw, work( ipw ) )
473
474
475
476
477
478 CALL pssyr2k( uplo, 'No transpose', k-1, jb, -one, a, ia,
479 $ j, desca, work, 1, 1, descw, one, a, ia,
480 $ ja, desca )
481
482
483
484 jx =
min(
indxg2l( j, nb, 0, iacol, npcol ), nq )
485 CALL pselset( a, i-1, j, desca, e( jx ) )
486
487 descw( csrc_ ) = mod( descw( csrc_ )+npcol-1, npcol )
488
489 10 CONTINUE
490
491
492
493 CALL pssytd2( uplo,
min( n, nb ), a, ia, ja, desca, d, e,
494 $ tau, work, lwork, iinfo )
495
496 ELSE
497
498
499
500 kk = mod( ja+n-1, nb )
501 IF( kk.EQ.0 )
502 $ kk = nb
503 CALL descset( descw, n, nb, nb, nb, iarow, iacol, ictxt,
505
506 DO 20 k = 1, n - nb, nb
507 i = ia + k - 1
508 j = ja + k - 1
509
510
511
512
513
514 CALL pslatrd( uplo, n-k+1, nb, a, i, j, desca, d, e, tau,
515 $ work, k, 1, descw, work( ipw ) )
516
517
518
519
520
521 CALL pssyr2k( uplo, 'No transpose', n-k-nb+1, nb, -one,
522 $ a, i+nb, j, desca, work, k+nb, 1, descw,
523 $ one, a, i+nb, j+nb, desca )
524
525
526
527 jx =
min(
indxg2l( j+nb-1, nb, 0, iacol, npcol ), nq )
528 CALL pselset( a, i+nb, j+nb-1, desca, e( jx ) )
529
530 descw( csrc_ ) = mod( descw( csrc_ )+1, npcol )
531
532 20 CONTINUE
533
534
535
536 CALL pssytd2( uplo, kk, a, ia+k-1, ja+k-1, desca, d, e, tau,
537 $ work, lwork, iinfo )
538 END IF
539
540 CALL pb_topset( ictxt, 'Combine', 'Columnwise', colctop )
541 CALL pb_topset( ictxt, 'Combine', 'Rowwise', rowctop )
542
543 END IF
544
545 work( 1 ) = real( ttlwmin )
546
547 RETURN
548
549
550
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
integer function indxg2l(indxglob, nb, iproc, isrcproc, nprocs)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
integer function pjlaenv(ictxt, ispec, name, opts, n1, n2, n3, n4)
subroutine pselset(a, ia, ja, desca, alpha)
subroutine pslamr1d(n, a, ia, ja, desca, b, ib, jb, descb)
subroutine pslatrd(uplo, n, nb, a, ia, ja, desca, d, e, tau, w, iw, jw, descw, work)
subroutine pssytd2(uplo, n, a, ia, ja, desca, d, e, tau, work, lwork, info)
subroutine pssyttrd(uplo, n, a, ia, ja, desca, d, e, tau, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)