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