3
4
5
6
7
8
9
10 CHARACTER SCOPE
11 INTEGER CDEST0, ICTXT, N, RDEST0
12
13
14 DOUBLE PRECISION MINE( * )
15
16
17 EXTERNAL subptr
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 LOGICAL BCAST, RSCOPE, CSCOPE
61 INTEGER CMSSG, DEST, DIST, HISDIST, I, IAM, MYCOL,
62 $ MYROW, MYDIST, MYDIST2, NP, NPCOL, NPROW,
63 $ RMSSG, TCDEST, TRDEST
64
65
66 DOUBLE PRECISION HIS( 2 )
67
68
69 EXTERNAL blacs_gridinfo, dgebr2d, dgebs2d,
70 $ dgerv2d, dgesd2d
71
72
73 LOGICAL LSAME
75
76
77 INTRINSIC mod
78
79
80
81 dest = 0
82
83
84
85 bcast = ( ( rdest0.EQ.-1 ).OR.( cdest0.EQ.-1 ) )
86 IF( bcast ) THEN
87 trdest = 0
88 tcdest = 0
89 ELSE
90 trdest = rdest0
91 tcdest = cdest0
92 END IF
93
94
95
96 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
97
98
99
100 rscope =
lsame( scope,
'R' )
101 cscope =
lsame( scope,
'C' )
102
103 IF( rscope ) THEN
104 IF( bcast ) THEN
105 trdest = myrow
106 ELSE IF( myrow.NE.trdest ) THEN
107 RETURN
108 END IF
109 np = npcol
110 mydist = mod( npcol + mycol - tcdest, npcol )
111 ELSE IF( cscope ) THEN
112 IF( bcast ) THEN
113 tcdest = mycol
114 ELSE IF( mycol.NE.tcdest ) THEN
115 RETURN
116 END IF
117 np = nprow
118 mydist = mod( nprow + myrow - trdest, nprow )
119 ELSE IF(
lsame( scope,
'A' ) )
THEN
120 np = nprow * npcol
121 iam = myrow*npcol + mycol
122 dest = trdest*npcol + tcdest
123 mydist = mod( np + iam - dest, np )
124 ELSE
125 RETURN
126 END IF
127
128 IF( np.LT.2 )
129 $ RETURN
130
131 mydist2 = mydist
132 rmssg = myrow
133 cmssg = mycol
134 i = 1
135
136 10 CONTINUE
137
138 IF( mod( mydist, 2 ).NE.0 ) THEN
139
140
141
142 dist = i * ( mydist - mod( mydist, 2 ) )
143
144
145
146 IF( rscope ) THEN
147 cmssg = mod( tcdest + dist, np )
148 ELSE IF( cscope ) THEN
149 rmssg = mod( trdest + dist, np )
150 ELSE
151 cmssg = mod( dest + dist, np )
152 rmssg = cmssg / npcol
153 cmssg = mod( cmssg, npcol )
154 END IF
155
156 CALL dgesd2d( ictxt, n, 1, mine, n, rmssg, cmssg )
157
158 GO TO 20
159
160 ELSE
161
162
163
164
165 dist = mydist2 + i
166 IF( rscope ) THEN
167 cmssg = mod( tcdest + dist, np )
168 hisdist = mod( np + cmssg - tcdest, np )
169 ELSE IF( cscope ) THEN
170 rmssg = mod( trdest + dist, np )
171 hisdist = mod( np + rmssg - trdest, np )
172 ELSE
173 cmssg = mod( dest + dist, np )
174 rmssg = cmssg / npcol
175 cmssg = mod( cmssg, npcol )
176 hisdist = mod( np + rmssg*npcol+cmssg - dest, np )
177 END IF
178
179 IF( mydist2.LT.hisdist ) THEN
180
181
182
183 CALL dgerv2d( ictxt, n, 1, his, n, rmssg, cmssg )
184 CALL subptr( mine, his )
185
186 END IF
187 mydist = mydist / 2
188
189 END IF
190 i = i * 2
191
192 IF( i.LT.np )
193 $ GO TO 10
194
195 20 CONTINUE
196
197 IF( bcast ) THEN
198 IF( mydist2.EQ.0 ) THEN
199 CALL dgebs2d( ictxt, scope, ' ', n, 1, mine, n )
200 ELSE
201 CALL dgebr2d( ictxt, scope, ' ', n, 1, mine, n,
202 $ trdest, tcdest )
203 END IF
204 END IF
205
206 RETURN
207
208
209