3
4
5
6
7
8
9
10 INTEGER IA, IASEED, IZ, JA, JZ, N
11 REAL ANORM, FRESID
12
13
14 INTEGER DESCA( * ), DESCZ( * )
15 REAL 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 INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
150 $ LLD_, MB_, M_, NB_, N_, RSRC_
151 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
152 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
153 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
154 REAL ONE, ZERO
155 parameter( one = 1.0e+0, zero = 0.0e+0 )
156
157
158 INTEGER I, IACOL, IAROW, IB, ICTXT, IIA, IOFFA, IROFF,
159 $ IW, J, JB, JJA, JN, LDA, LDW, MYCOL, MYROW, NP,
160 $ NPCOL, NPROW
161 REAL EPS
162
163
164 INTEGER DESCW( DLEN_ )
165
166
169
170
171 INTEGER ICEIL, NUMROC
172 REAL PSLAMCH, PSLANGE
174
175
177
178
179
180 ictxt = desca( ctxt_ )
181 CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
183
184 CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
185 $ iarow, iacol )
186 iroff = mod( ia-1, desca( mb_ ) )
187 np =
numroc( n+iroff, desca( mb_ ), myrow, iarow, nprow )
188 IF( myrow.EQ.iarow )
189 $ np = np - iroff
191
192
193
194 CALL descset( descw, desca( mb_ ), n, desca( mb_ ), desca( nb_ ),
195 $ iarow, iacol, ictxt, desca( mb_ ) )
196
197 DO 10 i = ia, ia + n - 1, desca( mb_ )
198 ib =
min( ia+n-i, desca( mb_ ) )
199
200 CALL pslacpy(
'All', ib, n, a, i, ja, desca, work, 1, 1,
201 $ descw )
202 CALL psgemm( 'No transpose', 'Transpose', ib, n, n, one, work,
203 $ 1, 1, descw, z, iz, jz, descz, zero, a, i, ja,
204 $ desca )
205
206 descw( rsrc_ ) = mod( descw( rsrc_ )+1, nprow )
207
208 10 CONTINUE
209
210
211
212 CALL descset( descw, n, desca( nb_ ), desca( mb_ ), desca( nb_ ),
213 $ iarow, iacol, ictxt, ldw )
214
215 DO 20 j = ja, ja + n - 1, desca( nb_ )
216 jb =
min( ja+n-j, desca( nb_ ) )
217
218 CALL pslacpy(
'All', n, jb, a, ia, j, desca, work, 1, 1,
219 $ descw )
220 CALL psgemm( 'No transpose', 'No transpose', n, jb, n, one, z,
221 $ iz, jz, descz, work, 1, 1, descw, zero, a, ia, j,
222 $ desca )
223
224 descw( csrc_ ) = mod( descw( csrc_ )+1, npcol )
225
226 20 CONTINUE
227
228
229
230 jn =
min(
iceil( ja, desca( nb_ ) )*desca( nb_ ), ja+n-1 )
231 lda = desca( lld_ )
232 ioffa = iia + ( jja-1 )*lda
233 iw = 1
234 jb = jn - ja + 1
235 descw( csrc_ ) = iacol
236
237
238
239 IF( mycol.EQ.descw( csrc_ ) ) THEN
240 CALL psmatgen( ictxt,
'N',
'N', desca( m_ ), desca( n_ ),
241 $ desca( mb_ ), desca( nb_ ), work, ldw,
242 $ desca( rsrc_ ), desca( csrc_ ), iaseed, iia-1,
243 $ np, jja-1, jb, myrow, mycol, nprow, npcol )
244 CALL pslaset(
'Lower',
max( 0, n-2 ), jb, zero, zero, work,
245 $
min( iw+2, n ), 1, descw )
246 CALL smatadd( np, jb, -one, work, ldw, one, a( ioffa ), lda )
247 jja = jja + jb
248 ioffa = ioffa + jb*lda
249 END IF
250
251 iw = iw + desca( mb_ )
252 descw( csrc_ ) = mod( descw( csrc_ )+1, npcol )
253
254 DO 30 j = jn + 1, ja + n - 1, desca( nb_ )
255 jb =
min( ja+n-j, desca( nb_ ) )
256
257 IF( mycol.EQ.descw( csrc_ ) ) THEN
258 CALL psmatgen( ictxt,
'N',
'N', desca( m_ ), desca( n_ ),
259 $ desca( mb_ ), desca( nb_ ), work, ldw,
260 $ desca( rsrc_ ), desca( csrc_ ), iaseed,
261 $ iia-1, np, jja-1, jb, myrow, mycol, nprow,
262 $ npcol )
263 CALL pslaset(
'Lower',
max( 0, n-iw-1 ), jb, zero, zero,
264 $ work,
min( n, iw+2 ), 1, descw )
265 CALL smatadd( np, jb, -one, work, ldw, one, a( ioffa ),
266 $ lda )
267 jja = jja + jb
268 ioffa = ioffa + jb*lda
269 END IF
270 iw = iw + desca( mb_ )
271 descw( csrc_ ) = mod( descw( csrc_ )+1, npcol )
272 30 CONTINUE
273
274
275
276 fresid =
pslange(
'I', n, n, a, ia, ja, desca, work ) /
277 $ ( n*eps*anorm )
278
279 RETURN
280
281
282
subroutine psmatgen(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)
real function pslamch(ictxt, cmach)
subroutine pslaset(uplo, m, n, alpha, beta, a, ia, ja, desca)
subroutine pslacpy(uplo, m, n, a, ia, ja, desca, b, ib, jb, descb)
real function pslange(norm, m, n, a, ia, ja, desca, work)
subroutine smatadd(m, n, alpha, a, lda, beta, c, ldc)