3
4
5
6
7
8
9
10 INTEGER CDEST, CSRC, ICTXT, LDVD, LDVS, M, N, NB,
11 $ RDEST, RSRC
12
13
14 INTEGER 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, igesd2d, igerv2d,
ilacpy
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 ilacpy(
'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 igesd2d( 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 igerv2d( 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 ilacpy(
'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 ilacpy(
'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 igesd2d( ictxt, mq, n, vs, ldvs, irdest, cdest )
245 ELSE
246 CALL ilacpy(
'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 igerv2d( ictxt, mp, n, vd, ldvd, rsrc, icsrc )
259 END IF
260 END IF
261
262 RETURN
263
264
265
subroutine ilacpy(uplo, m, n, a, lda, b, ldb)
integer function ilcm(m, n)
integer function numroc(n, nb, iproc, isrcproc, nprocs)