1 SUBROUTINE pssyngst( IBTYPE, UPLO, N, A, IA, JA, DESCA, B, IB, JB,
2 $ DESCB, SCALE, WORK, LWORK, INFO )
11 INTEGER IA, IB, IBTYPE, INFO, JA, JB, LWORK, N
15 INTEGER DESCA( * ), DESCB( * )
16 REAL A( * ), B( * ), WORK( * )
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 )
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
222 INTEGER DESCAA( DLEN_ ), DESCG( DLEN_ ),
223 $ descr( dlen_ ), descrt( dlen_ ), idum1( 2 ),
228 INTEGER INDXG2P, NUMROC
229 EXTERNAL lsame, indxg2p, numroc
237 INTRINSIC ichar,
max,
min, mod, real
240 ictxt = desca( ctxt_ )
241 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
250 IF( nprow.EQ.-1 )
THEN
251 info = -( 700+ctxt_ )
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 )
257 iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
259 ibrow = indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
261 iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
263 ibcol = indxg2p( jb, descb( nb_ ), mycol, descb( csrc_ ),
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
277 work( 1 ) = real( lwopt )
278 lquery = ( lwork.EQ.-1 )
279 IF( ibtype.LT.1 .OR. ibtype.GT.3 )
THEN
281 ELSE IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
283 ELSE IF( n.LT.0 )
THEN
285 ELSE IF( iroffa.NE.0 )
THEN
287 ELSE IF( icoffa.NE.0 )
THEN
289 ELSE IF( desca( mb_ ).NE.desca( nb_ ) )
THEN
291 ELSE IF( iroffb.NE.0 .OR. ibrow.NE.iarow )
THEN
293 ELSE IF( icoffb.NE.0 .OR. ibcol.NE.iacol )
THEN
295 ELSE IF( descb( mb_ ).NE.desca( mb_ ) )
THEN
297 ELSE IF( descb( nb_ ).NE.desca( nb_ ) )
THEN
299 ELSE IF( ictxt.NE.descb( ctxt_ ) )
THEN
300 info = -( 1100+ctxt_ )
301 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
308 idum1( 2 ) = ichar(
'U' )
310 idum1( 2 ) = ichar(
'L' )
313 CALL pchk2mat( n, 3, n, 3, ia, ja, desca, 7, n, 3, n, 3, ib,
314 $ jb, descb, 11, 2, idum1, idum2, info )
318 CALL pxerbla( ictxt,
'PSSYNGST', -info )
320 ELSE IF( lquery )
THEN
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 )
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 )
342 indr = indg + descg( lld_ )*nb
343 indaa = indr + descr( lld_ )*nb
344 indrt = indaa + descaa( lld_ )*nb
348 kb =
min( n-k+1, nb )
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 )
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 )
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 )
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 )
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 )
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 )
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,
385 CALL pslacpy(
'L', kb, kb, a, k+ia-1, k+ja-1, desca,
386 $ work( indaa ), 1, 1, descaa )
388 IF( myrow.EQ.descaa( rsrc_ ) .AND. mycol.EQ.descaa( csrc_ ) )
392 work( indaa+j-1+( i-1 )*descaa( lld_ ) )
393 $ = work( indaa+i-1+( j-1 )*descaa( lld_ ) )
398 CALL pstrsm(
'Left',
'Lower',
'No Conj',
'Non-unit', kb, kb,
399 $ one, b, k+ib-1, k+jb-1, descb, work( indaa ), 1,
402 CALL pstrsm(
'Right',
'Lower',
'Conj',
'Non-unit', kb, kb, one,
403 $ b, k+ib-1, k+jb-1, descb, work( indaa ), 1, 1,
406 CALL pslacpy(
'L', kb, kb, work( indaa ), 1, 1, descaa, a,
407 $ k+ia-1, k+ja-1, desca )
409 CALL pstrsm(
'Right',
'Lower',
'Conj',
'Non-unit', npk, kb,
410 $ one, b, k+ib-1, k+jb-1, descb, a, postk+ia-1,
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 )
420 work( 1 ) = real( lwopt )