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