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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
239 $ LLD_, MB_, M_, NB_, N_, RSRC_
240 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
241 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
242 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
243 DOUBLE PRECISION ONE, ZERO
244 parameter( one = 1.0d+0, zero = 0.0d+0 )
245
246
247 LOGICAL LQUERY
248 INTEGER I, IACOL, IAROW, ICOFFA, ICTXT, II, IROFFA, J,
249 $ JJ, K, LWMIN, MPA0, MYCOL, MYROW, NPCOL, NPROW,
250 $ NQA0
251 DOUBLE PRECISION ALPHA
252
253
254 INTEGER DESCD( DLEN_ ), DESCE( DLEN_ )
255
256
258 $ dgebr2d, dgebs2d, dlarfg,
infog2l,
260
261
262 INTEGER INDXG2P, NUMROC
264
265
266 INTRINSIC dble,
max,
min, mod
267
268
269
270
271
272 ictxt = desca( ctxt_ )
273 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
274
275
276
277 info = 0
278 IF( nprow.EQ.-1 ) THEN
279 info = -(600+ctxt_)
280 ELSE
281 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 6, info )
282 IF( info.EQ.0 ) THEN
283 iroffa = mod( ia-1, desca( mb_ ) )
284 icoffa = mod( ja-1, desca( nb_ ) )
285 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
286 $ nprow )
287 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
288 $ npcol )
289 mpa0 =
numroc( m+iroffa, desca( mb_ ), myrow, iarow, nprow )
290 nqa0 =
numroc( n+icoffa, desca( nb_ ), mycol, iacol, npcol )
291 lwmin =
max( mpa0, nqa0 )
292
293 work( 1 ) = dble( lwmin )
294 lquery = ( lwork.EQ.-1 )
295 IF( iroffa.NE.icoffa ) THEN
296 info = -5
297 ELSE IF( desca( mb_ ).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 END IF
304
305 IF( info.LT.0 ) THEN
306 CALL pxerbla( ictxt,
'PDGEBD2', -info )
307 CALL blacs_abort( ictxt, 1 )
308 RETURN
309 ELSE IF( lquery ) THEN
310 RETURN
311 END IF
312
313 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, ii, jj,
314 $ iarow, iacol )
315
316 IF( m.EQ.1 .AND. n.EQ.1 ) THEN
317 IF( mycol.EQ.iacol ) THEN
318 IF( myrow.EQ.iarow ) THEN
319 i = ii+(jj-1)*desca( lld_ )
320 CALL dlarfg( 1, a( i ), a( i ), 1, tauq( jj ) )
321 d( jj ) = a( i )
322 CALL dgebs2d( ictxt, 'Columnwise', ' ', 1, 1, d( jj ),
323 $ 1 )
324 CALL dgebs2d( ictxt, 'Columnwise', ' ', 1, 1, tauq( jj ),
325 $ 1 )
326 ELSE
327 CALL dgebr2d( ictxt, 'Columnwise', ' ', 1, 1, d( jj ),
328 $ 1, iarow, iacol )
329 CALL dgebr2d( ictxt, 'Columnwise', ' ', 1, 1, tauq( jj ),
330 $ 1, iarow, iacol )
331 END IF
332 END IF
333 IF( myrow.EQ.iarow )
334 $ taup( ii ) = zero
335 RETURN
336 END IF
337
338 alpha = zero
339
340 IF( m.GE.n ) THEN
341
342
343
344 CALL descset( descd, 1, ja+
min(m,n)-1, 1, desca( nb_ ), myrow,
345 $ desca( csrc_ ), desca( ctxt_ ), 1 )
346 CALL descset( desce, ia+
min(m,n)-1, 1, desca( mb_ ), 1,
347 $ desca( rsrc_ ), mycol, desca( ctxt_ ),
348 $ desca( lld_ ) )
349 DO 10 k = 1, n
350 i = ia + k - 1
351 j = ja + k - 1
352
353
354
355
356 CALL pdlarfg( m-k+1, alpha, i, j, a,
min( i+1, m+ia-1 ),
357 $ j, desca, 1, tauq )
358 CALL pdelset( d, 1, j, descd, alpha )
359 CALL pdelset( a, i, j, desca, one )
360
361
362
363 CALL pdlarf(
'Left', m-k+1, n-k, a, i, j, desca, 1, tauq, a,
364 $ i, j+1, desca, work )
365 CALL pdelset( a, i, j, desca, alpha )
366
367 IF( k.LT.n ) THEN
368
369
370
371
372 CALL pdlarfg( n-k, alpha, i, j+1, a, i,
373 $
min( j+2, ja+n-1 ), desca, desca( m_ ),
374 $ taup )
375 CALL pdelset( e, i, 1, desce, alpha )
376 CALL pdelset( a, i, j+1, desca, one )
377
378
379
380 CALL pdlarf(
'Right', m-k, n-k, a, i, j+1, desca,
381 $ desca( m_ ), taup, a, i+1, j+1, desca,
382 $ work )
383 CALL pdelset( a, i, j+1, desca, alpha )
384 ELSE
385 CALL pdelset( taup, i, 1, desce, zero )
386 END IF
387 10 CONTINUE
388
389 ELSE
390
391
392
393 CALL descset( descd, ia+
min(m,n)-1, 1, desca( mb_ ), 1,
394 $ desca( rsrc_ ), mycol, desca( ctxt_ ),
395 $ desca( lld_ ) )
396 CALL descset( desce, 1, ja+
min(m,n)-1, 1, desca( nb_ ), myrow,
397 $ desca( csrc_ ), desca( ctxt_ ), 1 )
398 DO 20 k = 1, m
399 i = ia + k - 1
400 j = ja + k - 1
401
402
403
404
405 CALL pdlarfg( n-k+1, alpha, i, j, a, i,
406 $
min( j+1, ja+n-1 ), desca, desca( m_ ), taup )
407 CALL pdelset( d, i, 1, descd, alpha )
408 CALL pdelset( a, i, j, desca, one )
409
410
411
412 CALL pdlarf(
'Right', m-k, n-k+1, a, i, j, desca,
413 $ desca( m_ ), taup, a,
min( i+1, ia+m-1 ), j,
414 $ desca, work )
415 CALL pdelset( a, i, j, desca, alpha )
416
417 IF( k.LT.m ) THEN
418
419
420
421
422 CALL pdlarfg( m-k, alpha, i+1, j, a,
423 $
min( i+2, ia+m-1 ), j, desca, 1, tauq )
424 CALL pdelset( e, 1, j, desce, alpha )
425 CALL pdelset( a, i+1, j, desca, one )
426
427
428
429 CALL pdlarf(
'Left', m-k, n-k, a, i+1, j, desca, 1, tauq,
430 $ a, i+1, j+1, desca, work )
431 CALL pdelset( a, i+1, j, desca, alpha )
432 ELSE
433 CALL pdelset( tauq, 1, j, desce, zero )
434 END IF
435 20 CONTINUE
436 END IF
437
438 work( 1 ) = dble( lwmin )
439
440 RETURN
441
442
443
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pdelset(a, ia, ja, desca, alpha)
subroutine pdlarf(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
subroutine pdlarfg(n, alpha, iax, jax, x, ix, jx, descx, incx, tau)
subroutine pxerbla(ictxt, srname, info)