3
4
5
6
7
8
9
10 CHARACTER DIAG, TRANS, UPLO
11 INTEGER IA, IB, INFO, JA, JB, N, NRHS
12
13
14 INTEGER DESCA( * ), DESCB( * )
15 COMPLEX A( * ), B( * )
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
166 $ LLD_, MB_, M_, NB_, N_, RSRC_
167 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
168 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
169 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
170 COMPLEX ZERO, ONE
171 parameter( zero = 0.0e+0, one = 1.0e+0 )
172
173
174 LOGICAL NOTRAN, NOUNIT, UPPER
175 INTEGER I, IAROW, IBROW, ICOFFA, ICTXT, ICURCOL,
176 $ ICURROW, IROFFA, IROFFB, IDUM, II, IOFFA, J,
177 $ JBLK, JJ, JN, LDA, LL, MYCOL, MYROW, NPCOL,
178 $ NPROW
179
180
181 INTEGER IDUM1( 3 ), IDUM2( 3 )
182
183
186
187
188 LOGICAL LSAME
189 INTEGER ICEIL, INDXG2P
191
192
193 INTRINSIC ichar,
min, mod
194
195
196
197
198
199 ictxt = desca( ctxt_ )
200 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
201
202
203
204 info = 0
205 IF( nprow.EQ.-1 ) THEN
206 info = -907
207 ELSE
208 upper =
lsame( uplo,
'U' )
209 nounit =
lsame( diag,
'N' )
210 notran =
lsame( trans,
'N' )
211
212 CALL chk1mat( n, 4, n, 4, ia, ja, desca, 9, info )
213 CALL chk1mat( n, 4, nrhs, 5, ib, jb, descb, 13, info )
214 IF( info.EQ.0 ) THEN
215 iroffa = mod( ia-1, desca( mb_ ) )
216 icoffa = mod( ja-1, desca( nb_ ) )
217 iroffb = mod( ib-1, descb( mb_ ) )
218 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
219 $ nprow )
220 ibrow =
indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
221 $ nprow )
222 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
223 info = -1
224 ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans,
'T' ) .AND.
225 $ .NOT.
lsame( trans,
'C' ) )
THEN
226 info = -2
227 ELSE IF( .NOT.nounit .AND. .NOT.
lsame( diag,
'U' ) )
THEN
228 info = -3
229 ELSE IF( iroffa.NE.icoffa .OR. iroffa.NE.0 ) THEN
230 info = -8
231 ELSE IF( iroffa.NE.iroffb .OR. iarow.NE.ibrow ) THEN
232 info = -11
233 ELSE IF( desca( mb_ ).NE.desca( nb_ ) ) THEN
234 info = -904
235 ELSE IF( descb( mb_ ).NE.desca( nb_ ) ) THEN
236 info = -1304
237 END IF
238 END IF
239
240 IF( upper ) THEN
241 idum1( 1 ) = ichar( 'U' )
242 ELSE
243 idum1( 1 ) = ichar( 'L' )
244 END IF
245 idum2( 1 ) = 1
246 IF( notran ) THEN
247 idum1( 2 ) = ichar( 'N' )
248 ELSE IF(
lsame( trans,
'T' ) )
THEN
249 idum1( 2 ) = ichar( 'T' )
250 ELSE IF(
lsame( trans,
'C' ) )
THEN
251 idum1( 2 ) = ichar( 'C' )
252 END IF
253 idum2( 2 ) = 2
254 IF( nounit ) THEN
255 idum1( 3 ) = ichar( 'N' )
256 ELSE
257 idum1( 3 ) = ichar( 'D' )
258 END IF
259 idum2( 3 ) = 3
260 CALL pchk2mat( n, 4, n, 4, ia, ja, desca, 9, n, 4, nrhs, 5,
261 $ ib, jb, descb, 13, 3, idum1, idum2, info )
262 END IF
263
264 IF( info.NE.0 ) THEN
265 CALL pxerbla( ictxt,
'PCTRTRS', -info )
266 RETURN
267 END IF
268
269
270
271 IF( n.EQ.0 .OR. nrhs.EQ.0 )
272 $ RETURN
273
274
275
276 IF( nounit ) THEN
277 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol,
278 $ ii, jj, icurrow, icurcol )
279 jn =
min(
iceil( ja, desca( nb_ ) ) * desca( nb_ ), ja+n-1 )
280 lda = desca( lld_ )
281 ioffa = ii + ( jj - 1 ) * lda
282
283
284
285 jblk = jn-ja+1
286 IF( myrow.EQ.icurrow .AND. mycol.EQ.icurcol ) THEN
287 ll = ioffa
288 DO 10 i = 0, jblk-1
289 IF( a( ll ).EQ.zero .AND. info.EQ.0 )
290 $ info = i + 1
291 ll = ioffa + lda + 1
292 10 CONTINUE
293 END IF
294 IF( myrow.EQ.icurrow )
295 $ ioffa = ioffa + jblk
296 IF( mycol.EQ.icurcol )
297 $ ioffa = ioffa + jblk*lda
298 icurrow = mod( icurrow+1, nprow )
299 icurcol = mod( icurcol+1, npcol )
300
301
302
303 DO 30 j = jn+1, ja+n-1, desca( nb_ )
304 jblk =
min( ja+n-j, desca( nb_ ) )
305 IF( myrow.EQ.icurrow .AND. mycol.EQ.icurcol ) THEN
306 ll = ioffa
307 DO 20 i = 0, jblk-1
308 IF( a( ll ).EQ.zero .AND. info.EQ.0 )
309 $ info = j + i - ja + 1
310 ll = ioffa + lda + 1
311 20 CONTINUE
312 END IF
313 IF( myrow.EQ.icurrow )
314 $ ioffa = ioffa + jblk
315 IF( mycol.EQ.icurcol )
316 $ ioffa = ioffa + jblk*lda
317 icurrow = mod( icurrow+1, nprow )
318 icurcol = mod( icurcol+1, npcol )
319 30 CONTINUE
320 CALL igamx2d( ictxt, 'All', ' ', 1, 1, info, 1, idum, idum,
321 $ -1, -1, mycol )
322 IF( info.NE.0 )
323 $ RETURN
324 END IF
325
326
327
328 CALL pctrsm( 'Left', uplo, trans, diag, n, nrhs, one, a, ia, ja,
329 $ desca, b, ib, jb, descb )
330
331 RETURN
332
333
334
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
integer function iceil(inum, idenom)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
subroutine pxerbla(ictxt, srname, info)