3
4
5
6
7
8
9 INTEGER BWL, BWU, INFO, JA, LAF, LWORK, N
10
11
12 INTEGER DESCA( * ), IPIV( * )
13 COMPLEX*16 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
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357 DOUBLE PRECISION ONE, ZERO
358 parameter( one = 1.0d+0 )
359 parameter( zero = 0.0d+0 )
360 COMPLEX*16 CONE, CZERO
361 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
362 parameter( czero = ( 0.0d+0, 0.0d+0 ) )
363 INTEGER INT_ONE
364 parameter( int_one = 1 )
365 INTEGER DESCMULT, BIGNUM
366 parameter( descmult = 100, bignum = descmult*descmult )
367 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
368 $ LLD_, MB_, M_, NB_, N_, RSRC_
369 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
370 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
371 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
372
373
374 INTEGER APTR, BBPTR, BIPTR, BM, BM1, BM2, BMN, BN, BW,
375 $ CSRC, DBPTR, FIRST_PROC, I, ICTXT, ICTXT_NEW,
376 $ ICTXT_SAVE, IDUM3, J, JA_NEW, JPTR, L, LAF_MIN,
377 $ LBWL, LBWU, LDB, LDBB, LLDA, LM, LMJ, LN, LNJ,
378 $ LPTR, MYCOL, MYROW, MY_NUM_COLS, NB, NEICOL,
379 $ NP, NPACT, NPCOL, NPROW, NPSTR, NP_SAVE, NRHS,
380 $ ODD_N, ODD_SIZE, ODPTR, OFST, PART_OFFSET,
381 $ PART_SIZE, RETURN_CODE, STORE_N_A,
382 $ WORK_SIZE_MIN
383
384
385 INTEGER DESCA_1XP( 7 ), PARAM_CHECK( 9, 3 )
386
387
390 $ zgerv2d, zgesd2d, zlamov,
zlatcpy, zpbtrf,
391 $ zpotrf, zsyrk, ztbtrs, ztrmm, ztrrv2d, ztrsd2d,
392 $ ztrsm, ztrtrs
393
394
395 LOGICAL LSAME
396 INTEGER NUMROC
398
399
400 INTRINSIC ichar,
min, mod
401
402
403
404
405
406
407 info = 0
408
409
410
411
412 desca_1xp( 1 ) = 501
413
415
416 IF( return_code .NE. 0) THEN
417 info = -( 6*100 + 2 )
418 ENDIF
419
420
421
422 ictxt = desca_1xp( 2 )
423 csrc = desca_1xp( 5 )
424 nb = desca_1xp( 4 )
425 llda = desca_1xp( 6 )
426 store_n_a = desca_1xp( 3 )
427
428
429
430
431 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
432 np = nprow * npcol
433
434
435
436 IF( lwork .LT. -1) THEN
437 info = -11
438 ELSE IF ( lwork .EQ. -1 ) THEN
439 idum3 = -1
440 ELSE
441 idum3 = 1
442 ENDIF
443
444 IF( n .LT. 0 ) THEN
445 info = -1
446 ENDIF
447
448 IF( n+ja-1 .GT. store_n_a ) THEN
449 info = -( 6*100 + 6 )
450 ENDIF
451
452 IF(( bwl .GT. n-1 ) .OR.
453 $ ( bwl .LT. 0 ) ) THEN
454 info = -2
455 ENDIF
456
457 IF(( bwu .GT. n-1 ) .OR.
458 $ ( bwu .LT. 0 ) ) THEN
459 info = -3
460 ENDIF
461
462 IF( llda .LT. (2*bwl+2*bwu+1) ) THEN
463 info = -( 6*100 + 6 )
464 ENDIF
465
466 IF( nb .LE. 0 ) THEN
467 info = -( 6*100 + 4 )
468 ENDIF
469
470 bw = bwu+bwl
471
472
473
474 IF( nprow .NE. 1 ) THEN
475 info = -( 6*100+2 )
476 ENDIF
477
478 IF( n .GT. np*nb-mod( ja-1, nb )) THEN
479 info = -( 1 )
481 $ 'PZGBTRF, D&C alg.: only 1 block per proc',
482 $ -info )
483 RETURN
484 ENDIF
485
486 IF((ja+n-1.GT.nb) .AND. ( nb.LT.(bwl+bwu+1) )) THEN
487 info = -( 6*100+4 )
489 $ 'PZGBTRF, D&C alg.: NB too small',
490 $ -info )
491 RETURN
492 ENDIF
493
494
495
496
497 laf_min = (nb+bwu)*(bwl+bwu)+6*(bwl+bwu)*(bwl+2*bwu)
498
499 IF( laf .LT. laf_min ) THEN
500 info = -9
501
502 af( 1 ) = laf_min
504 $ 'PZGBTRF: auxiliary storage error ',
505 $ -info )
506 RETURN
507 ENDIF
508
509
510
511 work_size_min = 1
512
513 work( 1 ) = work_size_min
514
515 IF( lwork .LT. work_size_min ) THEN
516 IF( lwork .NE. -1 ) THEN
517 info = -11
518
519 work( 1 ) = work_size_min
521 $ 'PZGBTRF: worksize error ',
522 $ -info )
523 ENDIF
524 RETURN
525 ENDIF
526
527
528
529 param_check( 9, 1 ) = desca(5)
530 param_check( 8, 1 ) = desca(4)
531 param_check( 7, 1 ) = desca(3)
532 param_check( 6, 1 ) = desca(1)
533 param_check( 5, 1 ) = ja
534 param_check( 4, 1 ) = bwu
535 param_check( 3, 1 ) = bwl
536 param_check( 2, 1 ) = n
537 param_check( 1, 1 ) = idum3
538
539 param_check( 9, 2 ) = 605
540 param_check( 8, 2 ) = 604
541 param_check( 7, 2 ) = 603
542 param_check( 6, 2 ) = 601
543 param_check( 5, 2 ) = 5
544 param_check( 4, 2 ) = 3
545 param_check( 3, 2 ) = 2
546 param_check( 2, 2 ) = 1
547 param_check( 1, 2 ) = 11
548
549
550
551
552
553 IF( info.GE.0 ) THEN
554 info = bignum
555 ELSE IF( info.LT.-descmult ) THEN
556 info = -info
557 ELSE
558 info = -info * descmult
559 END IF
560
561
562
563 CALL globchk( ictxt, 9, param_check, 9,
564 $ param_check( 1, 3 ), info )
565
566
567
568
569 IF( info.EQ.bignum ) THEN
570 info = 0
571 ELSE IF( mod( info, descmult ) .EQ. 0 ) THEN
572 info = -info / descmult
573 ELSE
574 info = -info
575 END IF
576
577 IF( info.LT.0 ) THEN
578 CALL pxerbla( ictxt,
'PZGBTRF', -info )
579 RETURN
580 END IF
581
582
583
584 IF( n.EQ.0 )
585 $ RETURN
586
587
588
589
590
591 part_offset = nb*( (ja-1)/(npcol*nb) )
592
593 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb ) THEN
594 part_offset = part_offset + nb
595 ENDIF
596
597 IF ( mycol .LT. csrc ) THEN
598 part_offset = part_offset - nb
599 ENDIF
600
601
602
603
604
605
606
607 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
608
609
610
611 ja_new = mod( ja-1, nb ) + 1
612
613
614
615 np_save = np
616 np = ( ja_new+n-2 )/nb + 1
617
618
619
620 CALL reshape( ictxt, int_one, ictxt_new, int_one,
621 $ first_proc, int_one, np )
622
623
624
625 ictxt_save = ictxt
626 ictxt = ictxt_new
627 desca_1xp( 2 ) = ictxt_new
628
629
630
631 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
632
633
634
635 IF( myrow .LT. 0 ) THEN
636 GOTO 1234
637 ENDIF
638
639
640
641
642
643
644 part_size = nb
645
646
647
648 my_num_cols =
numroc( n, part_size, mycol, 0, npcol )
649
650
651
652 IF ( mycol .EQ. 0 ) THEN
653 part_offset = part_offset+mod( ja_new-1, part_size )
654 my_num_cols = my_num_cols - mod(ja_new-1, part_size )
655 ENDIF
656
657
658
659 ofst = part_offset*llda
660
661
662
663 odd_size =
numroc( n, part_size, mycol, 0, npcol )
664
665
666
667
668 DO 10 i = 1, laf_min
669 af( i ) = czero
670 10 CONTINUE
671
672 DO 9 j = 1, odd_size
673 DO 8 i = 1, bw
674 a( i+(j-1)*llda ) = czero
675 8 CONTINUE
676 9 CONTINUE
677
678
679
680
681
682
683
684
685
686
687
688 IF (mycol .LE. npcol-2) THEN
689
690
691
692 biptr = (nb-bw)*llda + 2*bw+1
693
694 CALL ztrsd2d( ictxt, 'U', 'N',
695 $
min( bw, bwu+
numroc( n, nb, mycol+1, 0, npcol ) ),
696 $ bw, a(biptr), llda-1, 0, mycol+1)
697
698 ENDIF
699
700
701
702
703
704
705
706
707
708
709
710
711 IF (mycol .NE. 0) THEN
712 lbwl = bw
713 lbwu = 0
714 aptr = 1
715 ELSE
716 lbwl = bwl
717 lbwu = bwu
718 aptr = 1+bwu
719 ENDIF
720
721 IF (mycol .NE. npcol-1) THEN
722 lm = nb - lbwu
723 ln = nb - bw
724 ELSE IF (mycol .NE. 0) THEN
725 lm = odd_size + bwu
726 ln =
max(odd_size-bw,0)
727 ELSE
728 lm = n
730 ENDIF
731
732 IF (ln .GT. 0) THEN
733
734 CALL zgbtrf(lm,ln, lbwl,lbwu, a(aptr),llda, ipiv, info)
735
736 IF( info.NE.0 ) THEN
737 info = info + nb*mycol
738 GO TO 90
739 END IF
740
741 nrhs = bw
742 ldb = llda-1
743
744
745
746
747
748
749 DO 23 j =
max(ln-bw+1,1), ln
750
751 lmj =
min( lbwl, lm-j )
752 lnj =
min( bw, j+bw-ln+aptr-1 )
753
754 l = ipiv( j )
755
756 jptr = j-(ln+1)+2*bw+1-lbwl + ln*llda
757
758 IF( l.NE.j ) THEN
759
760
761
762
763
764
765 lptr = l-(ln+1)+2*bw+1-lbwl + ln*llda
766
767 CALL zswap( lnj, a(lptr),ldb, a(jptr), ldb )
768
769 ENDIF
770
771
772
773
774 lptr = bw+1+aptr + (j-1)*llda
775
776 CALL zgeru(lmj,lnj,-cone, a(lptr),1, a(jptr),ldb,
777 $ a(jptr+1),ldb)
778 23 CONTINUE
779
780 ENDIF
781
782
783
784
785
786 IF (mycol .GT. 0) THEN
787
788 CALL ztrrv2d( ictxt,
'U',
'N',
min(bw, lm), bw, af( 1 ),
789 $ lm, 0, mycol-1)
790
791
792
793
794 DO 24 j = 1, ln
795
796 lmj =
min( lbwl, lm-j )
797 l = ipiv( j )
798
799 IF( l .NE. j ) THEN
800
801 CALL zswap(nrhs, af(l), lm, af(j), lm )
802 ENDIF
803
804 lptr = bw+1+aptr + (j-1)*llda
805
806 CALL zgeru( lmj,nrhs, -cone, a(lptr),1,
807 $ af(j), lm, af(j+1), lm)
808
809 24 CONTINUE
810
811 ENDIF
812
813 90 CONTINUE
814
815
816
817
818
819
820
821
822 IF (mycol .NE. npcol-1) THEN
823 bm = bw - lbwu
824 bn = bw
825 ELSE
826 bm =
min(bw,odd_size) + bwu
827 bn =
min(bw,odd_size)
828 ENDIF
829
830
831
832
833 bbptr = (nb+bwu)*bw + 1
834 ldbb = 2*bw + bwu
835
836
837
838
839 dbptr = bw+1 + lbwu + ln*llda
840
841 CALL zlamov('G',bm,bn, a(dbptr),llda-1,
842 $ af(bbptr + bw*ldbb),ldbb)
843
844
845
846 DO 870 j=1, bm
847 DO 880 i=j+lbwl, bm-1
848 af( bbptr+bw*ldbb+(j-1)*ldbb+i ) = czero
849 880 CONTINUE
850 870 CONTINUE
851
852 IF (mycol .NE. 0) THEN
853
854
855
856 odptr = lm-bm+1
857 CALL zlamov('G',bm,bw, af(odptr),lm,
858 $ af(bbptr +2*bw*ldbb),ldbb)
859 ENDIF
860
861 IF (npcol.EQ.1) THEN
862
863
864
865 CALL zgetrf( n-ln, n-ln, af(bbptr+bw*ldbb), ldbb,
866 $ ipiv(ln+1), info)
867
868 ENDIF
869
870
871
872
873
874
875
876 npact = npcol
877 npstr = 1
878
879
880
881 200 IF (npact .LE. 1) GOTO 300
882
883
884
885 IF (mod(mycol,npstr) .EQ. 0) THEN
886
887
888
889
890 IF (mod(mycol,2*npstr) .EQ. 0) THEN
891
892
893
894 neicol = mycol + npstr
895
896 IF (neicol/npstr .LT. npact-1) THEN
897 bmn = bw
898 ELSE IF (neicol/npstr .EQ. npact-1) THEN
899 odd_n =
numroc(n, nb, npcol-1, 0, npcol)
900 bmn =
min(bw,odd_n) + bwu
901 ELSE
902
903
904 GOTO 250
905 ENDIF
906
907
908
909 bm1 = bm
910 bm2 = bmn
911
912 IF (neicol/npstr .LE. npact-1 )THEN
913
914 CALL zgesd2d( ictxt, bm, 2*bw, af(bbptr+bw*ldbb),
915 $ ldbb, 0, neicol )
916
917 CALL zgerv2d( ictxt, bmn, 2*bw, af(bbptr+bm),
918 $ ldbb, 0, neicol)
919
920 IF( npact .EQ. 2 ) THEN
921
922
923
924 CALL zlamov( 'G', bmn, bw, af( bbptr+bm ),
925 $ ldbb, af( bbptr+2*bw*ldbb+bm ), ldbb )
926 ENDIF
927
928 ENDIF
929
930 ELSE
931
932
933
934
935
936 neicol = mycol - npstr
937
938 IF (neicol .EQ. 0) THEN
939 bmn = bw - bwu
940 ELSE
941 bmn = bw
942 ENDIF
943
944 bm1 = bmn
945 bm2 = bm
946
947 CALL zgesd2d( ictxt, bm, 2*bw, af(bbptr+bw*ldbb),
948 $ ldbb, 0, neicol )
949
950 CALL zlamov('G',bm, 2*bw, af(bbptr+bw*ldbb),ldbb,
951 $ af(bbptr+bmn),ldbb)
952
953 DO 31 j=bbptr+2*bw*ldbb, bbptr+3*bw*ldbb-1, ldbb
954 DO 32 i=0, ldbb-1
955 af(i+j) = czero
956 32 CONTINUE
957 31 CONTINUE
958
959 CALL zgerv2d( ictxt, bmn, 2*bw, af(bbptr+bw*ldbb),
960 $ ldbb, 0, neicol)
961
962 IF( npact .EQ. 2 ) THEN
963
964
965
966 CALL zlamov( 'G', bm, bw, af( bbptr+bmn ),
967 $ ldbb, af( bbptr+2*bw*ldbb+bmn ), ldbb )
968 ENDIF
969
970 ENDIF
971
972
973
974 IF (npact .NE. 2) THEN
975
976 CALL zgetrf(bm+bmn, bw, af(bbptr+bw*ldbb), ldbb,
977 $ ipiv(ln+1), info)
978
979
980
981 DO 301 j=bbptr,bbptr+bw*ldbb-1, ldbb
982 DO 302 i=0, bm1-1
983 af(i+j) = czero
984 302 CONTINUE
985 301 CONTINUE
986
987 CALL zlaswp(bw, af(bbptr), ldbb, 1, bw,
988 $ ipiv(ln+1), 1)
989
990 CALL ztrsm('L','L','N','U', bw, bw, cone,
991 $ af(bbptr+bw*ldbb), ldbb, af(bbptr), ldbb)
992
993
994
995 CALL zgemm( 'N', 'N', bm+bmn-bw, bw, bw,
996 $ -cone, af(bbptr+bw*ldbb+bw), ldbb,
997 $ af( bbptr ), ldbb, cone,
998 $ af( bbptr+bw ), ldbb )
999
1000
1001
1002 nrhs = bw
1003
1004 CALL zlaswp(nrhs, af(bbptr+2*bw*ldbb), ldbb, 1, bw,
1005 $ ipiv(ln+1), 1)
1006
1007 CALL ztrsm('L','L','N','U', bw, nrhs, cone,
1008 $ af(bbptr+bw*ldbb), ldbb, af(bbptr+2*bw*ldbb), ldbb)
1009
1010
1011
1012 CALL zgemm( 'N', 'N', bm+bmn-bw, nrhs, bw,
1013 $ -cone, af(bbptr+bw*ldbb+bw), ldbb,
1014 $ af( bbptr+2*bw*ldbb ), ldbb, cone,
1015 $ af( bbptr+2*bw*ldbb+bw ), ldbb )
1016
1017
1018
1019
1020 IF (mod(mycol,2*npstr) .EQ. 0) THEN
1021
1022
1023
1024 bm = bm1+bm2-bw
1025
1026
1027
1028
1029 CALL zlamov('G',bm,bw,
1030 $ af(bbptr+bw),
1031 $ ldbb, af(bbptr+bw*ldbb), ldbb)
1032 CALL zlamov('G',bm,bw,
1033 $ af(bbptr+2*bw*ldbb+bw),
1034 $ ldbb, af(bbptr+2*bw*ldbb), ldbb)
1035
1036
1037
1038 DO 1020 j=0, bw-1
1039 DO 1021 i=0, bm-1
1040 af(bbptr+2*bw*ldbb+bw+j*ldbb+i) = czero
1041 1021 CONTINUE
1042 1020 CONTINUE
1043
1044 ENDIF
1045
1046 ELSE
1047
1048
1049
1050 CALL zgetrf(bm+bmn,bm+bmn, af(bbptr+bw*ldbb), ldbb,
1051 $ ipiv(ln+1), info)
1052 ENDIF
1053
1054 ENDIF
1055
1056
1057
1058 250 CONTINUE
1059
1060 npact = (npact + 1)/2
1061 npstr = npstr * 2
1062 GOTO 200
1063
1064 300 CONTINUE
1065
1066
1067 1000 CONTINUE
1068
1069
1070
1071
1072 ictxt = ictxt_save
1073 IF( ictxt.NE.ictxt_new ) THEN
1074 CALL blacs_gridexit( ictxt_new )
1075 END IF
1076
1077 1234 CONTINUE
1078
1079
1080
1081
1082
1083 ictxt = ictxt_save
1084 np = np_save
1085
1086
1087
1088 work( 1 ) = work_size_min
1089
1090
1091
1092 CALL igamx2d( ictxt, 'A', ' ', 1, 1, info, 1, info, info,
1093 $ -1, 0, 0 )
1094
1095 IF( mycol.EQ.0 ) THEN
1096 CALL igebs2d( ictxt, 'A', ' ', 1, 1, info, 1 )
1097 ELSE
1098 CALL igebr2d( ictxt, 'A', ' ', 1, 1, info, 1, 0, 0 )
1099 ENDIF
1100
1101
1102 RETURN
1103
1104
1105
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 zlatcpy(uplo, m, n, a, lda, b, ldb)