mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-14 01:35:36 +00:00
Import BiCGSTAB solvers and tests
This commit is contained in:
parent
b9b9fcbfa0
commit
4180a4a8a7
@ -41,11 +41,13 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
|
|
||||||
#include <Grid/algorithms/iterative/Deflation.h>
|
#include <Grid/algorithms/iterative/Deflation.h>
|
||||||
#include <Grid/algorithms/iterative/ConjugateGradient.h>
|
#include <Grid/algorithms/iterative/ConjugateGradient.h>
|
||||||
|
#include <Grid/algorithms/iterative/BiCGSTAB.h>
|
||||||
#include <Grid/algorithms/iterative/ConjugateResidual.h>
|
#include <Grid/algorithms/iterative/ConjugateResidual.h>
|
||||||
#include <Grid/algorithms/iterative/NormalEquations.h>
|
#include <Grid/algorithms/iterative/NormalEquations.h>
|
||||||
#include <Grid/algorithms/iterative/SchurRedBlack.h>
|
#include <Grid/algorithms/iterative/SchurRedBlack.h>
|
||||||
#include <Grid/algorithms/iterative/ConjugateGradientMultiShift.h>
|
#include <Grid/algorithms/iterative/ConjugateGradientMultiShift.h>
|
||||||
#include <Grid/algorithms/iterative/ConjugateGradientMixedPrec.h>
|
#include <Grid/algorithms/iterative/ConjugateGradientMixedPrec.h>
|
||||||
|
#include <Grid/algorithms/iterative/BiCGSTABMixedPrec.h>
|
||||||
#include <Grid/algorithms/iterative/BlockConjugateGradient.h>
|
#include <Grid/algorithms/iterative/BlockConjugateGradient.h>
|
||||||
#include <Grid/algorithms/iterative/ConjugateGradientReliableUpdate.h>
|
#include <Grid/algorithms/iterative/ConjugateGradientReliableUpdate.h>
|
||||||
#include <Grid/algorithms/iterative/MinimalResidual.h>
|
#include <Grid/algorithms/iterative/MinimalResidual.h>
|
||||||
|
@ -320,6 +320,138 @@ public:
|
|||||||
return axpy_norm(out,-1.0,tmp,in);
|
return axpy_norm(out,-1.0,tmp,in);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class Field>
|
||||||
|
class HermitianSchurOperatorBase : public LinearOperatorBase<Field>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual RealD Mpc (const Field& in, Field& out) = 0;
|
||||||
|
virtual RealD MpcDag (const Field& in, Field& out) = 0;
|
||||||
|
virtual void MpcDagMpc(const Field& in, Field& out, RealD& ni, RealD& no) {
|
||||||
|
Field tmp(in.Grid());
|
||||||
|
tmp.Checkerboard() = in.Checkerboard();
|
||||||
|
ni = Mpc(in,tmp);
|
||||||
|
no = MpcDag(tmp,out);
|
||||||
|
}
|
||||||
|
virtual void HermOpAndNorm(const Field& in, Field& out, RealD& n1, RealD& n2) {
|
||||||
|
out.Checkerboard() = in.Checkerboard();
|
||||||
|
|
||||||
|
Mpc(in, out);
|
||||||
|
|
||||||
|
ComplexD dot = innerProduct(in,out); n1 = real(dot);
|
||||||
|
n2 = norm2(out);
|
||||||
|
}
|
||||||
|
virtual void HermOp(const Field& in, Field& out) {
|
||||||
|
RealD n1, n2;
|
||||||
|
HermOpAndNorm(in, out, n1, n2);
|
||||||
|
}
|
||||||
|
void Op(const Field& in, Field& out) {
|
||||||
|
Mpc(in, out);
|
||||||
|
}
|
||||||
|
void AdjOp(const Field& in, Field& out) {
|
||||||
|
MpcDag(in, out);
|
||||||
|
}
|
||||||
|
// Support for coarsening to a multigrid
|
||||||
|
void OpDiag(const Field& in, Field& out) {
|
||||||
|
assert(0); // must coarsen the unpreconditioned system
|
||||||
|
}
|
||||||
|
void OpDir(const Field& in, Field& out, int dir, int disp) {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Matrix, class Field>
|
||||||
|
class HermitianSchurDiagMooeeOperator : public HermitianSchurOperatorBase<Field>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Matrix& _Mat;
|
||||||
|
HermitianSchurDiagMooeeOperator(Matrix& Mat): _Mat(Mat){};
|
||||||
|
virtual RealD Mpc(const Field& in, Field& out) {
|
||||||
|
Field tmp(in.Grid());
|
||||||
|
tmp.Checkerboard() = !in.Checkerboard();
|
||||||
|
|
||||||
|
_Mat.Meooe(in, tmp);
|
||||||
|
_Mat.MooeeInv(tmp, out);
|
||||||
|
_Mat.Meooe(out, tmp);
|
||||||
|
|
||||||
|
_Mat.Mooee(in, out);
|
||||||
|
|
||||||
|
return axpy_norm(out, -1.0, tmp, out);
|
||||||
|
}
|
||||||
|
virtual RealD MpcDag(const Field& in, Field& out) {
|
||||||
|
Field tmp(in.Grid());
|
||||||
|
|
||||||
|
_Mat.MeooeDag(in, tmp);
|
||||||
|
_Mat.MooeeInvDag(tmp, out);
|
||||||
|
_Mat.MeooeDag(out, tmp);
|
||||||
|
|
||||||
|
_Mat.MooeeDag(in, out);
|
||||||
|
|
||||||
|
return axpy_norm(out, -1.0, tmp, out);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Matrix,class Field>
|
||||||
|
class HermitianSchurDiagOneOperator : public HermitianSchurOperatorBase<Field>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Matrix &_Mat;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HermitianSchurDiagOneOperator (Matrix& Mat): _Mat(Mat){};
|
||||||
|
virtual RealD Mpc(const Field& in, Field& out) {
|
||||||
|
Field tmp(in.Grid());
|
||||||
|
|
||||||
|
_Mat.Meooe(in, out);
|
||||||
|
_Mat.MooeeInv(out, tmp);
|
||||||
|
_Mat.Meooe(tmp, out);
|
||||||
|
_Mat.MooeeInv(out, tmp);
|
||||||
|
|
||||||
|
return axpy_norm(out, -1.0, tmp, in);
|
||||||
|
}
|
||||||
|
virtual RealD MpcDag(const Field& in, Field& out) {
|
||||||
|
Field tmp(in.Grid());
|
||||||
|
|
||||||
|
_Mat.MooeeInvDag(in, out);
|
||||||
|
_Mat.MeooeDag(out, tmp);
|
||||||
|
_Mat.MooeeInvDag(tmp, out);
|
||||||
|
_Mat.MeooeDag(out, tmp);
|
||||||
|
|
||||||
|
return axpy_norm(out, -1.0, tmp, in);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Matrix, class Field>
|
||||||
|
class HermitianSchurDiagTwoOperator : public HermitianSchurOperatorBase<Field>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Matrix& _Mat;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HermitianSchurDiagTwoOperator(Matrix& Mat): _Mat(Mat){};
|
||||||
|
|
||||||
|
virtual RealD Mpc(const Field& in, Field& out) {
|
||||||
|
Field tmp(in.Grid());
|
||||||
|
|
||||||
|
_Mat.MooeeInv(in, out);
|
||||||
|
_Mat.Meooe(out, tmp);
|
||||||
|
_Mat.MooeeInv(tmp, out);
|
||||||
|
_Mat.Meooe(out, tmp);
|
||||||
|
|
||||||
|
return axpy_norm(out, -1.0, tmp, in);
|
||||||
|
}
|
||||||
|
virtual RealD MpcDag(const Field& in, Field& out) {
|
||||||
|
Field tmp(in.Grid());
|
||||||
|
|
||||||
|
_Mat.MeooeDag(in, out);
|
||||||
|
_Mat.MooeeInvDag(out, tmp);
|
||||||
|
_Mat.MeooeDag(tmp, out);
|
||||||
|
_Mat.MooeeInvDag(out, tmp);
|
||||||
|
|
||||||
|
return axpy_norm(out, -1.0, tmp, in);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Left handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) psi = eta --> ( 1 - Moo^-1 Moe Mee^-1 Meo ) psi = Moo^-1 eta
|
// Left handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) psi = eta --> ( 1 - Moo^-1 Moe Mee^-1 Meo ) psi = Moo^-1 eta
|
||||||
// Right handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) Moo^-1 Moo psi = eta --> ( 1 - Moe Mee^-1 Meo ) Moo^-1 phi=eta ; psi = Moo^-1 phi
|
// Right handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) Moo^-1 Moo psi = eta --> ( 1 - Moe Mee^-1 Meo ) Moo^-1 phi=eta ; psi = Moo^-1 phi
|
||||||
|
221
Grid/algorithms/iterative/BiCGSTAB.h
Normal file
221
Grid/algorithms/iterative/BiCGSTAB.h
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./lib/algorithms/iterative/BiCGSTAB.h
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||||
|
Author: juettner <juettner@soton.ac.uk>
|
||||||
|
Author: David Murphy <djmurphy@mit.edu>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution
|
||||||
|
directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef GRID_BICGSTAB_H
|
||||||
|
#define GRID_BICGSTAB_H
|
||||||
|
|
||||||
|
NAMESPACE_BEGIN(Grid);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
// Base classes for iterative processes based on operators
|
||||||
|
// single input vec, single output vec.
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <class Field>
|
||||||
|
class BiCGSTAB : public OperatorFunction<Field>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using OperatorFunction<Field>::operator();
|
||||||
|
|
||||||
|
bool ErrorOnNoConverge; // throw an assert when the CG fails to converge.
|
||||||
|
// Defaults true.
|
||||||
|
RealD Tolerance;
|
||||||
|
Integer MaxIterations;
|
||||||
|
Integer IterationsToComplete; //Number of iterations the CG took to finish. Filled in upon completion
|
||||||
|
|
||||||
|
BiCGSTAB(RealD tol, Integer maxit, bool err_on_no_conv = true) :
|
||||||
|
Tolerance(tol), MaxIterations(maxit), ErrorOnNoConverge(err_on_no_conv){};
|
||||||
|
|
||||||
|
void operator()(LinearOperatorBase<Field>& Linop, const Field& src, Field& psi)
|
||||||
|
{
|
||||||
|
psi.Checkerboard() = src.Checkerboard();
|
||||||
|
conformable(psi, src);
|
||||||
|
|
||||||
|
RealD cp(0), rho(1), rho_prev(0), alpha(1), beta(0), omega(1);
|
||||||
|
RealD a(0), bo(0), d(0), b(0), ssq(0), qq(0);
|
||||||
|
|
||||||
|
Field p(src);
|
||||||
|
Field r(src);
|
||||||
|
Field rhat(src);
|
||||||
|
Field v(src);
|
||||||
|
Field s(src);
|
||||||
|
Field t(src);
|
||||||
|
Field h(src);
|
||||||
|
|
||||||
|
v = Zero();
|
||||||
|
p = Zero();
|
||||||
|
|
||||||
|
// Initial residual computation & set up
|
||||||
|
RealD guess = norm2(psi);
|
||||||
|
assert(std::isnan(guess) == 0);
|
||||||
|
|
||||||
|
Linop.HermOpAndNorm(psi, v, d, b);
|
||||||
|
|
||||||
|
r = src - v;
|
||||||
|
rhat = r;
|
||||||
|
a = norm2(r);
|
||||||
|
ssq = norm2(src);
|
||||||
|
|
||||||
|
std::cout << GridLogIterative << std::setprecision(8) << "BiCGSTAB: guess " << guess << std::endl;
|
||||||
|
std::cout << GridLogIterative << std::setprecision(8) << "BiCGSTAB: src " << ssq << std::endl;
|
||||||
|
std::cout << GridLogIterative << std::setprecision(8) << "BiCGSTAB: mp " << b << std::endl;
|
||||||
|
std::cout << GridLogIterative << std::setprecision(8) << "BiCGSTAB: r " << a << std::endl;
|
||||||
|
|
||||||
|
RealD rsq = Tolerance * Tolerance * ssq;
|
||||||
|
|
||||||
|
// Check if guess is really REALLY good :)
|
||||||
|
if(a <= rsq){ return; }
|
||||||
|
|
||||||
|
std::cout << GridLogIterative << std::setprecision(8) << "BiCGSTAB: k=0 residual " << a << " target " << rsq << std::endl;
|
||||||
|
|
||||||
|
GridStopWatch LinalgTimer;
|
||||||
|
GridStopWatch InnerTimer;
|
||||||
|
GridStopWatch AxpyNormTimer;
|
||||||
|
GridStopWatch LinearCombTimer;
|
||||||
|
GridStopWatch MatrixTimer;
|
||||||
|
GridStopWatch SolverTimer;
|
||||||
|
|
||||||
|
SolverTimer.Start();
|
||||||
|
int k;
|
||||||
|
for (k = 1; k <= MaxIterations; k++)
|
||||||
|
{
|
||||||
|
rho_prev = rho;
|
||||||
|
|
||||||
|
LinalgTimer.Start();
|
||||||
|
InnerTimer.Start();
|
||||||
|
ComplexD Crho = innerProduct(rhat,r);
|
||||||
|
InnerTimer.Stop();
|
||||||
|
rho = Crho.real();
|
||||||
|
|
||||||
|
beta = (rho / rho_prev) * (alpha / omega);
|
||||||
|
|
||||||
|
LinearCombTimer.Start();
|
||||||
|
bo = beta * omega;
|
||||||
|
auto p_v = p.View();
|
||||||
|
auto r_v = r.View();
|
||||||
|
auto v_v = v.View();
|
||||||
|
accelerator_for(ss, p_v.size(), Field::vector_object::Nsimd(),{
|
||||||
|
coalescedWrite(p_v[ss], beta*p_v(ss) - bo*v_v(ss) + r_v(ss));
|
||||||
|
});
|
||||||
|
LinearCombTimer.Stop();
|
||||||
|
LinalgTimer.Stop();
|
||||||
|
|
||||||
|
MatrixTimer.Start();
|
||||||
|
Linop.HermOp(p,v);
|
||||||
|
MatrixTimer.Stop();
|
||||||
|
|
||||||
|
LinalgTimer.Start();
|
||||||
|
InnerTimer.Start();
|
||||||
|
ComplexD Calpha = innerProduct(rhat,v);
|
||||||
|
InnerTimer.Stop();
|
||||||
|
alpha = rho / Calpha.real();
|
||||||
|
|
||||||
|
LinearCombTimer.Start();
|
||||||
|
auto h_v = h.View();
|
||||||
|
auto psi_v = psi.View();
|
||||||
|
accelerator_for(ss, h_v.size(), Field::vector_object::Nsimd(),{
|
||||||
|
coalescedWrite(h_v[ss], alpha*p_v(ss) + psi_v(ss));
|
||||||
|
});
|
||||||
|
|
||||||
|
auto s_v = s.View();
|
||||||
|
accelerator_for(ss, s_v.size(), Field::vector_object::Nsimd(),{
|
||||||
|
coalescedWrite(s_v[ss], -alpha*v_v(ss) + r_v(ss));
|
||||||
|
});
|
||||||
|
LinearCombTimer.Stop();
|
||||||
|
LinalgTimer.Stop();
|
||||||
|
|
||||||
|
MatrixTimer.Start();
|
||||||
|
Linop.HermOp(s,t);
|
||||||
|
MatrixTimer.Stop();
|
||||||
|
|
||||||
|
LinalgTimer.Start();
|
||||||
|
InnerTimer.Start();
|
||||||
|
ComplexD Comega = innerProduct(t,s);
|
||||||
|
InnerTimer.Stop();
|
||||||
|
omega = Comega.real() / norm2(t);
|
||||||
|
|
||||||
|
LinearCombTimer.Start();
|
||||||
|
auto t_v = t.View();
|
||||||
|
accelerator_for(ss, psi_v.size(), Field::vector_object::Nsimd(),{
|
||||||
|
coalescedWrite(psi_v[ss], h_v(ss) + omega * s_v(ss));
|
||||||
|
coalescedWrite(r_v[ss], -omega * t_v(ss) + s_v(ss));
|
||||||
|
});
|
||||||
|
LinearCombTimer.Stop();
|
||||||
|
|
||||||
|
cp = norm2(r);
|
||||||
|
LinalgTimer.Stop();
|
||||||
|
|
||||||
|
std::cout << GridLogIterative << "BiCGSTAB: Iteration " << k << " residual " << sqrt(cp/ssq) << " target " << Tolerance << std::endl;
|
||||||
|
|
||||||
|
// Stopping condition
|
||||||
|
if(cp <= rsq)
|
||||||
|
{
|
||||||
|
SolverTimer.Stop();
|
||||||
|
Linop.HermOpAndNorm(psi, v, d, qq);
|
||||||
|
p = v - src;
|
||||||
|
|
||||||
|
RealD srcnorm = sqrt(norm2(src));
|
||||||
|
RealD resnorm = sqrt(norm2(p));
|
||||||
|
RealD true_residual = resnorm / srcnorm;
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "BiCGSTAB Converged on iteration " << k << std::endl;
|
||||||
|
std::cout << GridLogMessage << "\tComputed residual " << sqrt(cp/ssq) << std::endl;
|
||||||
|
std::cout << GridLogMessage << "\tTrue residual " << true_residual << std::endl;
|
||||||
|
std::cout << GridLogMessage << "\tTarget " << Tolerance << std::endl;
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "Time breakdown " << std::endl;
|
||||||
|
std::cout << GridLogMessage << "\tElapsed " << SolverTimer.Elapsed() << std::endl;
|
||||||
|
std::cout << GridLogMessage << "\tMatrix " << MatrixTimer.Elapsed() << std::endl;
|
||||||
|
std::cout << GridLogMessage << "\tLinalg " << LinalgTimer.Elapsed() << std::endl;
|
||||||
|
std::cout << GridLogMessage << "\tInner " << InnerTimer.Elapsed() << std::endl;
|
||||||
|
std::cout << GridLogMessage << "\tAxpyNorm " << AxpyNormTimer.Elapsed() << std::endl;
|
||||||
|
std::cout << GridLogMessage << "\tLinearComb " << LinearCombTimer.Elapsed() << std::endl;
|
||||||
|
|
||||||
|
if(ErrorOnNoConverge){ assert(true_residual / Tolerance < 10000.0); }
|
||||||
|
|
||||||
|
IterationsToComplete = k;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "BiCGSTAB did NOT converge" << std::endl;
|
||||||
|
|
||||||
|
if(ErrorOnNoConverge){ assert(0); }
|
||||||
|
IterationsToComplete = k;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NAMESPACE_END(Grid);
|
||||||
|
|
||||||
|
#endif
|
158
Grid/algorithms/iterative/BiCGSTABMixedPrec.h
Normal file
158
Grid/algorithms/iterative/BiCGSTABMixedPrec.h
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./lib/algorithms/iterative/BiCGSTABMixedPrec.h
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Christopher Kelly <ckelly@phys.columbia.edu>
|
||||||
|
Author: David Murphy <djmurphy@mit.edu>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#ifndef GRID_BICGSTAB_MIXED_PREC_H
|
||||||
|
#define GRID_BICGSTAB_MIXED_PREC_H
|
||||||
|
|
||||||
|
NAMESPACE_BEGIN(Grid);
|
||||||
|
|
||||||
|
// Mixed precision restarted defect correction BiCGSTAB
|
||||||
|
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>
|
||||||
|
class MixedPrecisionBiCGSTAB : public LinearFunction<FieldD>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RealD Tolerance;
|
||||||
|
RealD InnerTolerance; // Initial tolerance for inner CG. Defaults to Tolerance but can be changed
|
||||||
|
Integer MaxInnerIterations;
|
||||||
|
Integer MaxOuterIterations;
|
||||||
|
GridBase* SinglePrecGrid; // Grid for single-precision fields
|
||||||
|
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 TotalOuterIterations; //Number of restarts
|
||||||
|
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
|
||||||
|
LinearFunction<FieldF> *guesser;
|
||||||
|
|
||||||
|
MixedPrecisionBiCGSTAB(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), Tolerance(tol), InnerTolerance(tol), MaxInnerIterations(maxinnerit),
|
||||||
|
MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid), OuterLoopNormMult(100.), guesser(NULL) {};
|
||||||
|
|
||||||
|
void useGuesser(LinearFunction<FieldF>& g){
|
||||||
|
guesser = &g;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator() (const FieldD& src_d_in, FieldD& sol_d)
|
||||||
|
{
|
||||||
|
TotalInnerIterations = 0;
|
||||||
|
|
||||||
|
GridStopWatch TotalTimer;
|
||||||
|
TotalTimer.Start();
|
||||||
|
|
||||||
|
int cb = src_d_in.Checkerboard();
|
||||||
|
sol_d.Checkerboard() = cb;
|
||||||
|
|
||||||
|
RealD src_norm = norm2(src_d_in);
|
||||||
|
RealD stop = src_norm * Tolerance*Tolerance;
|
||||||
|
|
||||||
|
GridBase* DoublePrecGrid = src_d_in.Grid();
|
||||||
|
FieldD tmp_d(DoublePrecGrid);
|
||||||
|
tmp_d.Checkerboard() = cb;
|
||||||
|
|
||||||
|
FieldD tmp2_d(DoublePrecGrid);
|
||||||
|
tmp2_d.Checkerboard() = cb;
|
||||||
|
|
||||||
|
FieldD src_d(DoublePrecGrid);
|
||||||
|
src_d = src_d_in; //source for next inner iteration, computed from residual during operation
|
||||||
|
|
||||||
|
RealD inner_tol = InnerTolerance;
|
||||||
|
|
||||||
|
FieldF src_f(SinglePrecGrid);
|
||||||
|
src_f.Checkerboard() = cb;
|
||||||
|
|
||||||
|
FieldF sol_f(SinglePrecGrid);
|
||||||
|
sol_f.Checkerboard() = cb;
|
||||||
|
|
||||||
|
BiCGSTAB<FieldF> CG_f(inner_tol, MaxInnerIterations);
|
||||||
|
CG_f.ErrorOnNoConverge = false;
|
||||||
|
|
||||||
|
GridStopWatch InnerCGtimer;
|
||||||
|
|
||||||
|
GridStopWatch PrecChangeTimer;
|
||||||
|
|
||||||
|
Integer &outer_iter = TotalOuterIterations; //so it will be equal to the final iteration count
|
||||||
|
|
||||||
|
for(outer_iter = 0; outer_iter < MaxOuterIterations; outer_iter++)
|
||||||
|
{
|
||||||
|
// Compute double precision rsd and also new RHS vector.
|
||||||
|
Linop_d.HermOp(sol_d, tmp_d);
|
||||||
|
RealD norm = axpy_norm(src_d, -1., tmp_d, src_d_in); //src_d is residual vector
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "MixedPrecisionBiCGSTAB: Outer iteration " << outer_iter << " residual " << norm << " target " << stop << std::endl;
|
||||||
|
|
||||||
|
if(norm < OuterLoopNormMult * stop){
|
||||||
|
std::cout << GridLogMessage << "MixedPrecisionBiCGSTAB: Outer iteration converged on iteration " << outer_iter << std::endl;
|
||||||
|
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();
|
||||||
|
|
||||||
|
sol_f = Zero();
|
||||||
|
|
||||||
|
//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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Final trial CG
|
||||||
|
std::cout << GridLogMessage << "MixedPrecisionBiCGSTAB: Starting final patch-up double-precision solve" << std::endl;
|
||||||
|
|
||||||
|
BiCGSTAB<FieldD> CG_d(Tolerance, MaxInnerIterations);
|
||||||
|
CG_d(Linop_d, src_d_in, sol_d);
|
||||||
|
TotalFinalStepIterations = CG_d.IterationsToComplete;
|
||||||
|
|
||||||
|
TotalTimer.Stop();
|
||||||
|
std::cout << GridLogMessage << "MixedPrecisionBiCGSTAB: Inner CG iterations " << TotalInnerIterations << " Restarts " << TotalOuterIterations << " Final CG iterations " << TotalFinalStepIterations << std::endl;
|
||||||
|
std::cout << GridLogMessage << "MixedPrecisionBiCGSTAB: Total time " << TotalTimer.Elapsed() << " Precision change " << PrecChangeTimer.Elapsed() << " Inner CG total " << InnerCGtimer.Elapsed() << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NAMESPACE_END(Grid);
|
||||||
|
|
||||||
|
#endif
|
@ -405,6 +405,70 @@ namespace Grid {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class Field> class HermitianSchurRedBlackDiagMooeeSolve : public SchurRedBlackBase<Field>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||||
|
|
||||||
|
HermitianSchurRedBlackDiagMooeeSolve(OperatorFunction<Field>& HermitianRBSolver, const bool initSubGuess = false,
|
||||||
|
const bool _solnAsInitGuess = false)
|
||||||
|
: SchurRedBlackBase<Field>(HermitianRBSolver, initSubGuess, _solnAsInitGuess) {};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// Override RedBlack specialisation
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
virtual void RedBlackSource(Matrix& _Matrix, const Field& src, Field& src_e, Field& src_o)
|
||||||
|
{
|
||||||
|
GridBase* grid = _Matrix.RedBlackGrid();
|
||||||
|
GridBase* fgrid = _Matrix.Grid();
|
||||||
|
|
||||||
|
Field tmp(grid);
|
||||||
|
Field Mtmp(grid);
|
||||||
|
|
||||||
|
pickCheckerboard(Even, src_e, src);
|
||||||
|
pickCheckerboard(Odd , src_o, src);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// src_o = Mdag * (source_o - Moe MeeInv source_e)
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
_Matrix.MooeeInv(src_e, tmp); assert( tmp.Checkerboard() == Even );
|
||||||
|
_Matrix.Meooe (tmp, Mtmp); assert( Mtmp.Checkerboard() == Odd );
|
||||||
|
src_o -= Mtmp; assert( src_o.Checkerboard() == Odd );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void RedBlackSolution(Matrix& _Matrix, const Field& sol_o, const Field& src_e, Field& sol)
|
||||||
|
{
|
||||||
|
GridBase* grid = _Matrix.RedBlackGrid();
|
||||||
|
GridBase* fgrid = _Matrix.Grid();
|
||||||
|
|
||||||
|
Field tmp(grid);
|
||||||
|
Field sol_e(grid);
|
||||||
|
Field src_e_i(grid);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
_Matrix.Meooe(sol_o, tmp); assert( tmp.Checkerboard() == Even );
|
||||||
|
src_e_i = src_e - tmp; assert( src_e_i.Checkerboard() == Even );
|
||||||
|
_Matrix.MooeeInv(src_e_i, sol_e); assert( sol_e.Checkerboard() == Even );
|
||||||
|
|
||||||
|
setCheckerboard(sol, sol_e); assert( sol_e.Checkerboard() == Even );
|
||||||
|
setCheckerboard(sol, sol_o); assert( sol_o.Checkerboard() == Odd );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void RedBlackSolve(Matrix& _Matrix, const Field& src_o, Field& sol_o)
|
||||||
|
{
|
||||||
|
HermitianSchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
this->_HermitianRBSolver(_HermOpEO, src_o, sol_o); assert(sol_o.Checkerboard() == Odd);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void RedBlackSolve(Matrix& _Matrix, const std::vector<Field>& src_o, std::vector<Field>& sol_o)
|
||||||
|
{
|
||||||
|
HermitianSchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
this->_HermitianRBSolver(_HermOpEO, src_o, sol_o);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Site diagonal is identity, right preconditioned by Mee^inv
|
// Site diagonal is identity, right preconditioned by Mee^inv
|
||||||
// ( 1 - Meo Moo^inv Moe Mee^inv ) phi =( 1 - Meo Moo^inv Moe Mee^inv ) Mee psi = = eta = eta
|
// ( 1 - Meo Moo^inv Moe Mee^inv ) phi =( 1 - Meo Moo^inv Moe Mee^inv ) Mee psi = = eta = eta
|
||||||
@ -482,5 +546,76 @@ namespace Grid {
|
|||||||
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class Field> class HermitianSchurRedBlackDiagTwoSolve : public SchurRedBlackBase<Field>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// Wrap the usual normal equations Schur trick
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
HermitianSchurRedBlackDiagTwoSolve(OperatorFunction<Field>& HermitianRBSolver, const bool initSubGuess = false,
|
||||||
|
const bool _solnAsInitGuess = false)
|
||||||
|
: SchurRedBlackBase<Field>(HermitianRBSolver, initSubGuess, _solnAsInitGuess) {};
|
||||||
|
|
||||||
|
virtual void RedBlackSource(Matrix& _Matrix, const Field& src, Field& src_e, Field& src_o)
|
||||||
|
{
|
||||||
|
GridBase* grid = _Matrix.RedBlackGrid();
|
||||||
|
GridBase* fgrid = _Matrix.Grid();
|
||||||
|
|
||||||
|
Field tmp(grid);
|
||||||
|
Field Mtmp(grid);
|
||||||
|
|
||||||
|
pickCheckerboard(Even, src_e, src);
|
||||||
|
pickCheckerboard(Odd , src_o, src);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
// src_o = Mdag * (source_o - Moe MeeInv source_e)
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
_Matrix.MooeeInv(src_e, tmp); assert( tmp.Checkerboard() == Even );
|
||||||
|
_Matrix.Meooe (tmp, Mtmp); assert( Mtmp.Checkerboard() == Odd );
|
||||||
|
src_o -= Mtmp; assert( src_o.Checkerboard() == Odd );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void RedBlackSolution(Matrix& _Matrix, const Field& sol_o, const Field& src_e, Field& sol)
|
||||||
|
{
|
||||||
|
GridBase* grid = _Matrix.RedBlackGrid();
|
||||||
|
GridBase* fgrid = _Matrix.Grid();
|
||||||
|
|
||||||
|
Field sol_o_i(grid);
|
||||||
|
Field tmp(grid);
|
||||||
|
Field sol_e(grid);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
// MooeeInv due to pecond
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
_Matrix.MooeeInv(sol_o, tmp);
|
||||||
|
sol_o_i = tmp;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
_Matrix.Meooe(sol_o_i, tmp); assert( tmp.Checkerboard() == Even );
|
||||||
|
tmp = src_e - tmp; assert( src_e.Checkerboard() == Even );
|
||||||
|
_Matrix.MooeeInv(tmp, sol_e); assert( sol_e.Checkerboard() == Even );
|
||||||
|
|
||||||
|
setCheckerboard(sol, sol_e); assert( sol_e.Checkerboard() == Even );
|
||||||
|
setCheckerboard(sol, sol_o_i); assert( sol_o_i.Checkerboard() == Odd );
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void RedBlackSolve(Matrix& _Matrix, const Field& src_o, Field& sol_o)
|
||||||
|
{
|
||||||
|
HermitianSchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
this->_HermitianRBSolver(_HermOpEO, src_o, sol_o);
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void RedBlackSolve(Matrix& _Matrix, const std::vector<Field>& src_o, std::vector<Field>& sol_o)
|
||||||
|
{
|
||||||
|
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
this->_HermitianRBSolver(_HermOpEO, src_o, sol_o);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,6 +80,8 @@ static Registrar<OneFlavourRatioEOFModule<FermionImplementationPolicy>,
|
|||||||
|
|
||||||
static Registrar< ConjugateGradientModule<WilsonFermionR::FermionField>,
|
static Registrar< ConjugateGradientModule<WilsonFermionR::FermionField>,
|
||||||
HMC_SolverModuleFactory<solver_string, WilsonFermionR::FermionField, Serialiser> > __CGWFmodXMLInit("ConjugateGradient");
|
HMC_SolverModuleFactory<solver_string, WilsonFermionR::FermionField, Serialiser> > __CGWFmodXMLInit("ConjugateGradient");
|
||||||
|
static Registrar< BiCGSTABModule<WilsonFermionR::FermionField>,
|
||||||
|
HMC_SolverModuleFactory<solver_string, WilsonFermionR::FermionField, Serialiser> > __CGWFmodXMLInit("BiCGSTAB");
|
||||||
static Registrar< ConjugateResidualModule<WilsonFermionR::FermionField>,
|
static Registrar< ConjugateResidualModule<WilsonFermionR::FermionField>,
|
||||||
HMC_SolverModuleFactory<solver_string, WilsonFermionR::FermionField, Serialiser> > __CRWFmodXMLInit("ConjugateResidual");
|
HMC_SolverModuleFactory<solver_string, WilsonFermionR::FermionField, Serialiser> > __CRWFmodXMLInit("ConjugateResidual");
|
||||||
|
|
||||||
|
@ -119,6 +119,17 @@ class ConjugateGradientModule: public SolverModule<ConjugateGradient, Field, Sol
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class Field >
|
||||||
|
class BiCGSTABModule: public SolverModule<BiCGSTAB, Field, SolverParameters> {
|
||||||
|
typedef SolverModule<BiCGSTAB, Field, SolverParameters> SolverBase;
|
||||||
|
using SolverBase::SolverBase; // for constructors
|
||||||
|
|
||||||
|
// acquire resource
|
||||||
|
virtual void initialize(){
|
||||||
|
this->SolverPtr.reset(new BiCGSTAB<Field>(this->Par_.tolerance, this->Par_.max_iterations, true));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class Field >
|
template <class Field >
|
||||||
class ConjugateResidualModule: public SolverModule<ConjugateResidual, Field, SolverParameters> {
|
class ConjugateResidualModule: public SolverModule<ConjugateResidual, Field, SolverParameters> {
|
||||||
typedef SolverModule<ConjugateResidual, Field, SolverParameters> SolverBase;
|
typedef SolverModule<ConjugateResidual, Field, SolverParameters> SolverBase;
|
||||||
|
85
tests/solver/Test_wilsonclover_bicgstab_prec.cc
Normal file
85
tests/solver/Test_wilsonclover_bicgstab_prec.cc
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_wilson_cg_unprec.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
;
|
||||||
|
|
||||||
|
template<class d>
|
||||||
|
struct scal {
|
||||||
|
d internal;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gamma::Algebra Gmu [] = {
|
||||||
|
Gamma::Algebra::GammaX,
|
||||||
|
Gamma::Algebra::GammaY,
|
||||||
|
Gamma::Algebra::GammaZ,
|
||||||
|
Gamma::Algebra::GammaT
|
||||||
|
};
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
Coordinate latt_size = GridDefaultLatt();
|
||||||
|
Coordinate simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
|
Coordinate mpi_layout = GridDefaultMpi();
|
||||||
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
|
std::vector<int> seeds({1,2,3,4});
|
||||||
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||||
|
|
||||||
|
LatticeFermion src(&Grid); random(pRNG,src);
|
||||||
|
RealD nrm = norm2(src);
|
||||||
|
LatticeFermion result(&Grid); result=Zero();
|
||||||
|
LatticeGaugeField Umu(&Grid); SU3::HotConfiguration(pRNG,Umu);
|
||||||
|
|
||||||
|
double volume=1;
|
||||||
|
for(int mu=0;mu<Nd;mu++){
|
||||||
|
volume=volume*latt_size[mu];
|
||||||
|
}
|
||||||
|
|
||||||
|
RealD mass = -0.1;
|
||||||
|
RealD csw_r = 1.0;
|
||||||
|
RealD csw_t = 1.0;
|
||||||
|
WilsonCloverFermionR Dw(Umu, Grid, RBGrid, mass, csw_r, csw_t);
|
||||||
|
|
||||||
|
LatticeFermion src_o(&RBGrid);
|
||||||
|
LatticeFermion result_o(&RBGrid);
|
||||||
|
pickCheckerboard(Odd, src_o, src);
|
||||||
|
result_o = Zero();
|
||||||
|
|
||||||
|
HermitianSchurDiagMooeeOperator<WilsonCloverFermionR,LatticeFermion> HermOp(Dw);
|
||||||
|
BiCGSTAB<LatticeFermion> CG(1.0e-8,10000);
|
||||||
|
CG(HermOp, src_o, result_o);
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
81
tests/solver/Test_wilsonclover_bicgstab_schur.cc
Normal file
81
tests/solver/Test_wilsonclover_bicgstab_schur.cc
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_wilson_cg_unprec.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
;
|
||||||
|
|
||||||
|
template<class d>
|
||||||
|
struct scal {
|
||||||
|
d internal;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gamma::Algebra Gmu [] = {
|
||||||
|
Gamma::Algebra::GammaX,
|
||||||
|
Gamma::Algebra::GammaY,
|
||||||
|
Gamma::Algebra::GammaZ,
|
||||||
|
Gamma::Algebra::GammaT
|
||||||
|
};
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
Coordinate latt_size = GridDefaultLatt();
|
||||||
|
Coordinate simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
|
Coordinate mpi_layout = GridDefaultMpi();
|
||||||
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
|
std::vector<int> seeds({1,2,3,4});
|
||||||
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||||
|
|
||||||
|
LatticeFermion src(&Grid); random(pRNG,src);
|
||||||
|
RealD nrm = norm2(src);
|
||||||
|
LatticeFermion result(&Grid); result=Zero();
|
||||||
|
LatticeGaugeField Umu(&Grid); SU3::HotConfiguration(pRNG,Umu);
|
||||||
|
|
||||||
|
double volume=1;
|
||||||
|
for(int mu=0;mu<Nd;mu++){
|
||||||
|
volume=volume*latt_size[mu];
|
||||||
|
}
|
||||||
|
|
||||||
|
RealD mass = -0.1;
|
||||||
|
RealD csw_r = 1.0;
|
||||||
|
RealD csw_t = 1.0;
|
||||||
|
WilsonCloverFermionR Dw(Umu, Grid, RBGrid, mass, csw_r, csw_t);
|
||||||
|
|
||||||
|
BiCGSTAB<LatticeFermion> CG(1.0e-8,10000);
|
||||||
|
HermitianSchurRedBlackDiagMooeeSolve<LatticeFermion> SchurSolver(CG);
|
||||||
|
|
||||||
|
SchurSolver(Dw, src, result);
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
80
tests/solver/Test_wilsonclover_bicgstab_unprec.cc
Normal file
80
tests/solver/Test_wilsonclover_bicgstab_unprec.cc
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_wilson_cg_unprec.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
;
|
||||||
|
|
||||||
|
template<class d>
|
||||||
|
struct scal {
|
||||||
|
d internal;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gamma::Algebra Gmu [] = {
|
||||||
|
Gamma::Algebra::GammaX,
|
||||||
|
Gamma::Algebra::GammaY,
|
||||||
|
Gamma::Algebra::GammaZ,
|
||||||
|
Gamma::Algebra::GammaT
|
||||||
|
};
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
Coordinate latt_size = GridDefaultLatt();
|
||||||
|
Coordinate simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
|
Coordinate mpi_layout = GridDefaultMpi();
|
||||||
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
|
std::vector<int> seeds({1,2,3,4});
|
||||||
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||||
|
|
||||||
|
LatticeFermion src(&Grid); random(pRNG,src);
|
||||||
|
RealD nrm = norm2(src);
|
||||||
|
LatticeFermion result(&Grid); result=Zero();
|
||||||
|
LatticeGaugeField Umu(&Grid); SU3::HotConfiguration(pRNG,Umu);
|
||||||
|
|
||||||
|
double volume=1;
|
||||||
|
for(int mu=0;mu<Nd;mu++){
|
||||||
|
volume=volume*latt_size[mu];
|
||||||
|
}
|
||||||
|
|
||||||
|
RealD mass = -0.1;
|
||||||
|
RealD csw_r = 1.0;
|
||||||
|
RealD csw_t = 1.0;
|
||||||
|
WilsonCloverFermionR Dw(Umu, Grid, RBGrid, mass, csw_r, csw_t);
|
||||||
|
|
||||||
|
HermitianLinearOperator<WilsonCloverFermionR,LatticeFermion> HermOp(Dw);
|
||||||
|
BiCGSTAB<LatticeFermion> CG(1.0e-8,10000);
|
||||||
|
CG(HermOp,src,result);
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
91
tests/solver/Test_wilsonclover_cg_prec.cc
Normal file
91
tests/solver/Test_wilsonclover_cg_prec.cc
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_wilson_cg_prec.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
;
|
||||||
|
|
||||||
|
template<class d>
|
||||||
|
struct scal {
|
||||||
|
d internal;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gamma::Algebra Gmu [] = {
|
||||||
|
Gamma::Algebra::GammaX,
|
||||||
|
Gamma::Algebra::GammaY,
|
||||||
|
Gamma::Algebra::GammaZ,
|
||||||
|
Gamma::Algebra::GammaT
|
||||||
|
};
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
|
||||||
|
Coordinate latt_size = GridDefaultLatt();
|
||||||
|
Coordinate simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
|
Coordinate mpi_layout = GridDefaultMpi();
|
||||||
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
|
std::vector<int> seeds({1,2,3,4});
|
||||||
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||||
|
|
||||||
|
LatticeFermion src(&Grid); random(pRNG,src);
|
||||||
|
RealD nrm = norm2(src);
|
||||||
|
LatticeFermion result(&Grid); result=Zero();
|
||||||
|
LatticeGaugeField Umu(&Grid); SU3::HotConfiguration(pRNG,Umu);
|
||||||
|
|
||||||
|
std::vector<LatticeColourMatrix> U(4,&Grid);
|
||||||
|
|
||||||
|
for(int mu=0;mu<Nd;mu++){
|
||||||
|
U[mu] = PeekIndex<LorentzIndex>(Umu,mu);
|
||||||
|
}
|
||||||
|
|
||||||
|
RealD mass = -0.1;
|
||||||
|
RealD csw_r = 1.0;
|
||||||
|
RealD csw_t = 1.0;
|
||||||
|
WilsonCloverFermionR Dw(Umu, Grid, RBGrid, mass, csw_r, csw_t);
|
||||||
|
|
||||||
|
// HermitianOperator<WilsonFermion,LatticeFermion> HermOp(Dw);
|
||||||
|
// ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
|
||||||
|
// CG(HermOp,src,result);
|
||||||
|
|
||||||
|
LatticeFermion src_o(&RBGrid);
|
||||||
|
LatticeFermion result_o(&RBGrid);
|
||||||
|
pickCheckerboard(Odd,src_o,src);
|
||||||
|
result_o=Zero();
|
||||||
|
|
||||||
|
SchurDiagMooeeOperator<WilsonCloverFermionR,LatticeFermion> HermOpEO(Dw);
|
||||||
|
ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
|
||||||
|
CG(HermOpEO,src_o,result_o);
|
||||||
|
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
77
tests/solver/Test_wilsonclover_cg_schur.cc
Normal file
77
tests/solver/Test_wilsonclover_cg_schur.cc
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_wilson_cg_schur.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
;
|
||||||
|
|
||||||
|
template<class d>
|
||||||
|
struct scal {
|
||||||
|
d internal;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gamma::Algebra Gmu [] = {
|
||||||
|
Gamma::Algebra::GammaX,
|
||||||
|
Gamma::Algebra::GammaY,
|
||||||
|
Gamma::Algebra::GammaZ,
|
||||||
|
Gamma::Algebra::GammaT
|
||||||
|
};
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
|
||||||
|
Coordinate latt_size = GridDefaultLatt();
|
||||||
|
Coordinate simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
|
Coordinate mpi_layout = GridDefaultMpi();
|
||||||
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
|
std::vector<int> seeds({1,2,3,4});
|
||||||
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||||
|
|
||||||
|
LatticeGaugeField Umu(&Grid); SU3::HotConfiguration(pRNG,Umu);
|
||||||
|
|
||||||
|
LatticeFermion src(&Grid); random(pRNG,src);
|
||||||
|
LatticeFermion result(&Grid); result=Zero();
|
||||||
|
LatticeFermion resid(&Grid);
|
||||||
|
|
||||||
|
RealD mass = -0.1;
|
||||||
|
RealD csw_r = 1.0;
|
||||||
|
RealD csw_t = 1.0;
|
||||||
|
WilsonCloverFermionR Dw(Umu, Grid, RBGrid, mass, csw_r, csw_t);
|
||||||
|
|
||||||
|
ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
|
||||||
|
SchurRedBlackDiagMooeeSolve<LatticeFermion> SchurSolver(CG);
|
||||||
|
|
||||||
|
SchurSolver(Dw,src,result);
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
80
tests/solver/Test_wilsonclover_cg_unprec.cc
Normal file
80
tests/solver/Test_wilsonclover_cg_unprec.cc
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_wilson_cg_unprec.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
;
|
||||||
|
|
||||||
|
template<class d>
|
||||||
|
struct scal {
|
||||||
|
d internal;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gamma::Algebra Gmu [] = {
|
||||||
|
Gamma::Algebra::GammaX,
|
||||||
|
Gamma::Algebra::GammaY,
|
||||||
|
Gamma::Algebra::GammaZ,
|
||||||
|
Gamma::Algebra::GammaT
|
||||||
|
};
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
Coordinate latt_size = GridDefaultLatt();
|
||||||
|
Coordinate simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
|
Coordinate mpi_layout = GridDefaultMpi();
|
||||||
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
|
std::vector<int> seeds({1,2,3,4});
|
||||||
|
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||||
|
|
||||||
|
LatticeFermion src(&Grid); random(pRNG,src);
|
||||||
|
RealD nrm = norm2(src);
|
||||||
|
LatticeFermion result(&Grid); result=Zero();
|
||||||
|
LatticeGaugeField Umu(&Grid); SU3::HotConfiguration(pRNG,Umu);
|
||||||
|
|
||||||
|
double volume=1;
|
||||||
|
for(int mu=0;mu<Nd;mu++){
|
||||||
|
volume=volume*latt_size[mu];
|
||||||
|
}
|
||||||
|
|
||||||
|
RealD mass = -0.1;
|
||||||
|
RealD csw_r = 1.0;
|
||||||
|
RealD csw_t = 1.0;
|
||||||
|
WilsonCloverFermionR Dw(Umu, Grid, RBGrid, mass, csw_r, csw_t);
|
||||||
|
|
||||||
|
MdagMLinearOperator<WilsonFermionR,LatticeFermion> HermOp(Dw);
|
||||||
|
ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
|
||||||
|
CG(HermOp,src,result);
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
126
tests/solver/Test_wilsonclover_mixedbicgstab_prec.cc
Normal file
126
tests/solver/Test_wilsonclover_mixedbicgstab_prec.cc
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_dwf_cg_prec.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
;
|
||||||
|
|
||||||
|
template<class d>
|
||||||
|
struct scal {
|
||||||
|
d internal;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gamma::Algebra Gmu [] = {
|
||||||
|
Gamma::Algebra::GammaX,
|
||||||
|
Gamma::Algebra::GammaY,
|
||||||
|
Gamma::Algebra::GammaZ,
|
||||||
|
Gamma::Algebra::GammaT
|
||||||
|
};
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "::::: NB: to enable a quick bit reproducibility check use the --checksums flag. " << std::endl;
|
||||||
|
|
||||||
|
GridCartesian *FGrid_d = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd, vComplexD::Nsimd()), GridDefaultMpi());
|
||||||
|
GridCartesian *FGrid_f = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd, vComplexF::Nsimd()), GridDefaultMpi());
|
||||||
|
GridRedBlackCartesian *FrbGrid_d = SpaceTimeGrid::makeFourDimRedBlackGrid(FGrid_d);
|
||||||
|
GridRedBlackCartesian *FrbGrid_f = SpaceTimeGrid::makeFourDimRedBlackGrid(FGrid_f);
|
||||||
|
|
||||||
|
std::vector<int> fSeeds({1, 2, 3, 4});
|
||||||
|
GridParallelRNG fPRNG(FGrid_d);
|
||||||
|
fPRNG.SeedFixedIntegers(fSeeds);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
LatticeFermionD src(FGrid_d); gaussian(fPRNG, src);
|
||||||
|
LatticeFermionD result(FGrid_d); result = Zero();
|
||||||
|
LatticeGaugeFieldD Umu_d(FGrid_d); SU3::HotConfiguration(fPRNG, Umu_d);
|
||||||
|
LatticeGaugeFieldF Umu_f(FGrid_f); precisionChange(Umu_f, Umu_d);
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
RealD mass = -0.1;
|
||||||
|
RealD csw_r = 1.0;
|
||||||
|
RealD csw_t = 1.0;
|
||||||
|
WilsonCloverFermionD Dw_d(Umu_d, *FGrid_d, *FrbGrid_d, mass, csw_r, csw_t);
|
||||||
|
WilsonCloverFermionF Dw_f(Umu_f, *FGrid_f, *FrbGrid_f, mass, csw_r, csw_t);
|
||||||
|
|
||||||
|
LatticeFermionD src_o(FrbGrid_d);
|
||||||
|
LatticeFermionD result_o(FrbGrid_d);
|
||||||
|
LatticeFermionD result_o_2(FrbGrid_d);
|
||||||
|
pickCheckerboard(Odd, src_o, src);
|
||||||
|
result_o.Checkerboard() = Odd;
|
||||||
|
result_o = Zero();
|
||||||
|
result_o_2.Checkerboard() = Odd;
|
||||||
|
result_o_2 = Zero();
|
||||||
|
|
||||||
|
HermitianSchurDiagMooeeOperator<WilsonCloverFermionD, LatticeFermionD> HermOpEO_d(Dw_d);
|
||||||
|
HermitianSchurDiagMooeeOperator<WilsonCloverFermionF, LatticeFermionF> HermOpEO_f(Dw_f);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "::::::::::::: Starting mixed CG" << std::endl;
|
||||||
|
MixedPrecisionBiCGSTAB<LatticeFermionD, LatticeFermionF> mCG(1.0e-8, 10000, 50, FrbGrid_f, HermOpEO_f, HermOpEO_d);
|
||||||
|
mCG(src_o, result_o);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "::::::::::::: Starting regular CG" << std::endl;
|
||||||
|
BiCGSTAB<LatticeFermionD> CG(1.0e-8, 10000);
|
||||||
|
CG(HermOpEO_d, src_o, result_o_2);
|
||||||
|
|
||||||
|
LatticeFermionD diff_o(FrbGrid_d);
|
||||||
|
RealD diff = axpy_norm(diff_o, -1.0, result_o, result_o_2);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "::::::::::::: Diff between mixed and regular CG: " << diff << std::endl;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIME
|
||||||
|
if( GridCmdOptionExists(argv,argv+argc,"--checksums") )
|
||||||
|
{
|
||||||
|
std::string file1("./Propagator1");
|
||||||
|
emptyUserRecord record;
|
||||||
|
uint32_t nersc_csum;
|
||||||
|
uint32_t scidac_csuma;
|
||||||
|
uint32_t scidac_csumb;
|
||||||
|
typedef SpinColourVectorD FermionD;
|
||||||
|
typedef vSpinColourVectorD vFermionD;
|
||||||
|
|
||||||
|
BinarySimpleMunger<FermionD,FermionD> munge;
|
||||||
|
std::string format = getFormatString<vFermionD>();
|
||||||
|
|
||||||
|
BinaryIO::writeLatticeObject<vFermionD,FermionD>(result_o,file1,munge, 0, format,
|
||||||
|
nersc_csum,scidac_csuma,scidac_csumb);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << " Mixed checksums "<<std::hex << scidac_csuma << " "<<scidac_csumb<<std::endl;
|
||||||
|
|
||||||
|
BinaryIO::writeLatticeObject<vFermionD,FermionD>(result_o_2,file1,munge, 0, format,
|
||||||
|
nersc_csum,scidac_csuma,scidac_csumb);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << " CG checksums "<<std::hex << scidac_csuma << " "<<scidac_csumb<<std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
126
tests/solver/Test_wilsonclover_mixedcg_prec.cc
Normal file
126
tests/solver/Test_wilsonclover_mixedcg_prec.cc
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_dwf_cg_prec.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
;
|
||||||
|
|
||||||
|
template<class d>
|
||||||
|
struct scal {
|
||||||
|
d internal;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gamma::Algebra Gmu [] = {
|
||||||
|
Gamma::Algebra::GammaX,
|
||||||
|
Gamma::Algebra::GammaY,
|
||||||
|
Gamma::Algebra::GammaZ,
|
||||||
|
Gamma::Algebra::GammaT
|
||||||
|
};
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "::::: NB: to enable a quick bit reproducibility check use the --checksums flag. " << std::endl;
|
||||||
|
|
||||||
|
GridCartesian *FGrid_d = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd, vComplexD::Nsimd()), GridDefaultMpi());
|
||||||
|
GridCartesian *FGrid_f = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd, vComplexF::Nsimd()), GridDefaultMpi());
|
||||||
|
GridRedBlackCartesian *FrbGrid_d = SpaceTimeGrid::makeFourDimRedBlackGrid(FGrid_d);
|
||||||
|
GridRedBlackCartesian *FrbGrid_f = SpaceTimeGrid::makeFourDimRedBlackGrid(FGrid_f);
|
||||||
|
|
||||||
|
std::vector<int> fSeeds({1, 2, 3, 4});
|
||||||
|
GridParallelRNG fPRNG(FGrid_d);
|
||||||
|
fPRNG.SeedFixedIntegers(fSeeds);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
LatticeFermionD src(FGrid_d); gaussian(fPRNG, src);
|
||||||
|
LatticeFermionD result(FGrid_d); result = Zero();
|
||||||
|
LatticeGaugeFieldD Umu_d(FGrid_d); SU3::HotConfiguration(fPRNG, Umu_d);
|
||||||
|
LatticeGaugeFieldF Umu_f(FGrid_f); precisionChange(Umu_f, Umu_d);
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
RealD mass = -0.1;
|
||||||
|
RealD csw_r = 1.0;
|
||||||
|
RealD csw_t = 1.0;
|
||||||
|
WilsonCloverFermionD Dw_d(Umu_d, *FGrid_d, *FrbGrid_d, mass, csw_r, csw_t);
|
||||||
|
WilsonCloverFermionF Dw_f(Umu_f, *FGrid_f, *FrbGrid_f, mass, csw_r, csw_t);
|
||||||
|
|
||||||
|
LatticeFermionD src_o(FrbGrid_d);
|
||||||
|
LatticeFermionD result_o(FrbGrid_d);
|
||||||
|
LatticeFermionD result_o_2(FrbGrid_d);
|
||||||
|
pickCheckerboard(Odd, src_o, src);
|
||||||
|
result_o.Checkerboard() = Odd;
|
||||||
|
result_o = Zero();
|
||||||
|
result_o_2.Checkerboard() = Odd;
|
||||||
|
result_o_2 = Zero();
|
||||||
|
|
||||||
|
SchurDiagMooeeOperator<WilsonCloverFermionD, LatticeFermionD> HermOpEO_d(Dw_d);
|
||||||
|
SchurDiagMooeeOperator<WilsonCloverFermionF, LatticeFermionF> HermOpEO_f(Dw_f);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "::::::::::::: Starting mixed CG" << std::endl;
|
||||||
|
MixedPrecisionConjugateGradient<LatticeFermionD, LatticeFermionF> mCG(1.0e-8, 10000, 50, FrbGrid_f, HermOpEO_f, HermOpEO_d);
|
||||||
|
mCG(src_o, result_o);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "::::::::::::: Starting regular CG" << std::endl;
|
||||||
|
ConjugateGradient<LatticeFermionD> CG(1.0e-8, 10000);
|
||||||
|
CG(HermOpEO_d, src_o, result_o_2);
|
||||||
|
|
||||||
|
LatticeFermionD diff_o(FrbGrid_d);
|
||||||
|
RealD diff = axpy_norm(diff_o, -1.0, result_o, result_o_2);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << "::::::::::::: Diff between mixed and regular CG: " << diff << std::endl;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIME
|
||||||
|
if( GridCmdOptionExists(argv,argv+argc,"--checksums") )
|
||||||
|
{
|
||||||
|
std::string file1("./Propagator1");
|
||||||
|
emptyUserRecord record;
|
||||||
|
uint32_t nersc_csum;
|
||||||
|
uint32_t scidac_csuma;
|
||||||
|
uint32_t scidac_csumb;
|
||||||
|
typedef SpinColourVectorD FermionD;
|
||||||
|
typedef vSpinColourVectorD vFermionD;
|
||||||
|
|
||||||
|
BinarySimpleMunger<FermionD,FermionD> munge;
|
||||||
|
std::string format = getFormatString<vFermionD>();
|
||||||
|
|
||||||
|
BinaryIO::writeLatticeObject<vFermionD,FermionD>(result_o,file1,munge, 0, format,
|
||||||
|
nersc_csum,scidac_csuma,scidac_csumb);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << " Mixed checksums "<<std::hex << scidac_csuma << " "<<scidac_csumb<<std::endl;
|
||||||
|
|
||||||
|
BinaryIO::writeLatticeObject<vFermionD,FermionD>(result_o_2,file1,munge, 0, format,
|
||||||
|
nersc_csum,scidac_csuma,scidac_csumb);
|
||||||
|
|
||||||
|
std::cout << GridLogMessage << " CG checksums "<<std::hex << scidac_csuma << " "<<scidac_csumb<<std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user