3
    4
    5
    6
    7
    8
    9
   10      CHARACTER          TRANS, UPLO
   11      INTEGER            IB, INFO, JA, LAF, LWORK, N, NRHS
   12
   13
   14      INTEGER            DESCA( * ), DESCB( * )
   15      REAL               AF( * ), B( * ), D( * ), DL( * ), DU( * ),
   16     $                   WORK( * )
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235
  236
  237
  238
  239
  240
  241
  242
  243
  244
  245
  246
  247
  248
  249
  250
  251
  252
  253
  254
  255
  256
  257
  258
  259
  260
  261
  262
  263
  264
  265
  266
  267
  268
  269
  270
  271
  272
  273
  274
  275
  276
  277
  278
  279
  280
  281
  282
  283
  284
  285
  286
  287
  288
  289
  290
  291
  292
  293
  294
  295
  296
  297
  298
  299
  300
  301
  302
  303
  304
  305
  306
  307
  308
  309
  310
  311
  312
  313
  314
  315
  316
  317
  318
  319
  320
  321
  322
  323
  324
  325
  326
  327
  328
  329
  330
  331
  332
  333
  334
  335
  336
  337
  338
  339
  340
  341
  342
  343
  344
  345
  346
  347
  348
  349
  350
  351
  352
  353
  354
  355
  356
  357
  358
  359
  360
  361
  362
  363
  364
  365
  366
  367
  368
  369
  370
  371
  372
  373
  374
  375
  376
  377
  378
  379
  380
  381
  382
  383
  384
  385
  386      REAL               ONE
  387      parameter( one = 1.0e+0 )
  388      REAL               ZERO
  389      parameter( zero = 0.0e+0 )
  390      INTEGER            INT_ONE
  391      parameter( int_one = 1 )
  392      INTEGER            DESCMULT, BIGNUM
  393      parameter( descmult = 100, bignum = descmult*descmult )
  394      INTEGER            BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
  395     $                   LLD_, MB_, M_, NB_, N_, RSRC_
  396      parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
  397     $                     ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
  398     $                     rsrc_ = 7, csrc_ = 8, lld_ = 9 )
  399
  400
  401      INTEGER            CSRC, FIRST_PROC, ICTXT, ICTXT_NEW, ICTXT_SAVE,
  402     $                   IDUM1, IDUM2, IDUM3, JA_NEW, LEVEL_DIST, LLDA,
  403     $                   LLDB, MYCOL, MYROW, MY_NUM_COLS, NB, NP, NPCOL,
  404     $                   NPROW, NP_SAVE, ODD_SIZE, PART_OFFSET,
  405     $                   PART_SIZE, RETURN_CODE, STORE_M_B, STORE_N_A,
  406     $                   TEMP, WORK_SIZE_MIN, WORK_U
  407
  408
  409      INTEGER            DESCA_1XP( 7 ), DESCB_PX1( 7 ),
  410     $                   PARAM_CHECK( 16, 3 )
  411
  412
  415     $                   sgemm, sgerv2d, sgesd2d, 
smatadd, stbtrs
 
  416
  417
  418      LOGICAL            LSAME
  419      INTEGER            NUMROC
  421
  422
  423      INTRINSIC          ichar, 
