3 * Example
Program solving Ax
=b via ScaLAPACK routine PDGESV
6 INTEGER DLEN_
, IA
, JA
, IB
, JB
, M
, N
, MB
, NB
, RSRC
,
7 $ CSRC
, MXLLDA
, MXLLDB
, NRHS
, NBRHS
, NOUT
,
8 $ MXLOCR
, MXLOCC
, MXRHSC
9 PARAMETER ( DLEN_
= 9, IA
= 1, JA
= 1, IB
= 1, JB
= 1,
10 $ M
= 9, N
= 9, MB
= 2, NB
= 2, RSRC
= 0,
11 $ CSRC
= 0, MXLLDA
= 5, MXLLDB
= 5, NRHS
= 1,
12 $ NBRHS
= 1, NOUT
= 6, MXLOCR
= 5, MXLOCC
= 4,
15 PARAMETER ( ONE
= 1.0D
+0 )
18 INTEGER ICTXT
, INFO
, MYCOL
, MYROW
, NPCOL
, NPROW
19 DOUBLE PRECISION ANORM
, BNORM
, EPS
, RESID
, XNORM
22 INTEGER DESCA
( DLEN_
), DESCB
( DLEN_
),
24 DOUBLE PRECISION A
( MXLLDA
, MXLOCC
), A0
( MXLLDA
, MXLOCC
),
25 $ B
( MXLLDB
, MXRHSC
), B0
( MXLLDB
, MXRHSC
),
28 * .. External Functions
..
29 DOUBLE PRECISION PDLAMCH
, PDLANGE
30 EXTERNAL PDLAMCH
, PDLANGE
32 * .. External Subroutines
..
33 EXTERNAL BLACS_EXIT
, BLACS_GRIDEXIT
, BLACS_GRIDINFO
,
34 $ DESCINIT
, MATINIT
, PDGEMM
, PDGESV
, PDLACPY
,
37 * .. Intrinsic Functions
..
40 * .. Data statements
..
41 DATA NPROW
/ 2 / , NPCOL
/ 3 /
43 * .. Executable Statements
..
45 * INITIALIZE THE PROCESS GRID
47 CALL SL_INIT
( ICTXT
, NPROW
, NPCOL
)
48 CALL BLACS_GRIDINFO
( ICTXT
, NPROW
, NPCOL
, MYROW
, MYCOL
)
50 * If I
'm not in the process grid, go to the end of the program
55 * DISTRIBUTE THE MATRIX ON THE PROCESS GRID
56 * Initialize the array descriptors for the matrices A and B
58 CALL DESCINIT( DESCA, M, N, MB, NB, RSRC, CSRC, ICTXT, MXLLDA,
60 CALL DESCINIT( DESCB, N, NRHS, NB, NBRHS, RSRC, CSRC, ICTXT,
63 * Generate matrices A and B and distribute to the process grid
65 CALL MATINIT( A, DESCA, B, DESCB )
67 * Make a copy of A and B for checking purposes
69 CALL PDLACPY( 'All
', N, N, A, 1, 1, DESCA, A0, 1, 1, DESCA )
70 CALL PDLACPY( 'All
', N, NRHS, B, 1, 1, DESCB, B0, 1, 1, DESCB )
72 * CALL THE SCALAPACK ROUTINE
73 * Solve the linear system A * X = B
75 CALL PDGESV( N, NRHS, A, IA, JA, DESCA, IPIV, B, IB, JB, DESCB,
78 IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 ) THEN
79 WRITE( NOUT, FMT = 9999 )
80 WRITE( NOUT, FMT = 9998 )M, N, NB
81 WRITE( NOUT, FMT = 9997 )NPROW*NPCOL, NPROW, NPCOL
82 WRITE( NOUT, FMT = 9996 )INFO
85 * Compute residual ||A * X - B|| / ( ||X|| * ||A|| * eps * N )
87 EPS = PDLAMCH( ICTXT, 'Epsilon
' )
88 ANORM = PDLANGE( 'I
', N, N, A, 1, 1, DESCA, WORK )
89 BNORM = PDLANGE( 'I
', N, NRHS, B, 1, 1, DESCB, WORK )
90 CALL PDGEMM( 'N
', 'N
', N, NRHS, N, ONE, A0, 1, 1, DESCA, B, 1, 1,
91 $ DESCB, -ONE, B0, 1, 1, DESCB )
92 XNORM = PDLANGE( 'I
', N, NRHS, B0, 1, 1, DESCB, WORK )
93 RESID = XNORM / ( ANORM*BNORM*EPS*DBLE( N ) )
95 IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 ) THEN
96 IF( RESID.LT.10.0D+0 ) THEN
97 WRITE( NOUT, FMT = 9995 )
98 WRITE( NOUT, FMT = 9993 )RESID
100 WRITE( NOUT, FMT = 9994 )
101 WRITE( NOUT, FMT = 9993 )RESID
105 * RELEASE THE PROCESS GRID
106 * Free the BLACS context
108 CALL BLACS_GRIDEXIT( ICTXT )
115 9999 FORMAT( / 'ScaLAPACK Example
Program #
1 -- May
1, 1997' )
116 9998 FORMAT( / 'Solving Ax
=b where A is a
', I3, ' by
', I3,
117 $ ' matrix with a block size of
', I3 )
118 9997 FORMAT( 'Running on
', I3, ' processes
, where the process grid
',
119 $ ' is
', I3, ' by
', I3 )
120 9996 FORMAT( / 'INFO code returned by PDGESV
= ', I3 )
122 $ 'According
to the normalized residual the solution is correct
.'
125 $ 'According
to the normalized residual the solution is incorrect
.'
127 9993 FORMAT( / '||A*x
- b||
/ ( ||x||
*||A||
*eps*N
) = ', 1P, E16.8 )
130 SUBROUTINE MATINIT( AA, DESCA, B, DESCB )
132 * MATINIT generates and distributes matrices A and B (depicted in
133 * Figures 2.5 and 2.6) to a 2 x 3 process grid
135 * .. Array Arguments ..
136 INTEGER DESCA( * ), DESCB( * )
137 DOUBLE PRECISION AA( * ), B( * )
141 PARAMETER ( CTXT_ = 2, LLD_ = 9 )
143 * .. Local Scalars ..
144 INTEGER ICTXT, MXLLDA, MYCOL, MYROW, NPCOL, NPROW
145 DOUBLE PRECISION A, C, K, L, P, S
147 * .. External Subroutines ..
148 EXTERNAL BLACS_GRIDINFO
150 * .. Executable Statements ..
152 ICTXT = DESCA( CTXT_ )
153 CALL BLACS_GRIDINFO( ICTXT, NPROW, NPCOL, MYROW, MYCOL )
162 MXLLDA = DESCA( LLD_ )
164 IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 ) THEN
179 AA( 5+2*MXLLDA ) = -A
184 AA( 5+3*MXLLDA ) = -C
190 ELSE IF( MYROW.EQ.0 .AND. MYCOL.EQ.1 ) THEN
206 ELSE IF( MYROW.EQ.0 .AND. MYCOL.EQ.2 ) THEN
217 ELSE IF( MYROW.EQ.1 .AND. MYCOL.EQ.0 ) THEN
229 AA( 4+2*MXLLDA ) = -A
238 ELSE IF( MYROW.EQ.1 .AND. MYCOL.EQ.1 ) THEN
251 ELSE IF( MYROW.EQ.1 .AND. MYCOL.EQ.2 ) THEN
263 SUBROUTINE SL_INIT( ICTXT, NPROW, NPCOL )
265 * .. Scalar Arguments ..
266 INTEGER ICTXT, NPCOL, NPROW
272 * SL_INIT initializes an NPROW x NPCOL process grid using a row-major
273 * ordering of the processes. This routine retrieves a default system
274 * context which will include all available processes. In addition it
275 * spawns the processes if needed.
280 * ICTXT (global output) INTEGER
281 * ICTXT specifies the BLACS context handle identifying the
282 * created process grid. The context itself is global.
284 * NPROW (global input) INTEGER
285 * NPROW specifies the number of process rows in the grid
288 * NPCOL (global input) INTEGER
289 * NPCOL specifies the number of process columns in the grid
292 * =====================================================================
294 * .. Local Scalars ..
297 * .. External Subroutines ..
298 EXTERNAL BLACS_GET, BLACS_GRIDINIT, BLACS_PINFO,
301 * .. Executable Statements ..
303 * Get starting information
305 CALL BLACS_PINFO( IAM, NPROCS )
307 * If machine needs additional set up, do it now
309 IF( NPROCS.LT.1 ) THEN
311 $ NPROCS = NPROW*NPCOL
312 CALL BLACS_SETUP( IAM, NPROCS )
315 * Define process grid
317 CALL BLACS_GET( -1, 0, ICTXT )
318 CALL BLACS_GRIDINIT( ICTXT, 'Row
-major
', NPROW, NPCOL )