1 SUBROUTINE pssvdchk( M, N, A, IA, JA, DESCA, U, IU, JU, DESCU, VT,
2 $ IVT, JVT, DESCVT, S, THRESH, WORK, LWORK,
11 INTEGER IA, IU, IVT, JA, JU, JVT, LWORK, M, N
15 INTEGER DESCA( * ), DESCU( * ), DESCVT( * ),
17 REAL A( * ), S( * ), U( * ), VT( * ), WORK( * )
201 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
202 $ MB_, NB_, RSRC_, CSRC_, LLD_
203 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
204 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
205 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
207 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0, mone = -1.0e0 )
210 INTEGER I, INFO, LDR, LOCALCOL, LWMIN, MP, MX, MYCOL,
211 $ MYROW, NPCOL, NPROW, NQ, PCOL, PTRR, PTRWORK,
212 $
SIZE, sizep, sizepos, sizeq
213 REAL FIRST, NORMA, NORMAI, NORMU, NORMVT, SECOND,
217 INTEGER DESCR( DLEN_ )
220 INTEGER INDXG2L, INDXG2P, NUMROC
221 REAL PSLAMCH, PSLANGE
222 EXTERNAL indxg2l, indxg2p, numroc, pslamch, pslange
235 CALL blacs_gridinfo( desca( ctxt_ ), nprow, npcol, myrow, mycol )
243 IF( nprow.EQ.-1 )
THEN
246 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 6, info )
247 CALL chk1mat( m, 1,
SIZE, sizepos, iu, ju, descu, 10, info )
248 CALL chk1mat(
SIZE, sizepos, n, 2, ivt, jvt, descvt, 14, info )
255 mp = numroc( m, desca( mb_ ), myrow, 0, nprow )
256 nq = numroc( n, desca( nb_ ), mycol, 0, npcol )
257 sizep = numroc(
SIZE, descvt( mb_ ), myrow, 0, nprow )
258 sizeq = numroc(
SIZE, descu( nb_ ), mycol, 0, npcol )
259 mx =
max( sizeq, nq )
260 lwmin = 2 + sizeq*sizep +
max( 2, mx )
264 IF( lwork.LT.lwmin )
THEN
266 ELSE IF( thresh.LE.0 )
THEN
271 CALL pxerbla( desca( ctxt_ ),
'PSSVDCHK', -info )
275 ldr =
max( 1, sizep )
276 ulp = pslamch( desca( ctxt_ ),
'P' )
277 normai = pslange(
'1', m, n, a, 1, 1, desca, work )
282 ptrwork = ptrr + sizeq*sizep
284 CALL descinit( descr,
SIZE,
SIZE, descvt( mb_ ), descu( nb_ ), 0,
285 $ 0, desca( ctxt_ ), ldr, info )
289 CALL pslaset(
'Full',
SIZE,
SIZE, zero, one, work( ptrr ), 1, 1,
291 CALL psgemm(
'T',
'N',
SIZE,
SIZE, m, one, u, 1, 1, descu, u, 1,
292 $ 1, descu, mone, work( ptrr ), 1, 1, descr )
294 normu = pslange(
'1',
SIZE,
SIZE, work( ptrr ), 1, 1, descr,
297 normu = normu / ulp /
SIZE / thresh
303 CALL pslaset(
'Full',
SIZE,
SIZE, zero, one, work( ptrr ), 1, 1,
305 CALL psgemm(
'N',
'T',
SIZE,
SIZE, n, one, vt, 1, 1, descvt, vt,
306 $ 1, 1, descvt, mone, work( ptrr ), 1, 1, descr )
307 normvt = pslange(
'1',
SIZE,
SIZE, work( ptrr ), 1, 1, descr,
310 normvt = normvt / ulp /
SIZE / thresh
314 mtm =
max( normvt, normu )*thresh
319 CALL pslaset(
'Full',
SIZE,
SIZE, zero, zero, work( ptrr ), 1, 1,
323 CALL pselset( work( ptrr ), i, i, descr, s( i ) )
329 pcol = indxg2p( i, descu( nb_ ), 0, 0, npcol )
330 localcol = indxg2l( i, descu( nb_ ), 0, 0, npcol )
331 IF( mycol.EQ.pcol )
THEN
332 CALL sscal( mp, s( i ), u( ( localcol-1 )*descu( lld_ )+1 ),
339 CALL psgemm(
'N',
'N', m, n,
SIZE, one, u, 1, 1, descu, vt, 1, 1,
340 $ descvt, mone, a, 1, 1, desca )
342 norma = pslange(
'1', m, n, a, 1, 1, desca, work( ptrwork ) )
343 thresha = normai*
max( m, n )*ulp*thresh
345 IF( norma.GT.thresha )
348 IF( thresha.EQ.0 )
THEN
351 chk = norma / thresha*thresh
356 DO 30 i = 1,
SIZE - 1
359 IF( first.LT.second )