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