1 SUBROUTINE pzpttrf( N, D, E, JA, DESCA, AF, LAF, WORK, LWORK,
9 INTEGER INFO, JA, LAF, LWORK, N
13 COMPLEX*16 AF( * ), E( * ), WORK( * )
14 DOUBLE PRECISION D( * )
351 DOUBLE PRECISION ONE, ZERO
352 parameter( one = 1.0d+0 )
353 parameter( zero = 0.0d+0 )
354 COMPLEX*16 CONE, CZERO
355 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
356 parameter( czero = ( 0.0d+0, 0.0d+0 ) )
358 parameter( int_one = 1 )
359 INTEGER DESCMULT, BIGNUM
360 parameter(descmult = 100, bignum = descmult * descmult)
361 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
362 $ lld_, mb_, m_, nb_, n_, rsrc_
363 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
364 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
365 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
368 INTEGER COMM_PROC, CSRC, FIRST_PROC, I, ICTXT,
369 $ ictxt_new, ictxt_save, idum3, int_temp, ja_new,
370 $ laf_min, level_dist, llda, mycol, myrow,
371 $ my_num_cols, nb, np, npcol, nprow, np_save,
372 $ odd_size, part_offset, part_size, return_code,
373 $ store_n_a, temp, work_size_min
376 INTEGER DESCA_1XP( 7 ), PARAM_CHECK( 7, 3 )
379 EXTERNAL blacs_get, blacs_gridexit, blacs_gridinfo,
381 $ zgemm, zgerv2d, zgesd2d, zlamov,
zlatcpy,
382 $ zpbtrf, zpotrf, zsyrk, ztbtrs, ztrmm, ztrrv2d,
383 $ ztrsd2d, ztrsm, ztrtrs
388 EXTERNAL lsame, numroc
391 INTRINSIC ichar,
min, mod
404 temp = desca( dtype_ )
405 IF( temp .EQ. 502 )
THEN
407 desca( dtype_ ) = 501
412 desca( dtype_ ) = temp
414 IF( return_code .NE. 0)
THEN
415 info = -( 5*100 + 2 )
420 ictxt = desca_1xp( 2 )
421 csrc = desca_1xp( 5 )
423 llda = desca_1xp( 6 )
424 store_n_a = desca_1xp( 3 )
429 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
434 IF( lwork .LT. -1)
THEN
436 ELSE IF ( lwork .EQ. -1 )
THEN
446 IF( n+ja-1 .GT. store_n_a )
THEN
447 info = -( 5*100 + 6 )
452 IF( nprow .NE. 1 )
THEN
456 IF( n .GT. np*nb-mod( ja-1, nb ))
THEN
459 $
'PZPTTRF, D&C alg.: only 1 block per proc',
464 IF((ja+n-1.GT.nb) .AND. ( nb.LT.2*int_one ))
THEN
467 $
'PZPTTRF, D&C alg.: NB too small',
475 laf_min = (12*npcol + 3*nb)
477 IF( laf .LT. laf_min )
THEN
482 $
'PZPTTRF: auxiliary storage error ',
489 work_size_min = 8*npcol
491 work( 1 ) = work_size_min
493 IF( lwork .LT. work_size_min )
THEN
494 IF( lwork .NE. -1 )
THEN
497 $
'PZPTTRF: worksize error ',
505 param_check( 7, 1 ) = desca(5)
506 param_check( 6, 1 ) = desca(4)
507 param_check( 5, 1 ) = desca(3)
508 param_check( 4, 1 ) = desca(1)
509 param_check( 3, 1 ) = ja
510 param_check( 2, 1 ) = n
511 param_check( 1, 1 ) = idum3
513 param_check( 7, 2 ) = 505
514 param_check( 6, 2 ) = 504
515 param_check( 5, 2 ) = 503
516 param_check( 4, 2 ) = 501
517 param_check( 3, 2 ) = 4
518 param_check( 2, 2 ) = 1
519 param_check( 1, 2 ) = 9
527 ELSE IF( info.LT.-descmult )
THEN
530 info = -info * descmult
535 CALL globchk( ictxt, 7, param_check, 7,
536 $ param_check( 1, 3 ), info )
541 IF( info.EQ.bignum )
THEN
543 ELSE IF( mod( info, descmult ) .EQ. 0 )
THEN
544 info = -info / descmult
550 CALL pxerbla( ictxt,
'PZPTTRF', -info )
563 part_offset = nb*( (ja-1)/(npcol*nb) )
565 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb )
THEN
566 part_offset = part_offset + nb
569 IF ( mycol .LT. csrc )
THEN
570 part_offset = part_offset - nb
579 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
583 ja_new = mod( ja-1, nb ) + 1
588 np = ( ja_new+n-2 )/nb + 1
592 CALL reshape( ictxt, int_one, ictxt_new, int_one,
593 $ first_proc, int_one, np )
599 desca_1xp( 2 ) = ictxt_new
603 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
607 IF( myrow .LT. 0 )
THEN
620 my_num_cols = numroc( n, part_size, mycol, 0, npcol )
624 IF ( mycol .EQ. 0 )
THEN
625 part_offset = part_offset+mod( ja_new-1, part_size )
626 my_num_cols = my_num_cols - mod(ja_new-1, part_size )
631 odd_size = my_num_cols
632 IF ( mycol .LT. np-1 )
THEN
633 odd_size = odd_size - int_one
651 IF ( mycol .LT. np-1 )
THEN
657 CALL ztrsd2d( ictxt,
'U',
'N', 1, 1,
658 $ e( part_offset+odd_size+1 ), llda-1, 0,
667 CALL zpttrf( odd_size, d( part_offset+1 ), e( part_offset+1 ),
676 IF ( mycol .LT. np-1 )
THEN
683 e( part_offset+odd_size ) = e( part_offset+odd_size )/
684 $ d( part_offset+odd_size )
691 d( part_offset+odd_size+1 ) = d( part_offset+odd_size+1 )-
692 $ d( part_offset+odd_size )*dble( e( part_offset+odd_size )*
693 $ dconjg( e( part_offset+odd_size ) ) )
702 IF ( mycol .NE. 0 )
THEN
709 CALL ztrrv2d( ictxt,
'U',
'N', 1, 1, af( 1 ), odd_size, 0,
716 CALL zpttrsv(
'L',
'N', odd_size, int_one, d( part_offset+1 ),
717 $ e( part_offset+1 ), af( 1 ), odd_size, info )
722 af( i ) = af( i )/d( part_offset+i )
732 int_temp = odd_size*int_one+2+1
736 af( int_temp ) = af( int_temp )-d( part_offset+i )*
737 $ ( af( i )*dconjg( af( i ) ) )
744 CALL zgesd2d( ictxt, int_one, int_one, af( odd_size+3 ),
745 $ int_one, 0, mycol-1 )
748 IF ( mycol .LT. np-1 )
THEN
756 $ - d( part_offset+odd_size )
757 $ * dconjg( e( part_offset+odd_size )
772 CALL igamx2d( ictxt,
'A',
' ', 1, 1, info, 1, info, info,
775 IF( mycol.EQ.0 )
THEN
776 CALL igebs2d( ictxt,
'A',
' ', 1, 1, info, 1 )
778 CALL igebr2d( ictxt,
'A',
' ', 1, 1, info, 1, 0, 0 )
781 IF ( info.NE.0 )
THEN
796 IF( mycol .EQ. npcol-1 )
THEN
804 IF( (mod( mycol+1, 2 ) .EQ. 0) .AND. ( mycol .GT. 0 ) )
THEN
806 CALL zgesd2d( ictxt, int_one, int_one,
808 $ int_one, 0, mycol-1 )
816 $ dcmplx( d( part_offset+odd_size+1 ) )
820 IF( mycol.LT. npcol-1 )
THEN
822 CALL zgerv2d( ictxt, int_one, int_one,
823 $ af( odd_size+2+1 ),
829 af( odd_size+2 ) = af( odd_size+2 )+af( odd_size+3 )
844 IF( mod( (mycol+1)/level_dist, 2) .NE. 0 )
GOTO 11
848 IF( mycol-level_dist .GE. 0 )
THEN
849 CALL zgerv2d( ictxt, int_one, int_one, work( 1 ),
850 $ int_one, 0, mycol-level_dist )
852 af( odd_size+2 ) = af( odd_size+2 )+work( 1 )
858 IF( mycol+level_dist .LT. npcol-1 )
THEN
859 CALL zgerv2d( ictxt, int_one, int_one, work( 1 ),
860 $ int_one, 0, mycol+level_dist )
862 af( odd_size+2 ) = af( odd_size+2 )+work( 1 )
866 level_dist = level_dist*2
875 IF( af( odd_size+2 ) .EQ. czero )
THEN
884 IF( level_dist .EQ. 1 )
THEN
885 comm_proc = mycol + 1
890 af( odd_size+3 ) = af( odd_size+1 )
893 comm_proc = mycol + level_dist/2
896 IF( mycol/level_dist .LE. (npcol-1)/level_dist-2 )
THEN
898 CALL zgerv2d( ictxt, int_one, int_one,
900 $ int_one, 0, comm_proc )
902 IF( info .EQ. 0 )
THEN
908 af( odd_size+1 ) = af( odd_size+1 )/af( odd_size+2 )
915 work( 1 ) = -one*af( odd_size+1 )*af( odd_size+2 )
916 $ *dconjg( af( odd_size+1 ) )
920 CALL zgesd2d( ictxt, int_one, int_one, work( 1 ), int_one,
921 $ 0, mycol+level_dist )
931 IF( (mycol/level_dist .GT. 0 ).AND.
932 $ ( mycol/level_dist .LE. (npcol-1)/level_dist-1 ) )
THEN
934 IF( level_dist .GT. 1)
THEN
939 CALL zgerv2d( ictxt, int_one, int_one,
940 $ af( odd_size+2+1 ),
941 $ int_one, 0, mycol-level_dist/2 )
950 af( odd_size+3 ) = ( af( odd_size+3 ) )
959 work( 1 ) = -one*af( odd_size+3 )*af( odd_size+2 )
960 $ *dconjg( af( odd_size+3 ) )
964 CALL zgesd2d( ictxt, int_one, int_one, work( 1 ), int_one,
965 $ 0, mycol-level_dist )
969 IF( mycol/level_dist .LE. (npcol-1)/level_dist-2 )
THEN
973 IF( ( mod( mycol/( 2*level_dist ),2 )) .EQ.0 )
THEN
974 comm_proc = mycol + level_dist
976 comm_proc = mycol - level_dist
983 work( 1 ) = -one*af( odd_size+3 )
989 CALL zgesd2d( ictxt, int_one, int_one, work( 1 ), int_one,
1005 IF( ictxt_save .NE. ictxt_new )
THEN
1006 CALL blacs_gridexit( ictxt_new )
1018 work( 1 ) = work_size_min
1022 CALL igamx2d( ictxt,
'A',
' ', 1, 1, info, 1, info, info,
1025 IF( mycol.EQ.0 )
THEN
1026 CALL igebs2d( ictxt,
'A',
' ', 1, 1, info, 1 )
1028 CALL igebr2d( ictxt,
'A',
' ', 1, 1, info, 1, 0, 0 )