1 SUBROUTINE pdsvdtst( M, N, NPROW, NPCOL, NB, ISEED, THRESH, WORK,
2 $ RESULT, LWORK, NOUT )
10 INTEGER LWORK, M, N, NB, NOUT, NPCOL, NPROW
11 DOUBLE 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,
230 EXTERNAL blacs_barrier, blacs_get, blacs_gridexit,
231 $ blacs_gridinfo, blacs_gridinit, blacs_pinfo,
233 $
descinit, dgamn2d, dgamx2d, dlabad, dscal,
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 ), 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 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' )
371 CALL dlabad( 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 pdlaset(
'All', m, n, zero, zero, work( ptra ),
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 IF( myrow.EQ.0 .AND. mycol.EQ.0 )
THEN
630 IF( result( i ).EQ.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 )