Routine: PZLAPIV()  File: SRC\pzlapiv.f

 
 
# lines: 356
  # code: 356
  # comment: 0
  # blank:0
# Variables:39
# Callers:2
# Callings:1
# Words:96
# Keywords:59
 

 

..
     .. Array Arguments ..
     ..
  Purpose
  =======
  PZLAPIV applies either P (permutation matrix indicated by IPIV)
  or inv( P ) to a general M-by-N distributed matrix
  sub( A ) = A(IA:IA+M-1,JA:JA+N-1), resulting in row or column
  pivoting. The pivot vector may be distributed across a process row
  or a column. The pivot vector should be aligned with the distributed
  matrix A. This routine will transpose the pivot vector if necessary.
  For example if the row pivots should be applied to the columns of
  sub( A ), pass ROWCOL='C' and PIVROC='C'.
  Notes
  =====
  Each global data object is described by an associated description
  vector.  This vector stores the information required to establish
  the mapping between an object element and its corresponding process
  and memory location.
  Let A be a generic term for any 2D block cyclicly distributed array.
  Such a global array has an associated description vector DESCA.
  In the following comments, the character _ should be read as
  "of the global array".
  NOTATION        STORED IN      EXPLANATION
  --------------- -------------- --------------------------------------
  DTYPE_A(global) DESCA( DTYPE_ )The descriptor type.  In this case,
                                 DTYPE_A = 1.
  CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
                                 the BLACS process grid A is distribu-
                                 ted over. The context itself is glo-
                                 bal, but the handle (the integer
                                 value) may vary.
  M_A    (global) DESCA( M_ )    The number of rows in the global
                                 array A.
  N_A    (global) DESCA( N_ )    The number of columns in the global
                                 array A.
  MB_A   (global) DESCA( MB_ )   The blocking factor used to distribute
                                 the rows of the array.
  NB_A   (global) DESCA( NB_ )   The blocking factor used to distribute
                                 the columns of the array.
  RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
                                 row of the array A is distributed.
  CSRC_A (global) DESCA( CSRC_ ) The process column over which the
                                 first column of the array A is
                                 distributed.
  LLD_A  (local)  DESCA( LLD_ )  The leading dimension of the local
                                 array.  LLD_A >= MAX(1,LOCr(M_A)).
  Let K be the number of rows or columns of a distributed matrix,
  and assume that its process grid has dimension p x q.
  LOCr( K ) denotes the number of elements of K that a process
  would receive if K were distributed over the p processes of its
  process column.
  Similarly, LOCc( K ) denotes the number of elements of K that a
  process would receive if K were distributed over the q processes of
  its process row.
  The values of LOCr() and LOCc() may be determined via a call to the
  ScaLAPACK tool function, NUMROC:
          LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
          LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
  An upper bound for these quantities may be computed by:
          LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
          LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
  Restrictions
  ============
  IPIV must always be a distributed vector (not a matrix).  Thus:
  IF( ROWPIV .EQ. 'C' ) THEN
     JP must be 1
  ELSE
     IP must be 1
  END IF
  The following restrictions apply when IPIV must be transposed:
  IF( ROWPIV.EQ.'C' .AND. PIVROC.EQ.'C') THEN
      DESCIP(MB_) must equal DESCA(NB_)
  ELSE IF( ROWPIV.EQ.'R" .AND. PIVROC.EQ.'R') THEN
      DESCIP(NB_) must equal DESCA(MB_)
  END IF
  Arguments
  =========
  DIREC   (global input) CHARACTER*1
          Specifies in which order the permutation is applied:
            = 'F' (Forward) Applies pivots Forward from top of matrix.
                  Computes P*sub( A ).
            = 'B' (Backward) Applies pivots Backward from bottom of
                  matrix. Computes inv( P )*sub( A ).
  ROWCOL  (global input) CHARACTER*1
          Specifies if the rows or columns are to be permuted:
             = 'R' Rows will be permuted,
             = 'C' Columns will be permuted.
  PIVROC  (global input) CHARACTER*1
          Specifies whether IPIV is distributed over a process row
          or column:
          = 'R' IPIV distributed over a process row
          = 'C' IPIV distributed over a process column
  M       (global input) INTEGER
          The number of rows to be operated on, i.e. the number of
          rows of the distributed submatrix sub( A ). M >= 0.
  N       (global input) INTEGER
          The number of columns to be operated on, i.e. the number of
          columns of the distributed submatrix sub( A ). N >= 0.
  A       (local input/local output) COMPLEX*16 pointer into the
          local memory to an array of dimension (LLD_A, LOCc(JA+N-1)).
          On entry, this array contains the local pieces of the
          distributed submatrix sub( A ) to which the row or column
          interchanges will be applied. On exit, the local pieces
          of the permuted distributed submatrix.
  IA      (global input) INTEGER
          The row index in the global array A indicating the first
          row of sub( A ).
  JA      (global input) INTEGER
          The column index in the global array A indicating the
          first column of sub( A ).
  DESCA   (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed matrix A.
  IPIV    (local input) INTEGER array, dimension (LIPIV) where LIPIV is
          when ROWCOL='R' or 'r':
             >= LOCr( IA+M-1 ) + MB_A      if PIVROC='C' or 'c',
             >= LOCc( M + MOD(JP-1,NB_P) ) if PIVROC='R' or 'r', and,
          when ROWCOL='C' or 'c':
             >= LOCr( N + MOD(IP-1,MB_P) ) if PIVROC='C' or 'c',
             >= LOCc( JA+N-1 ) + NB_A      if PIVROC='R' or 'r'.
          This array contains the pivoting information. IPIV(i) is the
          global row (column), local row (column) i was swapped with.
          When ROWCOL='R' or 'r' and PIVROC='C' or 'c', or ROWCOL='C'
          or 'c' and PIVROC='R' or 'r', the last piece of this array of
          size MB_A (resp. NB_A) is used as workspace. In those cases,
          this array is tied to the distributed matrix A.
  IP      (global input) INTEGER
          The row index in the global array P indicating the first
          row of sub( P ).
  JP      (global input) INTEGER
          The column index in the global array P indicating the
          first column of sub( P ).
  DESCIP  (global and local input) INTEGER array of dimension DLEN_.
          The array descriptor for the distributed vector IPIV.
  IWORK   (local workspace) INTEGER array, dimension (LDW)
          where LDW is equal to the workspace necessary for
          transposition, and the storage of the tranposed IPIV:
          Let LCM be the least common multiple of NPROW and NPCOL.
          IF( ROWCOL.EQ.'R' .AND. PIVROC.EQ.'R' ) THEN
             IF( NPROW.EQ.NPCOL ) THEN
                LDW = LOCr( N_P + MOD(JP-1, NB_P) ) + NB_P
             ELSE
                LDW = LOCr( N_P + MOD(JP-1, NB_P) ) +
                      NB_P * CEIL( CEIL(LOCc(N_P)/NB_P) / (LCM/NPCOL) )
             END IF
          ELSE IF( ROWCOL.EQ.'C' .AND. PIVROC.EQ.'C' ) THEN
             IF( NPROW.EQ.NPCOL ) THEN
                LDW = LOCc( M_P + MOD(IP-1, MB_P) ) + MB_P
             ELSE
                LDW = LOCc( M_P + MOD(IP-1, MB_P) ) +
                      MB_P * CEIL( CEIL(LOCr(M_P)/MB_P) / (LCM/NPROW) )
             END IF
          ELSE
             IWORK is not referenced.
          END IF
  =====================================================================
     .. Parameters ..

 
Display dynamic version Find AutoScroll Reload FontSize: - + Hide Comments Hide Blanks Frame FullScreen MailPrint

 
001        SUBROUTINE PZLAPIV( DIREC , ROWCOL , PIVROC , M , N , A , IA , JA ,
002       $DESCA , IPIV , IP , JP , DESCIP , IWORK )
003  
004  *     -- ScaLAPACK auxiliary routine(version 1.7) --
005  *     University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
006  *     and University of California , Berkeley.
007  *     November 15 , 1997
008  
009  *     .. Scalar Arguments ..
010        CHARACTER*1 DIREC , PIVROC , ROWCOL
011        INTEGER IA , IP , JA , JP , M , N
012        INTEGER BLOCK_CYCLIC_2D , CSRC_ , CTXT_ , DLEN_ , DTYPE_ ,
013       $LLD_ , MB_ , M_ , NB_ , N_ , RSRC_
014        PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
015       $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
016       $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
017  *     ..
018  *     .. Local Scalars ..
019        LOGICAL ROWPVT
020        INTEGER I , ICTXT , ICURCOL , ICURROW , IIP , ITMP , IPT ,
021       $JJP , JPT , MYCOL , MYROW , NPCOL , NPROW
022  *     ..
023  *     .. Local Arrays ..
024        INTEGER DESCPT( DLEN_ )
025  *     ..
026  *     .. External Subroutines ..
027        EXTERNAL BLACS_GRIDINFO , IGEBR2D , IGEBS2D ,
028       $INFOG2L , PICOL2ROW , PIROW2COL , PZLAPV2  
029  *     ..
030  *     .. External Functions ..
031        LOGICAL LSAME
032        INTEGER NUMROC , INDXG2P
033        EXTERNAL LSAME , NUMROC , INDXG2P
034  *     ..
035  *     .. Intrinsic Functions ..
036        INTRINSIC MAX , MOD
037  *     ..
038  *     .. Executable Statements ..
039  
040  *     Get grid parameters
041  
042        ICTXT = DESCA( CTXT_ )
043        CALL BLACS_GRIDINFO( ICTXT , NPROW , NPCOL , MYROW , MYCOL )
044        ROWPVT = LSAME( ROWCOL , 'R' )
045  
046  *     If we're pivoting the rows of sub( A )
047  
048        IF( ROWPVT ) THEN
049            IF( M.LE.1 .OR. N.LT.1 )
050       $        RETURN
051  
052  *             If the pivot vector is already distributed correctly
053  
054                IF( LSAME( PIVROC , 'C' ) ) THEN
055                    CALL PZLAPV2 ( DIREC , ROWCOL , M , N , A , IA , JA , DESCA , IPIV ,
056       $            IP , JP , DESCIP )
057  
058  *                 Otherwise , we must redistribute IPIV to match PZLAPV2
059  
060                ELSE
061  
062  *                 Take IPIV distributed over row 0 , and store it in
063  *                 iwork , distributed over column 0
064  
065                    IPT = MOD( JP - 1 , DESCA(MB_) )
066                    DESCPT(M_) = M + IPT + NPROW*DESCA(MB_)
067                    DESCPT(N_) = 1
068                    DESCPT(MB_) = DESCA(MB_)
069                    DESCPT(NB_) = 1
070                    DESCPT(RSRC_) = INDXG2P( IA , DESCA(MB_) , IA , DESCA(RSRC_) ,
071       $            NPROW )
072                    DESCPT(CSRC_) = MYCOL
073                    DESCPT(CTXT_) = ICTXT
074                    DESCPT(LLD_) = NUMROC( DESCPT(M_) , DESCPT(MB_) , MYROW ,
075       $            DESCPT(RSRC_) , NPROW )
076                    ITMP = NUMROC( DESCIP(N_) , DESCIP(NB_) , MYCOL ,
077       $            DESCIP(CSRC_) , NPCOL )
078                    CALL INFOG2L( IP , JP - IPT , DESCIP , NPROW , NPCOL , MYROW ,
079       $            MYCOL , IIP , JJP , ICURROW , ICURCOL )
080                    CALL PIROW2COL( ICTXT , M + IPT , 1 , DESCIP(NB_) , IPIV(JJP) ,
081       $            ITMP , IWORK , DESCPT(LLD_) , 0 , ICURCOL ,
082       $            DESCPT(RSRC_) ,
083       $            MYCOL , IWORK(DESCPT(LLD_) - DESCPT(MB_) + 1) )
084  
085  *                 Send column - distributed pivots to all columns
086  
087                    ITMP = DESCPT(LLD_) - DESCPT(MB_)
088                    IF( MYCOL.EQ.0 ) THEN
089                        CALL IGEBS2D( ICTXT , 'Row' , ' ' , ITMP , 1 , IWORK , ITMP )
090                    ELSE
091                        CALL IGEBR2D( ICTXT , 'Row' , ' ' , ITMP , 1 , IWORK , ITMP ,
092       $                MYROW , 0 )
093                    END IF
094  
095  *                 Adjust pivots so they are relative to the start of IWORK ,
096  *                 not IPIV
097  
098                    IPT = IPT + 1
099                    DO 10 I = 1 , ITMP
100                        IWORK(I) = IWORK(I) - JP + IPT
101     10             CONTINUE
102                    CALL PZLAPV2 ( DIREC , ROWCOL , M , N , A , IA , JA , DESCA , IWORK ,
103       $            IPT , 1 , DESCPT )
104                END IF
105  
106  *             Otherwise , we're pivoting the columns of sub( A )
107  
108            ELSE
109                IF( M.LT.1 .OR. N.LE.1 )
110       $            RETURN
111  
112  *                 If the pivot vector is already distributed correctly
113  
114                    IF( LSAME( PIVROC , 'R' ) ) THEN
115                        CALL PZLAPV2 ( DIREC , ROWCOL , M , N , A , IA , JA , DESCA , IPIV ,
116       $                IP , JP , DESCIP )
117  
118  *                     Otherwise , we must redistribute IPIV to match PZLAPV2
119  
120                    ELSE
121  
122  *                     Take IPIV distributed over column 0 , and store it in
123  *                     iwork , distributed over row 0
124  
125                        JPT = MOD( IP - 1 , DESCA(NB_) )
126                        DESCPT(M_) = 1
127                        DESCPT(N_) = N + JPT + NPCOL*DESCA(NB_)
128                        DESCPT(MB_) = 1
129                        DESCPT(NB_) = DESCA(NB_)
130                        DESCPT(RSRC_) = MYROW
131                        DESCPT(CSRC_) = INDXG2P( JA , DESCA(NB_) , JA , DESCA(CSRC_) ,
132       $                NPCOL )
133                        DESCPT(CTXT_) = ICTXT
134                        DESCPT(LLD_) = 1
135                        CALL INFOG2L( IP - JPT , JP , DESCIP , NPROW , NPCOL , MYROW ,
136       $                MYCOL , IIP , JJP , ICURROW , ICURCOL )
137                        ITMP = NUMROC( N + JPT , DESCPT(NB_) , MYCOL , DESCPT(CSRC_) ,
138       $                NPCOL )
139                        CALL PICOL2ROW( ICTXT , N + JPT , 1 , DESCIP(MB_) , IPIV(IIP) ,
140       $                DESCIP(LLD_) , IWORK , MAX(1 , ITMP) , ICURROW ,
141       $                0 , 0 , DESCPT(CSRC_) , IWORK(ITMP + 1) )
142  
143  *                     Send row - distributed pivots to all rows
144  
145                        IF( MYROW.EQ.0 ) THEN
146                            CALL IGEBS2D( ICTXT , 'Column' , ' ' , ITMP , 1 , IWORK ,
147       $                    ITMP )
148                        ELSE
149                            CALL IGEBR2D( ICTXT , 'Column' , ' ' , ITMP , 1 , IWORK ,
150       $                    ITMP , 0 , MYCOL )
151                        END IF
152  
153  *                     Adjust pivots so they are relative to the start of IWORK ,
154  *                     not IPIV
155  
156                        JPT = JPT + 1
157                        DO 20 I = 1 , ITMP
158                            IWORK(I) = IWORK(I) - IP + JPT
159     20                 CONTINUE
160                        CALL PZLAPV2 ( DIREC , ROWCOL , M , N , A , IA , JA , DESCA , IWORK ,
161       $                1 , JPT , DESCPT )
162                    END IF
163                END IF
164  
165                RETURN
166  
167  *             End of PZLAPIV
168  
169            END