99 GRID_TRACE(
"ConjugateGradientMultiShiftMixedPrecCleanup");
100 GridBase *DoublePrecGrid = src_d.Grid();
105 int nshift =
shifts.order;
107 std::vector<RealD> &mass(
shifts.poles);
108 std::vector<RealD> &mresidual(
shifts.tolerances);
109 std::vector<RealD> alpha(nshift,1.0);
112 FieldD p_d(DoublePrecGrid);
116 FieldD tmp_d(DoublePrecGrid);
117 FieldD r_d(DoublePrecGrid);
119 FieldD mmp_d(DoublePrecGrid);
121 assert(psi_d.size()==nshift);
122 assert(mass.size()==nshift);
123 assert(mresidual.size()==nshift);
126 std::vector<RealD> bs(nshift);
127 std::vector<RealD> rsq(nshift);
128 std::vector<RealD> rsqf(nshift);
129 std::vector<std::array<RealD,2> > z(nshift);
130 std::vector<int> converged(nshift);
132 const int primary =0;
143 for(
int s=0;s<nshift;s++){
144 assert( mass[s]>= mass[primary] );
155 for(
int s=0;s<nshift;s++){
164 for(
int s=0;s<nshift;s++){
165 rsq[s] = cp * mresidual[s] * mresidual[s];
167 std::cout<<
GridLogMessage<<
"ConjugateGradientMultiShiftMixedPrecCleanup: shift "<< s <<
" target resid "<<rsq[s]<<std::endl;
177 Linop_f.HermOpAndNorm(p_f,mmp_f,d,qq);
180 tmp_d = tmp_d - mmp_d;
181 std::cout <<
" Testing operators match "<<
norm2(mmp_d)<<
" f "<<
norm2(mmp_f)<<
" diff "<<
norm2(tmp_d)<<std::endl;
184 axpy(mmp_d,mass[0],p_d,mmp_d);
195 for(
int s=1;s<nshift;s++){
197 z[s][iz] = 1.0/( 1.0 - b*(mass[s]-mass[0]));
205 for(
int s=0;s<nshift;s++) {
206 axpby(psi_d[s],0.,-bs[s]*alpha[s],src_d,src_d);
213 GridStopWatch AXPYTimer, ShiftTimer, QRTimer, MatrixTimer, SolverTimer, PrecChangeTimer, CleanupTimer;
227 PrecChangeTimer.
Start();
229 PrecChangeTimer.
Stop();
232 for(
int s=0;s<nshift;s++){
233 if ( ! converged[s] ) {
235 axpy(ps_f[s],a,ps_f[s],r_f);
237 RealD as =a *z[s][iz]*bs[s] /(z[s][1-iz]*b);
238 axpby(ps_f[s],z[s][iz],as,r_f,ps_f[s]);
245 PrecChangeTimer.
Start();
247 PrecChangeTimer.
Stop();
251 PrecChangeTimer.
Start();
253 PrecChangeTimer.
Stop();
256 axpy(mmp_d,mass[0],p_d,mmp_d);
267 for(
int s=1;s<nshift;s++){
269 RealD z0 = z[s][1-iz];
272 / (b*a*(z1-z0) + z1*bp*(1- (mass[s]-mass[0])*b));
273 bs[s] = b*z[s][iz]/z0;
280 for(
int s=0;s<nshift;s++){
282 if( (!converged[s]) ) {
283 axpy(psi_f[ss],-bs[s]*alpha[s],ps_f[s],psi_f[ss]);
290 int all_converged = 1;
291 for(
int s=0;s<nshift;s++){
293 if ( (!converged[s]) ){
296 RealD css = c * z[s][iz]* z[s][iz];
299 if ( ! converged[s] )
300 std::cout<<
GridLogMessage<<
"ConjugateGradientMultiShiftMixedPrecCleanup k="<<k<<
" Shift "<<s<<
" has converged"<<std::endl;
313 for(
int s=0;s<nshift;s++){
318 if ( all_converged ){
319 std::cout<<
GridLogMessage<<
"ConjugateGradientMultiShiftMixedPrecCleanup: All shifts have converged iteration "<<k<<std::endl;
320 std::cout<<
GridLogMessage<<
"ConjugateGradientMultiShiftMixedPrecCleanup: Checking solutions"<<std::endl;
322 std::cout<<
GridLogMessage<<
"ConjugateGradientMultiShiftMixedPrecCleanup: Not all shifts have converged iteration "<<k<<std::endl;
326 for(
int s=0; s < nshift; s++) {
328 axpy(tmp_d,mass[s],psi_d[s],mmp_d);
329 axpy(r_d,-alpha[s],src_d,tmp_d);
333 std::cout<<
GridLogMessage<<
"ConjugateGradientMultiShiftMixedPrecCleanup: shift["<<s<<
"] true residual "<<
TrueResidualShift[s] <<
" target " << mresidual[s] << std::endl;
337 CleanupTimer.
Start();
338 std::cout<<
GridLogMessage<<
"ConjugateGradientMultiShiftMixedPrecCleanup: performing cleanup step for shift " << s << std::endl;
352 std::cout <<
GridLogMessage <<
"ConjugateGradientMultiShiftMixedPrecCleanup: Time Breakdown for body"<<std::endl;
367 std::cout<<
GridLogMessage<<
"CG multi shift did not converge"<<std::endl;