SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ psgebdrv()

subroutine psgebdrv ( integer  m,
integer  n,
real, dimension( * )  a,
integer  ia,
integer  ja,
integer, dimension( * )  desca,
real, dimension( * )  d,
real, dimension( * )  e,
real, dimension( * )  tauq,
real, dimension( * )  taup,
real, dimension( * )  work,
integer  info 
)

Definition at line 1 of file psgebdrv.f.

3*
4* -- ScaLAPACK 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 INTEGER INFO, IA, JA, M, N
11* ..
12* .. Array Arguments ..
13 INTEGER DESCA( * )
14 REAL A( * ), D( * ), E( * ), TAUP( * ), TAUQ( * ),
15 $ WORK( * )
16* ..
17*
18* Purpose
19* =======
20*
21* PSGEBDRV computes sub( A ) = A(IA:IA+M-1,JA:JA+N-1) from sub( A ),
22* Q, P returned by PSGEBRD:
23*
24* sub( A ) := Q * B * P'.
25*
26* Notes
27* =====
28*
29* Each global data object is described by an associated description
30* vector. This vector stores the information required to establish
31* the mapping between an object element and its corresponding process
32* and memory location.
33*
34* Let A be a generic term for any 2D block cyclicly distributed array.
35* Such a global array has an associated description vector DESCA.
36* In the following comments, the character _ should be read as
37* "of the global array".
38*
39* NOTATION STORED IN EXPLANATION
40* --------------- -------------- --------------------------------------
41* DTYPE_A(global) DESCA( DTYPE_ )The descriptor type. In this case,
42* DTYPE_A = 1.
43* CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
44* the BLACS process grid A is distribu-
45* ted over. The context itself is glo-
46* bal, but the handle (the integer
47* value) may vary.
48* M_A (global) DESCA( M_ ) The number of rows in the global
49* array A.
50* N_A (global) DESCA( N_ ) The number of columns in the global
51* array A.
52* MB_A (global) DESCA( MB_ ) The blocking factor used to distribute
53* the rows of the array.
54* NB_A (global) DESCA( NB_ ) The blocking factor used to distribute
55* the columns of the array.
56* RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
57* row of the array A is distributed.
58* CSRC_A (global) DESCA( CSRC_ ) The process column over which the
59* first column of the array A is
60* distributed.
61* LLD_A (local) DESCA( LLD_ ) The leading dimension of the local
62* array. LLD_A >= MAX(1,LOCr(M_A)).
63*
64* Let K be the number of rows or columns of a distributed matrix,
65* and assume that its process grid has dimension p x q.
66* LOCr( K ) denotes the number of elements of K that a process
67* would receive if K were distributed over the p processes of its
68* process column.
69* Similarly, LOCc( K ) denotes the number of elements of K that a
70* process would receive if K were distributed over the q processes of
71* its process row.
72* The values of LOCr() and LOCc() may be determined via a call to the
73* ScaLAPACK tool function, NUMROC:
74* LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
75* LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
76* An upper bound for these quantities may be computed by:
77* LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
78* LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
79*
80* Arguments
81* =========
82*
83* M (global input) INTEGER
84* The number of rows to be operated on, i.e. the number of rows
85* of the distributed submatrix sub( A ). M >= 0.
86*
87* N (global input) INTEGER
88* The number of columns to be operated on, i.e. the number of
89* columns of the distributed submatrix sub( A ). N >= 0.
90*
91* A (local input/local output) REAL pointer into the
92* local memory to an array of dimension (LLD_A, LOCc(JA+N-1)).
93* On entry, this array contains the local pieces of sub( A )
94* as returned by PSGEBRD. On exit, the original distribu-
95* ted matrix sub( A ) is restored.
96*
97* IA (global input) INTEGER
98* The row index in the global array A indicating the first
99* row of sub( A ).
100*
101* JA (global input) INTEGER
102* The column index in the global array A indicating the
103* first column of sub( A ).
104*
105* DESCA (global and local input) INTEGER array of dimension DLEN_.
106* The array descriptor for the distributed matrix A.
107*
108* D (local input) REAL array, dimension
109* LOCc(JA+MIN(M,N)-1) if M >= N; LOCr(IA+MIN(M,N)-1) otherwise.
110* The distributed diagonal elements of the bidiagonal matrix
111* B: D(i) = A(i,i). D is tied to the distributed matrix A.
112*
113* E (local input) REAL array, dimension
114* LOCr(IA+MIN(M,N)-1) if M >= N; LOCc(JA+MIN(M,N)-2) otherwise.
115* The distributed off-diagonal elements of the bidiagonal
116* distributed matrix B:
117* if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;
118* if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.
119* E is tied to the distributed matrix A.
120*
121* TAUQ (local input) REAL array dimension
122* LOCc(JA+MIN(M,N)-1). The scalar factors of the elementary
123* reflectors which represent the orthogonal matrix Q. TAUQ
124* is tied to the distributed matrix A. See Further Details.
125*
126* TAUP (local input) REAL array, dimension
127* LOCr(IA+MIN(M,N)-1). The scalar factors of the elementary
128* reflectors which represent the orthogonal matrix P. TAUP
129* is tied to the distributed matrix A. See Further Details.
130*
131* WORK (local workspace) REAL array, dimension (LWORK)
132* LWORK >= 2*NB*( MP + NQ + NB )
133*
134* where NB = MB_A = NB_A,
135* IROFFA = MOD( IA-1, NB ), ICOFFA = MOD( JA-1, NB ),
136* IAROW = INDXG2P( IA, NB, MYROW, RSRC_A, NPROW ),
137* IACOL = INDXG2P( JA, NB, MYCOL, CSRC_A, NPCOL ),
138* MP = NUMROC( M+IROFFA, NB, MYROW, IAROW, NPROW ),
139* NQ = NUMROC( N+ICOFFA, NB, MYCOL, IACOL, NPCOL ).
140*
141* INDXG2P and NUMROC are ScaLAPACK tool functions;
142* MYROW, MYCOL, NPROW and NPCOL can be determined by calling
143* the subroutine BLACS_GRIDINFO.
144*
145* INFO (global output) INTEGER
146* On exit, if INFO <> 0, a discrepancy has been found between
147* the diagonal and off-diagonal elements of A and the copies
148* contained in the arrays D and E.
149*
150* =====================================================================
151*
152* .. Parameters ..
153 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
154 $ LLD_, MB_, M_, NB_, N_, RSRC_
155 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
156 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
157 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
158 REAL EIGHT, ONE, ZERO
159 parameter( eight = 8.0e+0, one = 1.0e+0, zero = 0.0e+0 )
160* ..
161* .. Local Scalars ..
162 INTEGER I, IACOL, IAROW, ICTXT, IIA, IL, IPTP, IPTQ,
163 $ IPV, IPW, IPWK, IOFF, IV, J, JB, JJA, JL, JV,
164 $ K, MN, MP, MYCOL, MYROW, NB, NPCOL, NPROW, NQ
165 REAL ADDBND, D1, D2, E1, E2
166* ..
167* .. Local Arrays ..
168 INTEGER DESCD( DLEN_ ), DESCE( DLEN_ ), DESCV( DLEN_ ),
169 $ DESCW( DLEN_ )
170* ..
171* .. External Subroutines ..
172 EXTERNAL blacs_gridinfo, descset, igsum2d, infog2l,
174 $ pselget
175* ..
176* .. External Functions ..
177 INTEGER INDXG2P, NUMROC
178 REAL PSLAMCH
179 EXTERNAL indxg2p, numroc, pslamch
180* ..
181* .. Intrinsic Functions ..
182 INTRINSIC abs, max, min, mod
183* ..
184* .. Executable Statements ..
185*
186* Get grid parameters
187*
188 ictxt = desca( ctxt_ )
189 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
190*
191 info = 0
192 nb = desca( mb_ )
193 ioff = mod( ia-1, nb )
194 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
195 $ iarow, iacol )
196 mp = numroc( m+ioff, nb, myrow, iarow, nprow )
197 nq = numroc( n+ioff, nb, mycol, iacol, npcol )
198 ipv = 1
199 ipw = ipv + mp*nb
200 iptp = ipw + nq*nb
201 iptq = iptp + nb*nb
202 ipwk = iptq + nb*nb
203*
204 iv = 1
205 jv = 1
206 mn = min( m, n )
207 il = max( ( (ia+mn-2) / nb )*nb + 1, ia )
208 jl = max( ( (ja+mn-2) / nb )*nb + 1, ja )
209 iarow = indxg2p( il, nb, myrow, desca( rsrc_ ), nprow )
210 iacol = indxg2p( jl, nb, mycol, desca( csrc_ ), npcol )
211 CALL descset( descv, ia+m-il, nb, nb, nb, iarow, iacol, ictxt,
212 $ max( 1, mp ) )
213 CALL descset( descw, nb, ja+n-jl, nb, nb, iarow, iacol, ictxt,
214 $ nb )
215*
216 addbnd = eight * pslamch( ictxt, 'eps' )
217*
218* When A is an upper bidiagonal form
219*
220 IF( m.GE.n ) THEN
221*
222 CALL descset( descd, 1, ja+mn-1, 1, desca( nb_ ), myrow,
223 $ desca( csrc_ ), desca( ctxt_ ), 1 )
224 CALL descset( desce, ia+mn-1, 1, desca( mb_ ), 1,
225 $ desca( rsrc_ ), mycol, desca( ctxt_ ),
226 $ desca( lld_ ) )
227*
228 DO 10 j = 0, mn-1
229 d1 = zero
230 e1 = zero
231 d2 = zero
232 e2 = zero
233 CALL pselget( ' ', ' ', d2, d, 1, ja+j, descd )
234 CALL pselget( 'Columnwise', ' ', d1, a, ia+j, ja+j, desca )
235 IF( j.LT.(mn-1) ) THEN
236 CALL pselget( ' ', ' ', e2, e, ia+j, 1, desce )
237 CALL pselget( 'Rowwise', ' ', e1, a, ia+j, ja+j+1,
238 $ desca )
239 END IF
240*
241 IF( ( abs( d1 - d2 ).GT.( abs( d2 ) * addbnd ) ) .OR.
242 $ ( abs( e1 - e2 ).GT.( abs( e2 ) * addbnd ) ) )
243 $ info = info + 1
244 10 CONTINUE
245*
246 DO 20 j = jl, ja+nb-ioff, -nb
247 jb = min( ja+n-j, nb )
248 i = ia + j - ja
249 k = i - ia + 1
250*
251* Compute upper triangular matrix TQ from TAUQ.
252*
253 CALL pslarft( 'Forward', 'Columnwise', m-k+1, jb, a, i, j,
254 $ desca, tauq, work( iptq ), work( ipwk ) )
255*
256* Copy Householder vectors into workspace.
257*
258 CALL pslacpy( 'Lower', m-k+1, jb, a, i, j, desca,
259 $ work( ipv ), iv, jv, descv )
260 CALL pslaset( 'Upper', m-k+1, jb, zero, one, work( ipv ),
261 $ iv, jv, descv )
262*
263* Zero out the strict lower triangular part of A.
264*
265 CALL pslaset( 'Lower', m-k, jb, zero, zero, a, i+1, j,
266 $ desca )
267*
268* Compute upper triangular matrix TP from TAUP.
269*
270 CALL pslarft( 'Forward', 'Rowwise', n-k, jb, a, i, j+1,
271 $ desca, taup, work( iptp ), work( ipwk ) )
272*
273* Copy Householder vectors into workspace.
274*
275 CALL pslacpy( 'Upper', jb, n-k, a, i, j+1, desca,
276 $ work( ipw ), iv, jv+1, descw )
277 CALL pslaset( 'Lower', jb, n-k, zero, one, work( ipw ), iv,
278 $ jv+1, descw )
279*
280* Zero out the strict+1 upper triangular part of A.
281*
282 CALL pslaset( 'Upper', jb, n-k-1, zero, zero, a, i, j+2,
283 $ desca )
284*
285* Apply block Householder transformation from Left.
286*
287 CALL pslarfb( 'Left', 'No transpose', 'Forward',
288 $ 'Columnwise', m-k+1, n-k+1, jb, work( ipv ),
289 $ iv, jv, descv, work( iptq ), a, i, j, desca,
290 $ work( ipwk ) )
291*
292* Apply block Householder transformation from Right.
293*
294 CALL pslarfb( 'Right', 'Transpose', 'Forward', 'Rowwise',
295 $ m-k+1, n-k, jb, work( ipw ), iv, jv+1, descw,
296 $ work( iptp ), a, i, j+1, desca, work( ipwk ) )
297*
298 descv( m_ ) = descv( m_ ) + nb
299 descv( rsrc_ ) = mod( descv( rsrc_ ) + nprow - 1, nprow )
300 descv( csrc_ ) = mod( descv( csrc_ ) + npcol - 1, npcol )
301 descw( n_ ) = descw( n_ ) + nb
302 descw( rsrc_ ) = descv( rsrc_ )
303 descw( csrc_ ) = descv( csrc_ )
304*
305 20 CONTINUE
306*
307* Handle first block separately
308*
309 jb = min( n, nb - ioff )
310 iv = ioff + 1
311 jv = ioff + 1
312*
313* Compute upper triangular matrix TQ from TAUQ.
314*
315 CALL pslarft( 'Forward', 'Columnwise', m, jb, a, ia, ja, desca,
316 $ tauq, work( iptq ), work( ipwk ) )
317*
318* Copy Householder vectors into workspace.
319*
320 CALL pslacpy( 'Lower', m, jb, a, ia, ja, desca, work( ipv ),
321 $ iv, jv, descv )
322 CALL pslaset( 'Upper', m, jb, zero, one, work( ipv ), iv, jv,
323 $ descv )
324*
325* Zero out the strict lower triangular part of A.
326*
327 CALL pslaset( 'Lower', m-1, jb, zero, zero, a, ia+1, ja,
328 $ desca )
329*
330* Compute upper triangular matrix TP from TAUP.
331*
332 CALL pslarft( 'Forward', 'Rowwise', n-1, jb, a, ia, ja+1,
333 $ desca, taup, work( iptp ), work( ipwk ) )
334*
335* Copy Householder vectors into workspace.
336*
337 CALL pslacpy( 'Upper', jb, n-1, a, ia, ja+1, desca,
338 $ work( ipw ), iv, jv+1, descw )
339 CALL pslaset( 'Lower', jb, n-1, zero, one, work( ipw ), iv,
340 $ jv+1, descw )
341*
342* Zero out the strict+1 upper triangular part of A.
343*
344 CALL pslaset( 'Upper', jb, n-2, zero, zero, a, ia, ja+2,
345 $ desca )
346*
347* Apply block Householder transformation from left.
348*
349 CALL pslarfb( 'Left', 'No transpose', 'Forward', 'Columnwise',
350 $ m, n, jb, work( ipv ), iv, jv, descv,
351 $ work( iptq ), a, ia, ja, desca, work( ipwk ) )
352*
353* Apply block Householder transformation from right.
354*
355 CALL pslarfb( 'Right', 'Transpose', 'Forward', 'Rowwise', m,
356 $ n-1, jb, work( ipw ), iv, jv+1, descw,
357 $ work( iptp ), a, ia, ja+1, desca, work( ipwk ) )
358*
359 ELSE
360*
361 CALL descset( descd, ia+mn-1, 1, desca( mb_ ), 1,
362 $ desca( rsrc_ ), mycol, desca( ctxt_ ),
363 $ desca( lld_ ) )
364 CALL descset( desce, 1, ja+mn-2, 1, desca( nb_ ), myrow,
365 $ desca( csrc_ ), desca( ctxt_ ), 1 )
366*
367 DO 30 j = 0, mn-1
368 d1 = zero
369 e1 = zero
370 d2 = zero
371 e2 = zero
372 CALL pselget( ' ', ' ', d2, d, ia+j, 1, descd )
373 CALL pselget( 'Rowwise', ' ', d1, a, ia+j, ja+j, desca )
374 IF( j.LT.(mn-1) ) THEN
375 CALL pselget( ' ', ' ', e2, e, 1, ja+j, desce )
376 CALL pselget( 'Columnwise', ' ', e1, a, ia+j+1, ja+j,
377 $ desca )
378 END IF
379*
380 IF( ( abs( d1 - d2 ).GT.( abs( d2 ) * addbnd ) ) .OR.
381 $ ( abs( e1 - e2 ).GT.( abs( e2 ) * addbnd ) ) )
382 $ info = info + 1
383 30 CONTINUE
384*
385 DO 40 i = il, ia+nb-ioff, -nb
386 jb = min( ia+m-i, nb )
387 j = ja + i - ia
388 k = j - ja + 1
389*
390* Compute upper triangular matrix TQ from TAUQ.
391*
392 CALL pslarft( 'Forward', 'Columnwise', m-k, jb, a, i+1, j,
393 $ desca, tauq, work( iptq ), work( ipwk ) )
394*
395* Copy Householder vectors into workspace.
396*
397 CALL pslacpy( 'Lower', m-k, jb, a, i+1, j, desca,
398 $ work( ipv ), iv+1, jv, descv )
399 CALL pslaset( 'Upper', m-k, jb, zero, one, work( ipv ),
400 $ iv+1, jv, descv )
401*
402* Zero out the strict lower triangular part of A.
403*
404 CALL pslaset( 'Lower', m-k-1, jb, zero, zero, a, i+2, j,
405 $ desca )
406*
407* Compute upper triangular matrix TP from TAUP.
408*
409 CALL pslarft( 'Forward', 'Rowwise', n-k+1, jb, a, i, j,
410 $ desca, taup, work( iptp ), work( ipwk ) )
411*
412* Copy Householder vectors into workspace.
413*
414 CALL pslacpy( 'Upper', jb, n-k+1, a, i, j, desca,
415 $ work( ipw ), iv, jv, descw )
416 CALL pslaset( 'Lower', jb, n-k+1, zero, one, work( ipw ),
417 $ iv, jv, descw )
418*
419* Zero out the strict+1 upper triangular part of A.
420*
421 CALL pslaset( 'Upper', jb, n-k, zero, zero, a, i, j+1,
422 $ desca )
423*
424* Apply block Householder transformation from Left.
425*
426 CALL pslarfb( 'Left', 'No transpose', 'Forward',
427 $ 'Columnwise', m-k, n-k+1, jb, work( ipv ),
428 $ iv+1, jv, descv, work( iptq ), a, i+1, j,
429 $ desca, work( ipwk ) )
430*
431* Apply block Householder transformation from Right.
432*
433 CALL pslarfb( 'Right', 'Transpose', 'Forward', 'Rowwise',
434 $ m-k+1, n-k+1, jb, work( ipw ), iv, jv, descw,
435 $ work( iptp ), a, i, j, desca, work( ipwk ) )
436*
437 descv( m_ ) = descv( m_ ) + nb
438 descv( rsrc_ ) = mod( descv( rsrc_ ) + nprow - 1, nprow )
439 descv( csrc_ ) = mod( descv( csrc_ ) + npcol - 1, npcol )
440 descw( n_ ) = descw( n_ ) + nb
441 descw( rsrc_ ) = descv( rsrc_ )
442 descw( csrc_ ) = descv( csrc_ )
443*
444 40 CONTINUE
445*
446* Handle first block separately
447*
448 jb = min( m, nb - ioff )
449 iv = ioff + 1
450 jv = ioff + 1
451*
452* Compute upper triangular matrix TQ from TAUQ.
453*
454 CALL pslarft( 'Forward', 'Columnwise', m-1, jb, a, ia+1, ja,
455 $ desca, tauq, work( iptq ), work( ipwk ) )
456*
457* Copy Householder vectors into workspace.
458*
459 CALL pslacpy( 'Lower', m-1, jb, a, ia+1, ja, desca,
460 $ work( ipv ), iv+1, jv, descv )
461 CALL pslaset( 'Upper', m-1, jb, zero, one, work( ipv ), iv+1,
462 $ jv, descv )
463*
464* Zero out the strict lower triangular part of A.
465*
466 CALL pslaset( 'Lower', m-2, jb, zero, zero, a, ia+2, ja,
467 $ desca )
468*
469* Compute upper triangular matrix TP from TAUP.
470*
471 CALL pslarft( 'Forward', 'Rowwise', n, jb, a, ia, ja, desca,
472 $ taup, work( iptp ), work( ipwk ) )
473*
474* Copy Householder vectors into workspace.
475*
476 CALL pslacpy( 'Upper', jb, n, a, ia, ja, desca, work( ipw ),
477 $ iv, jv, descw )
478 CALL pslaset( 'Lower', jb, n, zero, one, work( ipw ), iv, jv,
479 $ descw )
480*
481* Zero out the strict+1 upper triangular part of A.
482*
483 CALL pslaset( 'Upper', jb, n-1, zero, zero, a, ia, ja+1,
484 $ desca )
485*
486* Apply block Householder transformation from left
487*
488 CALL pslarfb( 'Left', 'No transpose', 'Forward', 'Columnwise',
489 $ m-1, n, jb, work( ipv ), iv+1, jv, descv,
490 $ work( iptq ), a, ia+1, ja, desca, work( ipwk ) )
491*
492* Apply block Householder transformation from right
493*
494 CALL pslarfb( 'Right', 'Transpose', 'Forward', 'Rowwise', m, n,
495 $ jb, work( ipw ), iv, jv, descw, work( iptp ),
496 $ a, ia, ja, desca, work( ipwk ) )
497 END IF
498*
499 CALL igsum2d( ictxt, 'All', ' ', 1, 1, info, 1, -1, 0 )
500*
501 RETURN
502*
503* End of PSGEBDRV
504*
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
Definition descset.f:3
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
Definition indxg2p.f:2
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
Definition infog2l.f:3
integer function numroc(n, nb, iproc, isrcproc, nprocs)
Definition numroc.f:2
real function pslamch(ictxt, cmach)
Definition pcblastst.f:7455
#define max(A, B)
Definition pcgemr.c:180
#define min(A, B)
Definition pcgemr.c:181
subroutine pslaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
Definition psblastst.f:6863
subroutine pselget(scope, top, alpha, a, ia, ja, desca)
Definition pselget.f:2
subroutine pslacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
Definition pslacpy.f:3
subroutine pslarfb(side, trans, direct, storev, m, n, k, v, iv, jv, descv, t, c, ic, jc, descc, work)
Definition pslarfb.f:3
subroutine pslarft(direct, storev, n, k, v, iv, jv, descv, tau, t, work)
Definition pslarft.f:3
Here is the call graph for this function:
Here is the caller graph for this function: