3
4
5
6
7
8
9
10
11
12 CHARACTER UPLO
13 INTEGER BW, IB, INFO, JA, LAF, LWORK, N, NRHS
14
15
16 INTEGER DESCA( * ), DESCB( * )
17 COMPLEX*16 A( * ), AF( * ), B( * ), WORK( * )
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366 DOUBLE PRECISION ONE, ZERO
367 parameter( one = 1.0d+0 )
368 parameter( zero = 0.0d+0 )
369 COMPLEX*16 CONE, CZERO
370 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
371 parameter( czero = ( 0.0d+0, 0.0d+0 ) )
372 INTEGER INT_ONE
373 parameter( int_one = 1 )
374 INTEGER DESCMULT, BIGNUM
375 parameter(descmult = 100, bignum = descmult * descmult)
376 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
377 $ LLD_, MB_, M_, NB_, N_, RSRC_
378 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
379 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
380 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
381
382
383 INTEGER CSRC, FIRST_PROC, ICTXT, ICTXT_NEW, ICTXT_SAVE,
384 $ IDUM1, IDUM3, JA_NEW, LLDA, LLDB, MYCOL, MYROW,
385 $ NB, NP, NPCOL, NPROW, NP_SAVE, PART_OFFSET,
386 $ RETURN_CODE, STORE_M_B, STORE_N_A,
387 $ WORK_SIZE_MIN
388
389
390 INTEGER DESCA_1XP( 7 ), DESCB_PX1( 7 ),
391 $ PARAM_CHECK( 16, 3 )
392
393
396
397
398 LOGICAL LSAME
399 INTEGER NUMROC
401
402
403 INTRINSIC ichar,
min, mod
404
405
406
407
408
409 info = 0
410
411
412
413
414 desca_1xp( 1 ) = 501
415 descb_px1( 1 ) = 502
416
418
419 IF( return_code .NE. 0) THEN
420 info = -( 7*100 + 2 )
421 ENDIF
422
424
425 IF( return_code .NE. 0) THEN
426 info = -( 10*100 + 2 )
427 ENDIF
428
429
430
431
432 IF( desca_1xp( 2 ) .NE. descb_px1( 2 ) ) THEN
433 info = -( 10*100 + 2 )
434 ENDIF
435
436
437
438
439
440 IF( desca_1xp( 4 ) .NE. descb_px1( 4 ) ) THEN
441 info = -( 10*100 + 4 )
442 ENDIF
443
444
445
446 IF( desca_1xp( 5 ) .NE. descb_px1( 5 ) ) THEN
447 info = -( 10*100 + 5 )
448 ENDIF
449
450
451
452 ictxt = desca_1xp( 2 )
453 csrc = desca_1xp( 5 )
454 nb = desca_1xp( 4 )
455 llda = desca_1xp( 6 )
456 store_n_a = desca_1xp( 3 )
457 lldb = descb_px1( 6 )
458 store_m_b = descb_px1( 3 )
459
460
461
462
463 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
464 np = nprow * npcol
465
466
467
468 IF(
lsame( uplo,
'U' ) )
THEN
469 idum1 = ichar( 'U' )
470 ELSE IF (
lsame( uplo,
'L' ) )
THEN
471 idum1 = ichar( 'L' )
472 ELSE
473 info = -1
474 END IF
475
476 IF( lwork .LT. -1) THEN
477 info = -14
478 ELSE IF ( lwork .EQ. -1 ) THEN
479 idum3 = -1
480 ELSE
481 idum3 = 1
482 ENDIF
483
484 IF( n .LT. 0 ) THEN
485 info = -2
486 ENDIF
487
488 IF( n+ja-1 .GT. store_n_a ) THEN
489 info = -( 7*100 + 6 )
490 ENDIF
491
492 IF(( bw .GT. n-1 ) .OR.
493 $ ( bw .LT. 0 ) ) THEN
494 info = -3
495 ENDIF
496
497 IF( llda .LT. (bw+1) ) THEN
498 info = -( 7*100 + 6 )
499 ENDIF
500
501 IF( nb .LE. 0 ) THEN
502 info = -( 7*100 + 4 )
503 ENDIF
504
505 IF( n+ib-1 .GT. store_m_b ) THEN
506 info = -( 10*100 + 3 )
507 ENDIF
508
509 IF( lldb .LT. nb ) THEN
510 info = -( 10*100 + 6 )
511 ENDIF
512
513 IF( nrhs .LT. 0 ) THEN
514 info = -3
515 ENDIF
516
517
518
519 IF( ja .NE. ib) THEN
520 info = -6
521 ENDIF
522
523
524
525 IF( nprow .NE. 1 ) THEN
526 info = -( 7*100+2 )
527 ENDIF
528
529 IF( n .GT. np*nb-mod( ja-1, nb )) THEN
530 info = -( 2 )
532 $ 'PZPBTRS, D&C alg.: only 1 block per proc',
533 $ -info )
534 RETURN
535 ENDIF
536
537 IF((ja+n-1.GT.nb) .AND. ( nb.LT.2*bw )) THEN
538 info = -( 7*100+4 )
540 $ 'PZPBTRS, D&C alg.: NB too small',
541 $ -info )
542 RETURN
543 ENDIF
544
545
546 work_size_min =
547 $ (bw*nrhs)
548
549 work( 1 ) = work_size_min
550
551 IF( lwork .LT. work_size_min ) THEN
552 IF( lwork .NE. -1 ) THEN
553 info = -14
555 $ 'PZPBTRS: worksize error',
556 $ -info )
557 ENDIF
558 RETURN
559 ENDIF
560
561
562
563 param_check( 16, 1 ) = descb(5)
564 param_check( 15, 1 ) = descb(4)
565 param_check( 14, 1 ) = descb(3)
566 param_check( 13, 1 ) = descb(2)
567 param_check( 12, 1 ) = descb(1)
568 param_check( 11, 1 ) = ib
569 param_check( 10, 1 ) = desca(5)
570 param_check( 9, 1 ) = desca(4)
571 param_check( 8, 1 ) = desca(3)
572 param_check( 7, 1 ) = desca(1)
573 param_check( 6, 1 ) = ja
574 param_check( 5, 1 ) = nrhs
575 param_check( 4, 1 ) = bw
576 param_check( 3, 1 ) = n
577 param_check( 2, 1 ) = idum3
578 param_check( 1, 1 ) = idum1
579
580 param_check( 16, 2 ) = 1005
581 param_check( 15, 2 ) = 1004
582 param_check( 14, 2 ) = 1003
583 param_check( 13, 2 ) = 1002
584 param_check( 12, 2 ) = 1001
585 param_check( 11, 2 ) = 9
586 param_check( 10, 2 ) = 705
587 param_check( 9, 2 ) = 704
588 param_check( 8, 2 ) = 703
589 param_check( 7, 2 ) = 701
590 param_check( 6, 2 ) = 6
591 param_check( 5, 2 ) = 4
592 param_check( 4, 2 ) = 3
593 param_check( 3, 2 ) = 2
594 param_check( 2, 2 ) = 14
595 param_check( 1, 2 ) = 1
596
597
598
599
600
601 IF( info.GE.0 ) THEN
602 info = bignum
603 ELSE IF( info.LT.-descmult ) THEN
604 info = -info
605 ELSE
606 info = -info * descmult
607 END IF
608
609
610
611 CALL globchk( ictxt, 16, param_check, 16,
612 $ param_check( 1, 3 ), info )
613
614
615
616
617 IF( info.EQ.bignum ) THEN
618 info = 0
619 ELSE IF( mod( info, descmult ) .EQ. 0 ) THEN
620 info = -info / descmult
621 ELSE
622 info = -info
623 END IF
624
625 IF( info.LT.0 ) THEN
626 CALL pxerbla( ictxt,
'PZPBTRS', -info )
627 RETURN
628 END IF
629
630
631
632 IF( n.EQ.0 )
633 $ RETURN
634
635 IF( nrhs.EQ.0 )
636 $ RETURN
637
638
639
640
641
642 part_offset = nb*( (ja-1)/(npcol*nb) )
643
644 IF ( (mycol-csrc) .LT. (ja-part_offset-1)/nb ) THEN
645 part_offset = part_offset + nb
646 ENDIF
647
648 IF ( mycol .LT. csrc ) THEN
649 part_offset = part_offset - nb
650 ENDIF
651
652
653
654
655
656
657
658 first_proc = mod( ( ja-1 )/nb+csrc, npcol )
659
660
661
662 ja_new = mod( ja-1, nb ) + 1
663
664
665
666 np_save = np
667 np = ( ja_new+n-2 )/nb + 1
668
669
670
671 CALL reshape( ictxt, int_one, ictxt_new, int_one,
672 $ first_proc, int_one, np )
673
674
675
676 ictxt_save = ictxt
677 ictxt = ictxt_new
678 desca_1xp( 2 ) = ictxt_new
679 descb_px1( 2 ) = ictxt_new
680
681
682
683 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
684
685
686
687 IF( myrow .LT. 0 ) THEN
688 GOTO 1234
689 ENDIF
690
691
692
693
694
695 info = 0
696
697
698
699 IF(
lsame( uplo,
'L' ) )
THEN
700
701 CALL pzpbtrsv(
'L',
'N', n, bw, nrhs, a( part_offset+1 ),
702 $ ja_new, desca_1xp, b, ib, descb_px1, af, laf,
703 $ work, lwork, info )
704
705 ELSE
706
707 CALL pzpbtrsv(
'U',
'C', n, bw, nrhs, a( part_offset+1 ),
708 $ ja_new, desca_1xp, b, ib, descb_px1, af, laf,
709 $ work, lwork, info )
710
711 ENDIF
712
713
714
715 IF(
lsame( uplo,
'L' ) )
THEN
716
717 CALL pzpbtrsv(
'L',
'C', n, bw, nrhs, a( part_offset+1 ),
718 $ ja_new, desca_1xp, b, ib, descb_px1, af, laf,
719 $ work, lwork, info )
720
721 ELSE
722
723 CALL pzpbtrsv(
'U',
'N', n, bw, nrhs, a( part_offset+1 ),
724 $ ja_new, desca_1xp, b, ib, descb_px1, af, laf,
725 $ work, lwork, info )
726
727 ENDIF
728 1000 CONTINUE
729
730
731
732
733 IF( ictxt_save .NE. ictxt_new ) THEN
734 CALL blacs_gridexit( ictxt_new )
735 ENDIF
736
737 1234 CONTINUE
738
739
740
741 ictxt = ictxt_save
742 np = np_save
743
744
745
746 work( 1 ) = work_size_min
747
748
749 RETURN
750
751
752
subroutine desc_convert(desc_in, desc_out, info)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine globchk(ictxt, n, x, ldx, iwork, info)
subroutine pxerbla(ictxt, srname, info)
subroutine pzpbtrsv(uplo, trans, n, bw, nrhs, a, ja, desca, b, ib, descb, af, laf, work, lwork, info)
void reshape(Int *context_in, Int *major_in, Int *context_out, Int *major_out, Int *first_proc, Int *nprow_new, Int *npcol_new)