3
4
5
6
7
8
9
10 INTEGER IA, INFO, JA, LWORK, M, N
11
12
13 INTEGER DESCA( * )
14 REAL 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 REAL ONE, ZERO
244 parameter( one = 1.0e+0, zero = 0.0e+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 REAL ALPHA
252
253
254 INTEGER DESCD( DLEN_ ), DESCE( DLEN_ )
255
256
259 $
pxerbla, sgebr2d, sgebs2d, slarfg
260
261
262 INTEGER INDXG2P, NUMROC
264
265
266 INTRINSIC max,
min, mod, real
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 ) = real( 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,
'PSGEBD2', -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 slarfg( 1, a( i ), a( i ), 1, tauq( jj ) )
321 d( jj ) = a( i )
322 CALL sgebs2d( ictxt, 'Columnwise', ' ', 1, 1, d( jj ),
323 $ 1 )
324 CALL sgebs2d( ictxt, 'Columnwise', ' ', 1, 1, tauq( jj ),
325 $ 1 )
326 ELSE
327 CALL sgebr2d( ictxt, 'Columnwise', ' ', 1, 1, d( jj ),
328 $ 1, iarow, iacol )
329 CALL sgebr2d( 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 pslarfg( m-k+1, alpha, i, j, a,
min( i+1, m+ia-1 ),
357 $ j, desca, 1, tauq )
358 CALL pselset( d, 1, j, descd, alpha )
359 CALL pselset( a, i, j, desca, one )
360
361
362
363 CALL pslarf(
'Left', m-k+1, n-k, a, i, j, desca, 1, tauq, a,
364 $ i, j+1, desca, work )
365 CALL pselset( a, i, j, desca, alpha )
366
367 IF( k.LT.n ) THEN
368
369
370
371
372 CALL pslarfg( n-k, alpha, i, j+1, a, i,
373 $
min( j+2, ja+n-1 ), desca, desca( m_ ),
374 $ taup )
375 CALL pselset( e, i, 1, desce, alpha )
376 CALL pselset( a, i, j+1, desca, one )
377
378
379
380 CALL pslarf(
'Right', m-k, n-k, a, i, j+1, desca,
381 $ desca( m_ ), taup, a, i+1, j+1, desca,
382 $ work )
383 CALL pselset( a, i, j+1, desca, alpha )
384 ELSE
385 CALL pselset( 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 pslarfg( n-k+1, alpha, i, j, a, i,
406 $
min( j+1, ja+n-1 ), desca, desca( m_ ), taup )
407 CALL pselset( d, i, 1, descd, alpha )
408 CALL pselset( a, i, j, desca, one )
409
410
411
412 CALL pslarf(
'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 pselset( a, i, j, desca, alpha )
416
417 IF( k.LT.m ) THEN
418
419
420
421
422 CALL pslarfg( m-k, alpha, i+1, j, a,
423 $
min( i+2, ia+m-1 ), j, desca, 1, tauq )
424 CALL pselset( e, 1, j, desce, alpha )
425 CALL pselset( a, i+1, j, desca, one )
426
427
428
429 CALL pslarf(
'Left', m-k, n-k, a, i+1, j, desca, 1, tauq,
430 $ a, i+1, j+1, desca, work )
431 CALL pselset( a, i+1, j, desca, alpha )
432 ELSE
433 CALL pselset( tauq, 1, j, desce, zero )
434 END IF
435 20 CONTINUE
436 END IF
437
438 work( 1 ) = real( 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 pselset(a, ia, ja, desca, alpha)
subroutine pslarf(side, m, n, v, iv, jv, descv, incv, tau, c, ic, jc, descc, work)
subroutine pslarfg(n, alpha, iax, jax, x, ix, jx, descx, incx, tau)
subroutine pxerbla(ictxt, srname, info)