mirror of
https://github.com/paboyle/Grid.git
synced 2025-06-15 06:17:05 +01:00
Merge branch 'develop' into feature/clover
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/Test_serialisation.cc
|
||||
|
||||
@ -29,12 +29,11 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
GRID_SERIALIZABLE_ENUM(myenum, undef, red, 1, blue, 2, green, 3);
|
||||
|
||||
|
||||
class myclass: Serializable {
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(myclass,
|
||||
@ -79,14 +78,14 @@ void ioTest(const std::string &filename, const O &object, const std::string &nam
|
||||
// writer needs to be destroyed so that writing physically happens
|
||||
{
|
||||
W writer(filename);
|
||||
|
||||
|
||||
write(writer, "testobject", object);
|
||||
}
|
||||
|
||||
|
||||
R reader(filename);
|
||||
O buf;
|
||||
bool good;
|
||||
|
||||
|
||||
read(reader, "testobject", buf);
|
||||
good = (object == buf);
|
||||
std::cout << name << " IO test: " << (good ? "success" : "failure");
|
||||
@ -98,7 +97,7 @@ int main(int argc,char **argv)
|
||||
{
|
||||
std::cout << "==== basic IO" << std::endl;
|
||||
XmlWriter WR("bother.xml");
|
||||
|
||||
|
||||
// test basic type writing
|
||||
std::cout << "-- basic writing to 'bother.xml'..." << std::endl;
|
||||
push(WR,"BasicTypes");
|
||||
@ -112,12 +111,12 @@ int main(int argc,char **argv)
|
||||
write(WR,"d",d);
|
||||
write(WR,"b",b);
|
||||
pop(WR);
|
||||
|
||||
|
||||
// test serializable class writing
|
||||
myclass obj(1234); // non-trivial constructor
|
||||
std::vector<myclass> vec;
|
||||
std::pair<myenum, myenum> pair;
|
||||
|
||||
|
||||
std::cout << "-- serialisable class writing to 'bother.xml'..." << std::endl;
|
||||
write(WR,"obj",obj);
|
||||
WR.write("obj2", obj);
|
||||
@ -132,11 +131,11 @@ int main(int argc,char **argv)
|
||||
std::cout << "-- serialisable class comparison:" << std::endl;
|
||||
std::cout << "vec[0] == obj: " << ((vec[0] == obj) ? "true" : "false") << std::endl;
|
||||
std::cout << "vec[1] == obj: " << ((vec[1] == obj) ? "true" : "false") << std::endl;
|
||||
|
||||
|
||||
write(WR, "objpair", pair);
|
||||
std::cout << "-- pair writing to std::cout:" << std::endl;
|
||||
std::cout << pair << std::endl;
|
||||
|
||||
|
||||
// read tests
|
||||
std::cout << "\n==== IO self-consistency tests" << std::endl;
|
||||
//// XML
|
||||
@ -151,6 +150,11 @@ int main(int argc,char **argv)
|
||||
ioTest<TextWriter, TextReader>("iotest.dat", obj, "text (object) ");
|
||||
ioTest<TextWriter, TextReader>("iotest.dat", vec, "text (vector of objects)");
|
||||
ioTest<TextWriter, TextReader>("iotest.dat", pair, "text (pair of objects)");
|
||||
//// text
|
||||
ioTest<JSONWriter, JSONReader>("iotest.json", obj, "JSON (object) ");
|
||||
ioTest<JSONWriter, JSONReader>("iotest.json", vec, "JSON (vector of objects)");
|
||||
ioTest<JSONWriter, JSONReader>("iotest.json", pair, "JSON (pair of objects)");
|
||||
|
||||
//// HDF5
|
||||
#undef HAVE_HDF5
|
||||
#ifdef HAVE_HDF5
|
||||
@ -158,13 +162,13 @@ int main(int argc,char **argv)
|
||||
ioTest<Hdf5Writer, Hdf5Reader>("iotest.h5", vec, "HDF5 (vector of objects)");
|
||||
ioTest<Hdf5Writer, Hdf5Reader>("iotest.h5", pair, "HDF5 (pair of objects)");
|
||||
#endif
|
||||
|
||||
|
||||
std::cout << "\n==== vector flattening/reconstruction" << std::endl;
|
||||
typedef std::vector<std::vector<std::vector<double>>> vec3d;
|
||||
|
||||
|
||||
vec3d dv, buf;
|
||||
double d = 0.;
|
||||
|
||||
|
||||
dv.resize(4);
|
||||
for (auto &v1: dv)
|
||||
{
|
||||
@ -180,14 +184,14 @@ int main(int argc,char **argv)
|
||||
}
|
||||
std::cout << "original 3D vector:" << std::endl;
|
||||
std::cout << dv << std::endl;
|
||||
|
||||
|
||||
Flatten<vec3d> flatdv(dv);
|
||||
|
||||
|
||||
std::cout << "\ndimensions:" << std::endl;
|
||||
std::cout << flatdv.getDim() << std::endl;
|
||||
std::cout << "\nflattened vector:" << std::endl;
|
||||
std::cout << flatdv.getFlatVector() << std::endl;
|
||||
|
||||
|
||||
Reconstruct<vec3d> rec(flatdv.getFlatVector(), flatdv.getDim());
|
||||
std::cout << "\nreconstructed vector:" << std::endl;
|
||||
std::cout << flatdv.getVector() << std::endl;
|
||||
@ -199,10 +203,12 @@ int main(int argc,char **argv)
|
||||
|
||||
{
|
||||
JSONWriter JW("bother.json");
|
||||
|
||||
|
||||
// test basic type writing
|
||||
myenum a = myenum::red;
|
||||
push(JW,"BasicTypes");
|
||||
write(JW,std::string("i16"),i16);
|
||||
write(JW,"myenum",a);
|
||||
write(JW,"u16",u16);
|
||||
write(JW,"i32",i32);
|
||||
write(JW,"u32",u32);
|
||||
@ -212,23 +218,25 @@ int main(int argc,char **argv)
|
||||
write(JW,"d",d);
|
||||
write(JW,"b",b);
|
||||
pop(JW);
|
||||
|
||||
|
||||
|
||||
// test serializable class writing
|
||||
myclass obj(1234); // non-trivial constructor
|
||||
std::cout << obj << std::endl;
|
||||
std::cout << "-- serialisable class writing to 'bother.json'..." << std::endl;
|
||||
write(JW,"obj",obj);
|
||||
JW.write("obj2", obj);
|
||||
|
||||
std::cout << obj << std::endl;
|
||||
|
||||
|
||||
|
||||
std::vector<myclass> vec;
|
||||
vec.push_back(myclass(1234));
|
||||
vec.push_back(myclass(5678));
|
||||
vec.push_back(myclass(3838));
|
||||
write(JW, "objvec", vec);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
JSONReader RD("bother.json");
|
||||
myclass jcopy1;
|
||||
@ -238,8 +246,9 @@ int main(int argc,char **argv)
|
||||
std::cout << "Loaded (JSON) -----------------" << std::endl;
|
||||
std::cout << jcopy1 << std::endl << jveccopy1 << std::endl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
/*
|
||||
// This is still work in progress
|
||||
{
|
||||
// Testing the next element function
|
||||
|
@ -1,4 +1,4 @@
|
||||
SUBDIRS = . core forces hmc solver debug smearing IO
|
||||
SUBDIRS = . core forces hmc solver debug smearing IO lanczos
|
||||
|
||||
if BUILD_CHROMA_REGRESSION
|
||||
SUBDIRS+= qdpxx
|
||||
|
@ -80,31 +80,47 @@ int main (int argc, char ** argv)
|
||||
|
||||
|
||||
LatticeFermionD src_o(FrbGrid);
|
||||
LatticeFermionD result_o(FrbGrid);
|
||||
LatticeFermionD result_o_2(FrbGrid);
|
||||
LatticeFermionD result_cg(FrbGrid);
|
||||
pickCheckerboard(Odd,src_o,src);
|
||||
result_o.checkerboard = Odd;
|
||||
result_o = zero;
|
||||
result_o_2.checkerboard = Odd;
|
||||
result_o_2 = zero;
|
||||
result_cg.checkerboard = Odd;
|
||||
result_cg = zero;
|
||||
LatticeFermionD result_mcg(result_cg);
|
||||
LatticeFermionD result_rlcg(result_cg);
|
||||
|
||||
SchurDiagMooeeOperator<DomainWallFermionD,LatticeFermionD> HermOpEO(Ddwf);
|
||||
SchurDiagMooeeOperator<DomainWallFermionFH,LatticeFermionF> HermOpEO_f(Ddwf_f);
|
||||
|
||||
//#define DO_MIXED_CG
|
||||
#define DO_RLUP_CG
|
||||
|
||||
#ifdef DO_MIXED_CG
|
||||
std::cout << "Starting mixed CG" << std::endl;
|
||||
MixedPrecisionConjugateGradient<LatticeFermionD,LatticeFermionF> mCG(1.0e-8, 10000, 50, FrbGrid_f, HermOpEO_f, HermOpEO);
|
||||
mCG.InnerTolerance = 3.0e-5;
|
||||
mCG(src_o,result_o);
|
||||
mCG(src_o,result_mcg);
|
||||
#endif
|
||||
|
||||
#ifdef DO_RLUP_CG
|
||||
std::cout << "Starting reliable update CG" << std::endl;
|
||||
ConjugateGradientReliableUpdate<LatticeFermionD,LatticeFermionF> rlCG(1.e-8, 10000, 0.1, FrbGrid_f, HermOpEO_f, HermOpEO);
|
||||
rlCG(src_o,result_rlcg);
|
||||
#endif
|
||||
|
||||
std::cout << "Starting regular CG" << std::endl;
|
||||
ConjugateGradient<LatticeFermionD> CG(1.0e-8,10000);
|
||||
CG(HermOpEO,src_o,result_o_2);
|
||||
CG(HermOpEO,src_o,result_cg);
|
||||
|
||||
LatticeFermionD diff_o(FrbGrid);
|
||||
RealD diff = axpy_norm(diff_o, -1.0, result_o, result_o_2);
|
||||
|
||||
std::cout << "Diff between mixed and regular CG: " << diff << std::endl;
|
||||
#ifdef DO_MIXED_CG
|
||||
LatticeFermionD diff_mcg(FrbGrid);
|
||||
RealD vdiff_mcg = axpy_norm(diff_mcg, -1.0, result_cg, result_mcg);
|
||||
std::cout << "Diff between mixed and regular CG: " << vdiff_mcg << std::endl;
|
||||
#endif
|
||||
|
||||
#ifdef DO_RLUP_CG
|
||||
LatticeFermionD diff_rlcg(FrbGrid);
|
||||
RealD vdiff_rlcg = axpy_norm(diff_rlcg, -1.0, result_cg, result_rlcg);
|
||||
std::cout << "Diff between reliable update and regular CG: " << vdiff_rlcg << std::endl;
|
||||
#endif
|
||||
|
||||
Grid_finalize();
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ int main(int argc, char ** argv) {
|
||||
double volume = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
|
||||
|
||||
GridCartesian Fine(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian rbFine(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian rbFine(&Fine);
|
||||
GridParallelRNG fRNG(&Fine);
|
||||
|
||||
// fRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
|
||||
|
@ -47,7 +47,7 @@ int main (int argc, char ** argv)
|
||||
mask[0]=0;
|
||||
|
||||
GridCartesian Fine (latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBFine(latt_size,simd_layout,mpi_layout,mask,1);
|
||||
GridRedBlackCartesian RBFine(&Fine,mask,1);
|
||||
|
||||
GridParallelRNG FineRNG(&Fine); FineRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
||||
|
||||
|
@ -47,7 +47,7 @@ int main (int argc, char ** argv)
|
||||
mask[0]=0;
|
||||
|
||||
GridCartesian Fine (latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBFine(latt_size,simd_layout,mpi_layout,mask,1);
|
||||
GridRedBlackCartesian RBFine(&Fine,mask,1);
|
||||
|
||||
GridParallelRNG FineRNG(&Fine); FineRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
||||
|
||||
|
239
tests/core/Test_dwf_eofa_even_odd.cc
Normal file
239
tests/core/Test_dwf_eofa_even_odd.cc
Normal file
@ -0,0 +1,239 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/core/Test_dwf_eofa_even_odd.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
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);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
||||
|
||||
const int Ls = 8;
|
||||
// GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
std::vector<int> seeds4({1,2,3,4});
|
||||
std::vector<int> seeds5({5,6,7,8});
|
||||
|
||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
||||
|
||||
LatticeFermion src (FGrid); random(RNG5, src);
|
||||
LatticeFermion phi (FGrid); random(RNG5, phi);
|
||||
LatticeFermion chi (FGrid); random(RNG5, chi);
|
||||
LatticeFermion result(FGrid); result = zero;
|
||||
LatticeFermion ref (FGrid); ref = zero;
|
||||
LatticeFermion tmp (FGrid); tmp = zero;
|
||||
LatticeFermion err (FGrid); err = zero;
|
||||
LatticeGaugeField Umu (UGrid); SU3::HotConfiguration(RNG4, Umu);
|
||||
std::vector<LatticeColourMatrix> U(4,UGrid);
|
||||
|
||||
// Only one non-zero (y)
|
||||
Umu = zero;
|
||||
for(int nn=0; nn<Nd; nn++){
|
||||
random(RNG4, U[nn]);
|
||||
if(nn>0){ U[nn] = zero; }
|
||||
PokeIndex<LorentzIndex>(Umu, U[nn], nn);
|
||||
}
|
||||
|
||||
RealD mq1 = 0.1;
|
||||
RealD mq2 = 0.5;
|
||||
RealD mq3 = 1.0;
|
||||
RealD shift = 0.1234;
|
||||
RealD M5 = 1.8;
|
||||
int pm = 1;
|
||||
DomainWallEOFAFermionR Ddwf(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mq1, mq2, mq3, shift, pm, M5);
|
||||
|
||||
LatticeFermion src_e (FrbGrid);
|
||||
LatticeFermion src_o (FrbGrid);
|
||||
LatticeFermion r_e (FrbGrid);
|
||||
LatticeFermion r_o (FrbGrid);
|
||||
LatticeFermion r_eo (FGrid);
|
||||
LatticeFermion r_eeoo(FGrid);
|
||||
|
||||
std::cout << GridLogMessage << "==========================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Testing that Meo + Moe + Moo + Mee = Munprec " << std::endl;
|
||||
std::cout << GridLogMessage << "==========================================================" << std::endl;
|
||||
|
||||
pickCheckerboard(Even, src_e, src);
|
||||
pickCheckerboard(Odd, src_o, src);
|
||||
|
||||
Ddwf.Meooe(src_e, r_o); std::cout << GridLogMessage << "Applied Meo" << std::endl;
|
||||
Ddwf.Meooe(src_o, r_e); std::cout << GridLogMessage << "Applied Moe" << std::endl;
|
||||
setCheckerboard(r_eo, r_o);
|
||||
setCheckerboard(r_eo, r_e);
|
||||
|
||||
Ddwf.Mooee(src_e, r_e); std::cout << GridLogMessage << "Applied Mee" << std::endl;
|
||||
Ddwf.Mooee(src_o, r_o); std::cout << GridLogMessage << "Applied Moo" << std::endl;
|
||||
setCheckerboard(r_eeoo, r_e);
|
||||
setCheckerboard(r_eeoo, r_o);
|
||||
|
||||
r_eo = r_eo + r_eeoo;
|
||||
Ddwf.M(src, ref);
|
||||
|
||||
// std::cout << GridLogMessage << r_eo << std::endl;
|
||||
// std::cout << GridLogMessage << ref << std::endl;
|
||||
|
||||
err = ref - r_eo;
|
||||
std::cout << GridLogMessage << "EO norm diff " << norm2(err) << " " << norm2(ref) << " " << norm2(r_eo) << std::endl;
|
||||
|
||||
LatticeComplex cerr(FGrid);
|
||||
cerr = localInnerProduct(err,err);
|
||||
// std::cout << GridLogMessage << cerr << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Test Ddagger is the dagger of D by requiring " << std::endl;
|
||||
std::cout << GridLogMessage << "= < phi | Deo | chi > * = < chi | Deo^dag| phi> " << std::endl;
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
|
||||
LatticeFermion chi_e (FrbGrid);
|
||||
LatticeFermion chi_o (FrbGrid);
|
||||
|
||||
LatticeFermion dchi_e(FrbGrid);
|
||||
LatticeFermion dchi_o(FrbGrid);
|
||||
|
||||
LatticeFermion phi_e (FrbGrid);
|
||||
LatticeFermion phi_o (FrbGrid);
|
||||
|
||||
LatticeFermion dphi_e(FrbGrid);
|
||||
LatticeFermion dphi_o(FrbGrid);
|
||||
|
||||
pickCheckerboard(Even, chi_e, chi);
|
||||
pickCheckerboard(Odd , chi_o, chi);
|
||||
pickCheckerboard(Even, phi_e, phi);
|
||||
pickCheckerboard(Odd , phi_o, phi);
|
||||
|
||||
Ddwf.Meooe (chi_e, dchi_o);
|
||||
Ddwf.Meooe (chi_o, dchi_e);
|
||||
Ddwf.MeooeDag(phi_e, dphi_o);
|
||||
Ddwf.MeooeDag(phi_o, dphi_e);
|
||||
|
||||
ComplexD pDce = innerProduct(phi_e, dchi_e);
|
||||
ComplexD pDco = innerProduct(phi_o, dchi_o);
|
||||
ComplexD cDpe = innerProduct(chi_e, dphi_e);
|
||||
ComplexD cDpo = innerProduct(chi_o, dphi_o);
|
||||
|
||||
std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
|
||||
std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDce-conj(cDpo) << std::endl;
|
||||
std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDco-conj(cDpe) << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Test MeeInv Mee = 1 " << std::endl;
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
|
||||
pickCheckerboard(Even, chi_e, chi);
|
||||
pickCheckerboard(Odd , chi_o, chi);
|
||||
|
||||
Ddwf.Mooee (chi_e, src_e);
|
||||
Ddwf.MooeeInv(src_e, phi_e);
|
||||
|
||||
Ddwf.Mooee (chi_o, src_o);
|
||||
Ddwf.MooeeInv(src_o, phi_o);
|
||||
|
||||
setCheckerboard(phi, phi_e);
|
||||
setCheckerboard(phi, phi_o);
|
||||
|
||||
err = phi - chi;
|
||||
std::cout << GridLogMessage << "norm diff " << norm2(err) << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Test MeeInvDag MeeDag = 1 " << std::endl;
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
|
||||
pickCheckerboard(Even, chi_e, chi);
|
||||
pickCheckerboard(Odd , chi_o, chi);
|
||||
|
||||
Ddwf.MooeeDag (chi_e, src_e);
|
||||
Ddwf.MooeeInvDag(src_e, phi_e);
|
||||
|
||||
Ddwf.MooeeDag (chi_o, src_o);
|
||||
Ddwf.MooeeInvDag(src_o, phi_o);
|
||||
|
||||
setCheckerboard(phi, phi_e);
|
||||
setCheckerboard(phi, phi_o);
|
||||
|
||||
err = phi - chi;
|
||||
std::cout << GridLogMessage << "norm diff " << norm2(err) << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Test MpcDagMpc is Hermitian " << std::endl;
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
|
||||
random(RNG5, phi);
|
||||
random(RNG5, chi);
|
||||
pickCheckerboard(Even, chi_e, chi);
|
||||
pickCheckerboard(Odd , chi_o, chi);
|
||||
pickCheckerboard(Even, phi_e, phi);
|
||||
pickCheckerboard(Odd , phi_o, phi);
|
||||
RealD t1,t2;
|
||||
|
||||
SchurDiagMooeeOperator<DomainWallEOFAFermionR,LatticeFermion> HermOpEO(Ddwf);
|
||||
HermOpEO.MpcDagMpc(chi_e, dchi_e, t1, t2);
|
||||
HermOpEO.MpcDagMpc(chi_o, dchi_o, t1, t2);
|
||||
|
||||
HermOpEO.MpcDagMpc(phi_e, dphi_e, t1, t2);
|
||||
HermOpEO.MpcDagMpc(phi_o, dphi_o, t1, t2);
|
||||
|
||||
pDce = innerProduct(phi_e, dchi_e);
|
||||
pDco = innerProduct(phi_o, dchi_o);
|
||||
cDpe = innerProduct(chi_e, dphi_e);
|
||||
cDpo = innerProduct(chi_o, dphi_o);
|
||||
|
||||
std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
|
||||
std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDco-conj(cDpo) << std::endl;
|
||||
std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDce-conj(cDpe) << std::endl;
|
||||
|
||||
Grid_finalize();
|
||||
}
|
@ -47,7 +47,7 @@ int main (int argc, char ** argv)
|
||||
vol = vol * latt_size[d];
|
||||
}
|
||||
GridCartesian GRID(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGRID(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGRID(&GRID);
|
||||
|
||||
LatticeComplexD one(&GRID);
|
||||
LatticeComplexD zz(&GRID);
|
||||
|
@ -28,6 +28,9 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
@ -82,6 +85,7 @@ int main (int argc, char ** argv)
|
||||
|
||||
Uorg = Uorg - Umu;
|
||||
std::cout << " Norm Difference "<< norm2(Uorg) << std::endl;
|
||||
std::cout << " Norm "<< norm2(Umu) << std::endl;
|
||||
|
||||
|
||||
std::cout<< "*****************************************************************" <<std::endl;
|
||||
|
@ -33,22 +33,68 @@ using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
typedef typename GparityDomainWallFermionR::FermionField FermionField;
|
||||
//typedef GparityDomainWallFermionD GparityDiracOp;
|
||||
//typedef DomainWallFermionD StandardDiracOp;
|
||||
//#define DOP_PARAMS
|
||||
|
||||
typedef GparityMobiusFermionD GparityDiracOp;
|
||||
typedef MobiusFermionD StandardDiracOp;
|
||||
#define DOP_PARAMS ,1.5, 0.5
|
||||
|
||||
|
||||
typedef typename GparityDiracOp::FermionField GparityFermionField;
|
||||
typedef typename GparityDiracOp::GaugeField GparityGaugeField;
|
||||
typedef typename GparityFermionField::vector_type vComplexType;
|
||||
|
||||
typedef typename StandardDiracOp::FermionField StandardFermionField;
|
||||
typedef typename StandardDiracOp::GaugeField StandardGaugeField;
|
||||
|
||||
enum{ same_vComplex = std::is_same<vComplexType, typename StandardFermionField::vector_type>::value };
|
||||
static_assert(same_vComplex == 1, "Dirac Operators must have same underlying SIMD complex type");
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
const int nu = 3;
|
||||
int nu = 0;
|
||||
|
||||
Grid_init(&argc,&argv);
|
||||
|
||||
for(int i=1;i<argc;i++){
|
||||
if(std::string(argv[i]) == "--Gparity-dir"){
|
||||
std::stringstream ss; ss << argv[i+1]; ss >> nu;
|
||||
std::cout << GridLogMessage << "Set Gparity direction to " << nu << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
||||
std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<std::endl;
|
||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
||||
std::cout << GridLogMessage<< "* Testing Gparity Dirac operator "<<std::endl;
|
||||
std::cout << GridLogMessage<< "* Vectorising space-time by "<<vComplexType::Nsimd()<<std::endl;
|
||||
#ifdef GRID_OMP
|
||||
if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) std::cout << GridLogMessage<< "* Using Overlapped Comms/Compute" <<std::endl;
|
||||
if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute) std::cout << GridLogMessage<< "* Using sequential comms compute" <<std::endl;
|
||||
#endif
|
||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptGeneric ) std::cout << GridLogMessage<< "* Using GENERIC Nc WilsonKernels" <<std::endl;
|
||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptHandUnroll) std::cout << GridLogMessage<< "* Using UNROLLED Nc=3 WilsonKernels" <<std::endl;
|
||||
if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptInlineAsm ) std::cout << GridLogMessage<< "* Using Asm Nc=3 WilsonKernels" <<std::endl;
|
||||
std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
|
||||
|
||||
const int Ls=4;
|
||||
const int L =4;
|
||||
std::vector<int> latt_2f(Nd,L);
|
||||
std::vector<int> latt_1f(Nd,L); latt_1f[nu] = 2*L;
|
||||
//const int L =4;
|
||||
//std::vector<int> latt_2f(Nd,L);
|
||||
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> latt_2f = GridDefaultLatt();
|
||||
std::vector<int> latt_1f(latt_2f); latt_1f[nu] = 2*latt_2f[nu];
|
||||
int L = latt_2f[nu];
|
||||
|
||||
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplexType::Nsimd());
|
||||
|
||||
std::cout << GridLogMessage << "SIMD layout: ";
|
||||
for(int i=0;i<simd_layout.size();i++) std::cout << simd_layout[i] << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
std::vector<int> mpi_layout = GridDefaultMpi(); //node layout
|
||||
|
||||
GridCartesian * UGrid_1f = SpaceTimeGrid::makeFourDimGrid(latt_1f, simd_layout, mpi_layout);
|
||||
@ -67,13 +113,13 @@ int main (int argc, char ** argv)
|
||||
GridParallelRNG RNG5_2f(FGrid_2f); RNG5_2f.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4_2f(UGrid_2f); RNG4_2f.SeedFixedIntegers(seeds4);
|
||||
|
||||
LatticeGaugeField Umu_2f(UGrid_2f);
|
||||
GparityGaugeField Umu_2f(UGrid_2f);
|
||||
SU3::HotConfiguration(RNG4_2f,Umu_2f);
|
||||
|
||||
LatticeFermion src (FGrid_2f);
|
||||
LatticeFermion tmpsrc(FGrid_2f);
|
||||
FermionField src_2f(FGrid_2f);
|
||||
LatticeFermion src_1f(FGrid_1f);
|
||||
StandardFermionField src (FGrid_2f);
|
||||
StandardFermionField tmpsrc(FGrid_2f);
|
||||
GparityFermionField src_2f(FGrid_2f);
|
||||
StandardFermionField src_1f(FGrid_1f);
|
||||
|
||||
// Replicate fermion source
|
||||
random(RNG5_2f,src);
|
||||
@ -81,8 +127,8 @@ int main (int argc, char ** argv)
|
||||
tmpsrc=src*2.0;
|
||||
PokeIndex<0>(src_2f,tmpsrc,1);
|
||||
|
||||
LatticeFermion result_1f(FGrid_1f); result_1f=zero;
|
||||
LatticeGaugeField Umu_1f(UGrid_1f);
|
||||
StandardFermionField result_1f(FGrid_1f); result_1f=zero;
|
||||
StandardGaugeField Umu_1f(UGrid_1f);
|
||||
Replicate(Umu_2f,Umu_1f);
|
||||
|
||||
//Coordinate grid for reference
|
||||
@ -92,7 +138,7 @@ int main (int argc, char ** argv)
|
||||
//Copy-conjugate the gauge field
|
||||
//First C-shift the lattice by Lx/2
|
||||
{
|
||||
LatticeGaugeField Umu_shift = conjugate( Cshift(Umu_1f,nu,L) );
|
||||
StandardGaugeField Umu_shift = conjugate( Cshift(Umu_1f,nu,L) );
|
||||
Umu_1f = where( xcoor_1f >= Integer(L), Umu_shift, Umu_1f );
|
||||
|
||||
// hack test to check the same
|
||||
@ -101,7 +147,7 @@ int main (int argc, char ** argv)
|
||||
cout << GridLogMessage << "Umu diff " << norm2(Umu_shift)<<std::endl;
|
||||
|
||||
//Make the gauge field antiperiodic in nu-direction
|
||||
LatticeColourMatrix Unu(UGrid_1f);
|
||||
decltype(PeekIndex<LorentzIndex>(Umu_1f,nu)) Unu(UGrid_1f);
|
||||
Unu = PeekIndex<LorentzIndex>(Umu_1f,nu);
|
||||
Unu = where(xcoor_1f == Integer(2*L-1), -Unu, Unu);
|
||||
PokeIndex<LorentzIndex>(Umu_1f,Unu,nu);
|
||||
@ -115,33 +161,33 @@ int main (int argc, char ** argv)
|
||||
|
||||
RealD mass=0.0;
|
||||
RealD M5=1.8;
|
||||
DomainWallFermionR Ddwf(Umu_1f,*FGrid_1f,*FrbGrid_1f,*UGrid_1f,*UrbGrid_1f,mass,M5);
|
||||
StandardDiracOp Ddwf(Umu_1f,*FGrid_1f,*FrbGrid_1f,*UGrid_1f,*UrbGrid_1f,mass,M5 DOP_PARAMS);
|
||||
|
||||
LatticeFermion src_o_1f(FrbGrid_1f);
|
||||
LatticeFermion result_o_1f(FrbGrid_1f);
|
||||
StandardFermionField src_o_1f(FrbGrid_1f);
|
||||
StandardFermionField result_o_1f(FrbGrid_1f);
|
||||
pickCheckerboard(Odd,src_o_1f,src_1f);
|
||||
result_o_1f=zero;
|
||||
|
||||
SchurDiagMooeeOperator<DomainWallFermionR,LatticeFermion> HermOpEO(Ddwf);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
|
||||
SchurDiagMooeeOperator<StandardDiracOp,StandardFermionField> HermOpEO(Ddwf);
|
||||
ConjugateGradient<StandardFermionField> CG(1.0e-8,10000);
|
||||
CG(HermOpEO,src_o_1f,result_o_1f);
|
||||
|
||||
// const int nu = 3;
|
||||
std::vector<int> twists(Nd,0);
|
||||
twists[nu] = 1;
|
||||
GparityDomainWallFermionR::ImplParams params;
|
||||
GparityDiracOp::ImplParams params;
|
||||
params.twists = twists;
|
||||
GparityDomainWallFermionR GPDdwf(Umu_2f,*FGrid_2f,*FrbGrid_2f,*UGrid_2f,*UrbGrid_2f,mass,M5,params);
|
||||
GparityDiracOp GPDdwf(Umu_2f,*FGrid_2f,*FrbGrid_2f,*UGrid_2f,*UrbGrid_2f,mass,M5 DOP_PARAMS,params);
|
||||
|
||||
for(int disp=-1;disp<=1;disp+=2)
|
||||
for(int mu=0;mu<5;mu++)
|
||||
{
|
||||
FermionField Dsrc_2f(FGrid_2f);
|
||||
GparityFermionField Dsrc_2f(FGrid_2f);
|
||||
|
||||
LatticeFermion Dsrc_1f(FGrid_1f);
|
||||
LatticeFermion Dsrc_2freplica(FGrid_1f);
|
||||
LatticeFermion Dsrc_2freplica0(FGrid_1f);
|
||||
LatticeFermion Dsrc_2freplica1(FGrid_1f);
|
||||
StandardFermionField Dsrc_1f(FGrid_1f);
|
||||
StandardFermionField Dsrc_2freplica(FGrid_1f);
|
||||
StandardFermionField Dsrc_2freplica0(FGrid_1f);
|
||||
StandardFermionField Dsrc_2freplica1(FGrid_1f);
|
||||
|
||||
if ( mu ==0 ) {
|
||||
std::cout << GridLogMessage<< " Cross checking entire hopping term"<<std::endl;
|
||||
@ -156,8 +202,8 @@ int main (int argc, char ** argv)
|
||||
std::cout << GridLogMessage << "S norms "<< norm2(src_2f) << " " << norm2(src_1f) <<std::endl;
|
||||
std::cout << GridLogMessage << "D norms "<< norm2(Dsrc_2f)<< " " << norm2(Dsrc_1f) <<std::endl;
|
||||
|
||||
LatticeFermion Dsrc_2f0(FGrid_2f); Dsrc_2f0 = PeekIndex<0>(Dsrc_2f,0);
|
||||
LatticeFermion Dsrc_2f1(FGrid_2f); Dsrc_2f1 = PeekIndex<0>(Dsrc_2f,1);
|
||||
StandardFermionField Dsrc_2f0(FGrid_2f); Dsrc_2f0 = PeekIndex<0>(Dsrc_2f,0);
|
||||
StandardFermionField Dsrc_2f1(FGrid_2f); Dsrc_2f1 = PeekIndex<0>(Dsrc_2f,1);
|
||||
|
||||
// Dsrc_2f1 = Dsrc_2f1 - Dsrc_2f0;
|
||||
// std::cout << GridLogMessage << " Cross check two halves " <<norm2(Dsrc_2f1)<<std::endl;
|
||||
@ -174,20 +220,20 @@ int main (int argc, char ** argv)
|
||||
}
|
||||
|
||||
{
|
||||
FermionField chi (FGrid_2f); gaussian(RNG5_2f,chi);
|
||||
FermionField phi (FGrid_2f); gaussian(RNG5_2f,phi);
|
||||
GparityFermionField chi (FGrid_2f); gaussian(RNG5_2f,chi);
|
||||
GparityFermionField phi (FGrid_2f); gaussian(RNG5_2f,phi);
|
||||
|
||||
FermionField chi_e (FrbGrid_2f);
|
||||
FermionField chi_o (FrbGrid_2f);
|
||||
GparityFermionField chi_e (FrbGrid_2f);
|
||||
GparityFermionField chi_o (FrbGrid_2f);
|
||||
|
||||
FermionField dchi_e (FrbGrid_2f);
|
||||
FermionField dchi_o (FrbGrid_2f);
|
||||
GparityFermionField dchi_e (FrbGrid_2f);
|
||||
GparityFermionField dchi_o (FrbGrid_2f);
|
||||
|
||||
FermionField phi_e (FrbGrid_2f);
|
||||
FermionField phi_o (FrbGrid_2f);
|
||||
GparityFermionField phi_e (FrbGrid_2f);
|
||||
GparityFermionField phi_o (FrbGrid_2f);
|
||||
|
||||
FermionField dphi_e (FrbGrid_2f);
|
||||
FermionField dphi_o (FrbGrid_2f);
|
||||
GparityFermionField dphi_e (FrbGrid_2f);
|
||||
GparityFermionField dphi_o (FrbGrid_2f);
|
||||
|
||||
pickCheckerboard(Even,chi_e,chi);
|
||||
pickCheckerboard(Odd ,chi_o,chi);
|
||||
@ -212,14 +258,14 @@ int main (int argc, char ** argv)
|
||||
|
||||
}
|
||||
|
||||
FermionField result_2f(FGrid_2f); result_2f=zero;
|
||||
FermionField src_o_2f(FrbGrid_2f);
|
||||
FermionField result_o_2f(FrbGrid_2f);
|
||||
GparityFermionField result_2f(FGrid_2f); result_2f=zero;
|
||||
GparityFermionField src_o_2f(FrbGrid_2f);
|
||||
GparityFermionField result_o_2f(FrbGrid_2f);
|
||||
pickCheckerboard(Odd,src_o_2f,src_2f);
|
||||
result_o_2f=zero;
|
||||
|
||||
ConjugateGradient<FermionField> CG2f(1.0e-8,10000);
|
||||
SchurDiagMooeeOperator<GparityDomainWallFermionR,FermionField> HermOpEO2f(GPDdwf);
|
||||
ConjugateGradient<GparityFermionField> CG2f(1.0e-8,10000);
|
||||
SchurDiagMooeeOperator<GparityDiracOp,GparityFermionField> HermOpEO2f(GPDdwf);
|
||||
CG2f(HermOpEO2f,src_o_2f,result_o_2f);
|
||||
|
||||
std::cout << "2f cb "<<result_o_2f.checkerboard<<std::endl;
|
||||
@ -227,10 +273,10 @@ int main (int argc, char ** argv)
|
||||
|
||||
std::cout << " result norms " <<norm2(result_o_2f)<<" " <<norm2(result_o_1f)<<std::endl;
|
||||
|
||||
LatticeFermion res0o (FrbGrid_2f);
|
||||
LatticeFermion res1o (FrbGrid_2f);
|
||||
LatticeFermion res0 (FGrid_2f);
|
||||
LatticeFermion res1 (FGrid_2f);
|
||||
StandardFermionField res0o (FrbGrid_2f);
|
||||
StandardFermionField res1o (FrbGrid_2f);
|
||||
StandardFermionField res0 (FGrid_2f);
|
||||
StandardFermionField res1 (FGrid_2f);
|
||||
|
||||
res0=zero;
|
||||
res1=zero;
|
||||
@ -244,9 +290,9 @@ int main (int argc, char ** argv)
|
||||
setCheckerboard(res0,res0o);
|
||||
setCheckerboard(res1,res1o);
|
||||
|
||||
LatticeFermion replica (FGrid_1f);
|
||||
LatticeFermion replica0(FGrid_1f);
|
||||
LatticeFermion replica1(FGrid_1f);
|
||||
StandardFermionField replica (FGrid_1f);
|
||||
StandardFermionField replica0(FGrid_1f);
|
||||
StandardFermionField replica1(FGrid_1f);
|
||||
Replicate(res0,replica0);
|
||||
Replicate(res1,replica1);
|
||||
|
||||
|
@ -40,7 +40,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||
|
@ -84,7 +84,7 @@ int main(int argc, char **argv) {
|
||||
double volume = latt_size[0] * latt_size[1] * latt_size[2] * latt_size[3];
|
||||
|
||||
GridCartesian Fine(latt_size, simd_layout, mpi_layout);
|
||||
GridRedBlackCartesian rbFine(latt_size, simd_layout, mpi_layout);
|
||||
GridRedBlackCartesian rbFine(&Fine);
|
||||
GridParallelRNG FineRNG(&Fine);
|
||||
GridSerialRNG SerialRNG;
|
||||
GridSerialRNG SerialRNG1;
|
||||
|
241
tests/core/Test_mobius_eofa_even_odd.cc
Normal file
241
tests/core/Test_mobius_eofa_even_odd.cc
Normal file
@ -0,0 +1,241 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/core/Test_dwf_eofa_even_odd.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
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);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
||||
|
||||
const int Ls = 8;
|
||||
// GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
std::vector<int> seeds4({1,2,3,4});
|
||||
std::vector<int> seeds5({5,6,7,8});
|
||||
|
||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
||||
|
||||
LatticeFermion src (FGrid); random(RNG5, src);
|
||||
LatticeFermion phi (FGrid); random(RNG5, phi);
|
||||
LatticeFermion chi (FGrid); random(RNG5, chi);
|
||||
LatticeFermion result(FGrid); result = zero;
|
||||
LatticeFermion ref (FGrid); ref = zero;
|
||||
LatticeFermion tmp (FGrid); tmp = zero;
|
||||
LatticeFermion err (FGrid); err = zero;
|
||||
LatticeGaugeField Umu (UGrid); SU3::HotConfiguration(RNG4, Umu);
|
||||
std::vector<LatticeColourMatrix> U(4,UGrid);
|
||||
|
||||
// Only one non-zero (y)
|
||||
Umu = zero;
|
||||
for(int nn=0; nn<Nd; nn++){
|
||||
random(RNG4, U[nn]);
|
||||
if(nn>0){ U[nn] = zero; }
|
||||
PokeIndex<LorentzIndex>(Umu, U[nn], nn);
|
||||
}
|
||||
|
||||
RealD b = 2.5;
|
||||
RealD c = 1.5;
|
||||
RealD mq1 = 0.1;
|
||||
RealD mq2 = 0.5;
|
||||
RealD mq3 = 1.0;
|
||||
RealD shift = 0.1234;
|
||||
RealD M5 = 1.8;
|
||||
int pm = 1;
|
||||
MobiusEOFAFermionR Ddwf(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mq1, mq2, mq3, shift, pm, M5, b, c);
|
||||
|
||||
LatticeFermion src_e (FrbGrid);
|
||||
LatticeFermion src_o (FrbGrid);
|
||||
LatticeFermion r_e (FrbGrid);
|
||||
LatticeFermion r_o (FrbGrid);
|
||||
LatticeFermion r_eo (FGrid);
|
||||
LatticeFermion r_eeoo(FGrid);
|
||||
|
||||
std::cout << GridLogMessage << "==========================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Testing that Meo + Moe + Moo + Mee = Munprec " << std::endl;
|
||||
std::cout << GridLogMessage << "==========================================================" << std::endl;
|
||||
|
||||
pickCheckerboard(Even, src_e, src);
|
||||
pickCheckerboard(Odd, src_o, src);
|
||||
|
||||
Ddwf.Meooe(src_e, r_o); std::cout << GridLogMessage << "Applied Meo" << std::endl;
|
||||
Ddwf.Meooe(src_o, r_e); std::cout << GridLogMessage << "Applied Moe" << std::endl;
|
||||
setCheckerboard(r_eo, r_o);
|
||||
setCheckerboard(r_eo, r_e);
|
||||
|
||||
Ddwf.Mooee(src_e, r_e); std::cout << GridLogMessage << "Applied Mee" << std::endl;
|
||||
Ddwf.Mooee(src_o, r_o); std::cout << GridLogMessage << "Applied Moo" << std::endl;
|
||||
setCheckerboard(r_eeoo, r_e);
|
||||
setCheckerboard(r_eeoo, r_o);
|
||||
|
||||
r_eo = r_eo + r_eeoo;
|
||||
Ddwf.M(src, ref);
|
||||
|
||||
// std::cout << GridLogMessage << r_eo << std::endl;
|
||||
// std::cout << GridLogMessage << ref << std::endl;
|
||||
|
||||
err = ref - r_eo;
|
||||
std::cout << GridLogMessage << "EO norm diff " << norm2(err) << " " << norm2(ref) << " " << norm2(r_eo) << std::endl;
|
||||
|
||||
LatticeComplex cerr(FGrid);
|
||||
cerr = localInnerProduct(err,err);
|
||||
// std::cout << GridLogMessage << cerr << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Test Ddagger is the dagger of D by requiring " << std::endl;
|
||||
std::cout << GridLogMessage << "= < phi | Deo | chi > * = < chi | Deo^dag| phi> " << std::endl;
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
|
||||
LatticeFermion chi_e (FrbGrid);
|
||||
LatticeFermion chi_o (FrbGrid);
|
||||
|
||||
LatticeFermion dchi_e(FrbGrid);
|
||||
LatticeFermion dchi_o(FrbGrid);
|
||||
|
||||
LatticeFermion phi_e (FrbGrid);
|
||||
LatticeFermion phi_o (FrbGrid);
|
||||
|
||||
LatticeFermion dphi_e(FrbGrid);
|
||||
LatticeFermion dphi_o(FrbGrid);
|
||||
|
||||
pickCheckerboard(Even, chi_e, chi);
|
||||
pickCheckerboard(Odd , chi_o, chi);
|
||||
pickCheckerboard(Even, phi_e, phi);
|
||||
pickCheckerboard(Odd , phi_o, phi);
|
||||
|
||||
Ddwf.Meooe (chi_e, dchi_o);
|
||||
Ddwf.Meooe (chi_o, dchi_e);
|
||||
Ddwf.MeooeDag(phi_e, dphi_o);
|
||||
Ddwf.MeooeDag(phi_o, dphi_e);
|
||||
|
||||
ComplexD pDce = innerProduct(phi_e, dchi_e);
|
||||
ComplexD pDco = innerProduct(phi_o, dchi_o);
|
||||
ComplexD cDpe = innerProduct(chi_e, dphi_e);
|
||||
ComplexD cDpo = innerProduct(chi_o, dphi_o);
|
||||
|
||||
std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
|
||||
std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDce-conj(cDpo) << std::endl;
|
||||
std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDco-conj(cDpe) << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Test MeeInv Mee = 1 " << std::endl;
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
|
||||
pickCheckerboard(Even, chi_e, chi);
|
||||
pickCheckerboard(Odd , chi_o, chi);
|
||||
|
||||
Ddwf.Mooee (chi_e, src_e);
|
||||
Ddwf.MooeeInv(src_e, phi_e);
|
||||
|
||||
Ddwf.Mooee (chi_o, src_o);
|
||||
Ddwf.MooeeInv(src_o, phi_o);
|
||||
|
||||
setCheckerboard(phi, phi_e);
|
||||
setCheckerboard(phi, phi_o);
|
||||
|
||||
err = phi - chi;
|
||||
std::cout << GridLogMessage << "norm diff " << norm2(err) << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Test MeeInvDag MeeDag = 1 " << std::endl;
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
|
||||
pickCheckerboard(Even, chi_e, chi);
|
||||
pickCheckerboard(Odd , chi_o, chi);
|
||||
|
||||
Ddwf.MooeeDag (chi_e, src_e);
|
||||
Ddwf.MooeeInvDag(src_e, phi_e);
|
||||
|
||||
Ddwf.MooeeDag (chi_o, src_o);
|
||||
Ddwf.MooeeInvDag(src_o, phi_o);
|
||||
|
||||
setCheckerboard(phi, phi_e);
|
||||
setCheckerboard(phi, phi_o);
|
||||
|
||||
err = phi - chi;
|
||||
std::cout << GridLogMessage << "norm diff " << norm2(err) << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
std::cout << GridLogMessage << "= Test MpcDagMpc is Hermitian " << std::endl;
|
||||
std::cout << GridLogMessage << "==============================================================" << std::endl;
|
||||
|
||||
random(RNG5, phi);
|
||||
random(RNG5, chi);
|
||||
pickCheckerboard(Even, chi_e, chi);
|
||||
pickCheckerboard(Odd , chi_o, chi);
|
||||
pickCheckerboard(Even, phi_e, phi);
|
||||
pickCheckerboard(Odd , phi_o, phi);
|
||||
RealD t1,t2;
|
||||
|
||||
SchurDiagMooeeOperator<MobiusEOFAFermionR,LatticeFermion> HermOpEO(Ddwf);
|
||||
HermOpEO.MpcDagMpc(chi_e, dchi_e, t1, t2);
|
||||
HermOpEO.MpcDagMpc(chi_o, dchi_o, t1, t2);
|
||||
|
||||
HermOpEO.MpcDagMpc(phi_e, dphi_e, t1, t2);
|
||||
HermOpEO.MpcDagMpc(phi_o, dphi_o, t1, t2);
|
||||
|
||||
pDce = innerProduct(phi_e, dchi_e);
|
||||
pDco = innerProduct(phi_o, dchi_o);
|
||||
cDpe = innerProduct(chi_e, dphi_e);
|
||||
cDpo = innerProduct(chi_o, dphi_o);
|
||||
|
||||
std::cout << GridLogMessage << "e " << pDce << " " << cDpe << std::endl;
|
||||
std::cout << GridLogMessage << "o " << pDco << " " << cDpo << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "pDce - conj(cDpo) " << pDco-conj(cDpo) << std::endl;
|
||||
std::cout << GridLogMessage << "pDco - conj(cDpe) " << pDce-conj(cDpe) << std::endl;
|
||||
|
||||
Grid_finalize();
|
||||
}
|
@ -40,7 +40,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||
|
@ -51,7 +51,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||
|
@ -52,7 +52,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||
|
102
tests/debug/Test_heatbath_dwf_eofa.cc
Normal file
102
tests/debug/Test_heatbath_dwf_eofa.cc
Normal file
@ -0,0 +1,102 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
|
||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
|
||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
// Parameters for test
|
||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
||||
const int Ls = 8;
|
||||
const int Npoles = 12;
|
||||
const RealD mf = 0.01;
|
||||
const RealD mpv = 1.0;
|
||||
const RealD M5 = 1.8;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
|
||||
|
||||
// Initialize spacetime grid
|
||||
std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << " Ls: " << Ls << std::endl;
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
||||
GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Set up RNGs
|
||||
std::vector<int> seeds4({1, 2, 3, 4});
|
||||
std::vector<int> seeds5({5, 6, 7, 8});
|
||||
GridParallelRNG RNG5(FGrid);
|
||||
RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid);
|
||||
RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
// Random gauge field
|
||||
LatticeGaugeField Umu(UGrid);
|
||||
SU3::HotConfiguration(RNG4, Umu);
|
||||
|
||||
DomainWallEOFAFermionR Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mpv, 0.0, -1, M5);
|
||||
DomainWallEOFAFermionR Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0, 1, M5);
|
||||
|
||||
// Construct the action and test the heatbath (zero initial guess)
|
||||
{
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, false);
|
||||
|
||||
Meofa.refresh(Umu, RNG5);
|
||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
||||
}
|
||||
|
||||
// Construct the action and test the heatbath (forecasted initial guesses)
|
||||
{
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, true);
|
||||
|
||||
Meofa.refresh(Umu, RNG5);
|
||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
108
tests/debug/Test_heatbath_dwf_eofa_gparity.cc
Normal file
108
tests/debug/Test_heatbath_dwf_eofa_gparity.cc
Normal file
@ -0,0 +1,108 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
|
||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
|
||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
typedef GparityWilsonImplR FermionImplPolicy;
|
||||
typedef GparityDomainWallEOFAFermionR FermionAction;
|
||||
typedef typename FermionAction::FermionField FermionField;
|
||||
|
||||
// Parameters for test
|
||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
||||
const int Ls = 8;
|
||||
const int Npoles = 12;
|
||||
const RealD mf = 0.01;
|
||||
const RealD mpv = 1.0;
|
||||
const RealD M5 = 1.8;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
|
||||
|
||||
// Initialize spacetime grid
|
||||
std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << " Ls: " << Ls << std::endl;
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
||||
GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Set up RNGs
|
||||
std::vector<int> seeds4({1, 2, 3, 4});
|
||||
std::vector<int> seeds5({5, 6, 7, 8});
|
||||
GridParallelRNG RNG5(FGrid);
|
||||
RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid);
|
||||
RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
// Random gauge field
|
||||
LatticeGaugeField Umu(UGrid);
|
||||
SU3::HotConfiguration(RNG4, Umu);
|
||||
|
||||
// GparityDomainWallFermionR::ImplParams params;
|
||||
FermionAction::ImplParams params;
|
||||
FermionAction Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mpv, 0.0, -1, M5, params);
|
||||
FermionAction Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0, 1, M5, params);
|
||||
|
||||
// Construct the action and test the heatbath (zero initial guess)
|
||||
{
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, false);
|
||||
|
||||
Meofa.refresh(Umu, RNG5);
|
||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
||||
}
|
||||
|
||||
// Construct the action and test the heatbath (forecasted initial guesses)
|
||||
{
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, true);
|
||||
|
||||
Meofa.refresh(Umu, RNG5);
|
||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
104
tests/debug/Test_heatbath_mobius_eofa.cc
Normal file
104
tests/debug/Test_heatbath_mobius_eofa.cc
Normal file
@ -0,0 +1,104 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
|
||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
|
||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
// Parameters for test
|
||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
||||
const int Ls = 8;
|
||||
const int Npoles = 12;
|
||||
const RealD b = 2.5;
|
||||
const RealD c = 1.5;
|
||||
const RealD mf = 0.01;
|
||||
const RealD mpv = 1.0;
|
||||
const RealD M5 = 1.8;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
|
||||
|
||||
// Initialize spacetime grid
|
||||
std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << " Ls: " << Ls << std::endl;
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
||||
GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Set up RNGs
|
||||
std::vector<int> seeds4({1, 2, 3, 4});
|
||||
std::vector<int> seeds5({5, 6, 7, 8});
|
||||
GridParallelRNG RNG5(FGrid);
|
||||
RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid);
|
||||
RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
// Random gauge field
|
||||
LatticeGaugeField Umu(UGrid);
|
||||
SU3::HotConfiguration(RNG4, Umu);
|
||||
|
||||
MobiusEOFAFermionR Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mpv, 0.0, -1, M5, b, c);
|
||||
MobiusEOFAFermionR Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0, 1, M5, b, c);
|
||||
|
||||
// Construct the action and test the heatbath (zero initial guess)
|
||||
{
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, false);
|
||||
|
||||
Meofa.refresh(Umu, RNG5);
|
||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
||||
}
|
||||
|
||||
// Construct the action and test the heatbath (forecasted initial guesses)
|
||||
{
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, true);
|
||||
|
||||
Meofa.refresh(Umu, RNG5);
|
||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
109
tests/debug/Test_heatbath_mobius_eofa_gparity.cc
Normal file
109
tests/debug/Test_heatbath_mobius_eofa_gparity.cc
Normal file
@ -0,0 +1,109 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/debug/Test_heatbath_dwf_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This program sets up the initial pseudofermion field |Phi> = Meofa^{-1/2}*|eta>, and
|
||||
// then uses this Phi to compute the action <Phi|Meofa|Phi>.
|
||||
// If all is working, one should find that <eta|eta> = <Phi|Meofa|Phi>.
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
typedef GparityWilsonImplR FermionImplPolicy;
|
||||
typedef GparityMobiusEOFAFermionR FermionAction;
|
||||
typedef typename FermionAction::FermionField FermionField;
|
||||
|
||||
// Parameters for test
|
||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
||||
const int Ls = 8;
|
||||
const int Npoles = 12;
|
||||
const RealD b = 2.5;
|
||||
const RealD c = 1.5;
|
||||
const RealD mf = 0.01;
|
||||
const RealD mpv = 1.0;
|
||||
const RealD M5 = 1.8;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is set up to use " << threads << " threads" << std::endl;
|
||||
|
||||
// Initialize spacetime grid
|
||||
std::cout << GridLogMessage << "Lattice dimensions: " << grid_dim << " Ls: " << Ls << std::endl;
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
||||
GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Set up RNGs
|
||||
std::vector<int> seeds4({1, 2, 3, 4});
|
||||
std::vector<int> seeds5({5, 6, 7, 8});
|
||||
GridParallelRNG RNG5(FGrid);
|
||||
RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid);
|
||||
RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
// Random gauge field
|
||||
LatticeGaugeField Umu(UGrid);
|
||||
SU3::HotConfiguration(RNG4, Umu);
|
||||
|
||||
FermionAction::ImplParams params;
|
||||
FermionAction Lop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mpv, 0.0, -1, M5, b, c, params);
|
||||
FermionAction Rop(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mpv, mf, mpv, -1.0, 1, M5, b, c, params);
|
||||
|
||||
// Construct the action and test the heatbath (zero initial guess)
|
||||
{
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, false);
|
||||
|
||||
Meofa.refresh(Umu, RNG5);
|
||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
||||
}
|
||||
|
||||
// Construct the action and test the heatbath (forecasted initial guesses)
|
||||
{
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, Npoles);
|
||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, true);
|
||||
|
||||
Meofa.refresh(Umu, RNG5);
|
||||
printf("<Phi|Meofa|Phi> = %1.15e\n", Meofa.S(Umu));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
206
tests/debug/Test_reweight_dwf_eofa.cc
Normal file
206
tests/debug/Test_reweight_dwf_eofa.cc
Normal file
@ -0,0 +1,206 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/debug/Test_reweight_dwf_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
// parameters for test
|
||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
||||
const int Ls = 8;
|
||||
const int Nhits = 25;
|
||||
const int max_iter = 5000;
|
||||
const RealD mf = 0.1;
|
||||
const RealD mb = 0.11;
|
||||
const RealD M5 = 1.8;
|
||||
const RealD stop_tol = 1.0e-12;
|
||||
|
||||
RealD mean(const std::vector<RealD>& data)
|
||||
{
|
||||
int N = data.size();
|
||||
RealD mean(0.0);
|
||||
for(int i=0; i<N; ++i){ mean += data[i]; }
|
||||
return mean/RealD(N);
|
||||
}
|
||||
|
||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
|
||||
{
|
||||
int N = data.size();
|
||||
RealD mean(0.0);
|
||||
for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
|
||||
return mean/RealD(N-1);
|
||||
}
|
||||
|
||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
|
||||
{
|
||||
int N = jacks.size();
|
||||
RealD std(0.0);
|
||||
for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
|
||||
return std::sqrt(RealD(N-1)/RealD(N)*std);
|
||||
}
|
||||
|
||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
|
||||
{
|
||||
int N = data.size();
|
||||
std::vector<RealD> jack_samples(N);
|
||||
std::vector<RealD> jack_stats(2);
|
||||
|
||||
jack_stats[0] = mean(data);
|
||||
for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
|
||||
jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
|
||||
return jack_stats;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
// Initialize spacetime grid
|
||||
std::cout << GridLogMessage << "Lattice dimensions: "
|
||||
<< grid_dim << " Ls: " << Ls << std::endl;
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
||||
GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Set up RNGs
|
||||
std::vector<int> seeds4({1, 2, 3, 4});
|
||||
std::vector<int> seeds5({5, 6, 7, 8});
|
||||
GridParallelRNG RNG5(FGrid);
|
||||
RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid);
|
||||
RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
// Random gauge field
|
||||
LatticeGaugeField Umu(UGrid);
|
||||
SU3::HotConfiguration(RNG4, Umu);
|
||||
|
||||
// Initialize RHMC fermion operators
|
||||
DomainWallFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5);
|
||||
DomainWallFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5);
|
||||
SchurDiagMooeeOperator<DomainWallFermionR, LatticeFermion> MdagM(Ddwf_f);
|
||||
SchurDiagMooeeOperator<DomainWallFermionR, LatticeFermion> VdagV(Ddwf_b);
|
||||
|
||||
// Degree 12 rational approximations to x^(1/4) and x^(-1/4)
|
||||
double lo = 0.0001;
|
||||
double hi = 95.0;
|
||||
int precision = 64;
|
||||
int degree = 12;
|
||||
AlgRemez remez(lo, hi, precision);
|
||||
std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
|
||||
remez.generateApprox(degree, 1, 4);
|
||||
MultiShiftFunction PowerQuarter(remez, stop_tol, false);
|
||||
MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
|
||||
|
||||
// Stochastically estimate reweighting factor via RHMC
|
||||
RealD scale = std::sqrt(0.5);
|
||||
std::vector<RealD> rw_rhmc(Nhits);
|
||||
ConjugateGradientMultiShift<LatticeFermion> msCG_V(max_iter, PowerQuarter);
|
||||
ConjugateGradientMultiShift<LatticeFermion> msCG_M(max_iter, PowerNegQuarter);
|
||||
std::cout.precision(12);
|
||||
|
||||
for(int hit=0; hit<Nhits; hit++){
|
||||
|
||||
// Gaussian source
|
||||
LatticeFermion Phi (Ddwf_f.FermionGrid());
|
||||
LatticeFermion PhiOdd (Ddwf_f.FermionRedBlackGrid());
|
||||
std::vector<LatticeFermion> tmp(2, Ddwf_f.FermionRedBlackGrid());
|
||||
gaussian(RNG5, Phi);
|
||||
Phi = Phi*scale;
|
||||
|
||||
pickCheckerboard(Odd, PhiOdd, Phi);
|
||||
|
||||
// evaluate -log(rw)
|
||||
msCG_V(VdagV, PhiOdd, tmp[0]);
|
||||
msCG_M(MdagM, tmp[0], tmp[1]);
|
||||
rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
|
||||
std::cout << std::endl << "==================================================" << std::endl;
|
||||
std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
|
||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
||||
|
||||
}
|
||||
|
||||
// Initialize EOFA fermion operators
|
||||
RealD shift_L = 0.0;
|
||||
RealD shift_R = -1.0;
|
||||
int pm = 1;
|
||||
DomainWallEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5);
|
||||
DomainWallEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5);
|
||||
MdagMLinearOperator<DomainWallEOFAFermionR, LatticeFermion> LdagL(Deofa_L);
|
||||
MdagMLinearOperator<DomainWallEOFAFermionR, LatticeFermion> RdagR(Deofa_R);
|
||||
|
||||
// Stochastically estimate reweighting factor via EOFA
|
||||
RealD k = Deofa_L.k;
|
||||
std::vector<RealD> rw_eofa(Nhits);
|
||||
ConjugateGradient<LatticeFermion> CG(stop_tol, max_iter);
|
||||
SchurRedBlackDiagMooeeSolve<LatticeFermion> SchurSolver(CG);
|
||||
|
||||
for(int hit=0; hit<Nhits; hit++){
|
||||
|
||||
// Gaussian source
|
||||
LatticeFermion Phi (Deofa_L.FermionGrid());
|
||||
LatticeFermion spProj_Phi(Deofa_L.FermionGrid());
|
||||
std::vector<LatticeFermion> tmp(2, Deofa_L.FermionGrid());
|
||||
gaussian(RNG5, Phi);
|
||||
Phi = Phi*scale;
|
||||
|
||||
// evaluate -log(rw)
|
||||
// LH term
|
||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
||||
Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
|
||||
G5R5(tmp[1], tmp[0]);
|
||||
tmp[0] = zero;
|
||||
SchurSolver(Deofa_L, tmp[1], tmp[0]);
|
||||
Deofa_L.Omega(tmp[0], tmp[1], -1, 1);
|
||||
rw_eofa[hit] = -k*innerProduct(spProj_Phi,tmp[1]).real();
|
||||
|
||||
// RH term
|
||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
||||
Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
|
||||
G5R5(tmp[1], tmp[0]);
|
||||
tmp[0] = zero;
|
||||
SchurSolver(Deofa_R, tmp[1], tmp[0]);
|
||||
Deofa_R.Omega(tmp[0], tmp[1], 1, 1);
|
||||
rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[1]).real();
|
||||
std::cout << std::endl << "==================================================" << std::endl;
|
||||
std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
|
||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
|
||||
std::vector<RealD> eofa_result = jack_stats(rw_eofa);
|
||||
std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
|
||||
std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
|
||||
|
||||
Grid_finalize();
|
||||
}
|
209
tests/debug/Test_reweight_dwf_eofa_gparity.cc
Normal file
209
tests/debug/Test_reweight_dwf_eofa_gparity.cc
Normal file
@ -0,0 +1,209 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/debug/Test_reweight_dwf_eofa_gparity.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
typedef typename GparityDomainWallFermionR::FermionField FermionField;
|
||||
|
||||
// parameters for test
|
||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
||||
const int Ls = 8;
|
||||
const int Nhits = 10;
|
||||
const int max_iter = 5000;
|
||||
const RealD mf = 0.1;
|
||||
const RealD mb = 0.11;
|
||||
const RealD M5 = 1.8;
|
||||
const RealD stop_tol = 1.0e-12;
|
||||
|
||||
RealD mean(const std::vector<RealD>& data)
|
||||
{
|
||||
int N = data.size();
|
||||
RealD mean(0.0);
|
||||
for(int i=0; i<N; ++i){ mean += data[i]; }
|
||||
return mean/RealD(N);
|
||||
}
|
||||
|
||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
|
||||
{
|
||||
int N = data.size();
|
||||
RealD mean(0.0);
|
||||
for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
|
||||
return mean/RealD(N-1);
|
||||
}
|
||||
|
||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
|
||||
{
|
||||
int N = jacks.size();
|
||||
RealD std(0.0);
|
||||
for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
|
||||
return std::sqrt(RealD(N-1)/RealD(N)*std);
|
||||
}
|
||||
|
||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
|
||||
{
|
||||
int N = data.size();
|
||||
std::vector<RealD> jack_samples(N);
|
||||
std::vector<RealD> jack_stats(2);
|
||||
|
||||
jack_stats[0] = mean(data);
|
||||
for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
|
||||
jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
|
||||
return jack_stats;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
// Initialize spacetime grid
|
||||
std::cout << GridLogMessage << "Lattice dimensions: "
|
||||
<< grid_dim << " Ls: " << Ls << std::endl;
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
||||
GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Set up RNGs
|
||||
std::vector<int> seeds4({1, 2, 3, 4});
|
||||
std::vector<int> seeds5({5, 6, 7, 8});
|
||||
GridParallelRNG RNG5(FGrid);
|
||||
RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid);
|
||||
RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
// Random gauge field
|
||||
LatticeGaugeField Umu(UGrid);
|
||||
SU3::HotConfiguration(RNG4, Umu);
|
||||
|
||||
// Initialize RHMC fermion operators
|
||||
GparityDomainWallFermionR::ImplParams params;
|
||||
GparityDomainWallFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5, params);
|
||||
GparityDomainWallFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5, params);
|
||||
SchurDiagMooeeOperator<GparityDomainWallFermionR, FermionField> MdagM(Ddwf_f);
|
||||
SchurDiagMooeeOperator<GparityDomainWallFermionR, FermionField> VdagV(Ddwf_b);
|
||||
|
||||
// Degree 12 rational approximations to x^(1/4) and x^(-1/4)
|
||||
double lo = 0.0001;
|
||||
double hi = 95.0;
|
||||
int precision = 64;
|
||||
int degree = 12;
|
||||
AlgRemez remez(lo, hi, precision);
|
||||
std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
|
||||
remez.generateApprox(degree, 1, 4);
|
||||
MultiShiftFunction PowerQuarter(remez, stop_tol, false);
|
||||
MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
|
||||
|
||||
// Stochastically estimate reweighting factor via RHMC
|
||||
RealD scale = std::sqrt(0.5);
|
||||
std::vector<RealD> rw_rhmc(Nhits);
|
||||
ConjugateGradientMultiShift<FermionField> msCG_V(max_iter, PowerQuarter);
|
||||
ConjugateGradientMultiShift<FermionField> msCG_M(max_iter, PowerNegQuarter);
|
||||
std::cout.precision(12);
|
||||
|
||||
for(int hit=0; hit<Nhits; hit++){
|
||||
|
||||
// Gaussian source
|
||||
FermionField Phi (Ddwf_f.FermionGrid());
|
||||
FermionField PhiOdd (Ddwf_f.FermionRedBlackGrid());
|
||||
std::vector<FermionField> tmp(2, Ddwf_f.FermionRedBlackGrid());
|
||||
gaussian(RNG5, Phi);
|
||||
Phi = Phi*scale;
|
||||
|
||||
pickCheckerboard(Odd, PhiOdd, Phi);
|
||||
|
||||
// evaluate -log(rw)
|
||||
msCG_V(VdagV, PhiOdd, tmp[0]);
|
||||
msCG_M(MdagM, tmp[0], tmp[1]);
|
||||
rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
|
||||
std::cout << std::endl << "==================================================" << std::endl;
|
||||
std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
|
||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
||||
|
||||
}
|
||||
|
||||
// Initialize EOFA fermion operators
|
||||
RealD shift_L = 0.0;
|
||||
RealD shift_R = -1.0;
|
||||
int pm = 1;
|
||||
GparityDomainWallEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5, params);
|
||||
GparityDomainWallEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5, params);
|
||||
MdagMLinearOperator<GparityDomainWallEOFAFermionR, FermionField> LdagL(Deofa_L);
|
||||
MdagMLinearOperator<GparityDomainWallEOFAFermionR, FermionField> RdagR(Deofa_R);
|
||||
|
||||
// Stochastically estimate reweighting factor via EOFA
|
||||
RealD k = Deofa_L.k;
|
||||
std::vector<RealD> rw_eofa(Nhits);
|
||||
ConjugateGradient<FermionField> CG(stop_tol, max_iter);
|
||||
SchurRedBlackDiagMooeeSolve<FermionField> SchurSolver(CG);
|
||||
|
||||
for(int hit=0; hit<Nhits; hit++){
|
||||
|
||||
// Gaussian source
|
||||
FermionField Phi (Deofa_L.FermionGrid());
|
||||
FermionField spProj_Phi(Deofa_L.FermionGrid());
|
||||
std::vector<FermionField> tmp(2, Deofa_L.FermionGrid());
|
||||
gaussian(RNG5, Phi);
|
||||
Phi = Phi*scale;
|
||||
|
||||
// evaluate -log(rw)
|
||||
// LH term
|
||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
||||
Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
|
||||
G5R5(tmp[1], tmp[0]);
|
||||
tmp[0] = zero;
|
||||
SchurSolver(Deofa_L, tmp[1], tmp[0]);
|
||||
Deofa_L.Omega(tmp[0], tmp[1], -1, 1);
|
||||
rw_eofa[hit] = -k*innerProduct(spProj_Phi,tmp[1]).real();
|
||||
|
||||
// RH term
|
||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
||||
Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
|
||||
G5R5(tmp[1], tmp[0]);
|
||||
tmp[0] = zero;
|
||||
SchurSolver(Deofa_R, tmp[1], tmp[0]);
|
||||
Deofa_R.Omega(tmp[0], tmp[1], 1, 1);
|
||||
rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[1]).real();
|
||||
std::cout << std::endl << "==================================================" << std::endl;
|
||||
std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
|
||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
|
||||
std::vector<RealD> eofa_result = jack_stats(rw_eofa);
|
||||
std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
|
||||
std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
|
||||
|
||||
Grid_finalize();
|
||||
}
|
215
tests/debug/Test_reweight_mobius_eofa.cc
Normal file
215
tests/debug/Test_reweight_mobius_eofa.cc
Normal file
@ -0,0 +1,215 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/debug/Test_reweight_dwf_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
// parameters for test
|
||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
||||
const int Ls = 8;
|
||||
const int Nhits = 10;
|
||||
const int max_iter = 5000;
|
||||
const RealD b = 2.5;
|
||||
const RealD c = 1.5;
|
||||
const RealD mf = 0.1;
|
||||
const RealD mb = 0.11;
|
||||
const RealD M5 = 1.8;
|
||||
const RealD stop_tol = 1.0e-12;
|
||||
|
||||
RealD mean(const std::vector<RealD>& data)
|
||||
{
|
||||
int N = data.size();
|
||||
RealD mean(0.0);
|
||||
for(int i=0; i<N; ++i){ mean += data[i]; }
|
||||
return mean/RealD(N);
|
||||
}
|
||||
|
||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
|
||||
{
|
||||
int N = data.size();
|
||||
RealD mean(0.0);
|
||||
for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
|
||||
return mean/RealD(N-1);
|
||||
}
|
||||
|
||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
|
||||
{
|
||||
int N = jacks.size();
|
||||
RealD std(0.0);
|
||||
for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
|
||||
return std::sqrt(RealD(N-1)/RealD(N)*std);
|
||||
}
|
||||
|
||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
|
||||
{
|
||||
int N = data.size();
|
||||
std::vector<RealD> jack_samples(N);
|
||||
std::vector<RealD> jack_stats(2);
|
||||
|
||||
jack_stats[0] = mean(data);
|
||||
for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
|
||||
jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
|
||||
return jack_stats;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
// Initialize spacetime grid
|
||||
std::cout << GridLogMessage << "Lattice dimensions: "
|
||||
<< grid_dim << " Ls: " << Ls << std::endl;
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
||||
GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Set up RNGs
|
||||
std::vector<int> seeds4({1, 2, 3, 4});
|
||||
std::vector<int> seeds5({5, 6, 7, 8});
|
||||
GridParallelRNG RNG5(FGrid);
|
||||
RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid);
|
||||
RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
// Random gauge field
|
||||
LatticeGaugeField Umu(UGrid);
|
||||
SU3::HotConfiguration(RNG4, Umu);
|
||||
|
||||
// Initialize RHMC fermion operators
|
||||
MobiusFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5, b, c);
|
||||
MobiusFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5, b, c);
|
||||
SchurDiagMooeeOperator<MobiusFermionR, LatticeFermion> MdagM(Ddwf_f);
|
||||
SchurDiagMooeeOperator<MobiusFermionR, LatticeFermion> VdagV(Ddwf_b);
|
||||
|
||||
// Degree 12 rational approximations to x^(1/4) and x^(-1/4)
|
||||
double lo = 0.0001;
|
||||
double hi = 95.0;
|
||||
int precision = 64;
|
||||
int degree = 12;
|
||||
AlgRemez remez(lo, hi, precision);
|
||||
std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
|
||||
remez.generateApprox(degree, 1, 4);
|
||||
MultiShiftFunction PowerQuarter(remez, stop_tol, false);
|
||||
MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
|
||||
|
||||
// Stochastically estimate reweighting factor via RHMC
|
||||
RealD scale = std::sqrt(0.5);
|
||||
std::vector<RealD> rw_rhmc(Nhits);
|
||||
ConjugateGradientMultiShift<LatticeFermion> msCG_V(max_iter, PowerQuarter);
|
||||
ConjugateGradientMultiShift<LatticeFermion> msCG_M(max_iter, PowerNegQuarter);
|
||||
std::cout.precision(12);
|
||||
|
||||
for(int hit=0; hit<Nhits; hit++){
|
||||
|
||||
// Gaussian source
|
||||
LatticeFermion Phi (Ddwf_f.FermionGrid());
|
||||
LatticeFermion PhiOdd (Ddwf_f.FermionRedBlackGrid());
|
||||
std::vector<LatticeFermion> tmp(2, Ddwf_f.FermionRedBlackGrid());
|
||||
gaussian(RNG5, Phi);
|
||||
Phi = Phi*scale;
|
||||
|
||||
pickCheckerboard(Odd, PhiOdd, Phi);
|
||||
|
||||
// evaluate -log(rw)
|
||||
msCG_V(VdagV, PhiOdd, tmp[0]);
|
||||
msCG_M(MdagM, tmp[0], tmp[1]);
|
||||
rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
|
||||
std::cout << std::endl << "==================================================" << std::endl;
|
||||
std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
|
||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
||||
|
||||
}
|
||||
|
||||
// Initialize EOFA fermion operators
|
||||
RealD shift_L = 0.0;
|
||||
RealD shift_R = -1.0;
|
||||
int pm = 1;
|
||||
MobiusEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5, b, c);
|
||||
MobiusEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5, b, c);
|
||||
MdagMLinearOperator<MobiusEOFAFermionR, LatticeFermion> LdagL(Deofa_L);
|
||||
MdagMLinearOperator<MobiusEOFAFermionR, LatticeFermion> RdagR(Deofa_R);
|
||||
|
||||
// Stochastically estimate reweighting factor via EOFA
|
||||
RealD k = Deofa_L.k;
|
||||
std::vector<RealD> rw_eofa(Nhits);
|
||||
ConjugateGradient<LatticeFermion> CG(stop_tol, max_iter);
|
||||
SchurRedBlackDiagMooeeSolve<LatticeFermion> SchurSolver(CG);
|
||||
|
||||
// Compute -log(Z), where: ( RHMC det ratio ) = Z * ( EOFA det ratio )
|
||||
RealD Z = std::pow(b+c+1.0,Ls) + mf*std::pow(b+c-1.0,Ls);
|
||||
Z /= std::pow(b+c+1.0,Ls) + mb*std::pow(b+c-1.0,Ls);
|
||||
Z = -12.0*grid_dim[0]*grid_dim[1]*grid_dim[2]*grid_dim[3]*std::log(Z);
|
||||
|
||||
for(int hit=0; hit<Nhits; hit++){
|
||||
|
||||
// Gaussian source
|
||||
LatticeFermion Phi (Deofa_L.FermionGrid());
|
||||
LatticeFermion spProj_Phi(Deofa_L.FermionGrid());
|
||||
std::vector<LatticeFermion> tmp(2, Deofa_L.FermionGrid());
|
||||
gaussian(RNG5, Phi);
|
||||
Phi = Phi*scale;
|
||||
|
||||
// evaluate -log(rw)
|
||||
// LH term
|
||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
||||
Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
|
||||
G5R5(tmp[1], tmp[0]);
|
||||
tmp[0] = zero;
|
||||
SchurSolver(Deofa_L, tmp[1], tmp[0]);
|
||||
Deofa_L.Dtilde(tmp[0], tmp[1]);
|
||||
Deofa_L.Omega(tmp[1], tmp[0], -1, 1);
|
||||
rw_eofa[hit] = Z - k*innerProduct(spProj_Phi,tmp[0]).real();
|
||||
|
||||
// RH term
|
||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
||||
Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
|
||||
G5R5(tmp[1], tmp[0]);
|
||||
tmp[0] = zero;
|
||||
SchurSolver(Deofa_R, tmp[1], tmp[0]);
|
||||
Deofa_R.Dtilde(tmp[0], tmp[1]);
|
||||
Deofa_R.Omega(tmp[1], tmp[0], 1, 1);
|
||||
rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[0]).real();
|
||||
std::cout << std::endl << "==================================================" << std::endl;
|
||||
std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
|
||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
|
||||
std::vector<RealD> eofa_result = jack_stats(rw_eofa);
|
||||
std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
|
||||
std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
|
||||
|
||||
Grid_finalize();
|
||||
}
|
218
tests/debug/Test_reweight_mobius_eofa_gparity.cc
Normal file
218
tests/debug/Test_reweight_mobius_eofa_gparity.cc
Normal file
@ -0,0 +1,218 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/debug/Test_reweight_dwf_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
typedef typename GparityDomainWallFermionR::FermionField FermionField;
|
||||
|
||||
// parameters for test
|
||||
const std::vector<int> grid_dim = { 8, 8, 8, 8 };
|
||||
const int Ls = 8;
|
||||
const int Nhits = 10;
|
||||
const int max_iter = 5000;
|
||||
const RealD b = 2.5;
|
||||
const RealD c = 1.5;
|
||||
const RealD mf = 0.1;
|
||||
const RealD mb = 0.11;
|
||||
const RealD M5 = 1.8;
|
||||
const RealD stop_tol = 1.0e-12;
|
||||
|
||||
RealD mean(const std::vector<RealD>& data)
|
||||
{
|
||||
int N = data.size();
|
||||
RealD mean(0.0);
|
||||
for(int i=0; i<N; ++i){ mean += data[i]; }
|
||||
return mean/RealD(N);
|
||||
}
|
||||
|
||||
RealD jack_mean(const std::vector<RealD>& data, int sample)
|
||||
{
|
||||
int N = data.size();
|
||||
RealD mean(0.0);
|
||||
for(int i=0; i<N; ++i){ if(i != sample){ mean += data[i]; } }
|
||||
return mean/RealD(N-1);
|
||||
}
|
||||
|
||||
RealD jack_std(const std::vector<RealD>& jacks, RealD mean)
|
||||
{
|
||||
int N = jacks.size();
|
||||
RealD std(0.0);
|
||||
for(int i=0; i<N; ++i){ std += std::pow(jacks[i]-mean, 2.0); }
|
||||
return std::sqrt(RealD(N-1)/RealD(N)*std);
|
||||
}
|
||||
|
||||
std::vector<RealD> jack_stats(const std::vector<RealD>& data)
|
||||
{
|
||||
int N = data.size();
|
||||
std::vector<RealD> jack_samples(N);
|
||||
std::vector<RealD> jack_stats(2);
|
||||
|
||||
jack_stats[0] = mean(data);
|
||||
for(int i=0; i<N; i++){ jack_samples[i] = jack_mean(data,i); }
|
||||
jack_stats[1] = jack_std(jack_samples, jack_stats[0]);
|
||||
return jack_stats;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
// Initialize spacetime grid
|
||||
std::cout << GridLogMessage << "Lattice dimensions: "
|
||||
<< grid_dim << " Ls: " << Ls << std::endl;
|
||||
GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(grid_dim,
|
||||
GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Set up RNGs
|
||||
std::vector<int> seeds4({1, 2, 3, 4});
|
||||
std::vector<int> seeds5({5, 6, 7, 8});
|
||||
GridParallelRNG RNG5(FGrid);
|
||||
RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid);
|
||||
RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
// Random gauge field
|
||||
LatticeGaugeField Umu(UGrid);
|
||||
SU3::HotConfiguration(RNG4, Umu);
|
||||
|
||||
// Initialize RHMC fermion operators
|
||||
GparityDomainWallFermionR::ImplParams params;
|
||||
GparityMobiusFermionR Ddwf_f(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, M5, b, c, params);
|
||||
GparityMobiusFermionR Ddwf_b(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, M5, b, c, params);
|
||||
SchurDiagMooeeOperator<GparityMobiusFermionR, FermionField> MdagM(Ddwf_f);
|
||||
SchurDiagMooeeOperator<GparityMobiusFermionR, FermionField> VdagV(Ddwf_b);
|
||||
|
||||
// Degree 12 rational approximations to x^(1/4) and x^(-1/4)
|
||||
double lo = 0.0001;
|
||||
double hi = 95.0;
|
||||
int precision = 64;
|
||||
int degree = 12;
|
||||
AlgRemez remez(lo, hi, precision);
|
||||
std::cout << GridLogMessage << "Generating degree " << degree << " for x^(1/4)" << std::endl;
|
||||
remez.generateApprox(degree, 1, 4);
|
||||
MultiShiftFunction PowerQuarter(remez, stop_tol, false);
|
||||
MultiShiftFunction PowerNegQuarter(remez, stop_tol, true);
|
||||
|
||||
// Stochastically estimate reweighting factor via RHMC
|
||||
RealD scale = std::sqrt(0.5);
|
||||
std::vector<RealD> rw_rhmc(Nhits);
|
||||
ConjugateGradientMultiShift<FermionField> msCG_V(max_iter, PowerQuarter);
|
||||
ConjugateGradientMultiShift<FermionField> msCG_M(max_iter, PowerNegQuarter);
|
||||
std::cout.precision(12);
|
||||
|
||||
for(int hit=0; hit<Nhits; hit++){
|
||||
|
||||
// Gaussian source
|
||||
FermionField Phi (Ddwf_f.FermionGrid());
|
||||
FermionField PhiOdd (Ddwf_f.FermionRedBlackGrid());
|
||||
std::vector<FermionField> tmp(2, Ddwf_f.FermionRedBlackGrid());
|
||||
gaussian(RNG5, Phi);
|
||||
Phi = Phi*scale;
|
||||
|
||||
pickCheckerboard(Odd, PhiOdd, Phi);
|
||||
|
||||
// evaluate -log(rw)
|
||||
msCG_V(VdagV, PhiOdd, tmp[0]);
|
||||
msCG_M(MdagM, tmp[0], tmp[1]);
|
||||
rw_rhmc[hit] = norm2(tmp[1]) - norm2(PhiOdd);
|
||||
std::cout << std::endl << "==================================================" << std::endl;
|
||||
std::cout << " --- RHMC: Hit " << hit << ": rw = " << rw_rhmc[hit];
|
||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
||||
|
||||
}
|
||||
|
||||
// Initialize EOFA fermion operators
|
||||
RealD shift_L = 0.0;
|
||||
RealD shift_R = -1.0;
|
||||
int pm = 1;
|
||||
GparityMobiusEOFAFermionR Deofa_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5, b, c, params);
|
||||
GparityMobiusEOFAFermionR Deofa_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5, b, c, params);
|
||||
MdagMLinearOperator<GparityMobiusEOFAFermionR, FermionField> LdagL(Deofa_L);
|
||||
MdagMLinearOperator<GparityMobiusEOFAFermionR, FermionField> RdagR(Deofa_R);
|
||||
|
||||
// Stochastically estimate reweighting factor via EOFA
|
||||
RealD k = Deofa_L.k;
|
||||
std::vector<RealD> rw_eofa(Nhits);
|
||||
ConjugateGradient<FermionField> CG(stop_tol, max_iter);
|
||||
SchurRedBlackDiagMooeeSolve<FermionField> SchurSolver(CG);
|
||||
|
||||
// Compute -log(Z), where: ( RHMC det ratio ) = Z * ( EOFA det ratio )
|
||||
RealD Z = std::pow(b+c+1.0,Ls) + mf*std::pow(b+c-1.0,Ls);
|
||||
Z /= std::pow(b+c+1.0,Ls) + mb*std::pow(b+c-1.0,Ls);
|
||||
Z = -12.0*grid_dim[0]*grid_dim[1]*grid_dim[2]*grid_dim[3]*std::log(Z);
|
||||
|
||||
for(int hit=0; hit<Nhits; hit++){
|
||||
|
||||
// Gaussian source
|
||||
FermionField Phi (Deofa_L.FermionGrid());
|
||||
FermionField spProj_Phi(Deofa_L.FermionGrid());
|
||||
std::vector<FermionField> tmp(2, Deofa_L.FermionGrid());
|
||||
gaussian(RNG5, Phi);
|
||||
Phi = Phi*scale;
|
||||
|
||||
// evaluate -log(rw)
|
||||
// LH term
|
||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pminus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
||||
Deofa_L.Omega(spProj_Phi, tmp[0], -1, 0);
|
||||
G5R5(tmp[1], tmp[0]);
|
||||
tmp[0] = zero;
|
||||
SchurSolver(Deofa_L, tmp[1], tmp[0]);
|
||||
Deofa_L.Dtilde(tmp[0], tmp[1]);
|
||||
Deofa_L.Omega(tmp[1], tmp[0], -1, 1);
|
||||
rw_eofa[hit] = 2.0*Z - k*innerProduct(spProj_Phi,tmp[0]).real();
|
||||
|
||||
// RH term
|
||||
for(int s=0; s<Ls; ++s){ axpby_ssp_pplus(spProj_Phi, 0.0, Phi, 1.0, Phi, s, s); }
|
||||
Deofa_R.Omega(spProj_Phi, tmp[0], 1, 0);
|
||||
G5R5(tmp[1], tmp[0]);
|
||||
tmp[0] = zero;
|
||||
SchurSolver(Deofa_R, tmp[1], tmp[0]);
|
||||
Deofa_R.Dtilde(tmp[0], tmp[1]);
|
||||
Deofa_R.Omega(tmp[1], tmp[0], 1, 1);
|
||||
rw_eofa[hit] += k*innerProduct(spProj_Phi,tmp[0]).real();
|
||||
std::cout << std::endl << "==================================================" << std::endl;
|
||||
std::cout << " --- EOFA: Hit " << hit << ": rw = " << rw_eofa[hit];
|
||||
std::cout << std::endl << "==================================================" << std::endl << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::vector<RealD> rhmc_result = jack_stats(rw_rhmc);
|
||||
std::vector<RealD> eofa_result = jack_stats(rw_eofa);
|
||||
std::cout << std::endl << "RHMC: rw = " << rhmc_result[0] << " +/- " << rhmc_result[1] << std::endl;
|
||||
std::cout << std::endl << "EOFA: rw = " << eofa_result[0] << " +/- " << eofa_result[1] << std::endl;
|
||||
|
||||
Grid_finalize();
|
||||
}
|
164
tests/forces/Test_dwf_force_eofa.cc
Normal file
164
tests/forces/Test_dwf_force_eofa.cc
Normal file
@ -0,0 +1,164 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
std::vector<int> latt_size = GridDefaultLatt();
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
|
||||
const int Ls = 8;
|
||||
|
||||
GridCartesian *UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian *FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Want a different conf at every run
|
||||
// First create an instance of an engine.
|
||||
std::random_device rnd_device;
|
||||
// Specify the engine and distribution.
|
||||
std::mt19937 mersenne_engine(rnd_device());
|
||||
std::uniform_int_distribution<int> dist(1, 100);
|
||||
|
||||
auto gen = std::bind(dist, mersenne_engine);
|
||||
std::vector<int> seeds4(4);
|
||||
generate(begin(seeds4), end(seeds4), gen);
|
||||
|
||||
//std::vector<int> seeds4({1,2,3,5});
|
||||
std::vector<int> seeds5({5,6,7,8});
|
||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
||||
|
||||
LatticeFermion phi (FGrid); gaussian(RNG5, phi);
|
||||
LatticeFermion Mphi (FGrid);
|
||||
LatticeFermion MphiPrime (FGrid);
|
||||
|
||||
LatticeGaugeField U(UGrid);
|
||||
SU3::HotConfiguration(RNG4,U);
|
||||
|
||||
////////////////////////////////////
|
||||
// Unmodified matrix element
|
||||
////////////////////////////////////
|
||||
RealD mf = 0.01;
|
||||
RealD mb = 1.0;
|
||||
RealD M5 = 1.8;
|
||||
DomainWallEOFAFermionR Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5);
|
||||
DomainWallEOFAFermionR Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5);
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, true);
|
||||
|
||||
Meofa.refresh(U, RNG5);
|
||||
RealD S = Meofa.S(U); // pdag M p
|
||||
|
||||
// get the deriv of phidag M phi with respect to "U"
|
||||
LatticeGaugeField UdSdU(UGrid);
|
||||
Meofa.deriv(U, UdSdU);
|
||||
|
||||
////////////////////////////////////
|
||||
// Modify the gauge field a little
|
||||
////////////////////////////////////
|
||||
RealD dt = 0.0001;
|
||||
|
||||
LatticeColourMatrix mommu(UGrid);
|
||||
LatticeColourMatrix forcemu(UGrid);
|
||||
LatticeGaugeField mom(UGrid);
|
||||
LatticeGaugeField Uprime(UGrid);
|
||||
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
|
||||
SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
|
||||
|
||||
PokeIndex<LorentzIndex>(mom, mommu, mu);
|
||||
|
||||
// fourth order exponential approx
|
||||
parallel_for(auto i=mom.begin(); i<mom.end(); i++){
|
||||
Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
|
||||
}
|
||||
}
|
||||
|
||||
/*Ddwf.ImportGauge(Uprime);
|
||||
Ddwf.M (phi,MphiPrime);
|
||||
|
||||
ComplexD Sprime = innerProduct(MphiPrime ,MphiPrime);*/
|
||||
RealD Sprime = Meofa.S(Uprime);
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Use derivative to estimate dS
|
||||
//////////////////////////////////////////////
|
||||
|
||||
LatticeComplex dS(UGrid);
|
||||
dS = zero;
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
||||
mommu = Ta(mommu)*2.0;
|
||||
PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
|
||||
}
|
||||
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
||||
mommu = PeekIndex<LorentzIndex>(mom, mu);
|
||||
|
||||
// Update PF action density
|
||||
dS = dS + trace(mommu*forcemu)*dt;
|
||||
}
|
||||
|
||||
ComplexD dSpred = sum(dS);
|
||||
|
||||
/*std::cout << GridLogMessage << " S " << S << std::endl;
|
||||
std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
|
||||
std::cout << GridLogMessage << "dS " << Sprime-S << std::endl;
|
||||
std::cout << GridLogMessage << "predict dS " << dSpred << std::endl;*/
|
||||
printf("\nS = %1.15e\n", S);
|
||||
printf("Sprime = %1.15e\n", Sprime);
|
||||
printf("dS = %1.15e\n", Sprime - S);
|
||||
printf("real(dS_predict) = %1.15e\n", dSpred.real());
|
||||
printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
|
||||
|
||||
assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
|
||||
|
||||
std::cout << GridLogMessage << "Done" << std::endl;
|
||||
Grid_finalize();
|
||||
}
|
169
tests/forces/Test_dwf_gpforce_eofa.cc
Normal file
169
tests/forces/Test_dwf_gpforce_eofa.cc
Normal file
@ -0,0 +1,169 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
typedef GparityWilsonImplR FermionImplPolicy;
|
||||
typedef GparityDomainWallEOFAFermionR FermionAction;
|
||||
typedef typename FermionAction::FermionField FermionField;
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
std::vector<int> latt_size = GridDefaultLatt();
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
|
||||
const int Ls = 8;
|
||||
|
||||
GridCartesian *UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian *FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Want a different conf at every run
|
||||
// First create an instance of an engine.
|
||||
std::random_device rnd_device;
|
||||
// Specify the engine and distribution.
|
||||
std::mt19937 mersenne_engine(rnd_device());
|
||||
std::uniform_int_distribution<int> dist(1, 100);
|
||||
|
||||
auto gen = std::bind(dist, mersenne_engine);
|
||||
std::vector<int> seeds4(4);
|
||||
generate(begin(seeds4), end(seeds4), gen);
|
||||
|
||||
//std::vector<int> seeds4({1,2,3,5});
|
||||
std::vector<int> seeds5({5,6,7,8});
|
||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
||||
|
||||
FermionField phi (FGrid); gaussian(RNG5, phi);
|
||||
FermionField Mphi (FGrid);
|
||||
FermionField MphiPrime (FGrid);
|
||||
|
||||
LatticeGaugeField U(UGrid);
|
||||
SU3::HotConfiguration(RNG4,U);
|
||||
|
||||
////////////////////////////////////
|
||||
// Unmodified matrix element
|
||||
////////////////////////////////////
|
||||
RealD mf = 0.01;
|
||||
RealD mb = 1.0;
|
||||
RealD M5 = 1.8;
|
||||
FermionAction::ImplParams params;
|
||||
FermionAction Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5, params);
|
||||
FermionAction Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5, params);
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
|
||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, true);
|
||||
|
||||
Meofa.refresh(U, RNG5);
|
||||
RealD S = Meofa.S(U); // pdag M p
|
||||
|
||||
// get the deriv of phidag M phi with respect to "U"
|
||||
LatticeGaugeField UdSdU(UGrid);
|
||||
Meofa.deriv(U, UdSdU);
|
||||
|
||||
////////////////////////////////////
|
||||
// Modify the gauge field a little
|
||||
////////////////////////////////////
|
||||
RealD dt = 0.0001;
|
||||
|
||||
LatticeColourMatrix mommu(UGrid);
|
||||
LatticeColourMatrix forcemu(UGrid);
|
||||
LatticeGaugeField mom(UGrid);
|
||||
LatticeGaugeField Uprime(UGrid);
|
||||
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
|
||||
SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
|
||||
|
||||
PokeIndex<LorentzIndex>(mom, mommu, mu);
|
||||
|
||||
// fourth order exponential approx
|
||||
parallel_for(auto i=mom.begin(); i<mom.end(); i++){
|
||||
Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
|
||||
}
|
||||
}
|
||||
|
||||
/*Ddwf.ImportGauge(Uprime);
|
||||
Ddwf.M (phi,MphiPrime);
|
||||
|
||||
ComplexD Sprime = innerProduct(MphiPrime ,MphiPrime);*/
|
||||
RealD Sprime = Meofa.S(Uprime);
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Use derivative to estimate dS
|
||||
//////////////////////////////////////////////
|
||||
|
||||
LatticeComplex dS(UGrid);
|
||||
dS = zero;
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
||||
mommu = Ta(mommu)*2.0;
|
||||
PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
|
||||
}
|
||||
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
||||
mommu = PeekIndex<LorentzIndex>(mom, mu);
|
||||
|
||||
// Update PF action density
|
||||
dS = dS + trace(mommu*forcemu)*dt;
|
||||
}
|
||||
|
||||
ComplexD dSpred = sum(dS);
|
||||
|
||||
/*std::cout << GridLogMessage << " S " << S << std::endl;
|
||||
std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
|
||||
std::cout << GridLogMessage << "dS " << Sprime-S << std::endl;
|
||||
std::cout << GridLogMessage << "predict dS " << dSpred << std::endl;*/
|
||||
printf("\nS = %1.15e\n", S);
|
||||
printf("Sprime = %1.15e\n", Sprime);
|
||||
printf("dS = %1.15e\n", Sprime - S);
|
||||
printf("real(dS_predict) = %1.15e\n", dSpred.real());
|
||||
printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
|
||||
|
||||
assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
|
||||
|
||||
std::cout << GridLogMessage << "Done" << std::endl;
|
||||
Grid_finalize();
|
||||
}
|
@ -42,7 +42,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||
|
@ -42,7 +42,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||
|
166
tests/forces/Test_mobius_force_eofa.cc
Normal file
166
tests/forces/Test_mobius_force_eofa.cc
Normal file
@ -0,0 +1,166 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
std::vector<int> latt_size = GridDefaultLatt();
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
|
||||
const int Ls = 8;
|
||||
|
||||
GridCartesian *UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian *FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Want a different conf at every run
|
||||
// First create an instance of an engine.
|
||||
std::random_device rnd_device;
|
||||
// Specify the engine and distribution.
|
||||
std::mt19937 mersenne_engine(rnd_device());
|
||||
std::uniform_int_distribution<int> dist(1, 100);
|
||||
|
||||
auto gen = std::bind(dist, mersenne_engine);
|
||||
std::vector<int> seeds4(4);
|
||||
generate(begin(seeds4), end(seeds4), gen);
|
||||
|
||||
//std::vector<int> seeds4({1,2,3,5});
|
||||
std::vector<int> seeds5({5,6,7,8});
|
||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
||||
|
||||
LatticeFermion phi (FGrid); gaussian(RNG5, phi);
|
||||
LatticeFermion Mphi (FGrid);
|
||||
LatticeFermion MphiPrime (FGrid);
|
||||
|
||||
LatticeGaugeField U(UGrid);
|
||||
SU3::HotConfiguration(RNG4,U);
|
||||
|
||||
////////////////////////////////////
|
||||
// Unmodified matrix element
|
||||
////////////////////////////////////
|
||||
RealD b = 2.5;
|
||||
RealD c = 1.5;
|
||||
RealD mf = 0.01;
|
||||
RealD mb = 1.0;
|
||||
RealD M5 = 1.8;
|
||||
MobiusEOFAFermionR Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5, b, c);
|
||||
MobiusEOFAFermionR Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5, b, c);
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, Params, false);
|
||||
|
||||
Meofa.refresh(U, RNG5);
|
||||
RealD S = Meofa.S(U); // pdag M p
|
||||
|
||||
// get the deriv of phidag M phi with respect to "U"
|
||||
LatticeGaugeField UdSdU(UGrid);
|
||||
Meofa.deriv(U, UdSdU);
|
||||
|
||||
////////////////////////////////////
|
||||
// Modify the gauge field a little
|
||||
////////////////////////////////////
|
||||
RealD dt = 0.0001;
|
||||
|
||||
LatticeColourMatrix mommu(UGrid);
|
||||
LatticeColourMatrix forcemu(UGrid);
|
||||
LatticeGaugeField mom(UGrid);
|
||||
LatticeGaugeField Uprime(UGrid);
|
||||
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
|
||||
SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
|
||||
|
||||
PokeIndex<LorentzIndex>(mom, mommu, mu);
|
||||
|
||||
// fourth order exponential approx
|
||||
parallel_for(auto i=mom.begin(); i<mom.end(); i++){
|
||||
Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
|
||||
}
|
||||
}
|
||||
|
||||
/*Ddwf.ImportGauge(Uprime);
|
||||
Ddwf.M (phi,MphiPrime);
|
||||
|
||||
ComplexD Sprime = innerProduct(MphiPrime ,MphiPrime);*/
|
||||
RealD Sprime = Meofa.S(Uprime);
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Use derivative to estimate dS
|
||||
//////////////////////////////////////////////
|
||||
|
||||
LatticeComplex dS(UGrid);
|
||||
dS = zero;
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
||||
mommu = Ta(mommu)*2.0;
|
||||
PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
|
||||
}
|
||||
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
||||
mommu = PeekIndex<LorentzIndex>(mom, mu);
|
||||
|
||||
// Update PF action density
|
||||
dS = dS + trace(mommu*forcemu)*dt;
|
||||
}
|
||||
|
||||
ComplexD dSpred = sum(dS);
|
||||
|
||||
/*std::cout << GridLogMessage << " S " << S << std::endl;
|
||||
std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
|
||||
std::cout << GridLogMessage << "dS " << Sprime-S << std::endl;
|
||||
std::cout << GridLogMessage << "predict dS " << dSpred << std::endl;*/
|
||||
printf("\nS = %1.15e\n", S);
|
||||
printf("Sprime = %1.15e\n", Sprime);
|
||||
printf("dS = %1.15e\n", Sprime - S);
|
||||
printf("real(dS_predict) = %1.15e\n", dSpred.real());
|
||||
printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
|
||||
|
||||
assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
|
||||
|
||||
std::cout << GridLogMessage << "Done" << std::endl;
|
||||
Grid_finalize();
|
||||
}
|
171
tests/forces/Test_mobius_gpforce_eofa.cc
Normal file
171
tests/forces/Test_mobius_gpforce_eofa.cc
Normal file
@ -0,0 +1,171 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/forces/Test_dwf_force_eofa.cc
|
||||
|
||||
Copyright (C) 2017
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: David Murphy <dmurphy@phys.columbia.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 */
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
typedef GparityWilsonImplR FermionImplPolicy;
|
||||
typedef GparityMobiusEOFAFermionR FermionAction;
|
||||
typedef typename FermionAction::FermionField FermionField;
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
std::vector<int> latt_size = GridDefaultLatt();
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
|
||||
const int Ls = 8;
|
||||
|
||||
GridCartesian *UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian *UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian *FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
|
||||
GridRedBlackCartesian *FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
|
||||
|
||||
// Want a different conf at every run
|
||||
// First create an instance of an engine.
|
||||
std::random_device rnd_device;
|
||||
// Specify the engine and distribution.
|
||||
std::mt19937 mersenne_engine(rnd_device());
|
||||
std::uniform_int_distribution<int> dist(1, 100);
|
||||
|
||||
auto gen = std::bind(dist, mersenne_engine);
|
||||
std::vector<int> seeds4(4);
|
||||
generate(begin(seeds4), end(seeds4), gen);
|
||||
|
||||
//std::vector<int> seeds4({1,2,3,5});
|
||||
std::vector<int> seeds5({5,6,7,8});
|
||||
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
|
||||
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
|
||||
|
||||
FermionField phi (FGrid); gaussian(RNG5, phi);
|
||||
FermionField Mphi (FGrid);
|
||||
FermionField MphiPrime (FGrid);
|
||||
|
||||
LatticeGaugeField U(UGrid);
|
||||
SU3::HotConfiguration(RNG4,U);
|
||||
|
||||
////////////////////////////////////
|
||||
// Unmodified matrix element
|
||||
////////////////////////////////////
|
||||
RealD b = 2.5;
|
||||
RealD c = 1.5;
|
||||
RealD mf = 0.01;
|
||||
RealD mb = 1.0;
|
||||
RealD M5 = 1.8;
|
||||
FermionAction::ImplParams params;
|
||||
FermionAction Lop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, 0.0, -1, M5, b, c, params);
|
||||
FermionAction Rop(U, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, -1.0, 1, M5, b, c, params);
|
||||
OneFlavourRationalParams Params(0.95, 100.0, 5000, 1.0e-12, 12);
|
||||
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
|
||||
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, Params, false);
|
||||
|
||||
Meofa.refresh(U, RNG5);
|
||||
RealD S = Meofa.S(U); // pdag M p
|
||||
|
||||
// get the deriv of phidag M phi with respect to "U"
|
||||
LatticeGaugeField UdSdU(UGrid);
|
||||
Meofa.deriv(U, UdSdU);
|
||||
|
||||
////////////////////////////////////
|
||||
// Modify the gauge field a little
|
||||
////////////////////////////////////
|
||||
RealD dt = 0.0001;
|
||||
|
||||
LatticeColourMatrix mommu(UGrid);
|
||||
LatticeColourMatrix forcemu(UGrid);
|
||||
LatticeGaugeField mom(UGrid);
|
||||
LatticeGaugeField Uprime(UGrid);
|
||||
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
|
||||
SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
|
||||
|
||||
PokeIndex<LorentzIndex>(mom, mommu, mu);
|
||||
|
||||
// fourth order exponential approx
|
||||
parallel_for(auto i=mom.begin(); i<mom.end(); i++){
|
||||
Uprime[i](mu) = U[i](mu) + mom[i](mu)*U[i](mu)*dt + mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt/2.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt/6.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt/24.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt/120.0)
|
||||
+ mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *mom[i](mu) *U[i](mu)*(dt*dt*dt*dt*dt*dt/720.0);
|
||||
}
|
||||
}
|
||||
|
||||
/*Ddwf.ImportGauge(Uprime);
|
||||
Ddwf.M (phi,MphiPrime);
|
||||
|
||||
ComplexD Sprime = innerProduct(MphiPrime ,MphiPrime);*/
|
||||
RealD Sprime = Meofa.S(Uprime);
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// Use derivative to estimate dS
|
||||
//////////////////////////////////////////////
|
||||
|
||||
LatticeComplex dS(UGrid);
|
||||
dS = zero;
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
mommu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
||||
mommu = Ta(mommu)*2.0;
|
||||
PokeIndex<LorentzIndex>(UdSdU, mommu, mu);
|
||||
}
|
||||
|
||||
for(int mu=0; mu<Nd; mu++){
|
||||
forcemu = PeekIndex<LorentzIndex>(UdSdU, mu);
|
||||
mommu = PeekIndex<LorentzIndex>(mom, mu);
|
||||
|
||||
// Update PF action density
|
||||
dS = dS + trace(mommu*forcemu)*dt;
|
||||
}
|
||||
|
||||
ComplexD dSpred = sum(dS);
|
||||
|
||||
/*std::cout << GridLogMessage << " S " << S << std::endl;
|
||||
std::cout << GridLogMessage << " Sprime " << Sprime << std::endl;
|
||||
std::cout << GridLogMessage << "dS " << Sprime-S << std::endl;
|
||||
std::cout << GridLogMessage << "predict dS " << dSpred << std::endl;*/
|
||||
printf("\nS = %1.15e\n", S);
|
||||
printf("Sprime = %1.15e\n", Sprime);
|
||||
printf("dS = %1.15e\n", Sprime - S);
|
||||
printf("real(dS_predict) = %1.15e\n", dSpred.real());
|
||||
printf("imag(dS_predict) = %1.15e\n\n", dSpred.imag());
|
||||
|
||||
assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
|
||||
|
||||
std::cout << GridLogMessage << "Done" << std::endl;
|
||||
Grid_finalize();
|
||||
}
|
@ -42,7 +42,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||
|
@ -42,7 +42,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
int threads = GridThread::GetThreads();
|
||||
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||
|
@ -40,12 +40,6 @@ namespace Grid{
|
||||
double, StoppingCondition,
|
||||
int, MaxCGIterations,
|
||||
bool, ApplySmearing);
|
||||
|
||||
//template <class ReaderClass >
|
||||
//FermionParameters(Reader<ReaderClass>& Reader){
|
||||
// read(Reader, "Mobius", *this);
|
||||
//}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -113,9 +107,17 @@ int main(int argc, char **argv) {
|
||||
bool ApplySmearing = MyParams.Mobius.ApplySmearing;
|
||||
|
||||
|
||||
// Use this if you want to tweak the default decomposition
|
||||
// commented out as very architecture speficic
|
||||
|
||||
//std::vector<int> simd_lanes({2,2,1,1});
|
||||
|
||||
// Grid from the command line
|
||||
TheHMC.Resources.AddFourDimGrid("gauge");
|
||||
// Grid from the command line arguments --grid and --mpi
|
||||
// drop the simd_lanes argument to fall back to the default decomposition for the SIMD lanes
|
||||
|
||||
//TheHMC.Resources.AddFourDimGrid("gauge", simd_lanes); // tweak the SIMD lanes
|
||||
TheHMC.Resources.AddFourDimGrid("gauge"); // use default simd lanes decomposition
|
||||
|
||||
// Possibile to create the module by hand
|
||||
// hardcoding parameters or using a Reader
|
||||
|
||||
|
1085
tests/lanczos/FieldVectorIO.h
Normal file
1085
tests/lanczos/FieldVectorIO.h
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/lanczos/Makefile.am
Normal file
1
tests/lanczos/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
include Make.inc
|
136
tests/lanczos/Params.h
Normal file
136
tests/lanczos/Params.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
Params IO
|
||||
|
||||
Author: Christoph Lehner
|
||||
Date: 2017
|
||||
*/
|
||||
|
||||
#define PADD(p,X) p.get(#X,X);
|
||||
|
||||
class Params {
|
||||
protected:
|
||||
|
||||
std::string trim(const std::string& sc) {
|
||||
std::string s = sc;
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
std::map< std::string, std::string > lines;
|
||||
std::string _fn;
|
||||
|
||||
Params(const char* fn) : _fn(fn) {
|
||||
FILE* f = fopen(fn,"rt");
|
||||
assert(f);
|
||||
while (!feof(f)) {
|
||||
char buf[4096];
|
||||
if (fgets(buf,sizeof(buf),f)) {
|
||||
if (buf[0] != '#' && buf[0] != '\r' && buf[0] != '\n') {
|
||||
char* sep = strchr(buf,'=');
|
||||
assert(sep);
|
||||
*sep = '\0';
|
||||
lines[trim(buf)] = trim(sep+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
~Params() {
|
||||
}
|
||||
|
||||
std::string loghead() {
|
||||
return _fn + ": ";
|
||||
}
|
||||
|
||||
bool has(const char* name) {
|
||||
auto f = lines.find(name);
|
||||
return (f != lines.end());
|
||||
}
|
||||
|
||||
const std::string& get(const char* name) {
|
||||
auto f = lines.find(name);
|
||||
if (f == lines.end()) {
|
||||
std::cout << Grid::GridLogMessage << loghead() << "Could not find value for " << name << std::endl;
|
||||
abort();
|
||||
}
|
||||
return f->second;
|
||||
}
|
||||
|
||||
void parse(std::string& s, const std::string& cval) {
|
||||
std::stringstream trimmer;
|
||||
trimmer << cval;
|
||||
s.clear();
|
||||
trimmer >> s;
|
||||
}
|
||||
|
||||
void parse(int& i, const std::string& cval) {
|
||||
assert(sscanf(cval.c_str(),"%d",&i)==1);
|
||||
}
|
||||
|
||||
void parse(long long& i, const std::string& cval) {
|
||||
assert(sscanf(cval.c_str(),"%lld",&i)==1);
|
||||
}
|
||||
|
||||
void parse(double& f, const std::string& cval) {
|
||||
assert(sscanf(cval.c_str(),"%lf",&f)==1);
|
||||
}
|
||||
|
||||
void parse(float& f, const std::string& cval) {
|
||||
assert(sscanf(cval.c_str(),"%f",&f)==1);
|
||||
}
|
||||
|
||||
void parse(bool& b, const std::string& cval) {
|
||||
std::string lcval = cval;
|
||||
std::transform(lcval.begin(), lcval.end(), lcval.begin(), ::tolower);
|
||||
if (lcval == "true" || lcval == "yes") {
|
||||
b = true;
|
||||
} else if (lcval == "false" || lcval == "no") {
|
||||
b = false;
|
||||
} else {
|
||||
std::cout << "Invalid value for boolean: " << b << std::endl;
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void parse(std::complex<double>& f, const std::string& cval) {
|
||||
double r,i;
|
||||
assert(sscanf(cval.c_str(),"%lf %lf",&r,&i)==2);
|
||||
f = std::complex<double>(r,i);
|
||||
}
|
||||
|
||||
void parse(std::complex<float>& f, const std::string& cval) {
|
||||
float r,i;
|
||||
assert(sscanf(cval.c_str(),"%f %f",&r,&i)==2);
|
||||
f = std::complex<float>(r,i);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void get(const char* name, std::vector<T>& v) {
|
||||
int i = 0;
|
||||
v.resize(0);
|
||||
while (true) {
|
||||
char buf[4096];
|
||||
sprintf(buf,"%s[%d]",name,i++);
|
||||
if (!has(buf))
|
||||
break;
|
||||
T val;
|
||||
parse(val,get(buf));
|
||||
std::cout << Grid::GridLogMessage << loghead() << "Set " << buf << " to " << val << std::endl;
|
||||
v.push_back(val);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void get(const char* name, T& f) {
|
||||
parse(f,get(name));
|
||||
std::cout << Grid::GridLogMessage << loghead() << "Set " << name << " to " << f << std::endl;
|
||||
}
|
||||
|
||||
|
||||
};
|
727
tests/lanczos/Test_dwf_compressed_lanczos.cc
Normal file
727
tests/lanczos/Test_dwf_compressed_lanczos.cc
Normal file
@ -0,0 +1,727 @@
|
||||
/*
|
||||
Authors: Christoph Lehner
|
||||
Date: 2017
|
||||
|
||||
Multigrid Lanczos
|
||||
|
||||
|
||||
|
||||
TODO:
|
||||
|
||||
High priority:
|
||||
- Explore filtering of starting vector again, should really work: If cheby has 4 for low mode region and 1 for high mode, applying 15 iterations has 1e9 suppression
|
||||
of high modes, which should create the desired invariant subspace already? Missing something here??? Maybe dynamic range dangerous, i.e., could also kill interesting
|
||||
eigenrange if not careful.
|
||||
|
||||
Better: Use all Cheby up to order N in order to approximate a step function; try this! Problem: width of step function. Can kill eigenspace > 1e-3 and have < 1e-5 equal
|
||||
to 1
|
||||
|
||||
Low priority:
|
||||
- Given that I seem to need many restarts and high degree poly to create the base and this takes about 1 day, seriously consider a simple method to create a basis
|
||||
(ortho krylov low poly); and then fix up lowest say 200 eigenvalues by 1 run with high-degree poly (600 could be enough)
|
||||
*/
|
||||
#include <Grid/Grid.h>
|
||||
#include <Grid/algorithms/iterative/BlockImplicitlyRestartedLanczos/BlockImplicitlyRestartedLanczos.h>
|
||||
#include "FieldVectorIO.h"
|
||||
#include "Params.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
bool read_evals(GridBase* _grid, char* fn, std::vector<RealD>& evals) {
|
||||
|
||||
FILE* f = 0;
|
||||
uint32_t status = 0;
|
||||
if (_grid->IsBoss()) {
|
||||
f = fopen(fn,"rt");
|
||||
status = f ? 1 : 0;
|
||||
}
|
||||
_grid->GlobalSum(status);
|
||||
|
||||
if (!status)
|
||||
return false;
|
||||
|
||||
uint32_t N;
|
||||
if (f)
|
||||
assert(fscanf(f,"%d\n",&N)==1);
|
||||
else
|
||||
N = 0;
|
||||
_grid->GlobalSum(N);
|
||||
|
||||
std::cout << "Reading " << N << " eigenvalues" << std::endl;
|
||||
|
||||
evals.resize(N);
|
||||
|
||||
for (int i=0;i<N;i++) {
|
||||
if (f)
|
||||
assert(fscanf(f,"%lf",&evals[i])==1);
|
||||
else
|
||||
evals[i] = 0;
|
||||
}
|
||||
|
||||
_grid->GlobalSumVector(&evals[0],evals.size());
|
||||
|
||||
if (f)
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
void write_evals(char* fn, std::vector<RealD>& evals) {
|
||||
FILE* f = fopen(fn,"wt");
|
||||
assert(f);
|
||||
|
||||
int N = (int)evals.size();
|
||||
fprintf(f,"%d\n",N);
|
||||
|
||||
for (int i=0;i<N;i++) {
|
||||
fprintf(f,"%.15E\n",evals[i]);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void write_history(char* fn, std::vector<RealD>& hist) {
|
||||
FILE* f = fopen(fn,"wt");
|
||||
assert(f);
|
||||
|
||||
int N = (int)hist.size();
|
||||
for (int i=0;i<N;i++) {
|
||||
fprintf(f,"%d %.15E\n",i,hist[i]);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
template<typename Field>
|
||||
class FunctionHermOp : public LinearFunction<Field> {
|
||||
public:
|
||||
OperatorFunction<Field> & _poly;
|
||||
LinearOperatorBase<Field> &_Linop;
|
||||
|
||||
FunctionHermOp(OperatorFunction<Field> & poly,LinearOperatorBase<Field>& linop) : _poly(poly), _Linop(linop) {
|
||||
}
|
||||
|
||||
void operator()(const Field& in, Field& out) {
|
||||
_poly(_Linop,in,out);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Field>
|
||||
class CheckpointedLinearFunction : public LinearFunction<Field> {
|
||||
public:
|
||||
LinearFunction<Field>& _op;
|
||||
std::string _dir;
|
||||
int _max_apply;
|
||||
int _apply, _apply_actual;
|
||||
GridBase* _grid;
|
||||
FILE* _f;
|
||||
|
||||
CheckpointedLinearFunction(GridBase* grid, LinearFunction<Field>& op, const char* dir,int max_apply) : _op(op), _dir(dir), _grid(grid), _f(0),
|
||||
_max_apply(max_apply), _apply(0), _apply_actual(0) {
|
||||
|
||||
FieldVectorIO::conditionalMkDir(dir);
|
||||
|
||||
char fn[4096];
|
||||
sprintf(fn,"%s/ckpt_op.%4.4d",_dir.c_str(),_grid->ThisRank());
|
||||
printf("CheckpointLinearFunction:: file %s\n",fn);
|
||||
_f = fopen(fn,"r+b");
|
||||
if (!_f)
|
||||
_f = fopen(fn,"w+b");
|
||||
assert(_f);
|
||||
fseek(_f,0,SEEK_CUR);
|
||||
|
||||
}
|
||||
|
||||
~CheckpointedLinearFunction() {
|
||||
if (_f) {
|
||||
fclose(_f);
|
||||
_f = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool load_ckpt(const Field& in, Field& out) {
|
||||
|
||||
off_t cur = ftello(_f);
|
||||
fseeko(_f,0,SEEK_END);
|
||||
if (cur == ftello(_f))
|
||||
return false;
|
||||
fseeko(_f,cur,SEEK_SET);
|
||||
|
||||
size_t sz = sizeof(out._odata[0]) * out._odata.size();
|
||||
|
||||
GridStopWatch gsw;
|
||||
gsw.Start();
|
||||
uint32_t crc_exp;
|
||||
assert(fread(&crc_exp,4,1,_f)==1);
|
||||
assert(fread(&out._odata[0],sz,1,_f)==1);
|
||||
assert(FieldVectorIO::crc32_threaded((unsigned char*)&out._odata[0],sz,0x0)==crc_exp);
|
||||
gsw.Stop();
|
||||
|
||||
printf("CheckpointLinearFunction:: reading %lld\n",(long long)sz);
|
||||
std::cout << GridLogMessage << "Loading " << ((RealD)sz/1024./1024./1024.) << " GB in " << gsw.Elapsed() << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void save_ckpt(const Field& in, Field& out) {
|
||||
|
||||
fseek(_f,0,SEEK_CUR); // switch to write
|
||||
|
||||
size_t sz = sizeof(out._odata[0]) * out._odata.size();
|
||||
|
||||
GridStopWatch gsw;
|
||||
gsw.Start();
|
||||
uint32_t crc = FieldVectorIO::crc32_threaded((unsigned char*)&out._odata[0],sz,0x0);
|
||||
assert(fwrite(&crc,4,1,_f)==1);
|
||||
assert(fwrite(&out._odata[0],sz,1,_f)==1);
|
||||
fflush(_f); // try this on the GPFS to suppress OPA usage for disk during dslash; this is not needed at Lustre/JLAB
|
||||
gsw.Stop();
|
||||
|
||||
printf("CheckpointLinearFunction:: writing %lld\n",(long long)sz);
|
||||
std::cout << GridLogMessage << "Saving " << ((RealD)sz/1024./1024./1024.) << " GB in " << gsw.Elapsed() << std::endl;
|
||||
}
|
||||
|
||||
void operator()(const Field& in, Field& out) {
|
||||
|
||||
_apply++;
|
||||
|
||||
if (load_ckpt(in,out))
|
||||
return;
|
||||
|
||||
_op(in,out);
|
||||
|
||||
save_ckpt(in,out);
|
||||
|
||||
if (_apply_actual++ >= _max_apply) {
|
||||
std::cout << GridLogMessage << "Maximum application of operator reached, checkpoint and finish in future job" << std::endl;
|
||||
if (_f) { fclose(_f); _f=0; }
|
||||
in._grid->Barrier();
|
||||
Grid_finalize();
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CoarseField,typename Field>
|
||||
class ProjectedFunctionHermOp : public LinearFunction<CoarseField> {
|
||||
public:
|
||||
OperatorFunction<Field> & _poly;
|
||||
LinearOperatorBase<Field> &_Linop;
|
||||
BlockProjector<Field>& _pr;
|
||||
|
||||
ProjectedFunctionHermOp(BlockProjector<Field>& pr,OperatorFunction<Field> & poly,LinearOperatorBase<Field>& linop) : _poly(poly), _Linop(linop), _pr(pr) {
|
||||
}
|
||||
|
||||
void operator()(const CoarseField& in, CoarseField& out) {
|
||||
assert(_pr._bgrid._o_blocks == in._grid->oSites());
|
||||
|
||||
Field fin(_pr._bgrid._grid);
|
||||
Field fout(_pr._bgrid._grid);
|
||||
|
||||
GridStopWatch gsw1,gsw2,gsw3;
|
||||
// fill fin
|
||||
gsw1.Start();
|
||||
_pr.coarseToFine(in,fin);
|
||||
gsw1.Stop();
|
||||
|
||||
// apply poly
|
||||
gsw2.Start();
|
||||
_poly(_Linop,fin,fout);
|
||||
gsw2.Stop();
|
||||
|
||||
// fill out
|
||||
gsw3.Start();
|
||||
_pr.fineToCoarse(fout,out);
|
||||
gsw3.Stop();
|
||||
|
||||
auto eps = innerProduct(in,out);
|
||||
std::cout << GridLogMessage << "Operator timing details: c2f = " << gsw1.Elapsed() << " poly = " << gsw2.Elapsed() << " f2c = " << gsw3.Elapsed() <<
|
||||
" Complimentary Hermiticity check: " << eps.imag() / std::abs(eps) << std::endl;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CoarseField,typename Field>
|
||||
class ProjectedHermOp : public LinearFunction<CoarseField> {
|
||||
public:
|
||||
LinearOperatorBase<Field> &_Linop;
|
||||
BlockProjector<Field>& _pr;
|
||||
|
||||
ProjectedHermOp(BlockProjector<Field>& pr,LinearOperatorBase<Field>& linop) : _Linop(linop), _pr(pr) {
|
||||
}
|
||||
|
||||
void operator()(const CoarseField& in, CoarseField& out) {
|
||||
assert(_pr._bgrid._o_blocks == in._grid->oSites());
|
||||
Field fin(_pr._bgrid._grid);
|
||||
Field fout(_pr._bgrid._grid);
|
||||
_pr.coarseToFine(in,fin);
|
||||
_Linop.HermOp(fin,fout);
|
||||
_pr.fineToCoarse(fout,out);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Field>
|
||||
class PlainHermOp : public LinearFunction<Field> {
|
||||
public:
|
||||
LinearOperatorBase<Field> &_Linop;
|
||||
|
||||
PlainHermOp(LinearOperatorBase<Field>& linop) : _Linop(linop) {
|
||||
}
|
||||
|
||||
void operator()(const Field& in, Field& out) {
|
||||
_Linop.HermOp(in,out);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename vtype, int N > using CoarseSiteFieldGeneral = iScalar< iVector<vtype, N> >;
|
||||
template<int N> using CoarseSiteFieldD = CoarseSiteFieldGeneral< vComplexD, N >;
|
||||
template<int N> using CoarseSiteFieldF = CoarseSiteFieldGeneral< vComplexF, N >;
|
||||
template<int N> using CoarseSiteField = CoarseSiteFieldGeneral< vComplex, N >;
|
||||
template<int N> using CoarseLatticeFermion = Lattice< CoarseSiteField<N> >;
|
||||
template<int N> using CoarseLatticeFermionD = Lattice< CoarseSiteFieldD<N> >;
|
||||
|
||||
template<typename Field,int Nstop1>
|
||||
void CoarseGridLanczos(BlockProjector<Field>& pr,RealD alpha2,RealD beta,int Npoly2,
|
||||
int Nstop2,int Nk2,int Nm2,RealD resid2,RealD betastp2,int MaxIt,int MinRes2,
|
||||
LinearOperatorBase<Field>& HermOp, std::vector<RealD>& eval1, bool cg_test_enabled,
|
||||
int cg_test_maxiter,int nsingle,int SkipTest2, int MaxApply2,bool smoothed_eval_enabled,
|
||||
int smoothed_eval_inner,int smoothed_eval_outer,int smoothed_eval_begin,
|
||||
int smoothed_eval_end,RealD smoothed_eval_inner_resid) {
|
||||
|
||||
BlockedGrid<Field>& bgrid = pr._bgrid;
|
||||
BasisFieldVector<Field>& basis = pr._evec;
|
||||
|
||||
|
||||
std::vector<int> coarseFourDimLatt;
|
||||
for (int i=0;i<4;i++)
|
||||
coarseFourDimLatt.push_back(bgrid._nb[1+i] * bgrid._grid->_processors[1+i]);
|
||||
assert(bgrid._grid->_processors[0] == 1);
|
||||
|
||||
std::cout << GridLogMessage << "CoarseGrid = " << coarseFourDimLatt << " with basis = " << Nstop1 << std::endl;
|
||||
GridCartesian * UCoarseGrid = SpaceTimeGrid::makeFourDimGrid(coarseFourDimLatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
||||
GridCartesian * FCoarseGrid = SpaceTimeGrid::makeFiveDimGrid(bgrid._nb[0],UCoarseGrid);
|
||||
|
||||
Chebyshev<Field> Cheb2(alpha2,beta,Npoly2);
|
||||
CoarseLatticeFermion<Nstop1> src_coarse(FCoarseGrid);
|
||||
|
||||
// Second round of Lanczos in blocked space
|
||||
std::vector<RealD> eval2(Nm2);
|
||||
std::vector<RealD> eval3(Nm2);
|
||||
BasisFieldVector<CoarseLatticeFermion<Nstop1> > coef(Nm2,FCoarseGrid);
|
||||
|
||||
ProjectedFunctionHermOp<CoarseLatticeFermion<Nstop1>,LatticeFermion> Op2plain(pr,Cheb2,HermOp);
|
||||
CheckpointedLinearFunction<CoarseLatticeFermion<Nstop1> > Op2ckpt(src_coarse._grid,Op2plain,"checkpoint",MaxApply2);
|
||||
LinearFunction< CoarseLatticeFermion<Nstop1> >* Op2;
|
||||
if (MaxApply2) {
|
||||
Op2 = &Op2ckpt;
|
||||
} else {
|
||||
Op2 = &Op2plain;
|
||||
}
|
||||
ProjectedHermOp<CoarseLatticeFermion<Nstop1>,LatticeFermion> Op2nopoly(pr,HermOp);
|
||||
BlockImplicitlyRestartedLanczos<CoarseLatticeFermion<Nstop1> > IRL2(*Op2,*Op2,Nstop2,Nk2,Nm2,resid2,betastp2,MaxIt,MinRes2);
|
||||
|
||||
|
||||
src_coarse = 1.0;
|
||||
|
||||
// Precision test
|
||||
{
|
||||
Field tmp(bgrid._grid);
|
||||
CoarseLatticeFermion<Nstop1> tmp2(FCoarseGrid);
|
||||
CoarseLatticeFermion<Nstop1> tmp3(FCoarseGrid);
|
||||
tmp2 = 1.0;
|
||||
tmp3 = 1.0;
|
||||
|
||||
pr.coarseToFine(tmp2,tmp);
|
||||
pr.fineToCoarse(tmp,tmp2);
|
||||
|
||||
tmp2 -= tmp3;
|
||||
std::cout << GridLogMessage << "Precision Test c->f->c: " << norm2(tmp2) / norm2(tmp3) << std::endl;
|
||||
|
||||
//bgrid._grid->Barrier();
|
||||
//return;
|
||||
}
|
||||
|
||||
int Nconv;
|
||||
if (!FieldVectorIO::read_compressed_vectors("lanczos.output",pr,coef) ||
|
||||
!read_evals(UCoarseGrid,(char *)"lanczos.output/eigen-values.txt",eval3) ||
|
||||
!read_evals(UCoarseGrid,(char *)"lanczos.output/eigen-values.txt.linear",eval1) ||
|
||||
!read_evals(UCoarseGrid,(char *)"lanczos.output/eigen-values.txt.poly",eval2)
|
||||
) {
|
||||
|
||||
|
||||
IRL2.calc(eval2,coef,src_coarse,Nconv,true,SkipTest2);
|
||||
|
||||
coef.resize(Nstop2);
|
||||
eval2.resize(Nstop2);
|
||||
eval3.resize(Nstop2);
|
||||
|
||||
std::vector<Field> step3_cache;
|
||||
|
||||
// reconstruct eigenvalues of original operator
|
||||
for (int i=0;i<Nstop2;i++){
|
||||
RealD eval2_linear;
|
||||
|
||||
if (i<Nstop1) {
|
||||
eval2_linear = eval1[i];
|
||||
} else {
|
||||
eval2_linear = eval2[i-1];
|
||||
}
|
||||
|
||||
RealD eval2_poly = eval2[i];
|
||||
RealD eval_reconstruct = Cheb2.approxInv(eval2_poly,eval2_linear,100,1e-10);
|
||||
std::cout << i << " Reconstructed eval = " << eval_reconstruct << " from quess " << eval2_linear << std::endl;
|
||||
eval2[i] = eval_reconstruct;
|
||||
}
|
||||
|
||||
// as demonstrated in CG test below, best result from mixed determination
|
||||
for (int i=0;i<Nstop2;i++)
|
||||
eval3[i] = (i < Nstop1) ? eval1[i] : eval2[i];
|
||||
|
||||
for(int i=0;i<Nstop2;i++){
|
||||
std::cout << i<<" / "<< Nstop2<< " eigenvalue "<< eval3[i] <<std::endl;
|
||||
};
|
||||
|
||||
// write
|
||||
mkdir("lanczos.output",ACCESSPERMS);
|
||||
FieldVectorIO::write_compressed_vectors("lanczos.output",pr,coef,nsingle);
|
||||
if (bgrid._grid->IsBoss()) {
|
||||
write_evals((char *)"lanczos.output/eigen-values.txt",eval3);
|
||||
write_evals((char *)"lanczos.output/eigen-values.txt.linear",eval1);
|
||||
write_evals((char *)"lanczos.output/eigen-values.txt.poly",eval2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// fix up eigenvalues
|
||||
if (!read_evals(UCoarseGrid,(char *)"lanczos.output/eigen-values.txt.smoothed",eval3) && smoothed_eval_enabled) {
|
||||
|
||||
ConjugateGradient<LatticeFermion> CG(smoothed_eval_inner_resid, smoothed_eval_inner, false);
|
||||
|
||||
LatticeFermion v_i(basis[0]._grid);
|
||||
auto tmp = v_i;
|
||||
auto tmp2 = v_i;
|
||||
|
||||
for (int i=smoothed_eval_begin;i<smoothed_eval_end;i++) {
|
||||
|
||||
GridStopWatch gsw;
|
||||
|
||||
gsw.Start();
|
||||
|
||||
pr.coarseToFine(coef[i],v_i);
|
||||
v_i.checkerboard = Odd;
|
||||
|
||||
for (int j=0;j<smoothed_eval_outer;j++) {
|
||||
tmp=zero;
|
||||
//pr.deflate(coef,eval3,Nstop2,v_i,tmp);
|
||||
CG(HermOp, v_i, tmp);
|
||||
|
||||
v_i = 1.0 / ::sqrt( norm2(tmp) ) * tmp;
|
||||
}
|
||||
|
||||
tmp = v_i;
|
||||
|
||||
HermOp.HermOp(tmp,tmp2);
|
||||
|
||||
RealD ev = innerProduct(tmp,tmp2).real();
|
||||
|
||||
gsw.Stop();
|
||||
|
||||
std::cout << GridLogMessage << "Smoothed eigenvalue " << i << " from " << eval3[i] << " to " << ev << " in " << gsw.Elapsed() << std::endl;
|
||||
// " with effective smoother precision " << (CG.ResHistory.back() / CG.ResHistory.front() ) << std::endl;
|
||||
// CG.ResHistory.clear();
|
||||
|
||||
eval3[i] = ev;
|
||||
}
|
||||
|
||||
if (bgrid._grid->IsBoss()) {
|
||||
write_evals((char *)"lanczos.output/eigen-values.txt.smoothed",eval3);
|
||||
write_evals((char *)"lanczos.output/eigen-values.txt",eval3); // also reset this to the best ones we have available
|
||||
}
|
||||
}
|
||||
|
||||
// do CG test with and without deflation
|
||||
if (cg_test_enabled) {
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-8, cg_test_maxiter, false);
|
||||
LatticeFermion src_orig(bgrid._grid);
|
||||
src_orig.checkerboard = Odd;
|
||||
src_orig = 1.0;
|
||||
src_orig = src_orig * (1.0 / ::sqrt(norm2(src_orig)) );
|
||||
auto result = src_orig;
|
||||
|
||||
// undeflated solve
|
||||
result = zero;
|
||||
CG(HermOp, src_orig, result);
|
||||
// if (UCoarseGrid->IsBoss())
|
||||
// write_history("cg_test.undefl",CG.ResHistory);
|
||||
// CG.ResHistory.clear();
|
||||
|
||||
// deflated solve with all eigenvectors
|
||||
result = zero;
|
||||
pr.deflate(coef,eval2,Nstop2,src_orig,result);
|
||||
CG(HermOp, src_orig, result);
|
||||
// if (UCoarseGrid->IsBoss())
|
||||
// write_history("cg_test.defl_all",CG.ResHistory);
|
||||
// CG.ResHistory.clear();
|
||||
|
||||
// deflated solve with non-blocked eigenvectors
|
||||
result = zero;
|
||||
pr.deflate(coef,eval1,Nstop1,src_orig,result);
|
||||
CG(HermOp, src_orig, result);
|
||||
// if (UCoarseGrid->IsBoss())
|
||||
// write_history("cg_test.defl_full",CG.ResHistory);
|
||||
// CG.ResHistory.clear();
|
||||
|
||||
// deflated solve with all eigenvectors and original eigenvalues from proj
|
||||
result = zero;
|
||||
pr.deflate(coef,eval3,Nstop2,src_orig,result);
|
||||
CG(HermOp, src_orig, result);
|
||||
// if (UCoarseGrid->IsBoss())
|
||||
// write_history("cg_test.defl_all_ev3",CG.ResHistory);
|
||||
// CG.ResHistory.clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<typename Field>
|
||||
void quick_krylov_basis(BasisFieldVector<Field>& evec,Field& src,LinearFunction<Field>& Op,int Nstop) {
|
||||
Field tmp = src;
|
||||
Field tmp2 = tmp;
|
||||
|
||||
for (int i=0;i<Nstop;i++) {
|
||||
GridStopWatch gsw;
|
||||
gsw.Start();
|
||||
Op(tmp,tmp2);
|
||||
gsw.Stop();
|
||||
evec.orthogonalize(tmp2,i);
|
||||
|
||||
RealD nn = norm2(tmp2);
|
||||
nn = Grid::sqrt(nn);
|
||||
tmp2 = tmp2 * (1.0/nn);
|
||||
|
||||
evec[i] = tmp2;
|
||||
tmp = tmp2;
|
||||
std::cout << GridLogMessage << "Quick_krylov_basis: " << i << "/" << Nstop << " timing of operator=" << gsw.Elapsed() << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main (int argc, char ** argv) {
|
||||
|
||||
Grid_init(&argc,&argv);
|
||||
|
||||
const int MaxIt = 10000;
|
||||
|
||||
int Ls;
|
||||
RealD mass;
|
||||
RealD M5;
|
||||
std::vector < std::complex<double> > omega;
|
||||
|
||||
RealD alpha1, alpha2, beta;
|
||||
int Npoly1, Npoly2;
|
||||
int Nstop1, Nstop2;
|
||||
int Nk1, Nk2;
|
||||
int Np1, Np2;
|
||||
int MinRes1, MinRes2;
|
||||
int SkipTest2, MaxApply2;
|
||||
bool checkpoint_basis;
|
||||
bool cg_test_enabled;
|
||||
bool exit_after_basis_calculation;
|
||||
bool simple_krylov_basis;
|
||||
int cg_test_maxiter;
|
||||
int nsingle; // store in single precision, the rest in FP16
|
||||
int max_cheb_time_ms;
|
||||
bool smoothed_eval_enabled;
|
||||
int smoothed_eval_inner;
|
||||
int smoothed_eval_outer;
|
||||
int smoothed_eval_begin;
|
||||
int smoothed_eval_end;
|
||||
RealD smoothed_eval_inner_resid;
|
||||
|
||||
// vector representation
|
||||
std::vector<int> block_size; // 5d block size
|
||||
|
||||
RealD resid1, resid2, betastp1, betastp2, basis_norm_threshold;
|
||||
|
||||
std::string config;
|
||||
|
||||
Params jp("params.txt");
|
||||
PADD(jp,Npoly1); PADD(jp,Npoly2);
|
||||
PADD(jp,max_cheb_time_ms);
|
||||
PADD(jp,Nstop1); PADD(jp,Nstop2); PADD(jp,MaxApply2);
|
||||
PADD(jp,Nk1); PADD(jp,Nk2); PADD(jp,betastp1); PADD(jp,betastp2);
|
||||
PADD(jp,Np1); PADD(jp,Np2); basis_norm_threshold = 1e-5; //PADD(jp,basis_norm_threshold);
|
||||
PADD(jp,block_size); PADD(jp,smoothed_eval_enabled); PADD(jp,smoothed_eval_inner);
|
||||
PADD(jp,resid1); PADD(jp,resid2); PADD(jp,smoothed_eval_outer);
|
||||
PADD(jp,alpha1); PADD(jp,alpha2); PADD(jp,smoothed_eval_begin);
|
||||
PADD(jp,MinRes1); PADD(jp,MinRes2); PADD(jp,smoothed_eval_end);
|
||||
PADD(jp,beta); PADD(jp,mass); PADD(jp,smoothed_eval_inner_resid);
|
||||
PADD(jp,omega); PADD(jp,config);
|
||||
PADD(jp,M5); PADD(jp,cg_test_enabled);
|
||||
PADD(jp,cg_test_maxiter); PADD(jp,checkpoint_basis);
|
||||
PADD(jp,nsingle); PADD(jp,exit_after_basis_calculation);
|
||||
PADD(jp,simple_krylov_basis); PADD(jp,SkipTest2);
|
||||
|
||||
Ls = (int)omega.size();
|
||||
|
||||
// Grids
|
||||
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
||||
GridCartesian * UGridHP = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplexD::Nsimd()),GridDefaultMpi());
|
||||
GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridRedBlackCartesian * UrbGridHP = SpaceTimeGrid::makeFourDimRedBlackGrid(UGridHP);
|
||||
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
||||
GridCartesian * FGridHP = SpaceTimeGrid::makeFiveDimGrid(Ls,UGridHP);
|
||||
GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
|
||||
GridRedBlackCartesian * FrbGridHP = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGridHP);
|
||||
|
||||
// Gauge field
|
||||
LatticeGaugeField Umu(UGrid);
|
||||
FieldMetaData header;
|
||||
NerscIO::readConfiguration(Umu,header,config);
|
||||
std::cout << GridLogMessage << "Lattice dimensions: " << GridDefaultLatt()
|
||||
<< " Ls: " << Ls << std::endl;
|
||||
|
||||
// ZMobius EO Operator
|
||||
ZMobiusFermionR Ddwf(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mass, M5, omega,1.,0.);
|
||||
SchurDiagTwoOperator<ZMobiusFermionR,LatticeFermion> HermOp(Ddwf);
|
||||
|
||||
// Eigenvector storage
|
||||
const int Nm1 = Np1 + Nk1;
|
||||
const int Nm2 = Np2 + Nk2; // maximum number of vectors we need to keep
|
||||
std::cout << GridLogMessage << "Keep " << Nm1 << " full vectors" << std::endl;
|
||||
std::cout << GridLogMessage << "Keep " << Nm2 << " total vectors" << std::endl;
|
||||
assert(Nm2 >= Nm1);
|
||||
BasisFieldVector<LatticeFermion> evec(Nm1,FrbGrid); // start off with keeping full vectors
|
||||
|
||||
// First and second cheby
|
||||
Chebyshev<LatticeFermion> Cheb1(alpha1,beta,Npoly1);
|
||||
FunctionHermOp<LatticeFermion> Op1(Cheb1,HermOp);
|
||||
PlainHermOp<LatticeFermion> Op1test(HermOp);
|
||||
|
||||
// Eigenvalue storage
|
||||
std::vector<RealD> eval1(evec.size());
|
||||
|
||||
// Construct source vector
|
||||
LatticeFermion src(FrbGrid);
|
||||
{
|
||||
src=1.0;
|
||||
src.checkerboard = Odd;
|
||||
|
||||
// normalize
|
||||
RealD nn = norm2(src);
|
||||
nn = Grid::sqrt(nn);
|
||||
src = src * (1.0/nn);
|
||||
}
|
||||
|
||||
// Do a benchmark and a quick exit if performance is too little (ugly but needed due to performance fluctuations)
|
||||
if (max_cheb_time_ms) {
|
||||
// one round of warmup
|
||||
auto tmp = src;
|
||||
GridStopWatch gsw1,gsw2;
|
||||
gsw1.Start();
|
||||
Cheb1(HermOp,src,tmp);
|
||||
gsw1.Stop();
|
||||
Ddwf.ZeroCounters();
|
||||
gsw2.Start();
|
||||
Cheb1(HermOp,src,tmp);
|
||||
gsw2.Stop();
|
||||
Ddwf.Report();
|
||||
std::cout << GridLogMessage << "Performance check; warmup = " << gsw1.Elapsed() << " test = " << gsw2.Elapsed() << std::endl;
|
||||
int ms = (int)(gsw2.useconds()/1e3);
|
||||
if (ms > max_cheb_time_ms) {
|
||||
std::cout << GridLogMessage << "Performance too poor: " << ms << " ms, cutoff = " << max_cheb_time_ms << " ms" << std::endl;
|
||||
Grid_finalize();
|
||||
return 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// First round of Lanczos to get low mode basis
|
||||
BlockImplicitlyRestartedLanczos<LatticeFermion> IRL1(Op1,Op1test,Nstop1,Nk1,Nm1,resid1,betastp1,MaxIt,MinRes1);
|
||||
int Nconv;
|
||||
|
||||
char tag[1024];
|
||||
if (!FieldVectorIO::read_argonne(evec,(char *)"checkpoint") || !read_evals(UGrid,(char *)"checkpoint/eigen-values.txt",eval1)) {
|
||||
|
||||
if (simple_krylov_basis) {
|
||||
quick_krylov_basis(evec,src,Op1,Nstop1);
|
||||
} else {
|
||||
IRL1.calc(eval1,evec,src,Nconv,false,1);
|
||||
}
|
||||
evec.resize(Nstop1); // and throw away superfluous
|
||||
eval1.resize(Nstop1);
|
||||
if (checkpoint_basis)
|
||||
FieldVectorIO::write_argonne(evec,(char *)"checkpoint");
|
||||
if (UGrid->IsBoss() && checkpoint_basis)
|
||||
write_evals((char *)"checkpoint/eigen-values.txt",eval1);
|
||||
|
||||
Ddwf.Report();
|
||||
|
||||
if (exit_after_basis_calculation) {
|
||||
Grid_finalize();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// now test eigenvectors
|
||||
if (!simple_krylov_basis) {
|
||||
for (int i=0;i<Nstop1;i++){
|
||||
auto B = evec[i];
|
||||
auto tmp = B;
|
||||
auto v = B;
|
||||
|
||||
{
|
||||
HermOp.HermOp(B,v);
|
||||
|
||||
RealD vnum = real(innerProduct(B,v)); // HermOp.
|
||||
RealD vden = norm2(B);
|
||||
RealD vv0 = norm2(v);
|
||||
RealD eval2 = vnum/vden;
|
||||
v -= eval2*B;
|
||||
RealD vv = norm2(v);
|
||||
|
||||
std::cout << i << " OP eval = " << eval2 << " (" << eval1[i] << ") "
|
||||
<< "res2 = " << vv << " norm2 = " << norm2(B) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do second step only if needed
|
||||
if (Nstop1 <= Nstop2) {
|
||||
|
||||
// Now setup blocking
|
||||
assert(evec.size() == Nstop1);
|
||||
BlockedGrid<LatticeFermion> bgrid(FrbGrid, block_size);
|
||||
BlockProjector<LatticeFermion> pr(evec,bgrid);
|
||||
pr.createOrthonormalBasis(basis_norm_threshold);
|
||||
pr.createOrthonormalBasis(basis_norm_threshold); // another round due to precision issues created by local coherence
|
||||
|
||||
constexpr int common_basis_sizes[] = { 60, 250, 400 };
|
||||
constexpr int n_common_basis_sizes = sizeof(common_basis_sizes) / sizeof(common_basis_sizes[0]);
|
||||
switch (Nstop1) {
|
||||
#define BASIS(n) case common_basis_sizes[n]:\
|
||||
CoarseGridLanczos<LatticeFermion,common_basis_sizes[n]>\
|
||||
(pr,alpha2,beta,Npoly2,Nstop2,Nk2,Nm2,resid2,betastp2,MaxIt,MinRes2,HermOp,eval1, \
|
||||
cg_test_enabled,cg_test_maxiter,nsingle,SkipTest2, \
|
||||
MaxApply2,smoothed_eval_enabled,smoothed_eval_inner,smoothed_eval_outer, \
|
||||
smoothed_eval_begin,smoothed_eval_end,smoothed_eval_inner_resid); break;
|
||||
BASIS(0);
|
||||
BASIS(1);
|
||||
BASIS(2);
|
||||
default:
|
||||
std::cout << GridLogMessage << "Basis size " << Nstop1 << " must be added at compile-time" << std::endl;
|
||||
std::cout << GridLogMessage << "Currently available sizes: " << std::endl;
|
||||
for (int i=0;i<n_common_basis_sizes;i++) {
|
||||
std::cout << GridLogMessage << " " << common_basis_sizes[i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Grid_finalize();
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ int main(int argc, char **argv) {
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd, vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size, simd_layout, mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size, simd_layout, mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
std::vector<int> seeds({1, 2, 3, 4, 5});
|
||||
GridSerialRNG sRNG;
|
||||
@ -149,4 +149,4 @@ JSON
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
*/
|
||||
|
229
tests/solver/Test_dwf_mrhs_cg.cc
Normal file
229
tests/solver/Test_dwf_mrhs_cg.cc
Normal file
@ -0,0 +1,229 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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>
|
||||
#include <Grid/algorithms/iterative/BlockConjugateGradient.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
typedef typename DomainWallFermionR::FermionField FermionField;
|
||||
typedef typename DomainWallFermionR::ComplexField ComplexField;
|
||||
typename DomainWallFermionR::ImplParams params;
|
||||
|
||||
const int Ls=4;
|
||||
|
||||
Grid_init(&argc,&argv);
|
||||
|
||||
std::vector<int> latt_size = GridDefaultLatt();
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
std::vector<int> mpi_split (mpi_layout.size(),1);
|
||||
|
||||
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
||||
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
||||
GridRedBlackCartesian * rbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
|
||||
|
||||
int nrhs = UGrid->RankCount() ;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Split into 1^4 mpi communicators
|
||||
/////////////////////////////////////////////
|
||||
GridCartesian * SGrid = new GridCartesian(GridDefaultLatt(),
|
||||
GridDefaultSimd(Nd,vComplex::Nsimd()),
|
||||
mpi_split,
|
||||
*UGrid);
|
||||
|
||||
GridCartesian * SFGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,SGrid);
|
||||
GridRedBlackCartesian * SrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(SGrid);
|
||||
GridRedBlackCartesian * SFrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,SGrid);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Set up the problem as a 4d spreadout job
|
||||
///////////////////////////////////////////////
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
|
||||
GridParallelRNG pRNG(UGrid ); pRNG.SeedFixedIntegers(seeds);
|
||||
GridParallelRNG pRNG5(FGrid); pRNG5.SeedFixedIntegers(seeds);
|
||||
std::vector<FermionField> src(nrhs,FGrid);
|
||||
std::vector<FermionField> src_chk(nrhs,FGrid);
|
||||
std::vector<FermionField> result(nrhs,FGrid);
|
||||
FermionField tmp(FGrid);
|
||||
|
||||
for(int s=0;s<nrhs;s++) random(pRNG5,src[s]);
|
||||
for(int s=0;s<nrhs;s++) result[s]=zero;
|
||||
|
||||
LatticeGaugeField Umu(UGrid); SU3::HotConfiguration(pRNG,Umu);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Bounce these fields to disk
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Writing out in parallel view "<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
emptyUserRecord record;
|
||||
std::string file("./scratch.scidac");
|
||||
std::string filef("./scratch.scidac.ferm");
|
||||
int me = UGrid->ThisRank();
|
||||
LatticeGaugeField s_Umu(SGrid);
|
||||
FermionField s_src(SFGrid);
|
||||
FermionField s_src_split(SFGrid);
|
||||
FermionField s_tmp(SFGrid);
|
||||
FermionField s_res(SFGrid);
|
||||
|
||||
{
|
||||
FGrid->Barrier();
|
||||
ScidacWriter _ScidacWriter;
|
||||
_ScidacWriter.open(file);
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Writing out gauge field "<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
_ScidacWriter.writeScidacFieldRecord(Umu,record);
|
||||
_ScidacWriter.close();
|
||||
FGrid->Barrier();
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Reading in gauge field "<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
ScidacReader _ScidacReader;
|
||||
_ScidacReader.open(file);
|
||||
_ScidacReader.readScidacFieldRecord(s_Umu,record);
|
||||
_ScidacReader.close();
|
||||
FGrid->Barrier();
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Read in gauge field "<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
for(int n=0;n<nrhs;n++){
|
||||
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Writing out record "<<n<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
|
||||
std::stringstream filefn; filefn << filef << "."<< n;
|
||||
ScidacWriter _ScidacWriter;
|
||||
_ScidacWriter.open(filefn.str());
|
||||
_ScidacWriter.writeScidacFieldRecord(src[n],record);
|
||||
_ScidacWriter.close();
|
||||
}
|
||||
|
||||
FGrid->Barrier();
|
||||
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Reading back in the single process view "<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
|
||||
for(int n=0;n<nrhs;n++){
|
||||
if ( n==me ) {
|
||||
std::stringstream filefn; filefn << filef << "."<< n;
|
||||
ScidacReader _ScidacReader;
|
||||
_ScidacReader.open(filefn.str());
|
||||
_ScidacReader.readScidacFieldRecord(s_src,record);
|
||||
_ScidacReader.close();
|
||||
}
|
||||
}
|
||||
FGrid->Barrier();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// split the source out using MPI instead of I/O
|
||||
///////////////////////////////////////////////////////////////
|
||||
std::cout << GridLogMessage << " Splitting the grid data "<<std::endl;
|
||||
Grid_split (src,s_src_split);
|
||||
std::cout << GridLogMessage << " Finished splitting the grid data "<<std::endl;
|
||||
for(int n=0;n<nrhs;n++){
|
||||
std::cout <<GridLogMessage<<"Full "<< n <<" "<< norm2(src[n])<<std::endl;
|
||||
}
|
||||
s_tmp = s_src_split - s_src;
|
||||
for(int n=0;n<nrhs;n++){
|
||||
FGrid->Barrier();
|
||||
if ( n==me ) {
|
||||
std::cerr << GridLogMessage<<"Split "<< me << " " << norm2(s_src_split) << " " << norm2(s_src)<< " diff " << norm2(s_tmp)<<std::endl;
|
||||
}
|
||||
FGrid->Barrier();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Set up N-solvers as trivially parallel
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
RealD mass=0.01;
|
||||
RealD M5=1.8;
|
||||
DomainWallFermionR Dchk(Umu,*FGrid,*FrbGrid,*UGrid,*rbGrid,mass,M5);
|
||||
DomainWallFermionR Ddwf(s_Umu,*SFGrid,*SFrbGrid,*SGrid,*SrbGrid,mass,M5);
|
||||
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling DWF CG "<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
|
||||
MdagMLinearOperator<DomainWallFermionR,FermionField> HermOp(Ddwf);
|
||||
MdagMLinearOperator<DomainWallFermionR,FermionField> HermOpCk(Dchk);
|
||||
ConjugateGradient<FermionField> CG((1.0e-8/(me+1)),10000);
|
||||
s_res = zero;
|
||||
CG(HermOp,s_src,s_res);
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Report how long they all took
|
||||
/////////////////////////////////////////////////////////////
|
||||
std::vector<uint32_t> iterations(nrhs,0);
|
||||
iterations[me] = CG.IterationsToComplete;
|
||||
|
||||
for(int n=0;n<nrhs;n++){
|
||||
UGrid->GlobalSum(iterations[n]);
|
||||
std::cout << GridLogMessage<<" Rank "<<n<<" "<< iterations[n]<<" CG iterations"<<std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Gather and residual check on the results
|
||||
/////////////////////////////////////////////////////////////
|
||||
std::cout << GridLogMessage<< "Unsplitting the result"<<std::endl;
|
||||
Grid_unsplit(result,s_res);
|
||||
/*
|
||||
Grid_unsplit(src_chk,s_src);
|
||||
for(int n=0;n<nrhs;n++){
|
||||
tmp = src[n]-src_chk[n];
|
||||
std::cout << " src_chk "<<n<<" "<<norm2(src_chk[n])<<" " <<norm2(src[n])<<" " <<norm2(tmp)<< std::endl;
|
||||
std::cout << " diff " <<tmp<<std::endl;
|
||||
}
|
||||
*/
|
||||
|
||||
std::cout << GridLogMessage<< "Checking the residuals"<<std::endl;
|
||||
for(int n=0;n<nrhs;n++){
|
||||
HermOpCk.HermOp(result[n],tmp); tmp = tmp - src[n];
|
||||
std::cout << GridLogMessage<<" resid["<<n<<"] "<< norm2(tmp)<<std::endl;
|
||||
}
|
||||
|
||||
Grid_finalize();
|
||||
}
|
144
tests/solver/Test_dwf_mrhs_cg_mpi.cc
Normal file
144
tests/solver/Test_dwf_mrhs_cg_mpi.cc
Normal file
@ -0,0 +1,144 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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>
|
||||
#include <Grid/algorithms/iterative/BlockConjugateGradient.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
typedef typename DomainWallFermionR::FermionField FermionField;
|
||||
typedef typename DomainWallFermionR::ComplexField ComplexField;
|
||||
typename DomainWallFermionR::ImplParams params;
|
||||
|
||||
const int Ls=4;
|
||||
|
||||
Grid_init(&argc,&argv);
|
||||
|
||||
std::vector<int> latt_size = GridDefaultLatt();
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
std::vector<int> mpi_split (mpi_layout.size(),1);
|
||||
|
||||
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
||||
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
||||
GridRedBlackCartesian * rbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
|
||||
|
||||
int nrhs = UGrid->RankCount() ;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Split into 1^4 mpi communicators
|
||||
/////////////////////////////////////////////
|
||||
GridCartesian * SGrid = new GridCartesian(GridDefaultLatt(),
|
||||
GridDefaultSimd(Nd,vComplex::Nsimd()),
|
||||
mpi_split,
|
||||
*UGrid);
|
||||
|
||||
GridCartesian * SFGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,SGrid);
|
||||
GridRedBlackCartesian * SrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(SGrid);
|
||||
GridRedBlackCartesian * SFrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,SGrid);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Set up the problem as a 4d spreadout job
|
||||
///////////////////////////////////////////////
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
|
||||
GridParallelRNG pRNG(UGrid ); pRNG.SeedFixedIntegers(seeds);
|
||||
GridParallelRNG pRNG5(FGrid); pRNG5.SeedFixedIntegers(seeds);
|
||||
std::vector<FermionField> src(nrhs,FGrid);
|
||||
std::vector<FermionField> src_chk(nrhs,FGrid);
|
||||
std::vector<FermionField> result(nrhs,FGrid);
|
||||
FermionField tmp(FGrid);
|
||||
|
||||
for(int s=0;s<nrhs;s++) random(pRNG5,src[s]);
|
||||
for(int s=0;s<nrhs;s++) result[s]=zero;
|
||||
|
||||
LatticeGaugeField Umu(UGrid); SU3::HotConfiguration(pRNG,Umu);
|
||||
|
||||
/////////////////
|
||||
// MPI only sends
|
||||
/////////////////
|
||||
int me = UGrid->ThisRank();
|
||||
|
||||
LatticeGaugeField s_Umu(SGrid);
|
||||
FermionField s_src(SFGrid);
|
||||
FermionField s_tmp(SFGrid);
|
||||
FermionField s_res(SFGrid);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// split the source out using MPI instead of I/O
|
||||
///////////////////////////////////////////////////////////////
|
||||
Grid_split (Umu,s_Umu);
|
||||
Grid_split (src,s_src);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Set up N-solvers as trivially parallel
|
||||
///////////////////////////////////////////////////////////////
|
||||
RealD mass=0.01;
|
||||
RealD M5=1.8;
|
||||
DomainWallFermionR Dchk(Umu,*FGrid,*FrbGrid,*UGrid,*rbGrid,mass,M5);
|
||||
DomainWallFermionR Ddwf(s_Umu,*SFGrid,*SFrbGrid,*SGrid,*SrbGrid,mass,M5);
|
||||
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling DWF CG "<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
|
||||
MdagMLinearOperator<DomainWallFermionR,FermionField> HermOp(Ddwf);
|
||||
MdagMLinearOperator<DomainWallFermionR,FermionField> HermOpCk(Dchk);
|
||||
ConjugateGradient<FermionField> CG((1.0e-8/(me+1)),10000);
|
||||
s_res = zero;
|
||||
CG(HermOp,s_src,s_res);
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Report how long they all took
|
||||
/////////////////////////////////////////////////////////////
|
||||
std::vector<uint32_t> iterations(nrhs,0);
|
||||
iterations[me] = CG.IterationsToComplete;
|
||||
|
||||
for(int n=0;n<nrhs;n++){
|
||||
UGrid->GlobalSum(iterations[n]);
|
||||
std::cout << GridLogMessage<<" Rank "<<n<<" "<< iterations[n]<<" CG iterations"<<std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Gather and residual check on the results
|
||||
/////////////////////////////////////////////////////////////
|
||||
std::cout << GridLogMessage<< "Unsplitting the result"<<std::endl;
|
||||
Grid_unsplit(result,s_res);
|
||||
|
||||
std::cout << GridLogMessage<< "Checking the residuals"<<std::endl;
|
||||
for(int n=0;n<nrhs;n++){
|
||||
HermOpCk.HermOp(result[n],tmp); tmp = tmp - src[n];
|
||||
std::cout << GridLogMessage<<" resid["<<n<<"] "<< norm2(tmp)<<std::endl;
|
||||
}
|
||||
|
||||
Grid_finalize();
|
||||
}
|
163
tests/solver/Test_dwf_mrhs_cg_mpieo.cc
Normal file
163
tests/solver/Test_dwf_mrhs_cg_mpieo.cc
Normal file
@ -0,0 +1,163 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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>
|
||||
#include <Grid/algorithms/iterative/BlockConjugateGradient.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
typedef typename DomainWallFermionR::FermionField FermionField;
|
||||
typedef typename DomainWallFermionR::ComplexField ComplexField;
|
||||
typename DomainWallFermionR::ImplParams params;
|
||||
|
||||
const int Ls=4;
|
||||
|
||||
Grid_init(&argc,&argv);
|
||||
|
||||
std::vector<int> latt_size = GridDefaultLatt();
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
std::vector<int> mpi_split (mpi_layout.size(),1);
|
||||
|
||||
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
||||
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
||||
GridRedBlackCartesian * rbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
|
||||
|
||||
int nrhs = UGrid->RankCount() ;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Split into 1^4 mpi communicators
|
||||
/////////////////////////////////////////////
|
||||
GridCartesian * SGrid = new GridCartesian(GridDefaultLatt(),
|
||||
GridDefaultSimd(Nd,vComplex::Nsimd()),
|
||||
mpi_split,
|
||||
*UGrid);
|
||||
|
||||
GridCartesian * SFGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,SGrid);
|
||||
GridRedBlackCartesian * SrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(SGrid);
|
||||
GridRedBlackCartesian * SFrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,SGrid);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Set up the problem as a 4d spreadout job
|
||||
///////////////////////////////////////////////
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
|
||||
GridParallelRNG pRNG(UGrid ); pRNG.SeedFixedIntegers(seeds);
|
||||
GridParallelRNG pRNG5(FGrid); pRNG5.SeedFixedIntegers(seeds);
|
||||
std::vector<FermionField> src(nrhs,FGrid);
|
||||
std::vector<FermionField> src_chk(nrhs,FGrid);
|
||||
std::vector<FermionField> result(nrhs,FGrid);
|
||||
FermionField tmp(FGrid);
|
||||
|
||||
std::vector<FermionField> src_e(nrhs,FrbGrid);
|
||||
std::vector<FermionField> src_o(nrhs,FrbGrid);
|
||||
|
||||
for(int s=0;s<nrhs;s++) random(pRNG5,src[s]);
|
||||
for(int s=0;s<nrhs;s++) result[s]=zero;
|
||||
|
||||
LatticeGaugeField Umu(UGrid); SU3::HotConfiguration(pRNG,Umu);
|
||||
|
||||
/////////////////
|
||||
// MPI only sends
|
||||
/////////////////
|
||||
int me = UGrid->ThisRank();
|
||||
|
||||
LatticeGaugeField s_Umu(SGrid);
|
||||
FermionField s_src(SFGrid);
|
||||
FermionField s_src_e(SFrbGrid);
|
||||
FermionField s_src_o(SFrbGrid);
|
||||
FermionField s_tmp(SFGrid);
|
||||
FermionField s_res(SFGrid);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// split the source out using MPI instead of I/O
|
||||
///////////////////////////////////////////////////////////////
|
||||
Grid_split (Umu,s_Umu);
|
||||
Grid_split (src,s_src);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Check even odd cases
|
||||
///////////////////////////////////////////////////////////////
|
||||
for(int s=0;s<nrhs;s++){
|
||||
pickCheckerboard(Odd , src_o[s], src[s]);
|
||||
pickCheckerboard(Even, src_e[s], src[s]);
|
||||
}
|
||||
Grid_split (src_e,s_src_e);
|
||||
Grid_split (src_o,s_src_o);
|
||||
setCheckerboard(s_tmp, s_src_o);
|
||||
setCheckerboard(s_tmp, s_src_e);
|
||||
s_tmp = s_tmp - s_src;
|
||||
std::cout << GridLogMessage<<" EvenOdd Difference " <<norm2(s_tmp)<<std::endl;
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Set up N-solvers as trivially parallel
|
||||
///////////////////////////////////////////////////////////////
|
||||
RealD mass=0.01;
|
||||
RealD M5=1.8;
|
||||
DomainWallFermionR Dchk(Umu,*FGrid,*FrbGrid,*UGrid,*rbGrid,mass,M5);
|
||||
DomainWallFermionR Ddwf(s_Umu,*SFGrid,*SFrbGrid,*SGrid,*SrbGrid,mass,M5);
|
||||
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling DWF CG "<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
|
||||
MdagMLinearOperator<DomainWallFermionR,FermionField> HermOp(Ddwf);
|
||||
MdagMLinearOperator<DomainWallFermionR,FermionField> HermOpCk(Dchk);
|
||||
ConjugateGradient<FermionField> CG((1.0e-8/(me+1)),10000);
|
||||
s_res = zero;
|
||||
CG(HermOp,s_src,s_res);
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Report how long they all took
|
||||
/////////////////////////////////////////////////////////////
|
||||
std::vector<uint32_t> iterations(nrhs,0);
|
||||
iterations[me] = CG.IterationsToComplete;
|
||||
|
||||
for(int n=0;n<nrhs;n++){
|
||||
UGrid->GlobalSum(iterations[n]);
|
||||
std::cout << GridLogMessage<<" Rank "<<n<<" "<< iterations[n]<<" CG iterations"<<std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Gather and residual check on the results
|
||||
/////////////////////////////////////////////////////////////
|
||||
std::cout << GridLogMessage<< "Unsplitting the result"<<std::endl;
|
||||
Grid_unsplit(result,s_res);
|
||||
|
||||
std::cout << GridLogMessage<< "Checking the residuals"<<std::endl;
|
||||
for(int n=0;n<nrhs;n++){
|
||||
HermOpCk.HermOp(result[n],tmp); tmp = tmp - src[n];
|
||||
std::cout << GridLogMessage<<" resid["<<n<<"] "<< norm2(tmp)<<std::endl;
|
||||
}
|
||||
|
||||
Grid_finalize();
|
||||
}
|
@ -40,7 +40,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
std::vector<int> seeds({1,2,3,4,5});
|
||||
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||
|
130
tests/solver/Test_staggered_block_cg_prec.cc
Normal file
130
tests/solver/Test_staggered_block_cg_prec.cc
Normal file
@ -0,0 +1,130 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
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)
|
||||
{
|
||||
typedef typename ImprovedStaggeredFermion5DR::FermionField FermionField;
|
||||
typedef typename ImprovedStaggeredFermion5DR::ComplexField ComplexField;
|
||||
typename ImprovedStaggeredFermion5DR::ImplParams params;
|
||||
|
||||
const int Ls=8;
|
||||
|
||||
Grid_init(&argc,&argv);
|
||||
|
||||
std::vector<int> latt_size = GridDefaultLatt();
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
|
||||
GridCartesian * UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
|
||||
GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
|
||||
GridCartesian * FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
|
||||
GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
|
||||
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
GridParallelRNG pRNG(UGrid ); pRNG.SeedFixedIntegers(seeds);
|
||||
GridParallelRNG pRNG5(FGrid); pRNG5.SeedFixedIntegers(seeds);
|
||||
|
||||
FermionField src(FGrid); random(pRNG5,src);
|
||||
FermionField src_o(FrbGrid); pickCheckerboard(Odd,src_o,src);
|
||||
FermionField result_o(FrbGrid); result_o=zero;
|
||||
RealD nrm = norm2(src);
|
||||
|
||||
LatticeGaugeField Umu(UGrid); SU3::HotConfiguration(pRNG,Umu);
|
||||
|
||||
RealD mass=0.003;
|
||||
ImprovedStaggeredFermion5DR Ds(Umu,Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass);
|
||||
SchurStaggeredOperator<ImprovedStaggeredFermion5DR,FermionField> HermOp(Ds);
|
||||
|
||||
ConjugateGradient<FermionField> CG(1.0e-8,10000);
|
||||
int blockDim = 0;
|
||||
BlockConjugateGradient<FermionField> BCGrQ(BlockCGrQ,blockDim,1.0e-8,10000);
|
||||
BlockConjugateGradient<FermionField> BCG (BlockCG,blockDim,1.0e-8,10000);
|
||||
BlockConjugateGradient<FermionField> mCG (CGmultiRHS,blockDim,1.0e-8,10000);
|
||||
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling 4d CG "<<std::endl;
|
||||
std::cout << GridLogMessage << "****************************************************************** "<<std::endl;
|
||||
ImprovedStaggeredFermionR Ds4d(Umu,Umu,*UGrid,*UrbGrid,mass);
|
||||
SchurStaggeredOperator<ImprovedStaggeredFermionR,FermionField> HermOp4d(Ds4d);
|
||||
FermionField src4d(UGrid); random(pRNG,src4d);
|
||||
FermionField src4d_o(UrbGrid); pickCheckerboard(Odd,src4d_o,src4d);
|
||||
FermionField result4d_o(UrbGrid);
|
||||
|
||||
result4d_o=zero;
|
||||
CG(HermOp4d,src4d_o,result4d_o);
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling 5d CG for "<<Ls <<" right hand sides" <<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
Ds.ZeroCounters();
|
||||
result_o=zero;
|
||||
CG(HermOp,src_o,result_o);
|
||||
Ds.Report();
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling multiRHS CG for "<<Ls <<" right hand sides" <<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
Ds.ZeroCounters();
|
||||
result_o=zero;
|
||||
mCG(HermOp,src_o,result_o);
|
||||
Ds.Report();
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling Block CG for "<<Ls <<" right hand sides" <<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
Ds.ZeroCounters();
|
||||
result_o=zero;
|
||||
BCGrQ(HermOp,src_o,result_o);
|
||||
Ds.Report();
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
|
||||
Grid_finalize();
|
||||
}
|
@ -27,7 +27,6 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
#include <Grid/algorithms/iterative/BlockConjugateGradient.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
@ -75,7 +74,7 @@ int main (int argc, char ** argv)
|
||||
LatticeGaugeField Umu(UGrid); SU3::HotConfiguration(pRNG,Umu);
|
||||
|
||||
RealD mass=0.003;
|
||||
ImprovedStaggeredFermion5DR Ds(Umu,Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass);
|
||||
ImprovedStaggeredFermion5DR Ds(Umu,Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass);
|
||||
MdagMLinearOperator<ImprovedStaggeredFermion5DR,FermionField> HermOp(Ds);
|
||||
|
||||
ConjugateGradient<FermionField> CG(1.0e-8,10000);
|
||||
@ -99,21 +98,27 @@ int main (int argc, char ** argv)
|
||||
std::cout << GridLogMessage << " Calling 5d CG for "<<Ls <<" right hand sides" <<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
result=zero;
|
||||
Ds.ZeroCounters();
|
||||
CG(HermOp,src,result);
|
||||
Ds.Report();
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling multiRHS CG for "<<Ls <<" right hand sides" <<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
result=zero;
|
||||
Ds.ZeroCounters();
|
||||
mCG(HermOp,src,result);
|
||||
Ds.Report();
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling Block CG for "<<Ls <<" right hand sides" <<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
result=zero;
|
||||
Ds.ZeroCounters();
|
||||
BCGrQ(HermOp,src,result);
|
||||
Ds.Report();
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
|
||||
|
92
tests/solver/Test_staggered_cg_prec.cc
Normal file
92
tests/solver/Test_staggered_cg_prec.cc
Normal file
@ -0,0 +1,92 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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>
|
||||
#include <Grid/algorithms/iterative/BlockConjugateGradient.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
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)
|
||||
{
|
||||
typedef typename ImprovedStaggeredFermionR::FermionField FermionField;
|
||||
typedef typename ImprovedStaggeredFermionR::ComplexField ComplexField;
|
||||
typename ImprovedStaggeredFermionR::ImplParams params;
|
||||
|
||||
Grid_init(&argc,&argv);
|
||||
|
||||
std::vector<int> latt_size = GridDefaultLatt();
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> 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);
|
||||
|
||||
FermionField src(&Grid); random(pRNG,src);
|
||||
RealD nrm = norm2(src);
|
||||
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.003;
|
||||
ImprovedStaggeredFermionR Ds(Umu,Umu,Grid,RBGrid,mass);
|
||||
|
||||
FermionField res_o(&RBGrid);
|
||||
FermionField src_o(&RBGrid);
|
||||
pickCheckerboard(Odd,src_o,src);
|
||||
res_o=zero;
|
||||
|
||||
SchurStaggeredOperator<ImprovedStaggeredFermionR,FermionField> HermOpEO(Ds);
|
||||
ConjugateGradient<FermionField> CG(1.0e-8,10000);
|
||||
CG(HermOpEO,src_o,res_o);
|
||||
|
||||
FermionField tmp(&RBGrid);
|
||||
|
||||
HermOpEO.Mpc(res_o,tmp);
|
||||
std::cout << "check Mpc resid " << axpy_norm(tmp,-1.0,src_o,tmp)/norm2(src_o) << "\n";
|
||||
|
||||
Grid_finalize();
|
||||
}
|
@ -57,7 +57,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||
|
@ -52,7 +52,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||
|
@ -52,7 +52,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||
|
@ -52,7 +52,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||
|
@ -52,7 +52,7 @@ int main (int argc, char ** argv)
|
||||
std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||
std::vector<int> mpi_layout = GridDefaultMpi();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout);
|
||||
GridRedBlackCartesian RBGrid(&Grid);
|
||||
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||
|
Reference in New Issue
Block a user