min, mod
 
  424
  425
  426
  427
  428
  429      info = 0
  430
  431
  432
  433
  434      desca_1xp( 1 ) = 501
  435      descb_px1( 1 ) = 502
  436
  437      temp = desca( dtype_ )
  438      IF( temp.EQ.502 ) THEN
  439
  440         desca( dtype_ ) = 501
  441      END IF
  442
  444
  445      desca( dtype_ ) = temp
  446
  447      IF( return_code.NE.0 ) THEN
  448         info = -( 9*100+2 )
  449      END IF
  450
  452
  453      IF( return_code.NE.0 ) THEN
  454         info = -( 12*100+2 )
  455      END IF
  456
  457
  458
  459
  460      IF( desca_1xp( 2 ).NE.descb_px1( 2 ) ) THEN
  461         info = -( 12*100+2 )
  462      END IF
  463
  464
  465
  466
  467
  468      IF( desca_1xp( 4 ).NE.descb_px1( 4 ) ) THEN
  469         info = -( 12*100+4 )
  470      END IF
  471
  472
  473
  474      IF( desca_1xp( 5 ).NE.descb_px1( 5 ) ) THEN
  475         info = -( 12*100+5 )
  476      END IF
  477
  478
  479
  480      ictxt = desca_1xp( 2 )
  481      csrc = desca_1xp( 5 )
  482      nb = desca_1xp( 4 )
  483      llda = desca_1xp( 6 )
  484      store_n_a = desca_1xp( 3 )
  485      lldb = descb_px1( 6 )
  486      store_m_b = descb_px1( 3 )
  487
  488
  489
  490
  491      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
  492      np = nprow*npcol
  493
  494
  495
  496      IF( 
lsame( uplo, 
'U' ) ) 
THEN 
  497         idum1 = ichar( 'U' )
  498      ELSE IF( 
lsame( uplo, 
'L' ) ) 
THEN 
  499         idum1 = ichar( 'L' )
  500      ELSE
  501         info = -1
  502      END IF
  503
  504      IF( 
lsame( trans, 
'N' ) ) 
THEN 
  505         idum2 = ichar( 'N' )
  506      ELSE IF( 
lsame( trans, 
'T' ) ) 
THEN 
  507         idum2 = ichar( 'T' )
  508      ELSE IF( 
lsame( trans, 
'C' ) ) 
THEN 
  509         idum2 = ichar( 'T' )
  510      ELSE
  511         info = -2
  512      END IF
  513
  514      IF( lwork.LT.-1 ) THEN
  515         info = -16
  516      ELSE IF( lwork.EQ.-1 ) THEN
  517         idum3 = -1
  518      ELSE
  519         idum3 = 1
  520      END IF
  521
  522      IF( n.LT.0 ) THEN
  523         info = -3
  524      END IF
  525
  526      IF( n+ja-1.GT.store_n_a ) THEN
  527         info = -( 9*100+6 )
  528      END IF
  529
  530      IF( n+ib-1.GT.store_m_b ) THEN
  531         info = -( 12*100+3 )
  532      END IF
  533
  534      IF( lldb.LT.nb ) THEN
  535         info = -( 12*100+6 )
  536      END IF
  537
  538      IF( nrhs.LT.0 ) THEN
  539         info = -4
  540      END IF
  541
  542
  543
  544      IF( ja.NE.ib ) THEN
  545         info = -8
  546      END IF
  547
  548
  549
  550      IF( nprow.NE.1 ) THEN
  551         info = -( 9*100+2 )
  552      END IF
  553
  554      IF( n.GT.np*nb-mod( ja-1, nb ) ) THEN
  555         info = -( 3 )
  557     $                 'PSDTTRSV, D&C alg.: only 1 block per proc',
  558     $                 -info )
  559         RETURN
  560      END IF
  561
  562      IF( ( ja+n-1.GT.nb ) .AND. ( nb.LT.2*int_one ) ) THEN
  563         info = -( 9*100+4 )
  564         CALL pxerbla( ictxt, 
'PSDTTRSV, D&C alg.: NB too small',
 
  565     $                 -info )
  566         RETURN
  567      END IF
  568
  569
  570      work_size_min = int_one*nrhs
  571
  572      work( 1 ) = work_size_min
  573
  574      IF( lwork.LT.work_size_min ) THEN
  575         IF( lwork.NE.-1 ) THEN
  576            info = -16
  577            CALL pxerbla( ictxt, 
'PSDTTRSV: worksize error', -info )
 
  578         END IF
  579         RETURN
  580      END IF
  581
  582
  583
  584      param_check( 16, 1 ) = descb( 5 )
  585      param_check( 15, 1 ) = descb( 4 )
  586      param_check( 14, 1 ) = descb( 3 )
  587      param_check( 13, 1 ) = descb( 2 )
  588      param_check( 12, 1 ) = descb( 1 )
  589      param_check( 11, 1 ) = ib
  590      param_check( 10, 1 ) = desca( 5 )
  591      param_check( 9, 1 ) = desca( 4 )
  592      param_check( 8, 1 ) = desca( 3 )
  593      param_check( 7, 1 ) = desca( 1 )
  594      param_check( 6, 1 ) = ja
  595      param_check( 5, 1 ) = nrhs
  596      param_check( 4, 1 ) = n
  597      param_check( 3, 1 ) = idum3
  598      param_check( 2, 1 ) = idum2
  599      param_check( 1, 1 ) = idum1
  600
  601      param_check( 16, 2 ) = 1205
  602      param_check( 15, 2 ) = 1204
  603      param_check( 14, 2 ) = 1203
  604      param_check( 13, 2 ) = 1202
  605      param_check( 12, 2 ) = 1201
  606      param_check( 11, 2 ) = 11
  607      param_check( 10, 2 ) = 905
  608      param_check( 9, 2 ) = 904
  609      param_check( 8, 2 ) = 903
  610      param_check( 7, 2 ) = 901
  611      param_check( 6, 2 ) = 8
  612      param_check( 5, 2 ) = 4
  613      param_check( 4, 2 ) = 3
  614      param_check( 3, 2 ) = 16
  615      param_check( 2, 2 ) = 2
  616      param_check( 1, 2 ) = 1
  617
  618
  619
  620
  621
  622      IF( info.GE.0 ) THEN
  623         info = bignum
  624      ELSE IF( info.LT.-descmult ) THEN
  625         info = -info
  626      ELSE
  627         info = -info*descmult
  628      END IF
  629
  630
  631
  632      CALL globchk( ictxt, 16, param_check, 16, param_check( 1, 3 ),
 
  633     $              info )
  634
  635
  636
  637
  638      IF( info.EQ.bignum ) THEN
  639         info = 0
  640      ELSE IF( mod( info, descmult ).EQ.0 ) THEN
  641         info = -info / descmult
  642      ELSE
  643         info = -info
  644      END IF
  645
  646      IF( info.LT.0 ) THEN
  647         CALL pxerbla( ictxt, 
'PSDTTRSV', -info )
 
  648         RETURN
  649      END IF
  650
  651
  652
  653      IF( n.EQ.0 )
  654     $   RETURN
  655
  656      IF( nrhs.EQ.0 )
  657     $   RETURN
  658
  659
  660
  661
  662
  663      part_offset = nb*( ( ja-1 ) / ( npcol*nb ) )
  664
  665      IF( ( mycol-csrc ).LT.( ja-part_offset-1 ) / nb ) THEN
  666         part_offset = part_offset + nb
  667      END IF
  668
  669      IF( mycol.LT.csrc ) THEN
  670         part_offset = part_offset - nb
  671      END IF
  672
  673
  674
  675
  676
  677
  678
  679      first_proc = mod( ( ja-1 ) / nb+csrc, npcol )
  680
  681
  682
  683      ja_new = mod( ja-1, nb ) + 1
  684
  685
  686
  687      np_save = np
  688      np = ( ja_new+n-2 ) / nb + 1
  689
  690
  691
  692      CALL reshape( ictxt, int_one, ictxt_new, int_one, first_proc,
 
  693     $              int_one, np )
  694
  695
  696
  697      ictxt_save = ictxt
  698      ictxt = ictxt_new
  699      desca_1xp( 2 ) = ictxt_new
  700      descb_px1( 2 ) = ictxt_new
  701
  702
  703
  704      CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
  705
  706
  707
  708      IF( myrow.LT.0 ) THEN
  709         GO TO 180
  710      END IF
  711
  712
  713
  714
  715
  716
  717      part_size = nb
  718
  719
  720
  721      my_num_cols = 
