3
4
5
6
7
8
9
10 CHARACTER TRANS
11 INTEGER IB, INFO, JA, LAF, LWORK, N, NRHS
12
13
14 INTEGER DESCA( * ), DESCB( * )
15 DOUBLE PRECISION AF( * ), B( * ), D( * ), DL( * ), DU( * ),
16 $ WORK( * )
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
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
367
368
369
370
371
372
373
374
375
376
377
378
379
380 INTEGER INT_ONE
381 parameter( int_one = 1 )
382 INTEGER DESCMULT, BIGNUM
383 parameter( descmult = 100, bignum = descmult*descmult )
384 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
385 $ LLD_, MB_, M_, NB_, N_, RSRC_
386 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
387 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
388 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
389
390
391 INTEGER CSRC, FIRST_PROC, ICTXT, ICTXT_NEW, ICTXT_SAVE,
392 $ IDUM2, IDUM3, JA_NEW, LLDA, LLDB, MYCOL, MYROW,
393 $ MY_NUM_COLS, NB, NP, NPCOL, NPROW, NP_SAVE,
394 $ ODD_SIZE, PART_OFFSET, PART_SIZE, RETURN_CODE,
395 $ STORE_M_B, STORE_N_A, TEMP, WORK_SIZE_MIN
396
397
398 INTEGER DESCA_1XP( 7 ), DESCB_PX1( 7 ),
399 $ PARAM_CHECK( 15, 3 )
400
401
404
405
406 LOGICAL LSAME
407 INTEGER NUMROC
409
410
411 INTRINSIC ichar, mod
412
413
414
415
416
417 info = 0
418
419
420
421
422 desca_1xp( 1 ) = 501
423 descb_px1( 1 ) = 502
424
425 temp = desca( dtype_ )
426 IF( temp.EQ.502 ) THEN
427
428 desca( dtype_ ) = 501
429 END IF
430
432
433 desca( dtype_ ) = temp
434
435 IF( return_code.NE.0 ) THEN
436 info = -( 8*100+2 )
437 END IF
438
440
441 IF( return_code.NE.0 ) THEN
442 info = -( 11*100+2 )
443 END IF
444
445
446
447
448 IF( desca_1xp( 2 ).NE.descb_px1( 2 ) ) THEN
449 info = -( 11*100+2 )
450 END IF
451
452
453
454
455
456 IF( desca_1xp( 4 ).NE.descb_px1( 4 ) ) THEN
457 info = -( 11*100+4 )
458 END IF
459
460
461
462 IF( desca_1xp( 5 ).NE.descb_px1( 5 ) ) THEN
463 info = -( 11*100+5 )
464 END IF
465
466
467
468 ictxt = desca_1xp( 2 )
469 csrc = desca_1xp( 5 )
470 nb = desca_1xp( 4 )
471 llda = desca_1xp( 6 )
472 store_n_a = desca_1xp( 3 )
473 lldb = descb_px1( 6 )
474 store_m_b = descb_px1( 3 )
475
476
477
478
479 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
480 np = nprow*npcol
481
482
483
484 IF(
lsame( trans,
'N' ) )
THEN
485 idum2 = ichar( 'N' )
486 ELSE IF(
lsame( trans,
'T' ) )
THEN
487 idum2 = ichar( 'T' )
488 ELSE IF(
lsame( trans,
'C' ) )
THEN
489 idum2 = ichar( 'T' )
490 ELSE
491 info = -1
492 END IF
493
494 IF( lwork.LT.-1 ) THEN
495 info = -15
496 ELSE IF( lwork.EQ.-1 ) THEN
497 idum3 = -1
498 ELSE
499 idum3 = 1
500 END IF
501
502 IF( n.LT.0 ) THEN
503 info = -2
504 END IF
505
506 IF( n+ja-1.GT.store_n_a ) THEN
507 info = -( 8*100+6 )
508 END IF
509
510 IF( n+ib-1.GT.store_m_b ) THEN
511 info = -( 11*100+3 )
512 END IF
513
514 IF( lldb.LT.nb ) THEN
515 info = -( 11*100+6 )
516 END IF
517
518 IF( nrhs.LT.0 ) THEN
519 info = -3
520 END IF
521
522
523
524 IF( ja.NE.ib ) THEN
525 info = -7
526 END IF
527
528
529
530 IF( nprow.NE.1 ) THEN
531 info = -( 8*100+2 )
532 END IF
533
534 IF( n.GT.np*nb-mod( ja-1, nb ) ) THEN
535 info = -( 2 )
536 CALL pxerbla( ictxt,
'PDDTTRS, D&C alg.: only 1 block per proc'
537 $ , -info )
538 RETURN
539 END IF
540
541 IF( ( ja+n-1.GT.nb ) .AND. ( nb.LT.2*int_one ) ) THEN
542 info = -( 8*100+4 )
543 CALL pxerbla( ictxt,
'PDDTTRS, D&C alg.: NB too small', -info )
544 RETURN
545 END IF
546
547
548 work_size_min = 10*npcol + 4*nrhs
549
550 work( 1 ) = work_size_min
551
552 IF( lwork.LT.work_size_min ) THEN
553 IF( lwork.NE.-1 ) THEN
554 info = -15
555 CALL pxerbla( ictxt,
'PDDTTRS: worksize error', -info )
556 END IF
557 RETURN
558 END IF
559
560
561
562 param_check( 15, 1 ) = descb( 5 )
563 param_check( 14, 1 ) = descb( 4 )
564 param_check( 13, 1 ) = descb( 3 )
565 param_check( 12, 1 ) = descb( 2 )
566 param_check( 11, 1 ) = descb( 1 )
567 param_check( 10, 1 ) = ib
568 param_check( 9, 1 ) = desca( 5 )
569 param_check( 8, 1 ) = desca( 4 )
570 param_check( 7, 1 ) = desca( 3 )
571 param_check( 6, 1 ) = desca( 1 )
572 param_check( 5, 1 ) = ja
573 param_check( 4, 1 ) = nrhs
574 param_check( 3, 1 ) = n
575 param_check( 2, 1 ) = idum3
576 param_check( 1, 1 ) = idum2
577
578 param_check( 15, 2 ) = 1105
579 param_check( 14, 2 ) = 1104
580 param_check( 13, 2 ) = 1103
581 param_check( 12, 2 ) = 1102
582 param_check( 11, 2 ) = 1101
583 param_check( 10, 2 ) = 10
584 param_check( 9, 2 ) = 805
585 param_check( 8, 2 ) = 804
586 param_check( 7, 2 ) = 803
587 param_check( 6, 2 ) = 801
588 param_check( 5, 2 ) = 7
589 param_check( 4, 2 ) = 3
590 param_check( 3, 2 ) = 2
591 param_check( 2, 2 ) = 15
592 param_check( 1, 2 ) = 1
593
594
595
596
597
598 IF( info.GE.0 ) THEN
599 info = bignum
600 ELSE IF( info.LT.-descmult ) THEN
601 info = -info
602 ELSE
603 info = -info*descmult
604 END IF
605
606
607
608 CALL globchk( ictxt, 15, param_check, 15, param_check( 1, 3 ),
609 $ info )
610
611
612
613
614 IF( info.EQ.bignum ) THEN
615 info = 0
616 ELSE IF( mod( info, descmult ).EQ.0 ) THEN
617 info = -info / descmult
618 ELSE
619 info = -info
620 END IF
621
622 IF( info.LT.0 ) THEN
623 CALL pxerbla( ictxt,
'PDDTTRS', -info )
624 RETURN
625 END IF
626
627
628
629 IF( n.EQ.0 )
630 $ RETURN
631
632 IF( nrhs.EQ.0 )
633 $ RETURN
634
635
636
637
638
639 part_offset = nb*( ( ja-1 ) / ( npcol*nb ) )
640
641 IF( ( mycol-csrc ).LT.( ja-part_offset-1 ) / nb ) THEN
642 part_offset = part_offset + nb
643 END IF
644
645 IF( mycol.LT.csrc ) THEN
646 part_offset = part_offset - nb
647 END IF
648
649
650
651
652
653
654
655 first_proc = mod( ( ja-1 ) / nb+csrc, npcol )
656
657
658
659 ja_new = mod( ja-1, nb ) + 1
660
661
662
663 np_save = np
664 np = ( ja_new+n-2 ) / nb + 1
665
666
667
668 CALL reshape( ictxt, int_one, ictxt_new, int_one, first_proc,
669 $ int_one, np )
670
671
672
673 ictxt_save = ictxt
674 ictxt = ictxt_new
675 desca_1xp( 2 ) = ictxt_new
676 descb_px1( 2 ) = ictxt_new
677
678
679
680 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
681
682
683
684 IF( myrow.LT.0 ) THEN
685 GO TO 20
686 END IF
687
688
689
690
691
692
693 part_size = nb
694
695
696
697 my_num_cols =
numroc( n, part_size, mycol, 0, npcol )
698
699
700
701 IF( mycol.EQ.0 ) THEN
702 part_offset = part_offset + mod( ja_new-1, part_size )
703 my_num_cols = my_num_cols - mod( ja_new-1, part_size )
704 END IF
705
706
707
708 odd_size = my_num_cols
709 IF( mycol.LT.np-1 ) THEN
710 odd_size = odd_size - int_one
711 END IF
712
713
714
715
716
717 info = 0
718
719
720
721 IF(
lsame( trans,
'N' ) )
THEN
722
723 CALL pddttrsv(
'L',
'N', n, nrhs, dl( part_offset+1 ),
724 $ d( part_offset+1 ), du( part_offset+1 ), ja_new,
725 $ desca_1xp, b, ib, descb_px1, af, laf, work,
726 $ lwork, info )
727
728 ELSE
729
730 CALL pddttrsv(
'U',
'T', n, nrhs, dl( part_offset+1 ),
731 $ d( part_offset+1 ), du( part_offset+1 ), ja_new,
732 $ desca_1xp, b, ib, descb_px1, af, laf, work,
733 $ lwork, info )
734
735 END IF
736
737
738
739 IF( (
lsame( trans,
'C' ) ) .OR. (
lsame( trans,
'T' ) ) )
THEN
740
741 CALL pddttrsv(
'L',
'T', n, nrhs, dl( part_offset+1 ),
742 $ d( part_offset+1 ), du( part_offset+1 ), ja_new,
743 $ desca_1xp, b, ib, descb_px1, af, laf, work,
744 $ lwork, info )
745
746 ELSE
747
748 CALL pddttrsv(
'U',
'N', n, nrhs, dl( part_offset+1 ),
749 $ d( part_offset+1 ), du( part_offset+1 ), ja_new,
750 $ desca_1xp, b, ib, descb_px1, af, laf, work,
751 $ lwork, info )
752
753 END IF
754 10 CONTINUE
755
756
757
758
759 IF( ictxt_save.NE.ictxt_new ) THEN
760 CALL blacs_gridexit( ictxt_new )
761 END IF
762
763 20 CONTINUE
764
765
766
767 ictxt = ictxt_save
768 np = np_save
769
770
771
772 work( 1 ) = work_size_min
773
774
775 RETURN
776
777
778
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 pddttrsv(uplo, trans, n, nrhs, dl, d, du, ja, desca, b, ib, descb, af, laf, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)
void reshape(Int *context_in, Int *major_in, Int *context_out, Int *major_out, Int *first_proc, Int *nprow_new, Int *npcol_new)