mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-10 07:55:35 +00:00
Namespace, indent, tidy
This commit is contained in:
parent
f8cb46d360
commit
695af98a1d
@ -1,4 +1,4 @@
|
|||||||
/*************************************************************************************
|
/*************************************************************************************
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
@ -23,132 +23,134 @@ Author: Christopher Kelly <ckelly@phys.columbia.edu>
|
|||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
See the full license in the file "LICENSE" in the top level distribution directory
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
*************************************************************************************/
|
*************************************************************************************/
|
||||||
/* END LEGAL */
|
/* END LEGAL */
|
||||||
#ifndef GRID_CONJUGATE_GRADIENT_MIXED_PREC_H
|
#ifndef GRID_CONJUGATE_GRADIENT_MIXED_PREC_H
|
||||||
#define GRID_CONJUGATE_GRADIENT_MIXED_PREC_H
|
#define GRID_CONJUGATE_GRADIENT_MIXED_PREC_H
|
||||||
|
|
||||||
namespace Grid {
|
NAMESPACE_BEGIN(Grid);
|
||||||
|
|
||||||
//Mixed precision restarted defect correction CG
|
//Mixed precision restarted defect correction CG
|
||||||
template<class FieldD,class FieldF, typename std::enable_if< getPrecision<FieldD>::value == 2, int>::type = 0,typename std::enable_if< getPrecision<FieldF>::value == 1, int>::type = 0>
|
template<class FieldD,class FieldF,
|
||||||
class MixedPrecisionConjugateGradient : public LinearFunction<FieldD> {
|
typename std::enable_if< getPrecision<FieldD>::value == 2, int>::type = 0,
|
||||||
public:
|
typename std::enable_if< getPrecision<FieldF>::value == 1, int>::type = 0>
|
||||||
RealD Tolerance;
|
class MixedPrecisionConjugateGradient : public LinearFunction<FieldD> {
|
||||||
RealD InnerTolerance; //Initial tolerance for inner CG. Defaults to Tolerance but can be changed
|
public:
|
||||||
Integer MaxInnerIterations;
|
RealD Tolerance;
|
||||||
Integer MaxOuterIterations;
|
RealD InnerTolerance; //Initial tolerance for inner CG. Defaults to Tolerance but can be changed
|
||||||
GridBase* SinglePrecGrid; //Grid for single-precision fields
|
Integer MaxInnerIterations;
|
||||||
RealD OuterLoopNormMult; //Stop the outer loop and move to a final double prec solve when the residual is OuterLoopNormMult * Tolerance
|
Integer MaxOuterIterations;
|
||||||
LinearOperatorBase<FieldF> &Linop_f;
|
GridBase* SinglePrecGrid; //Grid for single-precision fields
|
||||||
LinearOperatorBase<FieldD> &Linop_d;
|
RealD OuterLoopNormMult; //Stop the outer loop and move to a final double prec solve when the residual is OuterLoopNormMult * Tolerance
|
||||||
|
LinearOperatorBase<FieldF> &Linop_f;
|
||||||
|
LinearOperatorBase<FieldD> &Linop_d;
|
||||||
|
|
||||||
Integer TotalInnerIterations; //Number of inner CG iterations
|
Integer TotalInnerIterations; //Number of inner CG iterations
|
||||||
Integer TotalOuterIterations; //Number of restarts
|
Integer TotalOuterIterations; //Number of restarts
|
||||||
Integer TotalFinalStepIterations; //Number of CG iterations in final patch-up step
|
Integer TotalFinalStepIterations; //Number of CG iterations in final patch-up step
|
||||||
|
|
||||||
//Option to speed up *inner single precision* solves using a LinearFunction that produces a guess
|
//Option to speed up *inner single precision* solves using a LinearFunction that produces a guess
|
||||||
LinearFunction<FieldF> *guesser;
|
LinearFunction<FieldF> *guesser;
|
||||||
|
|
||||||
MixedPrecisionConjugateGradient(RealD tol, Integer maxinnerit, Integer maxouterit, GridBase* _sp_grid, LinearOperatorBase<FieldF> &_Linop_f, LinearOperatorBase<FieldD> &_Linop_d) :
|
MixedPrecisionConjugateGradient(RealD tol, Integer maxinnerit, Integer maxouterit, GridBase* _sp_grid, LinearOperatorBase<FieldF> &_Linop_f, LinearOperatorBase<FieldD> &_Linop_d) :
|
||||||
Linop_f(_Linop_f), Linop_d(_Linop_d),
|
Linop_f(_Linop_f), Linop_d(_Linop_d),
|
||||||
Tolerance(tol), InnerTolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid),
|
Tolerance(tol), InnerTolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid),
|
||||||
OuterLoopNormMult(100.), guesser(NULL){ };
|
OuterLoopNormMult(100.), guesser(NULL){ };
|
||||||
|
|
||||||
void useGuesser(LinearFunction<FieldF> &g){
|
void useGuesser(LinearFunction<FieldF> &g){
|
||||||
guesser = &g;
|
guesser = &g;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator() (const FieldD &src_d_in, FieldD &sol_d){
|
void operator() (const FieldD &src_d_in, FieldD &sol_d){
|
||||||
TotalInnerIterations = 0;
|
TotalInnerIterations = 0;
|
||||||
|
|
||||||
GridStopWatch TotalTimer;
|
GridStopWatch TotalTimer;
|
||||||
TotalTimer.Start();
|
TotalTimer.Start();
|
||||||
|
|
||||||
int cb = src_d_in.checkerboard;
|
int cb = src_d_in.checkerboard;
|
||||||
sol_d.checkerboard = cb;
|
sol_d.checkerboard = cb;
|
||||||
|
|
||||||
RealD src_norm = norm2(src_d_in);
|
RealD src_norm = norm2(src_d_in);
|
||||||
RealD stop = src_norm * Tolerance*Tolerance;
|
RealD stop = src_norm * Tolerance*Tolerance;
|
||||||
|
|
||||||
GridBase* DoublePrecGrid = src_d_in._grid;
|
GridBase* DoublePrecGrid = src_d_in._grid;
|
||||||
FieldD tmp_d(DoublePrecGrid);
|
FieldD tmp_d(DoublePrecGrid);
|
||||||
tmp_d.checkerboard = cb;
|
tmp_d.checkerboard = cb;
|
||||||
|
|
||||||
FieldD tmp2_d(DoublePrecGrid);
|
FieldD tmp2_d(DoublePrecGrid);
|
||||||
tmp2_d.checkerboard = cb;
|
tmp2_d.checkerboard = cb;
|
||||||
|
|
||||||
FieldD src_d(DoublePrecGrid);
|
FieldD src_d(DoublePrecGrid);
|
||||||
src_d = src_d_in; //source for next inner iteration, computed from residual during operation
|
src_d = src_d_in; //source for next inner iteration, computed from residual during operation
|
||||||
|
|
||||||
RealD inner_tol = InnerTolerance;
|
RealD inner_tol = InnerTolerance;
|
||||||
|
|
||||||
FieldF src_f(SinglePrecGrid);
|
FieldF src_f(SinglePrecGrid);
|
||||||
src_f.checkerboard = cb;
|
src_f.checkerboard = cb;
|
||||||
|
|
||||||
FieldF sol_f(SinglePrecGrid);
|
FieldF sol_f(SinglePrecGrid);
|
||||||
sol_f.checkerboard = cb;
|
sol_f.checkerboard = cb;
|
||||||
|
|
||||||
ConjugateGradient<FieldF> CG_f(inner_tol, MaxInnerIterations);
|
ConjugateGradient<FieldF> CG_f(inner_tol, MaxInnerIterations);
|
||||||
CG_f.ErrorOnNoConverge = false;
|
CG_f.ErrorOnNoConverge = false;
|
||||||
|
|
||||||
GridStopWatch InnerCGtimer;
|
GridStopWatch InnerCGtimer;
|
||||||
|
|
||||||
GridStopWatch PrecChangeTimer;
|
GridStopWatch PrecChangeTimer;
|
||||||
|
|
||||||
Integer &outer_iter = TotalOuterIterations; //so it will be equal to the final iteration count
|
Integer &outer_iter = TotalOuterIterations; //so it will be equal to the final iteration count
|
||||||
|
|
||||||
for(outer_iter = 0; outer_iter < MaxOuterIterations; outer_iter++){
|
for(outer_iter = 0; outer_iter < MaxOuterIterations; outer_iter++){
|
||||||
//Compute double precision rsd and also new RHS vector.
|
//Compute double precision rsd and also new RHS vector.
|
||||||
Linop_d.HermOp(sol_d, tmp_d);
|
Linop_d.HermOp(sol_d, tmp_d);
|
||||||
RealD norm = axpy_norm(src_d, -1., tmp_d, src_d_in); //src_d is residual vector
|
RealD norm = axpy_norm(src_d, -1., tmp_d, src_d_in); //src_d is residual vector
|
||||||
|
|
||||||
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Outer iteration " <<outer_iter<<" residual "<< norm<< " target "<< stop<<std::endl;
|
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Outer iteration " <<outer_iter<<" residual "<< norm<< " target "<< stop<<std::endl;
|
||||||
|
|
||||||
if(norm < OuterLoopNormMult * stop){
|
if(norm < OuterLoopNormMult * stop){
|
||||||
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Outer iteration converged on iteration " <<outer_iter <<std::endl;
|
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Outer iteration converged on iteration " <<outer_iter <<std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
while(norm * inner_tol * inner_tol < stop) inner_tol *= 2; // inner_tol = sqrt(stop/norm) ??
|
|
||||||
|
|
||||||
PrecChangeTimer.Start();
|
|
||||||
precisionChange(src_f, src_d);
|
|
||||||
PrecChangeTimer.Stop();
|
|
||||||
|
|
||||||
zeroit(sol_f);
|
|
||||||
|
|
||||||
//Optionally improve inner solver guess (eg using known eigenvectors)
|
|
||||||
if(guesser != NULL)
|
|
||||||
(*guesser)(src_f, sol_f);
|
|
||||||
|
|
||||||
//Inner CG
|
|
||||||
CG_f.Tolerance = inner_tol;
|
|
||||||
InnerCGtimer.Start();
|
|
||||||
CG_f(Linop_f, src_f, sol_f);
|
|
||||||
InnerCGtimer.Stop();
|
|
||||||
TotalInnerIterations += CG_f.IterationsToComplete;
|
|
||||||
|
|
||||||
//Convert sol back to double and add to double prec solution
|
|
||||||
PrecChangeTimer.Start();
|
|
||||||
precisionChange(tmp_d, sol_f);
|
|
||||||
PrecChangeTimer.Stop();
|
|
||||||
|
|
||||||
axpy(sol_d, 1.0, tmp_d, sol_d);
|
|
||||||
}
|
}
|
||||||
|
while(norm * inner_tol * inner_tol < stop) inner_tol *= 2; // inner_tol = sqrt(stop/norm) ??
|
||||||
|
|
||||||
//Final trial CG
|
PrecChangeTimer.Start();
|
||||||
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Starting final patch-up double-precision solve"<<std::endl;
|
precisionChange(src_f, src_d);
|
||||||
|
PrecChangeTimer.Stop();
|
||||||
|
|
||||||
ConjugateGradient<FieldD> CG_d(Tolerance, MaxInnerIterations);
|
zeroit(sol_f);
|
||||||
CG_d(Linop_d, src_d_in, sol_d);
|
|
||||||
TotalFinalStepIterations = CG_d.IterationsToComplete;
|
|
||||||
|
|
||||||
TotalTimer.Stop();
|
//Optionally improve inner solver guess (eg using known eigenvectors)
|
||||||
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Inner CG iterations " << TotalInnerIterations << " Restarts " << TotalOuterIterations << " Final CG iterations " << TotalFinalStepIterations << std::endl;
|
if(guesser != NULL)
|
||||||
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Total time " << TotalTimer.Elapsed() << " Precision change " << PrecChangeTimer.Elapsed() << " Inner CG total " << InnerCGtimer.Elapsed() << std::endl;
|
(*guesser)(src_f, sol_f);
|
||||||
|
|
||||||
|
//Inner CG
|
||||||
|
CG_f.Tolerance = inner_tol;
|
||||||
|
InnerCGtimer.Start();
|
||||||
|
CG_f(Linop_f, src_f, sol_f);
|
||||||
|
InnerCGtimer.Stop();
|
||||||
|
TotalInnerIterations += CG_f.IterationsToComplete;
|
||||||
|
|
||||||
|
//Convert sol back to double and add to double prec solution
|
||||||
|
PrecChangeTimer.Start();
|
||||||
|
precisionChange(tmp_d, sol_f);
|
||||||
|
PrecChangeTimer.Stop();
|
||||||
|
|
||||||
|
axpy(sol_d, 1.0, tmp_d, sol_d);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
}
|
//Final trial CG
|
||||||
|
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Starting final patch-up double-precision solve"<<std::endl;
|
||||||
|
|
||||||
|
ConjugateGradient<FieldD> CG_d(Tolerance, MaxInnerIterations);
|
||||||
|
CG_d(Linop_d, src_d_in, sol_d);
|
||||||
|
TotalFinalStepIterations = CG_d.IterationsToComplete;
|
||||||
|
|
||||||
|
TotalTimer.Stop();
|
||||||
|
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Inner CG iterations " << TotalInnerIterations << " Restarts " << TotalOuterIterations << " Final CG iterations " << TotalFinalStepIterations << std::endl;
|
||||||
|
std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Total time " << TotalTimer.Elapsed() << " Precision change " << PrecChangeTimer.Elapsed() << " Inner CG total " << InnerCGtimer.Elapsed() << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NAMESPACE_END(Grid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user