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