4
5
6
7
8
9
10
11 INTEGER IA, IU, IVT, JA, JU, JVT, LWORK, M, N
12 DOUBLE PRECISION CHK, MTM, THRESH
13
14
15 INTEGER DESCA( * ), DESCU( * ), DESCVT( * ),
16 $ RESULT( * )
17 DOUBLE PRECISION A( * ), S( * ), U( * ), VT( * ), WORK( * )
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
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 )
206 DOUBLE PRECISION ZERO, ONE, MONE
207 parameter( zero = 0.0d+0, one = 1.0d+0, mone = -1.0d0 )
208
209
210 INTEGER I, INFO, LDR, LOCALCOL, LWMIN, MP, MX, MYCOL,
211 $ MYROW, NPCOL, NPROW, NQ, PCOL, PTRR, PTRWORK,
212 $ SIZE, SIZEP, SIZEPOS, SIZEQ
213 DOUBLE PRECISION FIRST, NORMA, NORMAI, NORMU, NORMVT, SECOND,
214 $ THRESHA, ULP
215
216
217 INTEGER DESCR( DLEN_ )
218
219
220 INTEGER INDXG2L, INDXG2P, NUMROC
221 DOUBLE PRECISION PDLAMCH, PDLANGE
223
224
227
228
230
231
232
233 IF( block_cyclic_2d*csrc_*dtype_*m_*n_*rsrc_.LT.0 ) RETURN
234
235
236
237 CALL blacs_gridinfo( desca( ctxt_ ), nprow, npcol, myrow, mycol )
238 info = 0
240
241
242
243
244 sizepos = 22
245 IF( nprow.EQ.-1 ) THEN
246 info = -607
247 ELSE
248 CALL chk1mat( m, 1, n, 2, ia, ja, desca, 6, info )
249 CALL chk1mat( m, 1,
SIZE, sizepos, iu, ju, descu, 10, info )
250 CALL chk1mat(
SIZE, sizepos, n, 2, ivt, jvt, descvt, 14, info )
251 END IF
252
253 IF( info.EQ.0 ) THEN
254
255
256
257 mp =
numroc( m, desca( mb_ ), myrow, 0, nprow )
258 nq =
numroc( n, desca( nb_ ), mycol, 0, npcol )
259 sizep =
numroc(
SIZE, descvt( mb_ ), myrow, 0, nprow )
260 sizeq =
numroc(
SIZE, descu( nb_ ), mycol, 0, npcol )
261 mx =
max( sizeq, nq )
262 lwmin = 2 + sizeq*sizep +
max( 2, mx )
263 work( 1 ) = lwmin
264 IF( lwork.EQ.-1 )
265 $ GO TO 40
266 IF( lwork.LT.lwmin ) THEN
267 info = -18
268 ELSE IF( thresh.LE.0 ) THEN
269 info = -16
270 END IF
271 END IF
272 IF( info.NE.0 ) THEN
273 CALL pxerbla( desca( ctxt_ ),
'PDSVDCHK', -info )
274 RETURN
275 END IF
276
277 ldr =
max( 1, sizep )
278 ulp =
pdlamch( desca( ctxt_ ),
'P' )
279 normai =
pdlange(
'1', m, n, a, ia, ja, desca, work )
280
281
282
283 ptrr = 2
284 ptrwork = ptrr + sizeq*sizep
285
286 CALL descinit( descr,
SIZE,
SIZE, descvt( mb_ ), descu( nb_ ), 0,
287 $ 0, desca( ctxt_ ), ldr, info )
288
289
290
291 CALL pdlaset(
'Full',
SIZE,
SIZE, zero, one, work( ptrr ), 1, 1,
292 $ descr )
293 CALL pdgemm( 'T', 'N', SIZE, SIZE, m, one, u, iu, ju, descu, u,
294 $ iu, ju, descu, mone, work( ptrr ), 1, 1, descr )
295
296 normu =
pdlange(
'1',
SIZE,
SIZE, work( ptrr ), 1, 1, descr,
297 $ work( ptrwork ) )
298
299 normu = normu / ulp / SIZE / thresh
300 IF( normu.GT.1. )
301 $ result( 2 ) = 1
302
303
304
305 CALL pdlaset(
'Full',
SIZE,
SIZE, zero, one, work( ptrr ), 1, 1,
306 $ descr )
307 CALL pdgemm( 'N', 'T', SIZE, SIZE, n, one, vt, ivt, jvt, descvt,
308 $ vt, ivt, jvt, descvt, mone, work( ptrr ),
309 $ 1, 1, descr )
310 normvt =
pdlange(
'1',
SIZE,
SIZE, work( ptrr ), 1, 1, descr,
311 $ work( ptrwork ) )
312
313 normvt = normvt / ulp / SIZE / thresh
314 IF( normvt.GT.1. )
315 $ result( 3 ) = 1
316
317 mtm =
max( normvt, normu )*thresh
318
319
320
321
322 CALL pdlaset(
'Full',
SIZE,
SIZE, zero, zero, work( ptrr ), 1, 1,
323 $ descr )
324
325 DO 10 i = 1, SIZE
326 CALL pdelset( work( ptrr ), i, i, descr, s( i ) )
327 10 CONTINUE
328
329
330
331 DO 20 i = 1, SIZE
332 pcol =
indxg2p( i, descu( nb_ ), 0, 0, npcol )
333 localcol =
indxg2l( i, descu( nb_ ), 0, 0, npcol )
334 IF( mycol.EQ.pcol ) THEN
335 CALL dscal( mp, s( i ), u( ( localcol-1 )*descu( lld_ )+1 ),
336 $ 1 )
337 END IF
338 20 CONTINUE
339
340
341
342 CALL pdgemm( 'N', 'N', m, n, SIZE, one, u, iu, ju, descu, vt,
343 $ ivt, jvt, descvt, mone, a, ia, ja, desca )
344
345 norma =
pdlange(
'1', m, n, a, ia, ja, desca, work( ptrwork ) )
346 thresha = normai*
max( m, n )*ulp*thresh
347
348 IF( norma.GT.thresha )
349 $ result( 1 ) = 1
350
351 IF( thresha.EQ.0 ) THEN
352 chk = 0.0d0
353 ELSE
354 chk = norma / thresha*thresh
355 END IF
356
357
358
359 DO 30 i = 1, SIZE - 1
360 first = s( i )
361 second = s( i+1 )
362 IF( first.LT.second )
363 $ result( 4 ) = 1
364 30 CONTINUE
365 40 CONTINUE
366 RETURN
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine descinit(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld, info)
integer function indxg2l(indxglob, nb, iproc, isrcproc, nprocs)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pdlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
double precision function pdlamch(ictxt, cmach)
subroutine pdelset(a, ia, ja, desca, alpha)
double precision function pdlange(norm, m, n, a, ia, ja, desca, work)
subroutine pxerbla(ictxt, srname, info)