3
4
5
6
7
8
9
10 INTEGER IA, INFO, JA, LWORK, M, N
11
12
13 INTEGER DESCA( * )
14 DOUBLE PRECISION A( * ), D( * ), E( * ), TAUP( * ), TAUQ( * ),
15 $ WORK( * )
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
240 $ LLD_, MB_, M_, NB_, N_, RSRC_
241 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
242 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
243 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
244 DOUBLE PRECISION ONE
245 parameter( one = 1.0d+0 )
246
247
248 LOGICAL LQUERY
249 CHARACTER COLCTOP, ROWCTOP
250 INTEGER I, IACOL, IAROW, ICTXT, IINFO, IOFF, IPW, IPY,
251 $ IW, J, JB, JS, JW, K, L, LWMIN, MN, MP, MYCOL,
252 $ MYROW, NB, NPCOL, NPROW, NQ
253
254
255 INTEGER DESCWX( DLEN_ ), DESCWY( DLEN_ ), IDUM1( 1 ),
256 $ IDUM2( 1 )
257
258
261 $ pb_topget, pb_topset,
pxerbla
262
263
264 INTEGER INDXG2L, INDXG2P, NUMROC
266
267
268 INTRINSIC dble,
max,
min, mod
269
270
271
272
273
274 ictxt = desca( ctxt_ )
275 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
276
277
278
279 info = 0
280 IF( nprow.EQ.-1 ) THEN
281 info = -(600+ctxt_)
282 ELSE
283 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 6, info )
284 IF( info.EQ.0 ) THEN
285 nb = desca( mb_ )
286 ioff = mod( ia-1, desca( mb_ ) )
287 iarow =
indxg2p( ia, nb, myrow, desca( rsrc_ ), nprow )
288 iacol =
indxg2p( ja, nb, mycol, desca( csrc_ ), npcol )
289 mp =
numroc( m+ioff, nb, myrow, iarow, nprow )
290 nq =
numroc( n+ioff, nb, mycol, iacol, npcol )
291 lwmin = nb*( mp+nq+1 ) + nq
292
293 work( 1 ) = dble( lwmin )
294 lquery = ( lwork.EQ.-1 )
295 IF( ioff.NE.mod( ja-1, desca( nb_ ) ) ) THEN
296 info = -5
297 ELSE IF( nb.NE.desca( nb_ ) ) THEN
298 info = -(600+nb_)
299 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
300 info = -12
301 END IF
302 END IF
303 IF( lquery ) THEN
304 idum1( 1 ) = -1
305 ELSE
306 idum1( 1 ) = 1
307 END IF
308 idum2( 1 ) = 12
309 CALL pchk1mat( m, 1, n, 2, ia, ja, desca, 6, 1, idum1, idum2,
310 $ info )
311 END IF
312
313 IF( info.LT.0 ) THEN
314 CALL pxerbla( ictxt,
'PDGEBRD', -info )
315 RETURN
316 ELSE IF( lquery ) THEN
317 RETURN
318 END IF
319
320
321
323 IF( mn.EQ.0 )
324 $ RETURN
325
326
327
328 CALL pb_topget( ictxt, 'Combine', 'Columnwise', colctop )
329 CALL pb_topget( ictxt, 'Combine', 'Rowwise', rowctop )
330 CALL pb_topset( ictxt, 'Combine', 'Columnwise', '1-tree' )
331 CALL pb_topset( ictxt, 'Combine', 'Rowwise', '1-tree' )
332
333 ipy = mp * nb + 1
334 ipw = nq * nb + ipy
335
336 CALL descset( descwx, m+ioff, nb, nb, nb, iarow, iacol, ictxt,
338 CALL descset( descwy, nb, n+ioff, nb, nb, iarow, iacol, ictxt,
339 $ nb )
340
341 mp =
numroc( m+ia-1, nb, myrow, desca( rsrc_ ), nprow )
342 nq =
numroc( n+ja-1, nb, mycol, desca( csrc_ ), npcol )
343 k = 1
344 jb = nb - ioff
345 iw = ioff + 1
346 jw = ioff + 1
347
348 DO 10 l = 1, mn+ioff-nb, nb
349 i = ia + k - 1
350 j = ja + k - 1
351
352
353
354
355
356 CALL pdlabrd( m-k+1, n-k+1, jb, a, i, j, desca, d, e, tauq,
357 $ taup, work, iw, jw, descwx, work( ipy ), iw,
358 $ jw, descwy, work( ipw ) )
359
360
361
362
363 CALL pdgemm( 'No transpose', 'No transpose', m-k-jb+1,
364 $ n-k-jb+1, jb, -one, a, i+jb, j, desca,
365 $ work( ipy ), iw, jw+jb, descwy, one, a, i+jb,
366 $ j+jb, desca )
367 CALL pdgemm( 'No transpose', 'No transpose', m-k-jb+1,
368 $ n-k-jb+1, jb, -one, work, iw+jb, jw, descwx, a, i,
369 $ j+jb, desca, one, a, i+jb, j+jb, desca )
370
371
372
373 IF( m.GE.n ) THEN
374 js =
min(
indxg2l( i+jb-1, nb, 0, desca( rsrc_ ), nprow ),
375 $ mp )
376 IF( js.GT.0 )
377 $
CALL pdelset( a, i+jb-1, j+jb, desca, e( js ) )
378 ELSE
379 js =
min(
indxg2l( j+jb-1, nb, 0, desca( csrc_ ), npcol ),
380 $ nq )
381 IF( js.GT.0 )
382 $
CALL pdelset( a, i+jb, j+jb-1, desca, e( js ) )
383 END IF
384
385 k = k + jb
386 jb = nb
387 iw = 1
388 jw = 1
389 descwx( m_ ) = descwx( m_ ) - jb
390 descwx( rsrc_ ) = mod( descwx( rsrc_ ) + 1, nprow )
391 descwx( csrc_ ) = mod( descwx( csrc_ ) + 1, npcol )
392 descwy( n_ ) = descwy( n_ ) - jb
393 descwy( rsrc_ ) = mod( descwy( rsrc_ ) + 1, nprow )
394 descwy( csrc_ ) = mod( descwy( csrc_ ) + 1, npcol )
395
396 10 CONTINUE
397
398
399
400 CALL pdgebd2( m-k+1, n-k+1, a, ia+k-1, ja+k-1, desca, d, e, tauq,
401 $ taup, work, lwork, iinfo )
402
403 CALL pb_topset( ictxt, 'Combine', 'Columnwise', colctop )
404 CALL pb_topset( ictxt, 'Combine', 'Rowwise', rowctop )
405
406 work( 1 ) = dble( lwmin )
407
408 RETURN
409
410
411
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
integer function indxg2l(indxglob, nb, iproc, isrcproc, nprocs)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
subroutine pdelset(a, ia, ja, desca, alpha)
subroutine pdgebd2(m, n, a, ia, ja, desca, d, e, tauq, taup, work, lwork, info)
subroutine pdlabrd(m, n, nb, a, ia, ja, desca, d, e, tauq, taup, x, ix, jx, descx, y, iy, jy, descy, work)
subroutine pxerbla(ictxt, srname, info)