1 SUBROUTINE pssvdtst( M, N, NPROW, NPCOL, NB, ISEED, THRESH, WORK,
2 $ RESULT, LWORK, NOUT )
10 INTEGER LWORK, M, N, NB, NOUT, NPCOL, NPROW
14 INTEGER ISEED( 4 ), RESULT( 9 )
210 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
211 $ mb_, nb_, rsrc_, csrc_, lld_, ntypes
212 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
213 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
214 $ rsrc_ = 7, csrc_ = 8, lld_ = 9, ntypes = 6 )
216 parameter( zero = 0.0e0, one = 1.0e0 )
219 CHARACTER HETERO, JOBU, JOBVT
220 INTEGER CONTEXT, DINFO, I, IA, IAM, INFO, ITYPE, IU,
221 $ ivt, ja, jobtype, ju, jvt, lda, ldu, ldvt,
222 $ llwork, lwmin, mycol, myrow, nnodes, nq, pass,
223 $ ptra, ptrac, ptrd, ptrs, ptrsc, ptru, ptruc,
224 $ ptrvt, ptrvtc, ptrwork, sethet,
SIZE, sizeq,
225 $ wpsgesvd, wpslagge, wpssvdchk, wpssvdcmp
226 REAL CHK, DELTA, H, MTM, OVFL, RTOVFL, RTUNFL, ULP,
230 EXTERNAL blacs_barrier, blacs_get, blacs_gridexit,
231 $ blacs_gridinfo, blacs_gridinit, blacs_pinfo,
233 $
descinit, sgamn2d, sgamx2d, slabad, sscal,
234 $ igamn2d, igamx2d, igebr2d, igebs2d,
pselset,
241 EXTERNAL numroc, pslamch
244 INTEGER DESCA( DLEN_ ), DESCU( DLEN_ ),
245 $ descvt( dlen_ ), itmp( 2 )
246 DOUBLE PRECISION CTIME( 1 ), WTIME( 1 )
249 INTRINSIC abs, int,
max,
min, sqrt
253 IF( block_cyclic_2d*csrc_*dtype_*lld_*mb_*m_*nb_*n_*rsrc_.LT.0 )
256 CALL blacs_pinfo( iam, nnodes )
257 CALL blacs_get( -1, 0, context )
258 CALL blacs_gridinit( context,
'R', nprow, npcol )
259 CALL blacs_gridinfo( context, nprow, npcol, myrow, mycol )
263 IF( ( myrow.GE.nprow ) .OR. ( myrow.LT.0 ) .OR.
264 $ ( mycol.GE.npcol ) .OR. ( mycol.LT.0 ) )
GO TO 110
265 CALL blacs_set( context, 15, 1 )
272 ELSE IF( n.LE.0 )
THEN
274 ELSE IF( nprow.LE.0 )
THEN
276 ELSE IF( npcol.LE.0 )
THEN
278 ELSE IF( nb.LE.0 )
THEN
280 ELSE IF( thresh.LE.0 )
THEN
295 lda = numroc( m, nb, myrow, 0, nprow )
297 nq = numroc( n, nb, mycol, 0, npcol )
299 sizeq = numroc(
SIZE, nb, mycol, 0, npcol )
300 ldvt = numroc(
SIZE, nb, myrow, 0, nprow )
301 ldvt =
max( 1, ldvt )
302 CALL descinit( desca, m, n, nb, nb, 0, 0, context, lda, dinfo )
303 CALL descinit( descu, m,
SIZE, nb, nb, 0, 0, context, ldu, dinfo )
304 CALL descinit( descvt,
SIZE, n, nb, nb, 0, 0, context, ldvt,
310 ptrac = ptra + lda*nq
311 ptrd = ptrac + lda*nq
314 ptrwork = ptrsc +
SIZE
324 CALL pslagge( m, n, work( ptrd ), work( ptra ), ia, ja, desca,
325 $ iseed,
SIZE, work( ptrwork ), -1, dinfo )
326 wpslagge = int( work( ptrwork ) )
328 CALL psgesvd(
'V',
'V', m, n, work( ptra ), ia, ja, desca,
329 $ work( ptrs ), work( ptru ), iu, ju, descu,
330 $ work( ptrvt ), ivt, jvt, descvt,
331 $ work( ptrwork ), -1, dinfo )
332 wpsgesvd = int( work( ptrwork ) )
334 CALL pssvdchk( m, n, work( ptrac ), ia, ja, desca, work( ptruc ),
335 $ iu, ju, descu, work( ptrvt ), ivt, jvt, descvt,
336 $ work( ptrs ), thresh, work( ptrwork ), -1,
338 wpssvdchk = int( work( ptrwork ) )
340 CALL pssvdcmp( m, n, 1, work( ptrs ), work( ptrsc ), work( ptru ),
341 $ work( ptruc ), iu, ju, descu, work( ptrvt ),
342 $ work( ptrvtc ), ivt, jvt, descvt, thresh,
343 $ result, delta, work( ptrwork ), -1 )
344 wpssvdcmp = int( work( ptrwork ) )
348 lwmin = 1 + 2*lda*nq + 3*
SIZE +
349 $
max( wpslagge, ldu*sizeq+ldvt*nq+
max( ldu*sizeq,
350 $ ldvt*nq )+wpsgesvd+
max( wpssvdchk, wpssvdcmp ) )
358 IF( lwork.LT.lwmin )
THEN
364 CALL pxerbla( desca( ctxt_ ),
'PSSVDTST', -info )
368 ulp = pslamch( context,
'P' )
369 unfl = pslamch( context,
'Safe min' )
371 CALL slabad( unfl, ovfl )
372 rtunfl = sqrt( unfl )
373 rtovfl = sqrt( ovfl )
377 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
THEN
378 CALL igebs2d( context,
'a',
' ', 4, 1, iseed, 4 )
380 CALL igebr2d( context,
'a',
' ', 4, 1, iseed, 4, 0, 0 )
385 DO 100 itype = 1, ntypes
389 ptrwork = ptrsc +
SIZE
390 llwork = lwork - ptrwork + 1
394 IF( itype.EQ.1 )
THEN
399 work( ptrd+i-1 ) = zero
402 CALL pslaset(
'All', m, n, zero, zero, work( ptra ),
405 ELSE IF( itype.EQ.2 )
THEN
410 work( ptrd+i-1 ) = one
413 CALL pslaset(
'All', m, n, zero, one, work( ptra ),
416 ELSE IF( itype.GT.2 )
THEN
421 h = ( ulp-1 ) / ( size-1 )
423 work( ptrd+i-1 ) = 1 + h*( i-1 )
429 IF( itype.EQ.3 )
THEN
433 CALL pslaset(
'All', m, n, zero, zero, work( ptra ),
437 CALL pselset( work( ptra ), i, i, desca,
441 ELSE IF( itype.EQ.4 )
THEN
445 CALL pslagge( m, n, work( ptrd ), work( ptra ), ia, ja,
446 $ desca, iseed,
SIZE, work( ptrwork ),
449 ELSE IF( itype.EQ.5 )
THEN
453 CALL sscal(
SIZE, rtovfl, work( ptrd ), 1 )
455 CALL pslagge( m, n, work( ptrd ), work( ptra ), ia, ja,
456 $ desca, iseed,
SIZE, work( ptrwork ),
459 ELSE IF( itype.EQ.6 )
THEN
463 CALL sscal(
SIZE, rtunfl, work( ptrd ), 1 )
464 CALL pslagge( m, n, work( ptrd ), work( ptra ), ia, ja,
465 $ desca, iseed,
SIZE, work( ptrwork ),
477 IF( jobtype.EQ.1 )
THEN
480 ptrvt = ptru + ldu*sizeq
481 ptruc = ptrvt + ldvt*nq
482 ptrwork = ptruc + ldu*sizeq
483 llwork = lwork - ptrwork + 1
484 ELSE IF( jobtype.EQ.2 )
THEN
487 ELSE IF( jobtype.EQ.3 )
THEN
491 ptrwork = ptrvtc + ldvt*nq
492 llwork = lwork - ptrwork + 1
493 ELSE IF( jobtype.EQ.4 )
THEN
497 llwork = lwork - ptrwork + 1
502 CALL pslacpy(
'A', m, n, work( ptra ), ia, ja, desca,
503 $ work( ptrac ), ia, ja, desca )
508 IF( jobtype.EQ.1 )
THEN
512 CALL blacs_barrier( context,
'All' )
515 CALL psgesvd( jobu, jobvt, m, n, work( ptrac ), ia, ja,
516 $ desca, work( ptrs ), work( ptru ), iu, ju,
517 $ descu, work( ptrvt ), ivt, jvt, descvt,
518 $ work( ptrwork ), wpsgesvd, info )
521 CALL slcombine( context,
'All',
'>',
'W', 1, 1, wtime )
522 CALL slcombine( context,
'All',
'>',
'C', 1, 1, ctime )
530 CALL igamn2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp, 1, 1,
532 CALL igamx2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp( 2 ),
533 $ 1, 1, 1, -1, -1, 0 )
535 IF( itmp( 1 ).NE.itmp( 2 ) )
THEN
536 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
THEN
537 WRITE( nout, fmt = * )
538 $
'Different processes return different INFO'
547 IF( info.EQ.( size+1 ) )
THEN
554 IF( info.EQ.zero )
THEN
557 work( i+ptrwork ) = work( i+ptrs-1 )
558 work( i+size+ptrwork ) = work( i+ptrs-1 )
561 CALL sgamn2d( desca( ctxt_ ),
'a',
' ',
SIZE, 1,
562 $ work( 1+ptrwork ),
SIZE, 1, 1, -1, -1,
564 CALL sgamx2d( desca( ctxt_ ),
'a',
' ',
SIZE, 1,
565 $ work( 1+size+ptrwork ),
SIZE, 1, 1, -1,
569 IF( abs( work( i+ptrwork )-work( size+i+
570 $ ptrwork ) ).GT.zero )
THEN
571 WRITE( nout, fmt = * )
'I= ', i,
' MIN=',
572 $ work( i+ptrwork ),
' MAX=',
573 $ work( size+i+ptrwork )
589 CALL pslacpy(
'A', m, n, work( ptra ), ia, ja, desca,
590 $ work( ptrac ), ia, ja, desca )
596 CALL pslacpy(
'A', m,
SIZE, work( ptru ), iu, ju, descu,
597 $ work( ptruc ), iu, ju, descu )
601 CALL pssvdchk( m, n, work( ptrac ), ia, ja, desca,
602 $ work( ptruc ), iu, ju, descu,
603 $ work( ptrvt ), ivt, jvt, descvt,
604 $ work( ptrs ), thresh, work( ptrwork ),
605 $ llwork, result, chk, mtm )
611 CALL psgesvd( jobu, jobvt, m, n, work( ptrac ), ia, ja,
612 $ desca, work( ptrsc ), work( ptruc ), iu,
613 $ ju, descu, work( ptrvtc ), ivt, jvt,
614 $ descvt, work( ptrwork ), wpsgesvd, info )
616 CALL pssvdcmp( m, n, jobtype, work( ptrs ),
617 $ work( ptrsc ), work( ptru ),
618 $ work( ptruc ), iu, ju, descu,
619 $ work( ptrvt ), work( ptrvtc ), ivt, jvt,
620 $ descvt, thresh, result, delta,
621 $ work( ptrwork ), llwork )
627 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
THEN
629 IF( result( i ).EQ.1 )
THEN
631 WRITE( nout, fmt = * )
'Test I = ', i,
'has failed'
632 WRITE( nout, fmt = * )
' '
636 WRITE( nout, fmt = 9999 )
'Passed', wtime( 1 ),
637 $ ctime( 1 ), m, n, nprow, npcol, nb, itype, chk, mtm,
642 CALL blacs_gridexit( context )
645 9999
FORMAT( a6, 2e10.3, 2i6, 2i4, i5, i6, 3f6.2, 4x, a1 )