2
3
4
5
6
7
8
9 CHARACTER DIAG, UPLO
10 INTEGER IA, INFO, JA, N
11
12
13 INTEGER DESCA( * )
14 DOUBLE PRECISION A( * )
15
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
134 $ LLD_, MB_, M_, NB_, N_, RSRC_
135 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
136 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
137 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
138 DOUBLE PRECISION ZERO, ONE
139 parameter( zero = 0.0d+0, one = 1.0d+0 )
140
141
142 LOGICAL NOUNIT, UPPER
143 INTEGER I, ICOFF, ICTXT, IROFF, ICURCOL, ICURROW,
144 $ IDUMMY, II, IOFFA, J, JB, JJ, JN, LDA, MYCOL,
145 $ MYROW, NN, NPCOL, NPROW
146
147
148 INTEGER IDUM1( 2 ), IDUM2( 2 )
149
150
154
155
156 LOGICAL LSAME
157 INTEGER ICEIL
159
160
161 INTRINSIC ichar,
min, mod
162
163
164
165
166
167 ictxt = desca( ctxt_ )
168 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
169
170
171
172 info = 0
173 IF( nprow.EQ.-1 ) THEN
174 info = -(700+ctxt_)
175 ELSE
176 upper =
lsame( uplo,
'U' )
177 nounit =
lsame( diag,
'N' )
178
179 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 7, info )
180 IF( info.EQ.0 ) THEN
181 iroff = mod( ia-1, desca( mb_ ) )
182 icoff = mod( ja-1, desca( nb_ ) )
183 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
184 info = -1
185 ELSE IF( .NOT.nounit .AND. .NOT.
lsame( diag,
'U' ) )
THEN
186 info = -2
187 ELSE IF( iroff.NE.icoff .OR. iroff.NE.0 ) THEN
188 info = -6
189 ELSE IF( desca( mb_ ).NE.desca( nb_ ) ) THEN
190 info = -(700+nb_)
191 END IF
192 END IF
193
194 IF( upper ) THEN
195 idum1( 1 ) = ichar( 'U' )
196 ELSE
197 idum1( 1 ) = ichar( 'L' )
198 END IF
199 idum2( 1 ) = 1
200 IF( nounit ) THEN
201 idum1( 2 ) = ichar( 'N' )
202 ELSE
203 idum1( 2 ) = ichar( 'U' )
204 END IF
205 idum2( 2 ) = 2
206
207 CALL pchk1mat( n, 3, n, 3, ia, ja, desca, 7, 2, idum1, idum2,
208 $ info )
209 END IF
210
211 IF( info.NE.0 ) THEN
212 CALL pxerbla( ictxt,
'PDTRTRI', -info )
213 RETURN
214 END IF
215
216
217
218 IF( n.EQ.0 )
219 $ RETURN
220
221
222
223 jn =
min(
iceil( ja, desca( nb_ ) ) * desca( nb_ ), ja+n-1 )
224 IF( nounit ) THEN
225 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol,
226 $ ii, jj, icurrow, icurcol )
227
228
229
230 jb = jn-ja+1
231 lda = desca( lld_ )
232 IF( myrow.EQ.icurrow .AND. mycol.EQ.icurcol ) THEN
233 ioffa = ii+(jj-1)*lda
234 DO 10 i = 0, jb-1
235 IF( a( ioffa ).EQ.zero .AND. info.EQ.0 )
236 $ info = i + 1
237 ioffa = ioffa + lda + 1
238 10 CONTINUE
239 END IF
240 IF( myrow.EQ.icurrow )
241 $ ii = ii + jb
242 IF( mycol.EQ.icurcol )
243 $ jj = jj + jb
244 icurrow = mod( icurrow+1, nprow )
245 icurcol = mod( icurcol+1, npcol )
246
247
248
249 DO 30 j = jn+1, ja+n-1, desca( nb_ )
250 jb =
min( ja+n-j, desca( nb_ ) )
251 IF( myrow.EQ.icurrow .AND. mycol.EQ.icurcol ) THEN
252 ioffa = ii+(jj-1)*lda
253 DO 20 i = 0, jb-1
254 IF( a( ioffa ).EQ.zero .AND. info.EQ.0 )
255 $ info = j + i - ja + 1
256 ioffa = ioffa + lda + 1
257 20 CONTINUE
258 END IF
259 IF( myrow.EQ.icurrow )
260 $ ii = ii + jb
261 IF( mycol.EQ.icurcol )
262 $ jj = jj + jb
263 icurrow = mod( icurrow+1, nprow )
264 icurcol = mod( icurcol+1, npcol )
265 30 CONTINUE
266 CALL igamx2d( ictxt, 'All', ' ', 1, 1, info, 1, idummy,
267 $ idummy, -1, -1, mycol )
268 IF( info.NE.0 )
269 $ RETURN
270 END IF
271
272
273
274 IF( upper ) THEN
275
276
277
278 jb = jn-ja+1
279
280
281
282 CALL pdtrti2( uplo, diag, jb, a, ia, ja, desca, info )
283
284
285
286 DO 40 j = jn+1, ja+n-1, desca( nb_ )
287 jb =
min( desca( nb_ ), ja+n-j )
288 i = ia + j - ja
289
290
291
292 CALL pdtrmm( 'Left', uplo, 'No transpose', diag, j-ja, jb,
293 $ one, a, ia, ja, desca, a, ia, j, desca )
294 CALL pdtrsm( 'Right', uplo, 'No transpose', diag, j-ja,
295 $ jb, -one, a, i, j, desca, a, ia, j, desca )
296
297
298
299 CALL pdtrti2( uplo, diag, jb, a, i, j, desca, info )
300
301 40 CONTINUE
302
303 ELSE
304
305
306
307 nn = ( ( ja+n-2 ) / desca( nb_ ) )*desca( nb_ ) + 1
308 DO 50 j = nn, jn+1, -desca( nb_ )
309 jb =
min( desca( nb_ ), ja+n-j )
310 i = ia + j - ja
311 IF( j+jb.LE.ja+n-1 ) THEN
312
313
314
315 CALL pdtrmm( 'Left', uplo, 'No transpose', diag,
316 $ ja+n-j-jb, jb, one, a, i+jb, j+jb, desca,
317 $ a, i+jb, j, desca )
318 CALL pdtrsm( 'Right', uplo, 'No transpose', diag,
319 $ ja+n-j-jb, jb, -one, a, i, j, desca,
320 $ a, i+jb, j, desca )
321 END IF
322
323
324
325 CALL pdtrti2( uplo, diag, jb, a, i, j, desca, info )
326
327 50 CONTINUE
328
329
330
331 jb = jn-ja+1
332 IF( ja+jb.LE.ja+n-1 ) THEN
333
334
335
336 CALL pdtrmm( 'Left', uplo, 'No transpose', diag, n-jb, jb,
337 $ one, a, ia+jb, ja+jb, desca, a, ia+jb, ja,
338 $ desca )
339 CALL pdtrsm( 'Right', uplo, 'No transpose', diag, n-jb, jb,
340 $ -one, a, ia, ja, desca, a, ia+jb, ja, desca )
341 END IF
342
343
344
345 CALL pdtrti2( uplo, diag, jb, a, ia, ja, desca, info )
346
347 END IF
348
349 RETURN
350
351
352
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
integer function iceil(inum, idenom)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
subroutine pdtrti2(uplo, diag, n, a, ia, ja, desca, info)
subroutine pxerbla(ictxt, srname, info)