1 SUBROUTINE pdsvdtst( M, N, NPROW, NPCOL, NB, ISEED, THRESH, WORK,
2 $ RESULT, LWORK, NOUT )
10 INTEGER LWORK, M, N, NB, NOUT, NPCOL
11DOUBLE PRECISION THRESH
14 INTEGER ISEED( 4 ), RESULT( 9 )
15 DOUBLE PRECISION WORK( * )
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 )
215 DOUBLE PRECISION ZERO, ONE
216 parameter( zero = 0.0d0, one = 1.0d0 )
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, ptrwork, ptrs, ptrsc, ptru,
224 $ ptruc, ptrvt, ptrvtc, sethet,
SIZE, sizeq,
225 $ wpdgesvd, wpdlagge, wpdsvdchk, wpdsvdcmp
226 DOUBLE PRECISION CHK, DELTA, H, MTM, OVFL, RTOVFL, RTUNFL, ULP,
234 $ igamn2d, igamx2d, igebr2d, igebs2d,
pdelset,
240 DOUBLE PRECISION PDLAMCH
241 EXTERNAL numroc, pdlamch
244 INTEGER DESCA( DLEN_ ), DESCU( DLEN_ ),
245 $ descvt( dlen_ ), itmp( 2 )
246 DOUBLE PRECISION CTIME( 1 ), ( 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 )
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,
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 pdlagge( m, n, work( ptrd ), work( ptra ), ia, ja, desca,
325 $ iseed,
SIZE, work( ptrwork ), -1, dinfo )
326 wpdlagge = int( work( ptrwork ) )
328 CALL pdgesvd(
'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 wpdgesvd = int( work( ptrwork ) )
334 CALL pdsvdchk( 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 wpdsvdchk = int( work( ptrwork )
340 CALL pdsvdcmp( 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 wpdsvdcmp = int( work( ptrwork ) )
348 lwmin = 1 + 2*lda*nq + 3*
SIZE +
349 $
max( wpdlagge, ldu*sizeq+ldvt*nq+
max( ldu*sizeq,
350 $ ldvt*nq )+wpdgesvd+
max( wpdsvdchk, wpdsvdcmp ) )
358 IF( lwork.LT.lwmin )
THEN
364 CALL pxerbla( desca( ctxt_ ),
'PDSVDTST', -info )
368 ulp = pdlamch( context,
'P' )
369 unfl = pdlamch( context,
'Safe min' )
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 pdlaset(
'All', m, n, zero
405 ELSE IF( itype.EQ.2 )
THEN
410 work( ptrd+i-1 ) = one
413 CALL pdlaset(
'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 pdlaset(
'All', m, n, zero, zero, work( ptra ),
437 CALL pdelset( work( ptra ), i, i, desca,
441 ELSE IF( itype.EQ.4 )
THEN
445 CALL pdlagge( m, n, work( ptrd ), work( ptra ), ia, ja,
446 $ desca, iseed,
SIZE, work( ptrwork ),
449 ELSE IF( itype.EQ.5 )
THEN
453 CALL dscal(
SIZE, rtovfl, work( ptrd ), 1 )
455 CALL pdlagge( m, n, work( ptrd ), work( ptra ), ia, ja,
456 $ desca, iseed,
SIZE, work( ptrwork ),
459 ELSE IF( itype.EQ.6 )
THEN
463 CALL dscal(
SIZE, rtunfl, work( ptrd ), 1 )
464 CALL pdlagge( 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 pdlacpy(
'A', m, n, work( ptra ), ia, ja, desca,
503 $ work( ptrac ), ia, ja, desca )
508 IF( jobtype.EQ.1 )
THEN
513 CALL blacs_barrier( context,
'All' )
516 CALL pdgesvd( jobu, jobvt, m, n, work( ptrac ), ia, ja,
517 $ desca, work( ptrs ), work( ptru ), iu, ju,
518 $ descu, work( ptrvt ), ivt, jvt, descvt,
519 $ work( ptrwork ), wpdgesvd, info )
522 CALL slcombine( context,
'All',
'>',
'W', 1, 1, wtime )
523 CALL slcombine( context,
'All',
'>',
'C', 1, 1, ctime )
531 CALL igamn2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp, 1, 1,
533 CALL igamx2d( desca( ctxt_ ),
'a',
' ', 1, 1, itmp( 2 ),
534 $ 1, 1, 1, -1, -1, 0 )
536 IF( itmp( 1 ).NE.itmp( 2 ) )
THEN
537 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
THEN
538 WRITE( nout, fmt = * )
539 $
'Different processes return different INFO'
548 IF( info.EQ.( size+1 ) )
THEN
555 IF( info.EQ.zero )
THEN
558 work( i+ptrwork ) = work( i+ptrs-1 )
559 work( i+size+ptrwork ) = work( i+ptrs-1 )
562 CALL dgamn2d( desca( ctxt_ ),
'a',
' ',
SIZE, 1,
563 $ work( 1+ptrwork ),
SIZE, 1, 1, -1, -1,
565 CALL dgamx2d( desca( ctxt_ ),
'a',
' ',
SIZE, 1,
566 $ work( 1+size+ptrwork ),
SIZE, 1, 1, -1,
570 IF( abs( work( i+ptrwork )-work( size+i+
571 $ ptrwork ) ).GT.zero )
THEN
572 WRITE( nout, fmt = * )
'I= ', i,
' MIN=',
573 $ work( i+ptrwork ),
' MAX=',
574 $ work( size+i+ptrwork )
590 CALL PDLACPY( 'a
', M, N, WORK( PTRA ), IA, JA, DESCA,
591 $ WORK( PTRAC ), IA, JA, DESCA )
597 CALL PDLACPY( 'a
', M, SIZE, WORK( PTRU ), IU, JU, DESCU,
598 $ WORK( PTRUC ), IU, JU, DESCU )
602 CALL PDSVDCHK( M, N, WORK( PTRAC ), IA, JA, DESCA,
603 $ WORK( PTRUC ), IU, JU, DESCU,
604 $ WORK( PTRVT ), IVT, JVT, DESCVT,
605 $ WORK( PTRS ), THRESH, WORK( PTRWORK ),
606 $ LLWORK, RESULT, CHK, MTM )
612 CALL PDGESVD( JOBU, JOBVT, M, N, WORK( PTRAC ), IA, JA,
613 $ DESCA, WORK( PTRSC ), WORK( PTRUC ), IU,
614 $ JU, DESCU, WORK( PTRVTC ), IVT, JVT,
615 $ DESCVT, WORK( PTRWORK ), WPDGESVD, INFO )
617 CALL PDSVDCMP( M, N, JOBTYPE, WORK( PTRS ),
618 $ WORK( PTRSC ), WORK( PTRU ),
619 $ WORK( PTRUC ), IU, JU, DESCU,
620 $ WORK( PTRVT ), WORK( PTRVTC ), IVT, JVT,
621 $ DESCVT, THRESH, RESULT, DELTA,
622 $ WORK( PTRWORK ), LLWORK )
628.EQ..AND..EQ.
IF( MYROW0 MYCOL0 ) THEN
630.EQ.
IF( RESULT( I )1 ) THEN
632 WRITE( NOUT, FMT = * )'test i =
', I, 'has failed
'
633 WRITE( NOUT, FMT = * )' '
637 WRITE( NOUT, FMT = 9999 )'passed
', WTIME( 1 ),
638 $ CTIME( 1 ), M, N, NPROW, NPCOL, NB, ITYPE, CHK, MTM,
643 CALL BLACS_GRIDEXIT( CONTEXT )
646 9999 FORMAT( A6, 2E10.3, 2I6, 2I4, I5, I6, 3F6.2, 4X, A1 )