Routine: PDLASCL()  File: SRC\pdlascl.f

 
 
# lines: 512
  # code: 512
  # comment: 0
  # blank:0
# Variables:60
# Callers:5
# Callings:1
# Words:332
# Keywords:234
 

 

..
     .. Array Arguments ..
     ..
  Purpose
  =======
  PDLASCL multiplies the M-by-N real distributed matrix sub( A )
  denoting A(IA:IA+M-1,JA:JA+N-1) by the real scalar CTO/CFROM.  This
  is done without over/underflow as long as the final result
  CTO * A(I,J) / CFROM does not over/underflow. TYPE specifies that
  sub( A ) may be full, upper triangular, lower triangular or upper
  Hessenberg.
  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
  Arguments
  =========
  TYPE    (global input) CHARACTER
          TYPE indices the storage type of the input distributed
          matrix.
          = 'G':  sub( A ) is a full matrix,
          = 'L':  sub( A ) is a lower triangular matrix,
          = 'U':  sub( A ) is an upper triangular matrix,
          = 'H':  sub( A ) is an upper Hessenberg matrix.
  CFROM   (global input) DOUBLE PRECISION
  CTO     (global input) DOUBLE PRECISION
          The distributed matrix sub( A ) is multiplied by CTO/CFROM.
          A(I,J) is computed without over/underflow if the final
          result CTO * A(I,J) / CFROM can be represented without
          over/underflow.  CFROM must be nonzero.
  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) DOUBLE PRECISION pointer into the
          local memory to an array of dimension (LLD_A,LOCc(JA+N-1)).
          This array contains the local pieces of the distributed
          matrix sub( A ). On exit, this array contains the local
          pieces of the distributed matrix multiplied by CTO/CFROM.
  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.
  INFO    (local output) INTEGER
          = 0:  successful exit
          < 0:  If the i-th argument is an array and the j-entry had
                an illegal value, then INFO = -(i*100+j), if the i-th
                argument is a scalar and had an illegal value, then
                INFO = -i.
  =====================================================================
     .. Parameters ..

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

 
001        SUBROUTINE PDLASCL( TYPE , CFROM , CTO , M , N , A , IA , JA , DESCA ,
002       $INFO )
003  
004  *     -- ScaLAPACK auxiliary routine(version 1.7) --
005  *     University of Tennessee , Knoxville , Oak Ridge National Laboratory ,
006  *     and University of California , Berkeley.
007  *     May 1 , 1997
008  
009  *     .. Scalar Arguments ..
010        CHARACTER TYPE
011        INTEGER IA , INFO , JA , M , N
012        DOUBLE PRECISION CFROM , CTO
013        INTEGER BLOCK_CYCLIC_2D , CSRC_ , CTXT_ , DLEN_ , DTYPE_ ,
014       $LLD_ , MB_ , M_ , NB_ , N_ , RSRC_
015        PARAMETER( BLOCK_CYCLIC_2D = 1 , DLEN_ = 9 , DTYPE_ = 1 ,
016       $CTXT_ = 2 , M_ = 3 , N_ = 4 , MB_ = 5 , NB_ = 6 ,
017       $RSRC_ = 7 , CSRC_ = 8 , LLD_ = 9 )
018        DOUBLE PRECISION ONE , ZERO
019        PARAMETER( ZERO = 0.0D0 , ONE = 1.0D0 )
020  *     ..
021  *     .. Local Scalars ..
022        LOGICAL DONE
023        INTEGER IACOL , IAROW , ICOFFA , ICTXT , ICURCOL , ICURROW ,
024       $IIA , II , INXTROW , IOFFA , IROFFA , ITYPE , J , JB ,
025       $JJA , JJ , JN , KK , LDA , LL , MYCOL , MYROW , MP ,
026       $NPCOL , NPROW , NQ
027        DOUBLE PRECISION BIGNUM , CFROM1 , CFROMC , CTO1 , CTOC , MUL , SMLNUM
028  *     ..
029  *     .. External Subroutines ..
030        EXTERNAL BLACS_GRIDINFO , CHK1MAT , INFOG2L , PXERBLA
031  *     ..
032  *     .. External Functions ..
033        LOGICAL LSAME
034        INTEGER ICEIL , NUMROC
035        DOUBLE PRECISION PDLAMCH
036        EXTERNAL ICEIL , LSAME , NUMROC , PDLAMCH
037  *     ..
038  *     .. Intrinsic Functions ..
039        INTRINSIC ABS , MIN , MOD
040  *     ..
041  *     .. Executable Statements ..
042  
043  *     Get grid parameters
044  
045        ICTXT = DESCA( CTXT_ )
046        CALL BLACS_GRIDINFO( ICTXT , NPROW , NPCOL , MYROW , MYCOL )
047  
048  *     Test the input parameters
049  
050        IF( NPROW.EQ. - 1 ) THEN
051            INFO = - 907
052        ELSE
053            INFO = 0
054            CALL CHK1MAT( M , 4 , N , 6 , IA , JA , DESCA , 9 , INFO )
055            IF( INFO.EQ.0 ) THEN
056                IF( LSAME( TYPE , 'G' ) ) THEN
057                    ITYPE = 0
058                ELSE IF( LSAME( TYPE , 'L' ) ) THEN
059                    ITYPE = 1
060                ELSE IF( LSAME( TYPE , 'U' ) ) THEN
061                    ITYPE = 2
062                ELSE IF( LSAME( TYPE , 'H' ) ) THEN
063                    ITYPE = 3
064                ELSE
065                    ITYPE = - 1
066                END IF
067                IF( ITYPE.EQ. - 1 ) THEN
068                    INFO = - 1
069                ELSE IF( CFROM.EQ.ZERO ) THEN
070                    INFO = - 4
071                END IF
072            END IF
073        END IF
074  
075        IF( INFO.NE.0 ) THEN
076            CALL PXERBLA( ICTXT , 'PDLASCL' , - INFO )
077            RETURN
078        END IF
079  
080  *     Quick return if possible
081  
082        IF( N.EQ.0 .OR. M.EQ.0 )
083       $    RETURN
084  
085  *         Get machine parameters
086  
087            SMLNUM = PDLAMCH( ICTXT , 'S' )
088            BIGNUM = ONE / SMLNUM
089  
090            CFROMC = CFROM
091            CTOC = CTO
092  
093  *         Compute local indexes
094  
095            LDA = DESCA( LLD_ )
096            IROFFA = MOD( IA - 1 , DESCA( MB_ ) )
097            ICOFFA = MOD( JA - 1 , DESCA( NB_ ) )
098            JN = MIN( ICEIL( JA , DESCA( NB_ ) ) * DESCA( NB_ ) , JA + N - 1 )
099            CALL INFOG2L( IA , JA , DESCA , NPROW , NPCOL , MYROW , MYCOL , IIA , JJA ,
100       $    IAROW , IACOL )
101            MP = NUMROC( M + IROFFA , DESCA( MB_ ) , MYROW , IAROW , NPROW )
102            IF( MYROW.EQ.IAROW )
103       $        MP = MP - IROFFA
104                NQ = NUMROC( N + ICOFFA , DESCA( NB_ ) , MYCOL , IACOL , NPCOL )
105                IF( MYCOL.EQ.IACOL )
106       $            NQ = NQ - ICOFFA
107  
108     10 CONTINUE
109        CFROM1 = CFROMC*SMLNUM
110        CTO1 = CTOC / BIGNUM
111        IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN
112            MUL = SMLNUM
113            DONE = .FALSE.
114            CFROMC = CFROM1
115        ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN
116            MUL = BIGNUM
117            DONE = .FALSE.
118            CTOC = CTO1
119        ELSE
120            MUL = CTOC / CFROMC
121            DONE = .TRUE.
122        END IF
123  
124        IOFFA =( JJA - 1 ) * LDA
125        ICURROW = IAROW
126        ICURCOL = IACOL
127  
128        IF( ITYPE.EQ.0 ) THEN
129  
130  *         Full matrix
131  
132            DO 30 JJ = JJA , JJA + NQ - 1
133                DO 20 II = IIA , IIA + MP - 1
134                    A( IOFFA + II ) = A( IOFFA + II ) * MUL
135     20         CONTINUE
136                IOFFA = IOFFA + LDA
137     30     CONTINUE
138  
139        ELSE IF( ITYPE.EQ.1 ) THEN
140  
141  *         Lower triangular matrix
142  
143            II = IIA
144            JJ = JJA
145            JB = JN - JA + 1
146  
147            IF( MYCOL.EQ.ICURCOL ) THEN
148                IF( MYROW.EQ.ICURROW ) THEN
149                    DO 50 LL = JJ , JJ + JB - 1
150                        DO 40 KK = II + LL - JJ , IIA + MP - 1
151                            A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
152     40                 CONTINUE
153                        IOFFA = IOFFA + LDA
154     50             CONTINUE
155                ELSE
156                    DO 70 LL = JJ , JJ + JB - 1
157                        DO 60 KK = II , IIA + MP - 1
158                            A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
159     60                 CONTINUE
160                        IOFFA = IOFFA + LDA
161     70             CONTINUE
162                END IF
163                JJ = JJ + JB
164            END IF
165  
166            IF( MYROW.EQ.ICURROW )
167       $        II = II + JB
168                ICURROW = MOD( ICURROW + 1 , NPROW )
169                ICURCOL = MOD( ICURCOL + 1 , NPCOL )
170  
171  *             Loop over remaining block of columns
172  
173                DO 120 J = JN + 1 , JA + N - 1 , DESCA( NB_ )
174                    JB = MIN( JA + N - J , DESCA( NB_ ) )
175  
176                    IF( MYCOL.EQ.ICURCOL ) THEN
177                        IF( MYROW.EQ.ICURROW ) THEN
178                            DO 90 LL = JJ , JJ + JB - 1
179                                DO 80 KK = II + LL - JJ , IIA + MP - 1
180                                    A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
181     80                         CONTINUE
182                                IOFFA = IOFFA + LDA
183     90                     CONTINUE
184                        ELSE
185                            DO 110 LL = JJ , JJ + JB - 1
186                                DO 100 KK = II , IIA + MP - 1
187                                    A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
188    100                         CONTINUE
189                                IOFFA = IOFFA + LDA
190    110                     CONTINUE
191                        END IF
192                        JJ = JJ + JB
193                    END IF
194  
195                    IF( MYROW.EQ.ICURROW )
196       $                II = II + JB
197                        ICURROW = MOD( ICURROW + 1 , NPROW )
198                        ICURCOL = MOD( ICURCOL + 1 , NPCOL )
199  
200    120         CONTINUE
201  
202            ELSE IF( ITYPE.EQ.2 ) THEN
203  
204  *             Upper triangular matrix
205  
206                II = IIA
207                JJ = JJA
208                JB = JN - JA + 1
209  
210                IF( MYCOL.EQ.ICURCOL ) THEN
211                    IF( MYROW.EQ.ICURROW ) THEN
212                        DO 140 LL = JJ , JJ + JB - 1
213                            DO 130 KK = IIA , MIN(II + LL - JJ , IIA + MP - 1)
214                                A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
215    130                     CONTINUE
216                            IOFFA = IOFFA + LDA
217    140                 CONTINUE
218                    ELSE
219                        DO 160 LL = JJ , JJ + JB - 1
220                            DO 150 KK = IIA , MIN(II - 1 , IIA + MP - 1)
221                                A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
222    150                     CONTINUE
223                            IOFFA = IOFFA + LDA
224    160                 CONTINUE
225                    END IF
226                    JJ = JJ + JB
227                END IF
228  
229                IF( MYROW.EQ.ICURROW )
230       $            II = II + JB
231                    ICURROW = MOD( ICURROW + 1 , NPROW )
232                    ICURCOL = MOD( ICURCOL + 1 , NPCOL )
233  
234  *                 Loop over remaining block of columns
235  
236                    DO 210 J = JN + 1 , JA + N - 1 , DESCA( NB_ )
237                        JB = MIN( JA + N - J , DESCA( NB_ ) )
238  
239                        IF( MYCOL.EQ.ICURCOL ) THEN
240                            IF( MYROW.EQ.ICURROW ) THEN
241                                DO 180 LL = JJ , JJ + JB - 1
242                                    DO 170 KK = IIA , MIN(II + LL - JJ , IIA + MP - 1)
243                                        A( IOFFA + KK ) = A( IOFFA + KK )*MUL
244    170                             CONTINUE
245                                    IOFFA = IOFFA + LDA
246    180                         CONTINUE
247                            ELSE
248                                DO 200 LL = JJ , JJ + JB - 1
249                                    DO 190 KK = IIA , MIN(II - 1 , IIA + MP - 1)
250                                        A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
251    190                             CONTINUE
252                                    IOFFA = IOFFA + LDA
253    200                         CONTINUE
254                            END IF
255                            JJ = JJ + JB
256                        END IF
257  
258                        IF( MYROW.EQ.ICURROW )
259       $                    II = II + JB
260                            ICURROW = MOD( ICURROW + 1 , NPROW )
261                            ICURCOL = MOD( ICURCOL + 1 , NPCOL )
262  
263    210             CONTINUE
264  
265                ELSE IF( ITYPE.EQ.3 ) THEN
266  
267  *                 Upper Hessenberg matrix
268  
269                    II = IIA
270                    JJ = JJA
271                    JB = JN - JA + 1
272  
273  *                 Only one process row
274  
275                    IF( NPROW.EQ.1 ) THEN
276  
277  *                     Handle first block of columns separately
278  
279                        IF( MYCOL.EQ.ICURCOL ) THEN
280                            DO 230 LL = JJ , JJ + JB - 1
281                                DO 220 KK = IIA , MIN( II + LL - JJ + 1 , IIA + MP - 1 )
282                                    A( IOFFA + KK ) = A( IOFFA + KK )*MUL
283    220                         CONTINUE
284                                IOFFA = IOFFA + LDA
285    230                     CONTINUE
286                            JJ = JJ + JB
287                        END IF
288  
289                        ICURCOL = MOD( ICURCOL + 1 , NPCOL )
290  
291  *                     Loop over remaining block of columns
292  
293                        DO 260 J = JN + 1 , JA + N - 1 , DESCA( NB_ )
294                            JB = MIN( JA + N - J , DESCA( NB_ ) )
295  
296                            IF( MYCOL.EQ.ICURCOL ) THEN
297                                DO 250 LL = JJ , JJ + JB - 1
298                                    DO 240 KK = IIA , MIN( II + LL - JJ + 1 , IIA + MP - 1 )
299                                        A( IOFFA + KK ) = A( IOFFA + KK )*MUL
300    240                             CONTINUE
301                                    IOFFA = IOFFA + LDA
302    250                         CONTINUE
303                                JJ = JJ + JB
304                            END IF
305  
306                            II = II + JB
307                            ICURCOL = MOD( ICURCOL + 1 , NPCOL )
308  
309    260                 CONTINUE
310  
311                    ELSE
312  
313  *                     Handle first block of columns separately
314  
315                        INXTROW = MOD( ICURROW + 1 , NPROW )
316                        IF( MYCOL.EQ.ICURCOL ) THEN
317                            IF( MYROW.EQ.ICURROW ) THEN
318                                DO 280 LL = JJ , JJ + JB - 1
319                                    DO 270 KK = IIA , MIN(II + LL - JJ + 1 , IIA + MP - 1)
320                                        A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
321    270                             CONTINUE
322                                    IOFFA = IOFFA + LDA
323    280                         CONTINUE
324                            ELSE
325                                DO 300 LL = JJ , JJ + JB - 1
326                                    DO 290 KK = IIA , MIN(II - 1 , IIA + MP - 1)
327                                        A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
328    290                             CONTINUE
329                                    IOFFA = IOFFA + LDA
330    300                         CONTINUE
331                                IF( MYROW.EQ.INXTROW .AND. II.LE.IIA + MP - 1 )
332       $                            A( II + (JJ + JB - 2)*LDA ) = A( II + (JJ + JB - 2)*LDA ) * MUL
333                                END IF
334                                JJ = JJ + JB
335                            END IF
336  
337                            IF( MYROW.EQ.ICURROW )
338       $                        II = II + JB
339                                ICURROW = INXTROW
340                                ICURROW = MOD( ICURROW + 1 , NPROW )
341                                ICURCOL = MOD( ICURCOL + 1 , NPCOL )
342  
343  *                             Loop over remaining block of columns
344  
345                                DO 350 J = JN + 1 , JA + N - 1 , DESCA( NB_ )
346                                    JB = MIN( JA + N - J , DESCA( NB_ ) )
347  
348                                    IF( MYCOL.EQ.ICURCOL ) THEN
349                                        IF( MYROW.EQ.ICURROW ) THEN
350                                            DO 320 LL = JJ , JJ + JB - 1
351                                                DO 310 KK = IIA , MIN( II + LL - JJ + 1 , IIA + MP - 1 )
352                                                    A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
353    310                                         CONTINUE
354                                                IOFFA = IOFFA + LDA
355    320                                     CONTINUE
356                                        ELSE
357                                            DO 340 LL = JJ , JJ + JB - 1
358                                                DO 330 KK = IIA , MIN( II - 1 , IIA + MP - 1 )
359                                                    A( IOFFA + KK ) = A( IOFFA + KK ) * MUL
360    330                                         CONTINUE
361                                                IOFFA = IOFFA + LDA
362    340                                     CONTINUE
363                                            IF( MYROW.EQ.INXTROW .AND. II.LE.IIA + MP - 1 )
364       $                                        A( II + (JJ + JB - 2)*LDA ) = A( II + (JJ + JB - 2)*LDA ) *
365       $                                        MUL
366                                            END IF
367                                            JJ = JJ + JB
368                                        END IF
369  
370                                        IF( MYROW.EQ.ICURROW )
371       $                                    II = II + JB
372                                            ICURROW = INXTROW
373                                            ICURROW = MOD( ICURROW + 1 , NPROW )
374                                            ICURCOL = MOD( ICURCOL + 1 , NPCOL )
375  
376    350                         CONTINUE
377  
378                            END IF
379  
380                        END IF
381  
382                        IF( .NOT.DONE )
383       $                    GO TO 10
384  
385                            RETURN
386  
387  *                         End of PDLASCL
388  
389                        END