mirror of
https://github.com/paboyle/Grid.git
synced 2025-04-09 21:50:45 +01:00
Merge remote-tracking branch 'upstream/develop' into feature/seqA2A
This commit is contained in:
commit
8ef4657805
@ -380,6 +380,12 @@ namespace Grid {
|
|||||||
template<class Field> class OperatorFunction {
|
template<class Field> class OperatorFunction {
|
||||||
public:
|
public:
|
||||||
virtual void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) = 0;
|
virtual void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) = 0;
|
||||||
|
virtual void operator() (LinearOperatorBase<Field> &Linop, const std::vector<Field> &in,std::vector<Field> &out) {
|
||||||
|
assert(in.size()==out.size());
|
||||||
|
for(int k=0;k<in.size();k++){
|
||||||
|
(*this)(Linop,in[k],out[k]);
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Field> class LinearFunction {
|
template<class Field> class LinearFunction {
|
||||||
@ -421,7 +427,7 @@ namespace Grid {
|
|||||||
// Hermitian operator Linear function and operator function
|
// Hermitian operator Linear function and operator function
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
template<class Field>
|
template<class Field>
|
||||||
class HermOpOperatorFunction : public OperatorFunction<Field> {
|
class HermOpOperatorFunction : public OperatorFunction<Field> {
|
||||||
void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) {
|
void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) {
|
||||||
Linop.HermOp(in,out);
|
Linop.HermOp(in,out);
|
||||||
};
|
};
|
||||||
|
@ -55,6 +55,14 @@ namespace Grid {
|
|||||||
template<class Field> class CheckerBoardedSparseMatrixBase : public SparseMatrixBase<Field> {
|
template<class Field> class CheckerBoardedSparseMatrixBase : public SparseMatrixBase<Field> {
|
||||||
public:
|
public:
|
||||||
virtual GridBase *RedBlackGrid(void)=0;
|
virtual GridBase *RedBlackGrid(void)=0;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Query the even even properties to make algorithmic decisions
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
virtual RealD Mass(void) { return 0.0; };
|
||||||
|
virtual int ConstEE(void) { return 0; }; // Disable assumptions unless overridden
|
||||||
|
virtual int isTrivialEE(void) { return 0; }; // by a derived class that knows better
|
||||||
|
|
||||||
// half checkerboard operaions
|
// half checkerboard operaions
|
||||||
virtual void Meooe (const Field &in, Field &out)=0;
|
virtual void Meooe (const Field &in, Field &out)=0;
|
||||||
virtual void Mooee (const Field &in, Field &out)=0;
|
virtual void Mooee (const Field &in, Field &out)=0;
|
||||||
|
@ -135,7 +135,7 @@ void operator()(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi)
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void operator()(LinearOperatorBase<Field> &Linop, const std::vector<Field> &Src, std::vector<Field> &Psi)
|
virtual void operator()(LinearOperatorBase<Field> &Linop, const std::vector<Field> &Src, std::vector<Field> &Psi)
|
||||||
{
|
{
|
||||||
if ( CGtype == BlockCGrQVec ) {
|
if ( CGtype == BlockCGrQVec ) {
|
||||||
BlockCGrQsolveVec(Linop,Src,Psi);
|
BlockCGrQsolveVec(Linop,Src,Psi);
|
||||||
|
@ -86,229 +86,23 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
*/
|
*/
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Use base class to share code
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Take a matrix and form a Red Black solver calling a Herm solver
|
// Take a matrix and form a Red Black solver calling a Herm solver
|
||||||
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Now make the norm reflect extra factor of Mee
|
template<class Field> class SchurRedBlackBase {
|
||||||
template<class Field> class SchurRedBlackStaggeredSolve {
|
protected:
|
||||||
private:
|
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||||
OperatorFunction<Field> & _HermitianRBSolver;
|
OperatorFunction<Field> & _HermitianRBSolver;
|
||||||
int CBfactorise;
|
int CBfactorise;
|
||||||
bool subGuess;
|
bool subGuess;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
SchurRedBlackBase(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false) :
|
||||||
// Wrap the usual normal equations Schur trick
|
_HermitianRBSolver(HermitianRBSolver)
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
SchurRedBlackStaggeredSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false) :
|
|
||||||
_HermitianRBSolver(HermitianRBSolver)
|
|
||||||
{
|
|
||||||
CBfactorise=0;
|
|
||||||
subtractGuess(initSubGuess);
|
|
||||||
};
|
|
||||||
void subtractGuess(const bool initSubGuess)
|
|
||||||
{
|
|
||||||
subGuess = initSubGuess;
|
|
||||||
}
|
|
||||||
bool isSubtractGuess(void)
|
|
||||||
{
|
|
||||||
return subGuess;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Matrix>
|
|
||||||
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
|
||||||
ZeroGuesser<Field> guess;
|
|
||||||
(*this)(_Matrix,in,out,guess);
|
|
||||||
}
|
|
||||||
template<class Matrix, class Guesser>
|
|
||||||
void operator() (Matrix & _Matrix,const Field &in, Field &out, Guesser &guess){
|
|
||||||
|
|
||||||
// FIXME CGdiagonalMee not implemented virtual function
|
|
||||||
// FIXME use CBfactorise to control schur decomp
|
|
||||||
GridBase *grid = _Matrix.RedBlackGrid();
|
|
||||||
GridBase *fgrid= _Matrix.Grid();
|
|
||||||
|
|
||||||
SchurStaggeredOperator<Matrix,Field> _HermOpEO(_Matrix);
|
|
||||||
|
|
||||||
Field src_e(grid);
|
|
||||||
Field src_o(grid);
|
|
||||||
Field sol_e(grid);
|
|
||||||
Field sol_o(grid);
|
|
||||||
Field tmp(grid);
|
|
||||||
Field Mtmp(grid);
|
|
||||||
Field resid(fgrid);
|
|
||||||
|
|
||||||
std::cout << GridLogMessage << " SchurRedBlackStaggeredSolve " <<std::endl;
|
|
||||||
pickCheckerboard(Even,src_e,in);
|
|
||||||
pickCheckerboard(Odd ,src_o,in);
|
|
||||||
pickCheckerboard(Even,sol_e,out);
|
|
||||||
pickCheckerboard(Odd ,sol_o,out);
|
|
||||||
std::cout << GridLogMessage << " SchurRedBlackStaggeredSolve checkerboards picked" <<std::endl;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
// src_o = (source_o - Moe MeeInv source_e)
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
_Matrix.MooeeInv(src_e,tmp); assert( tmp.checkerboard ==Even);
|
|
||||||
_Matrix.Meooe (tmp,Mtmp); assert( Mtmp.checkerboard ==Odd);
|
|
||||||
tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd);
|
|
||||||
|
|
||||||
//src_o = tmp; assert(src_o.checkerboard ==Odd);
|
|
||||||
_Matrix.Mooee(tmp,src_o); // Extra factor of "m" in source from dumb choice of matrix norm.
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
// Call the red-black solver
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
std::cout<<GridLogMessage << "SchurRedBlackStaggeredSolver calling the Mpc solver" <<std::endl;
|
|
||||||
guess(src_o, sol_o);
|
|
||||||
Mtmp = sol_o;
|
|
||||||
_HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
|
||||||
std::cout<<GridLogMessage << "SchurRedBlackStaggeredSolver called the Mpc solver" <<std::endl;
|
|
||||||
// Fionn A2A boolean behavioural control
|
|
||||||
if (subGuess) sol_o = sol_o-Mtmp;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
|
||||||
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
|
||||||
///////////////////////////////////////////////////
|
|
||||||
_Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even);
|
|
||||||
src_e = src_e-tmp; assert( src_e.checkerboard ==Even);
|
|
||||||
_Matrix.MooeeInv(src_e,sol_e); assert( sol_e.checkerboard ==Even);
|
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "SchurRedBlackStaggeredSolver reconstructed other CB" <<std::endl;
|
|
||||||
setCheckerboard(out,sol_e); assert( sol_e.checkerboard ==Even);
|
|
||||||
setCheckerboard(out,sol_o); assert( sol_o.checkerboard ==Odd );
|
|
||||||
std::cout<<GridLogMessage << "SchurRedBlackStaggeredSolver inserted solution" <<std::endl;
|
|
||||||
|
|
||||||
// Verify the unprec residual
|
|
||||||
if ( ! subGuess ) {
|
|
||||||
_Matrix.M(out,resid);
|
|
||||||
resid = resid-in;
|
|
||||||
RealD ns = norm2(in);
|
|
||||||
RealD nr = norm2(resid);
|
|
||||||
std::cout<<GridLogMessage << "SchurRedBlackStaggered solver true unprec resid "<< std::sqrt(nr/ns) <<" nr "<< nr <<" ns "<<ns << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << GridLogMessage << "Guess subtracted after solve." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<class Field> using SchurRedBlackStagSolve = SchurRedBlackStaggeredSolve<Field>;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Take a matrix and form a Red Black solver calling a Herm solver
|
|
||||||
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
template<class Field> class SchurRedBlackDiagMooeeSolve {
|
|
||||||
private:
|
|
||||||
OperatorFunction<Field> & _HermitianRBSolver;
|
|
||||||
int CBfactorise;
|
|
||||||
bool subGuess;
|
|
||||||
public:
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
// Wrap the usual normal equations Schur trick
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
SchurRedBlackDiagMooeeSolve(OperatorFunction<Field> &HermitianRBSolver,int cb=0, const bool initSubGuess = false) : _HermitianRBSolver(HermitianRBSolver)
|
|
||||||
{
|
|
||||||
CBfactorise=cb;
|
|
||||||
subtractGuess(initSubGuess);
|
|
||||||
};
|
|
||||||
void subtractGuess(const bool initSubGuess)
|
|
||||||
{
|
|
||||||
subGuess = initSubGuess;
|
|
||||||
}
|
|
||||||
bool isSubtractGuess(void)
|
|
||||||
{
|
|
||||||
return subGuess;
|
|
||||||
}
|
|
||||||
template<class Matrix>
|
|
||||||
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
|
||||||
ZeroGuesser<Field> guess;
|
|
||||||
(*this)(_Matrix,in,out,guess);
|
|
||||||
}
|
|
||||||
template<class Matrix, class Guesser>
|
|
||||||
void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){
|
|
||||||
|
|
||||||
// FIXME CGdiagonalMee not implemented virtual function
|
|
||||||
// FIXME use CBfactorise to control schur decomp
|
|
||||||
GridBase *grid = _Matrix.RedBlackGrid();
|
|
||||||
GridBase *fgrid= _Matrix.Grid();
|
|
||||||
|
|
||||||
SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
|
|
||||||
|
|
||||||
Field src_e(grid);
|
|
||||||
Field src_o(grid);
|
|
||||||
Field sol_e(grid);
|
|
||||||
Field sol_o(grid);
|
|
||||||
Field tmp(grid);
|
|
||||||
Field Mtmp(grid);
|
|
||||||
Field resid(fgrid);
|
|
||||||
|
|
||||||
pickCheckerboard(Even,src_e,in);
|
|
||||||
pickCheckerboard(Odd ,src_o,in);
|
|
||||||
pickCheckerboard(Even,sol_e,out);
|
|
||||||
pickCheckerboard(Odd ,sol_o,out);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
// 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);
|
|
||||||
tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd);
|
|
||||||
|
|
||||||
// get the right MpcDag
|
|
||||||
_HermOpEO.MpcDag(tmp,src_o); assert(src_o.checkerboard ==Odd);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
// Call the red-black solver
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
std::cout<<GridLogMessage << "SchurRedBlack solver calling the MpcDagMp solver" <<std::endl;
|
|
||||||
guess(src_o,sol_o);
|
|
||||||
Mtmp = sol_o;
|
|
||||||
_HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
|
||||||
// Fionn A2A boolean behavioural control
|
|
||||||
if (subGuess) sol_o = sol_o-Mtmp;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
|
||||||
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
|
||||||
///////////////////////////////////////////////////
|
|
||||||
_Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even);
|
|
||||||
src_e = src_e-tmp; assert( src_e.checkerboard ==Even);
|
|
||||||
_Matrix.MooeeInv(src_e,sol_e); assert( sol_e.checkerboard ==Even);
|
|
||||||
|
|
||||||
setCheckerboard(out,sol_e); assert( sol_e.checkerboard ==Even);
|
|
||||||
setCheckerboard(out,sol_o); assert( sol_o.checkerboard ==Odd );
|
|
||||||
|
|
||||||
// Verify the unprec residual
|
|
||||||
if ( ! subGuess ) {
|
|
||||||
_Matrix.M(out,resid);
|
|
||||||
resid = resid-in;
|
|
||||||
RealD ns = norm2(in);
|
|
||||||
RealD nr = norm2(resid);
|
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "SchurRedBlackDiagMooee solver true unprec resid "<< std::sqrt(nr/ns) <<" nr "<< nr <<" ns "<<ns << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << GridLogMessage << "Guess subtracted after solve." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Take a matrix and form a Red Black solver calling a Herm solver
|
|
||||||
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
template<class Field> class SchurRedBlackDiagTwoSolve {
|
|
||||||
private:
|
|
||||||
OperatorFunction<Field> & _HermitianRBSolver;
|
|
||||||
int CBfactorise;
|
|
||||||
bool subGuess;
|
|
||||||
public:
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
// Wrap the usual normal equations Schur trick
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
SchurRedBlackDiagTwoSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false) :
|
|
||||||
_HermitianRBSolver(HermitianRBSolver)
|
|
||||||
{
|
{
|
||||||
CBfactorise = 0;
|
CBfactorise = 0;
|
||||||
subtractGuess(initSubGuess);
|
subtractGuess(initSubGuess);
|
||||||
@ -322,12 +116,86 @@ namespace Grid {
|
|||||||
return subGuess;
|
return subGuess;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Matrix>
|
/////////////////////////////////////////////////////////////
|
||||||
|
// Shared code
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
||||||
ZeroGuesser<Field> guess;
|
ZeroGuesser<Field> guess;
|
||||||
(*this)(_Matrix,in,out,guess);
|
(*this)(_Matrix,in,out,guess);
|
||||||
}
|
}
|
||||||
template<class Matrix,class Guesser>
|
void operator()(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &out)
|
||||||
|
{
|
||||||
|
ZeroGuesser<Field> guess;
|
||||||
|
(*this)(_Matrix,in,out,guess);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Guesser>
|
||||||
|
void operator()(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &out,Guesser &guess)
|
||||||
|
{
|
||||||
|
GridBase *grid = _Matrix.RedBlackGrid();
|
||||||
|
GridBase *fgrid= _Matrix.Grid();
|
||||||
|
int nblock = in.size();
|
||||||
|
|
||||||
|
std::vector<Field> src_o(nblock,grid);
|
||||||
|
std::vector<Field> sol_o(nblock,grid);
|
||||||
|
|
||||||
|
std::vector<Field> guess_save;
|
||||||
|
|
||||||
|
Field resid(fgrid);
|
||||||
|
Field tmp(grid);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
// Prepare RedBlack source
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
for(int b=0;b<nblock;b++){
|
||||||
|
RedBlackSource(_Matrix,in[b],tmp,src_o[b]);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
// Make the guesses
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
if ( subGuess ) guess_save.resize(nblock,grid);
|
||||||
|
|
||||||
|
for(int b=0;b<nblock;b++){
|
||||||
|
guess(src_o[b],sol_o[b]);
|
||||||
|
|
||||||
|
if ( subGuess ) {
|
||||||
|
guess_save[b] = sol_o[b];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// Call the block solver
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
std::cout<<GridLogMessage << "SchurRedBlackBase calling the solver for "<<nblock<<" RHS" <<std::endl;
|
||||||
|
RedBlackSolve(_Matrix,src_o,sol_o);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
// A2A boolean behavioural control & reconstruct other checkerboard
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
for(int b=0;b<nblock;b++) {
|
||||||
|
|
||||||
|
if (subGuess) sol_o[b] = sol_o[b] - guess_save[b];
|
||||||
|
|
||||||
|
///////// Needs even source //////////////
|
||||||
|
pickCheckerboard(Even,tmp,in[b]);
|
||||||
|
RedBlackSolution(_Matrix,sol_o[b],tmp,out[b]);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// Check unprec residual if possible
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
if ( ! subGuess ) {
|
||||||
|
_Matrix.M(out[b],resid);
|
||||||
|
resid = resid-in[b];
|
||||||
|
RealD ns = norm2(in[b]);
|
||||||
|
RealD nr = norm2(resid);
|
||||||
|
|
||||||
|
std::cout<<GridLogMessage<< "SchurRedBlackBase solver true unprec resid["<<b<<"] "<<std::sqrt(nr/ns) << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout<<GridLogMessage<< "SchurRedBlackBase Guess subtracted after solve["<<b<<"] " << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class Guesser>
|
||||||
void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){
|
void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){
|
||||||
|
|
||||||
// FIXME CGdiagonalMee not implemented virtual function
|
// FIXME CGdiagonalMee not implemented virtual function
|
||||||
@ -335,52 +203,39 @@ namespace Grid {
|
|||||||
GridBase *grid = _Matrix.RedBlackGrid();
|
GridBase *grid = _Matrix.RedBlackGrid();
|
||||||
GridBase *fgrid= _Matrix.Grid();
|
GridBase *fgrid= _Matrix.Grid();
|
||||||
|
|
||||||
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
|
||||||
|
|
||||||
Field src_e(grid);
|
|
||||||
Field src_o(grid);
|
|
||||||
Field sol_e(grid);
|
|
||||||
Field sol_o(grid);
|
|
||||||
Field tmp(grid);
|
|
||||||
Field Mtmp(grid);
|
|
||||||
Field resid(fgrid);
|
Field resid(fgrid);
|
||||||
|
Field src_o(grid);
|
||||||
|
Field src_e(grid);
|
||||||
|
Field sol_o(grid);
|
||||||
|
|
||||||
pickCheckerboard(Even,src_e,in);
|
////////////////////////////////////////////////
|
||||||
pickCheckerboard(Odd ,src_o,in);
|
// RedBlack source
|
||||||
pickCheckerboard(Even,sol_e,out);
|
////////////////////////////////////////////////
|
||||||
pickCheckerboard(Odd ,sol_o,out);
|
RedBlackSource(_Matrix,in,src_e,src_o);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
// 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);
|
|
||||||
tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd);
|
|
||||||
|
|
||||||
// get the right MpcDag
|
////////////////////////////////
|
||||||
_HermOpEO.MpcDag(tmp,src_o); assert(src_o.checkerboard ==Odd);
|
// Construct the guess
|
||||||
|
////////////////////////////////
|
||||||
|
Field tmp(grid);
|
||||||
|
guess(src_o,sol_o);
|
||||||
|
|
||||||
|
Field guess_save(grid);
|
||||||
|
guess_save = sol_o;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// Call the red-black solver
|
// Call the red-black solver
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
std::cout<<GridLogMessage << "SchurRedBlack solver calling the MpcDagMp solver" <<std::endl;
|
RedBlackSolve(_Matrix,src_o,sol_o);
|
||||||
// _HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
|
||||||
guess(src_o,tmp);
|
////////////////////////////////////////////////
|
||||||
Mtmp = tmp;
|
|
||||||
_HermitianRBSolver(_HermOpEO,src_o,tmp); assert(tmp.checkerboard==Odd);
|
|
||||||
// Fionn A2A boolean behavioural control
|
// Fionn A2A boolean behavioural control
|
||||||
if (subGuess) tmp = tmp-Mtmp;
|
////////////////////////////////////////////////
|
||||||
_Matrix.MooeeInv(tmp,sol_o); assert( sol_o.checkerboard ==Odd);
|
if (subGuess) sol_o= sol_o-guess_save;
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
// RedBlack solution needs the even source
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
_Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even);
|
RedBlackSolution(_Matrix,sol_o,src_e,out);
|
||||||
src_e = src_e-tmp; assert( src_e.checkerboard ==Even);
|
|
||||||
_Matrix.MooeeInv(src_e,sol_e); assert( sol_e.checkerboard ==Even);
|
|
||||||
|
|
||||||
setCheckerboard(out,sol_e); assert( sol_e.checkerboard ==Even);
|
|
||||||
setCheckerboard(out,sol_o); assert( sol_o.checkerboard ==Odd );
|
|
||||||
|
|
||||||
// Verify the unprec residual
|
// Verify the unprec residual
|
||||||
if ( ! subGuess ) {
|
if ( ! subGuess ) {
|
||||||
@ -389,68 +244,182 @@ namespace Grid {
|
|||||||
RealD ns = norm2(in);
|
RealD ns = norm2(in);
|
||||||
RealD nr = norm2(resid);
|
RealD nr = norm2(resid);
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "SchurRedBlackDiagTwo solver true unprec resid "<< std::sqrt(nr/ns) <<" nr "<< nr <<" ns "<<ns << std::endl;
|
std::cout<<GridLogMessage << "SchurRedBlackBase solver true unprec resid "<< std::sqrt(nr/ns) << std::endl;
|
||||||
} else {
|
} else {
|
||||||
std::cout << GridLogMessage << "Guess subtracted after solve." << std::endl;
|
std::cout << GridLogMessage << "SchurRedBlackBase Guess subtracted after solve." << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
// Override in derived. Not virtual as template methods
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
virtual void RedBlackSource (Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o) =0;
|
||||||
|
virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol) =0;
|
||||||
|
virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o) =0;
|
||||||
|
virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)=0;
|
||||||
|
|
||||||
};
|
};
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Take a matrix and form a Red Black solver calling a Herm solver
|
template<class Field> class SchurRedBlackStaggeredSolve : public SchurRedBlackBase<Field> {
|
||||||
// Use of RB info prevents making SchurRedBlackSolve conform to standard interface
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
template<class Field> class SchurRedBlackDiagTwoMixed {
|
|
||||||
private:
|
|
||||||
LinearFunction<Field> & _HermitianRBSolver;
|
|
||||||
int CBfactorise;
|
|
||||||
bool subGuess;
|
|
||||||
public:
|
public:
|
||||||
|
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||||
|
|
||||||
|
SchurRedBlackStaggeredSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false)
|
||||||
|
: SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// 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 = (source_o - Moe MeeInv source_e)
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
_Matrix.MooeeInv(src_e,tmp); assert( tmp.checkerboard ==Even);
|
||||||
|
_Matrix.Meooe (tmp,Mtmp); assert( Mtmp.checkerboard ==Odd);
|
||||||
|
tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd);
|
||||||
|
|
||||||
|
_Matrix.Mooee(tmp,src_o); // Extra factor of "m" in source from dumb choice of matrix norm.
|
||||||
|
}
|
||||||
|
virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e_c,Field &sol)
|
||||||
|
{
|
||||||
|
GridBase *grid = _Matrix.RedBlackGrid();
|
||||||
|
GridBase *fgrid= _Matrix.Grid();
|
||||||
|
|
||||||
|
Field tmp(grid);
|
||||||
|
Field sol_e(grid);
|
||||||
|
Field src_e(grid);
|
||||||
|
|
||||||
|
src_e = src_e_c; // Const correctness
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
_Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even);
|
||||||
|
src_e = src_e-tmp; assert( src_e.checkerboard ==Even);
|
||||||
|
_Matrix.MooeeInv(src_e,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)
|
||||||
|
{
|
||||||
|
SchurStaggeredOperator<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)
|
||||||
|
{
|
||||||
|
SchurStaggeredOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<class Field> using SchurRedBlackStagSolve = SchurRedBlackStaggeredSolve<Field>;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Site diagonal has Mooee on it.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<class Field> class SchurRedBlackDiagMooeeSolve : public SchurRedBlackBase<Field> {
|
||||||
|
public:
|
||||||
|
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||||
|
|
||||||
|
SchurRedBlackDiagMooeeSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false)
|
||||||
|
: SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess) {};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// 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);
|
||||||
|
tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd);
|
||||||
|
|
||||||
|
// get the right MpcDag
|
||||||
|
SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
_HermOpEO.MpcDag(tmp,src_o); 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)
|
||||||
|
{
|
||||||
|
SchurDiagMooeeOperator<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)
|
||||||
|
{
|
||||||
|
SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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
|
||||||
|
//=> psi = MeeInv phi
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
template<class Field> class SchurRedBlackDiagTwoSolve : public SchurRedBlackBase<Field> {
|
||||||
|
public:
|
||||||
|
typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
// Wrap the usual normal equations Schur trick
|
// Wrap the usual normal equations Schur trick
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
SchurRedBlackDiagTwoMixed(LinearFunction<Field> &HermitianRBSolver, const bool initSubGuess = false) :
|
SchurRedBlackDiagTwoSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false)
|
||||||
_HermitianRBSolver(HermitianRBSolver)
|
: SchurRedBlackBase<Field>(HermitianRBSolver,initSubGuess) {};
|
||||||
{
|
|
||||||
CBfactorise=0;
|
|
||||||
subtractGuess(initSubGuess);
|
|
||||||
};
|
|
||||||
void subtractGuess(const bool initSubGuess)
|
|
||||||
{
|
|
||||||
subGuess = initSubGuess;
|
|
||||||
}
|
|
||||||
bool isSubtractGuess(void)
|
|
||||||
{
|
|
||||||
return subGuess;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Matrix>
|
virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)
|
||||||
void operator() (Matrix & _Matrix,const Field &in, Field &out){
|
{
|
||||||
ZeroGuesser<Field> guess;
|
|
||||||
(*this)(_Matrix,in,out,guess);
|
|
||||||
}
|
|
||||||
template<class Matrix, class Guesser>
|
|
||||||
void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){
|
|
||||||
|
|
||||||
// FIXME CGdiagonalMee not implemented virtual function
|
|
||||||
// FIXME use CBfactorise to control schur decomp
|
|
||||||
GridBase *grid = _Matrix.RedBlackGrid();
|
GridBase *grid = _Matrix.RedBlackGrid();
|
||||||
GridBase *fgrid= _Matrix.Grid();
|
GridBase *fgrid= _Matrix.Grid();
|
||||||
|
|
||||||
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
|
|
||||||
Field src_e(grid);
|
|
||||||
Field src_o(grid);
|
|
||||||
Field sol_e(grid);
|
|
||||||
Field sol_o(grid);
|
|
||||||
Field tmp(grid);
|
Field tmp(grid);
|
||||||
Field Mtmp(grid);
|
Field Mtmp(grid);
|
||||||
Field resid(fgrid);
|
|
||||||
|
|
||||||
pickCheckerboard(Even,src_e,in);
|
pickCheckerboard(Even,src_e,src);
|
||||||
pickCheckerboard(Odd ,src_o,in);
|
pickCheckerboard(Odd ,src_o,src);
|
||||||
pickCheckerboard(Even,sol_e,out);
|
|
||||||
pickCheckerboard(Odd ,sol_o,out);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
// src_o = Mdag * (source_o - Moe MeeInv source_e)
|
// src_o = Mdag * (source_o - Moe MeeInv source_e)
|
||||||
@ -461,43 +430,44 @@ namespace Grid {
|
|||||||
|
|
||||||
// get the right MpcDag
|
// get the right MpcDag
|
||||||
_HermOpEO.MpcDag(tmp,src_o); assert(src_o.checkerboard ==Odd);
|
_HermOpEO.MpcDag(tmp,src_o); assert(src_o.checkerboard ==Odd);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol)
|
||||||
// Call the red-black solver
|
{
|
||||||
//////////////////////////////////////////////////////////////
|
GridBase *grid = _Matrix.RedBlackGrid();
|
||||||
std::cout<<GridLogMessage << "SchurRedBlack solver calling the MpcDagMp solver" <<std::endl;
|
GridBase *fgrid= _Matrix.Grid();
|
||||||
// _HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(sol_o.checkerboard==Odd);
|
|
||||||
// _HermitianRBSolver(_HermOpEO,src_o,tmp); assert(tmp.checkerboard==Odd);
|
Field sol_o_i(grid);
|
||||||
guess(src_o,tmp);
|
Field tmp(grid);
|
||||||
Mtmp = tmp;
|
Field sol_e(grid);
|
||||||
_HermitianRBSolver(_HermOpEO,src_o,tmp); assert(tmp.checkerboard==Odd);
|
|
||||||
// Fionn A2A boolean behavioural control
|
////////////////////////////////////////////////
|
||||||
if (subGuess) tmp = tmp-Mtmp;
|
// MooeeInv due to pecond
|
||||||
_Matrix.MooeeInv(tmp,sol_o); assert( sol_o.checkerboard ==Odd);
|
////////////////////////////////////////////////
|
||||||
|
_Matrix.MooeeInv(sol_o,tmp);
|
||||||
|
sol_o_i = tmp;
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
// sol_e = M_ee^-1 * ( src_e - Meo sol_o )...
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
_Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even);
|
_Matrix.Meooe(sol_o_i,tmp); assert( tmp.checkerboard ==Even);
|
||||||
src_e = src_e-tmp; assert( src_e.checkerboard ==Even);
|
tmp = src_e-tmp; assert( src_e.checkerboard ==Even);
|
||||||
_Matrix.MooeeInv(src_e,sol_e); assert( sol_e.checkerboard ==Even);
|
_Matrix.MooeeInv(tmp,sol_e); assert( sol_e.checkerboard ==Even);
|
||||||
|
|
||||||
setCheckerboard(out,sol_e); assert( sol_e.checkerboard ==Even);
|
setCheckerboard(sol,sol_e); assert( sol_e.checkerboard ==Even);
|
||||||
setCheckerboard(out,sol_o); assert( sol_o.checkerboard ==Odd );
|
setCheckerboard(sol,sol_o_i); assert( sol_o_i.checkerboard ==Odd );
|
||||||
|
};
|
||||||
|
|
||||||
// Verify the unprec residual
|
virtual void RedBlackSolve (Matrix & _Matrix,const Field &src_o, Field &sol_o)
|
||||||
if ( ! subGuess ) {
|
{
|
||||||
_Matrix.M(out,resid);
|
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
resid = resid-in;
|
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
||||||
RealD ns = norm2(in);
|
};
|
||||||
RealD nr = norm2(resid);
|
virtual void RedBlackSolve (Matrix & _Matrix,const std::vector<Field> &src_o, std::vector<Field> &sol_o)
|
||||||
|
{
|
||||||
std::cout << GridLogMessage << "SchurRedBlackDiagTwo solver true unprec resid " << std::sqrt(nr / ns) << " nr " << nr << " ns " << ns << std::endl;
|
SchurDiagTwoOperator<Matrix,Field> _HermOpEO(_Matrix);
|
||||||
} else {
|
this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);
|
||||||
std::cout << GridLogMessage << "Guess subtracted after solve." << std::endl;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,8 +50,6 @@ void CartesianCommunicator::Init(int *argc, char ***argv)
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid_quiesce_nodes();
|
|
||||||
|
|
||||||
// Never clean up as done once.
|
// Never clean up as done once.
|
||||||
MPI_Comm_dup (MPI_COMM_WORLD,&communicator_world);
|
MPI_Comm_dup (MPI_COMM_WORLD,&communicator_world);
|
||||||
|
|
||||||
@ -124,10 +122,8 @@ CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors,
|
|||||||
// split the communicator
|
// split the communicator
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// int Nparent = parent._processors ;
|
// int Nparent = parent._processors ;
|
||||||
// std::cout << " splitting from communicator "<<parent.communicator <<std::endl;
|
|
||||||
int Nparent;
|
int Nparent;
|
||||||
MPI_Comm_size(parent.communicator,&Nparent);
|
MPI_Comm_size(parent.communicator,&Nparent);
|
||||||
// std::cout << " Parent size "<<Nparent <<std::endl;
|
|
||||||
|
|
||||||
int childsize=1;
|
int childsize=1;
|
||||||
for(int d=0;d<processors.size();d++) {
|
for(int d=0;d<processors.size();d++) {
|
||||||
@ -136,8 +132,6 @@ CartesianCommunicator::CartesianCommunicator(const std::vector<int> &processors,
|
|||||||
int Nchild = Nparent/childsize;
|
int Nchild = Nparent/childsize;
|
||||||
assert (childsize * Nchild == Nparent);
|
assert (childsize * Nchild == Nparent);
|
||||||
|
|
||||||
// std::cout << " child size "<<childsize <<std::endl;
|
|
||||||
|
|
||||||
std::vector<int> ccoor(_ndimension); // coor within subcommunicator
|
std::vector<int> ccoor(_ndimension); // coor within subcommunicator
|
||||||
std::vector<int> scoor(_ndimension); // coor of split within parent
|
std::vector<int> scoor(_ndimension); // coor of split within parent
|
||||||
std::vector<int> ssize(_ndimension); // coor of split within parent
|
std::vector<int> ssize(_ndimension); // coor of split within parent
|
||||||
|
@ -413,7 +413,7 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags)
|
|||||||
assert(((uint64_t)ptr&0x3F)==0);
|
assert(((uint64_t)ptr&0x3F)==0);
|
||||||
close(fd);
|
close(fd);
|
||||||
WorldShmCommBufs[r] =ptr;
|
WorldShmCommBufs[r] =ptr;
|
||||||
std::cout << "Set WorldShmCommBufs["<<r<<"]="<<ptr<< "("<< bytes<< "bytes)"<<std::endl;
|
// std::cout << "Set WorldShmCommBufs["<<r<<"]="<<ptr<< "("<< bytes<< "bytes)"<<std::endl;
|
||||||
}
|
}
|
||||||
_ShmAlloc=1;
|
_ShmAlloc=1;
|
||||||
_ShmAllocBytes = bytes;
|
_ShmAllocBytes = bytes;
|
||||||
@ -455,7 +455,7 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags)
|
|||||||
assert(((uint64_t)ptr&0x3F)==0);
|
assert(((uint64_t)ptr&0x3F)==0);
|
||||||
close(fd);
|
close(fd);
|
||||||
WorldShmCommBufs[r] =ptr;
|
WorldShmCommBufs[r] =ptr;
|
||||||
std::cout << "Set WorldShmCommBufs["<<r<<"]="<<ptr<< "("<< bytes<< "bytes)"<<std::endl;
|
// std::cout << "Set WorldShmCommBufs["<<r<<"]="<<ptr<< "("<< bytes<< "bytes)"<<std::endl;
|
||||||
}
|
}
|
||||||
_ShmAlloc=1;
|
_ShmAlloc=1;
|
||||||
_ShmAllocBytes = bytes;
|
_ShmAllocBytes = bytes;
|
||||||
@ -499,7 +499,7 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags)
|
|||||||
#endif
|
#endif
|
||||||
void * ptr = mmap(NULL,size, PROT_READ | PROT_WRITE, mmap_flag, fd, 0);
|
void * ptr = mmap(NULL,size, PROT_READ | PROT_WRITE, mmap_flag, fd, 0);
|
||||||
|
|
||||||
std::cout << "Set WorldShmCommBufs["<<r<<"]="<<ptr<< "("<< size<< "bytes)"<<std::endl;
|
// std::cout << "Set WorldShmCommBufs["<<r<<"]="<<ptr<< "("<< size<< "bytes)"<<std::endl;
|
||||||
if ( ptr == (void * )MAP_FAILED ) {
|
if ( ptr == (void * )MAP_FAILED ) {
|
||||||
perror("failed mmap");
|
perror("failed mmap");
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -464,8 +464,10 @@ void InsertSliceLocal(const Lattice<vobj> &lowDim, Lattice<vobj> & higherDim,int
|
|||||||
assert(orthog>=0);
|
assert(orthog>=0);
|
||||||
|
|
||||||
for(int d=0;d<nh;d++){
|
for(int d=0;d<nh;d++){
|
||||||
assert(lg->_processors[d] == hg->_processors[d]);
|
if ( d!=orthog ) {
|
||||||
assert(lg->_ldimensions[d] == hg->_ldimensions[d]);
|
assert(lg->_processors[d] == hg->_processors[d]);
|
||||||
|
assert(lg->_ldimensions[d] == hg->_ldimensions[d]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the above should guarantee that the operations are local
|
// the above should guarantee that the operations are local
|
||||||
@ -499,8 +501,10 @@ void ExtractSliceLocal(Lattice<vobj> &lowDim, Lattice<vobj> & higherDim,int slic
|
|||||||
assert(orthog>=0);
|
assert(orthog>=0);
|
||||||
|
|
||||||
for(int d=0;d<nh;d++){
|
for(int d=0;d<nh;d++){
|
||||||
assert(lg->_processors[d] == hg->_processors[d]);
|
if ( d!=orthog ) {
|
||||||
assert(lg->_ldimensions[d] == hg->_ldimensions[d]);
|
assert(lg->_processors[d] == hg->_processors[d]);
|
||||||
|
assert(lg->_ldimensions[d] == hg->_ldimensions[d]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the above should guarantee that the operations are local
|
// the above should guarantee that the operations are local
|
||||||
|
@ -146,9 +146,11 @@ public:
|
|||||||
if ( log.timestamp ) {
|
if ( log.timestamp ) {
|
||||||
log.StopWatch->Stop();
|
log.StopWatch->Stop();
|
||||||
GridTime now = log.StopWatch->Elapsed();
|
GridTime now = log.StopWatch->Elapsed();
|
||||||
|
|
||||||
if ( log.timing_mode==1 ) log.StopWatch->Reset();
|
if ( log.timing_mode==1 ) log.StopWatch->Reset();
|
||||||
log.StopWatch->Start();
|
log.StopWatch->Start();
|
||||||
stream << log.evidence()<< std::setw(6)<<now << log.background() << " : " ;
|
stream << log.evidence()
|
||||||
|
<< now << log.background() << " : " ;
|
||||||
}
|
}
|
||||||
stream << log.colour();
|
stream << log.colour();
|
||||||
return stream;
|
return stream;
|
||||||
|
@ -49,21 +49,35 @@ inline double usecond(void) {
|
|||||||
|
|
||||||
typedef std::chrono::system_clock GridClock;
|
typedef std::chrono::system_clock GridClock;
|
||||||
typedef std::chrono::time_point<GridClock> GridTimePoint;
|
typedef std::chrono::time_point<GridClock> GridTimePoint;
|
||||||
typedef std::chrono::milliseconds GridMillisecs;
|
|
||||||
typedef std::chrono::microseconds GridTime;
|
|
||||||
typedef std::chrono::microseconds GridUsecs;
|
|
||||||
|
|
||||||
inline std::ostream& operator<< (std::ostream & stream, const std::chrono::milliseconds & time)
|
typedef std::chrono::seconds GridSecs;
|
||||||
|
typedef std::chrono::milliseconds GridMillisecs;
|
||||||
|
typedef std::chrono::microseconds GridUsecs;
|
||||||
|
typedef std::chrono::microseconds GridTime;
|
||||||
|
|
||||||
|
inline std::ostream& operator<< (std::ostream & stream, const GridSecs & time)
|
||||||
{
|
{
|
||||||
stream << time.count()<<" ms";
|
stream << time.count()<<" s";
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
inline std::ostream& operator<< (std::ostream & stream, const std::chrono::microseconds & time)
|
inline std::ostream& operator<< (std::ostream & stream, const GridMillisecs & now)
|
||||||
{
|
{
|
||||||
stream << time.count()<<" usec";
|
GridSecs second(1);
|
||||||
|
auto secs = now/second ;
|
||||||
|
auto subseconds = now%second ;
|
||||||
|
stream << secs<<"."<<std::setw(3)<<std::setfill('0')<<subseconds.count()<<" s";
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
inline std::ostream& operator<< (std::ostream & stream, const GridUsecs & now)
|
||||||
|
{
|
||||||
|
GridSecs second(1);
|
||||||
|
auto seconds = now/second ;
|
||||||
|
auto subseconds = now%second ;
|
||||||
|
stream << seconds<<"."<<std::setw(6)<<std::setfill('0')<<subseconds.count()<<" s";
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class GridStopWatch {
|
class GridStopWatch {
|
||||||
private:
|
private:
|
||||||
bool running;
|
bool running;
|
||||||
|
@ -64,11 +64,6 @@ namespace Grid {
|
|||||||
virtual RealD M (const FermionField &in, FermionField &out)=0;
|
virtual RealD M (const FermionField &in, FermionField &out)=0;
|
||||||
virtual RealD Mdag (const FermionField &in, FermionField &out)=0;
|
virtual RealD Mdag (const FermionField &in, FermionField &out)=0;
|
||||||
|
|
||||||
// Query the even even properties to make algorithmic decisions
|
|
||||||
virtual int ConstEE(void) { return 1; }; // clover returns zero as EE depends on gauge field
|
|
||||||
virtual int isTrivialEE(void) { return 0; };
|
|
||||||
virtual RealD Mass(void) {return 0.0;};
|
|
||||||
|
|
||||||
// half checkerboard operaions
|
// half checkerboard operaions
|
||||||
virtual void Meooe (const FermionField &in, FermionField &out)=0;
|
virtual void Meooe (const FermionField &in, FermionField &out)=0;
|
||||||
virtual void MeooeDag (const FermionField &in, FermionField &out)=0;
|
virtual void MeooeDag (const FermionField &in, FermionField &out)=0;
|
||||||
|
@ -485,6 +485,7 @@ DX_INIT_DOXYGEN([$PACKAGE_NAME], [doxygen.cfg])
|
|||||||
|
|
||||||
############### Ouput
|
############### Ouput
|
||||||
cwd=`pwd -P`; cd ${srcdir}; abs_srcdir=`pwd -P`; cd ${cwd}
|
cwd=`pwd -P`; cd ${srcdir}; abs_srcdir=`pwd -P`; cd ${cwd}
|
||||||
|
GRID_CXX="$CXX"
|
||||||
GRID_CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS"
|
GRID_CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS"
|
||||||
GRID_LDFLAGS="$AM_LDFLAGS $LDFLAGS"
|
GRID_LDFLAGS="$AM_LDFLAGS $LDFLAGS"
|
||||||
GRID_LIBS=$LIBS
|
GRID_LIBS=$LIBS
|
||||||
@ -497,6 +498,7 @@ AM_LDFLAGS="-L${cwd}/Grid $AM_LDFLAGS"
|
|||||||
AC_SUBST([AM_CFLAGS])
|
AC_SUBST([AM_CFLAGS])
|
||||||
AC_SUBST([AM_CXXFLAGS])
|
AC_SUBST([AM_CXXFLAGS])
|
||||||
AC_SUBST([AM_LDFLAGS])
|
AC_SUBST([AM_LDFLAGS])
|
||||||
|
AC_SUBST([GRID_CXX])
|
||||||
AC_SUBST([GRID_CXXFLAGS])
|
AC_SUBST([GRID_CXXFLAGS])
|
||||||
AC_SUBST([GRID_LDFLAGS])
|
AC_SUBST([GRID_LDFLAGS])
|
||||||
AC_SUBST([GRID_LIBS])
|
AC_SUBST([GRID_LIBS])
|
||||||
|
@ -61,6 +61,10 @@ while test $# -gt 0; do
|
|||||||
echo @GRID_CXXFLAGS@
|
echo @GRID_CXXFLAGS@
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
--cxx)
|
||||||
|
echo @GRID_CXX@
|
||||||
|
;;
|
||||||
|
|
||||||
--ldflags)
|
--ldflags)
|
||||||
echo @GRID_LDFLAGS@
|
echo @GRID_LDFLAGS@
|
||||||
;;
|
;;
|
||||||
|
104
tests/debug/Test_split_laplacian.cc
Normal file
104
tests/debug/Test_split_laplacian.cc
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_dwf_mrhs_cg.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;
|
||||||
|
using namespace Grid::QCD;
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
typedef LatticeComplex ComplexField;
|
||||||
|
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
std::vector<int> latt_size = GridDefaultLatt();
|
||||||
|
int nd = latt_size.size();
|
||||||
|
int ndm1 = nd-1;
|
||||||
|
|
||||||
|
std::vector<int> simd_layout = GridDefaultSimd(nd,vComplex::Nsimd());
|
||||||
|
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||||
|
std::vector<int> mpi_split (mpi_layout.size(),1);
|
||||||
|
|
||||||
|
std::cout << " Full " << GridCmdVectorIntToString(latt_size) << " subgrid" <<std::endl;
|
||||||
|
std::cout << " Full " << GridCmdVectorIntToString(mpi_layout) << " sub communicator"<<std::endl;
|
||||||
|
std::cout << " Full " << GridCmdVectorIntToString(simd_layout)<< " simd layout " <<std::endl;
|
||||||
|
|
||||||
|
GridCartesian * GridN = new GridCartesian(latt_size,
|
||||||
|
simd_layout,
|
||||||
|
mpi_layout);
|
||||||
|
|
||||||
|
std::vector<int> latt_m = latt_size; latt_m[nd-1] = 1;
|
||||||
|
std::vector<int> mpi_m = mpi_layout; mpi_m [nd-1] = 1;
|
||||||
|
std::vector<int> simd_m = GridDefaultSimd(ndm1,vComplex::Nsimd()); simd_m.push_back(1);
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << " Requesting " << GridCmdVectorIntToString(latt_m)<< " subgrid" <<std::endl;
|
||||||
|
std::cout << " Requesting " << GridCmdVectorIntToString(mpi_m) << " sub communicator"<<std::endl;
|
||||||
|
std::cout << " Requesting " << GridCmdVectorIntToString(simd_m)<< " simd layout " <<std::endl;
|
||||||
|
GridCartesian * Grid_m = new GridCartesian(latt_m,
|
||||||
|
simd_m,
|
||||||
|
mpi_m,
|
||||||
|
*GridN);
|
||||||
|
|
||||||
|
Complex C(1.0);
|
||||||
|
Complex tmp;
|
||||||
|
|
||||||
|
ComplexField Full(GridN); Full = C;
|
||||||
|
ComplexField Full_cpy(GridN);
|
||||||
|
ComplexField Split(Grid_m);Split= C;
|
||||||
|
|
||||||
|
std::cout << GridLogMessage<< " Full volume "<< norm2(Full) <<std::endl;
|
||||||
|
std::cout << GridLogMessage<< " Split volume "<< norm2(Split) <<std::endl;
|
||||||
|
|
||||||
|
tmp=C;
|
||||||
|
GridN->GlobalSum(tmp);
|
||||||
|
std::cout << GridLogMessage<< " Full nodes "<< tmp <<std::endl;
|
||||||
|
|
||||||
|
tmp=C;
|
||||||
|
Grid_m->GlobalSum(tmp);
|
||||||
|
std::cout << GridLogMessage<< " Split nodes "<< tmp <<std::endl;
|
||||||
|
GridN->Barrier();
|
||||||
|
|
||||||
|
auto local_latt = GridN->LocalDimensions();
|
||||||
|
|
||||||
|
Full_cpy = zero;
|
||||||
|
std::vector<int> seeds({1,2,3,4});
|
||||||
|
GridParallelRNG RNG(GridN); RNG.SeedFixedIntegers(seeds);
|
||||||
|
|
||||||
|
random(RNG,Full);
|
||||||
|
for(int t=0;t<local_latt[nd-1];t++){
|
||||||
|
ExtractSliceLocal(Split,Full,0,t,Tp);
|
||||||
|
InsertSliceLocal (Split,Full_cpy,0,t,Tp);
|
||||||
|
}
|
||||||
|
Full_cpy = Full_cpy - Full;
|
||||||
|
std::cout << " NormFull " << norm2(Full)<<std::endl;
|
||||||
|
std::cout << " NormDiff " << norm2(Full_cpy)<<std::endl;
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
@ -83,7 +83,7 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
LatticeGaugeField Umu(UGrid);
|
LatticeGaugeField Umu(UGrid);
|
||||||
|
|
||||||
int conf = 0;
|
int conf = 2;
|
||||||
if(conf==0) {
|
if(conf==0) {
|
||||||
FieldMetaData header;
|
FieldMetaData header;
|
||||||
std::string file("./lat.in");
|
std::string file("./lat.in");
|
||||||
@ -131,9 +131,12 @@ int main (int argc, char ** argv)
|
|||||||
for(int s=0;s<nrhs;s++){
|
for(int s=0;s<nrhs;s++){
|
||||||
result[s]=zero;
|
result[s]=zero;
|
||||||
}
|
}
|
||||||
BlockConjugateGradient<FermionField> BCGV (BlockCGrQVec,blockDim,stp,100000);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
BCGV(HermOp,src,result);
|
BlockConjugateGradient<FermionField> BCGV (BlockCGrQVec,blockDim,stp,100000);
|
||||||
|
SchurRedBlackDiagTwoSolve<FermionField> SchurSolver(BCGV);
|
||||||
|
SchurSolver(Ddwf,src,result);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int rhs=0;rhs<nrhs;rhs++){
|
for(int rhs=0;rhs<nrhs;rhs++){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user