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