3
4
5
6
7
8
9
10 INTEGER IA, IASEED, IZ, JA, JZ, N
11 DOUBLE PRECISION ANORM, FRESID
12
13
14 INTEGER DESCA( * ), DESCZ( * )
15 COMPLEX*16 A( * ), WORK( * ), Z( * )
16
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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
155 $ LLD_, MB_, M_, NB_, N_, RSRC_
156 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
157 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
158 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
159 COMPLEX*16 ONE, ZERO
160 parameter( one = ( 1.0d+0, 0.0d+0 ),
161 $ zero = ( 0.0d+0, 0.0d+0 ) )
162
163
164 INTEGER I, IACOL, IAROW, IB, ICTXT, IIA, IOFFA, IROFF,
165 $ IW, J, JB, JJA, JN, LDA, LDW, MYCOL, MYROW, NP,
166 $ NPCOL, NPROW
167 DOUBLE PRECISION EPS
168
169
170 INTEGER DESCW( DLEN_ )
171
172
175
176
177 INTEGER ICEIL, NUMROC
178 DOUBLE PRECISION PDLAMCH, PZLANGE
180
181
183
184
185
186 ictxt = desca( ctxt_ )
187 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
189
190 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
191 $ iarow, iacol )
192 iroff = mod( ia-1, desca( mb_ ) )
193 np =
numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
194 IF( myrow.EQ.iarow )
195 $ np = np - iroff
197
198
199
200 CALL descset( descw, desca( mb_ ), n, desca( mb_ ), desca( nb_ ),
201 $ iarow, iacol, ictxt, desca( mb_ ) )
202
203 DO 10 i = ia, ia + n - 1, desca( mb_ )
204 ib =
min( ia+n-i, desca( mb_ ) )
205
206 CALL pzlacpy(
'All', ib, n, a, i, ja, desca, work, 1, 1,
207 $ descw )
208 CALL pzgemm( 'No transpose', 'Cong Tran', ib, n, n, one, work,
209 $ 1, 1, descw, z, iz, jz, descz, zero, a, i, ja,
210 $ desca )
211
212 descw( rsrc_ ) = mod( descw( rsrc_ )+1, nprow )
213
214 10 CONTINUE
215
216
217
218 CALL descset( descw, n, desca( nb_ ), desca( mb_ ), desca( nb_ ),
219 $ iarow, iacol, ictxt, ldw )
220
221 DO 20 j = ja, ja + n - 1, desca( nb_ )
222 jb =
min( ja+n-j, desca( nb_ ) )
223
224 CALL pzlacpy(
'All', n, jb, a, ia, j, desca, work, 1, 1,
225 $ descw )
226 CALL pzgemm( 'No transpose', 'No transpose', n, jb, n, one, z,
227 $ iz, jz, descz, work, 1, 1, descw, zero, a, ia, j,
228 $ desca )
229
230 descw( csrc_ ) = mod( descw( csrc_ )+1, npcol )
231
232 20 CONTINUE
233
234
235
236 jn =
min(
iceil( ja, desca( nb_ ) )*desca( nb_ ), ja+n-1 )
237 lda = desca( lld_ )
238 ioffa = iia + ( jja-1 )*lda
239 iw = 1
240 jb = jn - ja + 1
241 descw( csrc_ ) = iacol
242
243
244
245 IF( mycol.EQ.descw( csrc_ ) ) THEN
246 CALL pzmatgen( ictxt,
'N',
'N', desca( m_ ), desca( n_ ),
247 $ desca( mb_ ), desca( nb_ ), work, ldw,
248 $ desca( rsrc_ ), desca( csrc_ ), iaseed, iia-1,
249 $ np, jja-1, jb, myrow, mycol, nprow, npcol )
250 CALL pzlaset(
'Lower',
max( 0, n-2 ), jb, zero, zero, work,
251 $
min( iw+2, n ), 1, descw )
252 CALL zmatadd( np, jb, -one, work, ldw, one, a( ioffa ), lda )
253 jja = jja + jb
254 ioffa = ioffa + jb*lda
255 END IF
256
257 iw = iw + desca( mb_ )
258 descw( csrc_ ) = mod( descw( csrc_ )+1, npcol )
259
260 DO 30 j = jn + 1, ja + n - 1, desca( nb_ )
261 jb =
min( ja+n-j, desca( nb_ ) )
262
263 IF( mycol.EQ.descw( csrc_ ) ) THEN
264 CALL pzmatgen( ictxt,
'N',
'N', desca( m_ ), desca( n_ ),
265 $ desca( mb_ ), desca( nb_ ), work, ldw,
266 $ desca( rsrc_ ), desca( csrc_ ), iaseed,
267 $ iia-1, np, jja-1, jb, myrow, mycol, nprow,
268 $ npcol )
269 CALL pzlaset(
'Lower',
max( 0, n-iw-1 ), jb, zero, zero,
270 $ work,
min( n, iw+2 ), 1, descw )
271 CALL zmatadd( np, jb, -one, work, ldw, one, a( ioffa ),
272 $ lda )
273 jja = jja + jb
274 ioffa = ioffa + jb*lda
275 END IF
276 iw = iw + desca( mb_ )
277 descw( csrc_ ) = mod( descw( csrc_ )+1, npcol )
278 30 CONTINUE
279
280
281
282 fresid =
pzlange(
'I', n, n, a, ia, ja, desca, work ) /
283 $ ( n*eps*anorm )
284
285 RETURN
286
287
288
subroutine pzmatgen(ictxt, aform, diag, m, n, mb, nb, a, lda, iarow, iacol, iseed, iroff, irnum, icoff, icnum, myrow, mycol, nprow, npcol)
subroutine descset(desc, m, n, mb, nb, irsrc, icsrc, ictxt, lld)
integer function iceil(inum, idenom)
subroutine infog2l(grindx, gcindx, desc, nprow, npcol, myrow, mycol, lrindx, lcindx, rsrc, csrc)
integer function numroc(n, nb, iproc, isrcproc, nprocs)
double precision function pdlamch(ictxt, cmach)
subroutine pzlaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
subroutine pzlacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
double precision function pzlange(norm, m, n, a, ia, ja, desca, work)
subroutine zmatadd(m, n, alpha, a, lda, beta, c, ldc)