4
5
6
7
8
9
10
11
12 CHARACTER JOBU,JOBVT
13 INTEGER IA,INFO,IU,IVT,JA,JU,JVT,LWORK,M,N
14
15
16 INTEGER DESCA(*),DESCU(*),DESCVT(*)
17 DOUBLE PRECISION A(*),U(*),VT(*),WORK(*)
18 DOUBLE PRECISION S(*)
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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 INTEGER BLOCK_CYCLIC_2D,DLEN_,DTYPE_,CTXT_,M_,N_,MB_,NB_,RSRC_,
287 + CSRC_,LLD_,ITHVAL
288 parameter(block_cyclic_2d=1,dlen_=9,dtype_=1,ctxt_=2,m_=3,n_=4,
289 + mb_=5,nb_=6,rsrc_=7,csrc_=8,lld_=9,ithval=10)
290 DOUBLE PRECISION ZERO,ONE
291 parameter(zero= (0.0d+0),one= (1.0d+0))
292
293
294 CHARACTER UPLO
295 INTEGER CONTEXTC,CONTEXTR,I,INDD,INDD2,INDE,INDE2,INDTAUP,INDTAUQ,
296 + INDU,INDV,INDWORK,IOFFD,IOFFE,ISCALE,J,K,LDU,LDVT,LLWORK,
297 + LWMIN,MAXIM,MB,MP,MYPCOL,MYPCOLC,MYPCOLR,MYPROW,MYPROWC,
298 + MYPROWR,NB,NCVT,NPCOL,NPCOLC,NPCOLR,NPROCS,NPROW,NPROWC,
299 + NPROWR,NQ,NRU,SIZE,SIZEB,SIZEP,SIZEPOS,SIZEQ,WANTU,WANTVT,
300 + WATOBD,WBDTOSVD,WDBDSQR,WPDGEBRD,WPDLANGE,WPDORMBRPRT,
301 + WPDORMBRQLN
302 DOUBLE PRECISION ANRM,BIGNUM,EPS,RMAX,RMIN,SAFMIN,SIGMA,SMLNUM
303
304
305 INTEGER DESCTU(DLEN_),DESCTVT(DLEN_),IDUM1(3),IDUM2(3)
306 DOUBLE PRECISION C(1,1)
307
308
309 LOGICAL LSAME
310 INTEGER NUMROC
311 DOUBLE PRECISION PDLAMCH,PDLANGE
313
314
315 EXTERNAL blacs_get,blacs_gridexit,blacs_gridinfo,blacs_gridinit,
319
320
321 INTRINSIC max,
min,sqrt,dble
322
323
324
325 IF (block_cyclic_2d*dtype_*lld_*mb_*m_*nb_*n_.LT.0) RETURN
326
327 CALL blacs_gridinfo(desca(ctxt_),nprow,npcol,myprow,mypcol)
328 iscale = 0
329 info = 0
330
331 IF (nprow.EQ.-1) THEN
332 info = - (800+ctxt_)
333 ELSE
334
337 nprocs = nprow*npcol
338 IF (m.GE.n) THEN
339 ioffd = ja - 1
340 ioffe = ia - 1
341 sizepos = 1
342 ELSE
343 ioffd = ia - 1
344 ioffe = ja - 1
345 sizepos = 3
346 END IF
347
348 IF (
lsame(jobu,
'V'))
THEN
349 wantu = 1
350 ELSE
351 wantu = 0
352 END IF
353 IF (
lsame(jobvt,
'V'))
THEN
354 wantvt = 1
355 ELSE
356 wantvt = 0
357 END IF
358
359 CALL chk1mat(m,3,n,4,ia,ja,desca,8,info)
360 IF (wantu.EQ.1) THEN
361 CALL chk1mat(m,3,
SIZE,sizepos,iu,ju,descu,13,info)
362 END IF
363 IF (wantvt.EQ.1) THEN
364 CALL chk1mat(
SIZE,sizepos,n,4,ivt,jvt,descvt,17,info)
365 END IF
366 CALL igamx2d(desca(ctxt_),'A',' ',1,1,info,1,1,1,-1,-1,0)
367
368 IF (info.EQ.0) THEN
369
370
371
372 indd = 2
373 inde = indd + sizeb + ioffd
374 indd2 = inde + sizeb + ioffe
375 inde2 = indd2 + sizeb + ioffd
376
377 indtauq = inde2 + sizeb + ioffe
378 indtaup = indtauq + sizeb + ja - 1
379 indwork = indtaup + sizeb + ia - 1
380 llwork = lwork - indwork + 1
381
382
383
384 CALL blacs_get(desca(ctxt_),10,contextc)
385 CALL blacs_gridinit(contextc,'R',nprocs,1)
386 CALL blacs_gridinfo(contextc,nprowc,npcolc,myprowc,
387 + mypcolc)
388 CALL blacs_get(desca(ctxt_),10,contextr)
389 CALL blacs_gridinit(contextr,'R',1,nprocs)
390 CALL blacs_gridinfo(contextr,nprowr,npcolr,myprowr,
391 + mypcolr)
392
393
394
395 nru =
numroc(m,1,myprowc,0,nprocs)
396 ncvt =
numroc(n,1,mypcolr,0,nprocs)
397 nb = desca(nb_)
398 mb = desca(mb_)
399 mp =
numroc(m,mb,myprow,desca(rsrc_),nprow)
400 nq =
numroc(n,nb,mypcol,desca(csrc_),npcol)
401 IF (wantvt.EQ.1) THEN
402 sizep =
numroc(
SIZE,descvt(mb_),myprow,descvt(rsrc_),
403 + nprow)
404 ELSE
405 sizep = 0
406 END IF
407 IF (wantu.EQ.1) THEN
408 sizeq =
numroc(
SIZE,descu(nb_),mypcol,descu(csrc_),
409 + npcol)
410 ELSE
411 sizeq = 0
412 END IF
413
414
415
416 IF (myprow.EQ.0 .AND. mypcol.EQ.0) THEN
418 CALL igebs2d(desca(ctxt_),'All',' ',1,1,maxim,1)
419 ELSE
420 CALL igebr2d(desca(ctxt_),'All',' ',1,1,maxim,1,0,0)
421 END IF
422
423 wpdlange = mp
424 wpdgebrd = nb* (mp+nq+1) + nq
425 watobd =
max(
max(wpdlange,wpdgebrd),maxim)
426
427 wdbdsqr =
max(1,4*size)
428 wpdormbrqln =
max((nb* (nb-1))/2, (sizeq+mp)*nb) + nb*nb
429 wpdormbrprt =
max((mb* (mb-1))/2, (sizep+nq)*mb) + mb*mb
430 wbdtosvd = size* (wantu*nru+wantvt*ncvt) +
431 +
max(wdbdsqr,
max(wantu*wpdormbrqln,
432 + wantvt*wpdormbrprt))
433
434
435
436 lwmin = 1 + 6*sizeb +
max(watobd,wbdtosvd)
437 work(1) = dble(lwmin)
438
439 IF (wantu.NE.1 .AND. .NOT. (
lsame(jobu,
'N')))
THEN
440 info = -1
441 ELSE IF (wantvt.NE.1 .AND. .NOT. (
lsame(jobvt,
'N')))
THEN
442 info = -2
443 ELSE IF (lwork.LT.lwmin .AND. lwork.NE.-1) THEN
444 info = -19
445 END IF
446
447 END IF
448
449 idum1(1) = wantu
450 idum1(2) = wantvt
451 IF (lwork.EQ.-1) THEN
452 idum1(3) = -1
453 ELSE
454 idum1(3) = 1
455 END IF
456 idum2(1) = 1
457 idum2(2) = 2
458 idum2(3) = 19
459 CALL pchk1mat(m,3,n,4,ia,ja,desca,8,3,idum1,idum2,info)
460 IF (info.EQ.0) THEN
461 IF (wantu.EQ.1) THEN
462 CALL pchk1mat(m,3,
SIZE,4,iu,ju,descu,13,0,idum1,idum2,
463 + info)
464 END IF
465 IF (wantvt.EQ.1) THEN
466 CALL pchk1mat(
SIZE,3,n,4,ivt,jvt,descvt,17,0,idum1,
467 + idum2,info)
468 END IF
469 END IF
470
471 END IF
472
473 IF (info.NE.0) THEN
474 CALL pxerbla(desca(ctxt_),
'PDGESVD',-info)
475 RETURN
476 ELSE IF (lwork.EQ.-1) THEN
477 GO TO 40
478 END IF
479
480
481
482 IF (m.LE.0 .OR. n.LE.0) GO TO 40
483
484
485
486 safmin =
pdlamch(desca(ctxt_),
'Safe minimum')
487 eps =
pdlamch(desca(ctxt_),
'Precision')
488 smlnum = safmin/eps
489 bignum = one/smlnum
490 rmin = sqrt(smlnum)
491 rmax =
min(sqrt(bignum),one/sqrt(sqrt(safmin)))
492
493
494
495 anrm =
pdlange(
'1',m,n,a,ia,ja,desca,work(indwork))
496 IF (anrm.GT.zero .AND. anrm.LT.rmin) THEN
497 iscale = 1
498 sigma = rmin/anrm
499 ELSE IF (anrm.GT.rmax) THEN
500 iscale = 1
501 sigma = rmax/anrm
502 END IF
503
504 IF (iscale.EQ.1) THEN
505 CALL pdlascl(
'G',one,sigma,m,n,a,ia,ja,desca,info)
506 END IF
507
508 CALL pdgebrd(m,n,a,ia,ja,desca,work(indd),work(inde),
509 + work(indtauq),work(indtaup),work(indwork),llwork,
510 + info)
511
512
513
514
515
516
517
518 IF (m.GE.n) THEN
519
520 CALL pdlared1d(n+ioffd,ia,ja,desca,work(indd),work(indd2),
521 + work(indwork),llwork)
522
523 CALL pdlared2d(m+ioffe,ia,ja,desca,work(inde),work(inde2),
524 + work(indwork),llwork)
525 ELSE
526
527 CALL pdlared2d(m+ioffd,ia,ja,desca,work(indd),work(indd2),
528 + work(indwork),llwork)
529
530 CALL pdlared1d(n+ioffe,ia,ja,desca,work(inde),work(inde2),
531 + work(indwork),llwork)
532 END IF
533
534
535
536 IF (m.GE.n) THEN
537 uplo = 'U'
538 ELSE
539 uplo = 'L'
540 END IF
541
542 indu = indwork
543 indv = indu + size*nru*wantu
544 indwork = indv + size*ncvt*wantvt
545
548
549 CALL descinit(desctu,m,
SIZE,1,1,0,0,contextc,ldu,info)
550 CALL descinit(desctvt,
SIZE,n,1,1,0,0,contextr,ldvt,info)
551
552 IF (wantu.EQ.1) THEN
553 CALL pdlaset(
'Full',m,
SIZE,zero,one,work(indu),1,1,desctu)
554 ELSE
555 nru = 0
556 END IF
557
558 IF (wantvt.EQ.1) THEN
559 CALL pdlaset(
'Full',
SIZE,n,zero,one,work(indv),1,1,desctvt)
560 ELSE
561 ncvt = 0
562 END IF
563
564 CALL dbdsqr(uplo,SIZE,ncvt,nru,0,work(indd2+ioffd),
565 + work(inde2+ioffe),work(indv),SIZE,work(indu),ldu,c,1,
566 + work(indwork),info)
567
568
569
570 IF (wantu.EQ.1) CALL pdgemr2d(m,SIZE,work(indu),1,1,desctu,u,iu,
571 + ju,descu,descu(ctxt_))
572
573 IF (wantvt.EQ.1) CALL pdgemr2d(SIZE,n,work(indv),1,1,desctvt,vt,
574 + ivt,jvt,descvt,descvt(ctxt_))
575
576
577
578 IF (m.GT.n .AND. wantu.EQ.1) THEN
579 CALL pdlaset(
'Full',m-
SIZE,
SIZE,zero,zero,u,ia+
SIZE,ju,descu)
580 ELSE IF (n.GT.m .AND. wantvt.EQ.1) THEN
581 CALL pdlaset(
'Full',
SIZE,n-
SIZE,zero,zero,vt,ivt,jvt+
SIZE,
582 + descvt)
583 END IF
584
585
586
587 IF (wantu.EQ.1)
CALL pdormbr(
'Q',
'L',
'N',m,
SIZE,n,a,ia,ja,desca,
588 + work(indtauq),u,iu,ju,descu,
589 + work(indwork),llwork,info)
590
591 IF (wantvt.EQ.1)
CALL pdormbr(
'P',
'R',
'T',
SIZE,n,m,a,ia,ja,desca,
592 + work(indtaup),vt,ivt,jvt,descvt,
593 + work(indwork),llwork,info)
594
595
596
597 DO 10 i = 1,SIZE
598 s(i) = work(indd2+ioffd+i-1)
599 10 CONTINUE
600
601
602
603 IF (iscale.EQ.1) THEN
604 CALL dscal(SIZE,one/sigma,s,1)
605 END IF
606
607
608
609
610 IF (size.LE.ithval) THEN
611 j = SIZE
612 k = 1
613 ELSE
614 j = size/ithval
615 k = ithval
616 END IF
617
618 DO 20 i = 1,j
619 work(i+inde) = s((i-1)*k+1)
620 work(i+indd2) = s((i-1)*k+1)
621 20 CONTINUE
622
623 CALL dgamn2d(desca(ctxt_),'a',' ',j,1,work(1+inde),j,1,1,-1,-1,0)
624 CALL dgamx2d(desca(ctxt_),'a',' ',j,1,work(1+indd2),j,1,1,-1,-1,0)
625
626 DO 30 i = 1,j
627 IF ((work(i+inde)-work(i+indd2)).NE.zero) THEN
628 info = SIZE + 1
629 END IF
630 30 CONTINUE
631
632 40 CONTINUE
633
634 CALL blacs_gridexit(contextc)
635 CALL blacs_gridexit(contextr)
636
637
638
639 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 numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, nextra, ex, expos, info)
subroutine pdlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
double precision function pdlamch(ictxt, cmach)
subroutine pdgebrd(m, n, a, ia, ja, desca, d, e, tauq, taup, work, lwork, info)
double precision function pdlange(norm, m, n, a, ia, ja, desca, work)
subroutine pdlared1d(n, ia, ja, desc, bycol, byall, work, lwork)
subroutine pdlared2d(n, ia, ja, desc, byrow, byall, work, lwork)
subroutine pdlascl(type, cfrom, cto, m, n, a, ia, ja, desca, info)
subroutine pdormbr(vect, side, trans, m, n, k, a, ia, ja, desca, tau, c, ic, jc, descc, work, lwork, info)
subroutine pxerbla(ictxt, srname, info)
double precision function pzlange(norm, m, n, a, ia, ja, desca, work)