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