3
4
5
6
7
8
9
10 CHARACTER SIDE, TRANS
11 INTEGER IA, IC, INFO, JA, JC, K, L, LWORK, M, N
12
13
14 INTEGER DESCA( * ), DESCC( * )
15 DOUBLE PRECISION A( * ), C( * ), TAU( * ), 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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
225 $ LLD_, MB_, M_, NB_, N_, RSRC_
226 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
227 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
228 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
229
230
231 LOGICAL LEFT, LQUERY, NOTRAN
232 CHARACTER COLBTOP, ROWBTOP, TRANST
233 INTEGER I, I1, I2, I3, IACOL, IB, ICC, ICCOL, ICOFFA,
234 $ ICOFFC, ICROW, ICTXT, IINFO, IPW, IROFFC, JAA,
235 $ JCC, LCM, LCMP, LWMIN, MI, MPC0, MQA0, MYCOL,
236 $ MYROW, NI, NPCOL, NPROW, NQ, NQC0
237
238
239 INTEGER IDUM1( 5 ), IDUM2( 5 )
240
241
244
245
246 LOGICAL LSAME
247 INTEGER ICEIL, ILCM, INDXG2P, NUMROC
249
250
251 INTRINSIC dble, ichar,
max,
min, mod
252
253
254
255
256
257 ictxt = desca( ctxt_ )
258 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
259
260
261
262 info = 0
263 IF( nprow.EQ.-1 ) THEN
264 info = -(900+ctxt_)
265 ELSE
266 left =
lsame( side,
'L' )
267 notran =
lsame( trans,
'N' )
268
269
270
271 IF( left ) THEN
272 nq = m
273 CALL chk1mat( k, 5, m, 3, ia, ja, desca, 10, info )
274 ELSE
275 nq = n
276 CALL chk1mat( k, 5, n, 4, ia, ja, desca, 10, info )
277 END IF
278 CALL chk1mat( m, 3, n, 4, ic, jc, descc, 15, info )
279 IF( info.EQ.0 ) THEN
280 icoffa = mod( ja-1, desca( nb_ ) )
281 iroffc = mod( ic-1, descc( mb_ ) )
282 icoffc = mod( jc-1, descc( nb_ ) )
283 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
284 $ npcol )
285 icrow =
indxg2p( ic, descc( mb_ ), myrow, descc( rsrc_ ),
286 $ nprow )
287 iccol =
indxg2p( jc, descc( nb_ ), mycol, descc( csrc_ ),
288 $ npcol )
289 mpc0 =
numroc( m+iroffc, descc( mb_ ), myrow, icrow, nprow )
290 nqc0 =
numroc( n+icoffc, descc( nb_ ), mycol, iccol, npcol )
291
292 IF( left ) THEN
293 mqa0 =
numroc( m+icoffa, desca( nb_ ), mycol, iacol,
294 $ npcol )
295 lcm =
ilcm( nprow, npcol )
296 lcmp = lcm / nprow
297 lwmin =
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) )
299 $ m+iroffc, desca( mb_ ), 0, 0, nprow ),
300 $ desca( mb_ ), 0, 0, lcmp ), nqc0 ) ) *
301 $ desca( mb_ ) ) + desca( mb_ ) * desca( mb_ )
302 ELSE
303 lwmin =
max( ( desca( mb_ ) * ( desca( mb_ ) - 1 ) ) / 2,
304 $ ( mpc0 + nqc0 ) * desca( mb_ ) ) +
305 $ desca( mb_ ) * desca( mb_ )
306 END IF
307
308 work( 1 ) = dble( lwmin )
309 lquery = ( lwork.EQ.-1 )
310 IF( .NOT.left .AND. .NOT.
lsame( side,
'R' ) )
THEN
311 info = -1
312 ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans,
'T' ) )
THEN
313 info = -2
314 ELSE IF( k.LT.0 .OR. k.GT.nq ) THEN
315 info = -5
316 ELSE IF( k.LT.0 .OR. k.GT.nq ) THEN
317 info = -6
318 ELSE IF( left .AND. desca( nb_ ).NE.descc( mb_ ) ) THEN
319 info = -(1000+nb_)
320 ELSE IF( left .AND. icoffa.NE.iroffc ) THEN
321 info = -13
322 ELSE IF( .NOT.left .AND. icoffa.NE.icoffc ) THEN
323 info = -14
324 ELSE IF( .NOT.left .AND. iacol.NE.iccol ) THEN
325 info = -14
326 ELSE IF( .NOT.left .AND. desca( nb_ ).NE.descc( nb_ ) ) THEN
327 info = -(1500+nb_)
328 ELSE IF( ictxt.NE.descc( ctxt_ ) ) THEN
329 info = -(1500+ctxt_)
330 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
331 info = -17
332 END IF
333 END IF
334 IF( left ) THEN
335 idum1( 1 ) = ichar( 'L' )
336 ELSE
337 idum1( 1 ) = ichar( 'R' )
338 END IF
339 idum2( 1 ) = 1
340 IF( notran ) THEN
341 idum1( 2 ) = ichar( 'N' )
342 ELSE
343 idum1( 2 ) = ichar( 'T' )
344 END IF
345 idum2( 2 ) = 2
346 idum1( 3 ) = k
347 idum2( 3 ) = 5
348 idum1( 4 ) = l
349 idum2( 4 ) = 6
350 IF( lwork.EQ.-1 ) THEN
351 idum1( 5 ) = -1
352 ELSE
353 idum1( 5 ) = 1
354 END IF
355 idum2( 5 ) = 17
356 IF( left ) THEN
357 CALL pchk2mat( k, 5, m, 3, ia, ja, desca, 10, m, 3, n, 4,
358 $ ic, jc, descc, 15, 5, idum1, idum2, info )
359 ELSE
360 CALL pchk2mat( k, 5, n, 4, ia, ja, desca, 10, m, 3, n, 4,
361 $ ic, jc, descc, 15, 5, idum1, idum2, info )
362 END IF
363 END IF
364
365 IF( info.NE.0 ) THEN
366 CALL pxerbla( ictxt,
'PDORMRZ', -info )
367 RETURN
368 ELSE IF( lquery ) THEN
369 RETURN
370 END IF
371
372
373
374 IF( m.EQ.0 .OR. n.EQ.0 .OR. k.EQ.0 )
375 $ RETURN
376
377 CALL pb_topget( ictxt, 'Broadcast', 'Rowwise', rowbtop )
378 CALL pb_topget( ictxt, 'Broadcast', 'Columnwise', colbtop )
379
380 IF( ( left .AND. .NOT.notran ) .OR.
381 $ ( .NOT.left .AND. notran ) ) THEN
382 i1 =
min(
iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+k-1 )
383 $ + 1
384 i2 = ia + k - 1
385 i3 = desca( mb_ )
386 ELSE
387 i1 =
max( ( (ia+k-2) / desca( mb_ ) ) * desca( mb_ ) + 1, ia )
388 i2 =
min(
iceil( ia, desca( mb_ ) ) * desca( mb_ ), ia+k-1 )
389 $ + 1
390 i3 = -desca( mb_ )
391 END IF
392
393 IF( left ) THEN
394 ni = n
395 jcc = jc
396 jaa = ja + m - l
397 ELSE
398 mi = m
399 icc = ic
400 jaa = ja + n - l
401 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', ' ' )
402 IF( notran ) THEN
403 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'I-ring' )
404 ELSE
405 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', 'D-ring' )
406 END IF
407 END IF
408
409 IF( notran ) THEN
410 transt = 'T'
411 ELSE
412 transt = 'N'
413 END IF
414
415 IF( ( left .AND. .NOT.notran ) .OR.
416 $ ( .NOT.left .AND. notran ) ) THEN
417 ib = i1 - ia
418 IF( left ) THEN
419 mi = m
420 ELSE
421 ni = n
422 END IF
423 CALL pdormr3( side, trans, mi, ni, ib, l, a, ia, ja, desca,
424 $ tau, c, ic, jc, descc, work, lwork, iinfo )
425 END IF
426
427 ipw = desca( mb_ )*desca( mb_ ) + 1
428 DO 10 i = i1, i2, i3
429 ib =
min( desca( mb_ ), k-i+ia )
430
431
432
433
434 CALL pdlarzt(
'Backward',
'Rowwise', l, ib, a, i, jaa, desca,
435 $ tau, work, work( ipw ) )
436 IF( left ) THEN
437
438
439
440 mi = m - i + ia
441 icc = ic + i - ia
442 ELSE
443
444
445
446 ni = n - i + ia
447 jcc = jc + i - ia
448 END IF
449
450
451
452 CALL pdlarzb( side, transt,
'Backward',
'Rowwise', mi, ni, ib,
453 $ l, a, i, jaa, desca, work, c, icc, jcc, descc,
454 $ work( ipw ) )
455 10 CONTINUE
456
457 IF( ( left .AND. .NOT.notran ) .OR.
458 $ ( .NOT.left .AND. notran ) ) THEN
459 ib = i2 - ia
460 IF( left ) THEN
461 mi = m
462 ELSE
463 ni = n
464 END IF
465 CALL pdormr3( side, trans, mi, ni, ib, l, a, ia, ja, desca,
466 $ tau, c, ic, jc, descc, work, lwork, iinfo )
467 END IF
468
469 CALL pb_topset( ictxt, 'Broadcast', 'Rowwise', rowbtop )
470 CALL pb_topset( ictxt, 'Broadcast', 'Columnwise', colbtop )
471
472 work( 1 ) = dble( lwmin )
473
474 RETURN
475
476
477
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
integer function iceil(inum, idenom)
integer function ilcm(m, n)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
subroutine pdlarzb(side, trans, direct, storev, m, n, k, l, v, iv, jv, descv, t, c, ic, jc, descc, work)
subroutine pdlarzt(direct, storev, n, k, v, iv, jv, descv, tau, t, work)
subroutine pdormr3(side, trans, m, n, k, l, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)