1 SUBROUTINE pssyntrd( UPLO, N, A, IA, JA, DESCA, D, E, TAU, WORK,
11 INTEGER IA, INFO, JA, LWORK, N
15 REAL A( * ), D( * ), E( * ), TAU( * ), WORK( * )
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 )
257 parameter( one = 1.0e+0 )
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,
270 INTEGER DESCB( DLEN_ ), DESCW( DLEN_ ), IDUM1( 2 ),
274 EXTERNAL blacs_get, blacs_gridexit, blacs_gridinfo,
282 INTEGER INDXG2L, INDXG2P, NUMROC, PJLAENV
283 EXTERNAL lsame, indxg2l, indxg2p, numroc, pjlaenv
286 INTRINSIC ichar, int,
max,
min, mod, real, sqrt
291 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
295 ictxt = desca( ctxt_ )
296 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
301 IF( nprow.EQ.-1 )
THEN
302 info = -( 600+ctxt_ )
304 CALL chk1mat( n, 2, n, 2, ia, ja, desca, 6, info )
305 upper = lsame( uplo,
'U' )
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_ ),
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
322 work( 1 ) = real( ttlwmin )
323 lquery = ( lwork.EQ.-1 )
324 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
330 ELSE IF( iroffa.NE.icoffa .OR. icoffa.NE.0 )
THEN
332 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
334 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
339 idum1( 1 ) = ichar(
'U' )
341 idum1( 1 ) = ichar(
'L' )
344 IF( lwork.EQ.-1 )
THEN
350 CALL pchk1mat( n, 2, n, 2, ia, ja, desca, 6, 2, idum1, idum2,
355 CALL pxerbla( ictxt,
'PSSYNTRD', -info )
357 ELSE IF( lquery )
THEN
367 onepmin = n*n + 3*n + 1
369 CALL igamn2d( ictxt,
'A',
' ', 1, 1, llwork, 1, 1, -1, -1, -1,
378 IF( ( n.LT.minsz .OR. sqnpc.EQ.1 ) .AND. llwork.GE.onepmin .AND.
383 IF( llwork.GE.ttlwmin .AND. .NOT.upper )
THEN
388 IF( nprowb.GE.1 )
THEN
392 indd = indb + nps*nps
396 llwork = llwork - indw + 1
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 )
403 CALL pstrmr2d( uplo,
'N', n, n, a, ia, ja, desca, work( indb ),
404 $ 1, 1, descb, ictxt )
409 IF( nprowb.GT.0 )
THEN
411 IF( nprowb.EQ.1 )
THEN
412 CALL ssytrd( uplo, n, work( indb ), nps, work( indd ),
413 $ work( inde ), work( indtau ), work( indw ),
417 CALL pssyttrd(
'L', n, work( indb ), 1, 1, descb,
418 $ work( indd ), work( inde ),
419 $ work( indtau ), work( indw ), llwork,
428 CALL pslamr1d( n-1, work( inde ), 1, 1, descb, e, 1, ja,
431 CALL pslamr1d( n, work( indd ), 1, 1, descb, d, 1, ja, desca )
433 CALL pslamr1d( n, work( indtau ), 1, 1, descb, tau, 1, ja,
436 CALL pstrmr2d( uplo,
'N', n, n, work( indb ), 1, 1, descb, a,
437 $ ia, ja, desca, ictxt )
440 $
CALL blacs_gridexit( ctxtb )
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' )
455 kk = mod( ja+n-1, 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 ) )
462 DO 10 k = n - kk + 1, nb + 1, -nb
463 jb =
min( n-k+1, nb )
471 CALL pslatrd( uplo, k+jb-1, jb, a, ia, ja, desca, d, e,
472 $ tau, work, 1, 1, descw, work( ipw ) )
478 CALL pssyr2k( uplo,
'No transpose', k-1, jb, -one, a, ia,
479 $ j, desca, work, 1, 1, descw, one, a, ia,
484 jx =
min( indxg2l( j, nb, 0, iacol, npcol ), nq )
485 CALL pselset( a, i-1, j, desca, e( jx ) )
487 descw( csrc_ ) = mod( descw( csrc_ )+npcol-1, npcol )
493 CALL pssytd2( uplo,
min( n, nb ), a, ia, ja, desca, d, e,
494 $ tau, work, lwork, iinfo )
500 kk = mod( ja+n-1, nb )
503 CALL descset( descw, n, nb, nb, nb, iarow, iacol, ictxt,
506 DO 20 k = 1, n - nb, nb
514 CALL pslatrd( uplo, n-k+1, nb, a, i, j, desca, d, e, tau,
515 $ work, k, 1, descw, work( ipw ) )
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 )
527 jx =
min( indxg2l( j+nb-1, nb, 0, iacol, npcol ), nq )
528 CALL pselset( a, i+nb, j+nb-1, desca, e( jx ) )
530 descw( csrc_ ) = mod( descw( csrc_ )+1, npcol )
536 CALL pssytd2( uplo, kk, a, ia+k-1, ja+k-1, desca, d, e, tau,
537 $ work, lwork, iinfo )
540 CALL pb_topset( ictxt,
'Combine',
'Columnwise', colctop )
541 CALL pb_topset( ictxt,
'Combine',
'Rowwise', rowctop )
545 work( 1 ) = real( ttlwmin )