numroc( n, part_size, mycol, 0, npcol )
 
  722
  723
  724
  725      IF( mycol.EQ.0 ) THEN
  726         part_offset = part_offset + mod( ja_new-1, part_size )
  727         my_num_cols = my_num_cols - mod( ja_new-1, part_size )
  728      END IF
  729
  730
  731
  732      odd_size = my_num_cols
  733      IF( mycol.LT.np-1 ) THEN
  734         odd_size = odd_size - int_one
  735      END IF
  736
  737
  738
  739      work_u = int_one*odd_size + 3
  740
  741
  742
  743
  744
  745      IF( 
lsame( uplo, 
'L' ) ) 
THEN 
  746
  747         IF( 
lsame( trans, 
'N' ) ) 
THEN 
  748
  749
  750
  751
  752
  753
  754
  755
  756
  757
  758            CALL sdttrsv( uplo, 
'N', odd_size, nrhs,
 
  759     $                    dl( part_offset+2 ), d( part_offset+1 ),
  760     $                    du( part_offset+1 ), b( part_offset+1 ), lldb,
  761     $                    info )
  762
  763
  764            IF( mycol.LT.np-1 ) THEN
  765
  766
  767
  768               CALL saxpy( nrhs, -dl( part_offset+odd_size+1 ),
  769     $                     b( part_offset+odd_size ), lldb,
  770     $                     b( part_offset+odd_size+1 ), lldb )
  771
  772            END IF
  773
  774
  775            IF( mycol.NE.0 ) THEN
  776
  777
  778
  779               CALL sgemm( 'T', 'N', int_one, nrhs, odd_size, -one,
  780     $                     af( 1 ), odd_size, b( part_offset+1 ), lldb,
  781     $                     zero, work( 1+int_one-int_one ), int_one )
  782            END IF
  783
  784
  785
  786
  787
  788
  789
  790
  791
  792            IF( mycol.GT.0 ) THEN
  793
  794               CALL sgesd2d( ictxt, int_one, nrhs, work( 1 ), int_one,
  795     $                       0, mycol-1 )
  796
  797            END IF
  798
  799
  800
  801            IF( mycol.LT.npcol-1 ) THEN
  802
  803               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
  804     $                       0, mycol+1 )
  805
  806
  807
  808               CALL smatadd( int_one, nrhs, one, work( 1 ), int_one,
 
  809     $                       one, b( part_offset+odd_size+1 ), lldb )
  810
  811            END IF
  812
  813
  814
  815
  816            IF( mycol.EQ.npcol-1 ) THEN
  817               GO TO 30
  818            END IF
  819
  820
  821
  822
  823
  824
  825
  826            level_dist = 1
  827
  828
  829
  830   10       CONTINUE
  831            IF( mod( ( mycol+1 ) / level_dist, 2 ).NE.0 )
  832     $         GO TO 20
  833
  834
  835
  836            IF( mycol-level_dist.GE.0 ) THEN
  837
  838               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
  839     $                       0, mycol-level_dist )
  840
  841               CALL smatadd( int_one, nrhs, one, work( 1 ), int_one,
 
  842     $                       one, b( part_offset+odd_size+1 ), lldb )
  843
  844            END IF
  845
  846
  847
  848            IF( mycol+level_dist.LT.npcol-1 ) THEN
  849
  850               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
  851     $                       0, mycol+level_dist )
  852
  853               CALL smatadd( int_one, nrhs, one, work( 1 ), int_one,
 
  854     $                       one, b( part_offset+odd_size+1 ), lldb )
  855
  856            END IF
  857
  858            level_dist = level_dist*2
  859
  860            GO TO 10
  861   20       CONTINUE
  862
  863
  864
  865
  866
  867
  868
  869
  870
  871            CALL stbtrs( 'L', 'N', 'U', int_one,
  872     $                   
min( int_one, int_one-1 ), nrhs,
 
  873     $                   af( odd_size+2 ), int_one+1,
  874     $                   b( part_offset+odd_size+1 ), lldb, info )
  875
  876            IF( info.NE.0 ) THEN
  877               GO TO 170
  878            END IF
  879
  880
  881
  882
  883            IF( mycol / level_dist.LE.( npcol-1 ) / level_dist-2 ) THEN
  884
  885
  886
  887               CALL sgemm( 'T', 'N', int_one, nrhs, int_one, -one,
  888     $                     af( ( odd_size )*int_one+1 ), int_one,
  889     $                     b( part_offset+odd_size+1 ), lldb, zero,
  890     $                     work( 1 ), int_one )
  891
  892
  893
  894               CALL sgesd2d( ictxt, int_one, nrhs, work( 1 ), int_one,
  895     $                       0, mycol+level_dist )
  896
  897            END IF
  898
  899
  900
  901            IF( ( mycol / level_dist.GT.0 ) .AND.
  902     $          ( mycol / level_dist.LE.( npcol-1 ) / level_dist-1 ) )
  903     $           THEN
  904
  905
  906
  907
  908
  909               CALL sgemm( 'N', 'N', int_one, nrhs, int_one, -one,
  910     $                     af( odd_size*int_one+2+1 ), int_one,
  911     $                     b( part_offset+odd_size+1 ), lldb, zero,
  912     $                     work( 1 ), int_one )
  913
  914
  915
  916               CALL sgesd2d( ictxt, int_one, nrhs, work( 1 ), int_one,
  917     $                       0, mycol-level_dist )
  918
  919            END IF
  920
  921
  922   30       CONTINUE
  923
  924         ELSE
  925
  926
  927
  928
  929
  930
  931
  932
  933
  934
  935
  936            IF( mycol.EQ.npcol-1 ) THEN
  937               GO TO 80
  938            END IF
  939
  940
  941
  942            level_dist = 1
  943   40       CONTINUE
  944            IF( mod( ( mycol+1 ) / level_dist, 2 ).NE.0 )
  945     $         GO TO 50
  946
  947            level_dist = level_dist*2
  948
  949            GO TO 40
  950   50       CONTINUE
  951
  952
  953            IF( ( mycol / level_dist.GT.0 ) .AND.
  954     $          ( mycol / level_dist.LE.( npcol-1 ) / level_dist-1 ) )
  955     $           THEN
  956
  957
  958
  959               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
  960     $                       0, mycol-level_dist )
  961
  962
  963
  964
  965
  966               CALL sgemm( 'T', 'N', int_one, nrhs, int_one, -one,
  967     $                     af( odd_size*int_one+2+1 ), int_one,
  968     $                     work( 1 ), int_one, one,
  969     $                     b( part_offset+odd_size+1 ), lldb )
  970            END IF
  971
  972
  973
  974            IF( mycol / level_dist.LE.( npcol-1 ) / level_dist-2 ) THEN
  975
  976
  977
  978               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
  979     $                       0, mycol+level_dist )
  980
  981
  982
  983               CALL sgemm( 'N', 'N', int_one, nrhs, int_one, -one,
  984     $                     af( ( odd_size )*int_one+1 ), int_one,
  985     $                     work( 1 ), int_one, one,
  986     $                     b( part_offset+odd_size+1 ), lldb )
  987
  988            END IF
  989
  990
  991
  992
  993
  994            CALL stbtrs( 'L', 'T', 'U', int_one,
  995     $                   
min( int_one, int_one-1 ), nrhs,
 
  996     $                   af( odd_size+2 ), int_one+1,
  997     $                   b( part_offset+odd_size+1 ), lldb, info )
  998
  999            IF( info.NE.0 ) THEN
 1000               GO TO 170
 1001            END IF
 1002
 1003
 1004
 1005
 1006
 1007   60       CONTINUE
 1008            IF( level_dist.EQ.1 )
 1009     $         GO TO 70
 1010
 1011            level_dist = level_dist / 2
 1012
 1013
 1014
 1015            IF( mycol+level_dist.LT.npcol-1 ) THEN
 1016
 1017               CALL sgesd2d( ictxt, int_one, nrhs,
 1018     $                       b( part_offset+odd_size+1 ), lldb, 0,
 1019     $                       mycol+level_dist )
 1020
 1021            END IF
 1022
 1023
 1024
 1025            IF( mycol-level_dist.GE.0 ) THEN
 1026
 1027               CALL sgesd2d( ictxt, int_one, nrhs,
 1028     $                       b( part_offset+odd_size+1 ), lldb, 0,
 1029     $                       mycol-level_dist )
 1030
 1031            END IF
 1032
 1033            GO TO 60
 1034   70       CONTINUE
 1035
 1036
 1037   80       CONTINUE
 1038
 1039
 1040
 1041
 1042
 1043
 1044
 1045
 1046
 1047            IF( mycol.LT.npcol-1 ) THEN
 1048
 1049               CALL sgesd2d( ictxt, int_one, nrhs,
 1050     $                       b( part_offset+odd_size+1 ), lldb, 0,
 1051     $                       mycol+1 )
 1052
 1053            END IF
 1054
 1055
 1056
 1057            IF( mycol.GT.0 ) THEN
 1058
 1059               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1060     $                       0, mycol-1 )
 1061
 1062            END IF
 1063
 1064
 1065
 1066
 1067
 1068
 1069
 1070            IF( mycol.NE.0 ) THEN
 1071
 1072
 1073
 1074               CALL sgemm( 'N', 'N', odd_size, nrhs, int_one, -one,
 1075     $                     af( 1 ), odd_size, work( 1+int_one-int_one ),
 1076     $                     int_one, one, b( part_offset+1 ), lldb )
 1077
 1078            END IF
 1079
 1080
 1081            IF( mycol.LT.np-1 ) THEN
 1082
 1083
 1084
 1085               CALL saxpy( nrhs, -( dl( part_offset+odd_size+1 ) ),
 1086     $                     b( part_offset+odd_size+1 ), lldb,
 1087     $                     b( part_offset+odd_size ), lldb )
 1088
 1089            END IF
 1090
 1091
 1092
 1093            CALL sdttrsv( uplo, 
'T', odd_size, nrhs,
 
 1094     $                    dl( part_offset+2 ), d( part_offset+1 ),
 1095     $                    du( part_offset+1 ), b( part_offset+1 ), lldb,
 1096     $                    info )
 1097
 1098         END IF
 1099
 1100
 1101
 1102      ELSE
 1103
 1104
 1105
 1106         IF( 
lsame( trans, 
'T' ) ) 
THEN 
 1107
 1108
 1109
 1110
 1111
 1112
 1113
 1114
 1115
 1116
 1117            CALL sdttrsv( uplo, 
'T', odd_size, nrhs,
 
 1118     $                    dl( part_offset+2 ), d( part_offset+1 ),
 1119     $                    du( part_offset+1 ), b( part_offset+1 ), lldb,
 1120     $                    info )
 1121
 1122
 1123            IF( mycol.LT.np-1 ) THEN
 1124
 1125
 1126
 1127               CALL saxpy( nrhs, -( du( part_offset+odd_size ) ),
 1128     $                     b( part_offset+odd_size ), lldb,
 1129     $                     b( part_offset+odd_size+1 ), lldb )
 1130
 1131            END IF
 1132
 1133
 1134            IF( mycol.NE.0 ) THEN
 1135
 1136
 1137
 1138               CALL sgemm( 'T', 'N', int_one, nrhs, odd_size, -one,
 1139     $                     af( work_u+1 ), odd_size, b( part_offset+1 ),
 1140     $                     lldb, zero, work( 1+int_one-int_one ),
 1141     $                     int_one )
 1142            END IF
 1143
 1144
 1145
 1146
 1147
 1148
 1149
 1150
 1151
 1152            IF( mycol.GT.0 ) THEN
 1153
 1154               CALL sgesd2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1155     $                       0, mycol-1 )
 1156
 1157            END IF
 1158
 1159
 1160
 1161            IF( mycol.LT.npcol-1 ) THEN
 1162
 1163               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1164     $                       0, mycol+1 )
 1165
 1166
 1167
 1168               CALL smatadd( int_one, nrhs, one, work( 1 ), int_one,
 
 1169     $                       one, b( part_offset+odd_size+1 ), lldb )
 1170
 1171            END IF
 1172
 1173
 1174
 1175
 1176            IF( mycol.EQ.npcol-1 ) THEN
 1177               GO TO 110
 1178            END IF
 1179
 1180
 1181
 1182
 1183
 1184
 1185
 1186            level_dist = 1
 1187
 1188
 1189
 1190   90       CONTINUE
 1191            IF( mod( ( mycol+1 ) / level_dist, 2 ).NE.0 )
 1192     $         GO TO 100
 1193
 1194
 1195
 1196            IF( mycol-level_dist.GE.0 ) THEN
 1197
 1198               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1199     $                       0, mycol-level_dist )
 1200
 1201               CALL smatadd( int_one, nrhs, one, work( 1 ), int_one,
 
 1202     $                       one, b( part_offset+odd_size+1 ), lldb )
 1203
 1204            END IF
 1205
 1206
 1207
 1208            IF( mycol+level_dist.LT.npcol-1 ) THEN
 1209
 1210               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1211     $                       0, mycol+level_dist )
 1212
 1213               CALL smatadd( int_one, nrhs, one, work( 1 ), int_one,
 
 1214     $                       one, b( part_offset+odd_size+1 ), lldb )
 1215
 1216            END IF
 1217
 1218            level_dist = level_dist*2
 1219
 1220            GO TO 90
 1221  100       CONTINUE
 1222
 1223
 1224
 1225
 1226
 1227
 1228
 1229
 1230
 1231            CALL stbtrs( 'U', 'T', 'N', int_one,
 1232     $                   
min( int_one, int_one-1 ), nrhs,
 
 1233     $                   af( odd_size+2 ), int_one+1,
 1234     $                   b( part_offset+odd_size+1 ), lldb, info )
 1235
 1236            IF( info.NE.0 ) THEN
 1237               GO TO 170
 1238            END IF
 1239
 1240
 1241
 1242
 1243            IF( mycol / level_dist.LE.( npcol-1 ) / level_dist-2 ) THEN
 1244
 1245
 1246
 1247               CALL sgemm( 'T', 'N', int_one, nrhs, int_one, -one,
 1248     $                     af( work_u+( odd_size )*int_one+1 ), int_one,
 1249     $                     b( part_offset+odd_size+1 ), lldb, zero,
 1250     $                     work( 1 ), int_one )
 1251
 1252
 1253
 1254               CALL sgesd2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1255     $                       0, mycol+level_dist )
 1256
 1257            END IF
 1258
 1259
 1260
 1261            IF( ( mycol / level_dist.GT.0 ) .AND.
 1262     $          ( mycol / level_dist.LE.( npcol-1 ) / level_dist-1 ) )
 1263     $           THEN
 1264
 1265
 1266
 1267
 1268
 1269               CALL sgemm( 'N', 'N', int_one, nrhs, int_one, -one,
 1270     $                     af( work_u+odd_size*int_one+2+1 ), int_one,
 1271     $                     b( part_offset+odd_size+1 ), lldb, zero,
 1272     $                     work( 1 ), int_one )
 1273
 1274
 1275
 1276               CALL sgesd2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1277     $                       0, mycol-level_dist )
 1278
 1279            END IF
 1280
 1281
 1282  110       CONTINUE
 1283
 1284         ELSE
 1285
 1286
 1287
 1288
 1289
 1290
 1291
 1292
 1293
 1294
 1295
 1296            IF( mycol.EQ.npcol-1 ) THEN
 1297               GO TO 160
 1298            END IF
 1299
 1300
 1301
 1302            level_dist = 1
 1303  120       CONTINUE
 1304            IF( mod( ( mycol+1 ) / level_dist, 2 ).NE.0 )
 1305     $         GO TO 130
 1306
 1307            level_dist = level_dist*2
 1308
 1309            GO TO 120
 1310  130       CONTINUE
 1311
 1312
 1313            IF( ( mycol / level_dist.GT.0 ) .AND.
 1314     $          ( mycol / level_dist.LE.( npcol-1 ) / level_dist-1 ) )
 1315     $           THEN
 1316
 1317
 1318
 1319               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1320     $                       0, mycol-level_dist )
 1321
 1322
 1323
 1324
 1325
 1326               CALL sgemm( 'T', 'N', int_one, nrhs, int_one, -one,
 1327     $                     af( work_u+odd_size*int_one+2+1 ), int_one,
 1328     $                     work( 1 ), int_one, one,
 1329     $                     b( part_offset+odd_size+1 ), lldb )
 1330            END IF
 1331
 1332
 1333
 1334            IF( mycol / level_dist.LE.( npcol-1 ) / level_dist-2 ) THEN
 1335
 1336
 1337
 1338               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1339     $                       0, mycol+level_dist )
 1340
 1341
 1342
 1343               CALL sgemm( 'N', 'N', int_one, nrhs, int_one, -one,
 1344     $                     af( work_u+( odd_size )*int_one+1 ), int_one,
 1345     $                     work( 1 ), int_one, one,
 1346     $                     b( part_offset+odd_size+1 ), lldb )
 1347
 1348            END IF
 1349
 1350
 1351
 1352
 1353
 1354            CALL stbtrs( 'U', 'N', 'N', int_one,
 1355     $                   
min( int_one, int_one-1 ), nrhs,
 
 1356     $                   af( odd_size+2 ), int_one+1,
 1357     $                   b( part_offset+odd_size+1 ), lldb, info )
 1358
 1359            IF( info.NE.0 ) THEN
 1360               GO TO 170
 1361            END IF
 1362
 1363
 1364
 1365
 1366
 1367  140       CONTINUE
 1368            IF( level_dist.EQ.1 )
 1369     $         GO TO 150
 1370
 1371            level_dist = level_dist / 2
 1372
 1373
 1374
 1375            IF( mycol+level_dist.LT.npcol-1 ) THEN
 1376
 1377               CALL sgesd2d( ictxt, int_one, nrhs,
 1378     $                       b( part_offset+odd_size+1 ), lldb, 0,
 1379     $                       mycol+level_dist )
 1380
 1381            END IF
 1382
 1383
 1384
 1385            IF( mycol-level_dist.GE.0 ) THEN
 1386
 1387               CALL sgesd2d( ictxt, int_one, nrhs,
 1388     $                       b( part_offset+odd_size+1 ), lldb, 0,
 1389     $                       mycol-level_dist )
 1390
 1391            END IF
 1392
 1393            GO TO 140
 1394  150       CONTINUE
 1395
 1396
 1397  160       CONTINUE
 1398
 1399
 1400
 1401
 1402
 1403
 1404
 1405
 1406
 1407            IF( mycol.LT.npcol-1 ) THEN
 1408
 1409               CALL sgesd2d( ictxt, int_one, nrhs,
 1410     $                       b( part_offset+odd_size+1 ), lldb, 0,
 1411     $                       mycol+1 )
 1412
 1413            END IF
 1414
 1415
 1416
 1417            IF( mycol.GT.0 ) THEN
 1418
 1419               CALL sgerv2d( ictxt, int_one, nrhs, work( 1 ), int_one,
 1420     $                       0, mycol-1 )
 1421
 1422            END IF
 1423
 1424
 1425
 1426
 1427
 1428
 1429
 1430            IF( mycol.NE.0 ) THEN
 1431
 1432
 1433
 1434               CALL sgemm( 'N', 'N', odd_size, nrhs, int_one, -one,
 1435     $                     af( work_u+1 ), odd_size,
 1436     $                     work( 1+int_one-int_one ), int_one, one,
 1437     $                     b( part_offset+1 ), lldb )
 1438
 1439            END IF
 1440
 1441
 1442            IF( mycol.LT.np-1 ) THEN
 1443
 1444
 1445
 1446               CALL saxpy( nrhs, -( du( part_offset+odd_size ) ),
 1447     $                     b( part_offset+odd_size+1 ), lldb,
 1448     $                     b( part_offset+odd_size ), lldb )
 1449
 1450            END IF
 1451
 1452
 1453
 1454            CALL sdttrsv( uplo, 
'N', odd_size, nrhs,
 
 1455     $                    du( part_offset+2 ), d( part_offset+1 ),
 1456     $                    du( part_offset+1 ), b( part_offset+1 ), lldb,
 1457     $                    info )
 1458
 1459         END IF
 1460
 1461
 1462
 1463      END IF
 1464
 1465  170 CONTINUE
 1466
 1467
 1468
 1469
 1470      IF( ictxt_save.NE.ictxt_new ) THEN
 1471         CALL blacs_gridexit( ictxt_new )
 1472      END IF
 1473
 1474  180 CONTINUE
 1475
 1476
 1477
 1478      ictxt = ictxt_save
 1479      np = np_save
 1480
 1481
 1482
 1483      work( 1 ) = work_size_min
 1484
 1485
 1486      RETURN
 1487
 1488
 1489
subroutine desc_convert(desc_in, desc_out, info)
 
integer function numroc(n, nb, iproc, isrcproc, nprocs)
 
subroutine globchk(ictxt, n, x, ldx, iwork, info)
 
subroutine pxerbla(ictxt, srname, info)
 
void reshape(Int *context_in, Int *major_in, Int *context_out, Int *major_out, Int *first_proc, Int *nprow_new, Int *npcol_new)
 
subroutine sdttrsv(uplo, trans, n, nrhs, dl, d, du, b, ldb, info)
 
subroutine smatadd(m, n, alpha, a, lda, beta, c, ldc)