1 SUBROUTINE pdpttrf( N, D, E, JA, DESCA, AF, LAF, WORK, LWORK,
10 INTEGER INFO, JA, LAF, LWORK, N
14 DOUBLE PRECISION AF( * ), D( * ), E( * ), WORK( * )
350 parameter( one = 1.0d+0 )
351 DOUBLE PRECISION ZERO
352 parameter( zero = 0.0d+0 )
354 parameter( int_one = 1 )
355 INTEGER DESCMULT, BIGNUM
356 parameter( descmult = 100, bignum = descmult*descmult )
357 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
358 $ lld_, mb_, m_, nb_, n_, rsrc_
359 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
360 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
361 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
364 INTEGER COMM_PROC, CSRC, FIRST_PROC, I, ICTXT,
365 $ ictxt_new, ictxt_save, idum3, int_temp, ja_new,
366 $ laf_min, level_dist, llda, mycol, myrow,
367 $ my_num_cols, nb, np, npcol, nprow, np_save,
368 $ odd_size, part_offset, part_size, return_code,
369 $ store_n_a, temp, work_size_min
372 INTEGER DESCA_1XP( 7 ), PARAM_CHECK( 7, 3 )
377 $ dtrsd2d,
globchk, igamx2d, igebr2d, igebs2d,
398 temp = desca( dtype_ )
399 IF( temp.EQ.502 )
THEN
401 desca( dtype_ ) = 501
406 desca( dtype_ ) = temp
408 IF( return_code.NE.0 )
THEN
414 ictxt = desca_1xp( 2 )
415 csrc = desca_1xp( 5 )
417 llda = desca_1xp( 6 )
418 store_n_a = desca_1xp( 3 )
428 IF( lwork.LT.-1 )
THEN
430 ELSE IF( lwork.EQ.-1 )
THEN
440 IF( n+ja-1.GT.store_n_a )
THEN
446 IF( nprow.NE.1 )
THEN
450 IF( n.GT.np*nb-mod( ja-1, nb ) )
THEN
452 CALL pxerbla( ictxt,
'PDPTTRF, D&C alg.: only 1 block per proc'
457 IF( ( ja+n-1.GT.nb ) .AND. ( nb.LT.2*int_one ) )
THEN
459 CALL pxerbla( ictxt,
'PDPTTRF, D&C alg.: NB too small', -info )
466 laf_min = ( 12*npcol+3*nb )
468 IF( laf.LT.laf_min )
THEN
472 CALL pxerbla( ictxt,
'PDPTTRF: auxiliary storage error ',
479 work_size_min = 8*npcol
481 work( 1 ) = work_size_min
483 IF( lwork.LT.work_size_min
THEN
493 PARAM_CHECK( 7, 1 ) = DESCA( 5 )
494 PARAM_CHECK( 6, 1 ) = DESCA( 4 )
495 PARAM_CHECK( 5, 1 ) = DESCA( 3 )
496 PARAM_CHECK( 4, 1 ) = DESCA( 1 )
497 PARAM_CHECK( 3, 1 ) = JA
498 PARAM_CHECK( 2, 1 ) = N
499 PARAM_CHECK( 1, 1 ) = IDUM3
501 PARAM_CHECK( 7, 2 ) = 505
502 PARAM_CHECK( 6, 2 ) = 504
503 PARAM_CHECK( 5, 2 ) = 503
504 PARAM_CHECK( 4, 2 ) = 501
505 PARAM_CHECK( 3, 2 ) = 4
506 PARAM_CHECK( 2, 2 ) = 1
507 PARAM_CHECK( 1, 2 ) = 9
515.LT.
ELSE IF( INFO-DESCMULT ) THEN
518 INFO = -INFO*DESCMULT
523 CALL GLOBCHK( ICTXT, 7, PARAM_CHECK, 7, PARAM_CHECK( 1, 3 ),
529.EQ.
IF( INFOBIGNUM ) THEN
531.EQ.
ELSE IF( MOD( INFO, DESCMULT )0 ) THEN
532 INFO = -INFO / DESCMULT
538 CALL PXERBLA( ICTXT, 'pdpttrf', -INFO )
551 PART_OFFSET = NB*( ( JA-1 ) / ( NPCOL*NB ) )
553.LT.
IF( ( MYCOL-CSRC )( JA-PART_OFFSET-1 ) / NB ) THEN
554 PART_OFFSET = PART_OFFSET + NB
557.LT.
IF( MYCOLCSRC ) THEN
558 PART_OFFSET = PART_OFFSET - NB
567 FIRST_PROC = MOD( ( JA-1 ) / NB+CSRC, NPCOL )
571 JA_NEW = MOD( JA-1, NB ) + 1
576 NP = ( JA_NEW+N-2 ) / NB + 1
580 CALL RESHAPE( ICTXT, INT_ONE, ICTXT_NEW, INT_ONE, FIRST_PROC,
587 DESCA_1XP( 2 ) = ICTXT_NEW
591 CALL BLACS_GRIDINFO( ICTXT, NPROW, NPCOL, MYROW, MYCOL )
595.LT.
IF( MYROW0 ) THEN
608 MY_NUM_COLS = NUMROC( N, PART_SIZE, MYCOL, 0, NPCOL )
612.EQ.
IF( MYCOL0 ) THEN
613 PART_OFFSET = PART_OFFSET + MOD( JA_NEW-1, PART_SIZE )
614 MY_NUM_COLS = MY_NUM_COLS - MOD( JA_NEW-1, PART_SIZE )
619 ODD_SIZE = MY_NUM_COLS
620.LT.
IF( MYCOLNP-1 ) THEN
621 ODD_SIZE = ODD_SIZE - INT_ONE
639.LT.
IF( MYCOLNP-1 ) THEN
645 CALL DTRSD2D( ICTXT, 'u
', 'n
', 1, 1,
646 $ E( PART_OFFSET+ODD_SIZE+1 ), LLDA-1, 0, MYCOL+1 )
654 CALL DPTTRF( ODD_SIZE, D( PART_OFFSET+1 ), E( PART_OFFSET+1 ),
663.LT.
IF( MYCOLNP-1 ) THEN
670 E( PART_OFFSET+ODD_SIZE ) = E( PART_OFFSET+ODD_SIZE ) /
671 $ D( PART_OFFSET+ODD_SIZE )
678 D( PART_OFFSET+ODD_SIZE+1 ) = D( PART_OFFSET+ODD_SIZE+1 ) -
679 $ D( PART_OFFSET+ODD_SIZE )*
680 $ ( E( PART_OFFSET+ODD_SIZE )*
681 $ ( E( PART_OFFSET+ODD_SIZE ) ) )
690.NE.
IF( MYCOL0 ) THEN
697 CALL DTRRV2D( ICTXT, 'u
', 'n
', 1, 1, AF( 1 ), ODD_SIZE, 0,
704 CALL DPTTRSV( 'n
', ODD_SIZE, INT_ONE, D( PART_OFFSET+1 ),
705 $ E( PART_OFFSET+1 ), AF( 1 ), ODD_SIZE, INFO )
709 DO 30 I = 1, ODD_SIZE
710 AF( I ) = AF( I ) / D( PART_OFFSET+I )
720 INT_TEMP = ODD_SIZE*INT_ONE + 2 + 1
723 DO 40 I = 1, ODD_SIZE
724 AF( INT_TEMP ) = AF( INT_TEMP ) -
725 $ D( PART_OFFSET+I )*( AF( I )*
733 CALL DGESD2D( ICTXT, INT_ONE, INT_ONE, AF( ODD_SIZE+3 ),
734 $ INT_ONE, 0, MYCOL-1 )
737.LT.
IF( MYCOLNP-1 ) THEN
744 AF( ODD_SIZE+1 ) = -D( PART_OFFSET+ODD_SIZE )*
745 $ ( E( PART_OFFSET+ODD_SIZE )*
760 CALL IGAMX2D( ICTXT, 'a
', ' ', 1, 1, INFO, 1, INFO, INFO, -1, 0,
763.EQ.
IF( MYCOL0 ) THEN
764 CALL IGEBS2D( ICTXT, 'a
', ' ', 1, 1, INFO, 1 )
766 CALL IGEBR2D( ICTXT, 'a
', ' ', 1, 1, INFO, 1, 0, 0 )
784.EQ.
IF( MYCOLNPCOL-1 ) THEN
792.EQ..AND..GT.
IF( ( MOD( MYCOL+1, 2 )0 ) ( MYCOL0 ) ) THEN
794 CALL DGESD2D( ICTXT, INT_ONE, INT_ONE, AF( ODD_SIZE+1 ),
795 $ INT_ONE, 0, MYCOL-1 )
802 AF( ODD_SIZE+2 ) = DBLE( D( PART_OFFSET+ODD_SIZE+1 ) )
806.LT.
IF( MYCOLNPCOL-1 ) THEN
808 CALL DGERV2D( ICTXT, INT_ONE, INT_ONE, AF( ODD_SIZE+2+1 ),
809 $ INT_ONE, 0, MYCOL+1 )
813 AF( ODD_SIZE+2 ) = AF( ODD_SIZE+2 ) + AF( ODD_SIZE+3 )
828.NE.
IF( MOD( ( MYCOL+1 ) / LEVEL_DIST, 2 )0 )
833.GE.
IF( MYCOL-LEVEL_DIST0 ) THEN
834 CALL DGERV2D( ICTXT, INT_ONE, INT_ONE, WORK( 1 ), INT_ONE, 0,
837 AF( ODD_SIZE+2 ) = AF( ODD_SIZE+2 ) + WORK( 1 )
843.LT.
IF( MYCOL+LEVEL_DISTNPCOL-1 ) THEN
844 CALL DGERV2D( ICTXT, INT_ONE, INT_ONE, WORK( 1 ), INT_ONE, 0,
847 AF( ODD_SIZE+2 ) = AF( ODD_SIZE+2 ) + WORK( 1 )
851 LEVEL_DIST = LEVEL_DIST*2
860.EQ.
IF( AF( ODD_SIZE+2 )ZERO ) THEN
869.EQ.
IF( LEVEL_DIST1 ) THEN
870 COMM_PROC = MYCOL + 1
875 AF( ODD_SIZE+3 ) = AF( ODD_SIZE+1 )
878 COMM_PROC = MYCOL + LEVEL_DIST / 2
881.LE.
IF( MYCOL / LEVEL_DIST( NPCOL-1 ) / LEVEL_DIST-2 ) THEN
883 CALL DGERV2D( ICTXT, INT_ONE, INT_ONE, AF( ODD_SIZE+1 ),
884 $ INT_ONE, 0, COMM_PROC )
892 AF( ODD_SIZE+1 ) = AF( ODD_SIZE+1 ) / AF( ODD_SIZE+2 )
899 WORK( 1 ) = -ONE*AF( ODD_SIZE+1 )*AF( ODD_SIZE+2 )*
900 $ ( AF( ODD_SIZE+1 ) )
904 CALL DGESD2D( ICTXT, INT_ONE, INT_ONE, WORK( 1 ), INT_ONE, 0,
915.GT..AND.
IF( ( MYCOL / LEVEL_DIST0 )
916.LE.
$ ( MYCOL / LEVEL_DIST( NPCOL-1 ) / LEVEL_DIST-1 ) ) THEN
918.GT.
IF( LEVEL_DIST1 ) THEN
923 CALL DGERV2D( ICTXT, INT_ONE, INT_ONE, AF( ODD_SIZE+2+1 ),
924 $ INT_ONE, 0, MYCOL-LEVEL_DIST / 2 )
933 AF( ODD_SIZE+3 ) = ( AF( ODD_SIZE+3 ) ) / AF( ODD_SIZE+2 )
941 WORK( 1 ) = -ONE*AF( ODD_SIZE+3 )*AF( ODD_SIZE+2 )*
942 $ ( AF( ODD_SIZE+3 ) )
946 CALL DGESD2D( ICTXT, INT_ONE, INT_ONE, WORK( 1 ), INT_ONE, 0,
951.LE.
IF( MYCOL / LEVEL_DIST( NPCOL-1 ) / LEVEL_DIST-2 ) THEN
955.EQ.
IF( ( MOD( MYCOL / ( 2*LEVEL_DIST ), 2 ) )0 ) THEN
956 COMM_PROC = MYCOL + LEVEL_DIST
958 COMM_PROC = MYCOL - LEVEL_DIST
965 WORK( 1 ) = -ONE*AF( ODD_SIZE+3 )*AF( ODD_SIZE+2 )*
970 CALL DGESD2D( ICTXT, INT_ONE, INT_ONE, WORK( 1 ), INT_ONE,
986.NE.
IF( ICTXT_SAVEICTXT_NEW ) THEN
987 CALL BLACS_GRIDEXIT( ICTXT_NEW )
999 WORK( 1 ) = WORK_SIZE_MIN
1003 CALL IGAMX2D( ICTXT, 'a
', ' ', 1, 1, INFO, 1, INFO, INFO, -1, 0,
1006.EQ.
IF( MYCOL0 ) THEN
1007 CALL IGEBS2D( ICTXT, 'a
', ' ', 1, 1, INFO, 1 )
1009 CALL IGEBR2D( ICTXT, 'a
', ' ', 1, 1, INFO, 1, 0, 0 )