3
4
5
6
7
8
9
10
11
12
13 CHARACTER*1 ADIST, TRANS
14 INTEGER IACOL, IAROW, ICCOL, ICONTXT, ICROW, LDA, LDC,
15 $ M, N, NB
16 COMPLEX*16 BETA
17
18
19 COMPLEX*16 A( LDA, * ), C( LDC, * ), WORK( * )
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 COMPLEX*16 ONE, ZERO
180 parameter( one = ( 1.0d+0, 0.0d+0 ),
181 $ zero = ( 0.0d+0, 0.0d+0 ) )
182
183
184 LOGICAL COLFORM, ROWFORM
185 INTEGER I, IDEX, IGD, INFO, , JCROW, JDEX, LCM,
186 $ LCMP, , MCCOL, MCROW, ML, MP, MQ, MQ0,
187 $ MRCOL, MRROW, MYCOL, MYROW, NP, NP0, NPCOL,
188 $ NPROW, NQ
189 COMPLEX*16 TBETA
190
191
192 LOGICAL LSAME
193 INTEGER ILCM, ICEIL, NUMROC
195
196
200
201
203
204
205
206
207
208 IF( m.EQ.0 .OR. n.EQ.0 ) RETURN
209
211
212 colform =
lsame( adist,
'C' )
213 rowform =
lsame( adist,
'R' )
214
215
216
217 info = 0
218 IF( ( .NOT.colform ) .AND. ( .NOT.rowform ) ) THEN
219 info = 2
220 ELSE IF( m .LT.0 ) THEN
221 info = 4
222 ELSE IF( n .LT.0 ) THEN
223 info = 5
224 ELSE IF( nb.LT.1 ) THEN
225 info = 6
226 ELSE IF( iarow.LT.-1 .OR. iarow.GE.nprow .OR.
227 $ ( iarow.EQ.-1 .AND. colform ) ) THEN
228 info = 12
229 ELSE IF( iacol.LT.-1 .OR. iacol.GE.npcol .OR.
230 $ ( iacol.EQ.-1 .AND. rowform ) ) THEN
231 info = 13
232 ELSE IF( icrow.LT.-1 .OR. icrow.GE.nprow .OR.
233 $ ( icrow.EQ.-1 .AND. rowform ) ) THEN
234 info = 14
235 ELSE IF( iccol.LT.-1 .OR. iccol.GE.npcol .OR.
236 $ ( iccol.EQ.-1 .AND. colform ) ) THEN
237 info = 15
238 END IF
239
240 10 CONTINUE
241 IF( info .NE. 0 ) THEN
242 CALL pxerbla( icontxt,
'PBZTRAN ', info )
243 RETURN
244 END IF
245
246
247
248
249
250 lcm =
ilcm( nprow, npcol )
251 lcmp = lcm / nprow
252 lcmq = lcm / npcol
253 igd = npcol / lcmp
254
255
256
257 IF( colform ) THEN
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272 mrrow = mod( nprow+myrow-iarow, nprow )
273 mrcol = mod( npcol+mycol-iccol, npcol )
274 jcrow = icrow
275 IF( icrow.EQ.-1 ) jcrow = iarow
276
277 mp =
numroc( m, nb, myrow, iarow, nprow )
278 mq =
numroc( m, nb, mycol, iccol, npcol )
279 mq0 =
numroc(
numroc(m, nb, 0, 0, npcol), nb, 0, 0, lcmq )
280
281 IF( lda.LT.mp .AND.
282 $ ( iacol.EQ.mycol .OR. iacol.EQ.-1 ) ) THEN
283 info = 8
284 ELSE IF( ldc.LT.n .AND.
285 $ ( icrow.EQ.myrow .OR. icrow.EQ.-1 ) ) THEN
286 info = 11
287 END IF
288 IF( info.NE.0 ) GO TO 10
289
290
291
292 IF( iacol.GE.0 ) THEN
293 tbeta = zero
294 IF( myrow.EQ.jcrow ) tbeta = beta
295
296 DO 20 i = 0,
min( lcm,
iceil(m,nb) ) - 1
297 mcrow = mod( mod(i, nprow) + iarow, nprow )
298 mccol = mod( mod(i, npcol) + iccol, npcol )
299 IF( lcmq.EQ.1 ) mq0 =
numroc( m, nb, i, 0, npcol )
300 jdex = (i/npcol) * nb
301
302
303
304 IF( myrow.EQ.mcrow .AND. mycol.EQ.iacol ) THEN
305
306
307
308 idex = (i/nprow) * nb
309 IF( myrow.EQ.jcrow .AND. mycol.EQ.mccol ) THEN
310 CALL pbztr2at( icontxt, 'col
', TRANS, MP-IDEX, N, NB,
311 $ A(IDEX+1,1), LDA, TBETA, C(1,JDEX+1),
312 $ LDC, LCMP, LCMQ )
313
314
315
316 ELSE
317 CALL PBZTR2BT( ICONTXT, 'col', TRANS, MP-IDEX, N, NB,
318 $ A(IDEX+1,1), LDA, ZERO, WORK, N,
319 $ LCMP*NB )
320 CALL ZGESD2D( ICONTXT, N, MQ0, WORK, N, JCROW, MCCOL )
321 END IF
322
323
324
325.EQ..AND..EQ. ELSE IF( MYROWJCROW MYCOLMCCOL ) THEN
326.EQ..AND..EQ. IF( LCMQ1 TBETAZERO ) THEN
327 CALL ZGERV2D( ICONTXT, N, MQ0, C, LDC, MCROW, IACOL )
328 ELSE
329 CALL ZGERV2D( ICONTXT, N, MQ0, WORK, N, MCROW, IACOL )
330 CALL PBZTR2AF( ICONTXT, 'row', N, MQ-JDEX, NB, WORK, N,
331 $ TBETA, C(1,JDEX+1), LDC, LCMP, LCMQ,
332 $ MQ0 )
333 END IF
334 END IF
335 20 CONTINUE
336
337
338
339.EQ. IF( ICROW-1 ) THEN
340.EQ. IF( MYROWJCROW ) THEN
341 CALL ZGEBS2D( ICONTXT, 'col', '1-tree', N, MQ, C, LDC )
342 ELSE
343 CALL ZGEBR2D( ICONTXT, 'col', '1-tree', N, MQ, C, LDC,
344 $ JCROW, MYCOL )
345 END IF
346 END IF
347
348
349
350 ELSE
351.EQ. IF( LCMQ1 ) MQ0 = MQ
352
353
354
355
356 DO 30 I = 0, LCMP-1
357.EQ. IF( MRCOLMOD( NPROW*I+MRROW, NPCOL ) ) THEN
358.EQ..AND..EQ..OR..EQ. IF( LCMQ1(ICROW-1ICROWMYROW) ) THEN
359 CALL PBZTR2BT( ICONTXT, 'col', TRANS, MP-I*NB, N, NB,
360 $ A(I*NB+1,1), LDA, BETA, C, LDC,
361 $ LCMP*NB )
362 ELSE
363 CALL PBZTR2BT( ICONTXT, 'col', TRANS, MP-I*NB, N, NB,
364 $ A(I*NB+1,1), LDA, ZERO, WORK, N,
365 $ LCMP*NB )
366 END IF
367 END IF
368 30 CONTINUE
369
370
371
372 MCROW = MOD( MOD(MRCOL,NPROW)+IAROW, NPROW )
373.GT. IF( LCMQ1 ) THEN
374 MCCOL = MOD( NPCOL+MYCOL-ICCOL, NPCOL )
375 CALL PBZTRGET( ICONTXT, 'row', N, MQ0, ICEIL(M,NB), WORK, N,
376 $ MCROW, MCCOL, IGD, MYROW, MYCOL, NPROW,
377 $ NPCOL )
378 END IF
379
380
381
382.EQ. IF( ICROW-1 ) THEN
383.EQ. IF( MYROWMCROW ) THEN
384.GT. IF( LCMQ1 )
385 $ CALL PBZTRSRT( ICONTXT, 'row', N, MQ, NB, WORK, N, BETA,
386 $ C, LDC, LCMP, LCMQ, MQ0 )
387 CALL ZGEBS2D( ICONTXT, 'col', '1-tree', N, MQ, C, LDC )
388 ELSE
389 CALL ZGEBR2D( ICONTXT, 'col', '1-tree', N, MQ, C, LDC,
390 $ MCROW, MYCOL )
391 END IF
392
393
394
395 ELSE
396.EQ. IF( LCMQ1 ) THEN
397.EQ. IF( MYROWMCROW ) THEN
398.NE. IF( MYROWICROW )
399 $ CALL ZGESD2D( ICONTXT, N, MQ, WORK, N, ICROW, MYCOL )
400.EQ. ELSE IF( MYROWICROW ) THEN
401.EQ. IF( BETAZERO ) THEN
402 CALL ZGERV2D( ICONTXT, N, MQ, C, LDC, MCROW, MYCOL )
403 ELSE
404 CALL ZGERV2D( ICONTXT, N, MQ, WORK, N, MCROW, MYCOL )
405 CALL PBZMATADD( ICONTXT, 'g', N, MQ, ONE, WORK, N,
406 $ BETA, C, LDC )
407 END IF
408 END IF
409
410 ELSE
411 ML = MQ0 * MIN( LCMQ, MAX(0,ICEIL(M,NB)-MCCOL) )
412.EQ. IF( MYROWMCROW ) THEN
413.NE. IF( MYROWICROW )
414 $ CALL ZGESD2D( ICONTXT, N, ML, WORK, N, ICROW, MYCOL )
415.EQ. ELSE IF( MYROWICROW ) THEN
416 CALL ZGERV2D( ICONTXT, N, ML, WORK, N, MCROW, MYCOL )
417 END IF
418
419.EQ. IF( MYROWICROW )
420 $ CALL PBZTRSRT( ICONTXT, 'row', N, MQ, NB, WORK, N, BETA,
421 $ C, LDC, LCMP, LCMQ, MQ0 )
422 END IF
423 END IF
424
425 END IF
426
427
428
429 ELSE
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444 MRROW = MOD( NPROW+MYROW-ICROW, NPROW )
445 MRCOL = MOD( NPCOL+MYCOL-IACOL, NPCOL )
446 JCCOL = ICCOL
447.EQ. IF( ICCOL-1 ) JCCOL = IACOL
448
449 NP = NUMROC( N, NB, MYROW, ICROW, NPROW )
450 NQ = NUMROC( N, NB, MYCOL, IACOL, NPCOL )
451 NP0 = NUMROC( NUMROC(N, NB, 0, 0, NPROW), NB, 0, 0, LCMP )
452
453.LT..AND. IF( LDAM
454.EQ..OR..EQ. $ ( IAROWMYROW IAROW-1 ) ) THEN
455 INFO = 8
456.LT..AND. ELSE IF( LDCNP
457.EQ..OR..EQ. $ ( ICCOLMYCOL ICCOL-1 ) ) THEN
458 INFO = 11
459 END IF
460.NE. IF( INFO0 ) GO TO 10
461
462
463
464.GE. IF( IAROW0 ) THEN
465 TBETA = ZERO
466.EQ. IF( MYCOLJCCOL ) TBETA = BETA
467
468 DO 40 I = 0, MIN( LCM, ICEIL(N,NB) ) - 1
469 MCROW = MOD( MOD(I, NPROW) + ICROW, NPROW )
470 MCCOL = MOD( MOD(I, NPCOL) + IACOL, NPCOL )
471.EQ. IF( LCMP1 ) NP0 = NUMROC( N, NB, I, 0, NPROW )
472 IDEX = (I/NPROW) * NB
473
474
475
476.EQ..AND..EQ. IF( MYROWIAROW MYCOLMCCOL ) THEN
477
478
479
480 JDEX = (I/NPCOL) * NB
481.EQ..AND..EQ. IF( MYROWMCROW MYCOLJCCOL ) THEN
482 CALL PBZTR2AT( ICONTXT, 'row', TRANS, M, NQ-JDEX, NB,
483 $ A(1,JDEX+1), LDA, TBETA, C(IDEX+1,1),
484 $ LDC, LCMP, LCMQ )
485
486
487
488 ELSE
489 CALL PBZTR2BT( ICONTXT, 'row', TRANS, M, NQ-JDEX, NB,
490 $ A(1,JDEX+1), LDA, ZERO, WORK, NP0,
491 $ LCMQ*NB )
492 CALL ZGESD2D( ICONTXT, NP0, M, WORK, NP0,
493 $ MCROW, JCCOL )
494 END IF
495
496
497
498.EQ..AND..EQ. ELSE IF( MYROWMCROW MYCOLJCCOL ) THEN
499.EQ..AND..EQ. IF( LCMP1 TBETAZERO ) THEN
500 CALL ZGERV2D( ICONTXT, NP0, M, C, LDC, IAROW, MCCOL )
501 ELSE
502 CALL ZGERV2D( ICONTXT, NP0, M, WORK, NP0, IAROW, MCCOL )
503 CALL PBZTR2AF( ICONTXT, 'col', NP-IDEX, M, NB, WORK,
504 $ NP0, TBETA, C(IDEX+1,1), LDC, LCMP, LCMQ,
505 $ NP0 )
506 END IF
507 END IF
508 40 CONTINUE
509
510
511
512.EQ. IF( ICCOL-1 ) THEN
513.EQ. IF( MYCOLJCCOL ) THEN
514 CALL ZGEBS2D( ICONTXT, 'row', '1-tree', NP, M, C, LDC )
515 ELSE
516 CALL ZGEBR2D( ICONTXT, 'row', '1-tree', NP, M, C, LDC,
517 $ MYROW, JCCOL )
518 END IF
519 END IF
520
521
522
523 ELSE
524.EQ. IF( LCMP1 ) NP0 = NP
525
526
527
528
529 DO 50 I = 0, LCMQ-1
530.EQ. IF( MRROWMOD(NPCOL*I+MRCOL, NPROW) ) THEN
531.EQ..AND..EQ..OR..EQ. IF( LCMP1(ICCOL-1ICCOLMYCOL) ) THEN
532 CALL PBZTR2BT( ICONTXT, 'row', TRANS, M, NQ-I*NB, NB,
533 $ A(1,I*NB+1), LDA, BETA, C, LDC,
534 $ LCMQ*NB )
535 ELSE
536 CALL PBZTR2BT( ICONTXT, 'row', TRANS, M, NQ-I*NB, NB,
537 $ A(1,I*NB+1), LDA, ZERO, WORK, NP0,
538 $ LCMQ*NB )
539 END IF
540 END IF
541 50 CONTINUE
542
543
544
545 MCCOL = MOD( MOD(MRROW, NPCOL)+IACOL, NPCOL )
546.GT. IF( LCMP1 ) THEN
547 MCROW = MOD( NPROW+MYROW-ICROW, NPROW )
548 CALL PBZTRGET( ICONTXT, 'col', NP0, M, ICEIL(N,NB), WORK,
549 $ NP0, MCROW, MCCOL, IGD, MYROW, MYCOL, NPROW,
550 $ NPCOL )
551 END IF
552
553
554
555.EQ. IF( ICCOL-1 ) THEN
556.EQ. IF( MYCOLMCCOL ) THEN
557.GT. IF( LCMP1 )
558 $ CALL PBZTRSRT( ICONTXT, 'col', np, m, nb, work, np0,
559 $ beta, c, ldc, lcmp, lcmq, np0 )
560 CALL zgebs2d( icontxt,
'Row',
'1-tree', np, m, c, ldc )
561 ELSE
562 CALL zgebr2d( icontxt, 'row
', '1-tree
', NP, M, C, LDC,
563 $ MYROW, MCCOL )
564 END IF
565
566
567
568 ELSE
569.EQ. IF( LCMP1 ) THEN
570.EQ. IF( MYCOLMCCOL ) THEN
571.NE. IF( MYCOLICCOL )
572 $ CALL ZGESD2D( ICONTXT, NP, M, WORK, NP, MYROW, ICCOL )
573.EQ. ELSE IF( MYCOLICCOL ) THEN
574.EQ. IF( BETAZERO ) THEN
575 CALL ZGERV2D( ICONTXT, NP, M, C, LDC, MYROW, MCCOL )
576 ELSE
577 CALL ZGERV2D( ICONTXT, NP, M, WORK, NP, MYROW, MCCOL )
578 CALL PBZMATADD( ICONTXT, 'g', NP, M, ONE, WORK, NP,
579 $ BETA, C, LDC )
580 END IF
581 END IF
582
583 ELSE
584 ML = M * MIN( LCMP, MAX( 0, ICEIL(N,NB) - MCROW ) )
585.EQ. IF( MYCOLMCCOL ) THEN
586.NE. IF( MYCOLICCOL )
587 $ CALL ZGESD2D( ICONTXT, NP0, ML, WORK, NP0,
588 $ MYROW, ICCOL )
589.EQ. ELSE IF( MYCOLICCOL ) THEN
590 CALL ZGERV2D( ICONTXT, NP0, ML, WORK, NP0,
591 $ MYROW, MCCOL )
592 END IF
593
594.EQ. IF( MYCOLICCOL )
595 $ CALL PBZTRSRT( ICONTXT, 'col', NP, M, NB, WORK, NP0,
596 $ BETA, C, LDC, LCMP, LCMQ, NP0 )
597 END IF
598 END IF
599
600 END IF
601 END IF
602
603 RETURN
604
605
606
integer function ilcm(m, n)
subroutine zgebr2d(contxt, scope, top, m, n, a, lda)
subroutine zgebs2d(contxt, scope, top, m, n, a, lda)
subroutine pxerbla(contxt, srname, info)
subroutine blacs_gridinfo(cntxt, nprow, npcol, myrow, mycol)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pbztr2af(icontxt, adist, m, n, nb, a, lda, beta, b, ldb, lcmp, lcmq, nint)
subroutine pbztr2bt(icontxt, adist, trans, m, n, nb, a, lda, beta, b, ldb, intv)
subroutine pbztr2at(icontxt, adist, trans, m, n, nb, a, lda, beta, b, ldb, lcmp, lcmq)
subroutine pbztrget(icontxt, adist, m, n, mnb, a, lda, mcrow, mccol, igd, myrow, mycol, nprow, npcol)
subroutine pbztrsrt(icontxt, adist, m, n, nb, a, lda, beta, b, ldb, lcmp, lcmq, nint)