3 IMPLICIT NONE
4
5
6
7
8
9
10
11 CHARACTER NORM, UPLO
12 INTEGER IA, JA, N
13
14
15 INTEGER DESCA( * )
16 DOUBLE PRECISION A( * ), 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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
165 $ LLD_, MB_, M_, NB_, N_, RSRC_
166 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
167 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
168 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
169 DOUBLE PRECISION ONE, ZERO
170 parameter( one = 1.0d+0, zero = 0.0d+0 )
171
172
173 INTEGER I, IAROW, IACOL, IB, ICOFF, ICTXT, ICURCOL,
174 $ ICURROW, II, IIA, IN, IROFF, ICSR, ICSR0,
175 $ IOFFA, IRSC, IRSC0, IRSR, IRSR0, JJ, JJA, K,
176 $ LDA, LL, MYCOL, MYROW, NP, NPCOL, NPROW, NQ
177 DOUBLE PRECISION SUM, VALUE
178
179
180 DOUBLE PRECISION SSQ( 2 ), COLSSQ( 2 )
181
182
183 EXTERNAL blacs_gridinfo, daxpy,
dcombssq,
184 $ dgamx2d, dgsum2d, dgebr2d,
187
188
189 LOGICAL LSAME
190 INTEGER ICEIL, IDAMAX, NUMROC
192
193
194 INTRINSIC abs,
max,
min, mod, sqrt
195
196
197
198
199
200 ictxt = desca( ctxt_ )
201 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
202 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol,
203 $ iia, jja, iarow, iacol )
204
205 iroff = mod( ia-1, desca( mb_ ) )
206 icoff = mod( ja-1, desca( nb_ ) )
207 np =
numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
208 nq =
numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
209 icsr = 1
210 irsr = icsr + nq
211 irsc = irsr + nq
212 IF( myrow.EQ.iarow ) THEN
213 irsc0 = irsc + iroff
214 np = np - iroff
215 ELSE
216 irsc0 = irsc
217 END IF
218 IF( mycol.EQ.iacol ) THEN
219 icsr0 = icsr + icoff
220 irsr0 = irsr + icoff
221 nq = nq - icoff
222 ELSE
223 icsr0 = icsr
224 irsr0 = irsr
225 END IF
226 in =
min(
iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+n-1 )
227 lda = desca( lld_ )
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 ii = iia
262 jj = jja
263
264 IF( n.EQ.0 ) THEN
265
266 VALUE = zero
267
268
269
270
271 ELSE IF(
lsame( norm,
'M' ) )
THEN
272
273
274
275 VALUE = zero
276
277 IF(
lsame( uplo,
'U' ) )
THEN
278
279
280
281 ib = in-ia+1
282
283
284
285 IF( mycol.EQ.iacol ) THEN
286 DO 20 k = (jj-1)*lda, (jj+ib-2)*lda, lda
287 IF( ii.GT.iia ) THEN
288 DO 10 ll = iia, ii-1
289 VALUE =
max(
VALUE, abs( a( ll+k ) ) )
290 10 CONTINUE
291 END IF
292 IF( myrow.EQ.iarow )
293 $ ii = ii + 1
294 20 CONTINUE
295
296
297
298 IF( myrow.EQ.iarow )
299 $ ii = ii - ib
300
301 END IF
302
303
304
305 IF( myrow.EQ.iarow ) THEN
306 DO 40 k = ii, ii+ib-1
307 IF( jj.LE.jja+nq-1 ) THEN
308 DO 30 ll = (jj-1)*lda, (jja+nq-2)*lda, lda
309 VALUE =
max(
VALUE, abs( a( k+ll ) ) )
310 30 CONTINUE
311 END IF
312 IF( mycol.EQ.iacol )
313 $ jj = jj + 1
314 40 CONTINUE
315 ii = ii + ib
316 ELSE IF( mycol.EQ.iacol ) THEN
317 jj = jj + ib
318 END IF
319
320 icurrow = mod( iarow+1, nprow )
321 icurcol = mod( iacol+1, npcol )
322
323
324
325 DO 90 i = in+1, ia+n-1, desca( mb_ )
326 ib =
min( desca( mb_ ), ia+n-i )
327
328
329
330 IF( mycol.EQ.icurcol ) THEN
331 DO 60 k = (jj-1)*lda, (jj+ib-2)*lda, lda
332 IF( ii.GT.iia ) THEN
333 DO 50 ll = iia, ii-1
334 VALUE =
max(
VALUE, abs( a( ll+k ) ) )
335 50 CONTINUE
336 END IF
337 IF( myrow.EQ.icurrow )
338 $ ii = ii + 1
339 60 CONTINUE
340
341
342
343 IF( myrow.EQ.icurrow )
344 $ ii = ii - ib
345 END IF
346
347
348
349 IF( myrow.EQ.icurrow ) THEN
350 DO 80 k = ii, ii+ib-1
351 IF( jj.LE.jja+nq-1 ) THEN
352 DO 70 ll = (jj-1)*lda, (jja+nq-2)*lda, lda
353 VALUE =
max(
VALUE, abs( a( k+ll ) ) )
354 70 CONTINUE
355 END IF
356 IF( mycol.EQ.icurcol )
357 $ jj = jj + 1
358 80 CONTINUE
359 ii = ii + ib
360 ELSE IF( mycol.EQ.icurcol ) THEN
361 jj = jj + ib
362 END IF
363 icurrow = mod( icurrow+1, nprow )
364 icurcol = mod( icurcol+1, npcol )
365 90 CONTINUE
366
367 ELSE
368
369
370
371 ib = in-ia+1
372
373
374
375 IF( mycol.EQ.iacol ) THEN
376 DO 110 k = (jj-1)*lda, (jj+ib-2)*lda, lda
377 IF( ii.LE.iia+np-1 ) THEN
378 DO 100 ll = ii, iia+np-1
379 VALUE =
max(
VALUE, abs( a( ll+k ) ) )
380 100 CONTINUE
381 END IF
382 IF( myrow.EQ.iarow )
383 $ ii = ii + 1
384 110 CONTINUE
385
386
387
388 IF( myrow.EQ.iarow )
389 $ ii = ii - ib
390 END IF
391
392
393
394 IF( myrow.EQ.iarow ) THEN
395 DO 130 k = 0, ib-1
396 IF( jj.GT.jja ) THEN
397 DO 120 ll = (jja-1)*lda, (jj-2)*lda, lda
398 VALUE =
max(
VALUE, abs( a( ii+ll ) ) )
399 120 CONTINUE
400 END IF
401 ii = ii + 1
402 IF( mycol.EQ.iacol )
403 $ jj = jj + 1
404 130 CONTINUE
405 ELSE IF( mycol.EQ.iacol ) THEN
406 jj = jj + ib
407 END IF
408
409 icurrow = mod( iarow+1, nprow )
410 icurcol = mod( iacol+1, npcol )
411
412
413
414 DO 180 i = in+1, ia+n-1, desca( mb_ )
415 ib =
min( desca( mb_ ), ia+n-i )
416
417
418
419 IF( mycol.EQ.icurcol ) THEN
420 DO 150 k = (jj-1)*lda, (jj+ib-2)*lda, lda
421 IF( ii.LE.iia+np-1 ) THEN
422 DO 140 ll = ii, iia+np-1
423 VALUE =
max(
VALUE, abs( a( ll+k ) ) )
424 140 CONTINUE
425 END IF
426 IF( myrow.EQ.icurrow )
427 $ ii = ii + 1
428 150 CONTINUE
429
430
431
432 IF( myrow.EQ.icurrow )
433 $ ii = ii - ib
434 END IF
435
436
437
438 IF( myrow.EQ.icurrow ) THEN
439 DO 170 k = 0, ib-1
440 IF( jj.GT.jja ) THEN
441 DO 160 ll = (jja-1)*lda, (jj-2)*lda, lda
442 VALUE =
max(
VALUE, abs( a( ii+ll ) ) )
443 160 CONTINUE
444 END IF
445 ii = ii + 1
446 IF( mycol.EQ.icurcol )
447 $ jj = jj + 1
448 170 CONTINUE
449 ELSE IF( mycol.EQ.icurcol ) THEN
450 jj = jj + ib
451 END IF
452 icurrow = mod( icurrow+1, nprow )
453 icurcol = mod( icurcol+1, npcol )
454
455 180 CONTINUE
456
457 END IF
458
459
460
461 CALL dgamx2d( ictxt, 'All', ' ', 1, 1, VALUE, 1, i, k, -1,
462 $ iarow, iacol )
463
464
465
466
467 ELSE IF(
lsame( norm,
'I' ) .OR.
lsame( norm,
'O' ) .OR.
468 $ norm.EQ.'1' ) THEN
469
470
471
472
473 IF(
lsame( uplo,
'U' ) )
THEN
474
475
476
477 ib = in-ia+1
478
479
480
481 IF( mycol.EQ.iacol ) THEN
482 ioffa = ( jj - 1 ) * lda
483 DO 200 k = 0, ib-1
484 sum = zero
485 IF( ii.GT.iia ) THEN
486 DO 190 ll = iia, ii-1
487 sum = sum + abs( a( ll+ioffa ) )
488 190 CONTINUE
489 END IF
490 ioffa = ioffa + lda
491 work( jj+k-jja+icsr0 ) = sum
492 IF( myrow.EQ.iarow )
493 $ ii = ii + 1
494 200 CONTINUE
495
496
497
498 IF( myrow.EQ.iarow )
499 $ ii = ii - ib
500
501 END IF
502
503
504
505 IF( myrow.EQ.iarow ) THEN
506 DO 220 k = ii, ii+ib-1
507 sum = zero
508 IF( jja+nq.GT.jj ) THEN
509 DO 210 ll = (jj-1)*lda, (jja+nq-2)*lda, lda
510 sum = sum + abs( a( k+ll ) )
511 210 CONTINUE
512 END IF
513 work( k-iia+irsc0 ) = sum
514 IF( mycol.EQ.iacol )
515 $ jj = jj + 1
516 220 CONTINUE
517 ii = ii + ib
518 ELSE IF( mycol.EQ.iacol ) THEN
519 jj = jj + ib
520 END IF
521
522 icurrow = mod( iarow+1, nprow )
523 icurcol = mod( iacol+1, npcol )
524
525
526
527 DO 270 i = in+1, ia+n-1, desca( mb_ )
528 ib =
min( desca( mb_ ), ia+n-i )
529
530
531
532 IF( mycol.EQ.icurcol ) THEN
533 ioffa = ( jj - 1 ) * lda
534 DO 240 k = 0, ib-1
535 sum = zero
536 IF( ii.GT.iia ) THEN
537 DO 230 ll = iia, ii-1
538 sum = sum + abs( a( ioffa+ll ) )
539 230 CONTINUE
540 END IF
541 ioffa = ioffa + lda
542 work( jj+k-jja+icsr0 ) = sum
543 IF( myrow.EQ.icurrow )
544 $ ii = ii + 1
545 240 CONTINUE
546
547
548
549 IF( myrow.EQ.icurrow )
550 $ ii = ii - ib
551
552 END IF
553
554
555
556 IF( myrow.EQ.icurrow ) THEN
557 DO 260 k = ii, ii+ib-1
558 sum = zero
559 IF( jja+nq.GT.jj ) THEN
560 DO 250 ll = (jj-1)*lda, (jja+nq-2)*lda, lda
561 sum = sum + abs( a( k+ll ) )
562 250 CONTINUE
563 END IF
564 work( k-iia+irsc0 ) = sum
565 IF( mycol.EQ.icurcol )
566 $ jj = jj + 1
567 260 CONTINUE
568 ii = ii + ib
569 ELSE IF( mycol.EQ.icurcol ) THEN
570 jj = jj + ib
571 END IF
572
573 icurrow = mod( icurrow+1, nprow )
574 icurcol = mod( icurcol+1, npcol )
575
576 270 CONTINUE
577
578 ELSE
579
580
581
582 ib = in-ia+1
583
584
585
586 IF( mycol.EQ.iacol ) THEN
587 ioffa = (jj-1)*lda
588 DO 290 k = 0, ib-1
589 sum = zero
590 IF( iia+np.GT.ii ) THEN
591 DO 280 ll = ii, iia+np-1
592 sum = sum + abs( a( ioffa+ll ) )
593 280 CONTINUE
594 END IF
595 ioffa = ioffa + lda
596 work( jj+k-jja+icsr0 ) = sum
597 IF( myrow.EQ.iarow )
598 $ ii = ii + 1
599 290 CONTINUE
600
601
602
603 IF( myrow.EQ.iarow )
604 $ ii = ii - ib
605
606 END IF
607
608
609
610 IF( myrow.EQ.iarow ) THEN
611 DO 310 k = ii, ii+ib-1
612 sum = zero
613 IF( jj.GT.jja ) THEN
614 DO 300 ll = (jja-1)*lda, (jj-2)*lda, lda
615 sum = sum + abs( a( k+ll ) )
616 300 CONTINUE
617 END IF
618 work( k-iia+irsc0 ) = sum
619 IF( mycol.EQ.iacol )
620 $ jj = jj + 1
621 310 CONTINUE
622 ii = ii + ib
623 ELSE IF( mycol.EQ.iacol ) THEN
624 jj = jj + ib
625 END IF
626
627 icurrow = mod( iarow+1, nprow )
628 icurcol = mod( iacol+1, npcol )
629
630
631
632 DO 360 i = in+1, ia+n-1, desca( mb_ )
633 ib =
min( desca( mb_ ), ia+n-i )
634
635
636
637 IF( mycol.EQ.icurcol ) THEN
638 ioffa = ( jj - 1 ) * lda
639 DO 330 k = 0, ib-1
640 sum = zero
641 IF( iia+np.GT.ii ) THEN
642 DO 320 ll = ii, iia+np-1
643 sum = sum + abs( a( ll+ioffa ) )
644 320 CONTINUE
645 END IF
646 ioffa = ioffa + lda
647 work( jj+k-jja+icsr0 ) = sum
648 IF( myrow.EQ.icurrow )
649 $ ii = ii + 1
650 330 CONTINUE
651
652
653
654 IF( myrow.EQ.icurrow )
655 $ ii = ii - ib
656
657 END IF
658
659
660
661 IF( myrow.EQ.icurrow ) THEN
662 DO 350 k = ii, ii+ib-1
663 sum = zero
664 IF( jj.GT.jja ) THEN
665 DO 340 ll = (jja-1)*lda, (jj-2)*lda, lda
666 sum = sum + abs( a( k+ll ) )
667 340 CONTINUE
668 END IF
669 work(k-iia+irsc0) = sum
670 IF( mycol.EQ.icurcol )
671 $ jj = jj + 1
672 350 CONTINUE
673 ii = ii + ib
674 ELSE IF( mycol.EQ.icurcol ) THEN
675 jj = jj + ib
676 END IF
677
678 icurrow = mod( icurrow+1, nprow )
679 icurcol = mod( icurcol+1, npcol )
680
681 360 CONTINUE
682 END IF
683
684
685
686
687
688
689 IF( mycol.EQ.iacol )
690 $ nq = nq + icoff
691 CALL dgsum2d( ictxt, 'Columnwise', ' ', 1, nq, work( icsr ), 1,
692 $ iarow, mycol )
693 IF( myrow.EQ.iarow )
694 $ np = np + iroff
695 CALL dgsum2d( ictxt, 'Rowwise', ' ', np, 1, work( irsc ),
696 $
max( 1, np ), myrow, iacol )
697
698 CALL pdcol2row( ictxt, n, 1, desca( mb_ ), work( irsc ),
699 $
max( 1, np ), work( irsr ),
max( 1, nq ),
700 $ iarow, iacol, iarow, iacol, work( irsc+np ) )
701
702 IF( myrow.EQ.iarow ) THEN
703 IF( mycol.EQ.iacol )
704 $ nq = nq - icoff
705 CALL daxpy( nq, one, work( irsr0 ), 1, work( icsr0 ), 1 )
706 IF( nq.LT.1 ) THEN
707 VALUE = zero
708 ELSE
709 VALUE = work( idamax( nq, work( icsr0 ), 1 ) )
710 END IF
711 CALL dgamx2d( ictxt, 'Rowwise', ' ', 1, 1, VALUE, 1, i, k,
712 $ -1, iarow, iacol )
713 END IF
714
715
716
717
718
719
720 ELSE IF(
lsame( norm,
'F' ) .OR.
lsame( norm,
'E' ) )
THEN
721
722
723
724 ssq(1) = zero
725 ssq(2) = one
726
727
728
729 IF(
lsame( uplo,
'U' ) )
THEN
730
731
732
733 ib = in-ia+1
734
735 IF( mycol.EQ.iacol ) THEN
736 DO 370 k = (jj-1)*lda, (jj+ib-2)*lda, lda
737 colssq(1) = zero
738 colssq(2) = one
739 CALL dlassq( ii-iia, a( iia+k ), 1,
740 $ colssq(1), colssq(2) )
741 IF( myrow.EQ.iarow )
742 $ ii = ii + 1
743 CALL dlassq( ii-iia, a( iia+k ), 1,
744 $ colssq(1), colssq(2) )
746 370 CONTINUE
747
748 jj = jj + ib
749 ELSE IF( myrow.EQ.iarow ) THEN
750 ii = ii + ib
751 END IF
752
753 icurrow = mod( iarow+1, nprow )
754 icurcol = mod( iacol+1, npcol )
755
756
757
758 DO 390 i = in+1, ia+n-1, desca( mb_ )
759 ib =
min( desca( mb_ ), ia+n-i )
760
761 IF( mycol.EQ.icurcol ) THEN
762 DO 380 k = (jj-1)*lda, (jj+ib-2)*lda, lda
763 colssq(1) = zero
764 colssq(2) = one
765 CALL dlassq( ii-iia, a( iia+k ), 1,
766 $ colssq(1), colssq(2) )
767 IF( myrow.EQ.icurrow )
768 $ ii = ii + 1
769 CALL dlassq( ii-iia, a(iia+k ), 1,
770 $ colssq(1), colssq(2) )
772 380 CONTINUE
773
774 jj = jj + ib
775 ELSE IF( myrow.EQ.icurrow ) THEN
776 ii = ii + ib
777 END IF
778
779 icurrow = mod( icurrow+1, nprow )
780 icurcol = mod( icurcol+1, npcol )
781
782 390 CONTINUE
783
784 ELSE
785
786
787
788 ib = in-ia+1
789
790 IF( mycol.EQ.iacol ) THEN
791 DO 400 k = (jj-1)*lda, (jj+ib-2)*lda, lda
792 colssq(1) = zero
793 colssq(2) = one
794 CALL dlassq( iia+np-ii, a( ii+k ), 1,
795 $ colssq(1), colssq(2) )
796 IF( myrow.EQ.iarow )
797 $ ii = ii + 1
798 CALL dlassq( iia+np-ii, a( ii+k ), 1,
799 $ colssq(1), colssq(2) )
801 400 CONTINUE
802
803 jj = jj + ib
804 ELSE IF( myrow.EQ.iarow ) THEN
805 ii = ii + ib
806 END IF
807
808 icurrow = mod( iarow+1, nprow )
809 icurcol = mod( iacol+1, npcol )
810
811
812
813 DO 420 i = in+1, ia+n-1, desca( mb_ )
814 ib =
min( desca( mb_ ), ia+n-i )
815
816 IF( mycol.EQ.icurcol ) THEN
817 DO 410 k = (jj-1)*lda, (jj+ib-2)*lda, lda
818 colssq(1) = zero
819 colssq(2) = one
820 CALL dlassq( iia+np-ii, a( ii+k ), 1,
821 $ colssq(1), colssq(2) )
822 IF( myrow.EQ.icurrow )
823 $ ii = ii + 1
824 CALL dlassq( iia+np-ii, a( ii+k ), 1,
825 $ colssq(1), colssq(2) )
827 410 CONTINUE
828
829 jj = jj + ib
830 ELSE IF( myrow.EQ.icurrow ) THEN
831 ii = ii + ib
832 END IF
833
834 icurrow = mod( icurrow+1, nprow )
835 icurcol = mod( icurcol+1, npcol )
836
837 420 CONTINUE
838
839 END IF
840
841
842
843 CALL pdtreecomb( ictxt,
'All', 2, ssq, iarow, iacol,
845 VALUE = ssq( 1 ) * sqrt( ssq( 2 ) )
846
847 END IF
848
849
850
851 IF( myrow.EQ.iarow .AND. mycol.EQ.iacol ) THEN
852 CALL dgebs2d( ictxt, 'All', ' ', 1, 1, VALUE, 1 )
853 ELSE
854 CALL dgebr2d( ictxt, 'All', ' ', 1, 1, VALUE, 1, iarow,
855 $ iacol )
856 END IF
857
859
860 RETURN
861
862
863
integer function iceil(inum, idenom)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pdcol2row(ictxt, m, n, nb, vs, ldvs, vd, ldvd, rsrc, csrc, rdest, cdest, work)
double precision function pdlansy(norm, uplo, n, a, ia, ja, desca, work)
subroutine dcombssq(v1, v2)
subroutine pdtreecomb(ictxt, scope, n, mine, rdest0, cdest0, subptr)