mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-10 15:55:37 +00:00
Merge branch 'develop' of https://github.com/paboyle/Grid into develop
This commit is contained in:
commit
d9de8fd5c9
@ -24,7 +24,7 @@ endif
|
|||||||
all: version-cache
|
all: version-cache
|
||||||
|
|
||||||
version-cache:
|
version-cache:
|
||||||
if [ `git status --porcelain | grep -v '??' | wc -l` -gt 0 ]; then\
|
@if [ `git status --porcelain | grep -v '??' | wc -l` -gt 0 ]; then\
|
||||||
a="uncommited changes";\
|
a="uncommited changes";\
|
||||||
else\
|
else\
|
||||||
a="clean";\
|
a="clean";\
|
||||||
|
@ -31,21 +31,13 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
|
||||||
template<class Field>
|
template<class Field>
|
||||||
class Guesser {
|
class ZeroGuesser: public LinearFunction<Field> {
|
||||||
public:
|
|
||||||
Guesser(void) = default;
|
|
||||||
virtual ~Guesser(void) = default;
|
|
||||||
virtual void operator()(const Field &src, Field &guess) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Field>
|
|
||||||
class ZeroGuesser: public Guesser<Field> {
|
|
||||||
public:
|
public:
|
||||||
virtual void operator()(const Field &src, Field &guess) { guess = zero; };
|
virtual void operator()(const Field &src, Field &guess) { guess = zero; };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Field>
|
template<class Field>
|
||||||
class SourceGuesser: public Guesser<Field> {
|
class SourceGuesser: public LinearFunction<Field> {
|
||||||
public:
|
public:
|
||||||
virtual void operator()(const Field &src, Field &guess) { guess = src; };
|
virtual void operator()(const Field &src, Field &guess) { guess = src; };
|
||||||
};
|
};
|
||||||
@ -54,7 +46,7 @@ public:
|
|||||||
// Fine grid deflation
|
// Fine grid deflation
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
template<class Field>
|
template<class Field>
|
||||||
class DeflatedGuesser: public Guesser<Field> {
|
class DeflatedGuesser: public LinearFunction<Field> {
|
||||||
private:
|
private:
|
||||||
const std::vector<Field> &evec;
|
const std::vector<Field> &evec;
|
||||||
const std::vector<RealD> &eval;
|
const std::vector<RealD> &eval;
|
||||||
@ -76,7 +68,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class FineField, class CoarseField>
|
template<class FineField, class CoarseField>
|
||||||
class LocalCoherenceDeflatedGuesser: public Guesser<FineField> {
|
class LocalCoherenceDeflatedGuesser: public LinearFunction<FineField> {
|
||||||
private:
|
private:
|
||||||
const std::vector<FineField> &subspace;
|
const std::vector<FineField> &subspace;
|
||||||
const std::vector<CoarseField> &evec_coarse;
|
const std::vector<CoarseField> &evec_coarse;
|
||||||
|
@ -423,4 +423,17 @@ namespace Grid {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper function to read space-separated values
|
||||||
|
template <typename T>
|
||||||
|
std::string vecToStr(const std::vector<T> &v)
|
||||||
|
{
|
||||||
|
using Grid::operator<<;
|
||||||
|
|
||||||
|
std::ostringstream sstr;
|
||||||
|
|
||||||
|
sstr << v;
|
||||||
|
|
||||||
|
return sstr.str();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -62,10 +62,10 @@ Application::Application(void)
|
|||||||
LOG(Message) << std::endl;
|
LOG(Message) << std::endl;
|
||||||
LOG(Message) << "** Default parameters (and associated C macros)" << std::endl;
|
LOG(Message) << "** Default parameters (and associated C macros)" << std::endl;
|
||||||
LOG(Message) << "ASCII output precision : " << MACOUT(DEFAULT_ASCII_PREC) << std::endl;
|
LOG(Message) << "ASCII output precision : " << MACOUT(DEFAULT_ASCII_PREC) << std::endl;
|
||||||
LOG(Message) << "Fermion implementation : " << MACOUTS(FIMPL) << std::endl;
|
LOG(Message) << "Fermion implementation : " << MACOUTS(FIMPLBASE) << std::endl;
|
||||||
LOG(Message) << "z-Fermion implementation: " << MACOUTS(ZFIMPL) << std::endl;
|
LOG(Message) << "z-Fermion implementation: " << MACOUTS(ZFIMPLBASE) << std::endl;
|
||||||
LOG(Message) << "Scalar implementation : " << MACOUTS(SIMPL) << std::endl;
|
LOG(Message) << "Scalar implementation : " << MACOUTS(SIMPLBASE) << std::endl;
|
||||||
LOG(Message) << "Gauge implementation : " << MACOUTS(GIMPL) << std::endl;
|
LOG(Message) << "Gauge implementation : " << MACOUTS(GIMPLBASE) << std::endl;
|
||||||
LOG(Message) << "Eigenvector base size : "
|
LOG(Message) << "Eigenvector base size : "
|
||||||
<< MACOUT(HADRONS_DEFAULT_LANCZOS_NBASIS) << std::endl;
|
<< MACOUT(HADRONS_DEFAULT_LANCZOS_NBASIS) << std::endl;
|
||||||
LOG(Message) << "Schur decomposition : " << MACOUTS(HADRONS_DEFAULT_SCHUR) << std::endl;
|
LOG(Message) << "Schur decomposition : " << MACOUTS(HADRONS_DEFAULT_SCHUR) << std::endl;
|
||||||
|
@ -45,135 +45,22 @@ Environment::Environment(void)
|
|||||||
{
|
{
|
||||||
dim_ = GridDefaultLatt();
|
dim_ = GridDefaultLatt();
|
||||||
nd_ = dim_.size();
|
nd_ = dim_.size();
|
||||||
grid4d_.reset(SpaceTimeGrid::makeFourDimGrid(
|
defaultGrid_ = {typeHash<vComplex>(), 1};
|
||||||
dim_, GridDefaultSimd(nd_, vComplex::Nsimd()),
|
grid4d_[defaultGrid_].reset(
|
||||||
|
SpaceTimeGrid::makeFourDimGrid(dim_,
|
||||||
|
GridDefaultSimd(nd_, vComplex::Nsimd()),
|
||||||
GridDefaultMpi()));
|
GridDefaultMpi()));
|
||||||
gridRb4d_.reset(SpaceTimeGrid::makeFourDimRedBlackGrid(grid4d_.get()));
|
gridRb4d_[defaultGrid_].reset(
|
||||||
|
SpaceTimeGrid::makeFourDimRedBlackGrid(grid4d_[defaultGrid_].get()));
|
||||||
vol_ = 1.;
|
vol_ = 1.;
|
||||||
for (auto d: dim_)
|
for (auto d: dim_)
|
||||||
{
|
{
|
||||||
vol_ *= d;
|
vol_ *= d;
|
||||||
}
|
}
|
||||||
rng4d_.reset(new GridParallelRNG(grid4d_.get()));
|
rng4d_.reset(new GridParallelRNG(grid4d_[defaultGrid_].get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// grids ///////////////////////////////////////////////////////////////////////
|
// grids ///////////////////////////////////////////////////////////////////////
|
||||||
void Environment::createGrid(const unsigned int Ls)
|
|
||||||
{
|
|
||||||
if ((Ls > 1) and (grid5d_.find(Ls) == grid5d_.end()))
|
|
||||||
{
|
|
||||||
auto g = getGrid();
|
|
||||||
|
|
||||||
grid5d_[Ls].reset(SpaceTimeGrid::makeFiveDimGrid(Ls, g));
|
|
||||||
gridRb5d_[Ls].reset(SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, g));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Environment::createCoarseGrid(const std::vector<int> &blockSize,
|
|
||||||
const unsigned int Ls)
|
|
||||||
{
|
|
||||||
int nd = getNd();
|
|
||||||
std::vector<int> fineDim = getDim(), coarseDim;
|
|
||||||
unsigned int cLs;
|
|
||||||
auto key4d = blockSize, key5d = blockSize;
|
|
||||||
|
|
||||||
createGrid(Ls);
|
|
||||||
coarseDim.resize(nd);
|
|
||||||
for (int d = 0; d < coarseDim.size(); d++)
|
|
||||||
{
|
|
||||||
coarseDim[d] = fineDim[d]/blockSize[d];
|
|
||||||
if (coarseDim[d]*blockSize[d] != fineDim[d])
|
|
||||||
{
|
|
||||||
HADRONS_ERROR(Size, "Fine dimension " + std::to_string(d)
|
|
||||||
+ " (" + std::to_string(fineDim[d])
|
|
||||||
+ ") not divisible by coarse dimension ("
|
|
||||||
+ std::to_string(coarseDim[d]) + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (blockSize.size() > nd)
|
|
||||||
{
|
|
||||||
cLs = Ls/blockSize[nd];
|
|
||||||
if (cLs*blockSize[nd] != Ls)
|
|
||||||
{
|
|
||||||
HADRONS_ERROR(Size, "Fine Ls (" + std::to_string(Ls)
|
|
||||||
+ ") not divisible by coarse Ls ("
|
|
||||||
+ std::to_string(cLs) + ")");
|
|
||||||
}
|
|
||||||
key4d.resize(nd);
|
|
||||||
key5d.push_back(Ls);
|
|
||||||
}
|
|
||||||
gridCoarse4d_[key4d].reset(
|
|
||||||
SpaceTimeGrid::makeFourDimGrid(coarseDim,
|
|
||||||
GridDefaultSimd(nd, vComplex::Nsimd()), GridDefaultMpi()));
|
|
||||||
if (Ls > 1)
|
|
||||||
{
|
|
||||||
gridCoarse5d_[key5d].reset(
|
|
||||||
SpaceTimeGrid::makeFiveDimGrid(cLs, gridCoarse4d_[key4d].get()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridCartesian * Environment::getGrid(const unsigned int Ls) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Ls == 1)
|
|
||||||
{
|
|
||||||
return grid4d_.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return grid5d_.at(Ls).get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(std::out_of_range &)
|
|
||||||
{
|
|
||||||
HADRONS_ERROR(Definition, "no grid with Ls= " + std::to_string(Ls));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridRedBlackCartesian * Environment::getRbGrid(const unsigned int Ls) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Ls == 1)
|
|
||||||
{
|
|
||||||
return gridRb4d_.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return gridRb5d_.at(Ls).get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(std::out_of_range &)
|
|
||||||
{
|
|
||||||
HADRONS_ERROR(Definition, "no red-black grid with Ls= " + std::to_string(Ls));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridCartesian * Environment::getCoarseGrid(
|
|
||||||
const std::vector<int> &blockSize, const unsigned int Ls) const
|
|
||||||
{
|
|
||||||
auto key = blockSize;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Ls == 1)
|
|
||||||
{
|
|
||||||
key.resize(getNd());
|
|
||||||
return gridCoarse4d_.at(key).get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
key.push_back(Ls);
|
|
||||||
return gridCoarse5d_.at(key).get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(std::out_of_range &)
|
|
||||||
{
|
|
||||||
HADRONS_ERROR(Definition, "no coarse grid with Ls= " + std::to_string(Ls));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Environment::getNd(void) const
|
unsigned int Environment::getNd(void) const
|
||||||
{
|
{
|
||||||
return nd_;
|
return nd_;
|
||||||
|
@ -63,6 +63,9 @@ inline Environment & env(void) const\
|
|||||||
return Environment::getInstance();\
|
return Environment::getInstance();\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEFINE_ENV_LAMBDA \
|
||||||
|
auto env = [](void)->Environment &{return Environment::getInstance();}
|
||||||
|
|
||||||
class Environment
|
class Environment
|
||||||
{
|
{
|
||||||
SINGLETON(Environment);
|
SINGLETON(Environment);
|
||||||
@ -83,15 +86,28 @@ private:
|
|||||||
int module{-1};
|
int module{-1};
|
||||||
std::unique_ptr<Object> data{nullptr};
|
std::unique_ptr<Object> data{nullptr};
|
||||||
};
|
};
|
||||||
|
typedef std::pair<size_t, unsigned int> FineGridKey;
|
||||||
|
typedef std::pair<size_t, std::vector<int>> CoarseGridKey;
|
||||||
public:
|
public:
|
||||||
// grids
|
// grids
|
||||||
|
template <typename VType = vComplex>
|
||||||
void createGrid(const unsigned int Ls);
|
void createGrid(const unsigned int Ls);
|
||||||
|
template <typename VType = vComplex>
|
||||||
void createCoarseGrid(const std::vector<int> &blockSize,
|
void createCoarseGrid(const std::vector<int> &blockSize,
|
||||||
const unsigned int Ls = 1);
|
const unsigned int Ls = 1);
|
||||||
GridCartesian * getGrid(const unsigned int Ls = 1) const;
|
template <typename VType = vComplex>
|
||||||
GridRedBlackCartesian * getRbGrid(const unsigned int Ls = 1) const;
|
GridCartesian * getGrid(void) const;
|
||||||
|
template <typename VType = vComplex>
|
||||||
|
GridRedBlackCartesian * getRbGrid(void) const;
|
||||||
|
template <typename VType = vComplex>
|
||||||
|
GridCartesian * getCoarseGrid(const std::vector<int> &blockSize) const;
|
||||||
|
template <typename VType = vComplex>
|
||||||
|
GridCartesian * getGrid(const unsigned int Ls) const;
|
||||||
|
template <typename VType = vComplex>
|
||||||
|
GridRedBlackCartesian * getRbGrid(const unsigned int Ls) const;
|
||||||
|
template <typename VType = vComplex>
|
||||||
GridCartesian * getCoarseGrid(const std::vector<int> &blockSize,
|
GridCartesian * getCoarseGrid(const std::vector<int> &blockSize,
|
||||||
const unsigned int Ls = 1) const;
|
const unsigned int Ls) const;
|
||||||
std::vector<int> getDim(void) const;
|
std::vector<int> getDim(void) const;
|
||||||
int getDim(const unsigned int mu) const;
|
int getDim(const unsigned int mu) const;
|
||||||
unsigned int getNd(void) const;
|
unsigned int getNd(void) const;
|
||||||
@ -158,12 +174,13 @@ private:
|
|||||||
bool protect_{true};
|
bool protect_{true};
|
||||||
// grids
|
// grids
|
||||||
std::vector<int> dim_;
|
std::vector<int> dim_;
|
||||||
GridPt grid4d_;
|
FineGridKey defaultGrid_;
|
||||||
std::map<unsigned int, GridPt> grid5d_;
|
std::map<FineGridKey, GridPt> grid4d_;
|
||||||
GridRbPt gridRb4d_;
|
std::map<FineGridKey, GridPt> grid5d_;
|
||||||
std::map<unsigned int, GridRbPt> gridRb5d_;
|
std::map<FineGridKey, GridRbPt> gridRb4d_;
|
||||||
std::map<std::vector<int>, GridPt> gridCoarse4d_;
|
std::map<FineGridKey, GridRbPt> gridRb5d_;
|
||||||
std::map<std::vector<int>, GridPt> gridCoarse5d_;
|
std::map<CoarseGridKey, GridPt> gridCoarse4d_;
|
||||||
|
std::map<CoarseGridKey, GridPt> gridCoarse5d_;
|
||||||
unsigned int nd_;
|
unsigned int nd_;
|
||||||
// random number generator
|
// random number generator
|
||||||
RngPt rng4d_;
|
RngPt rng4d_;
|
||||||
@ -203,6 +220,191 @@ void Holder<T>::reset(T *pt)
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Environment template implementation *
|
* Environment template implementation *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
// grids ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename VType>
|
||||||
|
void Environment::createGrid(const unsigned int Ls)
|
||||||
|
{
|
||||||
|
size_t hash = typeHash<VType>();
|
||||||
|
|
||||||
|
if (grid4d_.find({hash, 1}) == grid4d_.end())
|
||||||
|
{
|
||||||
|
grid4d_[{hash, 1}].reset(
|
||||||
|
SpaceTimeGrid::makeFourDimGrid(getDim(),
|
||||||
|
GridDefaultSimd(getNd(), VType::Nsimd()),
|
||||||
|
GridDefaultMpi()));
|
||||||
|
gridRb4d_[{hash, 1}].reset(
|
||||||
|
SpaceTimeGrid::makeFourDimRedBlackGrid(grid4d_[{hash, 1}].get()));
|
||||||
|
}
|
||||||
|
if (grid5d_.find({hash, Ls}) == grid5d_.end())
|
||||||
|
{
|
||||||
|
auto g = grid4d_[{hash, 1}].get();
|
||||||
|
|
||||||
|
grid5d_[{hash, Ls}].reset(SpaceTimeGrid::makeFiveDimGrid(Ls, g));
|
||||||
|
gridRb5d_[{hash, Ls}].reset(SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, g));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VType>
|
||||||
|
void Environment::createCoarseGrid(const std::vector<int> &blockSize,
|
||||||
|
const unsigned int Ls)
|
||||||
|
{
|
||||||
|
int nd = getNd();
|
||||||
|
std::vector<int> fineDim = getDim(), coarseDim(nd);
|
||||||
|
unsigned int cLs;
|
||||||
|
auto key4d = blockSize, key5d = blockSize;
|
||||||
|
size_t hash = typeHash<VType>();
|
||||||
|
|
||||||
|
createGrid(Ls);
|
||||||
|
for (int d = 0; d < coarseDim.size(); d++)
|
||||||
|
{
|
||||||
|
coarseDim[d] = fineDim[d]/blockSize[d];
|
||||||
|
if (coarseDim[d]*blockSize[d] != fineDim[d])
|
||||||
|
{
|
||||||
|
HADRONS_ERROR(Size, "Fine dimension " + std::to_string(d)
|
||||||
|
+ " (" + std::to_string(fineDim[d])
|
||||||
|
+ ") not divisible by coarse dimension ("
|
||||||
|
+ std::to_string(coarseDim[d]) + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (blockSize.size() > nd)
|
||||||
|
{
|
||||||
|
cLs = Ls/blockSize[nd];
|
||||||
|
if (cLs*blockSize[nd] != Ls)
|
||||||
|
{
|
||||||
|
HADRONS_ERROR(Size, "Fine Ls (" + std::to_string(Ls)
|
||||||
|
+ ") not divisible by coarse Ls ("
|
||||||
|
+ std::to_string(cLs) + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cLs = Ls;
|
||||||
|
}
|
||||||
|
key4d.resize(nd);
|
||||||
|
key5d.push_back(Ls);
|
||||||
|
|
||||||
|
CoarseGridKey hkey4d = {hash, key4d}, hkey5d = {hash, key5d};
|
||||||
|
|
||||||
|
if (gridCoarse4d_.find(hkey4d) == gridCoarse4d_.end())
|
||||||
|
{
|
||||||
|
gridCoarse4d_[hkey4d].reset(
|
||||||
|
SpaceTimeGrid::makeFourDimGrid(coarseDim,
|
||||||
|
GridDefaultSimd(nd, VType::Nsimd()), GridDefaultMpi()));
|
||||||
|
}
|
||||||
|
if (gridCoarse5d_.find(hkey5d) == gridCoarse5d_.end())
|
||||||
|
{
|
||||||
|
gridCoarse5d_[hkey5d].reset(
|
||||||
|
SpaceTimeGrid::makeFiveDimGrid(cLs, gridCoarse4d_[hkey4d].get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VType>
|
||||||
|
GridCartesian * Environment::getGrid(void) const
|
||||||
|
{
|
||||||
|
auto it = grid4d_.find({typeHash<VType>(), 1});
|
||||||
|
|
||||||
|
if (it != grid4d_.end())
|
||||||
|
{
|
||||||
|
return it->second.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRONS_ERROR(Definition, "no 4D grid for SIMD type '"
|
||||||
|
+ typeName<VType>() + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VType>
|
||||||
|
GridRedBlackCartesian * Environment::getRbGrid(void) const
|
||||||
|
{
|
||||||
|
auto it = gridRb4d_.find({typeHash<VType>(), 1});
|
||||||
|
|
||||||
|
if (it != gridRb4d_.end())
|
||||||
|
{
|
||||||
|
return it->second.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRONS_ERROR(Definition, "no 4D red-black grid for SIMD type '"
|
||||||
|
+ typeName<VType>() + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VType>
|
||||||
|
GridCartesian * Environment::getCoarseGrid(const std::vector<int> &blockSize) const
|
||||||
|
{
|
||||||
|
std::vector<int> s = blockSize;
|
||||||
|
|
||||||
|
s.resize(getNd());
|
||||||
|
auto it = gridCoarse4d_.find({typeHash<VType>(), s});
|
||||||
|
if (it != gridCoarse4d_.end())
|
||||||
|
{
|
||||||
|
return it->second.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRONS_ERROR(Definition, "no 4D coarse grid for SIMD type '"
|
||||||
|
+ typeName<VType>() + "' and block size "
|
||||||
|
+ vecToStr(blockSize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VType>
|
||||||
|
GridCartesian * Environment::getGrid(const unsigned int Ls) const
|
||||||
|
{
|
||||||
|
auto it = grid5d_.find({typeHash<VType>(), Ls});
|
||||||
|
|
||||||
|
if (it != grid5d_.end())
|
||||||
|
{
|
||||||
|
return it->second.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRONS_ERROR(Definition, "no 5D grid for SIMD type '"
|
||||||
|
+ typeName<VType>() + "' and Ls = "
|
||||||
|
+ std::to_string(Ls));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VType>
|
||||||
|
GridRedBlackCartesian * Environment::getRbGrid(const unsigned int Ls) const
|
||||||
|
{
|
||||||
|
auto it = gridRb5d_.find({typeHash<VType>(), Ls});
|
||||||
|
|
||||||
|
if (it != gridRb5d_.end())
|
||||||
|
{
|
||||||
|
return it->second.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRONS_ERROR(Definition, "no 5D red-black grid for SIMD type '"
|
||||||
|
+ typeName<VType>() + "' and Ls = "
|
||||||
|
+ std::to_string(Ls));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VType>
|
||||||
|
GridCartesian * Environment::getCoarseGrid(const std::vector<int> &blockSize,
|
||||||
|
const unsigned int Ls) const
|
||||||
|
{
|
||||||
|
std::vector<int> s = blockSize;
|
||||||
|
|
||||||
|
s.push_back(Ls);
|
||||||
|
auto it = gridCoarse5d_.find({typeHash<VType>(), s});
|
||||||
|
if (it != gridCoarse5d_.end())
|
||||||
|
{
|
||||||
|
return it->second.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRONS_ERROR(Definition, "no 5D coarse grid for SIMD type '"
|
||||||
|
+ typeName<VType>() + "', block size "
|
||||||
|
+ vecToStr(blockSize)
|
||||||
|
+ " and Ls = " + std::to_string(Ls));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// general memory management ///////////////////////////////////////////////////
|
// general memory management ///////////////////////////////////////////////////
|
||||||
template <typename B, typename T, typename ... Ts>
|
template <typename B, typename T, typename ... Ts>
|
||||||
void Environment::createDerivedObject(const std::string name,
|
void Environment::createDerivedObject(const std::string name,
|
||||||
@ -230,8 +432,8 @@ void Environment::createDerivedObject(const std::string name,
|
|||||||
object_[address].Ls = Ls;
|
object_[address].Ls = Ls;
|
||||||
object_[address].data.reset(new Holder<B>(new T(std::forward<Ts>(args)...)));
|
object_[address].data.reset(new Holder<B>(new T(std::forward<Ts>(args)...)));
|
||||||
object_[address].size = MemoryProfiler::stats->maxAllocated - initMem;
|
object_[address].size = MemoryProfiler::stats->maxAllocated - initMem;
|
||||||
object_[address].type = &typeid(B);
|
object_[address].type = typeIdPt<B>();
|
||||||
object_[address].derivedType = &typeid(T);
|
object_[address].derivedType = typeIdPt<T>();
|
||||||
if (MemoryProfiler::stats == &memStats)
|
if (MemoryProfiler::stats == &memStats)
|
||||||
{
|
{
|
||||||
MemoryProfiler::stats = nullptr;
|
MemoryProfiler::stats = nullptr;
|
||||||
@ -241,8 +443,8 @@ void Environment::createDerivedObject(const std::string name,
|
|||||||
else if ((object_[address].storage != Storage::cache) or
|
else if ((object_[address].storage != Storage::cache) or
|
||||||
(object_[address].storage != storage) or
|
(object_[address].storage != storage) or
|
||||||
(object_[address].name != name) or
|
(object_[address].name != name) or
|
||||||
(object_[address].type != &typeid(B)) or
|
(typeHash(object_[address].type) != typeHash<B>()) or
|
||||||
(object_[address].derivedType != &typeid(T)))
|
(typeHash(object_[address].derivedType) != typeHash<T>()))
|
||||||
{
|
{
|
||||||
HADRONS_ERROR_REF(ObjectDefinition, "object '" + name + "' already allocated", address);
|
HADRONS_ERROR_REF(ObjectDefinition, "object '" + name + "' already allocated", address);
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,11 @@ void Hadrons::initLogger(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// type utilities //////////////////////////////////////////////////////////////
|
// type utilities //////////////////////////////////////////////////////////////
|
||||||
|
size_t Hadrons::typeHash(const std::type_info *info)
|
||||||
|
{
|
||||||
|
return info->hash_code();
|
||||||
|
}
|
||||||
|
|
||||||
constexpr unsigned int maxNameSize = 1024u;
|
constexpr unsigned int maxNameSize = 1024u;
|
||||||
|
|
||||||
std::string Hadrons::typeName(const std::type_info *info)
|
std::string Hadrons::typeName(const std::type_info *info)
|
||||||
|
@ -62,18 +62,36 @@ using Grid::operator>>;
|
|||||||
|
|
||||||
#define END_MODULE_NAMESPACE }
|
#define END_MODULE_NAMESPACE }
|
||||||
|
|
||||||
#ifndef FIMPL
|
#define _HADRONS_IMPL(impl, sub) impl##sub
|
||||||
#define FIMPL WilsonImplR
|
#define HADRONS_IMPL(impl, sub) _HADRONS_IMPL(impl, sub)
|
||||||
|
|
||||||
|
#ifndef FIMPLBASE
|
||||||
|
#define FIMPLBASE WilsonImpl
|
||||||
#endif
|
#endif
|
||||||
#ifndef ZFIMPL
|
#define FIMPL HADRONS_IMPL(FIMPLBASE, R)
|
||||||
#define ZFIMPL ZWilsonImplR
|
#define FIMPLF HADRONS_IMPL(FIMPLBASE, F)
|
||||||
|
#define FIMPLD HADRONS_IMPL(FIMPLBASE, D)
|
||||||
|
|
||||||
|
#ifndef ZFIMPLBASE
|
||||||
|
#define ZFIMPLBASE ZWilsonImpl
|
||||||
#endif
|
#endif
|
||||||
#ifndef SIMPL
|
#define ZFIMPL HADRONS_IMPL(ZFIMPLBASE, R)
|
||||||
#define SIMPL ScalarImplCR
|
#define ZFIMPLF HADRONS_IMPL(ZFIMPLBASE, F)
|
||||||
|
#define ZFIMPLD HADRONS_IMPL(ZFIMPLBASE, D)
|
||||||
|
|
||||||
|
#ifndef SIMPLBASE
|
||||||
|
#define SIMPLBASE ScalarImplC
|
||||||
#endif
|
#endif
|
||||||
#ifndef GIMPL
|
#define SIMPL HADRONS_IMPL(SIMPLBASE, R)
|
||||||
#define GIMPL PeriodicGimplR
|
#define SIMPLF HADRONS_IMPL(SIMPLBASE, F)
|
||||||
|
#define SIMPLD HADRONS_IMPL(SIMPLBASE, D)
|
||||||
|
|
||||||
|
#ifndef GIMPLBASE
|
||||||
|
#define GIMPLBASE PeriodicGimpl
|
||||||
#endif
|
#endif
|
||||||
|
#define GIMPL HADRONS_IMPL(GIMPLBASE, R)
|
||||||
|
#define GIMPLF HADRONS_IMPL(GIMPLBASE, F)
|
||||||
|
#define GIMPLD HADRONS_IMPL(GIMPLBASE, D)
|
||||||
|
|
||||||
BEGIN_HADRONS_NAMESPACE
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
@ -155,14 +173,28 @@ const std::type_info * typeIdPt(const T &x)
|
|||||||
return &typeid(x);
|
return &typeid(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string typeName(const std::type_info *info);
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const std::type_info * typeIdPt(void)
|
const std::type_info * typeIdPt(void)
|
||||||
{
|
{
|
||||||
return &typeid(T);
|
return &typeid(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t typeHash(const std::type_info *info);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t typeHash(const T &x)
|
||||||
|
{
|
||||||
|
return typeHash(typeIdPt(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t typeHash(void)
|
||||||
|
{
|
||||||
|
return typeHash(typeIdPt<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string typeName(const std::type_info *info);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string typeName(const T &x)
|
std::string typeName(const T &x)
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,9 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
|||||||
#include <Hadrons/Modules/MSource/SeqConserved.hpp>
|
#include <Hadrons/Modules/MSource/SeqConserved.hpp>
|
||||||
#include <Hadrons/Modules/MSink/Smear.hpp>
|
#include <Hadrons/Modules/MSink/Smear.hpp>
|
||||||
#include <Hadrons/Modules/MSink/Point.hpp>
|
#include <Hadrons/Modules/MSink/Point.hpp>
|
||||||
|
#include <Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp>
|
||||||
#include <Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp>
|
#include <Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp>
|
||||||
|
#include <Hadrons/Modules/MSolver/Guesser.hpp>
|
||||||
#include <Hadrons/Modules/MSolver/RBPrecCG.hpp>
|
#include <Hadrons/Modules/MSolver/RBPrecCG.hpp>
|
||||||
#include <Hadrons/Modules/MSolver/A2AVectors.hpp>
|
#include <Hadrons/Modules/MSolver/A2AVectors.hpp>
|
||||||
#include <Hadrons/Modules/MGauge/UnitEm.hpp>
|
#include <Hadrons/Modules/MGauge/UnitEm.hpp>
|
||||||
|
85
Hadrons/Modules/MSolver/Guesser.hpp
Normal file
85
Hadrons/Modules/MSolver/Guesser.hpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: Hadrons/Modules/MSolver/Guesser.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#ifndef Hadrons_MSolver_Guesser_hpp_
|
||||||
|
#define Hadrons_MSolver_Guesser_hpp_
|
||||||
|
|
||||||
|
#include <Hadrons/Global.hpp>
|
||||||
|
#include <Hadrons/EigenPack.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
BEGIN_MODULE_NAMESPACE(MSolver)
|
||||||
|
|
||||||
|
template <typename FImpl, int nBasis>
|
||||||
|
std::shared_ptr<LinearFunction<typename FImpl::FermionField>>
|
||||||
|
makeGuesser(const std::string epackName)
|
||||||
|
{
|
||||||
|
typedef typename FImpl::FermionField FermionField;
|
||||||
|
typedef FermionEigenPack<FImpl> EPack;
|
||||||
|
typedef CoarseFermionEigenPack<FImpl, nBasis> CoarseEPack;
|
||||||
|
typedef DeflatedGuesser<FermionField> FineGuesser;
|
||||||
|
typedef LocalCoherenceDeflatedGuesser<
|
||||||
|
FermionField, typename CoarseEPack::CoarseField> CoarseGuesser;
|
||||||
|
|
||||||
|
std::shared_ptr<LinearFunction<typename FImpl::FermionField>> guesserPt;
|
||||||
|
|
||||||
|
DEFINE_ENV_LAMBDA;
|
||||||
|
|
||||||
|
if (epackName.empty())
|
||||||
|
{
|
||||||
|
guesserPt.reset(new ZeroGuesser<FermionField>());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto &epack = envGetDerived(EPack, CoarseEPack, epackName);
|
||||||
|
|
||||||
|
LOG(Message) << "using low-mode deflation with coarse eigenpack '"
|
||||||
|
<< epackName << "' ("
|
||||||
|
<< epack.evecCoarse.size() << " modes)" << std::endl;
|
||||||
|
guesserPt.reset(new CoarseGuesser(epack.evec, epack.evecCoarse,
|
||||||
|
epack.evalCoarse));
|
||||||
|
}
|
||||||
|
catch (Exceptions::ObjectType &e)
|
||||||
|
{
|
||||||
|
auto &epack = envGet(EPack, epackName);
|
||||||
|
|
||||||
|
LOG(Message) << "using low-mode deflation with eigenpack '"
|
||||||
|
<< epackName << "' ("
|
||||||
|
<< epack.evec.size() << " modes)" << std::endl;
|
||||||
|
guesserPt.reset(new FineGuesser(epack.evec, epack.eval));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return guesserPt;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif
|
35
Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.cc
Normal file
35
Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.cc
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
|
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 <Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
using namespace MSolver;
|
||||||
|
|
||||||
|
template class Grid::Hadrons::MSolver::TMixedPrecisionRBPrecCG<FIMPLF, FIMPLD, HADRONS_DEFAULT_LANCZOS_NBASIS>;
|
||||||
|
template class Grid::Hadrons::MSolver::TMixedPrecisionRBPrecCG<ZFIMPLF, ZFIMPLD, HADRONS_DEFAULT_LANCZOS_NBASIS>;
|
197
Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp
Normal file
197
Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015-2018
|
||||||
|
|
||||||
|
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#ifndef Hadrons_MSolver_MixedPrecisionRBPrecCG_hpp_
|
||||||
|
#define Hadrons_MSolver_MixedPrecisionRBPrecCG_hpp_
|
||||||
|
|
||||||
|
#include <Hadrons/Global.hpp>
|
||||||
|
#include <Hadrons/Module.hpp>
|
||||||
|
#include <Hadrons/ModuleFactory.hpp>
|
||||||
|
#include <Hadrons/Solver.hpp>
|
||||||
|
#include <Hadrons/EigenPack.hpp>
|
||||||
|
#include <Hadrons/Modules/MSolver/Guesser.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Mixed precision schur red-black preconditioned CG *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MSolver)
|
||||||
|
|
||||||
|
class MixedPrecisionRBPrecCGPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(MixedPrecisionRBPrecCGPar,
|
||||||
|
std::string , innerAction,
|
||||||
|
std::string , outerAction,
|
||||||
|
unsigned int, maxInnerIteration,
|
||||||
|
unsigned int, maxOuterIteration,
|
||||||
|
double , residual,
|
||||||
|
std::string , eigenPack);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||||
|
class TMixedPrecisionRBPrecCG: public Module<MixedPrecisionRBPrecCGPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FG_TYPE_ALIASES(FImplInner, Inner);
|
||||||
|
FG_TYPE_ALIASES(FImplOuter, Outer);
|
||||||
|
SOLVER_TYPE_ALIASES(FImplOuter,);
|
||||||
|
typedef HADRONS_DEFAULT_SCHUR_OP<FMatInner, FermionFieldInner> SchurFMatInner;
|
||||||
|
typedef HADRONS_DEFAULT_SCHUR_OP<FMatOuter, FermionFieldOuter> SchurFMatOuter;
|
||||||
|
private:
|
||||||
|
template <typename Field>
|
||||||
|
class OperatorFunctionWrapper: public OperatorFunction<Field>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OperatorFunctionWrapper(LinearFunction<Field> &fn): fn_(fn) {};
|
||||||
|
virtual ~OperatorFunctionWrapper(void) = default;
|
||||||
|
virtual void operator()(LinearOperatorBase<Field> &op,
|
||||||
|
const Field &in, Field &out)
|
||||||
|
{
|
||||||
|
fn_(in, out);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
LinearFunction<Field> &fn_;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TMixedPrecisionRBPrecCG(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TMixedPrecisionRBPrecCG(void) {};
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getReference(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_TMP(MixedPrecisionRBPrecCG,
|
||||||
|
ARG(TMixedPrecisionRBPrecCG<FIMPLF, FIMPLD, HADRONS_DEFAULT_LANCZOS_NBASIS>), MSolver);
|
||||||
|
MODULE_REGISTER_TMP(ZMixedPrecisionRBPrecCG,
|
||||||
|
ARG(TMixedPrecisionRBPrecCG<ZFIMPLF, ZFIMPLD, HADRONS_DEFAULT_LANCZOS_NBASIS>), MSolver);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TMixedPrecisionRBPrecCG implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||||
|
TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||||
|
::TMixedPrecisionRBPrecCG(const std::string name)
|
||||||
|
: Module<MixedPrecisionRBPrecCGPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||||
|
std::vector<std::string> TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||||
|
::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||||
|
std::vector<std::string> TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||||
|
::getReference(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> ref = {par().innerAction, par().outerAction};
|
||||||
|
|
||||||
|
if (!par().eigenPack.empty())
|
||||||
|
{
|
||||||
|
ref.push_back(par().eigenPack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||||
|
std::vector<std::string> TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||||
|
::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName(), getName() + "_subtract"};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||||
|
void TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||||
|
::setup(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Setting up Schur red-black preconditioned mixed-precision "
|
||||||
|
<< "CG for inner/outer action '" << par().innerAction
|
||||||
|
<< "'/'" << par().outerAction << "', residual "
|
||||||
|
<< par().residual << ", and maximum inner/outer iteration "
|
||||||
|
<< par().maxInnerIteration << "/" << par().maxOuterIteration
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
auto Ls = env().getObjectLs(par().innerAction);
|
||||||
|
auto &imat = envGet(FMatInner, par().innerAction);
|
||||||
|
auto &omat = envGet(FMatOuter, par().outerAction);
|
||||||
|
auto guesserPt = makeGuesser<FImplOuter, nBasis>(par().eigenPack);
|
||||||
|
|
||||||
|
auto makeSolver = [&imat, &omat, guesserPt, Ls, this](bool subGuess)
|
||||||
|
{
|
||||||
|
return [&imat, &omat, guesserPt, subGuess, Ls, this]
|
||||||
|
(FermionFieldOuter &sol, const FermionFieldOuter &source)
|
||||||
|
{
|
||||||
|
typedef typename FermionFieldInner::vector_type VTypeInner;
|
||||||
|
|
||||||
|
SchurFMatInner simat(imat);
|
||||||
|
SchurFMatOuter somat(omat);
|
||||||
|
MixedPrecisionConjugateGradient<FermionFieldOuter, FermionFieldInner>
|
||||||
|
mpcg(par().residual, par().maxInnerIteration,
|
||||||
|
par().maxOuterIteration,
|
||||||
|
env().template getGrid<VTypeInner>(Ls),
|
||||||
|
simat, somat);
|
||||||
|
OperatorFunctionWrapper<FermionFieldOuter> wmpcg(mpcg);
|
||||||
|
HADRONS_DEFAULT_SCHUR_SOLVE<FermionFieldOuter> schurSolver(wmpcg);
|
||||||
|
schurSolver.subtractGuess(subGuess);
|
||||||
|
schurSolver(omat, source, sol, *guesserPt);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
auto solver = makeSolver(false);
|
||||||
|
envCreate(Solver, getName(), Ls, solver, omat);
|
||||||
|
auto solver_subtract = makeSolver(true);
|
||||||
|
envCreate(Solver, getName() + "_subtract", Ls, solver_subtract, omat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImplInner, typename FImplOuter, int nBasis>
|
||||||
|
void TMixedPrecisionRBPrecCG<FImplInner, FImplOuter, nBasis>
|
||||||
|
::execute(void)
|
||||||
|
{}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_MSolver_MixedPrecisionRBPrecCG_hpp_
|
@ -35,6 +35,7 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
|||||||
#include <Hadrons/ModuleFactory.hpp>
|
#include <Hadrons/ModuleFactory.hpp>
|
||||||
#include <Hadrons/Solver.hpp>
|
#include <Hadrons/Solver.hpp>
|
||||||
#include <Hadrons/EigenPack.hpp>
|
#include <Hadrons/EigenPack.hpp>
|
||||||
|
#include <Hadrons/Modules/MSolver/Guesser.hpp>
|
||||||
|
|
||||||
BEGIN_HADRONS_NAMESPACE
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
@ -59,13 +60,6 @@ class TRBPrecCG: public Module<RBPrecCGPar>
|
|||||||
public:
|
public:
|
||||||
FG_TYPE_ALIASES(FImpl,);
|
FG_TYPE_ALIASES(FImpl,);
|
||||||
SOLVER_TYPE_ALIASES(FImpl,);
|
SOLVER_TYPE_ALIASES(FImpl,);
|
||||||
typedef FermionEigenPack<FImpl> EPack;
|
|
||||||
typedef CoarseFermionEigenPack<FImpl, nBasis> CoarseEPack;
|
|
||||||
typedef std::shared_ptr<Guesser<FermionField>> GuesserPt;
|
|
||||||
typedef DeflatedGuesser<typename FImpl::FermionField> FineGuesser;
|
|
||||||
typedef LocalCoherenceDeflatedGuesser<
|
|
||||||
typename FImpl::FermionField,
|
|
||||||
typename CoarseEPack::CoarseField> CoarseGuesser;
|
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
TRBPrecCG(const std::string name);
|
TRBPrecCG(const std::string name);
|
||||||
@ -140,43 +134,16 @@ void TRBPrecCG<FImpl, nBasis>::setup(void)
|
|||||||
|
|
||||||
auto Ls = env().getObjectLs(par().action);
|
auto Ls = env().getObjectLs(par().action);
|
||||||
auto &mat = envGet(FMat, par().action);
|
auto &mat = envGet(FMat, par().action);
|
||||||
std::string guesserName = getName() + "_guesser";
|
auto guesserPt = makeGuesser<FImpl, nBasis>(par().eigenPack);
|
||||||
GuesserPt guesser{nullptr};
|
|
||||||
|
|
||||||
if (par().eigenPack.empty())
|
auto makeSolver = [&mat, guesserPt, this](bool subGuess) {
|
||||||
{
|
return [&mat, guesserPt, subGuess, this](FermionField &sol,
|
||||||
guesser.reset(new ZeroGuesser<FermionField>());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
auto &epack = envGetDerived(EPack, CoarseEPack, par().eigenPack);
|
|
||||||
|
|
||||||
LOG(Message) << "using low-mode deflation with coarse eigenpack '"
|
|
||||||
<< par().eigenPack << "' ("
|
|
||||||
<< epack.evecCoarse.size() << " modes)" << std::endl;
|
|
||||||
guesser.reset(new CoarseGuesser(epack.evec, epack.evecCoarse,
|
|
||||||
epack.evalCoarse));
|
|
||||||
}
|
|
||||||
catch (Exceptions::ObjectType &e)
|
|
||||||
{
|
|
||||||
auto &epack = envGet(EPack, par().eigenPack);
|
|
||||||
|
|
||||||
LOG(Message) << "using low-mode deflation with eigenpack '"
|
|
||||||
<< par().eigenPack << "' ("
|
|
||||||
<< epack.evec.size() << " modes)" << std::endl;
|
|
||||||
guesser.reset(new FineGuesser(epack.evec, epack.eval));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto makeSolver = [&mat, guesser, this](bool subGuess) {
|
|
||||||
return [&mat, guesser, subGuess, this](FermionField &sol,
|
|
||||||
const FermionField &source) {
|
const FermionField &source) {
|
||||||
ConjugateGradient<FermionField> cg(par().residual,
|
ConjugateGradient<FermionField> cg(par().residual,
|
||||||
par().maxIteration);
|
par().maxIteration);
|
||||||
HADRONS_DEFAULT_SCHUR_SOLVE<FermionField> schurSolver(cg);
|
HADRONS_DEFAULT_SCHUR_SOLVE<FermionField> schurSolver(cg);
|
||||||
schurSolver.subtractGuess(subGuess);
|
schurSolver.subtractGuess(subGuess);
|
||||||
schurSolver(mat, source, sol, *guesser);
|
schurSolver(mat, source, sol, *guesserPt);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
auto solver = makeSolver(false);
|
auto solver = makeSolver(false);
|
||||||
|
@ -19,6 +19,7 @@ modules_cc =\
|
|||||||
Modules/MSink/Smear.cc \
|
Modules/MSink/Smear.cc \
|
||||||
Modules/MSolver/A2AVectors.cc \
|
Modules/MSolver/A2AVectors.cc \
|
||||||
Modules/MSolver/RBPrecCG.cc \
|
Modules/MSolver/RBPrecCG.cc \
|
||||||
|
Modules/MSolver/MixedPrecisionRBPrecCG.cc \
|
||||||
Modules/MSolver/LocalCoherenceLanczos.cc \
|
Modules/MSolver/LocalCoherenceLanczos.cc \
|
||||||
Modules/MGauge/StoutSmearing.cc \
|
Modules/MGauge/StoutSmearing.cc \
|
||||||
Modules/MGauge/Unit.cc \
|
Modules/MGauge/Unit.cc \
|
||||||
@ -80,7 +81,9 @@ modules_hpp =\
|
|||||||
Modules/MSource/SeqConserved.hpp \
|
Modules/MSource/SeqConserved.hpp \
|
||||||
Modules/MSink/Smear.hpp \
|
Modules/MSink/Smear.hpp \
|
||||||
Modules/MSink/Point.hpp \
|
Modules/MSink/Point.hpp \
|
||||||
|
Modules/MSolver/MixedPrecisionRBPrecCG.hpp \
|
||||||
Modules/MSolver/LocalCoherenceLanczos.hpp \
|
Modules/MSolver/LocalCoherenceLanczos.hpp \
|
||||||
|
Modules/MSolver/Guesser.hpp \
|
||||||
Modules/MSolver/RBPrecCG.hpp \
|
Modules/MSolver/RBPrecCG.hpp \
|
||||||
Modules/MSolver/A2AVectors.hpp \
|
Modules/MSolver/A2AVectors.hpp \
|
||||||
Modules/MGauge/UnitEm.hpp \
|
Modules/MGauge/UnitEm.hpp \
|
||||||
|
@ -57,7 +57,7 @@ int main(int argc, char *argv[])
|
|||||||
globalPar.trajCounter.start = 1500;
|
globalPar.trajCounter.start = 1500;
|
||||||
globalPar.trajCounter.end = 1520;
|
globalPar.trajCounter.end = 1520;
|
||||||
globalPar.trajCounter.step = 20;
|
globalPar.trajCounter.step = 20;
|
||||||
globalPar.seed = "1 2 3 4";
|
globalPar.runId = "test";
|
||||||
application.setPar(globalPar);
|
application.setPar(globalPar);
|
||||||
// gauge field
|
// gauge field
|
||||||
application.createModule<MGauge::Unit>("gauge");
|
application.createModule<MGauge::Unit>("gauge");
|
||||||
|
@ -59,7 +59,7 @@ int main(int argc, char *argv[])
|
|||||||
globalPar.trajCounter.start = 1500;
|
globalPar.trajCounter.start = 1500;
|
||||||
globalPar.trajCounter.end = 1520;
|
globalPar.trajCounter.end = 1520;
|
||||||
globalPar.trajCounter.step = 20;
|
globalPar.trajCounter.step = 20;
|
||||||
globalPar.seed = "1 2 3 4";
|
globalPar.runId = "test";
|
||||||
application.setPar(globalPar);
|
application.setPar(globalPar);
|
||||||
// gauge field
|
// gauge field
|
||||||
application.createModule<MGauge::Unit>("gauge");
|
application.createModule<MGauge::Unit>("gauge");
|
||||||
|
@ -51,7 +51,7 @@ using namespace Hadrons;
|
|||||||
globalPar.trajCounter.start = 1500; \
|
globalPar.trajCounter.start = 1500; \
|
||||||
globalPar.trajCounter.end = 1520; \
|
globalPar.trajCounter.end = 1520; \
|
||||||
globalPar.trajCounter.step = 20; \
|
globalPar.trajCounter.step = 20; \
|
||||||
globalPar.seed = "1 2 3 4"; \
|
globalPar.runId = "test"; \
|
||||||
globalPar.genetic.maxGen = 1000; \
|
globalPar.genetic.maxGen = 1000; \
|
||||||
globalPar.genetic.maxCstGen = 200; \
|
globalPar.genetic.maxCstGen = 200; \
|
||||||
globalPar.genetic.popSize = 20; \
|
globalPar.genetic.popSize = 20; \
|
||||||
|
@ -54,7 +54,7 @@ int main(int argc, char *argv[])
|
|||||||
globalPar.trajCounter.start = 1500;
|
globalPar.trajCounter.start = 1500;
|
||||||
globalPar.trajCounter.end = 1520;
|
globalPar.trajCounter.end = 1520;
|
||||||
globalPar.trajCounter.step = 20;
|
globalPar.trajCounter.step = 20;
|
||||||
globalPar.seed = "1 2 3 4";
|
globalPar.runId = "test";
|
||||||
globalPar.genetic.maxGen = 1000;
|
globalPar.genetic.maxGen = 1000;
|
||||||
globalPar.genetic.maxCstGen = 200;
|
globalPar.genetic.maxCstGen = 200;
|
||||||
globalPar.genetic.popSize = 20;
|
globalPar.genetic.popSize = 20;
|
||||||
|
@ -1,156 +0,0 @@
|
|||||||
/*************************************************************************************
|
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
|
||||||
|
|
||||||
Source file: Tests/Hadrons/Test_hadrons_quark.cc
|
|
||||||
|
|
||||||
Copyright (C) 2015-2018
|
|
||||||
|
|
||||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
|
|
||||||
|
|
||||||
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 "Test_hadrons.hpp"
|
|
||||||
|
|
||||||
using namespace Grid;
|
|
||||||
using namespace QCD;
|
|
||||||
using namespace Hadrons;
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Unit test functions within Quark module.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
// Alternative 4D & 5D projections
|
|
||||||
template<class vobj>
|
|
||||||
inline void make_4D_with_gammas(Lattice<vobj> &in_5d, Lattice<vobj> &out_4d, int Ls)
|
|
||||||
{
|
|
||||||
GridBase *_grid(out_4d._grid);
|
|
||||||
Lattice<vobj> tmp(_grid);
|
|
||||||
Gamma G5(Gamma::Algebra::Gamma5);
|
|
||||||
|
|
||||||
ExtractSlice(tmp, in_5d, 0, 0);
|
|
||||||
out_4d = 0.5 * (tmp - G5*tmp);
|
|
||||||
ExtractSlice(tmp, in_5d, Ls - 1, 0);
|
|
||||||
out_4d += 0.5 * (tmp + G5*tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class vobj>
|
|
||||||
inline void make_5D_with_gammas(Lattice<vobj> &in_4d, Lattice<vobj> &out_5d, int Ls)
|
|
||||||
{
|
|
||||||
out_5d = zero;
|
|
||||||
Gamma G5(Gamma::Algebra::Gamma5);
|
|
||||||
GridBase *_grid(in_4d._grid);
|
|
||||||
Lattice<vobj> tmp(_grid);
|
|
||||||
|
|
||||||
tmp = 0.5 * (in_4d + G5*in_4d);
|
|
||||||
InsertSlice(tmp, out_5d, 0, 0);
|
|
||||||
tmp = 0.5 * (in_4d - G5*in_4d);
|
|
||||||
InsertSlice(tmp, out_5d, Ls - 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
/***************************************************************************
|
|
||||||
* Initialisation.
|
|
||||||
**************************************************************************/
|
|
||||||
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(latt_size,simd_layout,mpi_layout);
|
|
||||||
GridCartesian *FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, &UGrid);
|
|
||||||
GridSerialRNG sRNG;
|
|
||||||
GridParallelRNG pRNG(&UGrid);
|
|
||||||
|
|
||||||
std::vector<int> seeds4({1,2,3,4});
|
|
||||||
std::vector<int> seeds5({5,6,7,8});
|
|
||||||
GridParallelRNG rng4(&UGrid);
|
|
||||||
GridParallelRNG rng5(FGrid);
|
|
||||||
rng4.SeedFixedIntegers(seeds4);
|
|
||||||
rng5.SeedFixedIntegers(seeds5);
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Build a 4D random source, and convert it to 5D.
|
|
||||||
**************************************************************************/
|
|
||||||
LatticeFermion test4(&UGrid);
|
|
||||||
LatticeFermion test5(FGrid);
|
|
||||||
LatticeFermion check5(FGrid);
|
|
||||||
|
|
||||||
gaussian(rng4, test4);
|
|
||||||
make_5D(test4, test5, Ls);
|
|
||||||
make_5D_with_gammas(test4, check5, Ls);
|
|
||||||
test5 -= check5;
|
|
||||||
std::cout << "4D -> 5D comparison, diff = " << Grid::sqrt(norm2(test5)) << std::endl;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Build a 5D random source, and project down to 4D.
|
|
||||||
**************************************************************************/
|
|
||||||
LatticeFermion check4(&UGrid);
|
|
||||||
gaussian(rng5, test5);
|
|
||||||
check5 = test5;
|
|
||||||
|
|
||||||
make_4D(test5, test4, Ls);
|
|
||||||
make_4D_with_gammas(check5, check4, Ls);
|
|
||||||
test4 -= check4;
|
|
||||||
std::cout << "5D -> 4D comparison, diff = " << Grid::sqrt(norm2(test4)) << std::endl;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Convert a propagator to a fermion & back.
|
|
||||||
**************************************************************************/
|
|
||||||
LatticeFermion ferm(&UGrid);
|
|
||||||
LatticePropagator prop(&UGrid), ref(&UGrid);
|
|
||||||
gaussian(rng4, prop);
|
|
||||||
|
|
||||||
// Define variables for sanity checking a single site.
|
|
||||||
typename SpinColourVector::scalar_object fermSite;
|
|
||||||
typename SpinColourMatrix::scalar_object propSite;
|
|
||||||
std::vector<int> site(Nd, 0);
|
|
||||||
|
|
||||||
for (int s = 0; s < Ns; ++s)
|
|
||||||
for (int c = 0; c < Nc; ++c)
|
|
||||||
{
|
|
||||||
ref = prop;
|
|
||||||
PropToFerm<WilsonImplR>(ferm, prop, s, c);
|
|
||||||
FermToProp<WilsonImplR>(prop, ferm, s, c);
|
|
||||||
|
|
||||||
std::cout << "Spin = " << s << ", Colour = " << c << std::endl;
|
|
||||||
ref -= prop;
|
|
||||||
std::cout << "Prop->Ferm->Prop test, diff = " << Grid::sqrt(norm2(ref)) << std::endl;
|
|
||||||
|
|
||||||
peekSite(fermSite, ferm, site);
|
|
||||||
peekSite(propSite, prop, site);
|
|
||||||
for (int s2 = 0; s2 < Ns; ++s2)
|
|
||||||
for (int c2 = 0; c2 < Nc; ++c2)
|
|
||||||
{
|
|
||||||
if (propSite()(s2, s)(c2, c) != fermSite()(s2)(c2))
|
|
||||||
{
|
|
||||||
std::cout << propSite()(s2, s)(c2, c) << " != "
|
|
||||||
<< fermSite()(s2)(c2) << " for spin = " << s2
|
|
||||||
<< ", col = " << c2 << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Grid_finalize();
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
@ -53,7 +53,7 @@ int main(int argc, char *argv[])
|
|||||||
globalPar.trajCounter.start = 1500;
|
globalPar.trajCounter.start = 1500;
|
||||||
globalPar.trajCounter.end = 1520;
|
globalPar.trajCounter.end = 1520;
|
||||||
globalPar.trajCounter.step = 20;
|
globalPar.trajCounter.step = 20;
|
||||||
globalPar.seed = "1 2 3 4";
|
globalPar.runId = "test";
|
||||||
application.setPar(globalPar);
|
application.setPar(globalPar);
|
||||||
// gauge field
|
// gauge field
|
||||||
application.createModule<MGauge::Unit>("gauge");
|
application.createModule<MGauge::Unit>("gauge");
|
||||||
|
@ -55,8 +55,7 @@ int main(int argc, char *argv[])
|
|||||||
globalPar.trajCounter.start = 309;
|
globalPar.trajCounter.start = 309;
|
||||||
globalPar.trajCounter.end = 310;
|
globalPar.trajCounter.end = 310;
|
||||||
globalPar.trajCounter.step = 1;
|
globalPar.trajCounter.step = 1;
|
||||||
|
globalPar.runId = "test";
|
||||||
globalPar.seed = "1 2 3 4";
|
|
||||||
|
|
||||||
application.setPar(globalPar);
|
application.setPar(globalPar);
|
||||||
// gauge field
|
// gauge field
|
||||||
|
Loading…
Reference in New Issue
Block a user