3
4
5
6
7
8
9
10 INTEGER IA, INFO, JA, K, LWORK, M, N
11
12
13 INTEGER DESCA( * )
14 REAL A( * ), TAU( * ), 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
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
158 $ LLD_, MB_, M_, NB_, N_, RSRC_
159 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
160 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
161 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
162 REAL ZERO
163 parameter( zero = 0.0e+0 )
164
165
166 LOGICAL LQUERY
167 CHARACTER COLBTOP, ROWBTOP
168 INTEGER I, IACOL, IAROW, IB, ICTXT, IINFO, IL, IN, IPW,
169 $ J, LWMIN, MPA0, MYCOL, MYROW, NPCOL, NPROW,
170 $ NQA0
171
172
173 INTEGER IDUM1( 2 ), IDUM2( 2 )
174
175
179
180
181 INTEGER ICEIL, INDXG2P, NUMROC
183
184
185 INTRINSIC max,
min, mod, real
186
187
188
189
190
191 ictxt = desca( ctxt_ )
192 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
193
194
195
196 info = 0
197 IF( nprow.EQ.-1 ) THEN
198 info = -(700+ctxt_)
199 ELSE
200 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 7, info )
201 IF( info.EQ.0 ) THEN
202 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
203 $ nprow )
204 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
205 $ npcol )
206 mpa0 =
numroc( m+mod( ia-1, desca( mb_ ) ), desca( mb_ ),
207 $ myrow, iarow, nprow )
208 nqa0 =
numroc( n+mod( ja-1, desca( nb_ ) ), desca( nb_ ),
209 $ mycol, iacol, npcol )
210 lwmin = desca( mb_ ) * ( mpa0 + nqa0 + desca( mb_ ) )
211
212 work( 1 ) = real( lwmin )
213 lquery = ( lwork.EQ.-1 )
214 IF( n.LT.m ) THEN
215 info = -2
216 ELSE IF( k.LT.0 .OR. k.GT.m ) THEN
217 info = -3
218 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
219 info = -10
220 END IF
221 END IF
222 idum1( 1 ) = k
223 idum2( 1 ) = 3
224 IF( lwork.EQ.-1 ) THEN
225 idum1( 2 ) = -1
226 ELSE
227 idum1( 2 ) = 1
228 END IF
229 idum2( 2 ) = 10
230 CALL pchk1mat( m, 1, n, 2, ia, ja, desca, 7, 2, idum1, idum2,
231 $ info )
232 END IF
233
234 IF( info.NE.0 ) THEN
235 CALL pxerbla( ictxt,
'PSORGLQ', -info )
236 RETURN
237 ELSE IF( lquery ) THEN
238 RETURN
239 END IF
240
241
242
243 IF( m.LE.0 )
244 $ RETURN
245
246 ipw = desca( mb_ ) * desca( mb_ ) + 1
247 in =
min(
iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+k-1 )
248 il =
max( ( (ia+k-2) / desca( mb_ ) ) * desca( mb_ ) + 1, ia )
249 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
250 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
251 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', ' ' )
252 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'D-ring' )
253
254 CALL pslaset(
'All', ia+m-il, il-ia, zero, zero, a, il, ja,
255 $ desca )
256
257
258
259 CALL psorgl2( ia+m-il, n-il+ia, ia+k-il, a, il, ja+il-ia, desca,
260 $ tau, work, lwork, iinfo )
261
262
263
264 IF( il.GT.in+1 ) THEN
265
266
267
268 DO 10 i = il-desca( mb_ ), in+1, -desca( mb_ )
269 ib =
min( desca( mb_ ), ia+m-i )
270 j = ja + i - ia
271
272 IF( i+ib.LE.ia+m-1 ) THEN
273
274
275
276
277 CALL pslarft(
'Forward',
'Rowwise', n-i+ia, ib, a, i, j,
278 $ desca, tau, work, work( ipw ) )
279
280
281
282 CALL pslarfb(
'Right',
'Transpose',
'Forward',
'Rowwise',
283 $ m-i-ib+ia, n-i+ia, ib, a, i, j, desca,
284 $ work, a, i+ib, j, desca, work( ipw ) )
285 END IF
286
287
288
289 CALL psorgl2( ib, n-i+ia, ib, a, i, j, desca, tau, work,
290 $ lwork, iinfo )
291
292
293
294 CALL pslaset(
'All', ib, i-ia, zero, zero, a, i, ja, desca )
295 10 CONTINUE
296
297 END IF
298
299
300
301 IF( il.GT.ia ) THEN
302
303 ib = in - ia + 1
304
305
306
307
308 CALL pslarft(
'Forward',
'Rowwise', n, ib, a, ia, ja, desca,
309 $ tau, work, work( ipw ) )
310
311
312
313 CALL pslarfb(
'Right',
'Transpose',
'Forward',
'Rowwise', m-ib,
314 $ n, ib, a, ia, ja, desca, work, a, ia+ib, ja,
315 $ desca, work( ipw ) )
316
317
318
319 CALL psorgl2( ib, n, ib, a, ia, ja, desca, tau, work, lwork,
320 $ iinfo )
321
322 END IF
323
324 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
325 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
326
327 work( 1 ) = real( lwmin )
328
329 RETURN
330
331
332
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
integer function iceil(inum, idenom)
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 pslaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
subroutine pslarfb(side, trans, direct, storev, m, n, k, v, iv, jv, descv, t, c, ic, jc, descc, work)
subroutine pslarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)
subroutine psorgl2(m, n, k, a, ia, ja, desca, tau, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)