1 SUBROUTINE pcpttrf( N, D, E, JA, DESCA, AF, LAF, WORK, LWORK,
12 INTEGER INFO, JA, LAF, LWORK, N
16 COMPLEX AF( * ), E( * ), WORK( * )
355 parameter( one = 1.0e+0 )
356 parameter( zero = 0.0e+0 )
358 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
359 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
361 parameter( int_one = 1 )
362 INTEGER DESCMULT, BIGNUM
363 parameter(descmult = 100, bignum = descmult * descmult)
364 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
365 $ lld_, mb_, m_, nb_, n_, rsrc_
366 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
367 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
368 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
371 INTEGER COMM_PROC, CSRC, FIRST_PROC, I, ICTXT,
372 $ ictxt_new, ictxt_save, idum3, int_temp, ja_new,
373 $ laf_min, level_dist, llda, mycol, myrow,
374 $ my_num_cols, nb, np, npcol, nprow, np_save,
375 $ odd_size, part_offset, part_size, return_code,
376 $ store_n_a, temp, work_size_min
379 INTEGER DESCA_1XP( 7 ), PARAM_CHECK( 7, 3 )
382 EXTERNAL blacs_get, blacs_gridexit, blacs_gridinfo,
383 $ caxpy, cgemm, cgerv2d, cgesd2d, clamov,
384 $
clatcpy, cpbtrf, cpotrf, csyrk, ctbtrs, ctrmm,
391 EXTERNAL lsame, numroc
394 INTRINSIC ichar,
min, mod
407 temp = desca( dtype_ )
408 IF( temp .EQ. 502 )
THEN
410 desca( dtype_ ) = 501
415 desca( dtype_ ) = temp
417 IF( return_code .NE. 0)
THEN
418 info = -( 5*100 + 2 )
423 ictxt = desca_1xp( 2 )
424 csrc = desca_1xp( 5 )
426 llda = desca_1xp( 6 )
427 store_n_a = desca_1xp( 3 )
432 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
437 IF( lwork .LT. -1)
THEN
439 ELSE IF ( lwork .EQ. -1 )
THEN
449 IF( n+ja-1 .GT. store_n_a )
THEN
450 info = -( 5*100 + 6 )
455 IF( nprow .NE. 1 )
THEN
459 IF( n .GT. np*nb-mod( ja-1, nb ))
THEN
462 $
'PCPTTRF, D&C alg.: only 1 block per proc',
467 IF((ja+n-1.GT.nb) .AND. ( nb.LT.2*int_one ))
THEN
470 $
'PCPTTRF, D&C alg.: NB too small',
478 laf_min = (12*npcol + 3*nb)
480 IF( laf .LT. laf_min )
THEN
485 $
'PCPTTRF: auxiliary storage error ',
492 work_size_min = 8*npcol
494 work( 1 ) = work_size_min
496 IF( lwork .LT. work_size_min )
THEN
497 IF( lwork .NE. -1 )
THEN
500 $
'PCPTTRF: worksize error ',
508 param_check( 7, 1 ) = desca(5)
509 param_check( 6, 1 ) = desca(4)
510 param_check( 5, 1 ) = desca(3)
511 param_check( 4, 1 ) = desca(1)
512 param_check( 3, 1 ) = ja
513 param_check( 2, 1 ) = n
514 param_check( 1, 1 ) = idum3
516 param_check( 7, 2 ) = 505
517 param_check( 6, 2 ) = 504
518 param_check( 5, 2 ) = 503
519 param_check( 4, 2 ) = 501
520 param_check( 3, 2 ) = 4
521 param_check( 2, 2 ) = 1
522 param_check( 1, 2 ) = 9
530 ELSE IF( info.LT.-descmult )
THEN
533 info = -info * descmult
538 CALL globchk( ictxt, 7, param_check, 7,
539 $ param_check( 1, 3 ), info )
544 IF( info.EQ.bignum )
THEN
546 ELSE IF( mod( info, descmult ) .EQ. 0 )
THEN
547 info = -info / descmult
553 CALL pxerbla( ictxt,
'PCPTTRF', -info )
566 part_offset = nb*( (ja-1)/(npcol*nb) )
568 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb )
THEN
569 part_offset = part_offset + nb
572 IF ( mycol .LT. csrc )
THEN
573 part_offset = part_offset - nb
582 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
586 ja_new = mod( ja-1, nb ) + 1
591 np = ( ja_new+n-2 )/nb + 1
595 CALL reshape( ictxt, int_one, ictxt_new, int_one,
596 $ first_proc, int_one, np )
602 desca_1xp( 2 ) = ictxt_new
606 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
610 IF( myrow .LT. 0 )
THEN
623 my_num_cols = numroc( n, part_size, mycol, 0, npcol )
627 IF ( mycol .EQ. 0 )
THEN
628 part_offset = part_offset+mod( ja_new-1, part_size )
629 my_num_cols = my_num_cols - mod(ja_new-1, part_size )
634 odd_size = my_num_cols
635 IF ( mycol .LT. np-1 )
THEN
636 odd_size = odd_size - int_one
654 IF ( mycol .LT. np-1 )
THEN
660 CALL ctrsd2d( ictxt,
'U',
'N', 1, 1,
661 $ e( part_offset+odd_size+1 ), llda-1, 0,
670 CALL cpttrf( odd_size, d( part_offset+1 ), e( part_offset+1 ),
679 IF ( mycol .LT. np-1 )
THEN
686 e( part_offset+odd_size ) = e( part_offset+odd_size )/
687 $ d( part_offset+odd_size )
694 d( part_offset+odd_size+1 ) = d( part_offset+odd_size+1 )-
695 $ d( part_offset+odd_size )*real( e( part_offset+odd_size )*
696 $ conjg( e( part_offset+odd_size ) ) )
705 IF ( mycol .NE. 0 )
THEN
712 CALL ctrrv2d( ictxt,
'U',
'N', 1, 1, af( 1 ), odd_size, 0,
719 CALL cpttrsv(
'L',
'N', odd_size, int_one, d( part_offset+1 ),
720 $ e( part_offset+1 ), af( 1 ), odd_size, info )
725 af( i ) = af( i )/d( part_offset+i )
735 int_temp = odd_size*int_one+2+1
739 af( int_temp ) = af( int_temp )-d( part_offset+i )*
740 $ ( af( i )*conjg( af( i ) ) )
747 CALL cgesd2d( ictxt, int_one, int_one, af( odd_size+3 ),
748 $ int_one, 0, mycol-1 )
751 IF ( mycol .LT. np-1 )
THEN
759 $ - d( part_offset+odd_size )
760 $ * conjg( e( part_offset+odd_size )
775 CALL igamx2d( ictxt,
'A',
' ', 1, 1, info, 1, info, info,
778 IF( mycol.EQ.0 )
THEN
779 CALL igebs2d( ictxt,
'A',
' ', 1, 1, info, 1 )
781 CALL igebr2d( ictxt,
'A',
' ', 1, 1, info, 1, 0, 0 )
784 IF ( info.NE.0 )
THEN
799 IF( mycol .EQ. npcol-1 )
THEN
807 IF( (mod( mycol+1, 2 ) .EQ. 0) .AND. ( mycol .GT. 0 ) )
THEN
809 CALL cgesd2d( ictxt, int_one, int_one,
811 $ int_one, 0, mycol-1 )
819 $
cmplx( d( part_offset+odd_size+1 ) )
823 IF( mycol.LT. npcol-1 )
THEN
825 CALL cgerv2d( ictxt, int_one, int_one,
826 $ af( odd_size+2+1 ),
832 af( odd_size+2 ) = af( odd_size+2 )+af( odd_size+3 )
847 IF( mod( (mycol+1)/level_dist, 2) .NE. 0 )
GOTO 11
851 IF( mycol-level_dist .GE. 0 )
THEN
852 CALL cgerv2d( ictxt, int_one, int_one, work( 1 ),
853 $ int_one, 0, mycol-level_dist )
855 af( odd_size+2 ) = af( odd_size+2 )+work( 1 )
861 IF( mycol+level_dist .LT. npcol-1 )
THEN
862 CALL cgerv2d( ictxt, int_one, int_one, work( 1 ),
863 $ int_one, 0, mycol+level_dist )
865 af( odd_size+2 ) = af( odd_size+2 )+work( 1 )
869 level_dist = level_dist*2
878 IF( af( odd_size+2 ) .EQ. czero )
THEN
887 IF( level_dist .EQ. 1 )
THEN
888 comm_proc = mycol + 1
893 af( odd_size+3 ) = af( odd_size+1 )
896 comm_proc = mycol + level_dist/2
899 IF( mycol/level_dist .LE. (npcol-1)/level_dist-2 )
THEN
901 CALL cgerv2d( ictxt, int_one, int_one,
903 $ int_one, 0, comm_proc )
905 IF( info .EQ. 0 )
THEN
911 af( odd_size+1 ) = af( odd_size+1 )/af( odd_size+2 )
918 work( 1 ) = -one*af( odd_size+1 )*af( odd_size+2 )
919 $ *conjg( af( odd_size+1 ) )
923 CALL cgesd2d( ictxt, int_one, int_one, work( 1 ), int_one,
924 $ 0, mycol+level_dist )
934 IF( (mycol/level_dist .GT. 0 ).AND.
935 $ ( mycol/level_dist .LE. (npcol-1)/level_dist-1 ) )
THEN
937 IF( level_dist .GT. 1)
THEN
942 CALL cgerv2d( ictxt, int_one, int_one,
943 $ af( odd_size+2+1 ),
944 $ int_one, 0, mycol-level_dist/2 )
953 af( odd_size+3 ) = ( af( odd_size+3 ) )
962 work( 1 ) = -one*af( odd_size+3 )*af( odd_size+2 )
963 $ *conjg( af( odd_size+3 ) )
967 CALL cgesd2d( ictxt, int_one, int_one, work( 1 ), int_one,
968 $ 0, mycol-level_dist )
972 IF( mycol/level_dist .LE. (npcol-1)/level_dist-2 )
THEN
976 IF( ( mod( mycol/( 2*level_dist ),2 )) .EQ.0 )
THEN
977 comm_proc = mycol + level_dist
979 comm_proc = mycol - level_dist
986 work( 1 ) = -one*af( odd_size+3 )
992 CALL cgesd2d( ictxt, int_one, int_one, work( 1 ), int_one,
1008 IF( ictxt_save .NE. ictxt_new )
THEN
1009 CALL blacs_gridexit( ictxt_new )
1021 work( 1 ) = work_size_min
1025 CALL igamx2d( ictxt,
'A',
' ', 1, 1, info, 1, info, info,
1028 IF( mycol.EQ.0 )
THEN
1029 CALL igebs2d( ictxt,
'A',
' ', 1, 1, info, 1 )
1031 CALL igebr2d( ictxt,
'A',
' ', 1, 1, info, 1, 0, 0 )