SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
All Classes Files Functions Variables Typedefs Macros
pstrtrs.f
Go to the documentation of this file.
1 SUBROUTINE pstrtrs( UPLO, TRANS, DIAG, N, NRHS, A, IA, JA, DESCA,
2 $ B, IB, JB, DESCB, INFO )
3*
4* -- ScaLAPACK auxiliary routine (version 1.7) --
5* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
6* and University of California, Berkeley.
7* May 1, 1997
8*
9* .. Scalar Arguments ..
10 CHARACTER DIAG, TRANS, UPLO
11 INTEGER IA, IB, INFO, JA, JB, N, NRHS
12* ..
13* .. Array Arguments ..
14 INTEGER DESCA( * ), DESCB( * )
15 REAL A( * ), B( * )
16* ..
17*
18* Purpose
19* =======
20*
21* PSTRTRS solves a triangular system of the form
22*
23* sub( A ) * X = sub( B ) or sub( A )**T * X = sub( B ),
24*
25* where sub( A ) denotes A(IA:IA+N-1,JA:JA+N-1) and is a triangular
26* distributed matrix of order N, and B(IB:IB+N-1,JB:JB+NRHS-1) is an
27* N-by-NRHS distributed matrix denoted by sub( B ). A check is made
28* to verify that sub( A ) is nonsingular.
29*
30* Notes
31* =====
32*
33* Each global data object is described by an associated description
34* vector. This vector stores the information required to establish
35* the mapping between an object element and its corresponding process
36* and memory location.
37*
38* Let A be a generic term for any 2D block cyclicly distributed array.
39* Such a global array has an associated description vector DESCA.
40* In the following comments, the character _ should be read as
41* "of the global array".
42*
43* NOTATION STORED IN EXPLANATION
44* --------------- -------------- --------------------------------------
45* DTYPE_A(global) DESCA( DTYPE_ )The descriptor type. In this case,
46* DTYPE_A = 1.
47* CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
48* the BLACS process grid A is distribu-
49* ted over. The context itself is glo-
50* bal, but the handle (the integer
51* value) may vary.
52* M_A (global) DESCA( M_ ) The number of rows in the global
53* array A.
54* N_A (global) DESCA( N_ ) The number of columns in the global
55* array A.
56* MB_A (global) DESCA( MB_ ) The blocking factor used to distribute
57* the rows of the array.
58* NB_A (global) DESCA( NB_ ) The blocking factor used to distribute
59* the columns of the array.
60* RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
61* row of the array A is distributed.
62* CSRC_A (global) DESCA( CSRC_ ) The process column over which the
63* first column of the array A is
64* distributed.
65* LLD_A (local) DESCA( LLD_ ) The leading dimension of the local
66* array. LLD_A >= MAX(1,LOCr(M_A)).
67*
68* Let K be the number of rows or columns of a distributed matrix,
69* and assume that its process grid has dimension p x q.
70* LOCr( K ) denotes the number of elements of K that a process
71* would receive if K were distributed over the p processes of its
72* process column.
73* Similarly, LOCc( K ) denotes the number of elements of K that a
74* process would receive if K were distributed over the q processes of
75* its process row.
76* The values of LOCr() and LOCc() may be determined via a call to the
77* ScaLAPACK tool function, NUMROC:
78* LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
79* LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
80* An upper bound for these quantities may be computed by:
81* LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
82* LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
83*
84* Arguments
85* =========
86*
87* UPLO (global input) CHARACTER
88* = 'U': sub( A ) is upper triangular;
89* = 'L': sub( A ) is lower triangular.
90*
91* TRANS (global input) CHARACTER
92* Specifies the form of the system of equations:
93* = 'N': Solve sub( A ) * X = sub( B ) (No transpose)
94* = 'T': Solve sub( A )**T * X = sub( B ) (Transpose)
95* = 'C': Solve sub( A )**T * X = sub( B ) (Transpose)
96*
97* DIAG (global input) CHARACTER
98* = 'N': sub( A ) is non-unit triangular;
99* = 'U': sub( A ) is unit triangular.
100*
101* N (global input) INTEGER
102* The number of rows and columns to be operated on i.e the
103* order of the distributed submatrix sub( A ). N >= 0.
104*
105* NRHS (global input) INTEGER
106* The number of right hand sides, i.e., the number of columns
107* of the distributed matrix sub( B ). NRHS >= 0.
108*
109* A (local input) REAL pointer into the local memory
110* to an array of dimension (LLD_A,LOCc(JA+N-1) ). This array
111* contains the local pieces of the distributed triangular
112* matrix sub( A ). If UPLO = 'U', the leading N-by-N upper
113* triangular part of sub( A ) contains the upper triangular
114* matrix, and the strictly lower triangular part of sub( A )
115* is not referenced. If UPLO = 'L', the leading N-by-N lower
116* triangular part of sub( A ) contains the lower triangular
117* matrix, and the strictly upper triangular part of sub( A )
118* is not referenced. If DIAG = 'U', the diagonal elements of
119* sub( A ) are also not referenced and are assumed to be 1.
120*
121* IA (global input) INTEGER
122* The row index in the global array A indicating the first
123* row of sub( A ).
124*
125* JA (global input) INTEGER
126* The column index in the global array A indicating the
127* first column of sub( A ).
128*
129* DESCA (global and local input) INTEGER array of dimension DLEN_.
130* The array descriptor for the distributed matrix A.
131*
132* B (local input/local output) REAL pointer into the
133* local memory to an array of dimension
134* (LLD_B,LOCc(JB+NRHS-1)). On entry, this array contains the
135* local pieces of the right hand side distributed matrix
136* sub( B ). On exit, if INFO = 0, sub( B ) is overwritten by
137* the solution matrix X.
138*
139* IB (global input) INTEGER
140* The row index in the global array B indicating the first
141* row of sub( B ).
142*
143* JB (global input) INTEGER
144* The column index in the global array B indicating the
145* first column of sub( B ).
146*
147* DESCB (global and local input) INTEGER array of dimension DLEN_.
148* The array descriptor for the distributed matrix B.
149*
150* INFO (output) INTEGER
151* = 0: successful exit
152* < 0: If the i-th argument is an array and the j-entry had
153* an illegal value, then INFO = -(i*100+j), if the i-th
154* argument is a scalar and had an illegal value, then
155* INFO = -i.
156* > 0: If INFO = i, the i-th diagonal element of sub( A ) is
157* zero, indicating that the submatrix is singular and the
158* solutions X have not been computed.
159*
160* =====================================================================
161*
162* .. Parameters ..
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* .. Local Scalars ..
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* .. Local Arrays ..
179 INTEGER IDUM1( 3 ), IDUM2( 3 )
180* ..
181* .. External Subroutines ..
182 EXTERNAL blacs_gridinfo, chk1mat, igamx2d, infog2l,
183 $ pchk2mat, pstrsm, pxerbla
184* ..
185* .. External Functions ..
186 LOGICAL LSAME
187 INTEGER ICEIL, INDXG2P
188 EXTERNAL iceil, indxg2p, lsame
189* ..
190* .. Intrinsic Functions ..
191 INTRINSIC ichar, min, mod
192* ..
193* .. Executable Statements ..
194*
195* Get grid parameters
196*
197 ictxt = desca( ctxt_ )
198 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
199*
200* Test input parameters
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* Quick return if possible
268*
269 IF( n.EQ.0 .OR. nrhs.EQ.0 )
270 $ RETURN
271*
272* Check for singularity if non-unit.
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* Handle first block separately
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* Loop over remaining blocks of columns
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* Solve A * x = b or A' * x = b.
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* End of PSTRTRS
332*
333 END
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
Definition chk1mat.f:3
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
Definition infog2l.f:3
#define min(A, B)
Definition pcgemr.c:181
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
Definition pchkxmat.f:175
subroutine pstrtrs(uplo, trans, diag, n, nrhs, a, ia, ja, desca, b, ib, jb, descb, info)
Definition pstrtrs.f:3
subroutine pxerbla(ictxt, srname, info)
Definition pxerbla.f:2