3
4
5
6
7
8
9
10 INTEGER INFO, JA, LAF, LWORK, N
11
12
13 INTEGER DESCA( * )
14 DOUBLE PRECISION AF( * ), D( * ), E( * ), 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 DOUBLE PRECISION ONE
350 parameter( one = 1.0d+0 )
351 DOUBLE PRECISION ZERO
352 parameter( zero = 0.0d+0 )
353 INTEGER INT_ONE
354 parameter( int_one = 1 )
355 INTEGER DESCMULT, BIGNUM
356 parameter( descmult = 100, bignum = descmult*descmult )
357 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
358 $ LLD_, MB_, M_, NB_, N_, RSRC_
359 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
360 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
361 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
362
363
364 INTEGER COMM_PROC, CSRC, FIRST_PROC, I, ICTXT,
365 $ ICTXT_NEW, ICTXT_SAVE, IDUM3, INT_TEMP, JA_NEW,
366 $ LAF_MIN, LEVEL_DIST, LLDA, MYCOL, MYROW,
367 $ MY_NUM_COLS, NB, NP, NPCOL, NPROW, NP_SAVE,
368 $ ODD_SIZE, PART_OFFSET, PART_SIZE, RETURN_CODE,
369 $ STORE_N_A, TEMP, WORK_SIZE_MIN
370
371
372 INTEGER DESCA_1XP( 7 ), PARAM_CHECK( 7, 3 )
373
374
376 $ dgerv2d, dgesd2d, dpttrf,
dpttrsv, dtrrv2d,
377 $ dtrsd2d,
globchk, igamx2d, igebr2d, igebs2d,
379
380
381 INTEGER NUMROC
383
384
385 INTRINSIC dble, mod
386
387
388
389
390
391 info = 0
392
393
394
395
396 desca_1xp( 1 ) = 501
397
398 temp = desca( dtype_ )
399 IF( temp.EQ.502 ) THEN
400
401 desca( dtype_ ) = 501
402 END IF
403
405
406 desca( dtype_ ) = temp
407
408 IF( return_code.NE.0 ) THEN
409 info = -( 5*100+2 )
410 END IF
411
412
413
414 ictxt = desca_1xp( 2 )
415 csrc = desca_1xp( 5 )
416 nb = desca_1xp( 4 )
417 llda = desca_1xp( 6 )
418 store_n_a = desca_1xp( 3 )
419
420
421
422
423 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
424 np = nprow*npcol
425
426
427
428 IF( lwork.LT.-1 ) THEN
429 info = -9
430 ELSE IF( lwork.EQ.-1 ) THEN
431 idum3 = -1
432 ELSE
433 idum3 = 1
434 END IF
435
436 IF( n.LT.0 ) THEN
437 info = -1
438 END IF
439
440 IF( n+ja-1.GT.store_n_a ) THEN
441 info = -( 5*100+6 )
442 END IF
443
444
445
446 IF( nprow.NE.1 ) THEN
447 info = -( 5*100+2 )
448 END IF
449
450 IF( n.GT.np*nb-mod( ja-1, nb ) ) THEN
451 info = -( 1 )
452 CALL pxerbla( ictxt,
'PDPTTRF, D&C alg.: only 1 block per proc'
453 $ , -info )
454 RETURN
455 END IF
456
457 IF( ( ja+n-1.GT.nb ) .AND. ( nb.LT.2*int_one ) ) THEN
458 info = -( 5*100+4 )
459 CALL pxerbla( ictxt,
'PDPTTRF, D&C alg.: NB too small', -info )
460 RETURN
461 END IF
462
463
464
465
466 laf_min = ( 12*npcol+3*nb )
467
468 IF( laf.LT.laf_min ) THEN
469 info = -7
470
471 af( 1 ) = laf_min
472 CALL pxerbla( ictxt,
'PDPTTRF: auxiliary storage error ',
473 $ -info )
474 RETURN
475 END IF
476
477
478
479 work_size_min = 8*npcol
480
481 work( 1 ) = work_size_min
482
483 IF( lwork.LT.work_size_min ) THEN
484 IF( lwork.NE.-1 ) THEN
485 info = -9
486 CALL pxerbla( ictxt,
'PDPTTRF: worksize error ', -info )
487 END IF
488 RETURN
489 END IF
490
491
492
493 param_check( 7, 1 ) = desca( 5 )
494 param_check( 6, 1 ) = desca( 4 )
495 param_check( 5, 1 ) = desca( 3 )
496 param_check( 4, 1 ) = desca( 1 )
497 param_check( 3, 1 ) = ja
498 param_check( 2, 1 ) = n
499 param_check( 1, 1 ) = idum3
500
501 param_check( 7, 2 ) = 505
502 param_check( 6, 2 ) = 504
503 param_check( 5, 2 ) = 503
504 param_check( 4, 2 ) = 501
505 param_check( 3, 2 ) = 4
506 param_check( 2, 2 ) = 1
507 param_check( 1, 2 ) = 9
508
509
510
511
512
513 IF( info.GE.0 ) THEN
514 info = bignum
515 ELSE IF( info.LT.-descmult ) THEN
516 info = -info
517 ELSE
518 info = -info*descmult
519 END IF
520
521
522
523 CALL globchk( ictxt, 7, param_check, 7, param_check( 1, 3 ),
524 $ info )
525
526
527
528
529 IF( info.EQ.bignum ) THEN
530 info = 0
531 ELSE IF( mod( info, descmult ).EQ.0 ) THEN
532 info = -info / descmult
533 ELSE
534 info = -info
535 END IF
536
537 IF( info.LT.0 ) THEN
538 CALL pxerbla( ictxt,
'PDPTTRF', -info )
539 RETURN
540 END IF
541
542
543
544 IF( n.EQ.0 )
545 $ RETURN
546
547
548
549
550
551 part_offset = nb*( ( ja-1 ) / ( npcol*nb ) )
552
553 IF( ( mycol-csrc ).LT.( ja-part_offset-1 ) / nb ) THEN
554 part_offset = part_offset + nb
555 END IF
556
557 IF( mycol.LT.csrc ) THEN
558 part_offset = part_offset - nb
559 END IF
560
561
562
563
564
565
566
567 first_proc = mod( ( ja-1 ) / nb+csrc, npcol )
568
569
570
571 ja_new = mod( ja-1, nb ) + 1
572
573
574
575 np_save = np
576 np = ( ja_new+n-2 ) / nb + 1
577
578
579
580 CALL reshape( ictxt, int_one, ictxt_new, int_one, first_proc,
581 $ int_one, np )
582
583
584
585 ictxt_save = ictxt
586 ictxt = ictxt_new
587 desca_1xp( 2 ) = ictxt_new
588
589
590
591 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
592
593
594
595 IF( myrow.LT.0 ) THEN
596 GO TO 90
597 END IF
598
599
600
601
602
603
604 part_size = nb
605
606
607
608 my_num_cols =
numroc( n, part_size, mycol, 0, npcol )
609
610
611
612 IF( mycol.EQ.0 ) THEN
613 part_offset = part_offset + mod( ja_new-1, part_size )
614 my_num_cols = my_num_cols - mod( ja_new-1, part_size )
615 END IF
616
617
618
619 odd_size = my_num_cols
620 IF( mycol.LT.np-1 ) THEN
621 odd_size = odd_size - int_one
622 END IF
623
624
625
626
627 DO 10 i = 1, laf_min
628 af( i ) = zero
629 10 CONTINUE
630
631
632
633
634
635
636
637
638
639 IF( mycol.LT.np-1 ) THEN
640
641
642
643
644
645 CALL dtrsd2d( ictxt, 'U', 'N', 1, 1,
646 $ e( part_offset+odd_size+1 ), llda-1, 0, mycol+1 )
647
648 END IF
649
650
651
652
653
654 CALL dpttrf( odd_size, d( part_offset+1 ), e( part_offset+1 ),
655 $ info )
656
657 IF( info.NE.0 ) THEN
658 info = mycol + 1
659 GO TO 20
660 END IF
661
662
663 IF( mycol.LT.np-1 ) THEN
664
665
666
667
668
669
670 e( part_offset+odd_size ) = e( part_offset+odd_size ) /
671 $ d( part_offset+odd_size )
672
673
674
675
676
677
678 d( part_offset+odd_size+1 ) = d( part_offset+odd_size+1 ) -
679 $ d( part_offset+odd_size )*
680 $ ( e( part_offset+odd_size )*
681 $ ( e( part_offset+odd_size ) ) )
682
683 END IF
684
685
686
687 20 CONTINUE
688
689
690 IF( mycol.NE.0 ) THEN
691
692
693
694
695
696
697 CALL dtrrv2d( ictxt, 'U', 'N', 1, 1, af( 1 ), odd_size, 0,
698 $ mycol-1 )
699
700 IF( info.EQ.0 ) THEN
701
702
703
704 CALL dpttrsv(
'N', odd_size, int_one, d( part_offset+1 ),
705 $ e( part_offset+1 ), af( 1 ), odd_size, info )
706
707
708
709 DO 30 i = 1, odd_size
710 af( i ) = af( i ) / d( part_offset+i )
711 30 CONTINUE
712
713
714
715
716
717
718
719
720 int_temp = odd_size*int_one + 2 + 1
721 af( int_temp ) = 0
722
723 DO 40 i = 1, odd_size
724 af( int_temp ) = af( int_temp ) -
725 $ d( part_offset+i )*( af( i )*
726 $ ( af( i ) ) )
727 40 CONTINUE
728
729
730
731
732
733 CALL dgesd2d( ictxt, int_one, int_one, af( odd_size+3 ),
734 $ int_one, 0, mycol-1 )
735
736
737 IF( mycol.LT.np-1 ) THEN
738
739
740
741
742
743
744 af( odd_size+1 ) = -d( part_offset+odd_size )*
745 $ ( e( part_offset+odd_size )*
746 $ af( odd_size ) )
747
748
749 END IF
750
751 END IF
752
753
754 END IF
755
756
757
758
759
760 CALL igamx2d( ictxt, 'A', ' ', 1, 1, info, 1, info, info, -1, 0,
761 $ 0 )
762
763 IF( mycol.EQ.0 ) THEN
764 CALL igebs2d( ictxt, 'A', ' ', 1, 1, info, 1 )
765 ELSE
766 CALL igebr2d( ictxt, 'A', ' ', 1, 1, info, 1, 0, 0 )
767 END IF
768
769 IF( info.NE.0 ) THEN
770 GO TO 80
771 END IF
772
773
774
775
776
777
778
779
780
781
782
783
784 IF( mycol.EQ.npcol-1 ) THEN
785 GO TO 70
786 END IF
787
788
789
790
791
792 IF( ( mod( mycol+1, 2 ).EQ.0 ) .AND. ( mycol.GT.0 ) ) THEN
793
794 CALL dgesd2d( ictxt, int_one, int_one, af( odd_size+1 ),
795 $ int_one, 0, mycol-1 )
796
797 END IF
798
799
800
801
802 af( odd_size+2 ) = dble( d( part_offset+odd_size+1 ) )
803
804
805
806 IF( mycol.LT.npcol-1 ) THEN
807
808 CALL dgerv2d( ictxt, int_one, int_one, af( odd_size+2+1 ),
809 $ int_one, 0, mycol+1 )
810
811
812
813 af( odd_size+2 ) = af( odd_size+2 ) + af( odd_size+3 )
814
815 END IF
816
817
818
819
820
821
822
823 level_dist = 1
824
825
826
827 50 CONTINUE
828 IF( mod( ( mycol+1 ) / level_dist, 2 ).NE.0 )
829 $ GO TO 60
830
831
832
833 IF( mycol-level_dist.GE.0 ) THEN
834 CALL dgerv2d( ictxt, int_one, int_one, work( 1 ), int_one, 0,
835 $ mycol-level_dist )
836
837 af( odd_size+2 ) = af( odd_size+2 ) + work( 1 )
838
839 END IF
840
841
842
843 IF( mycol+level_dist.LT.npcol-1 ) THEN
844 CALL dgerv2d( ictxt, int_one, int_one, work( 1 ), int_one, 0,
845 $ mycol+level_dist )
846
847 af( odd_size+2 ) = af( odd_size+2 ) + work( 1 )
848
849 END IF
850
851 level_dist = level_dist*2
852
853 GO TO 50
854 60 CONTINUE
855
856
857
858
859
860 IF( af( odd_size+2 ).EQ.zero ) THEN
861 info = npcol + mycol
862 END IF
863
864
865
866
867
868
869 IF( level_dist.EQ.1 ) THEN
870 comm_proc = mycol + 1
871
872
873
874
875 af( odd_size+3 ) = af( odd_size+1 )
876
877 ELSE
878 comm_proc = mycol + level_dist / 2
879 END IF
880
881 IF( mycol / level_dist.LE.( npcol-1 ) / level_dist-2 ) THEN
882
883 CALL dgerv2d( ictxt, int_one, int_one, af( odd_size+1 ),
884 $ int_one, 0, comm_proc )
885
886 IF( info.EQ.0 ) THEN
887
888
889
890
891
892 af( odd_size+1 ) = af( odd_size+1 ) / af( odd_size+2 )
893
894 END IF
895
896
897
898
899 work( 1 ) = -one*af( odd_size+1 )*af( odd_size+2 )*
900 $ ( af( odd_size+1 ) )
901
902
903
904 CALL dgesd2d( ictxt, int_one, int_one, work( 1 ), int_one, 0,
905 $ mycol+level_dist )
906
907 END IF
908
909
910
911
912
913
914
915 IF( ( mycol / level_dist.GT.0 ) .AND.
916 $ ( mycol / level_dist.LE.( npcol-1 ) / level_dist-1 ) ) THEN
917
918 IF( level_dist.GT.1 ) THEN
919
920
921
922
923 CALL dgerv2d( ictxt, int_one, int_one, af( odd_size+2+1 ),
924 $ int_one, 0, mycol-level_dist / 2 )
925
926 END IF
927
928
929 IF( info.EQ.0 ) THEN
930
931
932
933 af( odd_size+3 ) = ( af( odd_size+3 ) ) / af( odd_size+2 )
934
935 END IF
936
937
938
939
940
941 work( 1 ) = -one*af( odd_size+3 )*af( odd_size+2 )*
942 $ ( af( odd_size+3 ) )
943
944
945
946 CALL dgesd2d( ictxt, int_one, int_one, work( 1 ), int_one, 0,
947 $ mycol-level_dist )
948
949
950
951 IF( mycol / level_dist.LE.( npcol-1 ) / level_dist-2 ) THEN
952
953
954
955 IF( ( mod( mycol / ( 2*level_dist ), 2 ) ).EQ.0 ) THEN
956 comm_proc = mycol + level_dist
957 ELSE
958 comm_proc = mycol - level_dist
959 END IF
960
961
962
963
964
965 work( 1 ) = -one*af( odd_size+3 )*af( odd_size+2 )*
966 $ af( odd_size+1 )
967
968
969
970 CALL dgesd2d( ictxt, int_one, int_one, work( 1 ), int_one,
971 $ 0, comm_proc )
972
973 END IF
974
975 END IF
976
977
978 70 CONTINUE
979
980
981 80 CONTINUE
982
983
984
985
986 IF( ictxt_save.NE.ictxt_new ) THEN
987 CALL blacs_gridexit( ictxt_new )
988 END IF
989
990 90 CONTINUE
991
992
993
994 ictxt = ictxt_save
995 np = np_save
996
997
998
999 work( 1 ) = work_size_min
1000
1001
1002
1003 CALL igamx2d( ictxt, 'A', ' ', 1, 1, info, 1, info, info, -1, 0,
1004 $ 0 )
1005
1006 IF( mycol.EQ.0 ) THEN
1007 CALL igebs2d( ictxt, 'A', ' ', 1, 1, info, 1 )
1008 ELSE
1009 CALL igebr2d( ictxt, 'A', ' ', 1, 1, info, 1, 0, 0 )
1010 END IF
1011
1012
1013 RETURN
1014
1015
1016
subroutine desc_convert(desc_in, desc_out, info)
subroutine dpttrsv(trans, n, nrhs, d, e, b, ldb, 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)