mirror of
https://github.com/paboyle/Grid.git
synced 2025-06-13 04:37:05 +01:00
Merge branch 'develop' of https://github.com/paboyle/Grid into develop
This commit is contained in:
@ -4,11 +4,12 @@
|
||||
|
||||
Source file: ./tests/Test_serialisation.cc
|
||||
|
||||
Copyright (C) 2015-2016
|
||||
Copyright (C) 2015-2019
|
||||
|
||||
Author: Guido Cossu <guido.cossu@ed.ac.uk>
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: Michael Marshall <michael.marshall@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
|
||||
@ -28,6 +29,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
#include <typeinfo>
|
||||
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
@ -80,26 +82,159 @@ double d = 2*M_PI;
|
||||
bool b = false;
|
||||
|
||||
template <typename W, typename R, typename O>
|
||||
void ioTest(const std::string &filename, const O &object, const std::string &name)
|
||||
void ioTest(const std::string &filename, const O &object, const std::string &name,
|
||||
const char * tag = "testobject", unsigned short Precision = 0 )
|
||||
{
|
||||
std::cout << "IO test: " << name << " -> " << filename << " ...";
|
||||
// writer needs to be destroyed so that writing physically happens
|
||||
{
|
||||
W writer(filename);
|
||||
|
||||
write(writer, "testobject", object);
|
||||
if( Precision )
|
||||
writer.setPrecision(Precision);
|
||||
write(writer, tag , object);
|
||||
}
|
||||
|
||||
std::cout << " done. reading ...";
|
||||
R reader(filename);
|
||||
O buf;
|
||||
bool good;
|
||||
std::unique_ptr<O> buf( new O ); // In case object too big for stack
|
||||
|
||||
read(reader, "testobject", buf);
|
||||
good = (object == buf);
|
||||
std::cout << name << " IO test: " << (good ? "success" : "failure");
|
||||
std::cout << std::endl;
|
||||
if (!good) exit(EXIT_FAILURE);
|
||||
read(reader, tag, *buf);
|
||||
bool good = Serializable::CompareMember(object, *buf);
|
||||
if (!good) {
|
||||
std::cout << " failure!" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
std::cout << " done." << std::endl;
|
||||
}
|
||||
|
||||
// The only way I could get these iterators to work is to put the begin() and end() functions in the Eigen namespace
|
||||
// So if Eigen ever defines these, we'll have a conflict and have to change this
|
||||
namespace Eigen {
|
||||
template <typename ET>
|
||||
inline typename std::enable_if<EigenIO::is_tensor<ET>::value, typename EigenIO::Traits<ET>::scalar_type *>::type
|
||||
begin( ET & et ) { return reinterpret_cast<typename Grid::EigenIO::Traits<ET>::scalar_type *>(et.data()); }
|
||||
template <typename ET>
|
||||
inline typename std::enable_if<EigenIO::is_tensor<ET>::value, typename EigenIO::Traits<ET>::scalar_type *>::type
|
||||
end( ET & et ) { return begin(et) + et.size() * EigenIO::Traits<ET>::count; }
|
||||
}
|
||||
|
||||
// Perform I/O tests on a range of tensor types
|
||||
// Test coverage: scalars, complex and GridVectors in single, double and default precision
|
||||
class TensorIO : public Serializable {
|
||||
using TestScalar = ComplexD;
|
||||
using SR3 = Eigen::Sizes<9,4,2>;
|
||||
using SR5 = Eigen::Sizes<5,4,3,2,1>;
|
||||
using ESO = Eigen::StorageOptions;
|
||||
using TensorRank3 = Eigen::Tensor<ComplexF, 3, ESO::RowMajor>;
|
||||
using TensorR5 = Eigen::TensorFixedSize<Real, SR5>;
|
||||
using TensorR5Alt = Eigen::TensorFixedSize<Real, SR5, ESO::RowMajor>;
|
||||
using Tensor942 = Eigen::TensorFixedSize<TestScalar, SR3, ESO::RowMajor>;
|
||||
using aTensor942 = std::vector<Tensor942>;
|
||||
using Perambulator = Eigen::Tensor<SpinColourVector, 6, ESO::RowMajor>;
|
||||
using LSCTensor = Eigen::TensorFixedSize<SpinColourMatrix, Eigen::Sizes<6,5>>;
|
||||
|
||||
static const Real FlagR;
|
||||
static const Complex Flag;
|
||||
static const ComplexF FlagF;
|
||||
static const TestScalar FlagTS;
|
||||
static const char * const pszFilePrefix;
|
||||
|
||||
void Init(unsigned short Precision)
|
||||
{
|
||||
for( auto &s : Perambulator1 ) s = Flag;
|
||||
for( auto &s : Perambulator2 ) s = Flag;
|
||||
for( auto &s : tensorR5 ) s = FlagR;
|
||||
for( auto &s : tensorRank3 ) s = FlagF;
|
||||
for( auto &s : tensor_9_4_2 ) s = FlagTS;
|
||||
for( auto &t : atensor_9_4_2 )
|
||||
for( auto &s : t ) s = FlagTS;
|
||||
for( auto &s : MyLSCTensor ) s = Flag;
|
||||
}
|
||||
|
||||
// Perform an I/O test for a single Eigen tensor (of any type)
|
||||
template <typename W, typename R, typename T, typename... IndexTypes>
|
||||
static void TestOne(const char * MyTypeName, unsigned short Precision, std::string &filename,
|
||||
const char * pszExtension, unsigned int &TestNum,
|
||||
typename EigenIO::Traits<T>::scalar_type Flag, IndexTypes... otherDims)
|
||||
{
|
||||
using Traits = EigenIO::Traits<T>;
|
||||
using scalar_type = typename Traits::scalar_type;
|
||||
std::unique_ptr<T> pTensor{new T(otherDims...)};
|
||||
for( auto &s : * pTensor ) s = Flag;
|
||||
filename = pszFilePrefix + std::to_string(++TestNum) + "_" + MyTypeName + pszExtension;
|
||||
ioTest<W, R, T>(filename, * pTensor, MyTypeName, MyTypeName);
|
||||
}
|
||||
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(TensorIO
|
||||
, SpinColourVector, spinColourVector
|
||||
, SpinColourMatrix, spinColourMatrix
|
||||
, std::vector<std::string>, DistilParameterNames
|
||||
, std::vector<int>, DistilParameterValues
|
||||
, Perambulator, Perambulator1
|
||||
, Perambulator, Perambulator2
|
||||
, TensorR5, tensorR5
|
||||
, TensorRank3, tensorRank3
|
||||
, Tensor942, tensor_9_4_2
|
||||
, aTensor942, atensor_9_4_2
|
||||
, LSCTensor, MyLSCTensor
|
||||
);
|
||||
TensorIO()
|
||||
: DistilParameterNames {"do", "androids", "dream", "of", "electric", "sheep?"}
|
||||
, DistilParameterValues{2,3,1,4,5,1}
|
||||
, Perambulator1(2,3,1,4,5,1)
|
||||
, Perambulator2(7,1,6,1,5,1)
|
||||
, tensorRank3(7,3,2)
|
||||
, atensor_9_4_2(3) {}
|
||||
|
||||
#define TEST_PARAMS( T ) #T, Precision, filename, pszExtension, TestNum
|
||||
|
||||
// Perform a series of I/O tests for Eigen tensors, including a serialisable object
|
||||
template <typename WTR_, typename RDR_>
|
||||
static void Test(const char * pszExtension, unsigned short Precision = 0)
|
||||
{
|
||||
// Perform a series of tests on progressively more complex tensors
|
||||
unsigned int TestNum = 0;
|
||||
std::string filename;
|
||||
// Rank 1 tensor containing a single integer
|
||||
using TensorSingle = Eigen::TensorFixedSize<Integer, Eigen::Sizes<1>>;
|
||||
TestOne<WTR_, RDR_, TensorSingle>( TEST_PARAMS( TensorSingle ), 7 ); // lucky!
|
||||
// Rather convoluted way of defining four complex numbers
|
||||
using TensorSimple = Eigen::Tensor<iMatrix<TestScalar,2>, 6>;
|
||||
using I = typename TensorSimple::Index; // NB: Never specified, so same for all my test tensors
|
||||
// Try progressively more complicated tensors
|
||||
TestOne<WTR_, RDR_, TensorSimple, I,I,I,I,I,I>( TEST_PARAMS( TensorSimple ), FlagTS, 1,1,1,1,1,1 );
|
||||
TestOne<WTR_, RDR_, TensorRank3, I, I, I>( TEST_PARAMS( TensorRank3 ), FlagF, 6, 3, 2 );
|
||||
TestOne<WTR_, RDR_, Tensor942>(TEST_PARAMS( Tensor942 ), FlagTS);
|
||||
TestOne<WTR_, RDR_, LSCTensor>(TEST_PARAMS( LSCTensor ), Flag );
|
||||
TestOne<WTR_, RDR_, TensorR5>(TEST_PARAMS( TensorR5 ), FlagR);
|
||||
// Now test a serialisable object containing a number of tensors
|
||||
{
|
||||
static const char MyTypeName[] = "TensorIO";
|
||||
filename = pszFilePrefix + std::to_string(++TestNum) + "_" + MyTypeName + pszExtension;
|
||||
std::unique_ptr<TensorIO> pObj{new TensorIO()};
|
||||
pObj->Init(Precision);
|
||||
ioTest<WTR_, RDR_, TensorIO>(filename, * pObj, MyTypeName, MyTypeName, Precision);
|
||||
}
|
||||
// Stress test. Too large for the XML or text readers and writers!
|
||||
#ifdef STRESS_TEST
|
||||
const std::type_info &tw = typeid( WTR_ );
|
||||
if( tw == typeid( Hdf5Writer ) || tw == typeid( BinaryWriter ) ) {
|
||||
using LCMTensor=Eigen::TensorFixedSize<iMatrix<iVector<iMatrix<iVector<LorentzColourMatrix,5>,2>,7>,3>,
|
||||
Eigen::Sizes<2,4,11,10,9>, Eigen::StorageOptions::RowMajor>;
|
||||
std::cout << "sizeof( LCMTensor ) = " << sizeof( LCMTensor ) / 1024 / 1024 << " MB" << std::endl;
|
||||
TestOne<WTR_, RDR_, LCMTensor>(TEST_PARAMS( LCMTensor ), Flag);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
const Real TensorIO::FlagR {1};
|
||||
const Complex TensorIO::Flag {1,-1};
|
||||
const ComplexF TensorIO::FlagF {1,-1};
|
||||
const TensorIO::TestScalar TensorIO::FlagTS{1,-1};
|
||||
const char * const TensorIO::pszFilePrefix = "tensor_";
|
||||
|
||||
template <typename T>
|
||||
void tensorConvTestFn(GridSerialRNG &rng, const std::string label)
|
||||
{
|
||||
@ -121,12 +256,12 @@ void tensorConvTestFn(GridSerialRNG &rng, const std::string label)
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
Grid_init(&argc,&argv);
|
||||
|
||||
std::cout << std::boolalpha << "==== basic IO" << std::endl; // display true / false for boolean
|
||||
|
||||
GridSerialRNG rng;
|
||||
|
||||
rng.SeedFixedIntegers(std::vector<int>({42,10,81,9}));
|
||||
|
||||
std::cout << "==== basic IO" << std::endl;
|
||||
|
||||
XmlWriter WR("bother.xml");
|
||||
|
||||
// test basic type writing
|
||||
@ -146,7 +281,6 @@ int main(int argc,char **argv)
|
||||
// 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);
|
||||
@ -154,15 +288,15 @@ int main(int argc,char **argv)
|
||||
vec.push_back(obj);
|
||||
vec.push_back(myclass(5678));
|
||||
vec.push_back(myclass(3838));
|
||||
pair = std::make_pair(myenum::red, myenum::blue);
|
||||
|
||||
write(WR, "objvec", vec);
|
||||
std::cout << "-- serialisable class writing to std::cout:" << std::endl;
|
||||
std::cout << obj << std::endl;
|
||||
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;
|
||||
std::cout << "vec[0] == obj: " << (vec[0] == obj) << std::endl;
|
||||
std::cout << "vec[1] == obj: " << (vec[1] == obj) << std::endl;
|
||||
std::cout << "-- pair writing to std::cout:" << std::endl;
|
||||
std::pair<myenum, myenum> pair = std::make_pair(myenum::red, myenum::blue);
|
||||
std::cout << pair << std::endl;
|
||||
|
||||
// read tests
|
||||
@ -184,7 +318,15 @@ int main(int argc,char **argv)
|
||||
#ifdef HAVE_HDF5
|
||||
ioTest<Hdf5Writer, Hdf5Reader>("iotest.h5", obj, "HDF5 (object) ");
|
||||
ioTest<Hdf5Writer, Hdf5Reader>("iotest.h5", vec, "HDF5 (vector of objects)");
|
||||
std::cout << "\n==== detailed Hdf5 tensor tests (Grid::EigenIO)" << std::endl;
|
||||
TensorIO::Test<Hdf5Writer, Hdf5Reader>(".h5");
|
||||
#endif
|
||||
std::cout << "\n==== detailed binary tensor tests (Grid::EigenIO)" << std::endl;
|
||||
TensorIO::Test<BinaryWriter, BinaryReader>(".bin");
|
||||
std::cout << "\n==== detailed xml tensor tests (Grid::EigenIO)" << std::endl;
|
||||
TensorIO::Test<XmlWriter, XmlReader>(".xml", 6);
|
||||
std::cout << "\n==== detailed text tensor tests (Grid::EigenIO)" << std::endl;
|
||||
TensorIO::Test<TextWriter, TextReader>(".dat", 5);
|
||||
|
||||
std::cout << "\n==== vector flattening/reconstruction" << std::endl;
|
||||
typedef std::vector<std::vector<std::vector<double>>> vec3d;
|
||||
@ -227,4 +369,6 @@ int main(int argc,char **argv)
|
||||
tensorConvTest(rng, ColourVector);
|
||||
tensorConvTest(rng, SpinMatrix);
|
||||
tensorConvTest(rng, SpinVector);
|
||||
|
||||
Grid_finalize();
|
||||
}
|
||||
|
73
tests/smearing/Test_smearing.cc
Normal file
73
tests/smearing/Test_smearing.cc
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
*
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/Test_wilson_cg_prec.cc
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
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();
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
|
||||
std::vector<int> seeds({1,2,3,4});
|
||||
GridParallelRNG pRNG(&Grid); pRNG.SeedFixedIntegers(seeds);
|
||||
|
||||
LatticeFermion src(&Grid); random(pRNG,src);
|
||||
RealD nrm = norm2(src);
|
||||
LatticeFermion result(&Grid); result=zero;
|
||||
LatticeGaugeField Umu(&Grid);
|
||||
// SU3::HotConfiguration(pRNG,Umu);
|
||||
SU3::ColdConfiguration(Umu);
|
||||
std::vector<LatticeColourMatrix> U(4,&Grid);
|
||||
|
||||
for(int mu=0;mu<Nd;mu++){
|
||||
U[mu] = PeekIndex<LorentzIndex>(Umu,mu);
|
||||
}
|
||||
|
||||
std::vector<int> site({4,4,0,0});
|
||||
src=zero;
|
||||
SpinColourVector scv;
|
||||
scv=zero;
|
||||
scv()(0)(0) = 1.0;
|
||||
pokeSite(scv,src,site);
|
||||
|
||||
CovariantSmearing<PeriodicGimplR>::GaussianSmear(U, src, 2.0, 50, Tdir);
|
||||
|
||||
std::cout << src <<std::endl;
|
||||
|
||||
}
|
||||
|
194
tests/solver/Test_wilsonclover_mg_lime.cc
Normal file
194
tests/solver/Test_wilsonclover_mg_lime.cc
Normal file
@ -0,0 +1,194 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/solver/Test_wilsonclover_mg_mp.cc
|
||||
|
||||
Copyright (C) 2015-2018
|
||||
|
||||
Author: Daniel Richtmann <daniel.richtmann@ur.de>
|
||||
|
||||
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
|
||||
*************************************************************************************/
|
||||
/* */
|
||||
|
||||
|
||||
#include <Grid/Grid.h>
|
||||
#include <Test_multigrid_common.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Grid::QCD;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
|
||||
Grid_init(&argc, &argv);
|
||||
|
||||
// clang-format off
|
||||
GridCartesian *FGrid_d = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd, vComplexD::Nsimd()), GridDefaultMpi());
|
||||
GridCartesian *FGrid_f = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd, vComplexF::Nsimd()), GridDefaultMpi());
|
||||
GridRedBlackCartesian *FrbGrid_d = SpaceTimeGrid::makeFourDimRedBlackGrid(FGrid_d);
|
||||
GridRedBlackCartesian *FrbGrid_f = SpaceTimeGrid::makeFourDimRedBlackGrid(FGrid_f);
|
||||
// clang-format on
|
||||
|
||||
std::vector<int> fSeeds({1, 2, 3, 4});
|
||||
GridParallelRNG fPRNG(FGrid_d);
|
||||
fPRNG.SeedFixedIntegers(fSeeds);
|
||||
|
||||
// clang-format off
|
||||
LatticeFermionD src_d(FGrid_d); gaussian(fPRNG, src_d);
|
||||
LatticeFermionD resultMGD_d(FGrid_d); resultMGD_d = zero;
|
||||
LatticeFermionD resultMGF_d(FGrid_d); resultMGF_d = zero;
|
||||
LatticeGaugeFieldD Umu_d(FGrid_d);
|
||||
|
||||
#if 0
|
||||
{
|
||||
FieldMetaData header;
|
||||
std::string file("./qcdsf.769.00399.lime");
|
||||
std::cout <<GridLogMessage<<"**************************************"<<std::endl;
|
||||
std::cout <<GridLogMessage<<"** Reading back ILDG conf *********"<<std::endl;
|
||||
std::cout <<GridLogMessage<<"**************************************"<<std::endl;
|
||||
IldgReader _IldgReader;
|
||||
_IldgReader.open(file);
|
||||
_IldgReader.readConfiguration(Umu_d,header);
|
||||
_IldgReader.close();
|
||||
|
||||
}
|
||||
#else
|
||||
{
|
||||
FieldMetaData header;
|
||||
std::string file("./ckpoint_lat.IEEE64BIG.1100");
|
||||
NerscIO::readConfiguration(Umu_d,header,file);
|
||||
}
|
||||
#endif
|
||||
// SU3::HotConfiguration(fPRNG, Umu_d);
|
||||
|
||||
LatticeGaugeFieldF Umu_f(FGrid_f); precisionChange(Umu_f, Umu_d);
|
||||
// clang-format on
|
||||
|
||||
RealD mass = -0.25;
|
||||
RealD csw_r = 1.0;
|
||||
RealD csw_t = 1.0;
|
||||
|
||||
MultiGridParams mgParams;
|
||||
std::string inputXml{"./mg_params.xml"};
|
||||
|
||||
if(GridCmdOptionExists(argv, argv + argc, "--inputxml")) {
|
||||
inputXml = GridCmdOptionPayload(argv, argv + argc, "--inputxml");
|
||||
assert(inputXml.length() != 0);
|
||||
}
|
||||
|
||||
{
|
||||
XmlWriter writer("mg_params_template.xml");
|
||||
write(writer, "Params", mgParams);
|
||||
std::cout << GridLogMessage << "Written mg_params_template.xml" << std::endl;
|
||||
|
||||
XmlReader reader(inputXml);
|
||||
read(reader, "Params", mgParams);
|
||||
std::cout << GridLogMessage << "Read in " << inputXml << std::endl;
|
||||
}
|
||||
|
||||
checkParameterValidity(mgParams);
|
||||
std::cout << mgParams << std::endl;
|
||||
|
||||
LevelInfo levelInfo_d(FGrid_d, mgParams);
|
||||
LevelInfo levelInfo_f(FGrid_f, mgParams);
|
||||
|
||||
// Note: We do chiral doubling, so actually only nbasis/2 full basis vectors are used
|
||||
const int nbasis = 40;
|
||||
|
||||
WilsonCloverFermionD Dwc_d(Umu_d, *FGrid_d, *FrbGrid_d, mass, csw_r, csw_t);
|
||||
WilsonCloverFermionF Dwc_f(Umu_f, *FGrid_f, *FrbGrid_f, mass, csw_r, csw_t);
|
||||
|
||||
MdagMLinearOperator<WilsonCloverFermionD, LatticeFermionD> MdagMOpDwc_d(Dwc_d);
|
||||
MdagMLinearOperator<WilsonCloverFermionF, LatticeFermionF> MdagMOpDwc_f(Dwc_f);
|
||||
|
||||
std::cout << GridLogMessage << "**************************************************" << std::endl;
|
||||
std::cout << GridLogMessage << "Testing single-precision Multigrid for Wilson Clover" << std::endl;
|
||||
std::cout << GridLogMessage << "**************************************************" << std::endl;
|
||||
|
||||
auto MGPreconDwc_f = createMGInstance<vSpinColourVectorF, vTComplexF, nbasis, WilsonCloverFermionF>(mgParams, levelInfo_f, Dwc_f, Dwc_f);
|
||||
|
||||
MGPreconDwc_f->setup();
|
||||
|
||||
if(GridCmdOptionExists(argv, argv + argc, "--runchecks")) {
|
||||
MGPreconDwc_f->runChecks(1e-6);
|
||||
}
|
||||
|
||||
MixedPrecisionFlexibleGeneralisedMinimalResidual<LatticeFermionD, LatticeFermionF> MPFGMRESPREC(
|
||||
1.0e-12, 50000, FGrid_f, *MGPreconDwc_f, 100, false);
|
||||
|
||||
std::cout << std::endl << "Starting with a new solver" << std::endl;
|
||||
MPFGMRESPREC(MdagMOpDwc_d, src_d, resultMGF_d);
|
||||
|
||||
MGPreconDwc_f->reportTimings();
|
||||
|
||||
if(GridCmdOptionExists(argv, argv + argc, "--docomparison")) {
|
||||
|
||||
std::cout << GridLogMessage << "**************************************************" << std::endl;
|
||||
std::cout << GridLogMessage << "Testing double-precision Multigrid for Wilson Clover" << std::endl;
|
||||
std::cout << GridLogMessage << "**************************************************" << std::endl;
|
||||
|
||||
auto MGPreconDwc_d = createMGInstance<vSpinColourVectorD, vTComplexD, nbasis, WilsonCloverFermionD>(mgParams, levelInfo_d, Dwc_d, Dwc_d);
|
||||
|
||||
MGPreconDwc_d->setup();
|
||||
|
||||
if(GridCmdOptionExists(argv, argv + argc, "--runchecks")) {
|
||||
MGPreconDwc_d->runChecks(1e-13);
|
||||
}
|
||||
|
||||
FlexibleGeneralisedMinimalResidual<LatticeFermionD> FGMRESPREC(1.0e-12, 50000, *MGPreconDwc_d, 100, false);
|
||||
|
||||
std::cout << std::endl << "Starting with a new solver" << std::endl;
|
||||
FGMRESPREC(MdagMOpDwc_d, src_d, resultMGD_d);
|
||||
|
||||
MGPreconDwc_d->reportTimings();
|
||||
|
||||
std::cout << GridLogMessage << "**************************************************" << std::endl;
|
||||
std::cout << GridLogMessage << "Comparing single-precision Multigrid with double-precision one for Wilson Clover" << std::endl;
|
||||
std::cout << GridLogMessage << "**************************************************" << std::endl;
|
||||
|
||||
LatticeFermionD diffFullSolver(FGrid_d);
|
||||
|
||||
RealD deviationFullSolver = axpy_norm(diffFullSolver, -1.0, resultMGF_d, resultMGD_d);
|
||||
|
||||
// clang-format off
|
||||
LatticeFermionF src_f(FGrid_f); precisionChange(src_f, src_d);
|
||||
LatticeFermionF resMGF_f(FGrid_f); resMGF_f = zero;
|
||||
LatticeFermionD resMGD_d(FGrid_d); resMGD_d = zero;
|
||||
// clang-format on
|
||||
|
||||
(*MGPreconDwc_f)(src_f, resMGF_f);
|
||||
(*MGPreconDwc_d)(src_d, resMGD_d);
|
||||
|
||||
LatticeFermionD diffOnlyMG(FGrid_d);
|
||||
LatticeFermionD resMGF_d(FGrid_d);
|
||||
precisionChange(resMGF_d, resMGF_f);
|
||||
|
||||
RealD deviationOnlyPrec = axpy_norm(diffOnlyMG, -1.0, resMGF_d, resMGD_d);
|
||||
|
||||
// clang-format off
|
||||
std::cout << GridLogMessage << "Absolute difference between FGMRES preconditioned by double and single precicision MG: " << deviationFullSolver << std::endl;
|
||||
std::cout << GridLogMessage << "Relative deviation between FGMRES preconditioned by double and single precicision MG: " << deviationFullSolver / norm2(resultMGD_d) << std::endl;
|
||||
std::cout << GridLogMessage << "Absolute difference between one iteration of MG Prec in double and single precision: " << deviationOnlyPrec << std::endl;
|
||||
std::cout << GridLogMessage << "Relative deviation between one iteration of MG Prec in double and single precision: " << deviationOnlyPrec / norm2(resMGD_d) << std::endl;
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
Grid_finalize();
|
||||
}
|
Reference in New Issue
Block a user