3
4
5
6
7
8
9 INTEGER BWL, BWU, INFO, JA, LAF, LWORK, N
10
11
12 INTEGER DESCA( * )
13 REAL A( * ), AF( * ), WORK( * )
14
15
16
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 REAL ONE
343 parameter( one = 1.0e+0 )
344 REAL ZERO
345 parameter( zero = 0.0e+0 )
346 INTEGER INT_ONE
347 parameter( int_one = 1 )
348 INTEGER DESCMULT, BIGNUM
349 parameter( descmult = 100, bignum = descmult*descmult )
350 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
351 $ LLD_, MB_, M_, NB_, N_, RSRC_
352 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
353 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
354 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
355
356
357 INTEGER COMM_PROC, CSRC, FIRST_PROC, I, I1, I2, ICTXT,
358 $ ICTXT_NEW, ICTXT_SAVE, IDUM3, JA_NEW, LAF_MIN,
359 $ LEVEL_DIST, LLDA, MAX_BW, MBW2, MYCOL, MYROW,
360 $ MY_NUM_COLS, NB, NEXT_TRI_SIZE_M,
361 $ NEXT_TRI_SIZE_N, NP, NPCOL, NPROW, NP_SAVE,
362 $ ODD_SIZE, OFST, PART_OFFSET, PART_SIZE,
363 $ PREV_TRI_SIZE_M, PREV_TRI_SIZE_N, RETURN_CODE,
364 $ STORE_N_A, UP_PREV_TRI_SIZE_M,
365 $ UP_PREV_TRI_SIZE_N, WORK_SIZE_MIN, WORK_U
366
367
368 INTEGER DESCA_1XP( 7 ), PARAM_CHECK( 9, 3 )
369
370
371 EXTERNAL blacs_gridexit, blacs_gridinfo, saxpy,
sdbtrf,
373 $ slamov,
slatcpy, stbtrs, strmm, strrv2d,
374 $ strsd2d,
globchk, igamx2d, igebr2d, igebs2d,
376
377
378 INTEGER NUMROC
380
381
383
384
385
386
387
388 info = 0
389
390
391
392
393 desca_1xp( 1 ) = 501
394
396
397 IF( return_code.NE.0 ) THEN
398 info = -( 6*100+2 )
399 END IF
400
401
402
403 ictxt = desca_1xp( 2 )
404 csrc = desca_1xp( 5 )
405 nb = desca_1xp( 4 )
406 llda = desca_1xp( 6 )
407 store_n_a = desca_1xp( 3 )
408
409
410
411
412
413
414 max_bw =
max( bwl, bwu )
415 mbw2 = max_bw*max_bw
416
417 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
418 np = nprow*npcol
419
420
421
422 IF( lwork.LT.-1 ) THEN
423 info = -10
424 ELSE IF( lwork.EQ.-1 ) THEN
425 idum3 = -1
426 ELSE
427 idum3 = 1
428 END IF
429
430 IF( n.LT.0 ) THEN
431 info = -1
432 END IF
433
434 IF( n+ja-1.GT.store_n_a ) THEN
435 info = -( 6*100+6 )
436 END IF
437
438 IF( ( bwl.GT.n-1 ) .OR. ( bwl.LT.0 ) ) THEN
439 info = -2
440 END IF
441
442 IF( ( bwu.GT.n-1 ) .OR. ( bwu.LT.0 ) ) THEN
443 info = -3
444 END IF
445
446 IF( llda.LT.( bwl+bwu+1 ) ) THEN
447 info = -( 6*100+6 )
448 END IF
449
450 IF( nb.LE.0 ) THEN
451 info = -( 6*100+4 )
452 END IF
453
454
455
456 IF( nprow.NE.1 ) THEN
457 info = -( 6*100+2 )
458 END IF
459
460 IF( n.GT.np*nb-mod( ja-1, nb ) ) THEN
461 info = -( 1 )
462 CALL pxerbla( ictxt,
'PSDBTRF, D&C alg.: only 1 block per proc'
463 $ , -info )
464 RETURN
465 END IF
466
467 IF( ( ja+n-1.GT.nb ) .AND. ( nb.LT.2*
max( bwl, bwu ) ) )
THEN
468 info = -( 6*100+4 )
469 CALL pxerbla( ictxt,
'PSDBTRF, D&C alg.: NB too small', -info )
470 RETURN
471 END IF
472
473
474
475
476 laf_min = nb*( bwl+bwu ) + 6*
max( bwl, bwu )*
max( bwl, bwu )
477
478 IF( laf.LT.laf_min ) THEN
479 info = -8
480
481 af( 1 ) = laf_min
482 CALL pxerbla( ictxt,
'PSDBTRF: auxiliary storage error ',
483 $ -info )
484 RETURN
485 END IF
486
487
488
489 work_size_min =
max( bwl, bwu )*
max( bwl, bwu )
490
491 work( 1 ) = work_size_min
492
493 IF( lwork.LT.work_size_min ) THEN
494 IF( lwork.NE.-1 ) THEN
495 info = -10
496 CALL pxerbla( ictxt,
'PSDBTRF: worksize error ', -info )
497 END IF
498 RETURN
499 END IF
500
501
502
503 param_check( 9, 1 ) = desca( 5 )
504 param_check( 8, 1 ) = desca( 4 )
505 param_check( 7, 1 ) = desca( 3 )
506 param_check( 6, 1 ) = desca( 1 )
507 param_check( 5, 1 ) = ja
508 param_check( 4, 1 ) = bwu
509 param_check( 3, 1 ) = bwl
510 param_check( 2, 1 ) = n
511 param_check( 1, 1 ) = idum3
512
513 param_check( 9, 2 ) = 605
514 param_check( 8, 2 ) = 604
515 param_check( 7, 2 ) = 603
516 param_check( 6, 2 ) = 601
517 param_check( 5, 2 ) = 5
518 param_check( 4, 2 ) = 3
519 param_check( 3, 2 ) = 2
520 param_check( 2, 2 ) = 1
521 param_check( 1, 2 ) = 10
522
523
524
525
526
527 IF( info.GE.0 ) THEN
528 info = bignum
529 ELSE IF( info.LT.-descmult ) THEN
530 info = -info
531 ELSE
532 info = -info*descmult
533 END IF
534
535
536
537 CALL globchk( ictxt, 9, param_check, 9, param_check( 1, 3 ),
538 $ info )
539
540
541
542
543 IF( info.EQ.bignum ) THEN
544 info = 0
545 ELSE IF( mod( info, descmult ).EQ.0 ) THEN
546 info = -info / descmult
547 ELSE
548 info = -info
549 END IF
550
551 IF( info.LT.0 ) THEN
552 CALL pxerbla( ictxt,
'PSDBTRF', -info )
553 RETURN
554 END IF
555
556
557
558 IF( n.EQ.0 )
559 $ RETURN
560
561
562
563
564
565 part_offset = nb*( ( ja-1 ) / ( npcol*nb ) )
566
567 IF( ( mycol-csrc ).LT.( ja-part_offset-1 ) / nb ) THEN
568 part_offset = part_offset + nb
569 END IF
570
571 IF( mycol.LT.csrc ) THEN
572 part_offset = part_offset - nb
573 END IF
574
575
576
577
578
579
580
581 first_proc = mod( ( ja-1 ) / nb+csrc, npcol )
582
583
584
585 ja_new = mod( ja-1, nb ) + 1
586
587
588
589 np_save = np
590 np = ( ja_new+n-2 ) / nb + 1
591
592
593
594 CALL reshape( ictxt, int_one, ictxt_new, int_one, first_proc,
595 $ int_one, np )
596
597
598
599 ictxt_save = ictxt
600 ictxt = ictxt_new
601 desca_1xp( 2 ) = ictxt_new
602
603
604
605 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
606
607
608
609 IF( myrow.LT.0 ) THEN
610 GO TO 140
611 END IF
612
613
614
615
616
617
618 part_size = nb
619
620
621
622 my_num_cols =
numroc( n, part_size, mycol, 0, npcol )
623
624
625
626 IF( mycol.EQ.0 ) THEN
627 part_offset = part_offset + mod( ja_new-1, part_size )
628 my_num_cols = my_num_cols - mod( ja_new-1, part_size )
629 END IF
630
631
632
633 ofst = part_offset*llda
634
635
636
637 odd_size = my_num_cols
638 IF( mycol.LT.np-1 ) THEN
639 odd_size = odd_size - max_bw
640 END IF
641
642
643
644 work_u = bwu*odd_size + 3*mbw2
645
646
647
648
649 DO 10 i = 1, laf_min
650 af( i ) = zero
651 10 CONTINUE
652
653
654
655 DO 20 i = 1, work_size_min
656 work( i ) = zero
657 20 CONTINUE
658
659
660
661
662
663
664
665
666
667
668
669 IF( mycol.GT.0 ) THEN
670 prev_tri_size_m =
min( bwl,
numroc( n, part_size, mycol, 0,
671 $ npcol ) )
672 prev_tri_size_n =
min( bwl,
numroc( n, part_size, mycol-1, 0,
673 $ npcol ) )
674 END IF
675
676 IF( mycol.GT.0 ) THEN
677 up_prev_tri_size_m =
min( bwu,
678 $
numroc( n, part_size, mycol, 0, npcol ) )
679 up_prev_tri_size_n =
min( bwu,
680 $
numroc( n, part_size, mycol-1, 0,
681 $ npcol ) )
682 END IF
683
684 IF( mycol.LT.npcol-1 ) THEN
685 next_tri_size_m =
min( bwl,
numroc( n, part_size, mycol+1, 0,
686 $ npcol ) )
687 next_tri_size_n =
min( bwl,
numroc( n, part_size, mycol, 0,
688 $ npcol ) )
689 END IF
690
691 IF( mycol.LT.np-1 ) THEN
692
693
694
695
696
697 CALL strsd2d( ictxt, 'U', 'N', next_tri_size_m,
698 $ next_tri_size_n, a( ofst+( my_num_cols-bwl )*
699 $ llda+( bwl+bwu+1 ) ), llda-1, 0, mycol+1 )
700
701 END IF
702
703
704
705
706 CALL sdbtrf( odd_size, odd_size, bwl, bwu, a( ofst+1 ), llda,
707 $ info )
708
709 IF( info.NE.0 ) THEN
710 info = mycol + 1
711 GO TO 30
712 END IF
713
714
715 IF( mycol.LT.np-1 ) THEN
716
717
718
719
720
721
722 CALL slatcpy(
'U', bwl, bwl, a( ( ofst+( bwl+bwu+1 )+
723 $ ( odd_size-bwl )*llda ) ), llda-1,
724 $ af( odd_size*bwu+2*mbw2+1+max_bw-bwl ), max_bw )
725 CALL slamov( 'L', bwu, bwu, a( ( ofst+1+odd_size*llda ) ),
726 $ llda-1, af( work_u+odd_size*bwl+2*mbw2+1+max_bw-
727 $ bwu ), max_bw )
728
729
730
731 CALL stbtrs( 'L', 'N', 'U', bwu, bwl, bwu,
732 $ a( ofst+bwu+1+( odd_size-bwu )*llda ), llda,
733 $ af( work_u+odd_size*bwl+2*mbw2+1+max_bw-bwu ),
734 $ max_bw, info )
735
736
737
738 CALL stbtrs( 'U', 'T', 'N', bwl, bwu, bwl,
739 $ a( ofst+1+( odd_size-bwl )*llda ), llda,
740 $ af( odd_size*bwu+2*mbw2+1+max_bw-bwl ), max_bw,
741 $ info )
742
743
744
745
746 CALL slatcpy(
'L', bwl, bwl, af( odd_size*bwu+2*mbw2+1+max_bw-
747 $ bwl ), max_bw, a( ( ofst+( bwl+bwu+1 )+
748 $ ( odd_size-bwl )*llda ) ), llda-1 )
749
750
751
752 CALL slamov( 'L', bwu, bwu, af( work_u+odd_size*bwl+2*mbw2+1+
753 $ max_bw-bwu ), max_bw, a( ( ofst+1+odd_size*
754 $ llda ) ), llda-1 )
755
756
757
758
759
760
761
762
763
764 CALL sgemm( 'T', 'N', max_bw, max_bw, max_bw, -one,
765 $ af( odd_size*bwu+2*mbw2+1 ), max_bw,
766 $ af( work_u+odd_size*bwl+2*mbw2+1 ), max_bw, one,
767 $ a( ofst+odd_size*llda+1+bwu ), llda-1 )
768
769 END IF
770
771
772
773 30 CONTINUE
774
775
776 IF( mycol.NE.0 ) THEN
777
778
779
780
781
782
783
784
785
786 CALL strrv2d( ictxt, 'U', 'N', prev_tri_size_m,
787 $ prev_tri_size_n, af( work_u+1 ), bwl, 0,
788 $ mycol-1 )
789
790 IF( info.EQ.0 ) THEN
791
792
793
794
795
796 DO 50 i1 = 1, bwl
797 DO 40 i2 = i1 + 1, bwl
798 af( work_u+i2+( i1-1 )*bwl ) = af( work_u+i1+( i2-1 )*
799 $ bwl )
800 af( work_u+i1+( i2-1 )*bwl ) = zero
801 40 CONTINUE
802 50 CONTINUE
803
804 DO 60 i1 = 2, odd_size
805 i2 =
min( i1-1, bwl )
806 CALL sgemv( 'N', bwl, i2, -one,
807 $ af( work_u+1+( i1-1-i2 )*bwl ), bwl,
808 $ a( ofst+bwu+1+i2+( i1-1-i2 )*llda ), llda-1,
809 $ one, af( work_u+1+( i1-1 )*bwl ), 1 )
810 60 CONTINUE
811
812
813
814
815
816
817
818 CALL slamov( 'L', up_prev_tri_size_n, up_prev_tri_size_m,
819 $ a( ofst+1 ), llda-1, af( 1 ), bwu )
820
821 DO 80 i1 = 1, odd_size
822 i2 =
min( bwu, i1-1 )
823 CALL sgemv( 'N', bwu, i2, -one, af( ( i1-1-i2 )*bwu+1 ),
824 $ bwu, a( ofst+bwu+1-i2+( i1-1 )*llda ), 1,
825 $ one, af( ( i1-1 )*bwu+1 ), 1 )
826
827 DO 70 i = 1, bwu
828 af( ( i1-1 )*bwu+i ) = af( ( i1-1 )*bwu+i ) /
829 $ a( ( i1-1 )*llda+bwu+1 )
830 70 CONTINUE
831 80 CONTINUE
832
833
834
835
836
837
838 DO 90 i = 1, mbw2
839 af( odd_size*bwu+2*mbw2+i ) = zero
840 90 CONTINUE
841
842 CALL sgemm( 'N', 'T', bwu, bwl, odd_size, -one, af( 1 ),
843 $ bwu, af( work_u+1 ), bwl, zero,
844 $ af( 1+
max( 0, bwl-bwu )+odd_size*bwu+( 2*max_bw+
845 $
max( 0, bwu-bwl ) )*max_bw ), max_bw )
846
847
848
849
850
851 CALL sgesd2d( ictxt, max_bw, max_bw,
852 $ af( odd_size*bwu+2*mbw2+1 ), max_bw, 0,
853 $ mycol-1 )
854
855
856 IF( mycol.LT.np-1 ) THEN
857
858
859
860
861
862
863
864
865
866
867 CALL slamov( 'N', bwl, bwl,
868 $ af( work_u+( odd_size-bwl )*bwl+1 ), bwl,
869 $ af( ( odd_size )*bwu+1+( max_bw-bwl ) ),
870 $ max_bw )
871
872 CALL strmm( 'R', 'U', 'T', 'N', bwl, bwl, -one,
873 $ a( ( ofst+( bwl+bwu+1 )+( odd_size-bwl )*
874 $ llda ) ), llda-1, af( ( odd_size )*bwu+1+
875 $ ( max_bw-bwl ) ), max_bw )
876
877
878
879
880
881
882
883 CALL slamov( 'N', bwu, bwu, af( ( odd_size-bwu )*bwu+1 ),
884 $ bwu, af( work_u+( odd_size )*bwl+1+max_bw-
885 $ bwu ), max_bw )
886
887 CALL strmm( 'R', 'L', 'N', 'N', bwu, bwu, -one,
888 $ a( ( ofst+1+odd_size*llda ) ), llda-1,
889 $ af( work_u+( odd_size )*bwl+1+max_bw-bwu ),
890 $ max_bw )
891
892 END IF
893
894 END IF
895
896
897 END IF
898
899
900
901
902
903 CALL igamx2d( ictxt, 'A', ' ', 1, 1, info, 1, info, info, -1, 0,
904 $ 0 )
905
906 IF( mycol.EQ.0 ) THEN
907 CALL igebs2d( ictxt, 'A', ' ', 1, 1, info, 1 )
908 ELSE
909 CALL igebr2d( ictxt, 'A', ' ', 1, 1, info, 1, 0, 0 )
910 END IF
911
912 IF( info.NE.0 ) THEN
913 GO TO 130
914 END IF
915
916
917
918
919
920
921
922
923
924
925
926
927 IF( mycol.EQ.npcol-1 ) THEN
928 GO TO 120
929 END IF
930
931
932
933
934
935 IF( ( mod( mycol+1, 2 ).EQ.0 ) .AND. ( mycol.GT.0 ) ) THEN
936
937 CALL sgesd2d( ictxt, max_bw, max_bw, af( odd_size*bwu+1 ),
938 $ max_bw, 0, mycol-1 )
939
940 CALL sgesd2d( ictxt, max_bw, max_bw,
941 $ af( work_u+odd_size*bwl+1 ), max_bw, 0, mycol-1 )
942
943 END IF
944
945
946
947
948 CALL slamov( 'N', max_bw, max_bw, a( ofst+odd_size*llda+bwu+1 ),
949 $ llda-1, af( odd_size*bwu+mbw2+1 ), max_bw )
950
951
952
953 IF( mycol.LT.npcol-1 ) THEN
954
955 CALL sgerv2d( ictxt, max_bw, max_bw,
956 $ af( odd_size*bwu+2*mbw2+1 ), max_bw, 0, mycol+1 )
957
958
959
960 CALL saxpy( mbw2, one, af( odd_size*bwu+2*mbw2+1 ), 1,
961 $ af( odd_size*bwu+mbw2+1 ), 1 )
962
963 END IF
964
965
966
967
968
969
970
971 level_dist = 1
972
973
974
975 100 CONTINUE
976 IF( mod( ( mycol+1 ) / level_dist, 2 ).NE.0 )
977 $ GO TO 110
978
979
980
981 IF( mycol-level_dist.GE.0 ) THEN
982 CALL sgerv2d( ictxt, max_bw, max_bw, work( 1 ), max_bw, 0,
983 $ mycol-level_dist )
984
985 CALL saxpy( mbw2, one, work( 1 ), 1, af( odd_size*bwu+mbw2+1 ),
986 $ 1 )
987
988 END IF
989
990
991
992 IF( mycol+level_dist.LT.npcol-1 ) THEN
993 CALL sgerv2d( ictxt, max_bw, max_bw, work( 1 ), max_bw, 0,
994 $ mycol+level_dist )
995
996 CALL saxpy( mbw2, one, work( 1 ), 1, af( odd_size*bwu+mbw2+1 ),
997 $ 1 )
998
999 END IF
1000
1001 level_dist = level_dist*2
1002
1003 GO TO 100
1004 110 CONTINUE
1005
1006
1007
1008
1009
1010
1011
1012
1013 CALL sdbtrf( max_bw, max_bw,
min( max_bw-1, bwl ),
1014 $
min( max_bw-1, bwu ), af( odd_size*bwu+mbw2+1-
1015 $ (
min( max_bw-1, bwu ) ) ), max_bw+1, info )
1016
1017 IF( info.NE.0 ) THEN
1018 info = npcol + mycol
1019 END IF
1020
1021
1022
1023
1024
1025
1026 IF( level_dist.EQ.1 ) THEN
1027 comm_proc = mycol + 1
1028
1029
1030
1031
1032 CALL slamov( 'N', max_bw, max_bw, af( odd_size*bwu+1 ), max_bw,
1033 $ af( work_u+odd_size*bwl+2*mbw2+1 ), max_bw )
1034
1035 CALL slamov( 'N', max_bw, max_bw, af( work_u+odd_size*bwl+1 ),
1036 $ max_bw, af( odd_size*bwu+2*mbw2+1 ), max_bw )
1037
1038 ELSE
1039 comm_proc = mycol + level_dist / 2
1040 END IF
1041
1042 IF( mycol / level_dist.LE.( npcol-1 ) / level_dist-2 ) THEN
1043
1044 CALL sgerv2d( ictxt, max_bw, max_bw, af( odd_size*bwu+1 ),
1045 $ max_bw, 0, comm_proc )
1046
1047 CALL sgerv2d( ictxt, max_bw, max_bw,
1048 $ af( work_u+odd_size*bwl+1 ), max_bw, 0,
1049 $ comm_proc )
1050
1051 IF( info.EQ.0 ) THEN
1052
1053
1054
1055
1056
1057 CALL stbtrs(
'L',
'N',
'U', bwu,
min( bwl, bwu-1 ), bwu,
1058 $ af( odd_size*bwu+mbw2+1+( max_bw+1 )*( max_bw-
1059 $ bwu ) ), max_bw+1, af( work_u+odd_size*bwl+1+
1060 $ max_bw-bwu ), max_bw, info )
1061
1062
1063
1064
1065 CALL stbtrs(
'U',
'T',
'N', bwl,
min( bwu, bwl-1 ), bwl,
1066 $ af( odd_size*bwu+mbw2+1-
min( bwu,
1067 $ bwl-1 )+( max_bw+1 )*( max_bw-bwl ) ),
1068 $ max_bw+1, af( odd_size*bwu+1+max_bw-bwl ),
1069 $ max_bw, info )
1070
1071 END IF
1072
1073
1074
1075
1076 CALL sgemm( 'T', 'N', max_bw, max_bw, max_bw, -one,
1077 $ af( ( odd_size )*bwu+1 ), max_bw,
1078 $ af( work_u+( odd_size )*bwl+1 ), max_bw, zero,
1079 $ work( 1 ), max_bw )
1080
1081
1082
1083 CALL sgesd2d( ictxt, max_bw, max_bw, work( 1 ), max_bw, 0,
1084 $ mycol+level_dist )
1085
1086 END IF
1087
1088
1089
1090
1091
1092
1093
1094 IF( ( mycol / level_dist.GT.0 ) .AND.
1095 $ ( mycol / level_dist.LE.( npcol-1 ) / level_dist-1 ) ) THEN
1096
1097 IF( level_dist.GT.1 ) THEN
1098
1099
1100
1101
1102 CALL sgerv2d( ictxt, max_bw, max_bw,
1103 $ af( work_u+odd_size*bwl+2*mbw2+1 ), max_bw, 0,
1104 $ mycol-level_dist / 2 )
1105
1106
1107
1108
1109 CALL sgerv2d( ictxt, max_bw, max_bw,
1110 $ af( odd_size*bwu+2*mbw2+1 ), max_bw, 0,
1111 $ mycol-level_dist / 2 )
1112
1113 END IF
1114
1115
1116 IF( info.EQ.0 ) THEN
1117
1118
1119
1120
1121
1122
1123 CALL slatcpy(
'N', max_bw, max_bw,
1124 $ af( work_u+odd_size*bwl+2*mbw2+1 ), max_bw,
1125 $ work( 1 ), max_bw )
1126
1127 CALL stbtrs(
'L',
'N',
'U', max_bw,
min( bwl, max_bw-1 ),
1128 $ bwl, af( odd_size*bwu+mbw2+1 ), max_bw+1,
1129 $ work( 1+max_bw*( max_bw-bwl ) ), max_bw, info )
1130
1131
1132
1133 CALL slatcpy(
'N', max_bw, max_bw, work( 1 ), max_bw,
1134 $ af( work_u+odd_size*bwl+2*mbw2+1 ), max_bw )
1135
1136
1137
1138
1139
1140 CALL slatcpy(
'N', max_bw, max_bw,
1141 $ af( odd_size*bwu+2*mbw2+1 ), max_bw,
1142 $ work( 1 ), max_bw )
1143
1144 CALL stbtrs(
'U',
'T',
'N', max_bw,
min( bwu, max_bw-1 ),
1145 $ bwu, af( odd_size*bwu+mbw2+1-
min( bwu,
1146 $ max_bw-1 ) ), max_bw+1,
1147 $ work( 1+max_bw*( max_bw-bwu ) ), max_bw, info )
1148
1149
1150
1151 CALL slatcpy(
'N', max_bw, max_bw, work( 1 ), max_bw,
1152 $ af( odd_size*bwu+2*mbw2+1 ), max_bw )
1153
1154
1155 END IF
1156
1157
1158
1159
1160
1161 CALL sgemm( 'N', 'T', max_bw, max_bw, max_bw, -one,
1162 $ af( ( odd_size )*bwu+2*mbw2+1 ), max_bw,
1163 $ af( work_u+( odd_size )*bwl+2*mbw2+1 ), max_bw,
1164 $ zero, work( 1 ), max_bw )
1165
1166
1167
1168 CALL sgesd2d( ictxt, max_bw, max_bw, work( 1 ), max_bw, 0,
1169 $ mycol-level_dist )
1170
1171
1172
1173 IF( mycol / level_dist.LE.( npcol-1 ) / level_dist-2 ) THEN
1174
1175
1176
1177 IF( ( mod( mycol / ( 2*level_dist ), 2 ) ).EQ.0 ) THEN
1178 comm_proc = mycol + level_dist
1179 ELSE
1180 comm_proc = mycol - level_dist
1181 END IF
1182
1183
1184
1185
1186
1187 CALL sgemm( 'N', 'N', max_bw, max_bw, max_bw, -one,
1188 $ af( work_u+odd_size*bwl+2*mbw2+1 ), max_bw,
1189 $ af( odd_size*bwu+1 ), max_bw, zero, work( 1 ),
1190 $ max_bw )
1191
1192
1193
1194 CALL sgesd2d( ictxt, max_bw, max_bw, work( 1 ), max_bw, 0,
1195 $ comm_proc )
1196
1197 CALL sgemm( 'N', 'N', max_bw, max_bw, max_bw, -one,
1198 $ af( odd_size*bwu+2*mbw2+1 ), max_bw,
1199 $ af( work_u+odd_size*bwl+1 ), max_bw, zero,
1200 $ work( 1 ), max_bw )
1201
1202
1203
1204 CALL sgesd2d( ictxt, max_bw, max_bw, work( 1 ), max_bw, 0,
1205 $ comm_proc )
1206
1207 END IF
1208
1209 END IF
1210
1211
1212 120 CONTINUE
1213
1214
1215 130 CONTINUE
1216
1217
1218
1219
1220 IF( ictxt_save.NE.ictxt_new ) THEN
1221 CALL blacs_gridexit( ictxt_new )
1222 END IF
1223
1224 140 CONTINUE
1225
1226
1227
1228 ictxt = ictxt_save
1229 np = np_save
1230
1231
1232
1233 work( 1 ) = work_size_min
1234
1235
1236
1237 CALL igamx2d( ictxt, 'A', ' ', 1, 1, info, 1, info, info, -1, 0,
1238 $ 0 )
1239
1240 IF( mycol.EQ.0 ) THEN
1241 CALL igebs2d( ictxt, 'A', ' ', 1, 1, info, 1 )
1242 ELSE
1243 CALL igebr2d( ictxt, 'A', ' ', 1, 1, info, 1, 0, 0 )
1244 END IF
1245
1246
1247 RETURN
1248
1249
1250
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 sdbtrf(m, n, kl, ku, ab, ldab, info)
subroutine slatcpy(uplo, m, n, a, lda, b, ldb)