OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
pssdpsubtst.f
Go to the documentation of this file.
1 SUBROUTINE pssdpsubtst( WKNOWN, UPLO, N, THRESH, ABSTOL, A,
2 $ COPYA, Z, IA, JA, DESCA, WIN, WNEW,
3 $ IPREPAD, IPOSTPAD, WORK, LWORK, LWORK1,
4 $ IWORK, LIWORK,
5 $ RESULT, TSTNRM, QTQNRM, NOUT )
6*
7* -- ScaLAPACK testing routine (version 1.7) --
8* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
9* and University of California, Berkeley.
10* March 16, 2000
11*
12* .. Scalar Arguments ..
13 LOGICAL WKNOWN
14 CHARACTER UPLO
15 INTEGER IA, IPOSTPAD, IPREPAD, JA, LWORK, LWORK1, N,
16 $ NOUT, RESULT, LIWORK
17 REAL ABSTOL, QTQNRM, THRESH, TSTNRM
18* ..
19* .. Array Arguments ..
20 INTEGER DESCA( * ), IWORK( * )
21 REAL A( * ), COPYA( * ), WIN( * ), WNEW( * ),
22 $ WORK( * ), Z( * )
23* ..
24*
25* Purpose
26* =======
27*
28* PSSDPSUBTST calls PSSYEVD and then tests the output of
29* PSSYEVD
30* The following two tests are performed:
31* |AQ -QL| / (abstol + eps * norm(A) ) < N*THRESH
32* |QT * Q - I| / eps * norm(A) < N*THRESH
33* If WKNOWN then
34* we check to make sure that the eigenvalues match expectations
35* i.e. |WIN - WNEW(1+IPREPAD)| / (eps * |WIN|) < THRESH
36* where WIN is the array of eigenvalues as computed by
37* PSSYEVD when eigenvectors are requested
38*
39* Arguments
40* =========
41*
42* NP = the number of rows local to a given process.
43* NQ = the number of columns local to a given process.
44*
45* WKNOWN (global input) INTEGER
46* .FALSE.: WIN does not contain the eigenvalues
47* .TRUE.: WIN does contain the eigenvalues
48*
49* UPLO (global input) CHARACTER*1
50* Specifies whether the upper or lower triangular part of the
51* symmetric matrix A is stored:
52* = 'U': Upper triangular
53* = 'L': Lower triangular
54*
55* N (global input) INTEGER
56* Size of the matrix to be tested. (global size)
57*
58* THRESH (global input) REAL
59* A test will count as "failed" if the "error", computed as
60* described below, exceeds THRESH. Note that the error
61* is scaled to be O(1), so THRESH should be a reasonably
62* small multiple of 1, e.g., 10 or 100. In particular,
63* it should not depend on the precision (single vs. double)
64* or the size of the matrix. It must be at least zero.
65*
66* ABSTOL (global input) REAL
67* The absolute tolerance for the eigenvalues. An
68* eigenvalue is considered to be located if it has
69* been determined to lie in an interval whose width
70* is "abstol" or less. If "abstol" is less than or equal
71* to zero, then ulp*|T| will be used, where |T| is
72* the 1-norm of the matrix.
73*
74* A (local workspace) REAL array
75* global dimension (N, N), local dimension (DESCA(DLEN_), NQ)
76* A is distributed in a block cyclic manner over both rows
77* and columns.
78* See PSSYEVD for a description of block cyclic layout.
79* The test matrix, which is then modified by PSSYEVD
80* A has already been padded front and back, use A(1+IPREPAD)
81*
82* COPYA (local input) REAL array, dimension(N*N)
83* COPYA holds a copy of the original matrix A
84* identical in both form and content to A
85*
86* Z (local workspace) REAL array, dim (N*N)
87* Z is distributed in the same manner as A
88* Z contains the eigenvector matrix
89* Z is used as workspace by the test routines
90* PSSEPCHK and PSSEPQTQ.
91* Z has already been padded front and back, use Z(1+IPREPAD)
92*
93* IA (global input) INTEGER
94* On entry, IA specifies the global row index of the submatrix
95* of the global matrix A, COPYA and Z to operate on.
96*
97* JA (global input) INTEGER
98* On entry, IA specifies the global column index of the submat
99* of the global matrix A, COPYA and Z to operate on.
100*
101* DESCA (global/local input) INTEGER array of dimension 8
102* The array descriptor for the matrix A, COPYA and Z.
103*
104* WIN (global input) REAL array, dimension (N)
105* If .not. WKNOWN, WIN is ignored on input
106* Otherwise, WIN() is taken as the standard by which the
107* eigenvalues are to be compared against.
108*
109* WNEW (global workspace) REAL array, dimension (N)
110* The eigenvalues as computed by this call to PSSYEVD.
111* WNEW has already been padded front and back,
112* use WNEW(1+IPREPAD)
113*
114* WORK (local workspace) REAL array, dimension (LWORK)
115* WORK has already been padded front and back,
116* use WORK(1+IPREPAD)
117*
118* LWORK (local input) INTEGER
119* The actual length of the array WORK after padding.
120*
121*
122* LWORK1 (local input) INTEGER
123* The amount of real workspace to pass to PSSYEVD
124*
125* IWORK (local workspace) INTEGER array, dimension (LIWORK)
126* IWORK has already been padded front and back,
127* use IWORK(1+IPREPAD)
128*
129* LIWORK (local input) INTEGER
130* The length of the array IWORK after padding.
131*
132* RESULT (global output) INTEGER
133* The result of this call to PSSYEVD
134* RESULT = -3 => This process did not participate
135* RESULT = 0 => All tests passed
136* RESULT = 1 => ONe or more tests failed
137*
138* TSTNRM (global output) REAL
139* |AQ- QL| / (ABSTOL+EPS*|A|)*N
140*
141* QTQNRM (global output) REAL
142* |QTQ -I| / N*EPS
143*
144* .. Parameters ..
145*
146 INTEGER BLOCK_CYCLIC_2D, DLEN_, DT_, CTXT_, M_, N_,
147 $ MB_, NB_, RSRC_, CSRC_, LLD_
148 PARAMETER ( BLOCK_CYCLIC_2D = 1, dlen_ = 9, dt_ = 1,
149 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
150 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
151 REAL FIVE, NEGONE, PADVAL, ZERO
152 parameter( padval = 13.5285e+0, five = 5.0e+0,
153 $ negone = -1.0e+0, zero = 0.0e+0 )
154* ..
155* .. Local Scalars ..
156 INTEGER I, IAM, INFO, ISIZESUBTST, ISIZESYEVX,
157 $ ISIZETST, J, MINSIZE, MQ, MYCOL, MYROW,
158 $ NP, NPCOL, NPROW, NQ, RESAQ, RESQTQ,
159 $ SIZECHK, SIZEMQRLEFT, SIZEMQRRIGHT, SIZEQRF,
160 $ sizeqtq, sizesubtst, sizesyev, sizesyevx,
161 $ sizetms, sizetst, sizesyevd, isizesyevd,
162 $ trilwmin
163 REAL EPS, EPSNORMA, ERROR, MAXERROR, MINERROR,
164 $ NORMWIN, SAFMIN
165* ..
166* .. Local Arrays ..
167 INTEGER DESCZ( DLEN_ ), ITMP( 2 )
168* ..
169* .. External Functions ..
170*
171 LOGICAL LSAME
172 INTEGER NUMROC
173 REAL PSLAMCH, PSLANSY
174 EXTERNAL LSAME, NUMROC, PSLAMCH, PSLANSY
175* ..
176* .. External Subroutines ..
177 EXTERNAL blacs_gridinfo, descinit, igamn2d, igamx2d,
179 $ pssepchk, pssepqtq, pssyevd, sgamn2d, sgamx2d,
181* ..
182* .. Intrinsic Functions ..
183 INTRINSIC abs, max, min, mod
184* ..
185* .. Executable Statements ..
186* This is just to keep ftnchek happy
187 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dt_*lld_*mb_*m_*nb_*n_*
188 $ rsrc_.LT.0 )RETURN
189 CALL pslasizesqp( desca, iprepad, ipostpad, sizemqrleft,
190 $ sizemqrright, sizeqrf, sizetms, sizeqtq,
191 $ sizechk, sizesyevx, isizesyevx, sizesyev,
192 $ sizesyevd, isizesyevd, sizesubtst,
193 $ isizesubtst, sizetst, isizetst )
194*
195 tstnrm = negone
196 qtqnrm = negone
197 eps = pslamch( desca( ctxt_ ), 'eps' )
198 SAFMIN = PSLAMCH( DESCA( CTXT_ ), 'safe min' )
199*
200 NORMWIN = SAFMIN / EPS
201.GE. IF( N1 )
202 $ NORMWIN = MAX( ABS( WIN( 1+IPREPAD ) ),
203 $ ABS( WIN( N+IPREPAD ) ), NORMWIN )
204*
205* Make sure that we aren't using information from previous calls
206*
207 DO 10 I = 1, LWORK1, 1
208 WORK( I+IPREPAD ) = 14.3E+0
209 10 CONTINUE
210*
211 DO 30 I = 1, N
212 WNEW( I+IPREPAD ) = 3.14159E+0
213 30 CONTINUE
214*
215 CALL DESCINIT( DESCZ, DESCA( M_ ), DESCA( N_ ), DESCA( MB_ ),
216 $ DESCA( NB_ ), DESCA( RSRC_ ), DESCA( CSRC_ ),
217 $ DESCA( CTXT_ ), DESCA( LLD_ ), INFO )
218*
219 CALL BLACS_GRIDINFO( DESCA( CTXT_ ), NPROW, NPCOL, MYROW, MYCOL )
220*
221 IAM = 1
222.EQ..AND..EQ. IF( MYROW0 MYCOL0 )
223 $ IAM = 0
224*
225* If this process is not involved in this test, bail out now
226*
227.GE..OR..LT. IF( MYROWNPROW MYROW0 )
228 $ GO TO 150
229 RESULT = 0
230*
231 NP = NUMROC( N, DESCA( MB_ ), MYROW, 0, NPROW )
232 NQ = NUMROC( N, DESCA( NB_ ), MYCOL, 0, NPCOL )
233 MQ = NUMROC( N, DESCA( NB_ ), MYCOL, 0, NPCOL )
234*
235* Find the amount of workspace needed with or without eigenvectors.
236*
237 TRILWMIN = 3*N + MAX( DESCA( NB_ )*( NP+1 ), 3*DESCA( NB_ ) )
238 MINSIZE = MAX( 1 + 6*N + 2*NP*NQ, TRILWMIN ) + 2*N
239*
240 CALL SLACPY( 'a', NP, NQ, COPYA, DESCA( LLD_ ), A( 1+IPREPAD ),
241 $ DESCA( LLD_ ) )
242*
243 CALL PSFILLPAD( DESCA( CTXT_ ), NP, NQ, A, DESCA( LLD_ ), IPREPAD,
244 $ IPOSTPAD, PADVAL )
245*
246 CALL PSFILLPAD( DESCZ( CTXT_ ), NP, MQ, Z, DESCZ( LLD_ ), IPREPAD,
247 $ IPOSTPAD, PADVAL+1.0E+0 )
248*
249 CALL PSFILLPAD( DESCA( CTXT_ ), N, 1, WNEW, N, IPREPAD, IPOSTPAD,
250 $ PADVAL+2.0E+0 )
251*
252 CALL PSFILLPAD( DESCA( CTXT_ ), LWORK1, 1, WORK, LWORK1, IPREPAD,
253 $ IPOSTPAD, PADVAL+4.0E+0 )
254*
255* Make sure that PSSYEVD does not cheat (i.e. use answers
256* already computed.)
257*
258 DO 60 I = 1, N, 1
259 DO 50 J = 1, N, 1
260 CALL PSELSET( Z( 1+IPREPAD ), I, J, DESCA, 13.0E+0 )
261 50 CONTINUE
262 60 CONTINUE
263*
264 CALL SLBOOT
265 CALL SLTIMER( 1 )
266 CALL SLTIMER( 6 )
267 CALL PSSYEVD( 'v', UPLO, N, A( 1+IPREPAD ), IA, JA, DESCA,
268 $ WNEW( 1+IPREPAD ), Z( 1+IPREPAD ), IA, JA, DESCA,
269 $ WORK( 1+IPREPAD ), LWORK1, IWORK( 1+IPREPAD ),
270 $ LIWORK, INFO )
271 CALL SLTIMER( 6 )
272 CALL SLTIMER( 1 )
273*
274.LE. IF( THRESH0 ) THEN
275 RESULT = 0
276 ELSE
277 CALL PSCHEKPAD( DESCA( CTXT_ ), 'pssyevd-a', NP, NQ, A,
278 $ DESCA( LLD_ ), IPREPAD, IPOSTPAD, PADVAL )
279*
280 CALL PSCHEKPAD( DESCZ( CTXT_ ), 'pssyevd-z', NP, MQ, Z,
281 $ DESCZ( LLD_ ), IPREPAD, IPOSTPAD,
282 $ PADVAL+1.0E+0 )
283*
284 CALL PSCHEKPAD( DESCA( CTXT_ ), 'pssyevd-wnew', N, 1, WNEW, N,
285 $ IPREPAD, IPOSTPAD, PADVAL+2.0E+0 )
286*
287 CALL PSCHEKPAD( DESCA( CTXT_ ), 'pssyevd-work', LWORK1, 1,
288 $ WORK, LWORK1, IPREPAD, IPOSTPAD,
289 $ PADVAL+4.0E+0 )
290*
291* Check INFO
292*
293*
294* Make sure that all processes return the same value of INFO
295*
296 ITMP( 1 ) = INFO
297 ITMP( 2 ) = INFO
298*
299 CALL IGAMN2D( DESCA( CTXT_ ), 'a', ' ', 1, 1, ITMP, 1, 1, 1,
300 $ -1, -1, 0 )
301 CALL IGAMX2D( DESCA( CTXT_ ), 'a', ' ', 1, 1, ITMP( 2 ), 1, 1,
302 $ 1, -1, -1, 0 )
303*
304*
305.NE. IF( ITMP( 1 )ITMP( 2 ) ) THEN
306.EQ. IF( IAM0 )
307 $ WRITE( NOUT, FMT = * )
308 $ 'different processes return different info'
309 RESULT = 1
310.NE. ELSE IF( INFO0 ) THEN
311.EQ. IF( IAM0 ) THEN
312 WRITE( NOUT, FMT = 9999 )INFO
313.EQ. IF( INFO(N+1) )
314 $ WRITE( NOUT, FMT = 9994 )
315 RESULT = 1
316 END IF
317.EQ..AND..GE. ELSE IF( INFO14 LWORK1MINSIZE ) THEN
318.EQ. IF( IAM0 )
319 $ WRITE( NOUT, FMT = 9996 )INFO
320 RESULT = 1
321 END IF
322*
323.EQ..OR..GT. IF( RESULT0 INFON ) THEN
324*
325* Make sure that different processes return the same eigenvalues.
326* This is a more exhaustive check that provided by PSSYEVD.
327*
328 DO 70 I = 1, N
329 WORK( I ) = WNEW( I+IPREPAD )
330 WORK( I+N ) = WNEW( I+IPREPAD )
331 70 CONTINUE
332*
333 CALL SGAMN2D( DESCA( CTXT_ ), 'a', ' ', N, 1, WORK, N, 1,
334 $ 1, -1, -1, 0 )
335 CALL SGAMX2D( DESCA( CTXT_ ), 'a', ' ', N, 1,
336 $ WORK( 1+N ), N, 1, 1, -1, -1, 0 )
337*
338 DO 80 I = 1, N
339*
340.GT. IF( ABS( WORK( I )-WORK( N+I ) )ZERO ) THEN
341.EQ. IF( IAM0 )
342 $ WRITE( NOUT, FMT = 9995 )
343 RESULT = 1
344 GO TO 90
345 END IF
346 80 CONTINUE
347 90 CONTINUE
348 END IF
349*
350 CALL IGAMX2D( DESCA( CTXT_ ), 'a', ' ', 1, 1, RESULT, 1, 1, 1,
351 $ -1, -1, 0 )
352*
353* Compute eps * norm(A)
354*
355.EQ. IF( N0 ) THEN
356 EPSNORMA = EPS
357 ELSE
358 EPSNORMA = PSLANSY( 'i', UPLO, N, COPYA, IA, JA, DESCA,
359 $ WORK )*EPS
360 END IF
361*
362* Note that a couple key variables get redefined in PSSEPCHK
363* as described by this table:
364*
365* PSSEPTST name PSSEPCHK name
366* ------------- -------------
367* COPYA A
368* Z Q
369* A C
370*
371*
372*
373* Perform the |AQ - QE| test
374*
375 CALL PSFILLPAD( DESCA( CTXT_ ), SIZECHK, 1, WORK, SIZECHK,
376 $ IPREPAD, IPOSTPAD, 4.3E+0 )
377*
378 RESAQ = 0
379*
380 CALL PSSEPCHK( N, N, COPYA, IA, JA, DESCA,
381 $ MAX( ABSTOL+EPSNORMA, SAFMIN ), THRESH,
382 $ Z( 1+IPREPAD ), IA, JA, DESCZ,
383 $ A( 1+IPREPAD ), IA, JA, DESCA,
384 $ WNEW( 1+IPREPAD ), WORK( 1+IPREPAD ),
385 $ SIZECHK, TSTNRM, RESAQ )
386*
387 CALL PSCHEKPAD( DESCA( CTXT_ ), 'pssepchk-work', SIZECHK, 1,
388 $ WORK, SIZECHK, IPREPAD, IPOSTPAD, 4.3E+0 )
389*
390.NE. IF( RESAQ0 ) THEN
391 RESULT = 1
392 WRITE( NOUT, FMT = 9993 )
393 END IF
394*
395* Perform the |QTQ - I| test
396*
397 CALL PSFILLPAD( DESCA( CTXT_ ), SIZEQTQ, 1, WORK, SIZEQTQ,
398 $ IPREPAD, IPOSTPAD, 4.3E+0 )
399*
400 RESQTQ = 0
401*
402*
403 DO 40 I = 1, 2
404 IWORK( IPREPAD + I ) = 0
405 40 CONTINUE
406 CALL PSSEPQTQ( N, N, THRESH, Z( 1+IPREPAD ), IA, JA, DESCZ,
407 $ A( 1+IPREPAD ), IA, JA, DESCA,
408 $ IWORK( 1 ), IWORK( 1 ), WORK( 1 ),
409 $ WORK( IPREPAD+1 ), SIZEQTQ, QTQNRM, INFO,
410 $ RESQTQ )
411*
412 CALL PSCHEKPAD( DESCA( CTXT_ ), 'pssepqtq-work', SIZEQTQ, 1,
413 $ WORK, SIZEQTQ, IPREPAD, IPOSTPAD, 4.3E+0 )
414*
415.NE. IF( RESQTQ0 ) THEN
416 RESULT = 1
417 WRITE( NOUT, FMT = 9992 )
418 END IF
419*
420.NE. IF( INFO0 ) THEN
421.EQ. IF( IAM0 )
422 $ WRITE( NOUT, FMT = 9998 )INFO
423 RESULT = 1
424 END IF
425 ENDIF
426*
427* Check to make sure that we have the right eigenvalues
428*
429.AND..GT. IF( WKNOWN N0 ) THEN
430*
431* Find the largest difference between the computed
432* and expected eigenvalues
433*
434 MINERROR = NORMWIN
435 MAXERROR = 0
436*
437cc CALL SLASRT( 'I', N,WNEW( IPREPAD +1 ), INFO )
438c
439 DO 140 I = 1, N
440 ERROR = ABS( WIN( I+IPREPAD )-WNEW( I+IPREPAD ) )
441 MAXERROR = MAX( MAXERROR, ERROR )
442 140 CONTINUE
443 MINERROR = MIN( MAXERROR, MINERROR )
444*
445.GT. IF( MINERRORNORMWIN*FIVE*THRESH*EPS ) THEN
446.EQ. IF( IAM0 )
447 $ WRITE( NOUT, FMT = 9997 )MINERROR, NORMWIN
448 RESULT = 1
449 END IF
450 END IF
451*
452* All processes should report the same result
453*
454 CALL IGAMX2D( DESCA( CTXT_ ), 'a', ' ', 1, 1, RESULT, 1, 1, 1, -1,
455 $ -1, 0 )
456*
457 150 CONTINUE
458*
459*
460 RETURN
461*
462 9999 FORMAT( 'pssyevd returned info=', I7 )
463 9998 FORMAT( 'pssepqtq in pssdpsubtst returned info=', I7 )
464 9997 FORMAT( 'pssdpsubtst minerror =', D11.2, ' normwin=', D11.2 )
465 9996 FORMAT( 'pssyevd returned info=', I7,
466 $ ' despite adequate workspace' )
467 9995 FORMAT( 'different processes return different eigenvalues' )
468 9994 FORMAT( 'heterogeneity detected by pssyevd' )
469 9993 FORMAT( 'pssyevd failed the |aq -qe| test' )
470 9992 FORMAT( 'pssyevd failed the |qtq -i| test' )
471*
472* End of PSSDPSUBTST
473*
474 END
end diagonal values have been computed in the(sparse) matrix id.SOL
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
Definition slacpy.f:103
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21
subroutine descinit(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld, info)
Definition mpi.f:777
subroutine blacs_gridinfo(cntxt, nprow, npcol, myrow, mycol)
Definition mpi.f:754
subroutine pschekpad(ictxt, mess, m, n, a, lda, ipre, ipost, chkval)
Definition pschekpad.f:3
subroutine pselset(a, ia, ja, desca, alpha)
Definition pselset.f:2
subroutine psfillpad(ictxt, m, n, a, lda, ipre, ipost, chkval)
Definition psfillpad.f:2
subroutine pslasizesqp(desca, iprepad, ipostpad, sizemqrleft, sizemqrright, sizeqrf, sizetms, sizeqtq, sizechk, sizesyevx, isizesyevx, sizesyev, sizesyevd, isizesyevd, sizesubtst, isizesubtst, sizetst, isizetst)
Definition pslasizesqp.f:7
subroutine pssdpsubtst(wknown, uplo, n, thresh, abstol, a, copya, z, ia, ja, desca, win, wnew, iprepad, ipostpad, work, lwork, lwork1, iwork, liwork, result, tstnrm, qtqnrm, nout)
Definition pssdpsubtst.f:6
subroutine pssepchk(ms, nv, a, ia, ja, desca, epsnorma, thresh, q, iq, jq, descq, c, ic, jc, descc, w, work, lwork, tstnrm, result)
Definition pssepchk.f:6
subroutine pssepqtq(ms, nv, thresh, q, iq, jq, descq, c, ic, jc, descc, procdist, iclustr, gap, work, lwork, qtqnrm, info, res)
Definition pssepqtq.f:6
subroutine pssyevd(jobz, uplo, n, a, ia, ja, desca, w, z, iz, jz, descz, work, lwork, iwork, liwork, info)
Definition pssyevd.f:3
subroutine slboot()
Definition sltimer.f:2
subroutine sltimer(i)
Definition sltimer.f:47