6
7
8
9
10
11
12 INTEGER IA, IC, IQ, JA, JC, JQ, LWORK, MS, NV, RESULT
13 DOUBLE PRECISION EPSNORMA, THRESH, TSTNRM
14
15
16
17 INTEGER DESCA( * ), DESCC( * ), DESCQ( * )
18 DOUBLE PRECISION A( * ), C( * ), Q( * ), W( * ), WORK( * )
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 INTEGER INFO, J, LOCALCOL, MP, MYCOL, MYROW, NPCOL,
183 $ NPROW, NQ, PCOL
184 DOUBLE PRECISION NORM
185
186
187 INTEGER BLOCK_CYCLIC_2D, DLEN_, DTYPE_, CTXT_, M_, N_,
188 $ MB_, NB_, RSRC_, CSRC_, LLD_
189 parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
190 $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
191 $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
192 DOUBLE PRECISION ONE, NEGONE
193 parameter( one = 1.0d+0, negone = -1.0d+0 )
194
195
196 INTEGER INDXG2L, INDXG2P, NUMROC
197 DOUBLE PRECISION PDLANGE
199
200
201 EXTERNAL blacs_gridinfo,
chk1mat, dlacpy, dscal, pdgemm,
203
204
206
207
208
209 IF( block_cyclic_2d*csrc_*ctxt_*dlen_*dtype_*lld_*mb_*m_*nb_*n_*
210 $ rsrc_.LT.0 )RETURN
211
212 result = 0
213
214 CALL blacs_gridinfo( desca( ctxt_ ), nprow, npcol, myrow, mycol )
215
216 info = 0
217 CALL chk1mat( ms, 1, ms, 1, ia, ja, desca, 6, info )
218 CALL chk1mat( ms, 1, nv, 2, iq, jq, descq, 12, info )
219 CALL chk1mat( ms, 1, nv, 2, ic, jc, descc, 16, info )
220
221 IF( info.EQ.0 ) THEN
222
223 mp =
numroc( ms, desca( mb_ ), myrow, 0, nprow )
224 nq =
numroc( nv, desca( nb_ ), mycol, 0, npcol )
225
226 IF( iq.NE.1 ) THEN
227 info = -10
228 ELSE IF( jq.NE.1 ) THEN
229 info = -11
230 ELSE IF( ia.NE.1 ) THEN
231 info = -4
232 ELSE IF( ja.NE.1 ) THEN
233 info = -5
234 ELSE IF( ic.NE.1 ) THEN
235 info = -14
236 ELSE IF( jc.NE.1 ) THEN
237 info = -15
238 ELSE IF( lwork.LT.nq ) THEN
239 info = -19
240 END IF
241 END IF
242
243 IF( info.NE.0 ) THEN
244 CALL pxerbla( desca( ctxt_ ),
'PDSEPCHK', -info )
245 RETURN
246 END IF
247
248
249
250 CALL dlacpy( 'A', mp, nq, q, descq( lld_ ), c, descc( lld_ ) )
251
252
253 DO 10 j = 1, nv
254 pcol =
indxg2p( j, descc( nb_ ), 0, 0, npcol )
255 localcol =
indxg2l( j, descc( nb_ ), 0, 0, npcol )
256
257 IF( mycol.EQ.pcol ) THEN
258 CALL dscal( mp, w( j ), c( ( localcol-1 )*descc( lld_ )+1 ),
259 $ 1 )
260 END IF
261 10 CONTINUE
262
263
264
265
266 CALL pdgemm( 'N', 'N', ms, nv, ms, negone, a, 1, 1, desca, q, 1,
267 $ 1, descq, one, c, 1, 1, descc )
268
269
270
271
272 norm =
pdlange(
'M', ms, nv, c, 1, 1, descc, work )
273
274
275 tstnrm = norm / epsnorma /
max( ms, 1 )
276
277 IF( tstnrm.GT.thresh .OR. ( tstnrm-tstnrm.NE.0.0d0 ) ) THEN
278 result = 1
279 END IF
280
281
282 RETURN
283
284
285
subroutine chk1mat(ma, mapos0, na, napos0, ia, ja, desca, descapos0, 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)
double precision function pdlange(norm, m, n, a, ia, ja, desca, work)
subroutine pxerbla(ictxt, srname, info)