3
4
5
6
7
8
9
10 INTEGER CDEST, CSRC, ICTXT, LDVD, LDVS, M, N, NB,
11 $ RDEST, RSRC
12
13
14 DOUBLE PRECISION VD( LDVD, * ), VS( LDVS, * ), 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 INTEGER CBLKSKIP, ICPY, II, ISTART, ICSRC, IRDEST, JB,
97 $ JJ, K, LCM, MP, MQ, MYCOL, MYDIST, MYROW,
98 $ NBLOCKS, NPCOL, NPROW, RBLKSKIP
99
100
101 EXTERNAL blacs_gridinfo, dgesd2d, dgerv2d, dlacpy
102
103
104 INTEGER ILCM, NUMROC
106
107
108
109
110
111
112 icpy = 0
113
114 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
115
116
117
118
119 IF( nprow .NE. npcol ) THEN
120 lcm =
ilcm( nprow, npcol )
121 rblkskip = lcm / npcol
122 cblkskip = lcm / nprow
123
124
125
126 IF( myrow.EQ.rsrc ) THEN
127
128 istart = 1
129
130
131
132
133 mydist = mod( npcol+mycol-csrc, npcol )
134 mq =
numroc( m, nb, mycol, csrc, npcol )
135 irdest = mod( rdest+mydist, nprow )
136
137
138
139 DO 20 k = 1, rblkskip
140 jj = 1
141
142
143
144 IF( (myrow.NE.irdest).OR.(mycol.NE.cdest) ) THEN
145
146
147
148 DO 10 ii = istart, mq, nb*rblkskip
149 jb =
min( nb, mq-ii+1 )
150 CALL dlacpy( 'G', jb, n, vs(ii,1), ldvs,
151 $ work(jj), jb )
152 jj = jj + nb*n
153 10 CONTINUE
154
155
156
157
158 jj = jj - 1
159 IF( jj.GT.0 )
160 $ CALL dgesd2d( ictxt, jj, 1, work, jj, irdest,
161 $ cdest )
162
163
164
165
166 ELSE
167 icpy = istart
168 END IF
169
170 istart = istart + nb
171 irdest = mod( irdest+npcol, nprow )
172 20 CONTINUE
173 END IF
174
175
176
177 IF( mycol.EQ.cdest ) THEN
178
179 istart = 1
180
181
182
183
184 mydist = mod( nprow+myrow-rdest, nprow )
185 mp =
numroc( m, nb, myrow, rdest, nprow )
186 icsrc = mod( csrc+mydist, npcol )
187
188
189
190 DO 50 k = 1, cblkskip
191
192
193
194 IF( (myrow.NE.rsrc).OR.(mycol.NE.icsrc) ) THEN
195
196
197
198
199 nblocks = (mp - istart + nb) / nb
200 jj = ((nblocks+cblkskip-1) / cblkskip)*nb
201 IF( jj.GT.0 )
202 $ CALL dgerv2d( ictxt, jj, n, work, jj, rsrc, icsrc )
203
204
205
206 jj = 1
207 DO 30 ii = istart, mp, nb*cblkskip
208 jb =
min( nb, mp-ii+1 )
209 CALL dlacpy( 'G', jb, n, work(jj), jb, vd(ii,1),
210 $ ldvd )
211 jj = jj + nb*n
212 30 CONTINUE
213
214
215
216 ELSE
217 jj = icpy
218 DO 40 ii = istart, mp, nb*cblkskip
219 jb =
min( nb, mp-ii+1 )
220 CALL dlacpy( 'G', jb, n, vs(jj,1), ldvs, vd(ii,1),
221 $ ldvd )
222 jj = jj + nb*rblkskip
223 40 CONTINUE
224 END IF
225 istart = istart + nb
226 icsrc = mod( icsrc+nprow, npcol )
227 50 CONTINUE
228 END IF
229
230
231
232
233 ELSE
234
235 IF( myrow.EQ.rsrc ) THEN
236
237
238
239
240 mydist = mod( npcol+mycol-csrc, npcol )
241 mq =
numroc( m, nb, mycol, csrc, npcol )
242 irdest = mod( rdest+mydist, nprow )
243 IF( (myrow.NE.irdest).OR.(mycol.NE.cdest) ) THEN
244 CALL dgesd2d( ictxt, mq, n, vs, ldvs, irdest, cdest )
245 ELSE
246 CALL dlacpy( 'G', mq, n, vs, ldvs, vd, ldvd )
247 END IF
248 END IF
249 IF( mycol.EQ.cdest ) THEN
250
251
252
253
254 mydist = mod( nprow+myrow-rdest, nprow )
255 mp =
numroc( m, nb, myrow, rdest, nprow )
256 icsrc = mod( csrc+mydist, npcol )
257 IF( (mycol.NE.icsrc).OR.(myrow.NE. rsrc) )
258 $ CALL dgerv2d( ictxt, mp, n, vd, ldvd, rsrc, icsrc )
259 END IF
260 END IF
261
262 RETURN
263
264
265
integer function ilcm(m, n)
integer function numroc(n, nb, iproc, isrcproc, nprocs)