73 std::cout <<
GridLogMessage<<
"HDCG: fPcg starting single RHS"<<std::endl;
83 std::vector<Field> p(mmax,
grid);
84 std::vector<Field> mmp(mmax,
grid);
85 std::vector<RealD> pAp(mmax);
95 std::cout <<
GridLogMessage<<
"HDCG: fPcg guess nrm "<<guess<<std::endl;
97 std::cout <<
GridLogMessage<<
"HDCG: fPcg src nrm "<<src_nrm<<std::endl;
99 if ( src_nrm == 0.0 ) {
100 std::cout <<
GridLogMessage<<
"HDCG: fPcg given trivial source norm "<<src_nrm<<std::endl;
114 axpy (r, -1.0,mmp[0], src);
116 double n1 =
norm2(x);
117 double n2 =
norm2(mmp[0]);
118 double n3 =
norm2(r);
119 std::cout<<
GridLogMessage<<
"x,vstart,r = "<<n1<<
" "<<n2<<
" "<<n3<<std::endl;
138 std::cout <<
GridLogMessage<<
"HDCG: k=0 residual "<<rtzp<<
" rsq "<<rsq<<
"\n";
144 int peri_k = k % mmax;
145 int peri_kp = (k+1) % mmax;
148 d=
PcgM3(p[peri_k],mmp[peri_k]);
154 axpy(x,a,p[peri_k],x);
164 std::cout <<
GridLogMessage<<
"HDCG::fPcg iteration "<<k<<
" : vector r,z "<<n1<<
" "<<n2<<
"\n";
167 std::cout <<
GridLogMessage<<
"HDCG::fPcg iteration "<<k<<
" : inner rtzp "<<rtzp<<
"\n";
185 northog = (k>mmax-1)?(mmax-1):k;
187 std::cout<<
GridLogMessage<<
"HDCG::fPcg iteration "<<k<<
" : orthogonalising to last "<<northog<<
" vectors\n";
188 for(
int back=0; back < northog; back++){
189 int peri_back = (k-back)%mmax;
191 RealD beta = -pbApk/pAp[peri_back];
192 axpy(p[peri_kp],beta,p[peri_back],p[peri_kp]);
199 std::cout<<
GridLogMessage<<
"HDCG: fPcg k= "<<k<<
" residual = "<<rrn<<
"\n";
205 std::cout<<
GridLogMessage<<
"HDCG: fPcg converged in "<<k<<
" iterations and "<<HDCGTimer.
Elapsed()<<std::endl;;
208 axpy(tmp,-1.0,src,mmp[0]);
214 RealD true_residual = tmpnorm/srcnorm;
216 <<
"HDCG: true residual is "<<true_residual
217 <<
" solution "<<xnorm
218 <<
" source "<<srcnorm
230 std::cout<<
GridLogMessage<<
"HDCG: non-converged solution "<<xnorm<<
" source "<<srcnorm<<std::endl;
235 virtual void operator() (std::vector<Field> &src, std::vector<Field> &x)
237 std::cout <<
GridLogMessage<<
"HDCG: mrhs fPcg starting"<<std::endl;
238 src[0].Grid()->Barrier();
239 int nrhs = src.size();
240 std::vector<RealD> f(nrhs);
241 std::vector<RealD> rtzp(nrhs);
242 std::vector<RealD> rtz(nrhs);
243 std::vector<RealD> a(nrhs);
244 std::vector<RealD> d(nrhs);
245 std::vector<RealD> b(nrhs);
246 std::vector<RealD> rptzp(nrhs);
252 src[0].Grid()->Barrier();
253 std::vector<std::vector<Field> > p(nrhs);
for(
int r=0;r<nrhs;r++) p[r].resize(mmax,
grid);
255 src[0].Grid()->Barrier();
256 std::vector<std::vector<Field> > mmp(nrhs);
for(
int r=0;r<nrhs;r++) mmp[r].resize(mmax,
grid);
257 std::cout <<
GridLogMessage<<
"HDCG: fPcg allocated mmp"<<std::endl;
258 src[0].Grid()->Barrier();
259 std::vector<std::vector<RealD> > pAp(nrhs);
for(
int r=0;r<nrhs;r++) pAp[r].resize(mmax);
260 std::cout <<
GridLogMessage<<
"HDCG: fPcg allocated pAp"<<std::endl;
261 src[0].Grid()->Barrier();
262 std::vector<Field> z(nrhs,
grid);
263 std::vector<Field> mp (nrhs,
grid);
264 std::vector<Field> r (nrhs,
grid);
265 std::vector<Field> mu (nrhs,
grid);
266 std::cout <<
GridLogMessage<<
"HDCG: fPcg allocated z,mp,r,mu"<<std::endl;
267 src[0].Grid()->Barrier();
270 std::vector<RealD> src_nrm(nrhs);
271 for(
int rhs=0;rhs<nrhs;rhs++) {
272 src_nrm[rhs]=
norm2(src[rhs]);
273 assert(src_nrm[rhs]!=0.0);
275 std::vector<RealD> tn(nrhs);
284 for(
int rhs=0;rhs<nrhs;rhs++){
287 axpy (r[rhs], -1.0,mmp[rhs][0], src[rhs]);
296 std::vector<RealD> ssq(nrhs);
297 std::vector<RealD> rsq(nrhs);
298 std::vector<Field> pp(nrhs,
grid);
300 for(
int rhs=0;rhs<nrhs;rhs++){
303 ssq[rhs]=
norm2(src[rhs]);
305 std::cout <<
GridLogMessage<<
"mrhs HDCG: "<<rhs<<
" k=0 residual "<<rtzp[rhs]<<
" rsq "<<rsq[rhs]<<
"\n";
308 std::vector<RealD> rn(nrhs);
311 int peri_k = k % mmax;
312 int peri_kp = (k+1) % mmax;
314 for(
int rhs=0;rhs<nrhs;rhs++){
316 d[rhs]=
PcgM3(p[rhs][peri_k],mmp[rhs][peri_k]);
317 a[rhs] = rtz[rhs]/d[rhs];
320 pAp[rhs][peri_k] = d[rhs];
322 axpy(x[rhs],a[rhs],p[rhs][peri_k],x[rhs]);
323 rn[rhs] =
axpy_norm(r[rhs],-a[rhs],mmp[rhs][peri_k],r[rhs]);
332 for(
int rhs=0;rhs<nrhs;rhs++){
336 std::cout <<
GridLogMessage<<
"HDCG::fPcg rhs"<<rhs<<
" iteration "<<k<<
" : inner rtzp "<<rtzp[rhs]<<
"\n";
340 p[rhs][peri_kp]=mu[rhs];
343 b[rhs] = (rtzp[rhs])/rtz[rhs];
345 int northog = (k>mmax-1)?(mmax-1):k;
346 std::cout<<
GridLogMessage<<
"HDCG::fPcg iteration "<<k<<
" : orthogonalising to last "<<northog<<
" vectors\n";
347 for(
int back=0; back < northog; back++){
348 int peri_back = (k-back)%mmax;
350 RealD beta = -pbApk/pAp[rhs][peri_back];
351 axpy(p[rhs][peri_kp],beta,p[rhs][peri_back],p[rhs][peri_kp]);
358 std::cout<<
GridLogMessage<<
"HDCG: rhs "<<rhs<<
"fPcg k= "<<k<<
" residual = "<<rrn<<
"\n";
359 if ( rrn > max_rn ) max_rn = rrn;
366 std::cout<<
GridLogMessage<<
"HDCG: mrhs fPcg converged in "<<k<<
" iterations and "<<HDCGTimer.
Elapsed()<<std::endl;;
368 for(
int rhs=0;rhs<nrhs;rhs++){
371 axpy(tmp,-1.0,src[rhs],mmp[rhs][0]);
377 RealD true_residual = tmpnorm/srcnorm;
379 <<
"HDCG: true residual ["<<rhs<<
"] is "<<true_residual
380 <<
" solution "<<xnorm
381 <<
" source "<<srcnorm
391 for(
int rhs=0;rhs<nrhs;rhs++){
394 std::cout<<
GridLogMessage<<
"HDCG: non-converged solution "<<xnorm<<
" source "<<srcnorm<<std::endl;