3
4
5
6
7
8
9
10 CHARACTER UPLO
11 INTEGER IA, IB, IBTYPE, INFO, JA, JB, LWORK, N
12 REAL SCALE
13
14
15 INTEGER DESCA( * ), DESCB( * )
16 COMPLEX A( * ), B( * ), WORK( * )
17
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
202
203
204
205
206
207
208 COMPLEX ONEHALF, ONE, MONE
209 REAL RONE
210 parameter( onehalf = ( 0.5e0, 0.0e0 ),
211 $ one = ( 1.0e0, 0.0e0 ),
212 $ mone = ( -1.0e0, 0.0e0 ), rone = 1.0e0 )
213 INTEGER DLEN_, CTXT_, MB_, NB_, RSRC_, CSRC_, LLD_
214 parameter( dlen_ = 9, ctxt_ = 2, mb_ = 5, nb_ = 6,
215 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
216
217
218 LOGICAL LQUERY, UPPER
219 INTEGER I, IACOL, IAROW, IBCOL, IBROW, ICOFFA, ICOFFB,
220 $ ICTXT, INDAA, INDG, INDR, INDRT, IROFFA,
221 $ IROFFB, J, K, KB, LWMIN, LWOPT, MYCOL, MYROW,
222 $ NB, NP0, NPCOL, NPK, NPROW, NQ0, POSTK
223
224
225 INTEGER DESCAA( DLEN_ ), DESCG( DLEN_ ),
226 $ DESCR( DLEN_ ), DESCRT( DLEN_ ), IDUM1( 2 ),
227 $ IDUM2( 2 )
228
229
230 LOGICAL LSAME
231 INTEGER INDXG2P, NUMROC
233
234
238
239
241
242
243 ictxt = desca( ctxt_ )
244 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
245 scale = 1.0e0
246
247 nb = desca( mb_ )
248
249
250
251
252 info = 0
253 IF( nprow.EQ.-1 ) THEN
254 info = -( 700+ctxt_ )
255 ELSE
256 upper =
lsame( uplo,
'U' )
257 CALL chk1mat( n, 3, n, 3, ia, ja, desca, 7, info )
258 CALL chk1mat( n, 3, n, 3, ib, jb, descb, 11, info )
259 IF( info.EQ.0 ) THEN
260 iarow =
indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
261 $ nprow )
262 ibrow =
indxg2p( ib, descb( mb_ ), myrow, descb( rsrc_ ),
263 $ nprow )
264 iacol =
indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
265 $ npcol )
266 ibcol =
indxg2p( jb, descb( nb_ ), mycol, descb( csrc_ ),
267 $ npcol )
268 iroffa = mod( ia-1, desca( mb_ ) )
269 icoffa = mod( ja-1, desca( nb_ ) )
270 iroffb = mod( ib-1, descb( mb_ ) )
271 icoffb = mod( jb-1, descb( nb_ ) )
272 np0 =
numroc( n, nb, 0, 0, nprow )
273 nq0 =
numroc( n, nb, 0, 0, npcol )
274 lwmin =
max( nb*( np0+1 ), 3*nb )
275 IF( ibtype.EQ.1 .AND. .NOT.upper ) THEN
276 lwopt = 2*np0*nb + nq0*nb + nb*nb
277 ELSE
278 lwopt = lwmin
279 END IF
280 work( 1 ) =
cmplx( real( lwopt ) )
281 lquery = ( lwork.EQ.-1 )
282 IF( ibtype.LT.1 .OR. ibtype.GT.3 ) THEN
283 info = -1
284 ELSE IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
285 info = -2
286 ELSE IF( n.LT.0 ) THEN
287 info = -3
288 ELSE IF( iroffa.NE.0 ) THEN
289 info = -5
290 ELSE IF( icoffa.NE.0 ) THEN
291 info = -6
292 ELSE IF( desca( mb_ ).NE.desca( nb_ ) ) THEN
293 info = -( 700+nb_ )
294 ELSE IF( iroffb.NE.0 .OR. ibrow.NE.iarow ) THEN
295 info = -9
296 ELSE IF( icoffb.NE.0 .OR. ibcol.NE.iacol ) THEN
297 info = -10
298 ELSE IF( descb( mb_ ).NE.desca( mb_ ) ) THEN
299 info = -( 1100+mb_ )
300 ELSE IF( descb( nb_ ).NE.desca( nb_ ) ) THEN
301 info = -( 1100+nb_ )
302 ELSE IF( ictxt.NE.descb( ctxt_ ) ) THEN
303 info = -( 1100+ctxt_ )
304 ELSE IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
305 info = -13
306 END IF
307 END IF
308 idum1( 1 ) = ibtype
309 idum2( 1 ) = 1
310 IF( upper ) THEN
311 idum1( 2 ) = ichar( 'U' )
312 ELSE
313 idum1( 2 ) = ichar( 'L' )
314 END IF
315 idum2( 2 ) = 2
316 CALL pchk2mat( n, 3, n, 3, ia, ja, desca, 7, n, 3, n, 3, ib,
317 $ jb, descb, 11, 2, idum1, idum2, info )
318 END IF
319
320 IF( info.NE.0 ) THEN
321 CALL pxerbla( ictxt,
'PCHENGST', -info )
322 RETURN
323 ELSE IF( lquery ) THEN
324 RETURN
325 END IF
326
327
328
329 IF( n.EQ.0 )
330 $ RETURN
331
332
333 IF( ibtype.NE.1 .OR. upper .OR. lwork.LT.lwopt ) THEN
334 CALL pchegst( ibtype, uplo, n, a, ia, ja, desca, b, ib, jb,
335 $ descb, scale, info )
336 RETURN
337 END IF
338
339 CALL descset( descg, n, nb, nb, nb, iarow, iacol, ictxt, np0 )
340 CALL descset( descr, n, nb, nb, nb, iarow, iacol, ictxt, np0 )
341 CALL descset( descrt, nb, n, nb, nb, iarow, iacol, ictxt, nb )
342 CALL descset( descaa, nb, nb, nb, nb, iarow, iacol, ictxt, nb )
343
344 indg = 1
345 indr = indg + descg( lld_ )*nb
346 indaa = indr + descr( lld_ )*nb
347 indrt = indaa + descaa( lld_ )*nb
348
349 DO 30 k = 1, n, nb
350
351 kb =
min( n-k+1, nb )
352 postk = k + kb
353 npk = n - postk + 1
354
355
356 CALL pclacpy(
'A', n-postk+1, kb, b, postk+ib-1, k+jb-1, descb,
357 $ work( indg ), postk, 1, descg )
358 CALL pclacpy(
'A', n-postk+1, kb, a, postk+ia-1, k+ja-1, desca,
359 $ work( indr ), postk, 1, descr )
360 CALL pclacpy(
'A', kb, k-1, a, k+ia-1, ja, desca,
361 $ work( indrt ), 1, 1, descrt )
362
363 CALL pclacpy(
'L', kb, kb, a, k+ia-1, k+ja-1, desca,
364 $ work( indr ), k, 1, descr )
365 CALL pctrsm( 'Right', 'L', 'N', 'N', npk, kb, mone, b, k+ib-1,
366 $ k+jb-1, descb, work( indg ), postk, 1, descg )
367
368 CALL pchemm( 'Right', 'L', npk, kb, onehalf, a, k+ia-1, k+ja-1,
369 $ desca, work( indg ), postk, 1, descg, one,
370 $ work( indr ), postk, 1, descr )
371
372 CALL pcher2k( 'Lower', 'No T', npk, kb, one, work( indg ),
373 $ postk, 1, descg, work( indr ), postk, 1, descr,
374 $ rone, a, postk+ia-1, postk+ja-1, desca )
375
376 CALL pcgemm( 'No T', 'No Conj', npk, k-1, kb, one,
377 $ work( indg ), postk, 1, descg, work( indrt ), 1,
378 $ 1, descrt, one, a, postk+ia-1, ja, desca )
379
380 CALL pchemm( 'Right', 'L', npk, kb, one, work( indr ), k, 1,
381 $ descr, work( indg ), postk, 1, descg, one, a,
382 $ postk+ia-1, k+ja-1, desca )
383
384 CALL pctrsm( 'Left', 'Lower', 'No Conj', 'Non-unit', kb, k-1,
385 $ one, b, k+ib-1, k+jb-1, descb, a, k+ia-1, ja,
386 $ desca )
387
388 CALL pclacpy(
'L', kb, kb, a, k+ia-1, k+ja-1, desca,
389 $ work( indaa ), 1, 1, descaa )
390
391 IF( myrow.EQ.descaa( rsrc_ ) .AND. mycol.EQ.descaa( csrc_ ) )
392 $ THEN
393 DO 20 i = 1, kb
394 DO 10 j = 1, i
395 work( indaa+j-1+( i-1 )*descaa( lld_ ) )
396 $ = conjg( work( indaa+i-1+( j-1 )*descaa( lld_ ) ) )
397 10 CONTINUE
398 20 CONTINUE
399 END IF
400
401 CALL pctrsm( 'Left', 'Lower', 'No Conj', 'Non-unit', kb, kb,
402 $ one, b, k+ib-1, k+jb-1, descb, work( indaa ), 1,
403 $ 1, descaa )
404
405 CALL pctrsm( 'Right', 'Lower', 'Conj', 'Non-unit', kb, kb, one,
406 $ b, k+ib-1, k+jb-1, descb, work( indaa ), 1, 1,
407 $ descaa )
408
409 CALL pclacpy(
'L', kb, kb, work( indaa ), 1, 1, descaa, a,
410 $ k+ia-1, k+ja-1, desca )
411
412 CALL pctrsm( 'Right', 'Lower', 'Conj', 'Non-unit', npk, kb,
413 $ one, b, k+ib-1, k+jb-1, descb, a, postk+ia-1,
414 $ k+ja-1, desca )
415
416 descr( csrc_ ) = mod( descr( csrc_ )+1, npcol )
417 descg( csrc_ ) = mod( descg( csrc_ )+1, npcol )
418 descrt( rsrc_ ) = mod( descrt( rsrc_ )+1, nprow )
419 descaa( rsrc_ ) = mod( descaa( rsrc_ )+1, nprow )
420 descaa( csrc_ ) = mod( descaa( csrc_ )+1, npcol )
421 30 CONTINUE
422
423 work( 1 ) =
cmplx( real( lwopt ) )
424
425 RETURN
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, info)
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
integer function indxg2p(indxglob, nb, iproc, isrcproc, nprocs)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
subroutine pchegst(ibtype, uplo, n, a, ia, ja, desca, b, ib, jb, descb, scale, info)
subroutine pchk2mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, mb, mbpos0, nb, nbpos0, ib, jb, descb, descbpos0, nextra, ex, expos, info)
subroutine pclacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
subroutine pxerbla(ictxt, srname, info)