mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-09 23:45:36 +00:00
Merge branch 'develop' into feature/hmc_generalise
This commit is contained in:
commit
17629b8d9e
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@
|
|||||||
################
|
################
|
||||||
*~
|
*~
|
||||||
*#
|
*#
|
||||||
|
*.sublime-*
|
||||||
|
|
||||||
# Precompiled Headers #
|
# Precompiled Headers #
|
||||||
#######################
|
#######################
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# additional include paths necessary to compile the C++ library
|
# additional include paths necessary to compile the C++ library
|
||||||
SUBDIRS = lib benchmarks tests
|
SUBDIRS = lib benchmarks tests extras
|
||||||
|
|
||||||
include $(top_srcdir)/doxygen.inc
|
include $(top_srcdir)/doxygen.inc
|
||||||
|
|
||||||
|
@ -113,6 +113,36 @@ int main (int argc, char ** argv)
|
|||||||
std::cout<<GridLogMessage << "Called " #A " "<< (t1-t0)/ncall<<" us"<<std::endl;\
|
std::cout<<GridLogMessage << "Called " #A " "<< (t1-t0)/ncall<<" us"<<std::endl;\
|
||||||
std::cout<<GridLogMessage << "******************"<<std::endl;
|
std::cout<<GridLogMessage << "******************"<<std::endl;
|
||||||
|
|
||||||
|
#define BENCH_ZDW(A,in,out) \
|
||||||
|
zDw.CayleyZeroCounters(); \
|
||||||
|
zDw. A (in,out); \
|
||||||
|
FGrid->Barrier(); \
|
||||||
|
t0=usecond(); \
|
||||||
|
for(int i=0;i<ncall;i++){ \
|
||||||
|
zDw. A (in,out); \
|
||||||
|
} \
|
||||||
|
t1=usecond(); \
|
||||||
|
FGrid->Barrier(); \
|
||||||
|
zDw.CayleyReport(); \
|
||||||
|
std::cout<<GridLogMessage << "Called ZDw " #A " "<< (t1-t0)/ncall<<" us"<<std::endl;\
|
||||||
|
std::cout<<GridLogMessage << "******************"<<std::endl;
|
||||||
|
|
||||||
|
#define BENCH_DW_SSC(A,in,out) \
|
||||||
|
Dw.CayleyZeroCounters(); \
|
||||||
|
Dw. A (in,out); \
|
||||||
|
FGrid->Barrier(); \
|
||||||
|
t0=usecond(); \
|
||||||
|
for(int i=0;i<ncall;i++){ \
|
||||||
|
__SSC_START ; \
|
||||||
|
Dw. A (in,out); \
|
||||||
|
__SSC_STOP ; \
|
||||||
|
} \
|
||||||
|
t1=usecond(); \
|
||||||
|
FGrid->Barrier(); \
|
||||||
|
Dw.CayleyReport(); \
|
||||||
|
std::cout<<GridLogMessage << "Called " #A " "<< (t1-t0)/ncall<<" us"<<std::endl;\
|
||||||
|
std::cout<<GridLogMessage << "******************"<<std::endl;
|
||||||
|
|
||||||
#define BENCH_DW_MEO(A,in,out) \
|
#define BENCH_DW_MEO(A,in,out) \
|
||||||
Dw.CayleyZeroCounters(); \
|
Dw.CayleyZeroCounters(); \
|
||||||
Dw. A (in,out,0); \
|
Dw. A (in,out,0); \
|
||||||
@ -148,9 +178,15 @@ int main (int argc, char ** argv)
|
|||||||
LatticeFermion sref(sFGrid);
|
LatticeFermion sref(sFGrid);
|
||||||
LatticeFermion result(sFGrid);
|
LatticeFermion result(sFGrid);
|
||||||
|
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Constructing Vec5D Dw "<<std::endl;
|
std::cout<<GridLogMessage << "Constructing Vec5D Dw "<<std::endl;
|
||||||
DomainWallFermionVec5dR Dw(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,mass,M5);
|
DomainWallFermionVec5dR Dw(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,mass,M5);
|
||||||
|
|
||||||
|
RealD b=1.5;// Scale factor b+c=2, b-c=1
|
||||||
|
RealD c=0.5;
|
||||||
|
std::vector<ComplexD> gamma(Ls,std::complex<double>(1.0,0.0));
|
||||||
|
ZMobiusFermionVec5dR zDw(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,mass,M5,gamma,b,c);
|
||||||
|
|
||||||
std::cout<<GridLogMessage << "Calling Dhop "<<std::endl;
|
std::cout<<GridLogMessage << "Calling Dhop "<<std::endl;
|
||||||
FGrid->Barrier();
|
FGrid->Barrier();
|
||||||
|
|
||||||
@ -173,10 +209,13 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
BENCH_DW_MEO(Dhop ,src,result);
|
BENCH_DW_MEO(Dhop ,src,result);
|
||||||
BENCH_DW_MEO(DhopEO ,src_o,r_e);
|
BENCH_DW_MEO(DhopEO ,src_o,r_e);
|
||||||
BENCH_DW(Meooe ,src_o,r_e);
|
BENCH_DW_SSC(Meooe ,src_o,r_e);
|
||||||
BENCH_DW(Mooee ,src_o,r_o);
|
BENCH_DW(Mooee ,src_o,r_o);
|
||||||
BENCH_DW(MooeeInv,src_o,r_o);
|
BENCH_DW(MooeeInv,src_o,r_o);
|
||||||
|
|
||||||
|
BENCH_ZDW(Mooee ,src_o,r_o);
|
||||||
|
BENCH_ZDW(MooeeInv,src_o,r_o);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid_finalize();
|
Grid_finalize();
|
||||||
|
17
configure.ac
17
configure.ac
@ -102,6 +102,13 @@ case ${ac_MKL} in
|
|||||||
AC_DEFINE([USE_MKL], [1], [Define to 1 if you use the Intel MKL]);;
|
AC_DEFINE([USE_MKL], [1], [Define to 1 if you use the Intel MKL]);;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
############### HDF5
|
||||||
|
AC_ARG_WITH([hdf5],
|
||||||
|
[AS_HELP_STRING([--with-hdf5=prefix],
|
||||||
|
[try this for a non-standard install prefix of the HDF5 library])],
|
||||||
|
[AM_CXXFLAGS="-I$with_hdf5/include $AM_CXXFLAGS"]
|
||||||
|
[AM_LDFLAGS="-L$with_hdf5/lib $AM_LDFLAGS"])
|
||||||
|
|
||||||
############### first-touch
|
############### first-touch
|
||||||
AC_ARG_ENABLE([numa],
|
AC_ARG_ENABLE([numa],
|
||||||
[AC_HELP_STRING([--enable-numa=yes|no|prefix], [enable first touch numa opt])],
|
[AC_HELP_STRING([--enable-numa=yes|no|prefix], [enable first touch numa opt])],
|
||||||
@ -148,6 +155,12 @@ AC_SEARCH_LIBS([fftw_execute], [fftw3],
|
|||||||
[AC_DEFINE([HAVE_FFTW], [1], [Define to 1 if you have the `FFTW' library])]
|
[AC_DEFINE([HAVE_FFTW], [1], [Define to 1 if you have the `FFTW' library])]
|
||||||
[have_fftw=true])
|
[have_fftw=true])
|
||||||
|
|
||||||
|
AC_SEARCH_LIBS([H5Fopen], [hdf5_cpp],
|
||||||
|
[AC_DEFINE([HAVE_HDF5], [1], [Define to 1 if you have the `HDF5' library])]
|
||||||
|
[have_hdf5=true]
|
||||||
|
[LIBS="${LIBS} -lhdf5"], [], [-lhdf5])
|
||||||
|
AM_CONDITIONAL(BUILD_HDF5, [ test "${have_hdf5}X" == "trueX" ])
|
||||||
|
|
||||||
CXXFLAGS=$CXXFLAGS_CPY
|
CXXFLAGS=$CXXFLAGS_CPY
|
||||||
LDFLAGS=$LDFLAGS_CPY
|
LDFLAGS=$LDFLAGS_CPY
|
||||||
|
|
||||||
@ -393,10 +406,13 @@ AC_CONFIG_FILES(tests/IO/Makefile)
|
|||||||
AC_CONFIG_FILES(tests/core/Makefile)
|
AC_CONFIG_FILES(tests/core/Makefile)
|
||||||
AC_CONFIG_FILES(tests/debug/Makefile)
|
AC_CONFIG_FILES(tests/debug/Makefile)
|
||||||
AC_CONFIG_FILES(tests/forces/Makefile)
|
AC_CONFIG_FILES(tests/forces/Makefile)
|
||||||
|
AC_CONFIG_FILES(tests/hadrons/Makefile)
|
||||||
AC_CONFIG_FILES(tests/hmc/Makefile)
|
AC_CONFIG_FILES(tests/hmc/Makefile)
|
||||||
AC_CONFIG_FILES(tests/solver/Makefile)
|
AC_CONFIG_FILES(tests/solver/Makefile)
|
||||||
AC_CONFIG_FILES(tests/qdpxx/Makefile)
|
AC_CONFIG_FILES(tests/qdpxx/Makefile)
|
||||||
AC_CONFIG_FILES(benchmarks/Makefile)
|
AC_CONFIG_FILES(benchmarks/Makefile)
|
||||||
|
AC_CONFIG_FILES(extras/Makefile)
|
||||||
|
AC_CONFIG_FILES(extras/Hadrons/Makefile)
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
git_commit=`cd $srcdir && ./scripts/configure.commit`
|
git_commit=`cd $srcdir && ./scripts/configure.commit`
|
||||||
@ -425,6 +441,7 @@ GMP : `if test "x$have_gmp" = xtrue; then echo yes; else
|
|||||||
LAPACK : ${ac_LAPACK}
|
LAPACK : ${ac_LAPACK}
|
||||||
FFTW : `if test "x$have_fftw" = xtrue; then echo yes; else echo no; fi`
|
FFTW : `if test "x$have_fftw" = xtrue; then echo yes; else echo no; fi`
|
||||||
LIME (ILDG support) : `if test "x$have_lime" = xtrue; then echo yes; else echo no; fi`
|
LIME (ILDG support) : `if test "x$have_lime" = xtrue; then echo yes; else echo no; fi`
|
||||||
|
HDF5 : `if test "x$have_hdf5" = xtrue; then echo yes; else echo no; fi`
|
||||||
build DOXYGEN documentation : `if test "$DX_FLAG_doc" = '1'; then echo yes; else echo no; fi`
|
build DOXYGEN documentation : `if test "$DX_FLAG_doc" = '1'; then echo yes; else echo no; fi`
|
||||||
----- BUILD FLAGS -------------------------------------
|
----- BUILD FLAGS -------------------------------------
|
||||||
CXXFLAGS:
|
CXXFLAGS:
|
||||||
|
317
extras/Hadrons/Application.cc
Normal file
317
extras/Hadrons/Application.cc
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Application.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Application.hpp>
|
||||||
|
#include <Grid/Hadrons/GeneticScheduler.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace QCD;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
#define BIG_SEP "==============="
|
||||||
|
#define SEP "---------------"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Application implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructors ////////////////////////////////////////////////////////////////
|
||||||
|
Application::Application(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Modules available:" << std::endl;
|
||||||
|
auto list = ModuleFactory::getInstance().getBuilderList();
|
||||||
|
for (auto &m: list)
|
||||||
|
{
|
||||||
|
LOG(Message) << " " << m << std::endl;
|
||||||
|
}
|
||||||
|
auto dim = GridDefaultLatt(), mpi = GridDefaultMpi(), loc(dim);
|
||||||
|
locVol_ = 1;
|
||||||
|
for (unsigned int d = 0; d < dim.size(); ++d)
|
||||||
|
{
|
||||||
|
loc[d] /= mpi[d];
|
||||||
|
locVol_ *= loc[d];
|
||||||
|
}
|
||||||
|
LOG(Message) << "Global lattice: " << dim << std::endl;
|
||||||
|
LOG(Message) << "MPI partition : " << mpi << std::endl;
|
||||||
|
LOG(Message) << "Local lattice : " << loc << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Application::Application(const Application::GlobalPar &par)
|
||||||
|
: Application()
|
||||||
|
{
|
||||||
|
setPar(par);
|
||||||
|
}
|
||||||
|
|
||||||
|
Application::Application(const std::string parameterFileName)
|
||||||
|
: Application()
|
||||||
|
{
|
||||||
|
parameterFileName_ = parameterFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// environment shortcut ////////////////////////////////////////////////////////
|
||||||
|
Environment & Application::env(void) const
|
||||||
|
{
|
||||||
|
return Environment::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
|
void Application::setPar(const Application::GlobalPar &par)
|
||||||
|
{
|
||||||
|
par_ = par;
|
||||||
|
env().setSeed(strToVec<int>(par_.seed));
|
||||||
|
}
|
||||||
|
|
||||||
|
const Application::GlobalPar & Application::getPar(void)
|
||||||
|
{
|
||||||
|
return par_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute /////////////////////////////////////////////////////////////////////
|
||||||
|
void Application::run(void)
|
||||||
|
{
|
||||||
|
if (!parameterFileName_.empty() and (env().getNModule() == 0))
|
||||||
|
{
|
||||||
|
parseParameterFile(parameterFileName_);
|
||||||
|
}
|
||||||
|
if (!scheduled_)
|
||||||
|
{
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
printSchedule();
|
||||||
|
configLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse parameter file ////////////////////////////////////////////////////////
|
||||||
|
class ObjectId: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(ObjectId,
|
||||||
|
std::string, name,
|
||||||
|
std::string, type);
|
||||||
|
};
|
||||||
|
|
||||||
|
void Application::parseParameterFile(const std::string parameterFileName)
|
||||||
|
{
|
||||||
|
XmlReader reader(parameterFileName);
|
||||||
|
GlobalPar par;
|
||||||
|
ObjectId id;
|
||||||
|
|
||||||
|
LOG(Message) << "Building application from '" << parameterFileName << "'..." << std::endl;
|
||||||
|
read(reader, "parameters", par);
|
||||||
|
setPar(par);
|
||||||
|
push(reader, "modules");
|
||||||
|
push(reader, "module");
|
||||||
|
do
|
||||||
|
{
|
||||||
|
read(reader, "id", id);
|
||||||
|
env().createModule(id.name, id.type, reader);
|
||||||
|
} while (reader.nextElement("module"));
|
||||||
|
pop(reader);
|
||||||
|
pop(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::saveParameterFile(const std::string parameterFileName)
|
||||||
|
{
|
||||||
|
XmlWriter writer(parameterFileName);
|
||||||
|
ObjectId id;
|
||||||
|
const unsigned int nMod = env().getNModule();
|
||||||
|
|
||||||
|
LOG(Message) << "Saving application to '" << parameterFileName << "'..." << std::endl;
|
||||||
|
write(writer, "parameters", getPar());
|
||||||
|
push(writer, "modules");
|
||||||
|
for (unsigned int i = 0; i < nMod; ++i)
|
||||||
|
{
|
||||||
|
push(writer, "module");
|
||||||
|
id.name = env().getModuleName(i);
|
||||||
|
id.type = env().getModule(i)->getRegisteredName();
|
||||||
|
write(writer, "id", id);
|
||||||
|
env().getModule(i)->saveParameters(writer, "options");
|
||||||
|
pop(writer);
|
||||||
|
}
|
||||||
|
pop(writer);
|
||||||
|
pop(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// schedule computation ////////////////////////////////////////////////////////
|
||||||
|
#define MEM_MSG(size)\
|
||||||
|
sizeString((size)*locVol_) << " (" << sizeString(size) << "/site)"
|
||||||
|
|
||||||
|
#define DEFINE_MEMPEAK \
|
||||||
|
auto memPeak = [this](const std::vector<unsigned int> &program)\
|
||||||
|
{\
|
||||||
|
unsigned int memPeak;\
|
||||||
|
bool msg;\
|
||||||
|
\
|
||||||
|
msg = HadronsLogMessage.isActive();\
|
||||||
|
HadronsLogMessage.Active(false);\
|
||||||
|
env().dryRun(true);\
|
||||||
|
memPeak = env().executeProgram(program);\
|
||||||
|
env().dryRun(false);\
|
||||||
|
env().freeAll();\
|
||||||
|
HadronsLogMessage.Active(true);\
|
||||||
|
\
|
||||||
|
return memPeak;\
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::schedule(void)
|
||||||
|
{
|
||||||
|
DEFINE_MEMPEAK;
|
||||||
|
|
||||||
|
// build module dependency graph
|
||||||
|
LOG(Message) << "Building module graph..." << std::endl;
|
||||||
|
auto graph = env().makeModuleGraph();
|
||||||
|
auto con = graph.getConnectedComponents();
|
||||||
|
|
||||||
|
// constrained topological sort using a genetic algorithm
|
||||||
|
LOG(Message) << "Scheduling computation..." << std::endl;
|
||||||
|
LOG(Message) << " #module= " << graph.size() << std::endl;
|
||||||
|
LOG(Message) << " population size= " << par_.genetic.popSize << std::endl;
|
||||||
|
LOG(Message) << " max. generation= " << par_.genetic.maxGen << std::endl;
|
||||||
|
LOG(Message) << " max. cst. generation= " << par_.genetic.maxCstGen << std::endl;
|
||||||
|
LOG(Message) << " mutation rate= " << par_.genetic.mutationRate << std::endl;
|
||||||
|
|
||||||
|
unsigned int k = 0, gen, prevPeak, nCstPeak = 0;
|
||||||
|
std::random_device rd;
|
||||||
|
GeneticScheduler<unsigned int>::Parameters par;
|
||||||
|
|
||||||
|
par.popSize = par_.genetic.popSize;
|
||||||
|
par.mutationRate = par_.genetic.mutationRate;
|
||||||
|
par.seed = rd();
|
||||||
|
memPeak_ = 0;
|
||||||
|
CartesianCommunicator::BroadcastWorld(0, &(par.seed), sizeof(par.seed));
|
||||||
|
for (unsigned int i = 0; i < con.size(); ++i)
|
||||||
|
{
|
||||||
|
GeneticScheduler<unsigned int> scheduler(con[i], memPeak, par);
|
||||||
|
|
||||||
|
gen = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
LOG(Debug) << "Generation " << gen << ":" << std::endl;
|
||||||
|
scheduler.nextGeneration();
|
||||||
|
if (gen != 0)
|
||||||
|
{
|
||||||
|
if (prevPeak == scheduler.getMinValue())
|
||||||
|
{
|
||||||
|
nCstPeak++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nCstPeak = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prevPeak = scheduler.getMinValue();
|
||||||
|
if (gen % 10 == 0)
|
||||||
|
{
|
||||||
|
LOG(Iterative) << "Generation " << gen << ": "
|
||||||
|
<< MEM_MSG(scheduler.getMinValue()) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
gen++;
|
||||||
|
} while ((gen < par_.genetic.maxGen)
|
||||||
|
and (nCstPeak < par_.genetic.maxCstGen));
|
||||||
|
auto &t = scheduler.getMinSchedule();
|
||||||
|
if (scheduler.getMinValue() > memPeak_)
|
||||||
|
{
|
||||||
|
memPeak_ = scheduler.getMinValue();
|
||||||
|
}
|
||||||
|
for (unsigned int j = 0; j < t.size(); ++j)
|
||||||
|
{
|
||||||
|
program_.push_back(t[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scheduled_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::saveSchedule(const std::string filename)
|
||||||
|
{
|
||||||
|
TextWriter writer(filename);
|
||||||
|
std::vector<std::string> program;
|
||||||
|
|
||||||
|
if (!scheduled_)
|
||||||
|
{
|
||||||
|
HADRON_ERROR("Computation not scheduled");
|
||||||
|
}
|
||||||
|
LOG(Message) << "Saving current schedule to '" << filename << "'..."
|
||||||
|
<< std::endl;
|
||||||
|
for (auto address: program_)
|
||||||
|
{
|
||||||
|
program.push_back(env().getModuleName(address));
|
||||||
|
}
|
||||||
|
write(writer, "schedule", program);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::loadSchedule(const std::string filename)
|
||||||
|
{
|
||||||
|
DEFINE_MEMPEAK;
|
||||||
|
|
||||||
|
TextReader reader(filename);
|
||||||
|
std::vector<std::string> program;
|
||||||
|
|
||||||
|
LOG(Message) << "Loading schedule from '" << filename << "'..."
|
||||||
|
<< std::endl;
|
||||||
|
read(reader, "schedule", program);
|
||||||
|
program_.clear();
|
||||||
|
for (auto &name: program)
|
||||||
|
{
|
||||||
|
program_.push_back(env().getModuleAddress(name));
|
||||||
|
}
|
||||||
|
scheduled_ = true;
|
||||||
|
memPeak_ = memPeak(program_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::printSchedule(void)
|
||||||
|
{
|
||||||
|
if (!scheduled_)
|
||||||
|
{
|
||||||
|
HADRON_ERROR("Computation not scheduled");
|
||||||
|
}
|
||||||
|
LOG(Message) << "Schedule (memory peak: " << MEM_MSG(memPeak_) << "):"
|
||||||
|
<< std::endl;
|
||||||
|
for (unsigned int i = 0; i < program_.size(); ++i)
|
||||||
|
{
|
||||||
|
LOG(Message) << std::setw(4) << i + 1 << ": "
|
||||||
|
<< env().getModuleName(program_[i]) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop on configurations //////////////////////////////////////////////////////
|
||||||
|
void Application::configLoop(void)
|
||||||
|
{
|
||||||
|
auto range = par_.trajCounter;
|
||||||
|
|
||||||
|
for (unsigned int t = range.start; t < range.end; t += range.step)
|
||||||
|
{
|
||||||
|
LOG(Message) << BIG_SEP << " Starting measurement for trajectory " << t
|
||||||
|
<< " " << BIG_SEP << std::endl;
|
||||||
|
env().setTrajectory(t);
|
||||||
|
env().executeProgram(program_);
|
||||||
|
}
|
||||||
|
LOG(Message) << BIG_SEP << " End of measurement " << BIG_SEP << std::endl;
|
||||||
|
env().freeAll();
|
||||||
|
}
|
132
extras/Hadrons/Application.hpp
Normal file
132
extras/Hadrons/Application.hpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Application.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Application_hpp_
|
||||||
|
#define Hadrons_Application_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Environment.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Main program manager *
|
||||||
|
******************************************************************************/
|
||||||
|
class Application
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class TrajRange: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(TrajRange,
|
||||||
|
unsigned int, start,
|
||||||
|
unsigned int, end,
|
||||||
|
unsigned int, step);
|
||||||
|
};
|
||||||
|
class GeneticPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeneticPar(void):
|
||||||
|
popSize{20}, maxGen{1000}, maxCstGen{100}, mutationRate{.1} {};
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(GeneticPar,
|
||||||
|
unsigned int, popSize,
|
||||||
|
unsigned int, maxGen,
|
||||||
|
unsigned int, maxCstGen,
|
||||||
|
double , mutationRate);
|
||||||
|
};
|
||||||
|
class GlobalPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(GlobalPar,
|
||||||
|
TrajRange, trajCounter,
|
||||||
|
GeneticPar, genetic,
|
||||||
|
std::string, seed);
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructors
|
||||||
|
Application(void);
|
||||||
|
Application(const GlobalPar &par);
|
||||||
|
Application(const std::string parameterFileName);
|
||||||
|
// destructor
|
||||||
|
virtual ~Application(void) = default;
|
||||||
|
// access
|
||||||
|
void setPar(const GlobalPar &par);
|
||||||
|
const GlobalPar & getPar(void);
|
||||||
|
// module creation
|
||||||
|
template <typename M>
|
||||||
|
void createModule(const std::string name);
|
||||||
|
template <typename M>
|
||||||
|
void createModule(const std::string name, const typename M::Par &par);
|
||||||
|
// execute
|
||||||
|
void run(void);
|
||||||
|
// XML parameter file I/O
|
||||||
|
void parseParameterFile(const std::string parameterFileName);
|
||||||
|
void saveParameterFile(const std::string parameterFileName);
|
||||||
|
// schedule computation
|
||||||
|
void schedule(void);
|
||||||
|
void saveSchedule(const std::string filename);
|
||||||
|
void loadSchedule(const std::string filename);
|
||||||
|
void printSchedule(void);
|
||||||
|
// loop on configurations
|
||||||
|
void configLoop(void);
|
||||||
|
private:
|
||||||
|
// environment shortcut
|
||||||
|
Environment & env(void) const;
|
||||||
|
private:
|
||||||
|
long unsigned int locVol_;
|
||||||
|
std::string parameterFileName_{""};
|
||||||
|
GlobalPar par_;
|
||||||
|
std::vector<unsigned int> program_;
|
||||||
|
Environment::Size memPeak_;
|
||||||
|
bool scheduled_{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Application template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// module creation /////////////////////////////////////////////////////////////
|
||||||
|
template <typename M>
|
||||||
|
void Application::createModule(const std::string name)
|
||||||
|
{
|
||||||
|
env().createModule<M>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
void Application::createModule(const std::string name,
|
||||||
|
const typename M::Par &par)
|
||||||
|
{
|
||||||
|
env().createModule<M>(name, par);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Application_hpp_
|
743
extras/Hadrons/Environment.cc
Normal file
743
extras/Hadrons/Environment.cc
Normal file
@ -0,0 +1,743 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Environment.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Environment.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace QCD;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Environment implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
Environment::Environment(void)
|
||||||
|
{
|
||||||
|
nd_ = GridDefaultLatt().size();
|
||||||
|
grid4d_.reset(SpaceTimeGrid::makeFourDimGrid(
|
||||||
|
GridDefaultLatt(), GridDefaultSimd(nd_, vComplex::Nsimd()),
|
||||||
|
GridDefaultMpi()));
|
||||||
|
gridRb4d_.reset(SpaceTimeGrid::makeFourDimRedBlackGrid(grid4d_.get()));
|
||||||
|
auto loc = getGrid()->LocalDimensions();
|
||||||
|
locVol_ = 1;
|
||||||
|
for (unsigned int d = 0; d < loc.size(); ++d)
|
||||||
|
{
|
||||||
|
locVol_ *= loc[d];
|
||||||
|
}
|
||||||
|
rng4d_.reset(new GridParallelRNG(grid4d_.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// dry run /////////////////////////////////////////////////////////////////////
|
||||||
|
void Environment::dryRun(const bool isDry)
|
||||||
|
{
|
||||||
|
dryRun_ = isDry;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::isDryRun(void) const
|
||||||
|
{
|
||||||
|
return dryRun_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// trajectory number ///////////////////////////////////////////////////////////
|
||||||
|
void Environment::setTrajectory(const unsigned int traj)
|
||||||
|
{
|
||||||
|
traj_ = traj;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Environment::getTrajectory(void) const
|
||||||
|
{
|
||||||
|
return traj_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// grids ///////////////////////////////////////////////////////////////////////
|
||||||
|
void Environment::createGrid(const unsigned int Ls)
|
||||||
|
{
|
||||||
|
if (grid5d_.find(Ls) == grid5d_.end())
|
||||||
|
{
|
||||||
|
auto g = getGrid();
|
||||||
|
|
||||||
|
grid5d_[Ls].reset(SpaceTimeGrid::makeFiveDimGrid(Ls, g));
|
||||||
|
gridRb5d_[Ls].reset(SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, g));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 &)
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no grid with Ls= " << 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 &)
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no red-black 5D grid with Ls= " << Ls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Environment::getNd(void) const
|
||||||
|
{
|
||||||
|
return nd_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// random number generator /////////////////////////////////////////////////////
|
||||||
|
void Environment::setSeed(const std::vector<int> &seed)
|
||||||
|
{
|
||||||
|
rng4d_->SeedFixedIntegers(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
GridParallelRNG * Environment::get4dRng(void) const
|
||||||
|
{
|
||||||
|
return rng4d_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// module management ///////////////////////////////////////////////////////////
|
||||||
|
void Environment::pushModule(Environment::ModPt &pt)
|
||||||
|
{
|
||||||
|
std::string name = pt->getName();
|
||||||
|
|
||||||
|
if (!hasModule(name))
|
||||||
|
{
|
||||||
|
std::vector<unsigned int> inputAddress;
|
||||||
|
unsigned int address;
|
||||||
|
ModuleInfo m;
|
||||||
|
|
||||||
|
m.data = std::move(pt);
|
||||||
|
m.type = typeIdPt(*m.data.get());
|
||||||
|
m.name = name;
|
||||||
|
auto input = m.data->getInput();
|
||||||
|
for (auto &in: input)
|
||||||
|
{
|
||||||
|
if (!hasObject(in))
|
||||||
|
{
|
||||||
|
addObject(in , -1);
|
||||||
|
}
|
||||||
|
m.input.push_back(objectAddress_[in]);
|
||||||
|
}
|
||||||
|
auto output = m.data->getOutput();
|
||||||
|
module_.push_back(std::move(m));
|
||||||
|
address = static_cast<unsigned int>(module_.size() - 1);
|
||||||
|
moduleAddress_[name] = address;
|
||||||
|
for (auto &out: output)
|
||||||
|
{
|
||||||
|
if (!hasObject(out))
|
||||||
|
{
|
||||||
|
addObject(out, address);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (object_[objectAddress_[out]].module < 0)
|
||||||
|
{
|
||||||
|
object_[objectAddress_[out]].module = address;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object '" + out
|
||||||
|
+ "' is already produced by module '"
|
||||||
|
+ module_[object_[getObjectAddress(out)].module].name
|
||||||
|
+ "' (while pushing module '" + name + "')");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("module '" + name + "' already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Environment::getNModule(void) const
|
||||||
|
{
|
||||||
|
return module_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::createModule(const std::string name, const std::string type,
|
||||||
|
XmlReader &reader)
|
||||||
|
{
|
||||||
|
auto &factory = ModuleFactory::getInstance();
|
||||||
|
auto pt = factory.create(type, name);
|
||||||
|
|
||||||
|
pt->parseParameters(reader, "options");
|
||||||
|
pushModule(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleBase * Environment::getModule(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasModule(address))
|
||||||
|
{
|
||||||
|
return module_[address].data.get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no module with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleBase * Environment::getModule(const std::string name) const
|
||||||
|
{
|
||||||
|
return getModule(getModuleAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Environment::getModuleAddress(const std::string name) const
|
||||||
|
{
|
||||||
|
if (hasModule(name))
|
||||||
|
{
|
||||||
|
return moduleAddress_.at(name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no module with name '" + name + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Environment::getModuleName(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasModule(address))
|
||||||
|
{
|
||||||
|
return module_[address].name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no module with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Environment::getModuleType(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasModule(address))
|
||||||
|
{
|
||||||
|
return typeName(module_[address].type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no module with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Environment::getModuleType(const std::string name) const
|
||||||
|
{
|
||||||
|
return getModuleType(getModuleAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasModule(const unsigned int address) const
|
||||||
|
{
|
||||||
|
return (address < module_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasModule(const std::string name) const
|
||||||
|
{
|
||||||
|
return (moduleAddress_.find(name) != moduleAddress_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
Graph<unsigned int> Environment::makeModuleGraph(void) const
|
||||||
|
{
|
||||||
|
Graph<unsigned int> moduleGraph;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < module_.size(); ++i)
|
||||||
|
{
|
||||||
|
moduleGraph.addVertex(i);
|
||||||
|
for (auto &j: module_[i].input)
|
||||||
|
{
|
||||||
|
moduleGraph.addEdge(object_[j].module, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return moduleGraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BIG_SEP "==============="
|
||||||
|
#define SEP "---------------"
|
||||||
|
#define MEM_MSG(size)\
|
||||||
|
sizeString((size)*locVol_) << " (" << sizeString(size) << "/site)"
|
||||||
|
|
||||||
|
Environment::Size
|
||||||
|
Environment::executeProgram(const std::vector<unsigned int> &p)
|
||||||
|
{
|
||||||
|
Size memPeak = 0, sizeBefore, sizeAfter;
|
||||||
|
std::vector<std::set<unsigned int>> freeProg;
|
||||||
|
bool continueCollect, nothingFreed;
|
||||||
|
|
||||||
|
// build garbage collection schedule
|
||||||
|
freeProg.resize(p.size());
|
||||||
|
for (unsigned int i = 0; i < object_.size(); ++i)
|
||||||
|
{
|
||||||
|
auto pred = [i, this](const unsigned int j)
|
||||||
|
{
|
||||||
|
auto &in = module_[j].input;
|
||||||
|
auto it = std::find(in.begin(), in.end(), i);
|
||||||
|
|
||||||
|
return (it != in.end()) or (j == object_[i].module);
|
||||||
|
};
|
||||||
|
auto it = std::find_if(p.rbegin(), p.rend(), pred);
|
||||||
|
if (it != p.rend())
|
||||||
|
{
|
||||||
|
freeProg[p.rend() - it - 1].insert(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// program execution
|
||||||
|
for (unsigned int i = 0; i < p.size(); ++i)
|
||||||
|
{
|
||||||
|
// execute module
|
||||||
|
if (!isDryRun())
|
||||||
|
{
|
||||||
|
LOG(Message) << SEP << " Measurement step " << i+1 << "/"
|
||||||
|
<< p.size() << " (module '" << module_[p[i]].name
|
||||||
|
<< "') " << SEP << std::endl;
|
||||||
|
}
|
||||||
|
(*module_[p[i]].data)();
|
||||||
|
sizeBefore = getTotalSize();
|
||||||
|
// print used memory after execution
|
||||||
|
if (!isDryRun())
|
||||||
|
{
|
||||||
|
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeBefore)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
if (sizeBefore > memPeak)
|
||||||
|
{
|
||||||
|
memPeak = sizeBefore;
|
||||||
|
}
|
||||||
|
// garbage collection for step i
|
||||||
|
if (!isDryRun())
|
||||||
|
{
|
||||||
|
LOG(Message) << "Garbage collection..." << std::endl;
|
||||||
|
}
|
||||||
|
nothingFreed = true;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
continueCollect = false;
|
||||||
|
auto toFree = freeProg[i];
|
||||||
|
for (auto &j: toFree)
|
||||||
|
{
|
||||||
|
// continue garbage collection while there are still
|
||||||
|
// objects without owners
|
||||||
|
continueCollect = continueCollect or !hasOwners(j);
|
||||||
|
if(freeObject(j))
|
||||||
|
{
|
||||||
|
// if an object has been freed, remove it from
|
||||||
|
// the garbage collection schedule
|
||||||
|
freeProg[i].erase(j);
|
||||||
|
nothingFreed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (continueCollect);
|
||||||
|
// any remaining objects in step i garbage collection schedule
|
||||||
|
// is scheduled for step i + 1
|
||||||
|
if (i + 1 < p.size())
|
||||||
|
{
|
||||||
|
for (auto &j: freeProg[i])
|
||||||
|
{
|
||||||
|
freeProg[i + 1].insert(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// print used memory after garbage collection if necessary
|
||||||
|
if (!isDryRun())
|
||||||
|
{
|
||||||
|
sizeAfter = getTotalSize();
|
||||||
|
if (sizeBefore != sizeAfter)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Allocated objects: " << MEM_MSG(sizeAfter)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(Message) << "Nothing to free" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return memPeak;
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::Size Environment::executeProgram(const std::vector<std::string> &p)
|
||||||
|
{
|
||||||
|
std::vector<unsigned int> pAddress;
|
||||||
|
|
||||||
|
for (auto &n: p)
|
||||||
|
{
|
||||||
|
pAddress.push_back(getModuleAddress(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
return executeProgram(pAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
// general memory management ///////////////////////////////////////////////////
|
||||||
|
void Environment::addObject(const std::string name, const int moduleAddress)
|
||||||
|
{
|
||||||
|
if (!hasObject(name))
|
||||||
|
{
|
||||||
|
ObjInfo info;
|
||||||
|
|
||||||
|
info.name = name;
|
||||||
|
info.module = moduleAddress;
|
||||||
|
object_.push_back(std::move(info));
|
||||||
|
objectAddress_[name] = static_cast<unsigned int>(object_.size() - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object '" + name + "' already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::registerObject(const unsigned int address,
|
||||||
|
const unsigned int size, const unsigned int Ls)
|
||||||
|
{
|
||||||
|
if (!hasRegisteredObject(address))
|
||||||
|
{
|
||||||
|
if (hasObject(address))
|
||||||
|
{
|
||||||
|
object_[address].size = size;
|
||||||
|
object_[address].Ls = Ls;
|
||||||
|
object_[address].isRegistered = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object with address " + std::to_string(address)
|
||||||
|
+ " already registered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::registerObject(const std::string name,
|
||||||
|
const unsigned int size, const unsigned int Ls)
|
||||||
|
{
|
||||||
|
if (!hasObject(name))
|
||||||
|
{
|
||||||
|
addObject(name);
|
||||||
|
}
|
||||||
|
registerObject(getObjectAddress(name), size, Ls);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Environment::getObjectAddress(const std::string name) const
|
||||||
|
{
|
||||||
|
if (hasObject(name))
|
||||||
|
{
|
||||||
|
return objectAddress_.at(name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with name '" + name + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Environment::getObjectName(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasObject(address))
|
||||||
|
{
|
||||||
|
return object_[address].name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Environment::getObjectType(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasRegisteredObject(address))
|
||||||
|
{
|
||||||
|
return typeName(object_[address].type);
|
||||||
|
}
|
||||||
|
else if (hasObject(address))
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object with address " + std::to_string(address)
|
||||||
|
+ " exists but is not registered");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Environment::getObjectType(const std::string name) const
|
||||||
|
{
|
||||||
|
return getObjectType(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::Size Environment::getObjectSize(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasRegisteredObject(address))
|
||||||
|
{
|
||||||
|
return object_[address].size;
|
||||||
|
}
|
||||||
|
else if (hasObject(address))
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object with address " + std::to_string(address)
|
||||||
|
+ " exists but is not registered");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::Size Environment::getObjectSize(const std::string name) const
|
||||||
|
{
|
||||||
|
return getObjectSize(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Environment::getObjectLs(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasRegisteredObject(address))
|
||||||
|
{
|
||||||
|
return object_[address].Ls;
|
||||||
|
}
|
||||||
|
else if (hasObject(address))
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object with address " + std::to_string(address)
|
||||||
|
+ " exists but is not registered");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Environment::getObjectLs(const std::string name) const
|
||||||
|
{
|
||||||
|
return getObjectLs(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasObject(const unsigned int address) const
|
||||||
|
{
|
||||||
|
return (address < object_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasObject(const std::string name) const
|
||||||
|
{
|
||||||
|
auto it = objectAddress_.find(name);
|
||||||
|
|
||||||
|
return ((it != objectAddress_.end()) and hasObject(it->second));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasRegisteredObject(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasObject(address))
|
||||||
|
{
|
||||||
|
return object_[address].isRegistered;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasRegisteredObject(const std::string name) const
|
||||||
|
{
|
||||||
|
if (hasObject(name))
|
||||||
|
{
|
||||||
|
return hasRegisteredObject(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasCreatedObject(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasObject(address))
|
||||||
|
{
|
||||||
|
return (object_[address].data != nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasCreatedObject(const std::string name) const
|
||||||
|
{
|
||||||
|
if (hasObject(name))
|
||||||
|
{
|
||||||
|
return hasCreatedObject(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::isObject5d(const unsigned int address) const
|
||||||
|
{
|
||||||
|
return (getObjectLs(address) > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::isObject5d(const std::string name) const
|
||||||
|
{
|
||||||
|
return (getObjectLs(name) > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::Size Environment::getTotalSize(void) const
|
||||||
|
{
|
||||||
|
Environment::Size size = 0;
|
||||||
|
|
||||||
|
for (auto &o: object_)
|
||||||
|
{
|
||||||
|
if (o.isRegistered)
|
||||||
|
{
|
||||||
|
size += o.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::addOwnership(const unsigned int owner,
|
||||||
|
const unsigned int property)
|
||||||
|
{
|
||||||
|
if (hasObject(property))
|
||||||
|
{
|
||||||
|
object_[property].owners.insert(owner);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(property));
|
||||||
|
}
|
||||||
|
if (hasObject(owner))
|
||||||
|
{
|
||||||
|
object_[owner].properties.insert(property);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(owner));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::addOwnership(const std::string owner,
|
||||||
|
const std::string property)
|
||||||
|
{
|
||||||
|
addOwnership(getObjectAddress(owner), getObjectAddress(property));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasOwners(const unsigned int address) const
|
||||||
|
{
|
||||||
|
|
||||||
|
if (hasObject(address))
|
||||||
|
{
|
||||||
|
return (!object_[address].owners.empty());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::hasOwners(const std::string name) const
|
||||||
|
{
|
||||||
|
return hasOwners(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::freeObject(const unsigned int address)
|
||||||
|
{
|
||||||
|
if (!hasOwners(address))
|
||||||
|
{
|
||||||
|
if (!isDryRun() and object_[address].isRegistered)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Destroying object '" << object_[address].name
|
||||||
|
<< "'" << std::endl;
|
||||||
|
}
|
||||||
|
for (auto &p: object_[address].properties)
|
||||||
|
{
|
||||||
|
object_[p].owners.erase(address);
|
||||||
|
}
|
||||||
|
object_[address].size = 0;
|
||||||
|
object_[address].Ls = 0;
|
||||||
|
object_[address].isRegistered = false;
|
||||||
|
object_[address].type = nullptr;
|
||||||
|
object_[address].owners.clear();
|
||||||
|
object_[address].properties.clear();
|
||||||
|
object_[address].data.reset(nullptr);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Environment::freeObject(const std::string name)
|
||||||
|
{
|
||||||
|
return freeObject(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::freeAll(void)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < object_.size(); ++i)
|
||||||
|
{
|
||||||
|
freeObject(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::printContent(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Modules: " << std::endl;
|
||||||
|
for (unsigned int i = 0; i < module_.size(); ++i)
|
||||||
|
{
|
||||||
|
LOG(Message) << std::setw(4) << i << ": "
|
||||||
|
<< getModuleName(i) << std::endl;
|
||||||
|
}
|
||||||
|
LOG(Message) << "Objects: " << std::endl;
|
||||||
|
for (unsigned int i = 0; i < object_.size(); ++i)
|
||||||
|
{
|
||||||
|
LOG(Message) << std::setw(4) << i << ": "
|
||||||
|
<< getObjectName(i) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
385
extras/Hadrons/Environment.hpp
Normal file
385
extras/Hadrons/Environment.hpp
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Environment.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Environment_hpp_
|
||||||
|
#define Hadrons_Environment_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Graph.hpp>
|
||||||
|
|
||||||
|
#ifndef SITE_SIZE_TYPE
|
||||||
|
#define SITE_SIZE_TYPE unsigned int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Global environment *
|
||||||
|
******************************************************************************/
|
||||||
|
// forward declaration of Module
|
||||||
|
class ModuleBase;
|
||||||
|
|
||||||
|
class Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Object(void) = default;
|
||||||
|
virtual ~Object(void) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Holder: public Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Holder(void) = default;
|
||||||
|
Holder(T *pt);
|
||||||
|
virtual ~Holder(void) = default;
|
||||||
|
T & get(void) const;
|
||||||
|
T * getPt(void) const;
|
||||||
|
void reset(T *pt);
|
||||||
|
private:
|
||||||
|
std::unique_ptr<T> objPt_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Environment
|
||||||
|
{
|
||||||
|
SINGLETON(Environment);
|
||||||
|
public:
|
||||||
|
typedef SITE_SIZE_TYPE Size;
|
||||||
|
typedef std::unique_ptr<ModuleBase> ModPt;
|
||||||
|
typedef std::unique_ptr<GridCartesian> GridPt;
|
||||||
|
typedef std::unique_ptr<GridRedBlackCartesian> GridRbPt;
|
||||||
|
typedef std::unique_ptr<GridParallelRNG> RngPt;
|
||||||
|
typedef std::unique_ptr<LatticeBase> LatticePt;
|
||||||
|
private:
|
||||||
|
struct ModuleInfo
|
||||||
|
{
|
||||||
|
const std::type_info *type{nullptr};
|
||||||
|
std::string name;
|
||||||
|
ModPt data{nullptr};
|
||||||
|
std::vector<unsigned int> input;
|
||||||
|
};
|
||||||
|
struct ObjInfo
|
||||||
|
{
|
||||||
|
Size size{0};
|
||||||
|
unsigned int Ls{0};
|
||||||
|
bool isRegistered{false};
|
||||||
|
const std::type_info *type{nullptr};
|
||||||
|
std::string name;
|
||||||
|
int module{-1};
|
||||||
|
std::set<unsigned int> owners, properties;
|
||||||
|
std::unique_ptr<Object> data{nullptr};
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// dry run
|
||||||
|
void dryRun(const bool isDry);
|
||||||
|
bool isDryRun(void) const;
|
||||||
|
// trajectory number
|
||||||
|
void setTrajectory(const unsigned int traj);
|
||||||
|
unsigned int getTrajectory(void) const;
|
||||||
|
// grids
|
||||||
|
void createGrid(const unsigned int Ls);
|
||||||
|
GridCartesian * getGrid(const unsigned int Ls = 1) const;
|
||||||
|
GridRedBlackCartesian * getRbGrid(const unsigned int Ls = 1) const;
|
||||||
|
unsigned int getNd(void) const;
|
||||||
|
// random number generator
|
||||||
|
void setSeed(const std::vector<int> &seed);
|
||||||
|
GridParallelRNG * get4dRng(void) const;
|
||||||
|
// module management
|
||||||
|
void pushModule(ModPt &pt);
|
||||||
|
template <typename M>
|
||||||
|
void createModule(const std::string name);
|
||||||
|
template <typename M>
|
||||||
|
void createModule(const std::string name,
|
||||||
|
const typename M::Par &par);
|
||||||
|
void createModule(const std::string name,
|
||||||
|
const std::string type,
|
||||||
|
XmlReader &reader);
|
||||||
|
unsigned int getNModule(void) const;
|
||||||
|
ModuleBase * getModule(const unsigned int address) const;
|
||||||
|
ModuleBase * getModule(const std::string name) const;
|
||||||
|
template <typename M>
|
||||||
|
M * getModule(const unsigned int address) const;
|
||||||
|
template <typename M>
|
||||||
|
M * getModule(const std::string name) const;
|
||||||
|
unsigned int getModuleAddress(const std::string name) const;
|
||||||
|
std::string getModuleName(const unsigned int address) const;
|
||||||
|
std::string getModuleType(const unsigned int address) const;
|
||||||
|
std::string getModuleType(const std::string name) const;
|
||||||
|
bool hasModule(const unsigned int address) const;
|
||||||
|
bool hasModule(const std::string name) const;
|
||||||
|
Graph<unsigned int> makeModuleGraph(void) const;
|
||||||
|
Size executeProgram(const std::vector<unsigned int> &p);
|
||||||
|
Size executeProgram(const std::vector<std::string> &p);
|
||||||
|
// general memory management
|
||||||
|
void addObject(const std::string name,
|
||||||
|
const int moduleAddress = -1);
|
||||||
|
void registerObject(const unsigned int address,
|
||||||
|
const unsigned int size,
|
||||||
|
const unsigned int Ls = 1);
|
||||||
|
void registerObject(const std::string name,
|
||||||
|
const unsigned int size,
|
||||||
|
const unsigned int Ls = 1);
|
||||||
|
template <typename T>
|
||||||
|
unsigned int lattice4dSize(void) const;
|
||||||
|
template <typename T>
|
||||||
|
void registerLattice(const unsigned int address,
|
||||||
|
const unsigned int Ls = 1);
|
||||||
|
template <typename T>
|
||||||
|
void registerLattice(const std::string name,
|
||||||
|
const unsigned int Ls = 1);
|
||||||
|
template <typename T>
|
||||||
|
void setObject(const unsigned int address, T *object);
|
||||||
|
template <typename T>
|
||||||
|
void setObject(const std::string name, T *object);
|
||||||
|
template <typename T>
|
||||||
|
T * getObject(const unsigned int address) const;
|
||||||
|
template <typename T>
|
||||||
|
T * getObject(const std::string name) const;
|
||||||
|
template <typename T>
|
||||||
|
T * createLattice(const unsigned int address);
|
||||||
|
template <typename T>
|
||||||
|
T * createLattice(const std::string name);
|
||||||
|
unsigned int getObjectAddress(const std::string name) const;
|
||||||
|
std::string getObjectName(const unsigned int address) const;
|
||||||
|
std::string getObjectType(const unsigned int address) const;
|
||||||
|
std::string getObjectType(const std::string name) const;
|
||||||
|
Size getObjectSize(const unsigned int address) const;
|
||||||
|
Size getObjectSize(const std::string name) const;
|
||||||
|
unsigned int getObjectLs(const unsigned int address) const;
|
||||||
|
unsigned int getObjectLs(const std::string name) const;
|
||||||
|
bool hasObject(const unsigned int address) const;
|
||||||
|
bool hasObject(const std::string name) const;
|
||||||
|
bool hasRegisteredObject(const unsigned int address) const;
|
||||||
|
bool hasRegisteredObject(const std::string name) const;
|
||||||
|
bool hasCreatedObject(const unsigned int address) const;
|
||||||
|
bool hasCreatedObject(const std::string name) const;
|
||||||
|
bool isObject5d(const unsigned int address) const;
|
||||||
|
bool isObject5d(const std::string name) const;
|
||||||
|
Environment::Size getTotalSize(void) const;
|
||||||
|
void addOwnership(const unsigned int owner,
|
||||||
|
const unsigned int property);
|
||||||
|
void addOwnership(const std::string owner,
|
||||||
|
const std::string property);
|
||||||
|
bool hasOwners(const unsigned int address) const;
|
||||||
|
bool hasOwners(const std::string name) const;
|
||||||
|
bool freeObject(const unsigned int address);
|
||||||
|
bool freeObject(const std::string name);
|
||||||
|
void freeAll(void);
|
||||||
|
void printContent(void);
|
||||||
|
private:
|
||||||
|
// general
|
||||||
|
bool dryRun_{false};
|
||||||
|
unsigned int traj_, locVol_;
|
||||||
|
// grids
|
||||||
|
GridPt grid4d_;
|
||||||
|
std::map<unsigned int, GridPt> grid5d_;
|
||||||
|
GridRbPt gridRb4d_;
|
||||||
|
std::map<unsigned int, GridRbPt> gridRb5d_;
|
||||||
|
unsigned int nd_;
|
||||||
|
// random number generator
|
||||||
|
RngPt rng4d_;
|
||||||
|
// module and related maps
|
||||||
|
std::vector<ModuleInfo> module_;
|
||||||
|
std::map<std::string, unsigned int> moduleAddress_;
|
||||||
|
// lattice store
|
||||||
|
std::map<unsigned int, LatticePt> lattice_;
|
||||||
|
// object store
|
||||||
|
std::vector<ObjInfo> object_;
|
||||||
|
std::map<std::string, unsigned int> objectAddress_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Holder template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
Holder<T>::Holder(T *pt)
|
||||||
|
: objPt_(pt)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
T & Holder<T>::get(void) const
|
||||||
|
{
|
||||||
|
return &objPt_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T * Holder<T>::getPt(void) const
|
||||||
|
{
|
||||||
|
return objPt_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Holder<T>::reset(T *pt)
|
||||||
|
{
|
||||||
|
objPt_.reset(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Environment template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// module management ///////////////////////////////////////////////////////////
|
||||||
|
template <typename M>
|
||||||
|
void Environment::createModule(const std::string name)
|
||||||
|
{
|
||||||
|
ModPt pt(new M(name));
|
||||||
|
|
||||||
|
pushModule(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
void Environment::createModule(const std::string name,
|
||||||
|
const typename M::Par &par)
|
||||||
|
{
|
||||||
|
ModPt pt(new M(name));
|
||||||
|
|
||||||
|
static_cast<M *>(pt.get())->setPar(par);
|
||||||
|
pushModule(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
M * Environment::getModule(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (auto *pt = dynamic_cast<M *>(getModule(address)))
|
||||||
|
{
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("module '" + module_[address].name
|
||||||
|
+ "' does not have type " + typeid(M).name()
|
||||||
|
+ "(object type: " + getModuleType(address) + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename M>
|
||||||
|
M * Environment::getModule(const std::string name) const
|
||||||
|
{
|
||||||
|
return getModule<M>(getModuleAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
unsigned int Environment::lattice4dSize(void) const
|
||||||
|
{
|
||||||
|
return sizeof(typename T::vector_object)/getGrid()->Nsimd();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Environment::registerLattice(const unsigned int address,
|
||||||
|
const unsigned int Ls)
|
||||||
|
{
|
||||||
|
createGrid(Ls);
|
||||||
|
registerObject(address, Ls*lattice4dSize<T>(), Ls);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Environment::registerLattice(const std::string name, const unsigned int Ls)
|
||||||
|
{
|
||||||
|
createGrid(Ls);
|
||||||
|
registerObject(name, Ls*lattice4dSize<T>(), Ls);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Environment::setObject(const unsigned int address, T *object)
|
||||||
|
{
|
||||||
|
if (hasRegisteredObject(address))
|
||||||
|
{
|
||||||
|
object_[address].data.reset(new Holder<T>(object));
|
||||||
|
object_[address].type = &typeid(T);
|
||||||
|
}
|
||||||
|
else if (hasObject(address))
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object with address " + std::to_string(address) +
|
||||||
|
" exists but is not registered");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Environment::setObject(const std::string name, T *object)
|
||||||
|
{
|
||||||
|
setObject(getObjectAddress(name), object);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T * Environment::getObject(const unsigned int address) const
|
||||||
|
{
|
||||||
|
if (hasRegisteredObject(address))
|
||||||
|
{
|
||||||
|
if (auto h = dynamic_cast<Holder<T> *>(object_[address].data.get()))
|
||||||
|
{
|
||||||
|
return h->getPt();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object with address " + std::to_string(address) +
|
||||||
|
" does not have type '" + typeid(T).name() +
|
||||||
|
"' (has type '" + getObjectType(address) + "')");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (hasObject(address))
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object with address " + std::to_string(address) +
|
||||||
|
" exists but is not registered");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("no object with address " + std::to_string(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T * Environment::getObject(const std::string name) const
|
||||||
|
{
|
||||||
|
return getObject<T>(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T * Environment::createLattice(const unsigned int address)
|
||||||
|
{
|
||||||
|
GridCartesian *g = getGrid(getObjectLs(address));
|
||||||
|
|
||||||
|
setObject(address, new T(g));
|
||||||
|
|
||||||
|
return getObject<T>(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T * Environment::createLattice(const std::string name)
|
||||||
|
{
|
||||||
|
return createLattice<T>(getObjectAddress(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Environment_hpp_
|
106
extras/Hadrons/Factory.hpp
Normal file
106
extras/Hadrons/Factory.hpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Factory.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Factory_hpp_
|
||||||
|
#define Hadrons_Factory_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* abstract factory class *
|
||||||
|
******************************************************************************/
|
||||||
|
template <typename T>
|
||||||
|
class Factory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::function<std::unique_ptr<T>(const std::string)> Func;
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
Factory(void) = default;
|
||||||
|
// destructor
|
||||||
|
virtual ~Factory(void) = default;
|
||||||
|
// registration
|
||||||
|
void registerBuilder(const std::string type, const Func &f);
|
||||||
|
// get builder list
|
||||||
|
std::vector<std::string> getBuilderList(void) const;
|
||||||
|
// factory
|
||||||
|
std::unique_ptr<T> create(const std::string type,
|
||||||
|
const std::string name) const;
|
||||||
|
private:
|
||||||
|
std::map<std::string, Func> builder_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// registration ////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
void Factory<T>::registerBuilder(const std::string type, const Func &f)
|
||||||
|
{
|
||||||
|
builder_[type] = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get module list /////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
std::vector<std::string> Factory<T>::getBuilderList(void) const
|
||||||
|
{
|
||||||
|
std::vector<std::string> list;
|
||||||
|
|
||||||
|
for (auto &b: builder_)
|
||||||
|
{
|
||||||
|
list.push_back(b.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// factory /////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
std::unique_ptr<T> Factory<T>::create(const std::string type,
|
||||||
|
const std::string name) const
|
||||||
|
{
|
||||||
|
Func func;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
func = builder_.at(type);
|
||||||
|
}
|
||||||
|
catch (std::out_of_range &)
|
||||||
|
{
|
||||||
|
HADRON_ERROR("object of type '" + type + "' unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Factory_hpp_
|
329
extras/Hadrons/GeneticScheduler.hpp
Normal file
329
extras/Hadrons/GeneticScheduler.hpp
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/GeneticScheduler.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_GeneticScheduler_hpp_
|
||||||
|
#define Hadrons_GeneticScheduler_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Graph.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Scheduler based on a genetic algorithm *
|
||||||
|
******************************************************************************/
|
||||||
|
template <typename T>
|
||||||
|
class GeneticScheduler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<T> Gene;
|
||||||
|
typedef std::pair<Gene *, Gene *> GenePair;
|
||||||
|
typedef std::function<int(const Gene &)> ObjFunc;
|
||||||
|
struct Parameters
|
||||||
|
{
|
||||||
|
double mutationRate;
|
||||||
|
unsigned int popSize, seed;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
GeneticScheduler(Graph<T> &graph, const ObjFunc &func,
|
||||||
|
const Parameters &par);
|
||||||
|
// destructor
|
||||||
|
virtual ~GeneticScheduler(void) = default;
|
||||||
|
// access
|
||||||
|
const Gene & getMinSchedule(void);
|
||||||
|
int getMinValue(void);
|
||||||
|
// breed a new generation
|
||||||
|
void nextGeneration(void);
|
||||||
|
// heuristic benchmarks
|
||||||
|
void benchmarkCrossover(const unsigned int nIt);
|
||||||
|
// print population
|
||||||
|
friend std::ostream & operator<<(std::ostream &out,
|
||||||
|
const GeneticScheduler<T> &s)
|
||||||
|
{
|
||||||
|
out << "[";
|
||||||
|
for (auto &p: s.population_)
|
||||||
|
{
|
||||||
|
out << p.first << ", ";
|
||||||
|
}
|
||||||
|
out << "\b\b]";
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
// evolution steps
|
||||||
|
void initPopulation(void);
|
||||||
|
void doCrossover(void);
|
||||||
|
void doMutation(void);
|
||||||
|
// genetic operators
|
||||||
|
GenePair selectPair(void);
|
||||||
|
void crossover(Gene &c1, Gene &c2, const Gene &p1, const Gene &p2);
|
||||||
|
void mutation(Gene &m, const Gene &c);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Graph<T> &graph_;
|
||||||
|
const ObjFunc &func_;
|
||||||
|
const Parameters par_;
|
||||||
|
std::multimap<int, Gene> population_;
|
||||||
|
std::mt19937 gen_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
GeneticScheduler<T>::GeneticScheduler(Graph<T> &graph, const ObjFunc &func,
|
||||||
|
const Parameters &par)
|
||||||
|
: graph_(graph)
|
||||||
|
, func_(func)
|
||||||
|
, par_(par)
|
||||||
|
{
|
||||||
|
gen_.seed(par_.seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
const typename GeneticScheduler<T>::Gene &
|
||||||
|
GeneticScheduler<T>::getMinSchedule(void)
|
||||||
|
{
|
||||||
|
return population_.begin()->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int GeneticScheduler<T>::getMinValue(void)
|
||||||
|
{
|
||||||
|
return population_.begin()->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
// breed a new generation //////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
void GeneticScheduler<T>::nextGeneration(void)
|
||||||
|
{
|
||||||
|
// random initialization of the population if necessary
|
||||||
|
if (population_.size() != par_.popSize)
|
||||||
|
{
|
||||||
|
initPopulation();
|
||||||
|
}
|
||||||
|
LOG(Debug) << "Starting population:\n" << *this << std::endl;
|
||||||
|
|
||||||
|
// random mutations
|
||||||
|
//PARALLEL_FOR_LOOP
|
||||||
|
for (unsigned int i = 0; i < par_.popSize; ++i)
|
||||||
|
{
|
||||||
|
doMutation();
|
||||||
|
}
|
||||||
|
LOG(Debug) << "After mutations:\n" << *this << std::endl;
|
||||||
|
|
||||||
|
// mating
|
||||||
|
//PARALLEL_FOR_LOOP
|
||||||
|
for (unsigned int i = 0; i < par_.popSize/2; ++i)
|
||||||
|
{
|
||||||
|
doCrossover();
|
||||||
|
}
|
||||||
|
LOG(Debug) << "After mating:\n" << *this << std::endl;
|
||||||
|
|
||||||
|
// grim reaper
|
||||||
|
auto it = population_.begin();
|
||||||
|
|
||||||
|
std::advance(it, par_.popSize);
|
||||||
|
population_.erase(it, population_.end());
|
||||||
|
LOG(Debug) << "After grim reaper:\n" << *this << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// evolution steps /////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
void GeneticScheduler<T>::initPopulation(void)
|
||||||
|
{
|
||||||
|
population_.clear();
|
||||||
|
for (unsigned int i = 0; i < par_.popSize; ++i)
|
||||||
|
{
|
||||||
|
auto p = graph_.topoSort(gen_);
|
||||||
|
|
||||||
|
population_.insert(std::make_pair(func_(p), p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void GeneticScheduler<T>::doCrossover(void)
|
||||||
|
{
|
||||||
|
auto p = selectPair();
|
||||||
|
Gene &p1 = *(p.first), &p2 = *(p.second);
|
||||||
|
Gene c1, c2;
|
||||||
|
|
||||||
|
crossover(c1, c2, p1, p2);
|
||||||
|
PARALLEL_CRITICAL
|
||||||
|
{
|
||||||
|
population_.insert(std::make_pair(func_(c1), c1));
|
||||||
|
population_.insert(std::make_pair(func_(c2), c2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void GeneticScheduler<T>::doMutation(void)
|
||||||
|
{
|
||||||
|
std::uniform_real_distribution<double> mdis(0., 1.);
|
||||||
|
std::uniform_int_distribution<unsigned int> pdis(0, population_.size() - 1);
|
||||||
|
|
||||||
|
if (mdis(gen_) < par_.mutationRate)
|
||||||
|
{
|
||||||
|
Gene m;
|
||||||
|
auto it = population_.begin();
|
||||||
|
|
||||||
|
std::advance(it, pdis(gen_));
|
||||||
|
mutation(m, it->second);
|
||||||
|
PARALLEL_CRITICAL
|
||||||
|
{
|
||||||
|
population_.insert(std::make_pair(func_(m), m));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// genetic operators ///////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
typename GeneticScheduler<T>::GenePair GeneticScheduler<T>::selectPair(void)
|
||||||
|
{
|
||||||
|
std::vector<double> prob;
|
||||||
|
unsigned int ind;
|
||||||
|
Gene *p1, *p2;
|
||||||
|
|
||||||
|
for (auto &c: population_)
|
||||||
|
{
|
||||||
|
prob.push_back(1./c.first);
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
double probCpy;
|
||||||
|
|
||||||
|
std::discrete_distribution<unsigned int> dis1(prob.begin(), prob.end());
|
||||||
|
auto rIt = population_.begin();
|
||||||
|
ind = dis1(gen_);
|
||||||
|
std::advance(rIt, ind);
|
||||||
|
p1 = &(rIt->second);
|
||||||
|
probCpy = prob[ind];
|
||||||
|
prob[ind] = 0.;
|
||||||
|
std::discrete_distribution<unsigned int> dis2(prob.begin(), prob.end());
|
||||||
|
rIt = population_.begin();
|
||||||
|
std::advance(rIt, dis2(gen_));
|
||||||
|
p2 = &(rIt->second);
|
||||||
|
prob[ind] = probCpy;
|
||||||
|
} while (p1 == p2);
|
||||||
|
|
||||||
|
return std::make_pair(p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void GeneticScheduler<T>::crossover(Gene &c1, Gene &c2, const Gene &p1,
|
||||||
|
const Gene &p2)
|
||||||
|
{
|
||||||
|
Gene buf;
|
||||||
|
std::uniform_int_distribution<unsigned int> dis(0, p1.size() - 1);
|
||||||
|
unsigned int cut = dis(gen_);
|
||||||
|
|
||||||
|
c1.clear();
|
||||||
|
buf = p2;
|
||||||
|
for (unsigned int i = 0; i < cut; ++i)
|
||||||
|
{
|
||||||
|
c1.push_back(p1[i]);
|
||||||
|
buf.erase(std::find(buf.begin(), buf.end(), p1[i]));
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < buf.size(); ++i)
|
||||||
|
{
|
||||||
|
c1.push_back(buf[i]);
|
||||||
|
}
|
||||||
|
c2.clear();
|
||||||
|
buf = p2;
|
||||||
|
for (unsigned int i = cut; i < p1.size(); ++i)
|
||||||
|
{
|
||||||
|
buf.erase(std::find(buf.begin(), buf.end(), p1[i]));
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < buf.size(); ++i)
|
||||||
|
{
|
||||||
|
c2.push_back(buf[i]);
|
||||||
|
}
|
||||||
|
for (unsigned int i = cut; i < p1.size(); ++i)
|
||||||
|
{
|
||||||
|
c2.push_back(p1[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void GeneticScheduler<T>::mutation(Gene &m, const Gene &c)
|
||||||
|
{
|
||||||
|
Gene buf;
|
||||||
|
std::uniform_int_distribution<unsigned int> dis(0, c.size() - 1);
|
||||||
|
unsigned int cut = dis(gen_);
|
||||||
|
Graph<T> g1 = graph_, g2 = graph_;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < cut; ++i)
|
||||||
|
{
|
||||||
|
g1.removeVertex(c[i]);
|
||||||
|
}
|
||||||
|
for (unsigned int i = cut; i < c.size(); ++i)
|
||||||
|
{
|
||||||
|
g2.removeVertex(c[i]);
|
||||||
|
}
|
||||||
|
if (g1.size() > 0)
|
||||||
|
{
|
||||||
|
buf = g1.topoSort(gen_);
|
||||||
|
}
|
||||||
|
if (g2.size() > 0)
|
||||||
|
{
|
||||||
|
m = g2.topoSort(gen_);
|
||||||
|
}
|
||||||
|
for (unsigned int i = cut; i < c.size(); ++i)
|
||||||
|
{
|
||||||
|
m.push_back(buf[i - cut]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void GeneticScheduler<T>::benchmarkCrossover(const unsigned int nIt)
|
||||||
|
{
|
||||||
|
Gene p1, p2, c1, c2;
|
||||||
|
double neg = 0., eq = 0., pos = 0., total;
|
||||||
|
int improvement;
|
||||||
|
|
||||||
|
LOG(Message) << "Benchmarking crossover..." << std::endl;
|
||||||
|
for (unsigned int i = 0; i < nIt; ++i)
|
||||||
|
{
|
||||||
|
p1 = graph_.topoSort(gen_);
|
||||||
|
p2 = graph_.topoSort(gen_);
|
||||||
|
crossover(c1, c2, p1, p2);
|
||||||
|
improvement = (func_(c1) + func_(c2) - func_(p1) - func_(p2))/2;
|
||||||
|
if (improvement < 0) neg++; else if (improvement == 0) eq++; else pos++;
|
||||||
|
}
|
||||||
|
total = neg + eq + pos;
|
||||||
|
LOG(Message) << " -: " << neg/total << " =: " << eq/total
|
||||||
|
<< " +: " << pos/total << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_GeneticScheduler_hpp_
|
82
extras/Hadrons/Global.cc
Normal file
82
extras/Hadrons/Global.cc
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Global.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Global.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace QCD;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
HadronsLogger Hadrons::HadronsLogError(1,"Error");
|
||||||
|
HadronsLogger Hadrons::HadronsLogWarning(1,"Warning");
|
||||||
|
HadronsLogger Hadrons::HadronsLogMessage(1,"Message");
|
||||||
|
HadronsLogger Hadrons::HadronsLogIterative(1,"Iterative");
|
||||||
|
HadronsLogger Hadrons::HadronsLogDebug(1,"Debug");
|
||||||
|
|
||||||
|
// pretty size formatting //////////////////////////////////////////////////////
|
||||||
|
std::string Hadrons::sizeString(long unsigned int bytes)
|
||||||
|
|
||||||
|
{
|
||||||
|
constexpr unsigned int bufSize = 256;
|
||||||
|
const char *suffixes[7] = {"", "K", "M", "G", "T", "P", "E"};
|
||||||
|
char buf[256];
|
||||||
|
long unsigned int s = 0;
|
||||||
|
double count = bytes;
|
||||||
|
|
||||||
|
while (count >= 1024 && s < 7)
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
count /= 1024;
|
||||||
|
}
|
||||||
|
if (count - floor(count) == 0.0)
|
||||||
|
{
|
||||||
|
snprintf(buf, bufSize, "%d %sB", (int)count, suffixes[s]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(buf, bufSize, "%.1f %sB", count, suffixes[s]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// type utilities //////////////////////////////////////////////////////////////
|
||||||
|
constexpr unsigned int maxNameSize = 1024u;
|
||||||
|
|
||||||
|
std::string Hadrons::typeName(const std::type_info *info)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
buf = abi::__cxa_demangle(info->name(), nullptr, nullptr, nullptr);
|
||||||
|
name = buf;
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
150
extras/Hadrons/Global.hpp
Normal file
150
extras/Hadrons/Global.hpp
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Global.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Global_hpp_
|
||||||
|
#define Hadrons_Global_hpp_
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <stack>
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
#define BEGIN_HADRONS_NAMESPACE \
|
||||||
|
namespace Grid {\
|
||||||
|
using namespace QCD;\
|
||||||
|
namespace Hadrons {\
|
||||||
|
using Grid::operator<<;
|
||||||
|
#define END_HADRONS_NAMESPACE }}
|
||||||
|
|
||||||
|
#define BEGIN_MODULE_NAMESPACE(name)\
|
||||||
|
namespace name {\
|
||||||
|
using Grid::operator<<;
|
||||||
|
#define END_MODULE_NAMESPACE }
|
||||||
|
|
||||||
|
/* the 'using Grid::operator<<;' statement prevents a very nasty compilation
|
||||||
|
* error with GCC 5 (clang & GCC 6 compile fine without it).
|
||||||
|
*/
|
||||||
|
|
||||||
|
// FIXME: find a way to do that in a more general fashion
|
||||||
|
#ifndef FIMPL
|
||||||
|
#define FIMPL WilsonImplR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
// type aliases
|
||||||
|
#define TYPE_ALIASES(FImpl, suffix)\
|
||||||
|
typedef FermionOperator<FImpl> FMat##suffix; \
|
||||||
|
typedef typename FImpl::FermionField FermionField##suffix; \
|
||||||
|
typedef typename FImpl::PropagatorField PropagatorField##suffix; \
|
||||||
|
typedef typename FImpl::SitePropagator SitePropagator##suffix; \
|
||||||
|
typedef typename FImpl::DoubledGaugeField DoubledGaugeField##suffix;\
|
||||||
|
typedef std::function<void(FermionField##suffix &, \
|
||||||
|
const FermionField##suffix &)> SolverFn##suffix;
|
||||||
|
|
||||||
|
// logger
|
||||||
|
class HadronsLogger: public Logger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HadronsLogger(int on, std::string nm): Logger("Hadrons", on, nm,
|
||||||
|
GridLogColours, "BLACK"){};
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOG(channel) std::cout << HadronsLog##channel
|
||||||
|
#define HADRON_ERROR(msg)\
|
||||||
|
LOG(Error) << msg << " (" << __FUNCTION__ << " at " << __FILE__ << ":"\
|
||||||
|
<< __LINE__ << ")" << std::endl;\
|
||||||
|
abort();
|
||||||
|
|
||||||
|
#define DEBUG_VAR(var) LOG(Debug) << #var << "= " << (var) << std::endl;
|
||||||
|
|
||||||
|
extern HadronsLogger HadronsLogError;
|
||||||
|
extern HadronsLogger HadronsLogWarning;
|
||||||
|
extern HadronsLogger HadronsLogMessage;
|
||||||
|
extern HadronsLogger HadronsLogIterative;
|
||||||
|
extern HadronsLogger HadronsLogDebug;
|
||||||
|
|
||||||
|
// singleton pattern
|
||||||
|
#define SINGLETON(name)\
|
||||||
|
public:\
|
||||||
|
name(const name &e) = delete;\
|
||||||
|
void operator=(const name &e) = delete;\
|
||||||
|
static name & getInstance(void)\
|
||||||
|
{\
|
||||||
|
static name e;\
|
||||||
|
return e;\
|
||||||
|
}\
|
||||||
|
private:\
|
||||||
|
name(void);
|
||||||
|
|
||||||
|
#define SINGLETON_DEFCTOR(name)\
|
||||||
|
public:\
|
||||||
|
name(const name &e) = delete;\
|
||||||
|
void operator=(const name &e) = delete;\
|
||||||
|
static name & getInstance(void)\
|
||||||
|
{\
|
||||||
|
static name e;\
|
||||||
|
return e;\
|
||||||
|
}\
|
||||||
|
private:\
|
||||||
|
name(void) = default;
|
||||||
|
|
||||||
|
// pretty size formating
|
||||||
|
std::string sizeString(long unsigned int bytes);
|
||||||
|
|
||||||
|
// type utilities
|
||||||
|
template <typename T>
|
||||||
|
const std::type_info * typeIdPt(const T &x)
|
||||||
|
{
|
||||||
|
return &typeid(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string typeName(const std::type_info *info);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
const std::type_info * typeIdPt(void)
|
||||||
|
{
|
||||||
|
return &typeid(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string typeName(const T &x)
|
||||||
|
{
|
||||||
|
return typeName(typeIdPt(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string typeName(void)
|
||||||
|
{
|
||||||
|
return typeName(typeIdPt<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Global_hpp_
|
760
extras/Hadrons/Graph.hpp
Normal file
760
extras/Hadrons/Graph.hpp
Normal file
@ -0,0 +1,760 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Graph.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Graph_hpp_
|
||||||
|
#define Hadrons_Graph_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Oriented graph class *
|
||||||
|
******************************************************************************/
|
||||||
|
// I/O for edges
|
||||||
|
template <typename T>
|
||||||
|
std::ostream & operator<<(std::ostream &out, const std::pair<T, T> &e)
|
||||||
|
{
|
||||||
|
out << "\"" << e.first << "\" -> \"" << e.second << "\"";
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// main class
|
||||||
|
template <typename T>
|
||||||
|
class Graph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::pair<T, T> Edge;
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
Graph(void);
|
||||||
|
// destructor
|
||||||
|
virtual ~Graph(void) = default;
|
||||||
|
// access
|
||||||
|
void addVertex(const T &value);
|
||||||
|
void addEdge(const Edge &e);
|
||||||
|
void addEdge(const T &start, const T &end);
|
||||||
|
std::vector<T> getVertices(void) const;
|
||||||
|
void removeVertex(const T &value);
|
||||||
|
void removeEdge(const Edge &e);
|
||||||
|
void removeEdge(const T &start, const T &end);
|
||||||
|
unsigned int size(void) const;
|
||||||
|
// tests
|
||||||
|
bool gotValue(const T &value) const;
|
||||||
|
// graph topological manipulations
|
||||||
|
std::vector<T> getAdjacentVertices(const T &value) const;
|
||||||
|
std::vector<T> getChildren(const T &value) const;
|
||||||
|
std::vector<T> getParents(const T &value) const;
|
||||||
|
std::vector<T> getRoots(void) const;
|
||||||
|
std::vector<Graph<T>> getConnectedComponents(void) const;
|
||||||
|
std::vector<T> topoSort(void);
|
||||||
|
template <typename Gen>
|
||||||
|
std::vector<T> topoSort(Gen &gen);
|
||||||
|
std::vector<std::vector<T>> allTopoSort(void);
|
||||||
|
// I/O
|
||||||
|
friend std::ostream & operator<<(std::ostream &out, const Graph<T> &g)
|
||||||
|
{
|
||||||
|
out << "{";
|
||||||
|
for (auto &e: g.edgeSet_)
|
||||||
|
{
|
||||||
|
out << e << ", ";
|
||||||
|
}
|
||||||
|
if (g.edgeSet_.size() != 0)
|
||||||
|
{
|
||||||
|
out << "\b\b";
|
||||||
|
}
|
||||||
|
out << "}";
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
// vertex marking
|
||||||
|
void mark(const T &value, const bool doMark = true);
|
||||||
|
void markAll(const bool doMark = true);
|
||||||
|
void unmark(const T &value);
|
||||||
|
void unmarkAll(void);
|
||||||
|
bool isMarked(const T &value) const;
|
||||||
|
const T * getFirstMarked(const bool isMarked = true) const;
|
||||||
|
template <typename Gen>
|
||||||
|
const T * getRandomMarked(const bool isMarked, Gen &gen);
|
||||||
|
const T * getFirstUnmarked(void) const;
|
||||||
|
template <typename Gen>
|
||||||
|
const T * getRandomUnmarked(Gen &gen);
|
||||||
|
// prune marked/unmarked vertices
|
||||||
|
void removeMarked(const bool isMarked = true);
|
||||||
|
void removeUnmarked(void);
|
||||||
|
// depth-first search marking
|
||||||
|
void depthFirstSearch(void);
|
||||||
|
void depthFirstSearch(const T &root);
|
||||||
|
private:
|
||||||
|
std::map<T, bool> isMarked_;
|
||||||
|
std::set<Edge> edgeSet_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// build depedency matrix from topological sorts
|
||||||
|
template <typename T>
|
||||||
|
std::map<T, std::map<T, bool>>
|
||||||
|
makeDependencyMatrix(const std::vector<std::vector<T>> &topSort);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* template implementation *
|
||||||
|
******************************************************************************
|
||||||
|
* in all the following V is the number of vertex and E is the number of edge
|
||||||
|
* in the worst case E = V^2
|
||||||
|
*/
|
||||||
|
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
Graph<T>::Graph(void)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
|
// complexity: log(V)
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::addVertex(const T &value)
|
||||||
|
{
|
||||||
|
isMarked_[value] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::addEdge(const Edge &e)
|
||||||
|
{
|
||||||
|
addVertex(e.first);
|
||||||
|
addVertex(e.second);
|
||||||
|
edgeSet_.insert(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::addEdge(const T &start, const T &end)
|
||||||
|
{
|
||||||
|
addEdge(Edge(start, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::vector<T> Graph<T>::getVertices(void) const
|
||||||
|
{
|
||||||
|
std::vector<T> vertex;
|
||||||
|
|
||||||
|
for (auto &v: isMarked_)
|
||||||
|
{
|
||||||
|
vertex.push_back(v.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::removeVertex(const T &value)
|
||||||
|
{
|
||||||
|
// remove vertex from the mark table
|
||||||
|
auto vIt = isMarked_.find(value);
|
||||||
|
|
||||||
|
if (vIt != isMarked_.end())
|
||||||
|
{
|
||||||
|
isMarked_.erase(vIt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("vertex " << value << " does not exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove all edges containing the vertex
|
||||||
|
auto pred = [&value](const Edge &e)
|
||||||
|
{
|
||||||
|
return ((e.first == value) or (e.second == value));
|
||||||
|
};
|
||||||
|
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||||
|
|
||||||
|
while (eIt != edgeSet_.end())
|
||||||
|
{
|
||||||
|
edgeSet_.erase(eIt);
|
||||||
|
eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::removeEdge(const Edge &e)
|
||||||
|
{
|
||||||
|
auto eIt = edgeSet_.find(e);
|
||||||
|
|
||||||
|
if (eIt != edgeSet_.end())
|
||||||
|
{
|
||||||
|
edgeSet_.erase(eIt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("edge " << e << " does not exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::removeEdge(const T &start, const T &end)
|
||||||
|
{
|
||||||
|
removeEdge(Edge(start, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(1)
|
||||||
|
template <typename T>
|
||||||
|
unsigned int Graph<T>::size(void) const
|
||||||
|
{
|
||||||
|
return isMarked_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// tests ///////////////////////////////////////////////////////////////////////
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
bool Graph<T>::gotValue(const T &value) const
|
||||||
|
{
|
||||||
|
auto it = isMarked_.find(value);
|
||||||
|
|
||||||
|
if (it == isMarked_.end())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vertex marking //////////////////////////////////////////////////////////////
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::mark(const T &value, const bool doMark)
|
||||||
|
{
|
||||||
|
if (gotValue(value))
|
||||||
|
{
|
||||||
|
isMarked_[value] = doMark;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("vertex " << value << " does not exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::markAll(const bool doMark)
|
||||||
|
{
|
||||||
|
for (auto &v: isMarked_)
|
||||||
|
{
|
||||||
|
mark(v.first, doMark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::unmark(const T &value)
|
||||||
|
{
|
||||||
|
mark(value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::unmarkAll(void)
|
||||||
|
{
|
||||||
|
markAll(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
bool Graph<T>::isMarked(const T &value) const
|
||||||
|
{
|
||||||
|
if (gotValue(value))
|
||||||
|
{
|
||||||
|
return isMarked_.at(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HADRON_ERROR("vertex " << value << " does not exists");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
const T * Graph<T>::getFirstMarked(const bool isMarked) const
|
||||||
|
{
|
||||||
|
auto pred = [&isMarked](const std::pair<T, bool> &v)
|
||||||
|
{
|
||||||
|
return (v.second == isMarked);
|
||||||
|
};
|
||||||
|
auto vIt = std::find_if(isMarked_.begin(), isMarked_.end(), pred);
|
||||||
|
|
||||||
|
if (vIt != isMarked_.end())
|
||||||
|
{
|
||||||
|
return &(vIt->first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
template <typename Gen>
|
||||||
|
const T * Graph<T>::getRandomMarked(const bool isMarked, Gen &gen)
|
||||||
|
{
|
||||||
|
auto pred = [&isMarked](const std::pair<T, bool> &v)
|
||||||
|
{
|
||||||
|
return (v.second == isMarked);
|
||||||
|
};
|
||||||
|
std::uniform_int_distribution<unsigned int> dis(0, size() - 1);
|
||||||
|
auto rIt = isMarked_.begin();
|
||||||
|
|
||||||
|
std::advance(rIt, dis(gen));
|
||||||
|
auto vIt = std::find_if(rIt, isMarked_.end(), pred);
|
||||||
|
if (vIt != isMarked_.end())
|
||||||
|
{
|
||||||
|
return &(vIt->first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vIt = std::find_if(isMarked_.begin(), rIt, pred);
|
||||||
|
if (vIt != rIt)
|
||||||
|
{
|
||||||
|
return &(vIt->first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
const T * Graph<T>::getFirstUnmarked(void) const
|
||||||
|
{
|
||||||
|
return getFirstMarked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(log(V))
|
||||||
|
template <typename T>
|
||||||
|
template <typename Gen>
|
||||||
|
const T * Graph<T>::getRandomUnmarked(Gen &gen)
|
||||||
|
{
|
||||||
|
return getRandomMarked(false, gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// prune marked/unmarked vertices //////////////////////////////////////////////
|
||||||
|
// complexity: O(V^2*log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::removeMarked(const bool isMarked)
|
||||||
|
{
|
||||||
|
auto isMarkedCopy = isMarked_;
|
||||||
|
|
||||||
|
for (auto &v: isMarkedCopy)
|
||||||
|
{
|
||||||
|
if (v.second == isMarked)
|
||||||
|
{
|
||||||
|
removeVertex(v.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(V^2*log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::removeUnmarked(void)
|
||||||
|
{
|
||||||
|
removeMarked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// depth-first search marking //////////////////////////////////////////////////
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::depthFirstSearch(void)
|
||||||
|
{
|
||||||
|
depthFirstSearch(isMarked_.begin()->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
void Graph<T>::depthFirstSearch(const T &root)
|
||||||
|
{
|
||||||
|
std::vector<T> adjacentVertex;
|
||||||
|
|
||||||
|
mark(root);
|
||||||
|
adjacentVertex = getAdjacentVertices(root);
|
||||||
|
for (auto &v: adjacentVertex)
|
||||||
|
{
|
||||||
|
if (!isMarked(v))
|
||||||
|
{
|
||||||
|
depthFirstSearch(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// graph topological manipulations /////////////////////////////////////////////
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
std::vector<T> Graph<T>::getAdjacentVertices(const T &value) const
|
||||||
|
{
|
||||||
|
std::vector<T> adjacentVertex;
|
||||||
|
|
||||||
|
auto pred = [&value](const Edge &e)
|
||||||
|
{
|
||||||
|
return ((e.first == value) or (e.second == value));
|
||||||
|
};
|
||||||
|
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||||
|
|
||||||
|
while (eIt != edgeSet_.end())
|
||||||
|
{
|
||||||
|
if (eIt->first == value)
|
||||||
|
{
|
||||||
|
adjacentVertex.push_back((*eIt).second);
|
||||||
|
}
|
||||||
|
else if (eIt->second == value)
|
||||||
|
{
|
||||||
|
adjacentVertex.push_back((*eIt).first);
|
||||||
|
}
|
||||||
|
eIt = find_if(++eIt, edgeSet_.end(), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
return adjacentVertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
std::vector<T> Graph<T>::getChildren(const T &value) const
|
||||||
|
{
|
||||||
|
std::vector<T> child;
|
||||||
|
|
||||||
|
auto pred = [&value](const Edge &e)
|
||||||
|
{
|
||||||
|
return (e.first == value);
|
||||||
|
};
|
||||||
|
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||||
|
|
||||||
|
while (eIt != edgeSet_.end())
|
||||||
|
{
|
||||||
|
child.push_back((*eIt).second);
|
||||||
|
eIt = find_if(++eIt, edgeSet_.end(), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
std::vector<T> Graph<T>::getParents(const T &value) const
|
||||||
|
{
|
||||||
|
std::vector<T> parent;
|
||||||
|
|
||||||
|
auto pred = [&value](const Edge &e)
|
||||||
|
{
|
||||||
|
return (e.second == value);
|
||||||
|
};
|
||||||
|
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||||
|
|
||||||
|
while (eIt != edgeSet_.end())
|
||||||
|
{
|
||||||
|
parent.push_back((*eIt).first);
|
||||||
|
eIt = find_if(++eIt, edgeSet_.end(), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(V^2*log(V))
|
||||||
|
template <typename T>
|
||||||
|
std::vector<T> Graph<T>::getRoots(void) const
|
||||||
|
{
|
||||||
|
std::vector<T> root;
|
||||||
|
|
||||||
|
for (auto &v: isMarked_)
|
||||||
|
{
|
||||||
|
auto parent = getParents(v.first);
|
||||||
|
|
||||||
|
if (parent.size() == 0)
|
||||||
|
{
|
||||||
|
root.push_back(v.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complexity: O(V^2*log(V))
|
||||||
|
template <typename T>
|
||||||
|
std::vector<Graph<T>> Graph<T>::getConnectedComponents(void) const
|
||||||
|
{
|
||||||
|
std::vector<Graph<T>> res;
|
||||||
|
Graph<T> copy(*this);
|
||||||
|
|
||||||
|
while (copy.size() > 0)
|
||||||
|
{
|
||||||
|
copy.depthFirstSearch();
|
||||||
|
res.push_back(copy);
|
||||||
|
res.back().removeUnmarked();
|
||||||
|
res.back().unmarkAll();
|
||||||
|
copy.removeMarked();
|
||||||
|
copy.unmarkAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// topological sort using a directed DFS algorithm
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
std::vector<T> Graph<T>::topoSort(void)
|
||||||
|
{
|
||||||
|
std::stack<T> buf;
|
||||||
|
std::vector<T> res;
|
||||||
|
const T *vPt;
|
||||||
|
std::map<T, bool> tmpMarked(isMarked_);
|
||||||
|
|
||||||
|
// visit function
|
||||||
|
std::function<void(const T &)> visit = [&](const T &v)
|
||||||
|
{
|
||||||
|
if (tmpMarked.at(v))
|
||||||
|
{
|
||||||
|
HADRON_ERROR("cannot topologically sort a cyclic graph");
|
||||||
|
}
|
||||||
|
if (!isMarked(v))
|
||||||
|
{
|
||||||
|
std::vector<T> child = getChildren(v);
|
||||||
|
|
||||||
|
tmpMarked[v] = true;
|
||||||
|
for (auto &c: child)
|
||||||
|
{
|
||||||
|
visit(c);
|
||||||
|
}
|
||||||
|
mark(v);
|
||||||
|
tmpMarked[v] = false;
|
||||||
|
buf.push(v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// reset temporary marks
|
||||||
|
for (auto &v: tmpMarked)
|
||||||
|
{
|
||||||
|
tmpMarked.at(v.first) = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop on unmarked vertices
|
||||||
|
unmarkAll();
|
||||||
|
vPt = getFirstUnmarked();
|
||||||
|
while (vPt)
|
||||||
|
{
|
||||||
|
visit(*vPt);
|
||||||
|
vPt = getFirstUnmarked();
|
||||||
|
}
|
||||||
|
unmarkAll();
|
||||||
|
|
||||||
|
// create result vector
|
||||||
|
while (!buf.empty())
|
||||||
|
{
|
||||||
|
res.push_back(buf.top());
|
||||||
|
buf.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// random version of the topological sort
|
||||||
|
// complexity: O(V*log(V))
|
||||||
|
template <typename T>
|
||||||
|
template <typename Gen>
|
||||||
|
std::vector<T> Graph<T>::topoSort(Gen &gen)
|
||||||
|
{
|
||||||
|
std::stack<T> buf;
|
||||||
|
std::vector<T> res;
|
||||||
|
const T *vPt;
|
||||||
|
std::map<T, bool> tmpMarked(isMarked_);
|
||||||
|
|
||||||
|
// visit function
|
||||||
|
std::function<void(const T &)> visit = [&](const T &v)
|
||||||
|
{
|
||||||
|
if (tmpMarked.at(v))
|
||||||
|
{
|
||||||
|
HADRON_ERROR("cannot topologically sort a cyclic graph");
|
||||||
|
}
|
||||||
|
if (!isMarked(v))
|
||||||
|
{
|
||||||
|
std::vector<T> child = getChildren(v);
|
||||||
|
|
||||||
|
tmpMarked[v] = true;
|
||||||
|
std::shuffle(child.begin(), child.end(), gen);
|
||||||
|
for (auto &c: child)
|
||||||
|
{
|
||||||
|
visit(c);
|
||||||
|
}
|
||||||
|
mark(v);
|
||||||
|
tmpMarked[v] = false;
|
||||||
|
buf.push(v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// reset temporary marks
|
||||||
|
for (auto &v: tmpMarked)
|
||||||
|
{
|
||||||
|
tmpMarked.at(v.first) = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop on unmarked vertices
|
||||||
|
unmarkAll();
|
||||||
|
vPt = getRandomUnmarked(gen);
|
||||||
|
while (vPt)
|
||||||
|
{
|
||||||
|
visit(*vPt);
|
||||||
|
vPt = getRandomUnmarked(gen);
|
||||||
|
}
|
||||||
|
unmarkAll();
|
||||||
|
|
||||||
|
// create result vector
|
||||||
|
while (!buf.empty())
|
||||||
|
{
|
||||||
|
res.push_back(buf.top());
|
||||||
|
buf.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate all possible topological sorts
|
||||||
|
// Y. L. Varol & D. Rotem, Comput. J. 24(1), pp. 83–84, 1981
|
||||||
|
// http://comjnl.oupjournals.org/cgi/doi/10.1093/comjnl/24.1.83
|
||||||
|
// complexity: O(V*log(V)) (from the paper, but really ?)
|
||||||
|
template <typename T>
|
||||||
|
std::vector<std::vector<T>> Graph<T>::allTopoSort(void)
|
||||||
|
{
|
||||||
|
std::vector<std::vector<T>> res;
|
||||||
|
std::map<T, std::map<T, bool>> iMat;
|
||||||
|
|
||||||
|
// create incidence matrix
|
||||||
|
for (auto &v1: isMarked_)
|
||||||
|
for (auto &v2: isMarked_)
|
||||||
|
{
|
||||||
|
iMat[v1.first][v2.first] = false;
|
||||||
|
}
|
||||||
|
for (auto &v: isMarked_)
|
||||||
|
{
|
||||||
|
auto cVec = getChildren(v.first);
|
||||||
|
|
||||||
|
for (auto &c: cVec)
|
||||||
|
{
|
||||||
|
iMat[v.first][c] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate initial topological sort
|
||||||
|
res.push_back(topoSort());
|
||||||
|
|
||||||
|
// generate all other topological sorts by permutation
|
||||||
|
std::vector<T> p = res[0];
|
||||||
|
const unsigned int n = size();
|
||||||
|
std::vector<unsigned int> loc(n);
|
||||||
|
unsigned int i, k, k1;
|
||||||
|
T obj_k, obj_k1;
|
||||||
|
bool isFinal;
|
||||||
|
|
||||||
|
for (unsigned int j = 0; j < n; ++j)
|
||||||
|
{
|
||||||
|
loc[j] = j;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while (i < n-1)
|
||||||
|
{
|
||||||
|
k = loc[i];
|
||||||
|
k1 = k + 1;
|
||||||
|
obj_k = p[k];
|
||||||
|
if (k1 >= n)
|
||||||
|
{
|
||||||
|
isFinal = true;
|
||||||
|
obj_k1 = obj_k;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isFinal = false;
|
||||||
|
obj_k1 = p[k1];
|
||||||
|
}
|
||||||
|
if (iMat[res[0][i]][obj_k1] or isFinal)
|
||||||
|
{
|
||||||
|
for (unsigned int l = k; l >= i + 1; --l)
|
||||||
|
{
|
||||||
|
p[l] = p[l-1];
|
||||||
|
}
|
||||||
|
p[i] = obj_k;
|
||||||
|
loc[i] = i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p[k] = obj_k1;
|
||||||
|
p[k1] = obj_k;
|
||||||
|
loc[i] = k1;
|
||||||
|
i = 0;
|
||||||
|
res.push_back(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build depedency matrix from topological sorts ///////////////////////////////
|
||||||
|
// complexity: something like O(V^2*log(V!))
|
||||||
|
template <typename T>
|
||||||
|
std::map<T, std::map<T, bool>>
|
||||||
|
makeDependencyMatrix(const std::vector<std::vector<T>> &topSort)
|
||||||
|
{
|
||||||
|
std::map<T, std::map<T, bool>> m;
|
||||||
|
const std::vector<T> &vList = topSort[0];
|
||||||
|
|
||||||
|
for (auto &v1: vList)
|
||||||
|
for (auto &v2: vList)
|
||||||
|
{
|
||||||
|
bool dep = true;
|
||||||
|
|
||||||
|
for (auto &t: topSort)
|
||||||
|
{
|
||||||
|
auto i1 = std::find(t.begin(), t.end(), v1);
|
||||||
|
auto i2 = std::find(t.begin(), t.end(), v2);
|
||||||
|
|
||||||
|
dep = dep and (i1 - i2 > 0);
|
||||||
|
if (!dep) break;
|
||||||
|
}
|
||||||
|
m[v1][v2] = dep;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Graph_hpp_
|
80
extras/Hadrons/HadronsXmlRun.cc
Normal file
80
extras/Hadrons/HadronsXmlRun.cc
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/HadronsXmlRun.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Application.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace QCD;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// parse command line
|
||||||
|
std::string parameterFileName, scheduleFileName = "";
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
std::cerr << "usage: " << argv[0] << " <parameter file> [<precomputed schedule>] [Grid options]";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
std::exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
parameterFileName = argv[1];
|
||||||
|
if (argc > 2)
|
||||||
|
{
|
||||||
|
if (argv[2][0] != '-')
|
||||||
|
{
|
||||||
|
scheduleFileName = argv[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialization
|
||||||
|
Grid_init(&argc, &argv);
|
||||||
|
HadronsLogError.Active(GridLogError.isActive());
|
||||||
|
HadronsLogWarning.Active(GridLogWarning.isActive());
|
||||||
|
HadronsLogMessage.Active(GridLogMessage.isActive());
|
||||||
|
HadronsLogIterative.Active(GridLogIterative.isActive());
|
||||||
|
HadronsLogDebug.Active(GridLogDebug.isActive());
|
||||||
|
LOG(Message) << "Grid initialized" << std::endl;
|
||||||
|
|
||||||
|
// execution
|
||||||
|
Application application(parameterFileName);
|
||||||
|
|
||||||
|
application.parseParameterFile(parameterFileName);
|
||||||
|
if (!scheduleFileName.empty())
|
||||||
|
{
|
||||||
|
application.loadSchedule(scheduleFileName);
|
||||||
|
}
|
||||||
|
application.run();
|
||||||
|
|
||||||
|
// epilogue
|
||||||
|
LOG(Message) << "Grid is finalizing now" << std::endl;
|
||||||
|
Grid_finalize();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
72
extras/Hadrons/HadronsXmlSchedule.cc
Normal file
72
extras/Hadrons/HadronsXmlSchedule.cc
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/HadronsXmlSchedule.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Application.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace QCD;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// parse command line
|
||||||
|
std::string parameterFileName, scheduleFileName;
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
{
|
||||||
|
std::cerr << "usage: " << argv[0] << " <parameter file> <schedule output> [Grid options]";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
std::exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
parameterFileName = argv[1];
|
||||||
|
scheduleFileName = argv[2];
|
||||||
|
|
||||||
|
// initialization
|
||||||
|
Grid_init(&argc, &argv);
|
||||||
|
HadronsLogError.Active(GridLogError.isActive());
|
||||||
|
HadronsLogWarning.Active(GridLogWarning.isActive());
|
||||||
|
HadronsLogMessage.Active(GridLogMessage.isActive());
|
||||||
|
HadronsLogIterative.Active(GridLogIterative.isActive());
|
||||||
|
HadronsLogDebug.Active(GridLogDebug.isActive());
|
||||||
|
LOG(Message) << "Grid initialized" << std::endl;
|
||||||
|
|
||||||
|
// execution
|
||||||
|
Application application;
|
||||||
|
|
||||||
|
application.parseParameterFile(parameterFileName);
|
||||||
|
application.schedule();
|
||||||
|
application.printSchedule();
|
||||||
|
application.saveSchedule(scheduleFileName);
|
||||||
|
|
||||||
|
// epilogue
|
||||||
|
LOG(Message) << "Grid is finalizing now" << std::endl;
|
||||||
|
Grid_finalize();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
29
extras/Hadrons/Makefile.am
Normal file
29
extras/Hadrons/Makefile.am
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
lib_LIBRARIES = libHadrons.a
|
||||||
|
bin_PROGRAMS = HadronsXmlRun HadronsXmlSchedule
|
||||||
|
|
||||||
|
include modules.inc
|
||||||
|
|
||||||
|
libHadrons_a_SOURCES = \
|
||||||
|
$(modules_cc) \
|
||||||
|
Application.cc \
|
||||||
|
Environment.cc \
|
||||||
|
Global.cc \
|
||||||
|
Module.cc
|
||||||
|
libHadrons_adir = $(pkgincludedir)/Hadrons
|
||||||
|
nobase_libHadrons_a_HEADERS = \
|
||||||
|
$(modules_hpp) \
|
||||||
|
Application.hpp \
|
||||||
|
Environment.hpp \
|
||||||
|
Factory.hpp \
|
||||||
|
GeneticScheduler.hpp \
|
||||||
|
Global.hpp \
|
||||||
|
Graph.hpp \
|
||||||
|
Module.hpp \
|
||||||
|
Modules.hpp \
|
||||||
|
ModuleFactory.hpp
|
||||||
|
|
||||||
|
HadronsXmlRun_SOURCES = HadronsXmlRun.cc
|
||||||
|
HadronsXmlRun_LDADD = libHadrons.a -lGrid
|
||||||
|
|
||||||
|
HadronsXmlSchedule_SOURCES = HadronsXmlSchedule.cc
|
||||||
|
HadronsXmlSchedule_LDADD = libHadrons.a -lGrid
|
71
extras/Hadrons/Module.cc
Normal file
71
extras/Hadrons/Module.cc
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Module.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Module.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace QCD;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* ModuleBase implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
ModuleBase::ModuleBase(const std::string name)
|
||||||
|
: name_(name)
|
||||||
|
, env_(Environment::getInstance())
|
||||||
|
{}
|
||||||
|
|
||||||
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
|
std::string ModuleBase::getName(void) const
|
||||||
|
{
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment & ModuleBase::env(void) const
|
||||||
|
{
|
||||||
|
return env_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get factory registration name if available
|
||||||
|
std::string ModuleBase::getRegisteredName(void)
|
||||||
|
{
|
||||||
|
HADRON_ERROR("module '" + getName() + "' has a type not registered"
|
||||||
|
+ " in the factory");
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
void ModuleBase::operator()(void)
|
||||||
|
{
|
||||||
|
setup();
|
||||||
|
if (!env().isDryRun())
|
||||||
|
{
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
}
|
198
extras/Hadrons/Module.hpp
Normal file
198
extras/Hadrons/Module.hpp
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Module.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Module_hpp_
|
||||||
|
#define Hadrons_Module_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Environment.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
// module registration macros
|
||||||
|
#define MODULE_REGISTER(mod, base)\
|
||||||
|
class mod: public base\
|
||||||
|
{\
|
||||||
|
public:\
|
||||||
|
typedef base Base;\
|
||||||
|
using Base::Base;\
|
||||||
|
virtual std::string getRegisteredName(void)\
|
||||||
|
{\
|
||||||
|
return std::string(#mod);\
|
||||||
|
}\
|
||||||
|
};\
|
||||||
|
class mod##ModuleRegistrar\
|
||||||
|
{\
|
||||||
|
public:\
|
||||||
|
mod##ModuleRegistrar(void)\
|
||||||
|
{\
|
||||||
|
ModuleFactory &modFac = ModuleFactory::getInstance();\
|
||||||
|
modFac.registerBuilder(#mod, [&](const std::string name)\
|
||||||
|
{\
|
||||||
|
return std::unique_ptr<mod>(new mod(name));\
|
||||||
|
});\
|
||||||
|
}\
|
||||||
|
};\
|
||||||
|
static mod##ModuleRegistrar mod##ModuleRegistrarInstance;
|
||||||
|
|
||||||
|
#define MODULE_REGISTER_NS(mod, base, ns)\
|
||||||
|
class mod: public base\
|
||||||
|
{\
|
||||||
|
public:\
|
||||||
|
typedef base Base;\
|
||||||
|
using Base::Base;\
|
||||||
|
virtual std::string getRegisteredName(void)\
|
||||||
|
{\
|
||||||
|
return std::string(#ns "::" #mod);\
|
||||||
|
}\
|
||||||
|
};\
|
||||||
|
class ns##mod##ModuleRegistrar\
|
||||||
|
{\
|
||||||
|
public:\
|
||||||
|
ns##mod##ModuleRegistrar(void)\
|
||||||
|
{\
|
||||||
|
ModuleFactory &modFac = ModuleFactory::getInstance();\
|
||||||
|
modFac.registerBuilder(#ns "::" #mod, [&](const std::string name)\
|
||||||
|
{\
|
||||||
|
return std::unique_ptr<ns::mod>(new ns::mod(name));\
|
||||||
|
});\
|
||||||
|
}\
|
||||||
|
};\
|
||||||
|
static ns##mod##ModuleRegistrar ns##mod##ModuleRegistrarInstance;
|
||||||
|
|
||||||
|
#define ARG(...) __VA_ARGS__
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Module class *
|
||||||
|
******************************************************************************/
|
||||||
|
// base class
|
||||||
|
class ModuleBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
ModuleBase(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~ModuleBase(void) = default;
|
||||||
|
// access
|
||||||
|
std::string getName(void) const;
|
||||||
|
Environment &env(void) const;
|
||||||
|
// get factory registration name if available
|
||||||
|
virtual std::string getRegisteredName(void);
|
||||||
|
// dependencies/products
|
||||||
|
virtual std::vector<std::string> getInput(void) = 0;
|
||||||
|
virtual std::vector<std::string> getOutput(void) = 0;
|
||||||
|
// parse parameters
|
||||||
|
virtual void parseParameters(XmlReader &reader, const std::string name) = 0;
|
||||||
|
virtual void saveParameters(XmlWriter &writer, const std::string name) = 0;
|
||||||
|
// setup
|
||||||
|
virtual void setup(void) {};
|
||||||
|
// execution
|
||||||
|
void operator()(void);
|
||||||
|
virtual void execute(void) = 0;
|
||||||
|
private:
|
||||||
|
std::string name_;
|
||||||
|
Environment &env_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// derived class, templating the parameter class
|
||||||
|
template <typename P>
|
||||||
|
class Module: public ModuleBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef P Par;
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
Module(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~Module(void) = default;
|
||||||
|
// parse parameters
|
||||||
|
virtual void parseParameters(XmlReader &reader, const std::string name);
|
||||||
|
virtual void saveParameters(XmlWriter &writer, const std::string name);
|
||||||
|
// parameter access
|
||||||
|
const P & par(void) const;
|
||||||
|
void setPar(const P &par);
|
||||||
|
private:
|
||||||
|
P par_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// no parameter type
|
||||||
|
class NoPar {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class Module<NoPar>: public ModuleBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
Module(const std::string name): ModuleBase(name) {};
|
||||||
|
// destructor
|
||||||
|
virtual ~Module(void) = default;
|
||||||
|
// parse parameters (do nothing)
|
||||||
|
virtual void parseParameters(XmlReader &reader, const std::string name) {};
|
||||||
|
virtual void saveParameters(XmlWriter &writer, const std::string name)
|
||||||
|
{
|
||||||
|
push(writer, "options");
|
||||||
|
pop(writer);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
template <typename P>
|
||||||
|
Module<P>::Module(const std::string name)
|
||||||
|
: ModuleBase(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename P>
|
||||||
|
void Module<P>::parseParameters(XmlReader &reader, const std::string name)
|
||||||
|
{
|
||||||
|
read(reader, name, par_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P>
|
||||||
|
void Module<P>::saveParameters(XmlWriter &writer, const std::string name)
|
||||||
|
{
|
||||||
|
write(writer, name, par_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P>
|
||||||
|
const P & Module<P>::par(void) const
|
||||||
|
{
|
||||||
|
return par_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P>
|
||||||
|
void Module<P>::setPar(const P &par)
|
||||||
|
{
|
||||||
|
par_ = par;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Module_hpp_
|
49
extras/Hadrons/ModuleFactory.hpp
Normal file
49
extras/Hadrons/ModuleFactory.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/ModuleFactory.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_ModuleFactory_hpp_
|
||||||
|
#define Hadrons_ModuleFactory_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Factory.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* ModuleFactory *
|
||||||
|
******************************************************************************/
|
||||||
|
class ModuleFactory: public Factory<ModuleBase>
|
||||||
|
{
|
||||||
|
SINGLETON_DEFCTOR(ModuleFactory)
|
||||||
|
};
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_ModuleFactory_hpp_
|
40
extras/Hadrons/Modules.hpp
Normal file
40
extras/Hadrons/Modules.hpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Modules/MAction/DWF.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MAction/Wilson.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MContraction/Baryon.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MContraction/Meson.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MGauge/Load.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MGauge/Random.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MGauge/Unit.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSolver/RBPrecCG.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSource/Point.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSource/SeqGamma.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/MSource/Z2.hpp>
|
||||||
|
#include <Grid/Hadrons/Modules/Quark.hpp>
|
134
extras/Hadrons/Modules/MAction/DWF.hpp
Normal file
134
extras/Hadrons/Modules/MAction/DWF.hpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MAction/DWF.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_DWF_hpp_
|
||||||
|
#define Hadrons_DWF_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Domain wall quark action *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MAction)
|
||||||
|
|
||||||
|
class DWFPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(DWFPar,
|
||||||
|
std::string, gauge,
|
||||||
|
unsigned int, Ls,
|
||||||
|
double , mass,
|
||||||
|
double , M5);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TDWF: public Module<DWFPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TDWF(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TDWF(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(DWF, TDWF<FIMPL>, MAction);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DWF template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TDWF<FImpl>::TDWF(const std::string name)
|
||||||
|
: Module<DWFPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TDWF<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().gauge};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TDWF<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TDWF<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
size = 2*env().template lattice4dSize<typename FImpl::DoubledGaugeField>();
|
||||||
|
env().registerObject(getName(), size, par().Ls);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TDWF<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Setting up domain wall fermion matrix with m= "
|
||||||
|
<< par().mass << ", M5= " << par().M5 << " and Ls= "
|
||||||
|
<< par().Ls << " using gauge field '" << par().gauge << "'"
|
||||||
|
<< std::endl;
|
||||||
|
env().createGrid(par().Ls);
|
||||||
|
auto &U = *env().template getObject<LatticeGaugeField>(par().gauge);
|
||||||
|
auto &g4 = *env().getGrid();
|
||||||
|
auto &grb4 = *env().getRbGrid();
|
||||||
|
auto &g5 = *env().getGrid(par().Ls);
|
||||||
|
auto &grb5 = *env().getRbGrid(par().Ls);
|
||||||
|
FMat *fMatPt = new DomainWallFermion<FImpl>(U, g5, grb5, g4, grb4,
|
||||||
|
par().mass, par().M5);
|
||||||
|
env().setObject(getName(), fMatPt);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_DWF_hpp_
|
126
extras/Hadrons/Modules/MAction/Wilson.hpp
Normal file
126
extras/Hadrons/Modules/MAction/Wilson.hpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MAction/Wilson.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Wilson_hpp_
|
||||||
|
#define Hadrons_Wilson_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TWilson quark action *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MAction)
|
||||||
|
|
||||||
|
class WilsonPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(WilsonPar,
|
||||||
|
std::string, gauge,
|
||||||
|
double , mass);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TWilson: public Module<WilsonPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TWilson(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TWilson(void) = default;
|
||||||
|
// dependencies/products
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(Wilson, TWilson<FIMPL>, MAction);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TWilson template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TWilson<FImpl>::TWilson(const std::string name)
|
||||||
|
: Module<WilsonPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TWilson<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().gauge};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TWilson<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TWilson<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
size = 2*env().template lattice4dSize<typename FImpl::DoubledGaugeField>();
|
||||||
|
env().registerObject(getName(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TWilson<FImpl>::execute()
|
||||||
|
{
|
||||||
|
LOG(Message) << "Setting up TWilson fermion matrix with m= " << par().mass
|
||||||
|
<< " using gauge field '" << par().gauge << "'" << std::endl;
|
||||||
|
auto &U = *env().template getObject<LatticeGaugeField>(par().gauge);
|
||||||
|
auto &grid = *env().getGrid();
|
||||||
|
auto &gridRb = *env().getRbGrid();
|
||||||
|
FMat *fMatPt = new WilsonFermion<FImpl>(U, grid, gridRb, par().mass);
|
||||||
|
env().setObject(getName(), fMatPt);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Wilson_hpp_
|
131
extras/Hadrons/Modules/MContraction/Baryon.hpp
Normal file
131
extras/Hadrons/Modules/MContraction/Baryon.hpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MContraction/Baryon.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Baryon_hpp_
|
||||||
|
#define Hadrons_Baryon_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Baryon *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MContraction)
|
||||||
|
|
||||||
|
class BaryonPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(BaryonPar,
|
||||||
|
std::string, q1,
|
||||||
|
std::string, q2,
|
||||||
|
std::string, q3,
|
||||||
|
std::string, output);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
|
class TBaryon: public Module<BaryonPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TYPE_ALIASES(FImpl1, 1);
|
||||||
|
TYPE_ALIASES(FImpl2, 2);
|
||||||
|
TYPE_ALIASES(FImpl3, 3);
|
||||||
|
class Result: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||||
|
std::vector<std::vector<std::vector<Complex>>>, corr);
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TBaryon(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TBaryon(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(Baryon, ARG(TBaryon<FIMPL, FIMPL, FIMPL>), MContraction);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TBaryon implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
|
TBaryon<FImpl1, FImpl2, FImpl3>::TBaryon(const std::string name)
|
||||||
|
: Module<BaryonPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
|
std::vector<std::string> TBaryon<FImpl1, FImpl2, FImpl3>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> input = {par().q1, par().q2, par().q3};
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
|
std::vector<std::string> TBaryon<FImpl1, FImpl2, FImpl3>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl1, typename FImpl2, typename FImpl3>
|
||||||
|
void TBaryon<FImpl1, FImpl2, FImpl3>::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Computing baryon contractions '" << getName() << "' using"
|
||||||
|
<< " quarks '" << par().q1 << "', '" << par().q2 << "', and '"
|
||||||
|
<< par().q3 << "'" << std::endl;
|
||||||
|
|
||||||
|
XmlWriter writer(par().output);
|
||||||
|
PropagatorField1 &q1 = *env().template getObject<PropagatorField1>(par().q1);
|
||||||
|
PropagatorField2 &q2 = *env().template getObject<PropagatorField2>(par().q2);
|
||||||
|
PropagatorField3 &q3 = *env().template getObject<PropagatorField3>(par().q2);
|
||||||
|
LatticeComplex c(env().getGrid());
|
||||||
|
Result result;
|
||||||
|
|
||||||
|
// FIXME: do contractions
|
||||||
|
|
||||||
|
write(writer, "meson", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Baryon_hpp_
|
148
extras/Hadrons/Modules/MContraction/Meson.hpp
Normal file
148
extras/Hadrons/Modules/MContraction/Meson.hpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MContraction/Meson.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Meson_hpp_
|
||||||
|
#define Hadrons_Meson_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TMeson *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MContraction)
|
||||||
|
|
||||||
|
class MesonPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(MesonPar,
|
||||||
|
std::string, q1,
|
||||||
|
std::string, q2,
|
||||||
|
std::string, output);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl1, typename FImpl2>
|
||||||
|
class TMeson: public Module<MesonPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TYPE_ALIASES(FImpl1, 1);
|
||||||
|
TYPE_ALIASES(FImpl2, 2);
|
||||||
|
class Result: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
|
||||||
|
std::vector<std::vector<std::vector<Complex>>>, corr);
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TMeson(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TMeson(void) = default;
|
||||||
|
// dependencies/products
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(Meson, ARG(TMeson<FIMPL, FIMPL>), MContraction);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TMeson implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl1, typename FImpl2>
|
||||||
|
TMeson<FImpl1, FImpl2>::TMeson(const std::string name)
|
||||||
|
: Module<MesonPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl1, typename FImpl2>
|
||||||
|
std::vector<std::string> TMeson<FImpl1, FImpl2>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> input = {par().q1, par().q2};
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl1, typename FImpl2>
|
||||||
|
std::vector<std::string> TMeson<FImpl1, FImpl2>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> output = {getName()};
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl1, typename FImpl2>
|
||||||
|
void TMeson<FImpl1, FImpl2>::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Computing meson contractions '" << getName() << "' using"
|
||||||
|
<< " quarks '" << par().q1 << "' and '" << par().q2 << "'"
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
XmlWriter writer(par().output);
|
||||||
|
PropagatorField1 &q1 = *env().template getObject<PropagatorField1>(par().q1);
|
||||||
|
PropagatorField2 &q2 = *env().template getObject<PropagatorField2>(par().q2);
|
||||||
|
LatticeComplex c(env().getGrid());
|
||||||
|
SpinMatrix g[Ns*Ns], g5;
|
||||||
|
std::vector<TComplex> buf;
|
||||||
|
Result result;
|
||||||
|
|
||||||
|
g5 = makeGammaProd(Ns*Ns - 1);
|
||||||
|
result.corr.resize(Ns*Ns);
|
||||||
|
for (unsigned int i = 0; i < Ns*Ns; ++i)
|
||||||
|
{
|
||||||
|
g[i] = makeGammaProd(i);
|
||||||
|
}
|
||||||
|
for (unsigned int iSink = 0; iSink < Ns*Ns; ++iSink)
|
||||||
|
{
|
||||||
|
result.corr[iSink].resize(Ns*Ns);
|
||||||
|
for (unsigned int iSrc = 0; iSrc < Ns*Ns; ++iSrc)
|
||||||
|
{
|
||||||
|
c = trace(g[iSink]*q1*g[iSrc]*g5*adj(q2)*g5);
|
||||||
|
sliceSum(c, buf, Tp);
|
||||||
|
result.corr[iSink][iSrc].resize(buf.size());
|
||||||
|
for (unsigned int t = 0; t < buf.size(); ++t)
|
||||||
|
{
|
||||||
|
result.corr[iSink][iSrc][t] = TensorRemove(buf[t]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write(writer, "meson", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Meson_hpp_
|
78
extras/Hadrons/Modules/MGauge/Load.cc
Normal file
78
extras/Hadrons/Modules/MGauge/Load.cc
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MGauge/Load.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Modules/MGauge/Load.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
using namespace MGauge;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TLoad implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
TLoad::TLoad(const std::string name)
|
||||||
|
: Module<LoadPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
std::vector<std::string> TLoad::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> TLoad::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
void TLoad::setup(void)
|
||||||
|
{
|
||||||
|
env().registerLattice<LatticeGaugeField>(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
void TLoad::execute(void)
|
||||||
|
{
|
||||||
|
NerscField header;
|
||||||
|
std::string fileName = par().file + "."
|
||||||
|
+ std::to_string(env().getTrajectory());
|
||||||
|
|
||||||
|
LOG(Message) << "Loading NERSC configuration from file '" << fileName
|
||||||
|
<< "'" << std::endl;
|
||||||
|
LatticeGaugeField &U = *env().createLattice<LatticeGaugeField>(getName());
|
||||||
|
NerscIO::readConfiguration(U, header, fileName);
|
||||||
|
LOG(Message) << "NERSC header:" << std::endl;
|
||||||
|
dump_nersc_header(header, LOG(Message));
|
||||||
|
}
|
73
extras/Hadrons/Modules/MGauge/Load.hpp
Normal file
73
extras/Hadrons/Modules/MGauge/Load.hpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MGauge/Load.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Load_hpp_
|
||||||
|
#define Hadrons_Load_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Load a NERSC configuration *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MGauge)
|
||||||
|
|
||||||
|
class LoadPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(LoadPar,
|
||||||
|
std::string, file);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TLoad: public Module<LoadPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TLoad(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TLoad(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(Load, TLoad, MGauge);
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Load_hpp_
|
69
extras/Hadrons/Modules/MGauge/Random.cc
Normal file
69
extras/Hadrons/Modules/MGauge/Random.cc
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MGauge/Random.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Modules/MGauge/Random.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
using namespace MGauge;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRandom implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
TRandom::TRandom(const std::string name)
|
||||||
|
: Module<NoPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
std::vector<std::string> TRandom::getInput(void)
|
||||||
|
{
|
||||||
|
return std::vector<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> TRandom::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
void TRandom::setup(void)
|
||||||
|
{
|
||||||
|
env().registerLattice<LatticeGaugeField>(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
void TRandom::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Generating random gauge configuration" << std::endl;
|
||||||
|
LatticeGaugeField &U = *env().createLattice<LatticeGaugeField>(getName());
|
||||||
|
SU3::HotConfiguration(*env().get4dRng(), U);
|
||||||
|
}
|
66
extras/Hadrons/Modules/MGauge/Random.hpp
Normal file
66
extras/Hadrons/Modules/MGauge/Random.hpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MGauge/Random.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Random_hpp_
|
||||||
|
#define Hadrons_Random_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Random gauge *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MGauge)
|
||||||
|
|
||||||
|
class TRandom: public Module<NoPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TRandom(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TRandom(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(Random, TRandom, MGauge);
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Random_hpp_
|
69
extras/Hadrons/Modules/MGauge/Unit.cc
Normal file
69
extras/Hadrons/Modules/MGauge/Unit.cc
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MGauge/Unit.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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 <Grid/Hadrons/Modules/MGauge/Unit.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
using namespace MGauge;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TUnit implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
TUnit::TUnit(const std::string name)
|
||||||
|
: Module<NoPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
std::vector<std::string> TUnit::getInput(void)
|
||||||
|
{
|
||||||
|
return std::vector<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> TUnit::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
void TUnit::setup(void)
|
||||||
|
{
|
||||||
|
env().registerLattice<LatticeGaugeField>(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
void TUnit::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Creating unit gauge configuration" << std::endl;
|
||||||
|
LatticeGaugeField &U = *env().createLattice<LatticeGaugeField>(getName());
|
||||||
|
SU3::ColdConfiguration(*env().get4dRng(), U);
|
||||||
|
}
|
66
extras/Hadrons/Modules/MGauge/Unit.hpp
Normal file
66
extras/Hadrons/Modules/MGauge/Unit.hpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MGauge/Unit.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Unit_hpp_
|
||||||
|
#define Hadrons_Unit_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Unit gauge *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MGauge)
|
||||||
|
|
||||||
|
class TUnit: public Module<NoPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TUnit(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TUnit(void) = default;
|
||||||
|
// dependencies/products
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(Unit, TUnit, MGauge);
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Unit_hpp_
|
132
extras/Hadrons/Modules/MSolver/RBPrecCG.hpp
Normal file
132
extras/Hadrons/Modules/MSolver/RBPrecCG.hpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MSolver/RBPrecCG.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_RBPrecCG_hpp_
|
||||||
|
#define Hadrons_RBPrecCG_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Schur red-black preconditioned CG *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MSolver)
|
||||||
|
|
||||||
|
class RBPrecCGPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(RBPrecCGPar,
|
||||||
|
std::string, action,
|
||||||
|
double , residual);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TRBPrecCG: public Module<RBPrecCGPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TRBPrecCG(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TRBPrecCG(void) = default;
|
||||||
|
// dependencies/products
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(RBPrecCG, TRBPrecCG<FIMPL>, MSolver);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRBPrecCG template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TRBPrecCG<FImpl>::TRBPrecCG(const std::string name)
|
||||||
|
: Module(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TRBPrecCG<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().action};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TRBPrecCG<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TRBPrecCG<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
auto Ls = env().getObjectLs(par().action);
|
||||||
|
|
||||||
|
env().registerObject(getName(), 0, Ls);
|
||||||
|
env().addOwnership(getName(), par().action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TRBPrecCG<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
auto &mat = *(env().template getObject<FMat>(par().action));
|
||||||
|
auto solver = [&mat, this](FermionField &sol, const FermionField &source)
|
||||||
|
{
|
||||||
|
ConjugateGradient<FermionField> cg(par().residual, 10000);
|
||||||
|
SchurRedBlackDiagMooeeSolve<FermionField> schurSolver(cg);
|
||||||
|
|
||||||
|
schurSolver(mat, source, sol);
|
||||||
|
};
|
||||||
|
|
||||||
|
LOG(Message) << "setting up Schur red-black preconditioned CG for"
|
||||||
|
<< " action '" << par().action << "' with residual "
|
||||||
|
<< par().residual << std::endl;
|
||||||
|
env().setObject(getName(), new SolverFn(solver));
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_RBPrecCG_hpp_
|
135
extras/Hadrons/Modules/MSource/Point.hpp
Normal file
135
extras/Hadrons/Modules/MSource/Point.hpp
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MSource/Point.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Point_hpp_
|
||||||
|
#define Hadrons_Point_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Point source
|
||||||
|
------------
|
||||||
|
* src_x = delta_x,position
|
||||||
|
|
||||||
|
* options:
|
||||||
|
- position: space-separated integer sequence (e.g. "0 1 1 0")
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TPoint *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MSource)
|
||||||
|
|
||||||
|
class PointPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(PointPar,
|
||||||
|
std::string, position);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TPoint: public Module<PointPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TPoint(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TPoint(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(Point, TPoint<FIMPL>, MSource);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TPoint template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TPoint<FImpl>::TPoint(const std::string name)
|
||||||
|
: Module<PointPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TPoint<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TPoint<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TPoint<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
env().template registerLattice<PropagatorField>(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TPoint<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
std::vector<int> position = strToVec<int>(par().position);
|
||||||
|
typename SitePropagator::scalar_object id;
|
||||||
|
|
||||||
|
LOG(Message) << "Creating point source at position [" << par().position
|
||||||
|
<< "]" << std::endl;
|
||||||
|
PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
|
||||||
|
id = 1.;
|
||||||
|
src = zero;
|
||||||
|
pokeSite(id, src, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Point_hpp_
|
164
extras/Hadrons/Modules/MSource/SeqGamma.hpp
Normal file
164
extras/Hadrons/Modules/MSource/SeqGamma.hpp
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MSource/SeqGamma.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_SeqGamma_hpp_
|
||||||
|
#define Hadrons_SeqGamma_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Sequential source
|
||||||
|
-----------------------------
|
||||||
|
* src_x = q_x * theta(x_3 - tA) * theta(tB - x_3) * gamma * exp(i x.mom)
|
||||||
|
|
||||||
|
* options:
|
||||||
|
- q: input propagator (string)
|
||||||
|
- tA: begin timeslice (integer)
|
||||||
|
- tB: end timesilce (integer)
|
||||||
|
- gamma: gamma product to insert (integer)
|
||||||
|
- mom: momentum insertion, space-separated float sequence (e.g ".1 .2 1. 0.")
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* SeqGamma *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MSource)
|
||||||
|
|
||||||
|
class SeqGammaPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(SeqGammaPar,
|
||||||
|
std::string, q,
|
||||||
|
unsigned int, tA,
|
||||||
|
unsigned int, tB,
|
||||||
|
unsigned int, gamma,
|
||||||
|
std::string, mom);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TSeqGamma: public Module<SeqGammaPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TSeqGamma(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TSeqGamma(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(SeqGamma, TSeqGamma<FIMPL>, MSource);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TSeqGamma implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TSeqGamma<FImpl>::TSeqGamma(const std::string name)
|
||||||
|
: Module<SeqGammaPar>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TSeqGamma<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().q};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TSeqGamma<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TSeqGamma<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
env().template registerLattice<PropagatorField>(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TSeqGamma<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
if (par().tA == par().tB)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Generating gamma_" << par().gamma
|
||||||
|
<< " sequential source at t= " << par().tA << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(Message) << "Generating gamma_" << par().gamma
|
||||||
|
<< " sequential source for "
|
||||||
|
<< par().tA << " <= t <= " << par().tB << std::endl;
|
||||||
|
}
|
||||||
|
PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
|
||||||
|
PropagatorField &q = *env().template getObject<PropagatorField>(par().q);
|
||||||
|
Lattice<iScalar<vInteger>> t(env().getGrid());
|
||||||
|
LatticeComplex ph(env().getGrid()), coor(env().getGrid());
|
||||||
|
SpinMatrix g;
|
||||||
|
std::vector<Real> p;
|
||||||
|
Complex i(0.0,1.0);
|
||||||
|
|
||||||
|
g = makeGammaProd(par().gamma);
|
||||||
|
p = strToVec<Real>(par().mom);
|
||||||
|
ph = zero;
|
||||||
|
for(unsigned int mu = 0; mu < env().getNd(); mu++)
|
||||||
|
{
|
||||||
|
LatticeCoordinate(coor, mu);
|
||||||
|
ph = ph + p[mu]*coor;
|
||||||
|
}
|
||||||
|
ph = exp(i*ph);
|
||||||
|
LatticeCoordinate(t, Tp);
|
||||||
|
src = where((t >= par().tA) and (t <= par().tB), g*ph*q, 0.*q);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_SeqGamma_hpp_
|
151
extras/Hadrons/Modules/MSource/Z2.hpp
Normal file
151
extras/Hadrons/Modules/MSource/Z2.hpp
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/MSource/Z2.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Z2_hpp_
|
||||||
|
#define Hadrons_Z2_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Z_2 stochastic source
|
||||||
|
-----------------------------
|
||||||
|
* src_x = eta_x * theta(x_3 - tA) * theta(tB - x_3)
|
||||||
|
|
||||||
|
the eta_x are independent uniform random numbers in {+/- 1 +/- i}
|
||||||
|
|
||||||
|
* options:
|
||||||
|
- tA: begin timeslice (integer)
|
||||||
|
- tB: end timesilce (integer)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Z2 stochastic source *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(MSource)
|
||||||
|
|
||||||
|
class Z2Par: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(Z2Par,
|
||||||
|
unsigned int, tA,
|
||||||
|
unsigned int, tB);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TZ2: public Module<Z2Par>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TZ2(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TZ2(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(Z2, TZ2<FIMPL>, MSource);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TZ2 template implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TZ2<FImpl>::TZ2(const std::string name)
|
||||||
|
: Module<Z2Par>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TZ2<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TZ2<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TZ2<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
env().template registerLattice<PropagatorField>(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TZ2<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
Lattice<iScalar<vInteger>> t(env().getGrid());
|
||||||
|
LatticeComplex eta(env().getGrid());
|
||||||
|
Complex shift(1., 1.);
|
||||||
|
|
||||||
|
if (par().tA == par().tB)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Generating Z_2 wall source at t= " << par().tA
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG(Message) << "Generating Z_2 band for " << par().tA << " <= t <= "
|
||||||
|
<< par().tB << std::endl;
|
||||||
|
}
|
||||||
|
PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
|
||||||
|
LatticeCoordinate(t, Tp);
|
||||||
|
bernoulli(*env().get4dRng(), eta);
|
||||||
|
eta = (2.*eta - shift)*(1./::sqrt(2.));
|
||||||
|
eta = where((t >= par().tA) and (t <= par().tB), eta, 0.*eta);
|
||||||
|
src = 1.;
|
||||||
|
src = src*eta;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Z2_hpp_
|
185
extras/Hadrons/Modules/Quark.hpp
Normal file
185
extras/Hadrons/Modules/Quark.hpp
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: extras/Hadrons/Modules/Quark.hpp
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
Copyright (C) 2016
|
||||||
|
|
||||||
|
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_Quark_hpp_
|
||||||
|
#define Hadrons_Quark_hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TQuark *
|
||||||
|
******************************************************************************/
|
||||||
|
class QuarkPar: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(QuarkPar,
|
||||||
|
std::string, source,
|
||||||
|
std::string, solver);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class TQuark: public Module<QuarkPar>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TYPE_ALIASES(FImpl,);
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
TQuark(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~TQuark(void) = default;
|
||||||
|
// dependencies/products
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
private:
|
||||||
|
unsigned int Ls_;
|
||||||
|
SolverFn *solver_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER(Quark, TQuark<FIMPL>);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TQuark implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
TQuark<FImpl>::TQuark(const std::string name)
|
||||||
|
: Module(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TQuark<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in = {par().source, par().solver};
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> TQuark<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName(), getName() + "_5d"};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TQuark<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
Ls_ = env().getObjectLs(par().solver);
|
||||||
|
env().template registerLattice<PropagatorField>(getName());
|
||||||
|
if (Ls_ > 1)
|
||||||
|
{
|
||||||
|
env().template registerLattice<PropagatorField>(getName() + "_5d", Ls_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void TQuark<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Computing quark propagator '" << getName() << "'"
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
FermionField source(env().getGrid(Ls_)), sol(env().getGrid(Ls_)),
|
||||||
|
tmp(env().getGrid());
|
||||||
|
std::string propName = (Ls_ == 1) ? getName() : (getName() + "_5d");
|
||||||
|
PropagatorField &prop = *env().template createLattice<PropagatorField>(propName);
|
||||||
|
PropagatorField &fullSrc = *env().template getObject<PropagatorField>(par().source);
|
||||||
|
SolverFn &solver = *env().template getObject<SolverFn>(par().solver);
|
||||||
|
if (Ls_ > 1)
|
||||||
|
{
|
||||||
|
env().template createLattice<PropagatorField>(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(Message) << "Inverting using solver '" << par().solver
|
||||||
|
<< "' on source '" << par().source << "'" << std::endl;
|
||||||
|
for (unsigned int s = 0; s < Ns; ++s)
|
||||||
|
for (unsigned int c = 0; c < Nc; ++c)
|
||||||
|
{
|
||||||
|
LOG(Message) << "Inversion for spin= " << s << ", color= " << c
|
||||||
|
<< std::endl;
|
||||||
|
// source conversion for 4D sources
|
||||||
|
if (!env().isObject5d(par().source))
|
||||||
|
{
|
||||||
|
if (Ls_ == 1)
|
||||||
|
{
|
||||||
|
PropToFerm(source, fullSrc, s, c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
source = zero;
|
||||||
|
PropToFerm(tmp, fullSrc, s, c);
|
||||||
|
InsertSlice(tmp, source, 0, 0);
|
||||||
|
InsertSlice(tmp, source, Ls_-1, 0);
|
||||||
|
axpby_ssp_pplus(source, 0., source, 1., source, 0, 0);
|
||||||
|
axpby_ssp_pminus(source, 0., source, 1., source, Ls_-1, Ls_-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// source conversion for 5D sources
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Ls_ != env().getObjectLs(par().source))
|
||||||
|
{
|
||||||
|
HADRON_ERROR("Ls mismatch between quark action and source");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PropToFerm(source, fullSrc, s, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sol = zero;
|
||||||
|
solver(sol, source);
|
||||||
|
FermToProp(prop, sol, s, c);
|
||||||
|
// create 4D propagators from 5D one if necessary
|
||||||
|
if (Ls_ > 1)
|
||||||
|
{
|
||||||
|
PropagatorField &p4d =
|
||||||
|
*env().template getObject<PropagatorField>(getName());
|
||||||
|
|
||||||
|
axpby_ssp_pminus(sol, 0., sol, 1., sol, 0, 0);
|
||||||
|
axpby_ssp_pplus(sol, 0., sol, 1., sol, 0, Ls_-1);
|
||||||
|
ExtractSlice(tmp, sol, 0, 0);
|
||||||
|
FermToProp(p4d, tmp, s, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons_Quark_hpp_
|
39
extras/Hadrons/Modules/templates/Module.cc.template
Normal file
39
extras/Hadrons/Modules/templates/Module.cc.template
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include <Grid/Hadrons/Modules/___FILEBASENAME___.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* T___FILEBASENAME___ implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
T___FILEBASENAME___::T___FILEBASENAME___(const std::string name)
|
||||||
|
: Module<___FILEBASENAME___Par>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
std::vector<std::string> T___FILEBASENAME___::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> T___FILEBASENAME___::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
void T___FILEBASENAME___::setup(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
void T___FILEBASENAME___::execute(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
40
extras/Hadrons/Modules/templates/Module.hpp.template
Normal file
40
extras/Hadrons/Modules/templates/Module.hpp.template
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef Hadrons____FILEBASENAME____hpp_
|
||||||
|
#define Hadrons____FILEBASENAME____hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* ___FILEBASENAME___ *
|
||||||
|
******************************************************************************/
|
||||||
|
class ___FILEBASENAME___Par: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par,
|
||||||
|
unsigned int, i);
|
||||||
|
};
|
||||||
|
|
||||||
|
class T___FILEBASENAME___: public Module<___FILEBASENAME___Par>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
T___FILEBASENAME___(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~T___FILEBASENAME___(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER(___FILEBASENAME___, T___FILEBASENAME___);
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons____FILEBASENAME____hpp_
|
40
extras/Hadrons/Modules/templates/Module_in_NS.cc.template
Normal file
40
extras/Hadrons/Modules/templates/Module_in_NS.cc.template
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include <Grid/Hadrons/Modules/___NAMESPACE___/___FILEBASENAME___.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
using namespace ___NAMESPACE___;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* T___FILEBASENAME___ implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
T___FILEBASENAME___::T___FILEBASENAME___(const std::string name)
|
||||||
|
: Module<___FILEBASENAME___Par>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
std::vector<std::string> T___FILEBASENAME___::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> T___FILEBASENAME___::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
void T___FILEBASENAME___::setup(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
void T___FILEBASENAME___::execute(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
44
extras/Hadrons/Modules/templates/Module_in_NS.hpp.template
Normal file
44
extras/Hadrons/Modules/templates/Module_in_NS.hpp.template
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef Hadrons____FILEBASENAME____hpp_
|
||||||
|
#define Hadrons____FILEBASENAME____hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* ___FILEBASENAME___ *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(___NAMESPACE___)
|
||||||
|
|
||||||
|
class ___FILEBASENAME___Par: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par,
|
||||||
|
unsigned int, i);
|
||||||
|
};
|
||||||
|
|
||||||
|
class T___FILEBASENAME___: public Module<___FILEBASENAME___Par>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
T___FILEBASENAME___(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~T___FILEBASENAME___(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(___FILEBASENAME___, T___FILEBASENAME___, ___NAMESPACE___);
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons____FILEBASENAME____hpp_
|
81
extras/Hadrons/Modules/templates/Module_tmp.hpp.template
Normal file
81
extras/Hadrons/Modules/templates/Module_tmp.hpp.template
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#ifndef Hadrons____FILEBASENAME____hpp_
|
||||||
|
#define Hadrons____FILEBASENAME____hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* ___FILEBASENAME___ *
|
||||||
|
******************************************************************************/
|
||||||
|
class ___FILEBASENAME___Par: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par,
|
||||||
|
unsigned int, i);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class T___FILEBASENAME___: public Module<___FILEBASENAME___Par>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
T___FILEBASENAME___(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~T___FILEBASENAME___(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER(___FILEBASENAME___, T___FILEBASENAME___<FIMPL>);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* T___FILEBASENAME___ implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
T___FILEBASENAME___<FImpl>::T___FILEBASENAME___(const std::string name)
|
||||||
|
: Module<___FILEBASENAME___Par>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> T___FILEBASENAME___<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> T___FILEBASENAME___<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void T___FILEBASENAME___<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void T___FILEBASENAME___<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons____FILEBASENAME____hpp_
|
@ -0,0 +1,85 @@
|
|||||||
|
#ifndef Hadrons____FILEBASENAME____hpp_
|
||||||
|
#define Hadrons____FILEBASENAME____hpp_
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Global.hpp>
|
||||||
|
#include <Grid/Hadrons/Module.hpp>
|
||||||
|
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||||
|
|
||||||
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* ___FILEBASENAME___ *
|
||||||
|
******************************************************************************/
|
||||||
|
BEGIN_MODULE_NAMESPACE(___NAMESPACE___)
|
||||||
|
|
||||||
|
class ___FILEBASENAME___Par: Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par,
|
||||||
|
unsigned int, i);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
class T___FILEBASENAME___: public Module<___FILEBASENAME___Par>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
T___FILEBASENAME___(const std::string name);
|
||||||
|
// destructor
|
||||||
|
virtual ~T___FILEBASENAME___(void) = default;
|
||||||
|
// dependency relation
|
||||||
|
virtual std::vector<std::string> getInput(void);
|
||||||
|
virtual std::vector<std::string> getOutput(void);
|
||||||
|
// setup
|
||||||
|
virtual void setup(void);
|
||||||
|
// execution
|
||||||
|
virtual void execute(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_REGISTER_NS(___FILEBASENAME___, T___FILEBASENAME___<FIMPL>, ___NAMESPACE___);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* T___FILEBASENAME___ implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
T___FILEBASENAME___<FImpl>::T___FILEBASENAME___(const std::string name)
|
||||||
|
: Module<___FILEBASENAME___Par>(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// dependencies/products ///////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> T___FILEBASENAME___<FImpl>::getInput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> in;
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FImpl>
|
||||||
|
std::vector<std::string> T___FILEBASENAME___<FImpl>::getOutput(void)
|
||||||
|
{
|
||||||
|
std::vector<std::string> out = {getName()};
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup ///////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void T___FILEBASENAME___<FImpl>::setup(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution ///////////////////////////////////////////////////////////////////
|
||||||
|
template <typename FImpl>
|
||||||
|
void T___FILEBASENAME___<FImpl>::execute(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
END_MODULE_NAMESPACE
|
||||||
|
|
||||||
|
END_HADRONS_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Hadrons____FILEBASENAME____hpp_
|
31
extras/Hadrons/add_module.sh
Executable file
31
extras/Hadrons/add_module.sh
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if (( $# != 1 && $# != 2)); then
|
||||||
|
echo "usage: `basename $0` <module name> [<namespace>]" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
NAME=$1
|
||||||
|
NS=$2
|
||||||
|
|
||||||
|
if (( $# == 1 )); then
|
||||||
|
if [ -e "Modules/${NAME}.cc" ] || [ -e "Modules/${NAME}.hpp" ]; then
|
||||||
|
echo "error: files Modules/${NAME}.* already exists" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module.cc.template > Modules/${NAME}.cc
|
||||||
|
sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module.hpp.template > Modules/${NAME}.hpp
|
||||||
|
elif (( $# == 2 )); then
|
||||||
|
mkdir -p Modules/${NS}
|
||||||
|
if [ -e "Modules/${NS}/${NAME}.cc" ] || [ -e "Modules/${NS}/${NAME}.hpp" ]; then
|
||||||
|
echo "error: files Modules/${NS}/${NAME}.* already exists" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
TMPCC=".${NS}.${NAME}.tmp.cc"
|
||||||
|
TMPHPP=".${NS}.${NAME}.tmp.hpp"
|
||||||
|
sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_in_NS.cc.template > ${TMPCC}
|
||||||
|
sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_in_NS.hpp.template > ${TMPHPP}
|
||||||
|
sed "s/___NAMESPACE___/${NS}/g" ${TMPCC} > Modules/${NS}/${NAME}.cc
|
||||||
|
sed "s/___NAMESPACE___/${NS}/g" ${TMPHPP} > Modules/${NS}/${NAME}.hpp
|
||||||
|
rm -f ${TMPCC} ${TMPHPP}
|
||||||
|
fi
|
||||||
|
./make_module_list.sh
|
28
extras/Hadrons/add_module_template.sh
Executable file
28
extras/Hadrons/add_module_template.sh
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if (( $# != 1 && $# != 2)); then
|
||||||
|
echo "usage: `basename $0` <module name> [<namespace>]" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
NAME=$1
|
||||||
|
NS=$2
|
||||||
|
|
||||||
|
if (( $# == 1 )); then
|
||||||
|
if [ -e "Modules/${NAME}.cc" ] || [ -e "Modules/${NAME}.hpp" ]; then
|
||||||
|
echo "error: files Modules/${NAME}.* already exists" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_tmp.hpp.template > Modules/${NAME}.hpp
|
||||||
|
elif (( $# == 2 )); then
|
||||||
|
mkdir -p Modules/${NS}
|
||||||
|
if [ -e "Modules/${NS}/${NAME}.cc" ] || [ -e "Modules/${NS}/${NAME}.hpp" ]; then
|
||||||
|
echo "error: files Modules/${NS}/${NAME}.* already exists" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
TMPCC=".${NS}.${NAME}.tmp.cc"
|
||||||
|
TMPHPP=".${NS}.${NAME}.tmp.hpp"
|
||||||
|
sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_tmp_in_NS.hpp.template > ${TMPHPP}
|
||||||
|
sed "s/___NAMESPACE___/${NS}/g" ${TMPHPP} > Modules/${NS}/${NAME}.hpp
|
||||||
|
rm -f ${TMPCC} ${TMPHPP}
|
||||||
|
fi
|
||||||
|
./make_module_list.sh
|
12
extras/Hadrons/make_module_list.sh
Executable file
12
extras/Hadrons/make_module_list.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
echo 'modules_cc =\' > modules.inc
|
||||||
|
find Modules -name '*.cc' -type f -print | sed 's/^/ /;$q;s/$/ \\/' >> modules.inc
|
||||||
|
echo '' >> modules.inc
|
||||||
|
echo 'modules_hpp =\' >> modules.inc
|
||||||
|
find Modules -name '*.hpp' -type f -print | sed 's/^/ /;$q;s/$/ \\/' >> modules.inc
|
||||||
|
echo '' >> modules.inc
|
||||||
|
rm -f Modules.hpp
|
||||||
|
for f in `find Modules -name '*.hpp'`; do
|
||||||
|
echo "#include <Grid/Hadrons/${f}>" >> Modules.hpp
|
||||||
|
done
|
19
extras/Hadrons/modules.inc
Normal file
19
extras/Hadrons/modules.inc
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
modules_cc =\
|
||||||
|
Modules/MGauge/Load.cc \
|
||||||
|
Modules/MGauge/Random.cc \
|
||||||
|
Modules/MGauge/Unit.cc
|
||||||
|
|
||||||
|
modules_hpp =\
|
||||||
|
Modules/MAction/DWF.hpp \
|
||||||
|
Modules/MAction/Wilson.hpp \
|
||||||
|
Modules/MContraction/Baryon.hpp \
|
||||||
|
Modules/MContraction/Meson.hpp \
|
||||||
|
Modules/MGauge/Load.hpp \
|
||||||
|
Modules/MGauge/Random.hpp \
|
||||||
|
Modules/MGauge/Unit.hpp \
|
||||||
|
Modules/MSolver/RBPrecCG.hpp \
|
||||||
|
Modules/MSource/Point.hpp \
|
||||||
|
Modules/MSource/SeqGamma.hpp \
|
||||||
|
Modules/MSource/Z2.hpp \
|
||||||
|
Modules/Quark.hpp
|
||||||
|
|
1
extras/Makefile.am
Normal file
1
extras/Makefile.am
Normal file
@ -0,0 +1 @@
|
|||||||
|
SUBDIRS = Hadrons
|
65
lib/AlignedAllocator.cc
Normal file
65
lib/AlignedAllocator.cc
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
namespace Grid {
|
||||||
|
|
||||||
|
int PointerCache::victim;
|
||||||
|
|
||||||
|
PointerCache::PointerCacheEntry PointerCache::Entries[PointerCache::Ncache];
|
||||||
|
|
||||||
|
void *PointerCache::Insert(void *ptr,size_t bytes) {
|
||||||
|
|
||||||
|
if (bytes < 4096 ) return NULL;
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
assert(omp_in_parallel()==0);
|
||||||
|
#endif
|
||||||
|
void * ret = NULL;
|
||||||
|
int v = -1;
|
||||||
|
|
||||||
|
for(int e=0;e<Ncache;e++) {
|
||||||
|
if ( Entries[e].valid==0 ) {
|
||||||
|
v=e;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( v==-1 ) {
|
||||||
|
v=victim;
|
||||||
|
victim = (victim+1)%Ncache;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( Entries[v].valid ) {
|
||||||
|
ret = Entries[v].address;
|
||||||
|
Entries[v].valid = 0;
|
||||||
|
Entries[v].address = NULL;
|
||||||
|
Entries[v].bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entries[v].address=ptr;
|
||||||
|
Entries[v].bytes =bytes;
|
||||||
|
Entries[v].valid =1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *PointerCache::Lookup(size_t bytes) {
|
||||||
|
|
||||||
|
if (bytes < 4096 ) return NULL;
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
assert(omp_in_parallel()==0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(int e=0;e<Ncache;e++){
|
||||||
|
if ( Entries[e].valid && ( Entries[e].bytes == bytes ) ) {
|
||||||
|
Entries[e].valid = 0;
|
||||||
|
return Entries[e].address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/*************************************************************************************
|
/*************************************************************************************
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
@ -42,9 +42,32 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
|
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
|
||||||
|
class PointerCache {
|
||||||
|
private:
|
||||||
|
|
||||||
|
static const int Ncache=8;
|
||||||
|
static int victim;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *address;
|
||||||
|
size_t bytes;
|
||||||
|
int valid;
|
||||||
|
} PointerCacheEntry;
|
||||||
|
|
||||||
|
static PointerCacheEntry Entries[Ncache];
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
static void *Insert(void *ptr,size_t bytes) ;
|
||||||
|
static void *Lookup(size_t bytes) ;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// A lattice of something, but assume the something is SIMDized.
|
// A lattice of something, but assume the something is SIMDized.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
class alignedAllocator {
|
class alignedAllocator {
|
||||||
public:
|
public:
|
||||||
@ -66,27 +89,27 @@ public:
|
|||||||
|
|
||||||
pointer allocate(size_type __n, const void* _p= 0)
|
pointer allocate(size_type __n, const void* _p= 0)
|
||||||
{
|
{
|
||||||
|
size_type bytes = __n*sizeof(_Tp);
|
||||||
|
|
||||||
|
_Tp *ptr = (_Tp *) PointerCache::Lookup(bytes);
|
||||||
|
|
||||||
#ifdef HAVE_MM_MALLOC_H
|
#ifdef HAVE_MM_MALLOC_H
|
||||||
_Tp * ptr = (_Tp *) _mm_malloc(__n*sizeof(_Tp),128);
|
if ( ptr == (_Tp *) NULL ) ptr = (_Tp *) _mm_malloc(bytes,128);
|
||||||
#else
|
#else
|
||||||
_Tp * ptr = (_Tp *) memalign(128,__n*sizeof(_Tp));
|
if ( ptr == (_Tp *) NULL ) ptr = (_Tp *) memalign(128,bytes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_Tp tmp;
|
|
||||||
#ifdef GRID_NUMA
|
|
||||||
#pragma omp parallel for schedule(static)
|
|
||||||
for(int i=0;i<__n;i++){
|
|
||||||
ptr[i]=tmp;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(pointer __p, size_type) {
|
void deallocate(pointer __p, size_type __n) {
|
||||||
|
size_type bytes = __n * sizeof(_Tp);
|
||||||
|
pointer __freeme = (pointer)PointerCache::Insert((void *)__p,bytes);
|
||||||
|
|
||||||
#ifdef HAVE_MM_MALLOC_H
|
#ifdef HAVE_MM_MALLOC_H
|
||||||
_mm_free((void *)__p);
|
if ( __freeme ) _mm_free((void *)__freeme);
|
||||||
#else
|
#else
|
||||||
free((void *)__p);
|
if ( __freeme ) free((void *)__freeme);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void construct(pointer __p, const _Tp& __val) { };
|
void construct(pointer __p, const _Tp& __val) { };
|
||||||
|
@ -59,13 +59,13 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
///////////////////
|
///////////////////
|
||||||
// Grid headers
|
// Grid headers
|
||||||
///////////////////
|
///////////////////
|
||||||
#include <Grid/serialisation/Serialisation.h>
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include <Grid/Timer.h>
|
#include <Grid/Timer.h>
|
||||||
#include <Grid/PerfCount.h>
|
#include <Grid/PerfCount.h>
|
||||||
#include <Grid/Log.h>
|
#include <Grid/Log.h>
|
||||||
#include <Grid/AlignedAllocator.h>
|
#include <Grid/AlignedAllocator.h>
|
||||||
#include <Grid/Simd.h>
|
#include <Grid/Simd.h>
|
||||||
|
#include <Grid/serialisation/Serialisation.h>
|
||||||
#include <Grid/Threads.h>
|
#include <Grid/Threads.h>
|
||||||
#include <Grid/Lexicographic.h>
|
#include <Grid/Lexicographic.h>
|
||||||
#include <Grid/Init.h>
|
#include <Grid/Init.h>
|
||||||
|
1
lib/Hadrons
Symbolic link
1
lib/Hadrons
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../extras/Hadrons
|
@ -110,8 +110,8 @@ public:
|
|||||||
friend std::ostream& operator<< (std::ostream& stream, Logger& log){
|
friend std::ostream& operator<< (std::ostream& stream, Logger& log){
|
||||||
|
|
||||||
if ( log.active ) {
|
if ( log.active ) {
|
||||||
stream << log.background()<< log.topName << log.background()<< " : ";
|
stream << log.background()<< std::setw(10) << std::left << log.topName << log.background()<< " : ";
|
||||||
stream << log.colour() <<std::setw(14) << std::left << log.name << log.background() << " : ";
|
stream << log.colour() << std::setw(14) << std::left << log.name << log.background() << " : ";
|
||||||
if ( log.timestamp ) {
|
if ( log.timestamp ) {
|
||||||
StopWatch.Stop();
|
StopWatch.Stop();
|
||||||
GridTime now = StopWatch.Elapsed();
|
GridTime now = StopWatch.Elapsed();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
extra_sources=
|
extra_sources=
|
||||||
|
extra_headers=
|
||||||
if BUILD_COMMS_MPI
|
if BUILD_COMMS_MPI
|
||||||
extra_sources+=communicator/Communicator_mpi.cc
|
extra_sources+=communicator/Communicator_mpi.cc
|
||||||
extra_sources+=communicator/Communicator_base.cc
|
extra_sources+=communicator/Communicator_base.cc
|
||||||
@ -24,6 +25,12 @@ if BUILD_COMMS_NONE
|
|||||||
extra_sources+=communicator/Communicator_base.cc
|
extra_sources+=communicator/Communicator_base.cc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BUILD_HDF5
|
||||||
|
extra_sources+=serialisation/Hdf5IO.cc
|
||||||
|
extra_headers+=serialisation/Hdf5IO.h
|
||||||
|
extra_headers+=serialisation/Hdf5Type.h
|
||||||
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# Libraries
|
# Libraries
|
||||||
#
|
#
|
||||||
@ -32,6 +39,9 @@ include Eigen.inc
|
|||||||
|
|
||||||
lib_LIBRARIES = libGrid.a
|
lib_LIBRARIES = libGrid.a
|
||||||
|
|
||||||
libGrid_a_SOURCES = $(CCFILES) $(extra_sources)
|
CCFILES += $(extra_sources)
|
||||||
|
HFILES += $(extra_headers)
|
||||||
|
|
||||||
|
libGrid_a_SOURCES = $(CCFILES)
|
||||||
libGrid_adir = $(pkgincludedir)
|
libGrid_adir = $(pkgincludedir)
|
||||||
nobase_dist_pkginclude_HEADERS = $(HFILES) $(eigen_files) Config.h
|
nobase_dist_pkginclude_HEADERS = $(HFILES) $(eigen_files) Config.h
|
||||||
|
@ -205,12 +205,13 @@ public:
|
|||||||
void Stop(void) {
|
void Stop(void) {
|
||||||
count=0;
|
count=0;
|
||||||
cycles=0;
|
cycles=0;
|
||||||
|
size_t ign;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if ( fd!= -1) {
|
if ( fd!= -1) {
|
||||||
::ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
|
::ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
|
||||||
::ioctl(cyclefd, PERF_EVENT_IOC_DISABLE, 0);
|
::ioctl(cyclefd, PERF_EVENT_IOC_DISABLE, 0);
|
||||||
::read(fd, &count, sizeof(long long));
|
ign=::read(fd, &count, sizeof(long long));
|
||||||
::read(cyclefd, &cycles, sizeof(long long));
|
ign=::read(cyclefd, &cycles, sizeof(long long));
|
||||||
}
|
}
|
||||||
elapsed = cyclecount() - begin;
|
elapsed = cyclecount() - begin;
|
||||||
#else
|
#else
|
||||||
|
@ -113,7 +113,7 @@ Gather_plane_simple_table (std::vector<std::pair<int,int> >& table,const Lattice
|
|||||||
{
|
{
|
||||||
PARALLEL_FOR_LOOP
|
PARALLEL_FOR_LOOP
|
||||||
for(int i=0;i<table.size();i++){
|
for(int i=0;i<table.size();i++){
|
||||||
buffer[off+table[i].first]=compress(rhs._odata[so+table[i].second]);
|
vstream(buffer[off+table[i].first],compress(rhs._odata[so+table[i].second]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,11 +46,13 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
#endif
|
#endif
|
||||||
#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for collapse(2)")
|
#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for collapse(2)")
|
||||||
#define PARALLEL_REGION _Pragma("omp parallel")
|
#define PARALLEL_REGION _Pragma("omp parallel")
|
||||||
|
#define PARALLEL_CRITICAL _Pragma("omp critical")
|
||||||
#else
|
#else
|
||||||
#define PARALLEL_FOR_LOOP
|
#define PARALLEL_FOR_LOOP
|
||||||
#define PARALLEL_FOR_LOOP_INTERN
|
#define PARALLEL_FOR_LOOP_INTERN
|
||||||
#define PARALLEL_NESTED_LOOP2
|
#define PARALLEL_NESTED_LOOP2
|
||||||
#define PARALLEL_REGION
|
#define PARALLEL_REGION
|
||||||
|
#define PARALLEL_CRITICAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
@ -386,7 +386,7 @@ void InsertSlice(Lattice<vobj> &lowDim,Lattice<vobj> & higherDim,int slice, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the above should guarantee that the operations are local
|
// the above should guarantee that the operations are local
|
||||||
//PARALLEL_FOR_LOOP
|
PARALLEL_FOR_LOOP
|
||||||
for(int idx=0;idx<lg->lSites();idx++){
|
for(int idx=0;idx<lg->lSites();idx++){
|
||||||
std::vector<int> lcoor(nl);
|
std::vector<int> lcoor(nl);
|
||||||
std::vector<int> hcoor(nh);
|
std::vector<int> hcoor(nh);
|
||||||
@ -428,7 +428,7 @@ void ExtractSlice(Lattice<vobj> &lowDim, Lattice<vobj> & higherDim,int slice, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// the above should guarantee that the operations are local
|
// the above should guarantee that the operations are local
|
||||||
//PARALLEL_FOR_LOOP
|
PARALLEL_FOR_LOOP
|
||||||
for(int idx=0;idx<lg->lSites();idx++){
|
for(int idx=0;idx<lg->lSites();idx++){
|
||||||
std::vector<int> lcoor(nl);
|
std::vector<int> lcoor(nl);
|
||||||
std::vector<int> hcoor(nh);
|
std::vector<int> hcoor(nh);
|
||||||
|
@ -29,6 +29,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
*************************************************************************************/
|
*************************************************************************************/
|
||||||
/* END LEGAL */
|
/* END LEGAL */
|
||||||
|
|
||||||
|
#include <Grid/Eigen/Dense>
|
||||||
#include <Grid.h>
|
#include <Grid.h>
|
||||||
|
|
||||||
|
|
||||||
@ -48,18 +49,18 @@ namespace QCD {
|
|||||||
FourDimGrid,
|
FourDimGrid,
|
||||||
FourDimRedBlackGrid,_M5,p),
|
FourDimRedBlackGrid,_M5,p),
|
||||||
mass(_mass)
|
mass(_mass)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
void CayleyFermion5D<Impl>::Dminus(const FermionField &psi, FermionField &chi)
|
void CayleyFermion5D<Impl>::Dminus(const FermionField &psi, FermionField &chi)
|
||||||
{
|
{
|
||||||
int Ls=this->Ls;
|
int Ls=this->Ls;
|
||||||
FermionField tmp(psi._grid);
|
|
||||||
|
|
||||||
this->DW(psi,tmp,DaggerNo);
|
this->DW(psi,this->tmp(),DaggerNo);
|
||||||
|
|
||||||
for(int s=0;s<Ls;s++){
|
for(int s=0;s<Ls;s++){
|
||||||
axpby_ssp(chi,Coeff_t(1.0),psi,-cs[s],tmp,s,s);// chi = (1-c[s] D_W) psi
|
axpby_ssp(chi,Coeff_t(1.0),psi,-cs[s],this->tmp(),s,s);// chi = (1-c[s] D_W) psi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,8 +88,8 @@ template<class Impl> void CayleyFermion5D<Impl>::CayleyReport(void)
|
|||||||
std::cout << GridLogMessage << "CayleyFermion5D Number of MooeeInv Calls : " << MooeeInvCalls << std::endl;
|
std::cout << GridLogMessage << "CayleyFermion5D Number of MooeeInv Calls : " << MooeeInvCalls << std::endl;
|
||||||
std::cout << GridLogMessage << "CayleyFermion5D ComputeTime/Calls : " << MooeeInvTime / MooeeInvCalls << " us" << std::endl;
|
std::cout << GridLogMessage << "CayleyFermion5D ComputeTime/Calls : " << MooeeInvTime / MooeeInvCalls << " us" << std::endl;
|
||||||
|
|
||||||
// Flops = 9*12*Ls*vol/2
|
// Flops = MADD * Ls *Ls *4dvol * spin/colour/complex
|
||||||
RealD mflops = 9.0*12*volume*MooeeInvCalls/MooeeInvTime/2; // 2 for red black counting
|
RealD mflops = 2.0*24*this->Ls*volume*MooeeInvCalls/MooeeInvTime/2; // 2 for red black counting
|
||||||
std::cout << GridLogMessage << "Average mflops/s per call : " << mflops << std::endl;
|
std::cout << GridLogMessage << "Average mflops/s per call : " << mflops << std::endl;
|
||||||
std::cout << GridLogMessage << "Average mflops/s per call per rank : " << mflops/NP << std::endl;
|
std::cout << GridLogMessage << "Average mflops/s per call per rank : " << mflops/NP << std::endl;
|
||||||
}
|
}
|
||||||
@ -110,12 +111,11 @@ template<class Impl>
|
|||||||
void CayleyFermion5D<Impl>::DminusDag(const FermionField &psi, FermionField &chi)
|
void CayleyFermion5D<Impl>::DminusDag(const FermionField &psi, FermionField &chi)
|
||||||
{
|
{
|
||||||
int Ls=this->Ls;
|
int Ls=this->Ls;
|
||||||
FermionField tmp(psi._grid);
|
|
||||||
|
|
||||||
this->DW(psi,tmp,DaggerYes);
|
this->DW(psi,this->tmp(),DaggerYes);
|
||||||
|
|
||||||
for(int s=0;s<Ls;s++){
|
for(int s=0;s<Ls;s++){
|
||||||
axpby_ssp(chi,Coeff_t(1.0),psi,-cs[s],tmp,s,s);// chi = (1-c[s] D_W) psi
|
axpby_ssp(chi,Coeff_t(1.0),psi,-cs[s],this->tmp(),s,s);// chi = (1-c[s] D_W) psi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
@ -138,6 +138,7 @@ void CayleyFermion5D<Impl>::Meooe5D (const FermionField &psi, FermionField &D
|
|||||||
lower[0] =-mass*lower[0];
|
lower[0] =-mass*lower[0];
|
||||||
M5D(psi,psi,Din,lower,diag,upper);
|
M5D(psi,psi,Din,lower,diag,upper);
|
||||||
}
|
}
|
||||||
|
// FIXME Redunant with the above routine; check this and eliminate
|
||||||
template<class Impl> void CayleyFermion5D<Impl>::Meo5D (const FermionField &psi, FermionField &chi)
|
template<class Impl> void CayleyFermion5D<Impl>::Meo5D (const FermionField &psi, FermionField &chi)
|
||||||
{
|
{
|
||||||
int Ls=this->Ls;
|
int Ls=this->Ls;
|
||||||
@ -259,36 +260,33 @@ template<class Impl>
|
|||||||
void CayleyFermion5D<Impl>::Meooe (const FermionField &psi, FermionField &chi)
|
void CayleyFermion5D<Impl>::Meooe (const FermionField &psi, FermionField &chi)
|
||||||
{
|
{
|
||||||
int Ls=this->Ls;
|
int Ls=this->Ls;
|
||||||
FermionField tmp(psi._grid);
|
|
||||||
|
|
||||||
Meooe5D(psi,tmp);
|
Meooe5D(psi,this->tmp());
|
||||||
|
|
||||||
if ( psi.checkerboard == Odd ) {
|
if ( psi.checkerboard == Odd ) {
|
||||||
this->DhopEO(tmp,chi,DaggerNo);
|
this->DhopEO(this->tmp(),chi,DaggerNo);
|
||||||
} else {
|
} else {
|
||||||
this->DhopOE(tmp,chi,DaggerNo);
|
this->DhopOE(this->tmp(),chi,DaggerNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
void CayleyFermion5D<Impl>::MeooeDag (const FermionField &psi, FermionField &chi)
|
void CayleyFermion5D<Impl>::MeooeDag (const FermionField &psi, FermionField &chi)
|
||||||
{
|
{
|
||||||
FermionField tmp(psi._grid);
|
|
||||||
// Apply 4d dslash
|
// Apply 4d dslash
|
||||||
if ( psi.checkerboard == Odd ) {
|
if ( psi.checkerboard == Odd ) {
|
||||||
this->DhopEO(psi,tmp,DaggerYes);
|
this->DhopEO(psi,this->tmp(),DaggerYes);
|
||||||
} else {
|
} else {
|
||||||
this->DhopOE(psi,tmp,DaggerYes);
|
this->DhopOE(psi,this->tmp(),DaggerYes);
|
||||||
}
|
}
|
||||||
MeooeDag5D(tmp,chi);
|
MeooeDag5D(this->tmp(),chi);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
void CayleyFermion5D<Impl>::Mdir (const FermionField &psi, FermionField &chi,int dir,int disp){
|
void CayleyFermion5D<Impl>::Mdir (const FermionField &psi, FermionField &chi,int dir,int disp){
|
||||||
FermionField tmp(psi._grid);
|
Meo5D(psi,this->tmp());
|
||||||
Meo5D(psi,tmp);
|
|
||||||
// Apply 4d dslash fragment
|
// Apply 4d dslash fragment
|
||||||
this->DhopDir(tmp,chi,dir,disp);
|
this->DhopDir(this->tmp(),chi,dir,disp);
|
||||||
}
|
}
|
||||||
// force terms; five routines; default to Dhop on diagonal
|
// force terms; five routines; default to Dhop on diagonal
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
@ -459,9 +457,91 @@ void CayleyFermion5D<Impl>::SetCoefficientsInternal(RealD zolo_hi,std::vector<Co
|
|||||||
for(int j=0;j<Ls-1;j++) delta_d *= cee[j]/bee[j];
|
for(int j=0;j<Ls-1;j++) delta_d *= cee[j]/bee[j];
|
||||||
dee[Ls-1] += delta_d;
|
dee[Ls-1] += delta_d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int inv=1;
|
||||||
|
this->MooeeInternalCompute(0,inv,MatpInv,MatmInv);
|
||||||
|
this->MooeeInternalCompute(1,inv,MatpInvDag,MatmInvDag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Impl>
|
||||||
|
void CayleyFermion5D<Impl>::MooeeInternalCompute(int dag, int inv,
|
||||||
|
Vector<iSinglet<Simd> > & Matp,
|
||||||
|
Vector<iSinglet<Simd> > & Matm)
|
||||||
|
{
|
||||||
|
int Ls=this->Ls;
|
||||||
|
|
||||||
|
GridBase *grid = this->FermionRedBlackGrid();
|
||||||
|
int LLs = grid->_rdimensions[0];
|
||||||
|
|
||||||
|
if ( LLs == Ls ) return; // Not vectorised in 5th direction
|
||||||
|
|
||||||
|
Eigen::MatrixXcd Pplus = Eigen::MatrixXcd::Zero(Ls,Ls);
|
||||||
|
Eigen::MatrixXcd Pminus = Eigen::MatrixXcd::Zero(Ls,Ls);
|
||||||
|
|
||||||
|
for(int s=0;s<Ls;s++){
|
||||||
|
Pplus(s,s) = bee[s];
|
||||||
|
Pminus(s,s)= bee[s];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int s=0;s<Ls-1;s++){
|
||||||
|
Pminus(s,s+1) = -cee[s];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int s=0;s<Ls-1;s++){
|
||||||
|
Pplus(s+1,s) = -cee[s+1];
|
||||||
|
}
|
||||||
|
Pplus (0,Ls-1) = mass*cee[0];
|
||||||
|
Pminus(Ls-1,0) = mass*cee[Ls-1];
|
||||||
|
|
||||||
|
Eigen::MatrixXcd PplusMat ;
|
||||||
|
Eigen::MatrixXcd PminusMat;
|
||||||
|
|
||||||
|
if ( inv ) {
|
||||||
|
PplusMat =Pplus.inverse();
|
||||||
|
PminusMat=Pminus.inverse();
|
||||||
|
} else {
|
||||||
|
PplusMat =Pplus;
|
||||||
|
PminusMat=Pminus;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dag){
|
||||||
|
PplusMat.adjointInPlace();
|
||||||
|
PminusMat.adjointInPlace();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename SiteHalfSpinor::scalar_type scalar_type;
|
||||||
|
const int Nsimd=Simd::Nsimd();
|
||||||
|
Matp.resize(Ls*LLs);
|
||||||
|
Matm.resize(Ls*LLs);
|
||||||
|
|
||||||
|
for(int s2=0;s2<Ls;s2++){
|
||||||
|
for(int s1=0;s1<LLs;s1++){
|
||||||
|
int istride = LLs;
|
||||||
|
int ostride = 1;
|
||||||
|
Simd Vp;
|
||||||
|
Simd Vm;
|
||||||
|
scalar_type *sp = (scalar_type *)&Vp;
|
||||||
|
scalar_type *sm = (scalar_type *)&Vm;
|
||||||
|
for(int l=0;l<Nsimd;l++){
|
||||||
|
if ( switcheroo<Coeff_t>::iscomplex() ) {
|
||||||
|
sp[l] = PplusMat (l*istride+s1*ostride,s2);
|
||||||
|
sm[l] = PminusMat(l*istride+s1*ostride,s2);
|
||||||
|
} else {
|
||||||
|
// if real
|
||||||
|
scalar_type tmp;
|
||||||
|
tmp = PplusMat (l*istride+s1*ostride,s2);
|
||||||
|
sp[l] = scalar_type(tmp.real(),tmp.real());
|
||||||
|
tmp = PminusMat(l*istride+s1*ostride,s2);
|
||||||
|
sm[l] = scalar_type(tmp.real(),tmp.real());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Matp[LLs*s2+s1] = Vp;
|
||||||
|
Matm[LLs*s2+s1] = Vm;
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FermOpTemplateInstantiate(CayleyFermion5D);
|
FermOpTemplateInstantiate(CayleyFermion5D);
|
||||||
GparityFermOpTemplateInstantiate(CayleyFermion5D);
|
GparityFermOpTemplateInstantiate(CayleyFermion5D);
|
||||||
|
@ -33,6 +33,31 @@ namespace Grid {
|
|||||||
|
|
||||||
namespace QCD {
|
namespace QCD {
|
||||||
|
|
||||||
|
template<typename T> struct switcheroo {
|
||||||
|
static inline int iscomplex() { return 0; }
|
||||||
|
|
||||||
|
template<class vec>
|
||||||
|
static inline vec mult(vec a, vec b) {
|
||||||
|
return real_mult(a,b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct switcheroo<ComplexD> {
|
||||||
|
static inline int iscomplex() { return 1; }
|
||||||
|
|
||||||
|
template<class vec>
|
||||||
|
static inline vec mult(vec a, vec b) {
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<> struct switcheroo<ComplexF> {
|
||||||
|
static inline int iscomplex() { return 1; }
|
||||||
|
template<class vec>
|
||||||
|
static inline vec mult(vec a, vec b) {
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
class CayleyFermion5D : public WilsonFermion5D<Impl>
|
class CayleyFermion5D : public WilsonFermion5D<Impl>
|
||||||
{
|
{
|
||||||
@ -75,7 +100,19 @@ namespace Grid {
|
|||||||
std::vector<Coeff_t> &lower,
|
std::vector<Coeff_t> &lower,
|
||||||
std::vector<Coeff_t> &diag,
|
std::vector<Coeff_t> &diag,
|
||||||
std::vector<Coeff_t> &upper);
|
std::vector<Coeff_t> &upper);
|
||||||
|
|
||||||
void MooeeInternal(const FermionField &in, FermionField &out,int dag,int inv);
|
void MooeeInternal(const FermionField &in, FermionField &out,int dag,int inv);
|
||||||
|
void MooeeInternalCompute(int dag, int inv, Vector<iSinglet<Simd> > & Matp, Vector<iSinglet<Simd> > & Matm);
|
||||||
|
|
||||||
|
void MooeeInternalAsm(const FermionField &in, FermionField &out,
|
||||||
|
int LLs, int site,
|
||||||
|
Vector<iSinglet<Simd> > &Matp,
|
||||||
|
Vector<iSinglet<Simd> > &Matm);
|
||||||
|
void MooeeInternalZAsm(const FermionField &in, FermionField &out,
|
||||||
|
int LLs, int site,
|
||||||
|
Vector<iSinglet<Simd> > &Matp,
|
||||||
|
Vector<iSinglet<Simd> > &Matm);
|
||||||
|
|
||||||
|
|
||||||
virtual void Instantiatable(void)=0;
|
virtual void Instantiatable(void)=0;
|
||||||
|
|
||||||
@ -112,6 +149,12 @@ namespace Grid {
|
|||||||
std::vector<Coeff_t> ueem;
|
std::vector<Coeff_t> ueem;
|
||||||
std::vector<Coeff_t> dee;
|
std::vector<Coeff_t> dee;
|
||||||
|
|
||||||
|
// Matrices of 5d ee inverse params
|
||||||
|
Vector<iSinglet<Simd> > MatpInv;
|
||||||
|
Vector<iSinglet<Simd> > MatmInv;
|
||||||
|
Vector<iSinglet<Simd> > MatpInvDag;
|
||||||
|
Vector<iSinglet<Simd> > MatmInvDag;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
CayleyFermion5D(GaugeField &_Umu,
|
CayleyFermion5D(GaugeField &_Umu,
|
||||||
GridCartesian &FiveDimGrid,
|
GridCartesian &FiveDimGrid,
|
||||||
|
@ -29,13 +29,12 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
*************************************************************************************/
|
*************************************************************************************/
|
||||||
/* END LEGAL */
|
/* END LEGAL */
|
||||||
|
|
||||||
#include <Grid/Eigen/Dense>
|
|
||||||
#include <Grid.h>
|
#include <Grid.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
namespace QCD {
|
namespace QCD { /*
|
||||||
/*
|
|
||||||
* Dense matrix versions of routines
|
* Dense matrix versions of routines
|
||||||
*/
|
*/
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
@ -126,7 +125,6 @@ PARALLEL_FOR_LOOP
|
|||||||
for(int v=0;v<LLs;v++){
|
for(int v=0;v<LLs;v++){
|
||||||
|
|
||||||
vprefetch(psi[ss+v+LLs]);
|
vprefetch(psi[ss+v+LLs]);
|
||||||
// vprefetch(phi[ss+v+LLs]);
|
|
||||||
|
|
||||||
int vp= (v==LLs-1) ? 0 : v+1;
|
int vp= (v==LLs-1) ? 0 : v+1;
|
||||||
int vm= (v==0 ) ? LLs-1 : v-1;
|
int vm= (v==0 ) ? LLs-1 : v-1;
|
||||||
@ -145,9 +143,6 @@ PARALLEL_FOR_LOOP
|
|||||||
Simd hm_11 = psi[ss+vm]()(1)(1);
|
Simd hm_11 = psi[ss+vm]()(1)(1);
|
||||||
Simd hm_12 = psi[ss+vm]()(1)(2);
|
Simd hm_12 = psi[ss+vm]()(1)(2);
|
||||||
|
|
||||||
// if ( ss==0) std::cout << " hp_00 " <<hp_00<<std::endl;
|
|
||||||
// if ( ss==0) std::cout << " hm_00 " <<hm_00<<std::endl;
|
|
||||||
|
|
||||||
if ( vp<=v ) {
|
if ( vp<=v ) {
|
||||||
hp_00.v = Optimization::Rotate::tRotate<2>(hp_00.v);
|
hp_00.v = Optimization::Rotate::tRotate<2>(hp_00.v);
|
||||||
hp_01.v = Optimization::Rotate::tRotate<2>(hp_01.v);
|
hp_01.v = Optimization::Rotate::tRotate<2>(hp_01.v);
|
||||||
@ -165,42 +160,20 @@ PARALLEL_FOR_LOOP
|
|||||||
hm_12.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_12.v);
|
hm_12.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_12.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Can force these to real arithmetic and save 2x.
|
||||||
if ( ss==0) std::cout << " dphi_00 " <<d[v]()()() * phi[ss+v]()(0)(0) <<std::endl;
|
Simd p_00 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_00);
|
||||||
if ( ss==0) std::cout << " dphi_10 " <<d[v]()()() * phi[ss+v]()(1)(0) <<std::endl;
|
Simd p_01 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_01);
|
||||||
if ( ss==0) std::cout << " dphi_20 " <<d[v]()()() * phi[ss+v]()(2)(0) <<std::endl;
|
Simd p_02 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_02);
|
||||||
if ( ss==0) std::cout << " dphi_30 " <<d[v]()()() * phi[ss+v]()(3)(0) <<std::endl;
|
Simd p_10 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_10);
|
||||||
*/
|
Simd p_11 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_11);
|
||||||
Simd p_00 = d[v]()()() * phi[ss+v]()(0)(0) + l[v]()()()*hm_00;
|
Simd p_12 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_12);
|
||||||
Simd p_01 = d[v]()()() * phi[ss+v]()(0)(1) + l[v]()()()*hm_01;
|
Simd p_20 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_00);
|
||||||
Simd p_02 = d[v]()()() * phi[ss+v]()(0)(2) + l[v]()()()*hm_02;
|
Simd p_21 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_01);
|
||||||
Simd p_10 = d[v]()()() * phi[ss+v]()(1)(0) + l[v]()()()*hm_10;
|
Simd p_22 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_02);
|
||||||
Simd p_11 = d[v]()()() * phi[ss+v]()(1)(1) + l[v]()()()*hm_11;
|
Simd p_30 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_10);
|
||||||
Simd p_12 = d[v]()()() * phi[ss+v]()(1)(2) + l[v]()()()*hm_12;
|
Simd p_31 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_11);
|
||||||
Simd p_20 = d[v]()()() * phi[ss+v]()(2)(0) + u[v]()()()*hp_00;
|
Simd p_32 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_12);
|
||||||
Simd p_21 = d[v]()()() * phi[ss+v]()(2)(1) + u[v]()()()*hp_01;
|
|
||||||
Simd p_22 = d[v]()()() * phi[ss+v]()(2)(2) + u[v]()()()*hp_02;
|
|
||||||
Simd p_30 = d[v]()()() * phi[ss+v]()(3)(0) + u[v]()()()*hp_10;
|
|
||||||
Simd p_31 = d[v]()()() * phi[ss+v]()(3)(1) + u[v]()()()*hp_11;
|
|
||||||
Simd p_32 = d[v]()()() * phi[ss+v]()(3)(2) + u[v]()()()*hp_12;
|
|
||||||
|
|
||||||
|
|
||||||
// if ( ss==0){
|
|
||||||
/*
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(0)(0) << " bad "<<p_00<<" diff "<<chi[ss+v]()(0)(0)-p_00<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(0)(1) << " bad "<<p_01<<" diff "<<chi[ss+v]()(0)(1)-p_01<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(0)(2) << " bad "<<p_02<<" diff "<<chi[ss+v]()(0)(2)-p_02<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(1)(0) << " bad "<<p_10<<" diff "<<chi[ss+v]()(1)(0)-p_10<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(1)(1) << " bad "<<p_11<<" diff "<<chi[ss+v]()(1)(1)-p_11<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(1)(2) << " bad "<<p_12<<" diff "<<chi[ss+v]()(1)(2)-p_12<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(2)(0) << " bad "<<p_20<<" diff "<<chi[ss+v]()(2)(0)-p_20<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(2)(1) << " bad "<<p_21<<" diff "<<chi[ss+v]()(2)(1)-p_21<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(2)(2) << " bad "<<p_22<<" diff "<<chi[ss+v]()(2)(2)-p_22<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(3)(0) << " bad "<<p_30<<" diff "<<chi[ss+v]()(3)(0)-p_30<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(3)(1) << " bad "<<p_31<<" diff "<<chi[ss+v]()(3)(1)-p_31<<std::endl;
|
|
||||||
std::cout << ss<<" "<< v<< " good "<< chi[ss+v]()(3)(2) << " bad "<<p_32<<" diff "<<chi[ss+v]()(3)(2)-p_32<<std::endl;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
vstream(chi[ss+v]()(0)(0),p_00);
|
vstream(chi[ss+v]()(0)(0),p_00);
|
||||||
vstream(chi[ss+v]()(0)(1),p_01);
|
vstream(chi[ss+v]()(0)(1),p_01);
|
||||||
vstream(chi[ss+v]()(0)(2),p_02);
|
vstream(chi[ss+v]()(0)(2),p_02);
|
||||||
@ -261,7 +234,7 @@ void CayleyFermion5D<Impl>::M5Ddag(const FermionField &psi,
|
|||||||
M5Dtime-=usecond();
|
M5Dtime-=usecond();
|
||||||
PARALLEL_FOR_LOOP
|
PARALLEL_FOR_LOOP
|
||||||
for(int ss=0;ss<grid->oSites();ss+=LLs){ // adds LLs
|
for(int ss=0;ss<grid->oSites();ss+=LLs){ // adds LLs
|
||||||
|
#if 0
|
||||||
alignas(64) SiteHalfSpinor hp;
|
alignas(64) SiteHalfSpinor hp;
|
||||||
alignas(64) SiteHalfSpinor hm;
|
alignas(64) SiteHalfSpinor hm;
|
||||||
alignas(64) SiteSpinor fp;
|
alignas(64) SiteSpinor fp;
|
||||||
@ -287,9 +260,504 @@ PARALLEL_FOR_LOOP
|
|||||||
chi[ss+v] = chi[ss+v] +l[v]*fm;
|
chi[ss+v] = chi[ss+v] +l[v]*fm;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
for(int v=0;v<LLs;v++){
|
||||||
|
|
||||||
|
vprefetch(psi[ss+v+LLs]);
|
||||||
|
|
||||||
|
int vp= (v==LLs-1) ? 0 : v+1;
|
||||||
|
int vm= (v==0 ) ? LLs-1 : v-1;
|
||||||
|
|
||||||
|
Simd hp_00 = psi[ss+vp]()(0)(0);
|
||||||
|
Simd hp_01 = psi[ss+vp]()(0)(1);
|
||||||
|
Simd hp_02 = psi[ss+vp]()(0)(2);
|
||||||
|
Simd hp_10 = psi[ss+vp]()(1)(0);
|
||||||
|
Simd hp_11 = psi[ss+vp]()(1)(1);
|
||||||
|
Simd hp_12 = psi[ss+vp]()(1)(2);
|
||||||
|
|
||||||
|
Simd hm_00 = psi[ss+vm]()(2)(0);
|
||||||
|
Simd hm_01 = psi[ss+vm]()(2)(1);
|
||||||
|
Simd hm_02 = psi[ss+vm]()(2)(2);
|
||||||
|
Simd hm_10 = psi[ss+vm]()(3)(0);
|
||||||
|
Simd hm_11 = psi[ss+vm]()(3)(1);
|
||||||
|
Simd hm_12 = psi[ss+vm]()(3)(2);
|
||||||
|
|
||||||
|
if ( vp<=v ) {
|
||||||
|
hp_00.v = Optimization::Rotate::tRotate<2>(hp_00.v);
|
||||||
|
hp_01.v = Optimization::Rotate::tRotate<2>(hp_01.v);
|
||||||
|
hp_02.v = Optimization::Rotate::tRotate<2>(hp_02.v);
|
||||||
|
hp_10.v = Optimization::Rotate::tRotate<2>(hp_10.v);
|
||||||
|
hp_11.v = Optimization::Rotate::tRotate<2>(hp_11.v);
|
||||||
|
hp_12.v = Optimization::Rotate::tRotate<2>(hp_12.v);
|
||||||
|
}
|
||||||
|
if ( vm>=v ) {
|
||||||
|
hm_00.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_00.v);
|
||||||
|
hm_01.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_01.v);
|
||||||
|
hm_02.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_02.v);
|
||||||
|
hm_10.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_10.v);
|
||||||
|
hm_11.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_11.v);
|
||||||
|
hm_12.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_12.v);
|
||||||
|
}
|
||||||
|
|
||||||
|
Simd p_00 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_00);
|
||||||
|
Simd p_01 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_01);
|
||||||
|
Simd p_02 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(0)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_02);
|
||||||
|
Simd p_10 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(0)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_10);
|
||||||
|
Simd p_11 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(1)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_11);
|
||||||
|
Simd p_12 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(1)(2)) + switcheroo<Coeff_t>::mult(u[v]()()(),hp_12);
|
||||||
|
|
||||||
|
Simd p_20 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_00);
|
||||||
|
Simd p_21 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_01);
|
||||||
|
Simd p_22 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(2)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_02);
|
||||||
|
Simd p_30 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(0)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_10);
|
||||||
|
Simd p_31 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(1)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_11);
|
||||||
|
Simd p_32 = switcheroo<Coeff_t>::mult(d[v]()()(), phi[ss+v]()(3)(2)) + switcheroo<Coeff_t>::mult(l[v]()()(),hm_12);
|
||||||
|
|
||||||
|
vstream(chi[ss+v]()(0)(0),p_00);
|
||||||
|
vstream(chi[ss+v]()(0)(1),p_01);
|
||||||
|
vstream(chi[ss+v]()(0)(2),p_02);
|
||||||
|
vstream(chi[ss+v]()(1)(0),p_10);
|
||||||
|
vstream(chi[ss+v]()(1)(1),p_11);
|
||||||
|
vstream(chi[ss+v]()(1)(2),p_12);
|
||||||
|
vstream(chi[ss+v]()(2)(0),p_20);
|
||||||
|
vstream(chi[ss+v]()(2)(1),p_21);
|
||||||
|
vstream(chi[ss+v]()(2)(2),p_22);
|
||||||
|
vstream(chi[ss+v]()(3)(0),p_30);
|
||||||
|
vstream(chi[ss+v]()(3)(1),p_31);
|
||||||
|
vstream(chi[ss+v]()(3)(2),p_32);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
M5Dtime+=usecond();
|
M5Dtime+=usecond();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef AVX512
|
||||||
|
#include <simd/Intel512common.h>
|
||||||
|
#include <simd/Intel512avx.h>
|
||||||
|
#include <simd/Intel512single.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<class Impl>
|
||||||
|
void CayleyFermion5D<Impl>::MooeeInternalAsm(const FermionField &psi, FermionField &chi,
|
||||||
|
int LLs, int site,
|
||||||
|
Vector<iSinglet<Simd> > &Matp,
|
||||||
|
Vector<iSinglet<Simd> > &Matm)
|
||||||
|
{
|
||||||
|
#ifndef AVX512
|
||||||
|
{
|
||||||
|
SiteHalfSpinor BcastP;
|
||||||
|
SiteHalfSpinor BcastM;
|
||||||
|
SiteHalfSpinor SiteChiP;
|
||||||
|
SiteHalfSpinor SiteChiM;
|
||||||
|
|
||||||
|
// Ls*Ls * 2 * 12 * vol flops
|
||||||
|
for(int s1=0;s1<LLs;s1++){
|
||||||
|
for(int s2=0;s2<LLs;s2++){
|
||||||
|
for(int l=0; l<Simd::Nsimd();l++){ // simd lane
|
||||||
|
|
||||||
|
int s=s2+l*LLs;
|
||||||
|
int lex=s2+LLs*site;
|
||||||
|
|
||||||
|
if ( s2==0 && l==0) {
|
||||||
|
SiteChiP=zero;
|
||||||
|
SiteChiM=zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int sp=0;sp<2;sp++){
|
||||||
|
for(int co=0;co<Nc;co++){
|
||||||
|
vbroadcast(BcastP()(sp )(co),psi[lex]()(sp)(co),l);
|
||||||
|
}}
|
||||||
|
for(int sp=0;sp<2;sp++){
|
||||||
|
for(int co=0;co<Nc;co++){
|
||||||
|
vbroadcast(BcastM()(sp )(co),psi[lex]()(sp+2)(co),l);
|
||||||
|
}}
|
||||||
|
|
||||||
|
for(int sp=0;sp<2;sp++){
|
||||||
|
for(int co=0;co<Nc;co++){
|
||||||
|
SiteChiP()(sp)(co)=real_madd(Matp[LLs*s+s1]()()(),BcastP()(sp)(co),SiteChiP()(sp)(co)); // 1100 us.
|
||||||
|
SiteChiM()(sp)(co)=real_madd(Matm[LLs*s+s1]()()(),BcastM()(sp)(co),SiteChiM()(sp)(co)); // each found by commenting out
|
||||||
|
}}
|
||||||
|
|
||||||
|
}}
|
||||||
|
{
|
||||||
|
int lex = s1+LLs*site;
|
||||||
|
for(int sp=0;sp<2;sp++){
|
||||||
|
for(int co=0;co<Nc;co++){
|
||||||
|
vstream(chi[lex]()(sp)(co), SiteChiP()(sp)(co));
|
||||||
|
vstream(chi[lex]()(sp+2)(co), SiteChiM()(sp)(co));
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
// pointers
|
||||||
|
// MASK_REGS;
|
||||||
|
#define Chi_00 %%zmm1
|
||||||
|
#define Chi_01 %%zmm2
|
||||||
|
#define Chi_02 %%zmm3
|
||||||
|
#define Chi_10 %%zmm4
|
||||||
|
#define Chi_11 %%zmm5
|
||||||
|
#define Chi_12 %%zmm6
|
||||||
|
#define Chi_20 %%zmm7
|
||||||
|
#define Chi_21 %%zmm8
|
||||||
|
#define Chi_22 %%zmm9
|
||||||
|
#define Chi_30 %%zmm10
|
||||||
|
#define Chi_31 %%zmm11
|
||||||
|
#define Chi_32 %%zmm12
|
||||||
|
|
||||||
|
#define BCAST0 %%zmm13
|
||||||
|
#define BCAST1 %%zmm14
|
||||||
|
#define BCAST2 %%zmm15
|
||||||
|
#define BCAST3 %%zmm16
|
||||||
|
#define BCAST4 %%zmm17
|
||||||
|
#define BCAST5 %%zmm18
|
||||||
|
#define BCAST6 %%zmm19
|
||||||
|
#define BCAST7 %%zmm20
|
||||||
|
#define BCAST8 %%zmm21
|
||||||
|
#define BCAST9 %%zmm22
|
||||||
|
#define BCAST10 %%zmm23
|
||||||
|
#define BCAST11 %%zmm24
|
||||||
|
|
||||||
|
int incr=LLs*LLs*sizeof(iSinglet<Simd>);
|
||||||
|
for(int s1=0;s1<LLs;s1++){
|
||||||
|
for(int s2=0;s2<LLs;s2++){
|
||||||
|
int lex=s2+LLs*site;
|
||||||
|
uint64_t a0 = (uint64_t)&Matp[LLs*s2+s1]; // should be cacheable
|
||||||
|
uint64_t a1 = (uint64_t)&Matm[LLs*s2+s1];
|
||||||
|
uint64_t a2 = (uint64_t)&psi[lex];
|
||||||
|
for(int l=0; l<Simd::Nsimd();l++){ // simd lane
|
||||||
|
if ( (s2+l)==0 ) {
|
||||||
|
asm (
|
||||||
|
VPREFETCH1(0,%2) VPREFETCH1(0,%1)
|
||||||
|
VPREFETCH1(12,%2) VPREFETCH1(13,%2)
|
||||||
|
VPREFETCH1(14,%2) VPREFETCH1(15,%2)
|
||||||
|
VBCASTCDUP(0,%2,BCAST0)
|
||||||
|
VBCASTCDUP(1,%2,BCAST1)
|
||||||
|
VBCASTCDUP(2,%2,BCAST2)
|
||||||
|
VBCASTCDUP(3,%2,BCAST3)
|
||||||
|
VBCASTCDUP(4,%2,BCAST4) VMULMEM (0,%0,BCAST0,Chi_00)
|
||||||
|
VBCASTCDUP(5,%2,BCAST5) VMULMEM (0,%0,BCAST1,Chi_01)
|
||||||
|
VBCASTCDUP(6,%2,BCAST6) VMULMEM (0,%0,BCAST2,Chi_02)
|
||||||
|
VBCASTCDUP(7,%2,BCAST7) VMULMEM (0,%0,BCAST3,Chi_10)
|
||||||
|
VBCASTCDUP(8,%2,BCAST8) VMULMEM (0,%0,BCAST4,Chi_11)
|
||||||
|
VBCASTCDUP(9,%2,BCAST9) VMULMEM (0,%0,BCAST5,Chi_12)
|
||||||
|
VBCASTCDUP(10,%2,BCAST10) VMULMEM (0,%1,BCAST6,Chi_20)
|
||||||
|
VBCASTCDUP(11,%2,BCAST11) VMULMEM (0,%1,BCAST7,Chi_21)
|
||||||
|
VMULMEM (0,%1,BCAST8,Chi_22)
|
||||||
|
VMULMEM (0,%1,BCAST9,Chi_30)
|
||||||
|
VMULMEM (0,%1,BCAST10,Chi_31)
|
||||||
|
VMULMEM (0,%1,BCAST11,Chi_32)
|
||||||
|
: : "r" (a0), "r" (a1), "r" (a2) );
|
||||||
|
} else {
|
||||||
|
asm (
|
||||||
|
VBCASTCDUP(0,%2,BCAST0) VMADDMEM (0,%0,BCAST0,Chi_00)
|
||||||
|
VBCASTCDUP(1,%2,BCAST1) VMADDMEM (0,%0,BCAST1,Chi_01)
|
||||||
|
VBCASTCDUP(2,%2,BCAST2) VMADDMEM (0,%0,BCAST2,Chi_02)
|
||||||
|
VBCASTCDUP(3,%2,BCAST3) VMADDMEM (0,%0,BCAST3,Chi_10)
|
||||||
|
VBCASTCDUP(4,%2,BCAST4) VMADDMEM (0,%0,BCAST4,Chi_11)
|
||||||
|
VBCASTCDUP(5,%2,BCAST5) VMADDMEM (0,%0,BCAST5,Chi_12)
|
||||||
|
VBCASTCDUP(6,%2,BCAST6) VMADDMEM (0,%1,BCAST6,Chi_20)
|
||||||
|
VBCASTCDUP(7,%2,BCAST7) VMADDMEM (0,%1,BCAST7,Chi_21)
|
||||||
|
VBCASTCDUP(8,%2,BCAST8) VMADDMEM (0,%1,BCAST8,Chi_22)
|
||||||
|
VBCASTCDUP(9,%2,BCAST9) VMADDMEM (0,%1,BCAST9,Chi_30)
|
||||||
|
VBCASTCDUP(10,%2,BCAST10) VMADDMEM (0,%1,BCAST10,Chi_31)
|
||||||
|
VBCASTCDUP(11,%2,BCAST11) VMADDMEM (0,%1,BCAST11,Chi_32)
|
||||||
|
: : "r" (a0), "r" (a1), "r" (a2) );
|
||||||
|
}
|
||||||
|
a0 = a0+incr;
|
||||||
|
a1 = a1+incr;
|
||||||
|
a2 = a2+sizeof(Simd::scalar_type);
|
||||||
|
}}
|
||||||
|
{
|
||||||
|
int lexa = s1+LLs*site;
|
||||||
|
asm (
|
||||||
|
VSTORE(0,%0,Chi_00) VSTORE(1 ,%0,Chi_01) VSTORE(2 ,%0,Chi_02)
|
||||||
|
VSTORE(3,%0,Chi_10) VSTORE(4 ,%0,Chi_11) VSTORE(5 ,%0,Chi_12)
|
||||||
|
VSTORE(6,%0,Chi_20) VSTORE(7 ,%0,Chi_21) VSTORE(8 ,%0,Chi_22)
|
||||||
|
VSTORE(9,%0,Chi_30) VSTORE(10,%0,Chi_31) VSTORE(11,%0,Chi_32)
|
||||||
|
: : "r" ((uint64_t)&chi[lexa]) : "memory" );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef Chi_00
|
||||||
|
#undef Chi_01
|
||||||
|
#undef Chi_02
|
||||||
|
#undef Chi_10
|
||||||
|
#undef Chi_11
|
||||||
|
#undef Chi_12
|
||||||
|
#undef Chi_20
|
||||||
|
#undef Chi_21
|
||||||
|
#undef Chi_22
|
||||||
|
#undef Chi_30
|
||||||
|
#undef Chi_31
|
||||||
|
#undef Chi_32
|
||||||
|
|
||||||
|
#undef BCAST0
|
||||||
|
#undef BCAST1
|
||||||
|
#undef BCAST2
|
||||||
|
#undef BCAST3
|
||||||
|
#undef BCAST4
|
||||||
|
#undef BCAST5
|
||||||
|
#undef BCAST6
|
||||||
|
#undef BCAST7
|
||||||
|
#undef BCAST8
|
||||||
|
#undef BCAST9
|
||||||
|
#undef BCAST10
|
||||||
|
#undef BCAST11
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// Z-mobius version
|
||||||
|
template<class Impl>
|
||||||
|
void CayleyFermion5D<Impl>::MooeeInternalZAsm(const FermionField &psi, FermionField &chi,
|
||||||
|
int LLs, int site, Vector<iSinglet<Simd> > &Matp, Vector<iSinglet<Simd> > &Matm)
|
||||||
|
{
|
||||||
|
#ifndef AVX512
|
||||||
|
{
|
||||||
|
SiteHalfSpinor BcastP;
|
||||||
|
SiteHalfSpinor BcastM;
|
||||||
|
SiteHalfSpinor SiteChiP;
|
||||||
|
SiteHalfSpinor SiteChiM;
|
||||||
|
|
||||||
|
// Ls*Ls * 2 * 12 * vol flops
|
||||||
|
for(int s1=0;s1<LLs;s1++){
|
||||||
|
for(int s2=0;s2<LLs;s2++){
|
||||||
|
for(int l=0; l<Simd::Nsimd();l++){ // simd lane
|
||||||
|
|
||||||
|
int s=s2+l*LLs;
|
||||||
|
int lex=s2+LLs*site;
|
||||||
|
|
||||||
|
if ( s2==0 && l==0) {
|
||||||
|
SiteChiP=zero;
|
||||||
|
SiteChiM=zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int sp=0;sp<2;sp++){
|
||||||
|
for(int co=0;co<Nc;co++){
|
||||||
|
vbroadcast(BcastP()(sp )(co),psi[lex]()(sp)(co),l);
|
||||||
|
}}
|
||||||
|
for(int sp=0;sp<2;sp++){
|
||||||
|
for(int co=0;co<Nc;co++){
|
||||||
|
vbroadcast(BcastM()(sp )(co),psi[lex]()(sp+2)(co),l);
|
||||||
|
}}
|
||||||
|
|
||||||
|
for(int sp=0;sp<2;sp++){
|
||||||
|
for(int co=0;co<Nc;co++){
|
||||||
|
SiteChiP()(sp)(co)=SiteChiP()(sp)(co)+ Matp[LLs*s+s1]()()()*BcastP()(sp)(co);
|
||||||
|
SiteChiM()(sp)(co)=SiteChiM()(sp)(co)+ Matm[LLs*s+s1]()()()*BcastM()(sp)(co);
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
}}
|
||||||
|
{
|
||||||
|
int lex = s1+LLs*site;
|
||||||
|
for(int sp=0;sp<2;sp++){
|
||||||
|
for(int co=0;co<Nc;co++){
|
||||||
|
vstream(chi[lex]()(sp)(co), SiteChiP()(sp)(co));
|
||||||
|
vstream(chi[lex]()(sp+2)(co), SiteChiM()(sp)(co));
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
// pointers
|
||||||
|
// MASK_REGS;
|
||||||
|
#define Chi_00 %zmm0
|
||||||
|
#define Chi_01 %zmm1
|
||||||
|
#define Chi_02 %zmm2
|
||||||
|
#define Chi_10 %zmm3
|
||||||
|
#define Chi_11 %zmm4
|
||||||
|
#define Chi_12 %zmm5
|
||||||
|
#define Chi_20 %zmm6
|
||||||
|
#define Chi_21 %zmm7
|
||||||
|
#define Chi_22 %zmm8
|
||||||
|
#define Chi_30 %zmm9
|
||||||
|
#define Chi_31 %zmm10
|
||||||
|
#define Chi_32 %zmm11
|
||||||
|
#define pChi_00 %%zmm0
|
||||||
|
#define pChi_01 %%zmm1
|
||||||
|
#define pChi_02 %%zmm2
|
||||||
|
#define pChi_10 %%zmm3
|
||||||
|
#define pChi_11 %%zmm4
|
||||||
|
#define pChi_12 %%zmm5
|
||||||
|
#define pChi_20 %%zmm6
|
||||||
|
#define pChi_21 %%zmm7
|
||||||
|
#define pChi_22 %%zmm8
|
||||||
|
#define pChi_30 %%zmm9
|
||||||
|
#define pChi_31 %%zmm10
|
||||||
|
#define pChi_32 %%zmm11
|
||||||
|
|
||||||
|
#define BCAST_00 %zmm12
|
||||||
|
#define SHUF_00 %zmm13
|
||||||
|
#define BCAST_01 %zmm14
|
||||||
|
#define SHUF_01 %zmm15
|
||||||
|
#define BCAST_02 %zmm16
|
||||||
|
#define SHUF_02 %zmm17
|
||||||
|
#define BCAST_10 %zmm18
|
||||||
|
#define SHUF_10 %zmm19
|
||||||
|
#define BCAST_11 %zmm20
|
||||||
|
#define SHUF_11 %zmm21
|
||||||
|
#define BCAST_12 %zmm22
|
||||||
|
#define SHUF_12 %zmm23
|
||||||
|
|
||||||
|
#define Mp %zmm24
|
||||||
|
#define Mps %zmm25
|
||||||
|
#define Mm %zmm26
|
||||||
|
#define Mms %zmm27
|
||||||
|
#define N 8
|
||||||
|
int incr=LLs*LLs*sizeof(iSinglet<Simd>);
|
||||||
|
for(int s1=0;s1<LLs;s1++){
|
||||||
|
for(int s2=0;s2<LLs;s2++){
|
||||||
|
int lex=s2+LLs*site;
|
||||||
|
uint64_t a0 = (uint64_t)&Matp[LLs*s2+s1]; // should be cacheable
|
||||||
|
uint64_t a1 = (uint64_t)&Matm[LLs*s2+s1];
|
||||||
|
uint64_t a2 = (uint64_t)&psi[lex];
|
||||||
|
for(int l=0; l<Simd::Nsimd();l++){ // simd lane
|
||||||
|
if ( (s2+l)==0 ) {
|
||||||
|
LOAD64(%r8,a0);
|
||||||
|
LOAD64(%r9,a1);
|
||||||
|
LOAD64(%r10,a2);
|
||||||
|
asm (
|
||||||
|
VLOAD(0,%r8,Mp)// i r
|
||||||
|
VLOAD(0,%r9,Mm)
|
||||||
|
VSHUF(Mp,Mps) // r i
|
||||||
|
VSHUF(Mm,Mms)
|
||||||
|
VPREFETCH1(12,%r10) VPREFETCH1(13,%r10)
|
||||||
|
VPREFETCH1(14,%r10) VPREFETCH1(15,%r10)
|
||||||
|
|
||||||
|
VMULIDUP(0*N,%r10,Mps,Chi_00)
|
||||||
|
VMULIDUP(1*N,%r10,Mps,Chi_01)
|
||||||
|
VMULIDUP(2*N,%r10,Mps,Chi_02)
|
||||||
|
VMULIDUP(3*N,%r10,Mps,Chi_10)
|
||||||
|
VMULIDUP(4*N,%r10,Mps,Chi_11)
|
||||||
|
VMULIDUP(5*N,%r10,Mps,Chi_12)
|
||||||
|
|
||||||
|
VMULIDUP(6*N ,%r10,Mms,Chi_20)
|
||||||
|
VMULIDUP(7*N ,%r10,Mms,Chi_21)
|
||||||
|
VMULIDUP(8*N ,%r10,Mms,Chi_22)
|
||||||
|
VMULIDUP(9*N ,%r10,Mms,Chi_30)
|
||||||
|
VMULIDUP(10*N,%r10,Mms,Chi_31)
|
||||||
|
VMULIDUP(11*N,%r10,Mms,Chi_32)
|
||||||
|
|
||||||
|
VMADDSUBRDUP(0*N,%r10,Mp,Chi_00)
|
||||||
|
VMADDSUBRDUP(1*N,%r10,Mp,Chi_01)
|
||||||
|
VMADDSUBRDUP(2*N,%r10,Mp,Chi_02)
|
||||||
|
VMADDSUBRDUP(3*N,%r10,Mp,Chi_10)
|
||||||
|
VMADDSUBRDUP(4*N,%r10,Mp,Chi_11)
|
||||||
|
VMADDSUBRDUP(5*N,%r10,Mp,Chi_12)
|
||||||
|
|
||||||
|
VMADDSUBRDUP(6*N ,%r10,Mm,Chi_20)
|
||||||
|
VMADDSUBRDUP(7*N ,%r10,Mm,Chi_21)
|
||||||
|
VMADDSUBRDUP(8*N ,%r10,Mm,Chi_22)
|
||||||
|
VMADDSUBRDUP(9*N ,%r10,Mm,Chi_30)
|
||||||
|
VMADDSUBRDUP(10*N,%r10,Mm,Chi_31)
|
||||||
|
VMADDSUBRDUP(11*N,%r10,Mm,Chi_32)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
LOAD64(%r8,a0);
|
||||||
|
LOAD64(%r9,a1);
|
||||||
|
LOAD64(%r10,a2);
|
||||||
|
asm (
|
||||||
|
VLOAD(0,%r8,Mp)
|
||||||
|
VSHUF(Mp,Mps)
|
||||||
|
|
||||||
|
VLOAD(0,%r9,Mm)
|
||||||
|
VSHUF(Mm,Mms)
|
||||||
|
|
||||||
|
VMADDSUBIDUP(0*N,%r10,Mps,Chi_00) // Mri * Pii +- Cir
|
||||||
|
VMADDSUBIDUP(1*N,%r10,Mps,Chi_01)
|
||||||
|
VMADDSUBIDUP(2*N,%r10,Mps,Chi_02)
|
||||||
|
VMADDSUBIDUP(3*N,%r10,Mps,Chi_10)
|
||||||
|
VMADDSUBIDUP(4*N,%r10,Mps,Chi_11)
|
||||||
|
VMADDSUBIDUP(5*N,%r10,Mps,Chi_12)
|
||||||
|
|
||||||
|
VMADDSUBIDUP(6 *N,%r10,Mms,Chi_20)
|
||||||
|
VMADDSUBIDUP(7 *N,%r10,Mms,Chi_21)
|
||||||
|
VMADDSUBIDUP(8 *N,%r10,Mms,Chi_22)
|
||||||
|
VMADDSUBIDUP(9 *N,%r10,Mms,Chi_30)
|
||||||
|
VMADDSUBIDUP(10*N,%r10,Mms,Chi_31)
|
||||||
|
VMADDSUBIDUP(11*N,%r10,Mms,Chi_32)
|
||||||
|
|
||||||
|
VMADDSUBRDUP(0*N,%r10,Mp,Chi_00) // Cir = Mir * Prr +- ( Mri * Pii +- Cir)
|
||||||
|
VMADDSUBRDUP(1*N,%r10,Mp,Chi_01) // Ci = MiPr + Ci + MrPi ; Cr = MrPr - ( MiPi - Cr)
|
||||||
|
VMADDSUBRDUP(2*N,%r10,Mp,Chi_02)
|
||||||
|
VMADDSUBRDUP(3*N,%r10,Mp,Chi_10)
|
||||||
|
VMADDSUBRDUP(4*N,%r10,Mp,Chi_11)
|
||||||
|
VMADDSUBRDUP(5*N,%r10,Mp,Chi_12)
|
||||||
|
|
||||||
|
VMADDSUBRDUP(6 *N,%r10,Mm,Chi_20)
|
||||||
|
VMADDSUBRDUP(7 *N,%r10,Mm,Chi_21)
|
||||||
|
VMADDSUBRDUP(8 *N,%r10,Mm,Chi_22)
|
||||||
|
VMADDSUBRDUP(9 *N,%r10,Mm,Chi_30)
|
||||||
|
VMADDSUBRDUP(10*N,%r10,Mm,Chi_31)
|
||||||
|
VMADDSUBRDUP(11*N,%r10,Mm,Chi_32)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
a0 = a0+incr;
|
||||||
|
a1 = a1+incr;
|
||||||
|
a2 = a2+sizeof(Simd::scalar_type);
|
||||||
|
}}
|
||||||
|
{
|
||||||
|
int lexa = s1+LLs*site;
|
||||||
|
/*
|
||||||
|
SiteSpinor tmp;
|
||||||
|
asm (
|
||||||
|
VSTORE(0,%0,pChi_00) VSTORE(1 ,%0,pChi_01) VSTORE(2 ,%0,pChi_02)
|
||||||
|
VSTORE(3,%0,pChi_10) VSTORE(4 ,%0,pChi_11) VSTORE(5 ,%0,pChi_12)
|
||||||
|
VSTORE(6,%0,pChi_20) VSTORE(7 ,%0,pChi_21) VSTORE(8 ,%0,pChi_22)
|
||||||
|
VSTORE(9,%0,pChi_30) VSTORE(10,%0,pChi_31) VSTORE(11,%0,pChi_32)
|
||||||
|
: : "r" ((uint64_t)&tmp) : "memory" );
|
||||||
|
*/
|
||||||
|
|
||||||
|
asm (
|
||||||
|
VSTORE(0,%0,pChi_00) VSTORE(1 ,%0,pChi_01) VSTORE(2 ,%0,pChi_02)
|
||||||
|
VSTORE(3,%0,pChi_10) VSTORE(4 ,%0,pChi_11) VSTORE(5 ,%0,pChi_12)
|
||||||
|
VSTORE(6,%0,pChi_20) VSTORE(7 ,%0,pChi_21) VSTORE(8 ,%0,pChi_22)
|
||||||
|
VSTORE(9,%0,pChi_30) VSTORE(10,%0,pChi_31) VSTORE(11,%0,pChi_32)
|
||||||
|
: : "r" ((uint64_t)&chi[lexa]) : "memory" );
|
||||||
|
|
||||||
|
// if ( 1 || (site==0) ) {
|
||||||
|
// std::cout<<site << " s1 "<<s1<<"\n\t"<<tmp << "\n't" << chi[lexa] <<"\n\t"<<tmp-chi[lexa]<<std::endl;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef Chi_00
|
||||||
|
#undef Chi_01
|
||||||
|
#undef Chi_02
|
||||||
|
#undef Chi_10
|
||||||
|
#undef Chi_11
|
||||||
|
#undef Chi_12
|
||||||
|
#undef Chi_20
|
||||||
|
#undef Chi_21
|
||||||
|
#undef Chi_22
|
||||||
|
#undef Chi_30
|
||||||
|
#undef Chi_31
|
||||||
|
#undef Chi_32
|
||||||
|
|
||||||
|
#undef BCAST0
|
||||||
|
#undef BCAST1
|
||||||
|
#undef BCAST2
|
||||||
|
#undef BCAST3
|
||||||
|
#undef BCAST4
|
||||||
|
#undef BCAST5
|
||||||
|
#undef BCAST6
|
||||||
|
#undef BCAST7
|
||||||
|
#undef BCAST8
|
||||||
|
#undef BCAST9
|
||||||
|
#undef BCAST10
|
||||||
|
#undef BCAST11
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
void CayleyFermion5D<Impl>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv)
|
void CayleyFermion5D<Impl>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv)
|
||||||
{
|
{
|
||||||
@ -299,108 +767,41 @@ void CayleyFermion5D<Impl>::MooeeInternal(const FermionField &psi, FermionField
|
|||||||
|
|
||||||
chi.checkerboard=psi.checkerboard;
|
chi.checkerboard=psi.checkerboard;
|
||||||
|
|
||||||
Eigen::MatrixXcd Pplus = Eigen::MatrixXcd::Zero(Ls,Ls);
|
Vector<iSinglet<Simd> > Matp;
|
||||||
Eigen::MatrixXcd Pminus = Eigen::MatrixXcd::Zero(Ls,Ls);
|
Vector<iSinglet<Simd> > Matm;
|
||||||
|
Vector<iSinglet<Simd> > *_Matp;
|
||||||
|
Vector<iSinglet<Simd> > *_Matm;
|
||||||
|
|
||||||
for(int s=0;s<Ls;s++){
|
// MooeeInternalCompute(dag,inv,Matp,Matm);
|
||||||
Pplus(s,s) = bee[s];
|
if ( inv && dag ) {
|
||||||
Pminus(s,s)= bee[s];
|
_Matp = &MatpInvDag;
|
||||||
|
_Matm = &MatmInvDag;
|
||||||
}
|
}
|
||||||
|
if ( inv && (!dag) ) {
|
||||||
for(int s=0;s<Ls-1;s++){
|
_Matp = &MatpInv;
|
||||||
Pminus(s,s+1) = -cee[s];
|
_Matm = &MatmInv;
|
||||||
|
}
|
||||||
|
if ( !inv ) {
|
||||||
|
MooeeInternalCompute(dag,inv,Matp,Matm);
|
||||||
|
_Matp = &Matp;
|
||||||
|
_Matm = &Matm;
|
||||||
}
|
}
|
||||||
|
assert(_Matp->size()==Ls*LLs);
|
||||||
for(int s=0;s<Ls-1;s++){
|
|
||||||
Pplus(s+1,s) = -cee[s+1];
|
|
||||||
}
|
|
||||||
Pplus (0,Ls-1) = mass*cee[0];
|
|
||||||
Pminus(Ls-1,0) = mass*cee[Ls-1];
|
|
||||||
|
|
||||||
Eigen::MatrixXcd PplusMat ;
|
|
||||||
Eigen::MatrixXcd PminusMat;
|
|
||||||
|
|
||||||
if ( inv ) {
|
|
||||||
PplusMat =Pplus.inverse();
|
|
||||||
PminusMat=Pminus.inverse();
|
|
||||||
} else {
|
|
||||||
PplusMat =Pplus;
|
|
||||||
PminusMat=Pminus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dag){
|
|
||||||
PplusMat.adjointInPlace();
|
|
||||||
PminusMat.adjointInPlace();
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename SiteHalfSpinor::scalar_type scalar_type;
|
|
||||||
const int Nsimd=Simd::Nsimd();
|
|
||||||
Vector<iSinglet<Simd> > Matp(Ls*LLs);
|
|
||||||
Vector<iSinglet<Simd> > Matm(Ls*LLs);
|
|
||||||
|
|
||||||
for(int s2=0;s2<Ls;s2++){
|
|
||||||
for(int s1=0;s1<LLs;s1++){
|
|
||||||
int istride = LLs;
|
|
||||||
int ostride = 1;
|
|
||||||
Simd Vp;
|
|
||||||
Simd Vm;
|
|
||||||
scalar_type *sp = (scalar_type *)&Vp;
|
|
||||||
scalar_type *sm = (scalar_type *)&Vm;
|
|
||||||
for(int l=0;l<Nsimd;l++){
|
|
||||||
sp[l] = PplusMat (l*istride+s1*ostride ,s2);
|
|
||||||
sm[l] = PminusMat(l*istride+s1*ostride,s2);
|
|
||||||
}
|
|
||||||
Matp[LLs*s2+s1] = Vp;
|
|
||||||
Matm[LLs*s2+s1] = Vm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MooeeInvCalls++;
|
MooeeInvCalls++;
|
||||||
MooeeInvTime-=usecond();
|
MooeeInvTime-=usecond();
|
||||||
// Dynamic allocate on stack to get per thread without serialised heap acces
|
|
||||||
#pragma omp parallel
|
|
||||||
{
|
|
||||||
|
|
||||||
Vector<SiteHalfSpinor> SitePplus(LLs);
|
if ( switcheroo<Coeff_t>::iscomplex() ) {
|
||||||
Vector<SiteHalfSpinor> SitePminus(LLs);
|
PARALLEL_FOR_LOOP
|
||||||
Vector<SiteHalfSpinor> SiteChiP(LLs);
|
for(auto site=0;site<vol;site++){
|
||||||
Vector<SiteHalfSpinor> SiteChiM(LLs);
|
MooeeInternalZAsm(psi,chi,LLs,site,*_Matp,*_Matm);
|
||||||
Vector<SiteSpinor> SiteChi(LLs);
|
|
||||||
|
|
||||||
SiteHalfSpinor BcastP;
|
|
||||||
SiteHalfSpinor BcastM;
|
|
||||||
|
|
||||||
#pragma omp for
|
|
||||||
for(auto site=0;site<vol;site++){
|
|
||||||
|
|
||||||
for(int s=0;s<LLs;s++){
|
|
||||||
int lex = s+LLs*site;
|
|
||||||
spProj5p(SitePplus[s] ,psi[lex]);
|
|
||||||
spProj5m(SitePminus[s],psi[lex]);
|
|
||||||
SiteChiP[s]=zero;
|
|
||||||
SiteChiM[s]=zero;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
int s=0;
|
PARALLEL_FOR_LOOP
|
||||||
for(int l=0; l<Simd::Nsimd();l++){ // simd lane
|
for(auto site=0;site<vol;site++){
|
||||||
for(int s2=0;s2<LLs;s2++){ // Column loop of right hand side
|
MooeeInternalAsm(psi,chi,LLs,site,*_Matp,*_Matm);
|
||||||
vbroadcast(BcastP,SitePplus [s2],l);
|
|
||||||
vbroadcast(BcastM,SitePminus[s2],l);
|
|
||||||
for(int s1=0;s1<LLs;s1++){ // Column loop of reduction variables
|
|
||||||
SiteChiP[s1]=SiteChiP[s1]+Matp[LLs*s+s1]*BcastP;
|
|
||||||
SiteChiM[s1]=SiteChiM[s1]+Matm[LLs*s+s1]*BcastM;
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}}
|
|
||||||
|
|
||||||
for(int s=0;s<LLs;s++){
|
|
||||||
int lex = s+LLs*site;
|
|
||||||
spRecon5p(SiteChi[s],SiteChiP[s]);
|
|
||||||
accumRecon5m(SiteChi[s],SiteChiM[s]);
|
|
||||||
chi[lex] = SiteChi[s]*0.5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
MooeeInvTime+=usecond();
|
MooeeInvTime+=usecond();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,4 +815,5 @@ template void CayleyFermion5D<DomainWallVec5dImplD>::MooeeInternal(const Fermion
|
|||||||
template void CayleyFermion5D<ZDomainWallVec5dImplF>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
|
template void CayleyFermion5D<ZDomainWallVec5dImplF>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
|
||||||
template void CayleyFermion5D<ZDomainWallVec5dImplD>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
|
template void CayleyFermion5D<ZDomainWallVec5dImplD>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
@ -48,6 +48,8 @@ namespace Grid {
|
|||||||
|
|
||||||
FermionOperator(const ImplParams &p= ImplParams()) : Impl(p) {};
|
FermionOperator(const ImplParams &p= ImplParams()) : Impl(p) {};
|
||||||
|
|
||||||
|
virtual FermionField &tmp(void) = 0;
|
||||||
|
|
||||||
GridBase * Grid(void) { return FermionGrid(); }; // this is all the linalg routines need to know
|
GridBase * Grid(void) { return FermionGrid(); }; // this is all the linalg routines need to know
|
||||||
GridBase * RedBlackGrid(void) { return FermionRedBlackGrid(); };
|
GridBase * RedBlackGrid(void) { return FermionRedBlackGrid(); };
|
||||||
|
|
||||||
|
@ -48,10 +48,12 @@ namespace QCD {
|
|||||||
// typedef typename XXX GaugeField;
|
// typedef typename XXX GaugeField;
|
||||||
// typedef typename XXX GaugeActField;
|
// typedef typename XXX GaugeActField;
|
||||||
// typedef typename XXX FermionField;
|
// typedef typename XXX FermionField;
|
||||||
|
// typedef typename XXX PropagatorField;
|
||||||
// typedef typename XXX DoubledGaugeField;
|
// typedef typename XXX DoubledGaugeField;
|
||||||
// typedef typename XXX SiteSpinor;
|
// typedef typename XXX SiteSpinor;
|
||||||
// typedef typename XXX SiteHalfSpinor;
|
// typedef typename XXX SitePropagator;
|
||||||
// typedef typename XXX Compressor;
|
// typedef typename XXX SiteHalfSpinor;
|
||||||
|
// typedef typename XXX Compressor;
|
||||||
//
|
//
|
||||||
// and Methods:
|
// and Methods:
|
||||||
// void ImportGauge(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
|
// void ImportGauge(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
|
||||||
@ -94,14 +96,16 @@ namespace QCD {
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define INHERIT_FIMPL_TYPES(Impl)\
|
#define INHERIT_FIMPL_TYPES(Impl)\
|
||||||
typedef typename Impl::FermionField FermionField; \
|
typedef typename Impl::FermionField FermionField; \
|
||||||
typedef typename Impl::DoubledGaugeField DoubledGaugeField; \
|
typedef typename Impl::PropagatorField PropagatorField; \
|
||||||
typedef typename Impl::SiteSpinor SiteSpinor; \
|
typedef typename Impl::DoubledGaugeField DoubledGaugeField; \
|
||||||
typedef typename Impl::SiteHalfSpinor SiteHalfSpinor; \
|
typedef typename Impl::SiteSpinor SiteSpinor; \
|
||||||
typedef typename Impl::Compressor Compressor; \
|
typedef typename Impl::SitePropagator SitePropagator; \
|
||||||
typedef typename Impl::StencilImpl StencilImpl; \
|
typedef typename Impl::SiteHalfSpinor SiteHalfSpinor; \
|
||||||
typedef typename Impl::ImplParams ImplParams; \
|
typedef typename Impl::Compressor Compressor; \
|
||||||
typedef typename Impl::Coeff_t Coeff_t;
|
typedef typename Impl::StencilImpl StencilImpl; \
|
||||||
|
typedef typename Impl::ImplParams ImplParams; \
|
||||||
|
typedef typename Impl::Coeff_t Coeff_t; \
|
||||||
|
|
||||||
#define INHERIT_IMPL_TYPES(Base) \
|
#define INHERIT_IMPL_TYPES(Base) \
|
||||||
INHERIT_GIMPL_TYPES(Base) \
|
INHERIT_GIMPL_TYPES(Base) \
|
||||||
@ -127,14 +131,17 @@ namespace QCD {
|
|||||||
INHERIT_GIMPL_TYPES(Gimpl);
|
INHERIT_GIMPL_TYPES(Gimpl);
|
||||||
|
|
||||||
template <typename vtype> using iImplSpinor = iScalar<iVector<iVector<vtype, Dimension>, Ns> >;
|
template <typename vtype> using iImplSpinor = iScalar<iVector<iVector<vtype, Dimension>, Ns> >;
|
||||||
|
template <typename vtype> using iImplPropagator = iScalar<iMatrix<iMatrix<vtype, Dimension>, Ns> >;
|
||||||
template <typename vtype> using iImplHalfSpinor = iScalar<iVector<iVector<vtype, Dimension>, Nhs> >;
|
template <typename vtype> using iImplHalfSpinor = iScalar<iVector<iVector<vtype, Dimension>, Nhs> >;
|
||||||
template <typename vtype> using iImplDoubledGaugeField = iVector<iScalar<iMatrix<vtype, Dimension> >, Nds>;
|
template <typename vtype> using iImplDoubledGaugeField = iVector<iScalar<iMatrix<vtype, Dimension> >, Nds>;
|
||||||
|
|
||||||
typedef iImplSpinor<Simd> SiteSpinor;
|
typedef iImplSpinor<Simd> SiteSpinor;
|
||||||
|
typedef iImplPropagator<Simd> SitePropagator;
|
||||||
typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
|
typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
|
||||||
typedef iImplDoubledGaugeField<Simd> SiteDoubledGaugeField;
|
typedef iImplDoubledGaugeField<Simd> SiteDoubledGaugeField;
|
||||||
|
|
||||||
typedef Lattice<SiteSpinor> FermionField;
|
typedef Lattice<SiteSpinor> FermionField;
|
||||||
|
typedef Lattice<SitePropagator> PropagatorField;
|
||||||
typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
|
typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
|
||||||
|
|
||||||
typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
|
typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
|
||||||
@ -216,14 +223,17 @@ class DomainWallVec5dImpl : public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepres
|
|||||||
INHERIT_GIMPL_TYPES(Gimpl);
|
INHERIT_GIMPL_TYPES(Gimpl);
|
||||||
|
|
||||||
template <typename vtype> using iImplSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
|
template <typename vtype> using iImplSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
|
||||||
|
template <typename vtype> using iImplPropagator = iScalar<iMatrix<iMatrix<vtype, Nrepresentation>, Ns> >;
|
||||||
template <typename vtype> using iImplHalfSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Nhs> >;
|
template <typename vtype> using iImplHalfSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Nhs> >;
|
||||||
template <typename vtype> using iImplDoubledGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds>;
|
template <typename vtype> using iImplDoubledGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds>;
|
||||||
template <typename vtype> using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd>;
|
template <typename vtype> using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd>;
|
||||||
template <typename vtype> using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >;
|
template <typename vtype> using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >;
|
||||||
|
|
||||||
typedef iImplSpinor<Simd> SiteSpinor;
|
typedef iImplSpinor<Simd> SiteSpinor;
|
||||||
|
typedef iImplPropagator<Simd> SitePropagator;
|
||||||
typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
|
typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
|
||||||
typedef Lattice<SiteSpinor> FermionField;
|
typedef Lattice<SiteSpinor> FermionField;
|
||||||
|
typedef Lattice<SitePropagator> PropagatorField;
|
||||||
|
|
||||||
// Make the doubled gauge field a *scalar*
|
// Make the doubled gauge field a *scalar*
|
||||||
typedef iImplDoubledGaugeField<typename Simd::scalar_type> SiteDoubledGaugeField; // This is a scalar
|
typedef iImplDoubledGaugeField<typename Simd::scalar_type> SiteDoubledGaugeField; // This is a scalar
|
||||||
@ -352,14 +362,17 @@ class GparityWilsonImpl : public ConjugateGaugeImpl<GaugeImplTypes<S, Nrepresent
|
|||||||
INHERIT_GIMPL_TYPES(Gimpl);
|
INHERIT_GIMPL_TYPES(Gimpl);
|
||||||
|
|
||||||
template <typename vtype> using iImplSpinor = iVector<iVector<iVector<vtype, Nrepresentation>, Ns>, Ngp>;
|
template <typename vtype> using iImplSpinor = iVector<iVector<iVector<vtype, Nrepresentation>, Ns>, Ngp>;
|
||||||
|
template <typename vtype> using iImplPropagator = iVector<iMatrix<iMatrix<vtype, Nrepresentation>, Ns>, Ngp >;
|
||||||
template <typename vtype> using iImplHalfSpinor = iVector<iVector<iVector<vtype, Nrepresentation>, Nhs>, Ngp>;
|
template <typename vtype> using iImplHalfSpinor = iVector<iVector<iVector<vtype, Nrepresentation>, Nhs>, Ngp>;
|
||||||
template <typename vtype> using iImplDoubledGaugeField = iVector<iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds>, Ngp>;
|
template <typename vtype> using iImplDoubledGaugeField = iVector<iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds>, Ngp>;
|
||||||
|
|
||||||
typedef iImplSpinor<Simd> SiteSpinor;
|
typedef iImplSpinor<Simd> SiteSpinor;
|
||||||
|
typedef iImplPropagator<Simd> SitePropagator;
|
||||||
typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
|
typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
|
||||||
typedef iImplDoubledGaugeField<Simd> SiteDoubledGaugeField;
|
typedef iImplDoubledGaugeField<Simd> SiteDoubledGaugeField;
|
||||||
|
|
||||||
typedef Lattice<SiteSpinor> FermionField;
|
typedef Lattice<SiteSpinor> FermionField;
|
||||||
|
typedef Lattice<SitePropagator> PropagatorField;
|
||||||
typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
|
typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
|
||||||
|
|
||||||
typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
|
typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
|
||||||
|
@ -61,7 +61,9 @@ WilsonFermion<Impl>::WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid,
|
|||||||
LebesgueEvenOdd(_cbgrid),
|
LebesgueEvenOdd(_cbgrid),
|
||||||
Umu(&Fgrid),
|
Umu(&Fgrid),
|
||||||
UmuEven(&Hgrid),
|
UmuEven(&Hgrid),
|
||||||
UmuOdd(&Hgrid) {
|
UmuOdd(&Hgrid),
|
||||||
|
_tmp(&Hgrid)
|
||||||
|
{
|
||||||
// Allocate the required comms buffer
|
// Allocate the required comms buffer
|
||||||
ImportGauge(_Umu);
|
ImportGauge(_Umu);
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,9 @@ class WilsonFermion : public WilsonKernels<Impl>, public WilsonFermionStatic {
|
|||||||
GridBase *FermionGrid(void) { return _grid; }
|
GridBase *FermionGrid(void) { return _grid; }
|
||||||
GridBase *FermionRedBlackGrid(void) { return _cbgrid; }
|
GridBase *FermionRedBlackGrid(void) { return _cbgrid; }
|
||||||
|
|
||||||
|
FermionField _tmp;
|
||||||
|
FermionField &tmp(void) { return _tmp; }
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
// override multiply; cut number routines if pass dagger argument
|
// override multiply; cut number routines if pass dagger argument
|
||||||
// and also make interface more uniformly consistent
|
// and also make interface more uniformly consistent
|
||||||
|
@ -61,7 +61,8 @@ WilsonFermion5D<Impl>::WilsonFermion5D(GaugeField &_Umu,
|
|||||||
UmuEven(_FourDimRedBlackGrid),
|
UmuEven(_FourDimRedBlackGrid),
|
||||||
UmuOdd (_FourDimRedBlackGrid),
|
UmuOdd (_FourDimRedBlackGrid),
|
||||||
Lebesgue(_FourDimGrid),
|
Lebesgue(_FourDimGrid),
|
||||||
LebesgueEvenOdd(_FourDimRedBlackGrid)
|
LebesgueEvenOdd(_FourDimRedBlackGrid),
|
||||||
|
_tmp(&FiveDimRedBlackGrid)
|
||||||
{
|
{
|
||||||
if (Impl::LsVectorised) {
|
if (Impl::LsVectorised) {
|
||||||
|
|
||||||
|
@ -74,6 +74,9 @@ namespace QCD {
|
|||||||
typedef WilsonKernels<Impl> Kernels;
|
typedef WilsonKernels<Impl> Kernels;
|
||||||
PmuStat stat;
|
PmuStat stat;
|
||||||
|
|
||||||
|
FermionField _tmp;
|
||||||
|
FermionField &tmp(void) { return _tmp; }
|
||||||
|
|
||||||
void Report(void);
|
void Report(void);
|
||||||
void ZeroCounters(void);
|
void ZeroCounters(void);
|
||||||
double DhopCalls;
|
double DhopCalls;
|
||||||
|
@ -32,6 +32,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
// Vector IO utilities ///////////////////////////////////////////////////////
|
||||||
// helper function to read space-separated values
|
// helper function to read space-separated values
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<T> strToVec(const std::string s)
|
std::vector<T> strToVec(const std::string s)
|
||||||
@ -67,12 +68,78 @@ namespace Grid {
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Serializable {};
|
// Vector element trait //////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
struct element
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
static constexpr bool is_number = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct element<std::vector<T>>
|
||||||
|
{
|
||||||
|
typedef typename element<T>::type type;
|
||||||
|
static constexpr bool is_number = std::is_arithmetic<T>::value
|
||||||
|
or is_complex<T>::value
|
||||||
|
or element<T>::is_number;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vector flatening utility class ////////////////////////////////////////////
|
||||||
|
// Class to flatten a multidimensional std::vector
|
||||||
|
template <typename V>
|
||||||
|
class Flatten
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename element<V>::type Element;
|
||||||
|
public:
|
||||||
|
explicit Flatten(const V &vector);
|
||||||
|
const V & getVector(void);
|
||||||
|
const std::vector<Element> & getFlatVector(void);
|
||||||
|
const std::vector<size_t> & getDim(void);
|
||||||
|
private:
|
||||||
|
void accumulate(const Element &e);
|
||||||
|
template <typename W>
|
||||||
|
void accumulate(const W &v);
|
||||||
|
void accumulateDim(const Element &e);
|
||||||
|
template <typename W>
|
||||||
|
void accumulateDim(const W &v);
|
||||||
|
private:
|
||||||
|
const V &vector_;
|
||||||
|
std::vector<Element> flatVector_;
|
||||||
|
std::vector<size_t> dim_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Class to reconstruct a multidimensional std::vector
|
||||||
|
template <typename V>
|
||||||
|
class Reconstruct
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename element<V>::type Element;
|
||||||
|
public:
|
||||||
|
Reconstruct(const std::vector<Element> &flatVector,
|
||||||
|
const std::vector<size_t> &dim);
|
||||||
|
const V & getVector(void);
|
||||||
|
const std::vector<Element> & getFlatVector(void);
|
||||||
|
const std::vector<size_t> & getDim(void);
|
||||||
|
private:
|
||||||
|
void fill(std::vector<Element> &v);
|
||||||
|
template <typename W>
|
||||||
|
void fill(W &v);
|
||||||
|
void resize(std::vector<Element> &v, const unsigned int dim);
|
||||||
|
template <typename W>
|
||||||
|
void resize(W &v, const unsigned int dim);
|
||||||
|
private:
|
||||||
|
V vector_;
|
||||||
|
const std::vector<Element> &flatVector_;
|
||||||
|
std::vector<size_t> dim_;
|
||||||
|
size_t ind_{0};
|
||||||
|
unsigned int dimInd_{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Abstract writer/reader classes ////////////////////////////////////////////
|
||||||
// static polymorphism implemented using CRTP idiom
|
// static polymorphism implemented using CRTP idiom
|
||||||
|
class Serializable;
|
||||||
|
|
||||||
// Static abstract writer
|
// Static abstract writer
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -87,12 +154,7 @@ namespace Grid {
|
|||||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
||||||
write(const std::string& s, const U &output);
|
write(const std::string& s, const U &output);
|
||||||
template <typename U>
|
template <typename U>
|
||||||
typename std::enable_if<std::is_enum<U>::value, void>::type
|
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
|
||||||
write(const std::string& s, const U &output);
|
|
||||||
template <typename U>
|
|
||||||
typename std::enable_if<
|
|
||||||
!(std::is_base_of<Serializable, U>::value or std::is_enum<U>::value),
|
|
||||||
void>::type
|
|
||||||
write(const std::string& s, const U &output);
|
write(const std::string& s, const U &output);
|
||||||
private:
|
private:
|
||||||
T *upcast;
|
T *upcast;
|
||||||
@ -111,12 +173,7 @@ namespace Grid {
|
|||||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
||||||
read(const std::string& s, U &output);
|
read(const std::string& s, U &output);
|
||||||
template <typename U>
|
template <typename U>
|
||||||
typename std::enable_if<std::is_enum<U>::value, void>::type
|
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
|
||||||
read(const std::string& s, U &output);
|
|
||||||
template <typename U>
|
|
||||||
typename std::enable_if<
|
|
||||||
!(std::is_base_of<Serializable, U>::value or std::is_enum<U>::value),
|
|
||||||
void>::type
|
|
||||||
read(const std::string& s, U &output);
|
read(const std::string& s, U &output);
|
||||||
protected:
|
protected:
|
||||||
template <typename U>
|
template <typename U>
|
||||||
@ -125,16 +182,151 @@ namespace Grid {
|
|||||||
T *upcast;
|
T *upcast;
|
||||||
};
|
};
|
||||||
|
|
||||||
// type traits
|
|
||||||
// What is the vtype
|
|
||||||
template<typename T> struct isReader {
|
|
||||||
static const bool value = false;
|
|
||||||
};
|
|
||||||
template<typename T> struct isWriter {
|
|
||||||
static const bool value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generic writer interface
|
// Generic writer interface
|
||||||
|
// serializable base class
|
||||||
|
class Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
static inline void write(Writer<T> &WR,const std::string &s,
|
||||||
|
const Serializable &obj)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline void read(Reader<T> &RD,const std::string &s,
|
||||||
|
Serializable &obj)
|
||||||
|
{}
|
||||||
|
|
||||||
|
friend inline std::ostream & operator<<(std::ostream &os,
|
||||||
|
const Serializable &obj)
|
||||||
|
{
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Flatten class template implementation /////////////////////////////////////
|
||||||
|
template <typename V>
|
||||||
|
void Flatten<V>::accumulate(const Element &e)
|
||||||
|
{
|
||||||
|
flatVector_.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
template <typename W>
|
||||||
|
void Flatten<V>::accumulate(const W &v)
|
||||||
|
{
|
||||||
|
for (auto &e: v)
|
||||||
|
{
|
||||||
|
accumulate(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
void Flatten<V>::accumulateDim(const Element &e) {};
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
template <typename W>
|
||||||
|
void Flatten<V>::accumulateDim(const W &v)
|
||||||
|
{
|
||||||
|
dim_.push_back(v.size());
|
||||||
|
accumulateDim(v[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
Flatten<V>::Flatten(const V &vector)
|
||||||
|
: vector_(vector)
|
||||||
|
{
|
||||||
|
accumulate(vector_);
|
||||||
|
accumulateDim(vector_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
const V & Flatten<V>::getVector(void)
|
||||||
|
{
|
||||||
|
return vector_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
const std::vector<typename Flatten<V>::Element> &
|
||||||
|
Flatten<V>::getFlatVector(void)
|
||||||
|
{
|
||||||
|
return flatVector_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
const std::vector<size_t> & Flatten<V>::getDim(void)
|
||||||
|
{
|
||||||
|
return dim_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconstruct class template implementation /////////////////////////////////
|
||||||
|
template <typename V>
|
||||||
|
void Reconstruct<V>::fill(std::vector<Element> &v)
|
||||||
|
{
|
||||||
|
for (auto &e: v)
|
||||||
|
{
|
||||||
|
e = flatVector_[ind_++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
template <typename W>
|
||||||
|
void Reconstruct<V>::fill(W &v)
|
||||||
|
{
|
||||||
|
for (auto &e: v)
|
||||||
|
{
|
||||||
|
fill(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
void Reconstruct<V>::resize(std::vector<Element> &v, const unsigned int dim)
|
||||||
|
{
|
||||||
|
v.resize(dim_[dim]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
template <typename W>
|
||||||
|
void Reconstruct<V>::resize(W &v, const unsigned int dim)
|
||||||
|
{
|
||||||
|
v.resize(dim_[dim]);
|
||||||
|
for (auto &e: v)
|
||||||
|
{
|
||||||
|
resize(e, dim + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
Reconstruct<V>::Reconstruct(const std::vector<Element> &flatVector,
|
||||||
|
const std::vector<size_t> &dim)
|
||||||
|
: flatVector_(flatVector)
|
||||||
|
, dim_(dim)
|
||||||
|
{
|
||||||
|
resize(vector_, 0);
|
||||||
|
fill(vector_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
const V & Reconstruct<V>::getVector(void)
|
||||||
|
{
|
||||||
|
return vector_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
const std::vector<typename Reconstruct<V>::Element> &
|
||||||
|
Reconstruct<V>::getFlatVector(void)
|
||||||
|
{
|
||||||
|
return flatVector_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
const std::vector<size_t> & Reconstruct<V>::getDim(void)
|
||||||
|
{
|
||||||
|
return dim_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic writer interface //////////////////////////////////////////////////
|
||||||
|
>>>>>>> develop
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void push(Writer<T> &w, const std::string &s) {
|
inline void push(Writer<T> &w, const std::string &s) {
|
||||||
w.push(s);
|
w.push(s);
|
||||||
@ -212,23 +404,13 @@ namespace Grid {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
template <typename U>
|
template <typename U>
|
||||||
typename std::enable_if<std::is_enum<U>::value, void>::type
|
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
|
||||||
Writer<T>::write(const std::string &s, const U &output)
|
|
||||||
{
|
|
||||||
EnumIO<U>::write(*this, s, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
template <typename U>
|
|
||||||
typename std::enable_if<
|
|
||||||
!(std::is_base_of<Serializable, U>::value or std::is_enum<U>::value),
|
|
||||||
void>::type
|
|
||||||
Writer<T>::write(const std::string &s, const U &output)
|
Writer<T>::write(const std::string &s, const U &output)
|
||||||
{
|
{
|
||||||
upcast->writeDefault(s, output);
|
upcast->writeDefault(s, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reader template implementation ////////////////////////////////////////////
|
// Reader template implementation
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Reader<T>::Reader(void)
|
Reader<T>::Reader(void)
|
||||||
{
|
{
|
||||||
@ -257,17 +439,7 @@ namespace Grid {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
template <typename U>
|
template <typename U>
|
||||||
typename std::enable_if<std::is_enum<U>::value, void>::type
|
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
|
||||||
Reader<T>::read(const std::string &s, U &output)
|
|
||||||
{
|
|
||||||
EnumIO<U>::read(*this, s, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
template <typename U>
|
|
||||||
typename std::enable_if<
|
|
||||||
!(std::is_base_of<Serializable, U>::value or std::is_enum<U>::value),
|
|
||||||
void>::type
|
|
||||||
Reader<T>::read(const std::string &s, U &output)
|
Reader<T>::read(const std::string &s, U &output)
|
||||||
{
|
{
|
||||||
upcast->readDefault(s, output);
|
upcast->readDefault(s, output);
|
||||||
@ -291,7 +463,6 @@ namespace Grid {
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
103
lib/serialisation/Hdf5IO.cc
Normal file
103
lib/serialisation/Hdf5IO.cc
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#include <Grid.h>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
#ifndef H5_NO_NAMESPACE
|
||||||
|
using namespace H5NS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Writer implementation ///////////////////////////////////////////////////////
|
||||||
|
Hdf5Writer::Hdf5Writer(const std::string &fileName)
|
||||||
|
: fileName_(fileName)
|
||||||
|
, file_(fileName.c_str(), H5F_ACC_TRUNC)
|
||||||
|
{
|
||||||
|
group_ = file_.openGroup("/");
|
||||||
|
writeSingleAttribute(dataSetThres_, HDF5_GRID_GUARD "dataset_threshold",
|
||||||
|
Hdf5Type<unsigned int>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hdf5Writer::push(const std::string &s)
|
||||||
|
{
|
||||||
|
group_ = group_.createGroup(s);
|
||||||
|
path_.push_back(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hdf5Writer::pop(void)
|
||||||
|
{
|
||||||
|
path_.pop_back();
|
||||||
|
if (path_.empty())
|
||||||
|
{
|
||||||
|
group_ = file_.openGroup("/");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto binOp = [](const std::string &a, const std::string &b)->std::string
|
||||||
|
{
|
||||||
|
return a + "/" + b;
|
||||||
|
};
|
||||||
|
|
||||||
|
group_ = group_.openGroup(std::accumulate(path_.begin(), path_.end(),
|
||||||
|
std::string(""), binOp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void Hdf5Writer::writeDefault(const std::string &s, const std::string &x)
|
||||||
|
{
|
||||||
|
StrType strType(PredType::C_S1, x.size());
|
||||||
|
|
||||||
|
writeSingleAttribute(*(x.data()), s, strType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hdf5Writer::writeDefault(const std::string &s, const char *x)
|
||||||
|
{
|
||||||
|
std::string sx(x);
|
||||||
|
|
||||||
|
writeDefault(s, sx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reader implementation ///////////////////////////////////////////////////////
|
||||||
|
Hdf5Reader::Hdf5Reader(const std::string &fileName)
|
||||||
|
: fileName_(fileName)
|
||||||
|
, file_(fileName.c_str(), H5F_ACC_RDONLY)
|
||||||
|
{
|
||||||
|
group_ = file_.openGroup("/");
|
||||||
|
readSingleAttribute(dataSetThres_, HDF5_GRID_GUARD "dataset_threshold",
|
||||||
|
Hdf5Type<unsigned int>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hdf5Reader::push(const std::string &s)
|
||||||
|
{
|
||||||
|
group_ = group_.openGroup(s);
|
||||||
|
path_.push_back(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hdf5Reader::pop(void)
|
||||||
|
{
|
||||||
|
path_.pop_back();
|
||||||
|
if (path_.empty())
|
||||||
|
{
|
||||||
|
group_ = file_.openGroup("/");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto binOp = [](const std::string &a, const std::string &b)->std::string
|
||||||
|
{
|
||||||
|
return a + "/" + b;
|
||||||
|
};
|
||||||
|
|
||||||
|
group_ = group_.openGroup(std::accumulate(path_.begin(), path_.end(),
|
||||||
|
std::string(""), binOp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void Hdf5Reader::readDefault(const std::string &s, std::string &x)
|
||||||
|
{
|
||||||
|
Attribute attribute;
|
||||||
|
|
||||||
|
attribute = group_.openAttribute(s);
|
||||||
|
StrType strType = attribute.getStrType();
|
||||||
|
|
||||||
|
x.resize(strType.getSize());
|
||||||
|
attribute.read(strType, &(x[0]));
|
||||||
|
}
|
242
lib/serialisation/Hdf5IO.h
Normal file
242
lib/serialisation/Hdf5IO.h
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
#ifndef GRID_SERIALISATION_HDF5_H
|
||||||
|
#define GRID_SERIALISATION_HDF5_H
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <H5Cpp.h>
|
||||||
|
#include "Hdf5Type.h"
|
||||||
|
|
||||||
|
#ifndef H5_NO_NAMESPACE
|
||||||
|
#define H5NS H5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// default thresold above which datasets are used instead of attributes
|
||||||
|
#ifndef HDF5_DEF_DATASET_THRES
|
||||||
|
#define HDF5_DEF_DATASET_THRES 6u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// name guard for Grid metadata
|
||||||
|
#define HDF5_GRID_GUARD "_Grid_"
|
||||||
|
|
||||||
|
namespace Grid
|
||||||
|
{
|
||||||
|
class Hdf5Writer: public Writer<Hdf5Writer>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Hdf5Writer(const std::string &fileName);
|
||||||
|
virtual ~Hdf5Writer(void) = default;
|
||||||
|
void push(const std::string &s);
|
||||||
|
void pop(void);
|
||||||
|
void writeDefault(const std::string &s, const char *x);
|
||||||
|
template <typename U>
|
||||||
|
void writeDefault(const std::string &s, const U &x);
|
||||||
|
template <typename U>
|
||||||
|
typename std::enable_if<element<std::vector<U>>::is_number, void>::type
|
||||||
|
writeDefault(const std::string &s, const std::vector<U> &x);
|
||||||
|
template <typename U>
|
||||||
|
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
|
||||||
|
writeDefault(const std::string &s, const std::vector<U> &x);
|
||||||
|
private:
|
||||||
|
template <typename U>
|
||||||
|
void writeSingleAttribute(const U &x, const std::string &name,
|
||||||
|
const H5NS::DataType &type);
|
||||||
|
private:
|
||||||
|
std::string fileName_;
|
||||||
|
std::vector<std::string> path_;
|
||||||
|
H5NS::H5File file_;
|
||||||
|
H5NS::Group group_;
|
||||||
|
unsigned int dataSetThres_{HDF5_DEF_DATASET_THRES};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Hdf5Reader: public Reader<Hdf5Reader>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Hdf5Reader(const std::string &fileName);
|
||||||
|
virtual ~Hdf5Reader(void) = default;
|
||||||
|
void push(const std::string &s);
|
||||||
|
void pop(void);
|
||||||
|
template <typename U>
|
||||||
|
void readDefault(const std::string &s, U &output);
|
||||||
|
template <typename U>
|
||||||
|
typename std::enable_if<element<std::vector<U>>::is_number, void>::type
|
||||||
|
readDefault(const std::string &s, std::vector<U> &x);
|
||||||
|
template <typename U>
|
||||||
|
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
|
||||||
|
readDefault(const std::string &s, std::vector<U> &x);
|
||||||
|
private:
|
||||||
|
template <typename U>
|
||||||
|
void readSingleAttribute(U &x, const std::string &name,
|
||||||
|
const H5NS::DataType &type);
|
||||||
|
private:
|
||||||
|
std::string fileName_;
|
||||||
|
std::vector<std::string> path_;
|
||||||
|
H5NS::H5File file_;
|
||||||
|
H5NS::Group group_;
|
||||||
|
unsigned int dataSetThres_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Writer template implementation ////////////////////////////////////////////
|
||||||
|
template <typename U>
|
||||||
|
void Hdf5Writer::writeSingleAttribute(const U &x, const std::string &name,
|
||||||
|
const H5NS::DataType &type)
|
||||||
|
{
|
||||||
|
H5NS::Attribute attribute;
|
||||||
|
hsize_t attrDim = 1;
|
||||||
|
H5NS::DataSpace attrSpace(1, &attrDim);
|
||||||
|
|
||||||
|
attribute = group_.createAttribute(name, type, attrSpace);
|
||||||
|
attribute.write(type, &x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
void Hdf5Writer::writeDefault(const std::string &s, const U &x)
|
||||||
|
{
|
||||||
|
writeSingleAttribute(x, s, Hdf5Type<U>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void Hdf5Writer::writeDefault(const std::string &s, const std::string &x);
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
typename std::enable_if<element<std::vector<U>>::is_number, void>::type
|
||||||
|
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||||
|
{
|
||||||
|
// alias to element type
|
||||||
|
typedef typename element<std::vector<U>>::type Element;
|
||||||
|
|
||||||
|
// flatten the vector and getting dimensions
|
||||||
|
Flatten<std::vector<U>> flat(x);
|
||||||
|
std::vector<hsize_t> dim;
|
||||||
|
const auto &flatx = flat.getFlatVector();
|
||||||
|
|
||||||
|
for (auto &d: flat.getDim())
|
||||||
|
{
|
||||||
|
dim.push_back(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write to file
|
||||||
|
H5NS::DataSpace dataSpace(dim.size(), dim.data());
|
||||||
|
|
||||||
|
if (flatx.size() > dataSetThres_)
|
||||||
|
{
|
||||||
|
H5NS::DataSet dataSet;
|
||||||
|
|
||||||
|
dataSet = group_.createDataSet(s, Hdf5Type<Element>::type(), dataSpace);
|
||||||
|
dataSet.write(flatx.data(), Hdf5Type<Element>::type());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
H5NS::Attribute attribute;
|
||||||
|
|
||||||
|
attribute = group_.createAttribute(s, Hdf5Type<Element>::type(), dataSpace);
|
||||||
|
attribute.write(Hdf5Type<Element>::type(), flatx.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
|
||||||
|
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||||
|
{
|
||||||
|
push(s);
|
||||||
|
writeSingleAttribute(x.size(), HDF5_GRID_GUARD "vector_size",
|
||||||
|
Hdf5Type<uint64_t>::type());
|
||||||
|
for (hsize_t i = 0; i < x.size(); ++i)
|
||||||
|
{
|
||||||
|
write(s + "_" + std::to_string(i), x[i]);
|
||||||
|
}
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reader template implementation ////////////////////////////////////////////
|
||||||
|
template <typename U>
|
||||||
|
void Hdf5Reader::readSingleAttribute(U &x, const std::string &name,
|
||||||
|
const H5NS::DataType &type)
|
||||||
|
{
|
||||||
|
H5NS::Attribute attribute;
|
||||||
|
|
||||||
|
attribute = group_.openAttribute(name);
|
||||||
|
attribute.read(type, &x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
void Hdf5Reader::readDefault(const std::string &s, U &output)
|
||||||
|
{
|
||||||
|
readSingleAttribute(output, s, Hdf5Type<U>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void Hdf5Reader::readDefault(const std::string &s, std::string &x);
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
typename std::enable_if<element<std::vector<U>>::is_number, void>::type
|
||||||
|
Hdf5Reader::readDefault(const std::string &s, std::vector<U> &x)
|
||||||
|
{
|
||||||
|
// alias to element type
|
||||||
|
typedef typename element<std::vector<U>>::type Element;
|
||||||
|
|
||||||
|
// read the dimensions
|
||||||
|
H5NS::DataSpace dataSpace;
|
||||||
|
std::vector<hsize_t> hdim;
|
||||||
|
std::vector<size_t> dim;
|
||||||
|
hsize_t size = 1;
|
||||||
|
|
||||||
|
if (group_.attrExists(s))
|
||||||
|
{
|
||||||
|
dataSpace = group_.openAttribute(s).getSpace();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataSpace = group_.openDataSet(s).getSpace();
|
||||||
|
}
|
||||||
|
hdim.resize(dataSpace.getSimpleExtentNdims());
|
||||||
|
dataSpace.getSimpleExtentDims(hdim.data());
|
||||||
|
for (auto &d: hdim)
|
||||||
|
{
|
||||||
|
dim.push_back(d);
|
||||||
|
size *= d;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the flat vector
|
||||||
|
std::vector<Element> buf(size);
|
||||||
|
|
||||||
|
if (size > dataSetThres_)
|
||||||
|
{
|
||||||
|
H5NS::DataSet dataSet;
|
||||||
|
|
||||||
|
dataSet = group_.openDataSet(s);
|
||||||
|
dataSet.read(buf.data(), Hdf5Type<Element>::type());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
H5NS::Attribute attribute;
|
||||||
|
|
||||||
|
attribute = group_.openAttribute(s);
|
||||||
|
attribute.read(Hdf5Type<Element>::type(), buf.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
// reconstruct the multidimensional vector
|
||||||
|
Reconstruct<std::vector<U>> r(buf, dim);
|
||||||
|
|
||||||
|
x = r.getVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
|
||||||
|
Hdf5Reader::readDefault(const std::string &s, std::vector<U> &x)
|
||||||
|
{
|
||||||
|
uint64_t size;
|
||||||
|
|
||||||
|
push(s);
|
||||||
|
readSingleAttribute(size, HDF5_GRID_GUARD "vector_size",
|
||||||
|
Hdf5Type<uint64_t>::type());
|
||||||
|
x.resize(size);
|
||||||
|
for (hsize_t i = 0; i < x.size(); ++i)
|
||||||
|
{
|
||||||
|
read(s + "_" + std::to_string(i), x[i]);
|
||||||
|
}
|
||||||
|
pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
77
lib/serialisation/Hdf5Type.h
Normal file
77
lib/serialisation/Hdf5Type.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#ifndef GRID_SERIALISATION_HDF5_TYPE_H
|
||||||
|
#define GRID_SERIALISATION_HDF5_TYPE_H
|
||||||
|
|
||||||
|
#include <H5Cpp.h>
|
||||||
|
#include <complex>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#ifndef H5_NO_NAMESPACE
|
||||||
|
#define H5NS H5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HDF5_NATIVE_TYPE(predType, cType)\
|
||||||
|
template <>\
|
||||||
|
class Hdf5Type<cType>\
|
||||||
|
{\
|
||||||
|
public:\
|
||||||
|
static inline const H5NS::DataType & type(void)\
|
||||||
|
{\
|
||||||
|
return H5NS::PredType::predType;\
|
||||||
|
}\
|
||||||
|
static constexpr bool isNative = true;\
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEFINE_HDF5_NATIVE_TYPES \
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_B8, bool);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_CHAR, char);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_SCHAR, signed char);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_UCHAR, unsigned char);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_SHORT, short);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_USHORT, unsigned short);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_INT, int);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_UINT, unsigned int);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_LONG, long);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_ULONG, unsigned long);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_LLONG, long long);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_ULLONG, unsigned long long);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_FLOAT, float);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_DOUBLE, double);\
|
||||||
|
HDF5_NATIVE_TYPE(NATIVE_LDOUBLE, long double);
|
||||||
|
|
||||||
|
namespace Grid
|
||||||
|
{
|
||||||
|
template <typename T> class Hdf5Type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr bool isNative = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_HDF5_NATIVE_TYPES;
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
class Hdf5Type<std::complex<R>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static inline const H5NS::DataType & type(void)
|
||||||
|
{
|
||||||
|
if (typePtr_ == nullptr)
|
||||||
|
{
|
||||||
|
typePtr_.reset(new H5NS::CompType(sizeof(std::complex<R>)));
|
||||||
|
typePtr_->insertMember("re", 0, Hdf5Type<R>::type());
|
||||||
|
typePtr_->insertMember("im", sizeof(R), Hdf5Type<R>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
return *typePtr_;
|
||||||
|
}
|
||||||
|
static constexpr bool isNative = false;
|
||||||
|
private:
|
||||||
|
static std::unique_ptr<H5NS::CompType> typePtr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
std::unique_ptr<H5NS::CompType> Hdf5Type<std::complex<R>>::typePtr_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef HDF5_NATIVE_TYPE
|
||||||
|
|
||||||
|
#endif /* GRID_SERIALISATION_HDF5_TYPE_H */
|
@ -109,40 +109,36 @@ THE SOFTWARE.
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define GRID_MACRO_MEMBER(A,B) A B;
|
#define GRID_MACRO_MEMBER(A,B) A B;
|
||||||
|
#define GRID_MACRO_COMP_MEMBER(A,B) result = (result and (lhs. B == rhs. B));
|
||||||
#define GRID_MACRO_OS_WRITE_MEMBER(A,B) os<< #A <<" "#B <<" = "<< obj. B <<" ; " <<std::endl;
|
#define GRID_MACRO_OS_WRITE_MEMBER(A,B) os<< #A <<" "#B <<" = "<< obj. B <<" ; " <<std::endl;
|
||||||
#define GRID_MACRO_READ_MEMBER(A,B) Grid::read(RD,#B,obj. B);
|
#define GRID_MACRO_READ_MEMBER(A,B) Grid::read(RD,#B,obj. B);
|
||||||
#define GRID_MACRO_WRITE_MEMBER(A,B) Grid::write(WR,#B,obj. B);
|
#define GRID_MACRO_WRITE_MEMBER(A,B) Grid::write(WR,#B,obj. B);
|
||||||
|
|
||||||
#define GRID_SERIALIZABLE_CLASS_MEMBERS(cname,...) \
|
#define GRID_SERIALIZABLE_CLASS_MEMBERS(cname,...)\
|
||||||
\
|
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_MEMBER,__VA_ARGS__))\
|
||||||
\
|
template <typename T>\
|
||||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_MEMBER,__VA_ARGS__)) \
|
static inline void write(Writer<T> &WR,const std::string &s, const cname &obj){ \
|
||||||
\
|
push(WR,s);\
|
||||||
\
|
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_WRITE_MEMBER,__VA_ARGS__)) \
|
||||||
template <typename T>\
|
pop(WR);\
|
||||||
static inline void write(Writer<T> &WR,const std::string &s, const cname &obj){ \
|
}\
|
||||||
push(WR,s);\
|
template <typename T>\
|
||||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_WRITE_MEMBER,__VA_ARGS__)) \
|
static inline void read(Reader<T> &RD,const std::string &s, cname &obj){ \
|
||||||
pop(WR);\
|
push(RD,s);\
|
||||||
} \
|
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_READ_MEMBER,__VA_ARGS__)) \
|
||||||
\
|
pop(RD);\
|
||||||
\
|
}\
|
||||||
template <typename T>\
|
friend inline std::ostream & operator << (std::ostream &os, const cname &obj ) { \
|
||||||
static inline void read(Reader<T> &RD,const std::string &s, cname &obj){ \
|
os<<"class "<<#cname<<" {"<<std::endl;\
|
||||||
push(RD,s);\
|
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_OS_WRITE_MEMBER,__VA_ARGS__)) \
|
||||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_READ_MEMBER,__VA_ARGS__)) \
|
os<<"}"; \
|
||||||
pop(RD);\
|
return os;\
|
||||||
} \
|
}\
|
||||||
\
|
friend inline bool operator==(const cname &lhs, const cname &rhs) {\
|
||||||
\
|
bool result = true;\
|
||||||
friend inline std::ostream & operator << (std::ostream &os, const cname &obj ) { \
|
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_COMP_MEMBER,__VA_ARGS__))\
|
||||||
os<<"class "<<#cname<<" {"<<std::endl;\
|
return result;\
|
||||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_OS_WRITE_MEMBER,__VA_ARGS__)) \
|
}
|
||||||
os<<"}"; \
|
|
||||||
return os;\
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define GRID_ENUM_TYPE(obj) std::remove_reference<decltype(obj)>::type
|
#define GRID_ENUM_TYPE(obj) std::remove_reference<decltype(obj)>::type
|
||||||
#define GRID_MACRO_ENUMVAL(A,B) A = B,
|
#define GRID_MACRO_ENUMVAL(A,B) A = B,
|
||||||
@ -150,44 +146,52 @@ THE SOFTWARE.
|
|||||||
#define GRID_MACRO_ENUMTEST(A,B) else if (buf == #A) {obj = GRID_ENUM_TYPE(obj)::A;}
|
#define GRID_MACRO_ENUMTEST(A,B) else if (buf == #A) {obj = GRID_ENUM_TYPE(obj)::A;}
|
||||||
#define GRID_MACRO_ENUMCASEIO(A,B) case GRID_ENUM_TYPE(obj)::A: os << #A; break;
|
#define GRID_MACRO_ENUMCASEIO(A,B) case GRID_ENUM_TYPE(obj)::A: os << #A; break;
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
template <typename U>
|
|
||||||
class EnumIO {};
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GRID_SERIALIZABLE_ENUM(name,undefname,...)\
|
#define GRID_SERIALIZABLE_ENUM(name,undefname,...)\
|
||||||
enum class name {\
|
class name: public Grid::Serializable\
|
||||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMVAL,__VA_ARGS__))\
|
{\
|
||||||
undefname = -1\
|
public:\
|
||||||
|
enum EnumType\
|
||||||
|
{\
|
||||||
|
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMVAL,__VA_ARGS__))\
|
||||||
|
undefname = -1\
|
||||||
};\
|
};\
|
||||||
|
public:\
|
||||||
|
name(void): value_(undefname) {};\
|
||||||
|
name(EnumType value): value_(value) {};\
|
||||||
|
template <typename T>\
|
||||||
|
static inline void write(Grid::Writer<T> &WR,const std::string &s, const name &obj)\
|
||||||
|
{\
|
||||||
|
switch (obj.value_)\
|
||||||
|
{\
|
||||||
|
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMCASE,__VA_ARGS__))\
|
||||||
|
default: Grid::write(WR,s,#undefname); break;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
\
|
\
|
||||||
template<>\
|
template <typename T>\
|
||||||
class EnumIO<name> {\
|
static inline void read(Grid::Reader<T> &RD,const std::string &s, name &obj)\
|
||||||
public:\
|
{\
|
||||||
template <typename T>\
|
std::string buf;\
|
||||||
static inline void write(Writer<T> &WR,const std::string &s, const name &obj){ \
|
Grid::read(RD, s, buf);\
|
||||||
switch (obj) {\
|
if (buf == #undefname) {obj = name::undefname;}\
|
||||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMCASE,__VA_ARGS__))\
|
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMTEST,__VA_ARGS__))\
|
||||||
default: Grid::write(WR,s,#undefname); break;\
|
else {obj = name::undefname;}\
|
||||||
}\
|
}\
|
||||||
}\
|
inline operator EnumType(void) const\
|
||||||
\
|
{\
|
||||||
template <typename T>\
|
return value_;\
|
||||||
static inline void read(Reader<T> &RD,const std::string &s, name &obj){ \
|
}\
|
||||||
std::string buf;\
|
inline friend std::ostream & operator<<(std::ostream &os, const name &obj)\
|
||||||
Grid::read(RD, s, buf);\
|
{\
|
||||||
if (buf == #undefname) {obj = name::undefname;}\
|
|
||||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMTEST,__VA_ARGS__))\
|
|
||||||
else {obj = name::undefname;}\
|
|
||||||
}\
|
|
||||||
};\
|
|
||||||
\
|
|
||||||
inline std::ostream & operator << (std::ostream &os, const name &obj ) { \
|
|
||||||
switch (obj) {\
|
switch (obj) {\
|
||||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMCASEIO,__VA_ARGS__))\
|
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMCASEIO,__VA_ARGS__))\
|
||||||
default: os << #undefname; break;\
|
default: os << #undefname; break;\
|
||||||
}\
|
}\
|
||||||
return os;\
|
return os;\
|
||||||
};
|
}\
|
||||||
|
private:\
|
||||||
|
EnumType value_;\
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,6 +37,11 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
#include "TextIO.h"
|
#include "TextIO.h"
|
||||||
#include "XmlIO.h"
|
#include "XmlIO.h"
|
||||||
#include "JSON_IO.h"
|
#include "JSON_IO.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_HDF5
|
||||||
|
#include "Hdf5IO.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
// Todo:
|
// Todo:
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
@ -204,6 +204,29 @@ namespace Optimization {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MultRealPart{
|
||||||
|
inline __m256 operator()(__m256 a, __m256 b){
|
||||||
|
__m256 ymm0;
|
||||||
|
ymm0 = _mm256_shuffle_ps(a,a,_MM_SELECT_FOUR_FOUR(2,2,0,0)); // ymm0 <- ar ar,
|
||||||
|
return _mm256_mul_ps(ymm0,b); // ymm0 <- ar bi, ar br
|
||||||
|
}
|
||||||
|
inline __m256d operator()(__m256d a, __m256d b){
|
||||||
|
__m256d ymm0;
|
||||||
|
ymm0 = _mm256_shuffle_pd(a,a,0x0); // ymm0 <- ar ar, ar,ar b'00,00
|
||||||
|
return _mm256_mul_pd(ymm0,b); // ymm0 <- ar bi, ar br
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct MaddRealPart{
|
||||||
|
inline __m256 operator()(__m256 a, __m256 b, __m256 c){
|
||||||
|
__m256 ymm0 = _mm256_moveldup_ps(a); // ymm0 <- ar ar,
|
||||||
|
return _mm256_add_ps(_mm256_mul_ps( ymm0, b),c);
|
||||||
|
}
|
||||||
|
inline __m256d operator()(__m256d a, __m256d b, __m256d c){
|
||||||
|
__m256d ymm0 = _mm256_shuffle_pd( a, a, 0x0 );
|
||||||
|
return _mm256_add_pd(_mm256_mul_pd( ymm0, b),c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct MultComplex{
|
struct MultComplex{
|
||||||
// Complex float
|
// Complex float
|
||||||
inline __m256 operator()(__m256 a, __m256 b){
|
inline __m256 operator()(__m256 a, __m256 b){
|
||||||
@ -618,7 +641,9 @@ namespace Optimization {
|
|||||||
typedef Optimization::Sub SubSIMD;
|
typedef Optimization::Sub SubSIMD;
|
||||||
typedef Optimization::Div DivSIMD;
|
typedef Optimization::Div DivSIMD;
|
||||||
typedef Optimization::Mult MultSIMD;
|
typedef Optimization::Mult MultSIMD;
|
||||||
typedef Optimization::MultComplex MultComplexSIMD;
|
typedef Optimization::MultComplex MultComplexSIMD;
|
||||||
|
typedef Optimization::MultRealPart MultRealPartSIMD;
|
||||||
|
typedef Optimization::MaddRealPart MaddRealPartSIMD;
|
||||||
typedef Optimization::Conj ConjSIMD;
|
typedef Optimization::Conj ConjSIMD;
|
||||||
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
||||||
typedef Optimization::TimesI TimesISIMD;
|
typedef Optimization::TimesI TimesISIMD;
|
||||||
|
@ -189,6 +189,29 @@ namespace Optimization {
|
|||||||
// 2mul,4 mac +add+sub = 8 flop type insns
|
// 2mul,4 mac +add+sub = 8 flop type insns
|
||||||
// 3shuf + 2 (+shuf) = 5/6 simd perm and 1/2 the load.
|
// 3shuf + 2 (+shuf) = 5/6 simd perm and 1/2 the load.
|
||||||
|
|
||||||
|
struct MultRealPart{
|
||||||
|
inline __m512 operator()(__m512 a, __m512 b){
|
||||||
|
__m512 ymm0;
|
||||||
|
ymm0 = _mm512_moveldup_ps(a); // ymm0 <- ar ar,
|
||||||
|
return _mm512_mul_ps(ymm0,b); // ymm0 <- ar bi, ar br
|
||||||
|
}
|
||||||
|
inline __m512d operator()(__m512d a, __m512d b){
|
||||||
|
__m512d ymm0;
|
||||||
|
ymm0 = _mm512_shuffle_pd(a,a,0x00); // ymm0 <- ar ar, ar,ar b'00,00
|
||||||
|
return _mm512_mul_pd(ymm0,b); // ymm0 <- ar bi, ar br
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct MaddRealPart{
|
||||||
|
inline __m512 operator()(__m512 a, __m512 b, __m512 c){
|
||||||
|
__m512 ymm0 = _mm512_moveldup_ps(a); // ymm0 <- ar ar,
|
||||||
|
return _mm512_fmadd_ps( ymm0, b, c);
|
||||||
|
}
|
||||||
|
inline __m512d operator()(__m512d a, __m512d b, __m512d c){
|
||||||
|
__m512d ymm0 = _mm512_shuffle_pd( a, a, 0x00 );
|
||||||
|
return _mm512_fmadd_pd( ymm0, b, c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct MultComplex{
|
struct MultComplex{
|
||||||
// Complex float
|
// Complex float
|
||||||
inline __m512 operator()(__m512 a, __m512 b){
|
inline __m512 operator()(__m512 a, __m512 b){
|
||||||
@ -501,6 +524,8 @@ namespace Optimization {
|
|||||||
typedef Optimization::Mult MultSIMD;
|
typedef Optimization::Mult MultSIMD;
|
||||||
typedef Optimization::Div DivSIMD;
|
typedef Optimization::Div DivSIMD;
|
||||||
typedef Optimization::MultComplex MultComplexSIMD;
|
typedef Optimization::MultComplex MultComplexSIMD;
|
||||||
|
typedef Optimization::MultRealPart MultRealPartSIMD;
|
||||||
|
typedef Optimization::MaddRealPart MaddRealPartSIMD;
|
||||||
typedef Optimization::Conj ConjSIMD;
|
typedef Optimization::Conj ConjSIMD;
|
||||||
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
||||||
typedef Optimization::TimesI TimesISIMD;
|
typedef Optimization::TimesI TimesISIMD;
|
||||||
|
@ -224,6 +224,21 @@ namespace Optimization {
|
|||||||
#define cmul(a, b, c, i)\
|
#define cmul(a, b, c, i)\
|
||||||
c[i] = a[i]*b[i] - a[i+1]*b[i+1];\
|
c[i] = a[i]*b[i] - a[i+1]*b[i+1];\
|
||||||
c[i+1] = a[i]*b[i+1] + a[i+1]*b[i];
|
c[i+1] = a[i]*b[i+1] + a[i+1]*b[i];
|
||||||
|
|
||||||
|
struct MultRealPart{
|
||||||
|
template <typename T>
|
||||||
|
inline vec<T> operator()(vec<T> a, vec<T> b){
|
||||||
|
vec<T> out;
|
||||||
|
|
||||||
|
VECTOR_FOR(i, W<T>::c, 1)
|
||||||
|
{
|
||||||
|
out.v[2*i] = a[2*i]*b[2*i];
|
||||||
|
out.v[2*i+1] = a[2*i]*b[2*i+1];
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct MultComplex{
|
struct MultComplex{
|
||||||
// Complex
|
// Complex
|
||||||
@ -456,6 +471,7 @@ namespace Optimization {
|
|||||||
typedef Optimization::Div DivSIMD;
|
typedef Optimization::Div DivSIMD;
|
||||||
typedef Optimization::Mult MultSIMD;
|
typedef Optimization::Mult MultSIMD;
|
||||||
typedef Optimization::MultComplex MultComplexSIMD;
|
typedef Optimization::MultComplex MultComplexSIMD;
|
||||||
|
typedef Optimization::MultRealPart MultRealPartSIMD;
|
||||||
typedef Optimization::Conj ConjSIMD;
|
typedef Optimization::Conj ConjSIMD;
|
||||||
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
||||||
typedef Optimization::TimesI TimesISIMD;
|
typedef Optimization::TimesI TimesISIMD;
|
||||||
|
@ -220,6 +220,14 @@ namespace Optimization {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MultRealPart{
|
||||||
|
// Complex double
|
||||||
|
inline vector4double operator()(vector4double a, vector4double b){
|
||||||
|
// return vec_xmul(b, a);
|
||||||
|
return vec_xmul(a, b);
|
||||||
|
}
|
||||||
|
FLOAT_WRAP_2(operator(), inline)
|
||||||
|
};
|
||||||
struct MultComplex{
|
struct MultComplex{
|
||||||
// Complex double
|
// Complex double
|
||||||
inline vector4double operator()(vector4double a, vector4double b){
|
inline vector4double operator()(vector4double a, vector4double b){
|
||||||
@ -430,6 +438,7 @@ typedef Optimization::Sub SubSIMD;
|
|||||||
typedef Optimization::Mult MultSIMD;
|
typedef Optimization::Mult MultSIMD;
|
||||||
typedef Optimization::Div DivSIMD;
|
typedef Optimization::Div DivSIMD;
|
||||||
typedef Optimization::MultComplex MultComplexSIMD;
|
typedef Optimization::MultComplex MultComplexSIMD;
|
||||||
|
typedef Optimization::MultRealPart MultRealPartSIMD;
|
||||||
typedef Optimization::Conj ConjSIMD;
|
typedef Optimization::Conj ConjSIMD;
|
||||||
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
||||||
typedef Optimization::TimesI TimesISIMD;
|
typedef Optimization::TimesI TimesISIMD;
|
||||||
|
@ -177,6 +177,29 @@ namespace Optimization {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MultRealPart{
|
||||||
|
inline __m128 operator()(__m128 a, __m128 b){
|
||||||
|
__m128 ymm0;
|
||||||
|
ymm0 = _mm_shuffle_ps(a,a,_MM_SELECT_FOUR_FOUR(2,2,0,0)); // ymm0 <- ar ar,
|
||||||
|
return _mm_mul_ps(ymm0,b); // ymm0 <- ar bi, ar br
|
||||||
|
}
|
||||||
|
inline __m128d operator()(__m128d a, __m128d b){
|
||||||
|
__m128d ymm0;
|
||||||
|
ymm0 = _mm_shuffle_pd(a,a,0x0); // ymm0 <- ar ar, ar,ar b'00,00
|
||||||
|
return _mm_mul_pd(ymm0,b); // ymm0 <- ar bi, ar br
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct MaddRealPart{
|
||||||
|
inline __m128 operator()(__m128 a, __m128 b, __m128 c){
|
||||||
|
__m128 ymm0 = _mm_shuffle_ps(a,a,_MM_SELECT_FOUR_FOUR(2,2,0,0)); // ymm0 <- ar ar,
|
||||||
|
return _mm_add_ps(_mm_mul_ps( ymm0, b),c);
|
||||||
|
}
|
||||||
|
inline __m128d operator()(__m128d a, __m128d b, __m128d c){
|
||||||
|
__m128d ymm0 = _mm_shuffle_pd( a, a, 0x0 );
|
||||||
|
return _mm_add_pd(_mm_mul_pd( ymm0, b),c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct MultComplex{
|
struct MultComplex{
|
||||||
// Complex float
|
// Complex float
|
||||||
inline __m128 operator()(__m128 a, __m128 b){
|
inline __m128 operator()(__m128 a, __m128 b){
|
||||||
@ -325,9 +348,11 @@ namespace Optimization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _mm_alignr_epi64
|
||||||
#define _mm_alignr_epi32(a,b,n) _mm_alignr_epi8(a,b,(n*4)%16)
|
#define _mm_alignr_epi32(a,b,n) _mm_alignr_epi8(a,b,(n*4)%16)
|
||||||
#define _mm_alignr_epi64(a,b,n) _mm_alignr_epi8(a,b,(n*8)%16)
|
#define _mm_alignr_epi64(a,b,n) _mm_alignr_epi8(a,b,(n*8)%16)
|
||||||
|
#endif
|
||||||
|
|
||||||
template<int n> static inline __m128 tRotate(__m128 in){ return (__m128)_mm_alignr_epi32((__m128i)in,(__m128i)in,n); };
|
template<int n> static inline __m128 tRotate(__m128 in){ return (__m128)_mm_alignr_epi32((__m128i)in,(__m128i)in,n); };
|
||||||
template<int n> static inline __m128d tRotate(__m128d in){ return (__m128d)_mm_alignr_epi64((__m128i)in,(__m128i)in,n); };
|
template<int n> static inline __m128d tRotate(__m128d in){ return (__m128d)_mm_alignr_epi64((__m128i)in,(__m128i)in,n); };
|
||||||
|
|
||||||
@ -415,6 +440,8 @@ namespace Optimization {
|
|||||||
typedef Optimization::Div DivSIMD;
|
typedef Optimization::Div DivSIMD;
|
||||||
typedef Optimization::Mult MultSIMD;
|
typedef Optimization::Mult MultSIMD;
|
||||||
typedef Optimization::MultComplex MultComplexSIMD;
|
typedef Optimization::MultComplex MultComplexSIMD;
|
||||||
|
typedef Optimization::MultRealPart MultRealPartSIMD;
|
||||||
|
typedef Optimization::MaddRealPart MaddRealPartSIMD;
|
||||||
typedef Optimization::Conj ConjSIMD;
|
typedef Optimization::Conj ConjSIMD;
|
||||||
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
typedef Optimization::TimesMinusI TimesMinusISIMD;
|
||||||
typedef Optimization::TimesI TimesISIMD;
|
typedef Optimization::TimesI TimesISIMD;
|
||||||
|
@ -101,6 +101,11 @@ template <typename T> using IfNotInteger = Invoke<std::enable_if<!std::is_integr
|
|||||||
// general forms to allow for vsplat syntax
|
// general forms to allow for vsplat syntax
|
||||||
// need explicit declaration of types when used since
|
// need explicit declaration of types when used since
|
||||||
// clang cannot automatically determine the output type sometimes
|
// clang cannot automatically determine the output type sometimes
|
||||||
|
template <class Out, class Input1, class Input2, class Input3, class Operation>
|
||||||
|
Out trinary(Input1 src_1, Input2 src_2, Input3 src_3, Operation op) {
|
||||||
|
return op(src_1, src_2, src_3);
|
||||||
|
}
|
||||||
|
|
||||||
template <class Out, class Input1, class Input2, class Operation>
|
template <class Out, class Input1, class Input2, class Operation>
|
||||||
Out binary(Input1 src_1, Input2 src_2, Operation op) {
|
Out binary(Input1 src_1, Input2 src_2, Operation op) {
|
||||||
return op(src_1, src_2);
|
return op(src_1, src_2);
|
||||||
@ -178,6 +183,7 @@ class Grid_simd {
|
|||||||
const Grid_simd *__restrict__ r) {
|
const Grid_simd *__restrict__ r) {
|
||||||
*y = (*l) * (*r);
|
*y = (*l) * (*r);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend inline void sub(Grid_simd *__restrict__ y,
|
friend inline void sub(Grid_simd *__restrict__ y,
|
||||||
const Grid_simd *__restrict__ l,
|
const Grid_simd *__restrict__ l,
|
||||||
const Grid_simd *__restrict__ r) {
|
const Grid_simd *__restrict__ r) {
|
||||||
@ -188,7 +194,6 @@ class Grid_simd {
|
|||||||
const Grid_simd *__restrict__ r) {
|
const Grid_simd *__restrict__ r) {
|
||||||
*y = (*l) + (*r);
|
*y = (*l) + (*r);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend inline void mac(Grid_simd *__restrict__ y,
|
friend inline void mac(Grid_simd *__restrict__ y,
|
||||||
const Scalar_type *__restrict__ a,
|
const Scalar_type *__restrict__ a,
|
||||||
const Grid_simd *__restrict__ x) {
|
const Grid_simd *__restrict__ x) {
|
||||||
@ -260,7 +265,7 @@ class Grid_simd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
// opreator scalar * simd
|
// operator scalar * simd
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
friend inline Grid_simd operator*(const Scalar_type &a, Grid_simd b) {
|
friend inline Grid_simd operator*(const Scalar_type &a, Grid_simd b) {
|
||||||
Grid_simd va;
|
Grid_simd va;
|
||||||
@ -446,6 +451,11 @@ inline void vbroadcast(Grid_simd<S,V> &ret,const Grid_simd<S,V> &src,int lane){
|
|||||||
S* typepun =(S*) &src;
|
S* typepun =(S*) &src;
|
||||||
vsplat(ret,typepun[lane]);
|
vsplat(ret,typepun[lane]);
|
||||||
}
|
}
|
||||||
|
template <class S, class V, IfComplex<S> =0>
|
||||||
|
inline void rbroadcast(Grid_simd<S,V> &ret,const Grid_simd<S,V> &src,int lane){
|
||||||
|
S* typepun =(S*) &src;
|
||||||
|
ret.v = unary<V>(real(typepun[lane]), VsplatSIMD());
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////
|
///////////////////////
|
||||||
// Splat
|
// Splat
|
||||||
@ -462,6 +472,10 @@ template <class S, class V>
|
|||||||
inline void vsplat(Grid_simd<S, V> &ret, EnableIf<is_complex<S>, S> c) {
|
inline void vsplat(Grid_simd<S, V> &ret, EnableIf<is_complex<S>, S> c) {
|
||||||
vsplat(ret, real(c), imag(c));
|
vsplat(ret, real(c), imag(c));
|
||||||
}
|
}
|
||||||
|
template <class S, class V>
|
||||||
|
inline void rsplat(Grid_simd<S, V> &ret, EnableIf<is_complex<S>, S> c) {
|
||||||
|
vsplat(ret, real(c), real(c));
|
||||||
|
}
|
||||||
|
|
||||||
// if real fill with a, if complex fill with a in the real part (first function
|
// if real fill with a, if complex fill with a in the real part (first function
|
||||||
// above)
|
// above)
|
||||||
@ -563,6 +577,21 @@ inline Grid_simd<S, V> operator-(Grid_simd<S, V> a, Grid_simd<S, V> b) {
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Distinguish between complex types and others
|
||||||
|
template <class S, class V, IfComplex<S> = 0>
|
||||||
|
inline Grid_simd<S, V> real_mult(Grid_simd<S, V> a, Grid_simd<S, V> b) {
|
||||||
|
Grid_simd<S, V> ret;
|
||||||
|
ret.v = binary<V>(a.v, b.v, MultRealPartSIMD());
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
template <class S, class V, IfComplex<S> = 0>
|
||||||
|
inline Grid_simd<S, V> real_madd(Grid_simd<S, V> a, Grid_simd<S, V> b, Grid_simd<S,V> c) {
|
||||||
|
Grid_simd<S, V> ret;
|
||||||
|
ret.v = trinary<V>(a.v, b.v, c.v, MaddRealPartSIMD());
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Distinguish between complex types and others
|
// Distinguish between complex types and others
|
||||||
template <class S, class V, IfComplex<S> = 0>
|
template <class S, class V, IfComplex<S> = 0>
|
||||||
inline Grid_simd<S, V> operator*(Grid_simd<S, V> a, Grid_simd<S, V> b) {
|
inline Grid_simd<S, V> operator*(Grid_simd<S, V> a, Grid_simd<S, V> b) {
|
||||||
|
@ -95,10 +95,14 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
#define VIDUPd(SRC,DEST) "vpshufd $0xee," #SRC"," #DEST ";\n" // 32 bit level: 3,2,3,2
|
#define VIDUPd(SRC,DEST) "vpshufd $0xee," #SRC"," #DEST ";\n" // 32 bit level: 3,2,3,2
|
||||||
#define VIDUPf(SRC,DEST) "vmovshdup " #SRC ", " #DEST ";\n"
|
#define VIDUPf(SRC,DEST) "vmovshdup " #SRC ", " #DEST ";\n"
|
||||||
|
|
||||||
#define VBCASTRDUPd(OFF,A,DEST) "vbroadcastsd (" #OFF "*16+0)(" #A ")," #DEST ";\n"
|
#define VBCASTRDUPd(OFF,A,DEST) "vbroadcastsd (" #OFF "*16+0)(" #A ")," #DEST ";\n"
|
||||||
#define VBCASTIDUPd(OFF,A,DEST) "vbroadcastsd (" #OFF "*16+8)(" #A ")," #DEST ";\n"
|
#define VBCASTIDUPd(OFF,A,DEST) "vbroadcastsd (" #OFF "*16+8)(" #A ")," #DEST ";\n"
|
||||||
#define VBCASTRDUPf(OFF,PTR,DEST) "vbroadcastss (" #OFF "*8 +0)(" #PTR "), " #DEST ";\n"
|
#define VBCASTRDUPf(OFF,PTR,DEST) "vbroadcastss (" #OFF "*8 +0)(" #PTR "), " #DEST ";\n"
|
||||||
#define VBCASTIDUPf(OFF,PTR,DEST) "vbroadcastss (" #OFF "*8 +4)(" #PTR "), " #DEST ";\n"
|
#define VBCASTIDUPf(OFF,PTR,DEST) "vbroadcastss (" #OFF "*8 +4)(" #PTR "), " #DEST ";\n"
|
||||||
|
#define VBCASTCDUPf(OFF,A,DEST) "vbroadcastsd (" #OFF "*64 )(" #A ")," #DEST ";\n"
|
||||||
|
#define VBCASTZDUPf(OFF,A,DEST) "vbroadcastf32x4 (" #OFF "*64 )(" #A ")," #DEST ";\n"
|
||||||
|
#define VBCASTCDUP(OFF,A,DEST) VBCASTCDUPf(OFF,A,DEST)
|
||||||
|
#define VBCASTZDUP(OFF,A,DEST) VBCASTZDUPf(OFF,A,DEST)
|
||||||
|
|
||||||
#define VMADDSUBf(A,B,accum) "vfmaddsub231ps " #A "," #B "," #accum ";\n"
|
#define VMADDSUBf(A,B,accum) "vfmaddsub231ps " #A "," #B "," #accum ";\n"
|
||||||
#define VMADDSUBd(A,B,accum) "vfmaddsub231pd " #A "," #B "," #accum ";\n"
|
#define VMADDSUBd(A,B,accum) "vfmaddsub231pd " #A "," #B "," #accum ";\n"
|
||||||
@ -106,11 +110,15 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
#define VMADDSUBMEMd(O,P,B,accum) "vfmaddsub231pd " #O"*64("#P "),"#B "," #accum ";\n"
|
#define VMADDSUBMEMd(O,P,B,accum) "vfmaddsub231pd " #O"*64("#P "),"#B "," #accum ";\n"
|
||||||
|
|
||||||
|
|
||||||
|
#define VMADDRDUPf(O,P,B,accum) "vfmadd231ps (" #O"*8+0)("#P "){1to16},"#B "," #accum ";\n"
|
||||||
|
#define VMADDIDUPf(O,P,B,accum) "vfmadd231ps (" #O"*8+4)("#P "){1to16},"#B "," #accum ";\n"
|
||||||
#define VMADDSUBRDUPf(O,P,B,accum) "vfmaddsub231ps (" #O"*8+0)("#P "){1to16},"#B "," #accum ";\n"
|
#define VMADDSUBRDUPf(O,P,B,accum) "vfmaddsub231ps (" #O"*8+0)("#P "){1to16},"#B "," #accum ";\n"
|
||||||
#define VMADDSUBIDUPf(O,P,B,accum) "vfmaddsub231ps (" #O"*8+4)("#P "){1to16},"#B "," #accum ";\n"
|
#define VMADDSUBIDUPf(O,P,B,accum) "vfmaddsub231ps (" #O"*8+4)("#P "){1to16},"#B "," #accum ";\n"
|
||||||
#define VMULRDUPf(O,P,B,accum) "vmulps (" #O"*8+0)("#P "){1to16},"#B "," #accum ";\n"
|
#define VMULRDUPf(O,P,B,accum) "vmulps (" #O"*8+0)("#P "){1to16},"#B "," #accum ";\n"
|
||||||
#define VMULIDUPf(O,P,B,accum) "vmulps (" #O"*8+4)("#P "){1to16},"#B "," #accum ";\n"
|
#define VMULIDUPf(O,P,B,accum) "vmulps (" #O"*8+4)("#P "){1to16},"#B "," #accum ";\n"
|
||||||
|
|
||||||
|
#define VMADDRDUPd(O,P,B,accum) "vfmadd231pd (" #O"*16+0)("#P "){1to8},"#B "," #accum ";\n"
|
||||||
|
#define VMADDIDUPd(O,P,B,accum) "vfmadd231pd (" #O"*16+8)("#P "){1to8},"#B "," #accum ";\n"
|
||||||
#define VMADDSUBRDUPd(O,P,B,accum) "vfmaddsub231pd (" #O"*16+0)("#P "){1to8},"#B "," #accum ";\n"
|
#define VMADDSUBRDUPd(O,P,B,accum) "vfmaddsub231pd (" #O"*16+0)("#P "){1to8},"#B "," #accum ";\n"
|
||||||
#define VMADDSUBIDUPd(O,P,B,accum) "vfmaddsub231pd (" #O"*16+8)("#P "){1to8},"#B "," #accum ";\n"
|
#define VMADDSUBIDUPd(O,P,B,accum) "vfmaddsub231pd (" #O"*16+8)("#P "){1to8},"#B "," #accum ";\n"
|
||||||
#define VMULRDUPd(O,P,B,accum) "vmulpd (" #O"*16+0)("#P "){1to8},"#B "," #accum ";\n"
|
#define VMULRDUPd(O,P,B,accum) "vmulpd (" #O"*16+0)("#P "){1to8},"#B "," #accum ";\n"
|
||||||
|
@ -87,7 +87,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
VACCTIMESMINUSI1d(A,ACC,tmp) \
|
VACCTIMESMINUSI1d(A,ACC,tmp) \
|
||||||
VACCTIMESMINUSI2d(A,ACC,tmp)
|
VACCTIMESMINUSI2d(A,ACC,tmp)
|
||||||
|
|
||||||
#define LOAD64i(A,ptr) __asm__ ( "movq %0, %" #A : : "r"(ptr) : #A );
|
#define LOAD64a(A,ptr) "movq %0, %" #A : : "r"(ptr) : #A
|
||||||
|
#define LOAD64i(A,ptr) __asm__ ( LOAD64a(A,ptr));
|
||||||
#define LOAD64(A,ptr) LOAD64i(A,ptr)
|
#define LOAD64(A,ptr) LOAD64i(A,ptr)
|
||||||
|
|
||||||
#define VMOVf(A,DEST) "vmovaps " #A ", " #DEST ";\n"
|
#define VMOVf(A,DEST) "vmovaps " #A ", " #DEST ";\n"
|
||||||
@ -108,8 +109,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
//"vprefetche0 "#O"*64("#A");\n" "vprefetche1 ("#O"+12)*64("#A");\n"
|
//"vprefetche0 "#O"*64("#A");\n" "vprefetche1 ("#O"+12)*64("#A");\n"
|
||||||
// "clevict0 "#O"*64("#A");\n"
|
// "clevict0 "#O"*64("#A");\n"
|
||||||
|
|
||||||
#define VLOADf(OFF,PTR,DEST) "vmovaps " #OFF "*64(" #PTR "), " #DEST ";\n"
|
#define VLOADf(OFF,PTR,DEST) "vmovups " #OFF "*64(" #PTR "), " #DEST ";\n"
|
||||||
#define VLOADd(OFF,PTR,DEST) "vmovapd " #OFF "*64(" #PTR "), " #DEST ";\n"
|
#define VLOADd(OFF,PTR,DEST) "vmovupd " #OFF "*64(" #PTR "), " #DEST ";\n"
|
||||||
|
|
||||||
#define VADDf(A,B,DEST) "vaddps " #A "," #B "," #DEST ";\n"
|
#define VADDf(A,B,DEST) "vaddps " #A "," #B "," #DEST ";\n"
|
||||||
#define VADDd(A,B,DEST) "vaddpd " #A "," #B "," #DEST ";\n"
|
#define VADDd(A,B,DEST) "vaddpd " #A "," #B "," #DEST ";\n"
|
||||||
@ -143,8 +144,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
#define VSTOREf(OFF,PTR,SRC) "vmovntps " #SRC "," #OFF "*64(" #PTR ")" ";\n"
|
#define VSTOREf(OFF,PTR,SRC) "vmovntps " #SRC "," #OFF "*64(" #PTR ")" ";\n"
|
||||||
#define VSTOREd(OFF,PTR,SRC) "vmovntpd " #SRC "," #OFF "*64(" #PTR ")" ";\n"
|
#define VSTOREd(OFF,PTR,SRC) "vmovntpd " #SRC "," #OFF "*64(" #PTR ")" ";\n"
|
||||||
#else
|
#else
|
||||||
#define VSTOREf(OFF,PTR,SRC) "vmovaps " #SRC "," #OFF "*64(" #PTR ")" ";\n"
|
#define VSTOREf(OFF,PTR,SRC) "vmovups " #SRC "," #OFF "*64(" #PTR ")" ";\n"
|
||||||
#define VSTOREd(OFF,PTR,SRC) "vmovapd " #SRC "," #OFF "*64(" #PTR ")" ";\n"
|
#define VSTOREd(OFF,PTR,SRC) "vmovupd " #SRC "," #OFF "*64(" #PTR ")" ";\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Swaps Re/Im ; could unify this with IMCI
|
// Swaps Re/Im ; could unify this with IMCI
|
||||||
|
@ -144,10 +144,12 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
#define VMADDSUBMEM(O,P,B,accum) VMADDSUBMEMd(O,P,B,accum)
|
#define VMADDSUBMEM(O,P,B,accum) VMADDSUBMEMd(O,P,B,accum)
|
||||||
#define VMADDMEM(O,P,B,accum) VMADDMEMd(O,P,B,accum)
|
#define VMADDMEM(O,P,B,accum) VMADDMEMd(O,P,B,accum)
|
||||||
#define VMULMEM(O,P,B,accum) VMULMEMd(O,P,B,accum)
|
#define VMULMEM(O,P,B,accum) VMULMEMd(O,P,B,accum)
|
||||||
|
#undef VMADDRDUP
|
||||||
#undef VMADDSUBRDUP
|
#undef VMADDSUBRDUP
|
||||||
#undef VMADDSUBIDUP
|
#undef VMADDSUBIDUP
|
||||||
#undef VMULRDUP
|
#undef VMULRDUP
|
||||||
#undef VMULIDUP
|
#undef VMULIDUP
|
||||||
|
#define VMADDRDUP(O,P,B,accum) VMADDRDUPd(O,P,B,accum)
|
||||||
#define VMADDSUBRDUP(O,P,B,accum) VMADDSUBRDUPd(O,P,B,accum)
|
#define VMADDSUBRDUP(O,P,B,accum) VMADDSUBRDUPd(O,P,B,accum)
|
||||||
#define VMADDSUBIDUP(O,P,B,accum) VMADDSUBIDUPd(O,P,B,accum)
|
#define VMADDSUBIDUP(O,P,B,accum) VMADDSUBIDUPd(O,P,B,accum)
|
||||||
#define VMULRDUP(O,P,B,accum) VMULRDUPd(O,P,B,accum)
|
#define VMULRDUP(O,P,B,accum) VMULRDUPd(O,P,B,accum)
|
||||||
|
@ -144,10 +144,12 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
#define VMADDMEM(O,P,B,accum) VMADDMEMf(O,P,B,accum)
|
#define VMADDMEM(O,P,B,accum) VMADDMEMf(O,P,B,accum)
|
||||||
#define VMULMEM(O,P,B,accum) VMULMEMf(O,P,B,accum)
|
#define VMULMEM(O,P,B,accum) VMULMEMf(O,P,B,accum)
|
||||||
|
|
||||||
|
#undef VMADDRDUP
|
||||||
#undef VMADDSUBRDUP
|
#undef VMADDSUBRDUP
|
||||||
#undef VMADDSUBIDUP
|
#undef VMADDSUBIDUP
|
||||||
#undef VMULRDUP
|
#undef VMULRDUP
|
||||||
#undef VMULIDUP
|
#undef VMULIDUP
|
||||||
|
#define VMADDRDUP(O,P,B,accum) VMADDRDUPf(O,P,B,accum)
|
||||||
#define VMADDSUBRDUP(O,P,B,accum) VMADDSUBRDUPf(O,P,B,accum)
|
#define VMADDSUBRDUP(O,P,B,accum) VMADDSUBRDUPf(O,P,B,accum)
|
||||||
#define VMADDSUBIDUP(O,P,B,accum) VMADDSUBIDUPf(O,P,B,accum)
|
#define VMADDSUBIDUP(O,P,B,accum) VMADDSUBIDUPf(O,P,B,accum)
|
||||||
#define VMULRDUP(O,P,B,accum) VMULRDUPf(O,P,B,accum)
|
#define VMULRDUP(O,P,B,accum) VMULRDUPf(O,P,B,accum)
|
||||||
|
@ -65,7 +65,7 @@ void LebesgueOrder::CartesianBlocking(void)
|
|||||||
{
|
{
|
||||||
_LebesgueReorder.resize(0);
|
_LebesgueReorder.resize(0);
|
||||||
|
|
||||||
std::cout << GridLogDebug << " CartesianBlocking ";
|
// std::cout << GridLogDebug << " CartesianBlocking ";
|
||||||
// for(int d=0;d<Block.size();d++) std::cout <<Block[d]<<" ";
|
// for(int d=0;d<Block.size();d++) std::cout <<Block[d]<<" ";
|
||||||
// std::cout<<std::endl;
|
// std::cout<<std::endl;
|
||||||
|
|
||||||
|
@ -4,9 +4,8 @@ home=`pwd`
|
|||||||
|
|
||||||
# library Make.inc
|
# library Make.inc
|
||||||
cd $home/lib
|
cd $home/lib
|
||||||
HFILES=`find . -type f -name '*.h' -not -path '*/Old/*' -not -path '*/Eigen/*'`
|
HFILES=`find . -type f -name '*.h' -not -name '*Hdf5*' -not -path '*/Old/*' -not -path '*/Eigen/*'`
|
||||||
HFILES="$HFILES"
|
CCFILES=`find . -type f -name '*.cc' -not -name '*Communicator*.cc' -not -name '*Hdf5*'`
|
||||||
CCFILES=`find . -type f -name '*.cc' -not -name '*ommunicator*.cc'`
|
|
||||||
echo HFILES=$HFILES > Make.inc
|
echo HFILES=$HFILES > Make.inc
|
||||||
echo >> Make.inc
|
echo >> Make.inc
|
||||||
echo CCFILES=$CCFILES >> Make.inc
|
echo CCFILES=$CCFILES >> Make.inc
|
||||||
@ -24,10 +23,11 @@ for subdir in $dirs; do
|
|||||||
echo "tests: ${TESTLIST} ${SUB}" > Make.inc
|
echo "tests: ${TESTLIST} ${SUB}" > Make.inc
|
||||||
echo ${PREF}_PROGRAMS = ${TESTLIST} >> Make.inc
|
echo ${PREF}_PROGRAMS = ${TESTLIST} >> Make.inc
|
||||||
echo >> Make.inc
|
echo >> Make.inc
|
||||||
|
HADLINK=`[ $subdir = './hadrons' ] && echo '-lHadrons '`
|
||||||
for f in $TESTS; do
|
for f in $TESTS; do
|
||||||
BNAME=`basename $f .cc`
|
BNAME=`basename $f .cc`
|
||||||
echo ${BNAME}_SOURCES=$f >> Make.inc
|
echo ${BNAME}_SOURCES=$f >> Make.inc
|
||||||
echo ${BNAME}_LDADD=-lGrid>> Make.inc
|
echo ${BNAME}_LDADD=${HADLINK}-lGrid >> Make.inc
|
||||||
echo >> Make.inc
|
echo >> Make.inc
|
||||||
done
|
done
|
||||||
if [ $subdir != '.' ]; then
|
if [ $subdir != '.' ]; then
|
||||||
|
@ -29,132 +29,155 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|||||||
/* END LEGAL */
|
/* END LEGAL */
|
||||||
#include <Grid/Grid.h>
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
namespace Grid {
|
|
||||||
|
|
||||||
GRID_SERIALIZABLE_ENUM(myenum, undef, red, 1, blue, 2, green, 3);
|
|
||||||
|
|
||||||
class myclass: Serializable {
|
|
||||||
public:
|
|
||||||
|
|
||||||
GRID_SERIALIZABLE_CLASS_MEMBERS(myclass,
|
|
||||||
myenum, e,
|
|
||||||
std::vector<myenum>, ve,
|
|
||||||
std::string, name,
|
|
||||||
int, x,
|
|
||||||
double, y,
|
|
||||||
bool , b,
|
|
||||||
std::vector<double>, array,
|
|
||||||
std::vector<std::vector<double>>, twodimarray,
|
|
||||||
);
|
|
||||||
|
|
||||||
myclass() {}
|
|
||||||
myclass(int i)
|
|
||||||
: array(4,5.1), twodimarray(3,std::vector<double>(2,1.23456)), ve({myenum::blue, myenum::red})
|
|
||||||
{
|
|
||||||
e=myenum::red;
|
|
||||||
x=i;
|
|
||||||
y=2*i;
|
|
||||||
b=true;
|
|
||||||
name="bother said pooh";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace Grid;
|
using namespace Grid;
|
||||||
|
|
||||||
int16_t i16 = 1;
|
GRID_SERIALIZABLE_ENUM(myenum, undef, red, 1, blue, 2, green, 3);
|
||||||
|
|
||||||
|
class myclass: Serializable {
|
||||||
|
public:
|
||||||
|
GRID_SERIALIZABLE_CLASS_MEMBERS(myclass,
|
||||||
|
myenum, e,
|
||||||
|
std::vector<myenum>, ve,
|
||||||
|
std::string, name,
|
||||||
|
int, x,
|
||||||
|
double, y,
|
||||||
|
bool , b,
|
||||||
|
std::vector<double>, array,
|
||||||
|
std::vector<std::vector<double>>, twodimarray,
|
||||||
|
std::vector<std::vector<std::vector<Complex>>>, cmplx3darray
|
||||||
|
);
|
||||||
|
myclass() {}
|
||||||
|
myclass(int i)
|
||||||
|
: array(4,5.1)
|
||||||
|
, twodimarray(3,std::vector<double>(5, 1.23456))
|
||||||
|
, cmplx3darray(3,std::vector<std::vector<Complex>>(5, std::vector<Complex>(7, Complex(1.2, 3.4))))
|
||||||
|
, ve(2, myenum::blue)
|
||||||
|
{
|
||||||
|
e=myenum::red;
|
||||||
|
x=i;
|
||||||
|
y=2*i;
|
||||||
|
b=true;
|
||||||
|
name="bother said pooh";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int16_t i16 = 1;
|
||||||
uint16_t u16 = 2;
|
uint16_t u16 = 2;
|
||||||
int32_t i32 = 3;
|
int32_t i32 = 3;
|
||||||
uint32_t u32 = 4;
|
uint32_t u32 = 4;
|
||||||
int64_t i64 = 5;
|
int64_t i64 = 5;
|
||||||
uint64_t u64 = 6;
|
uint64_t u64 = 6;
|
||||||
float f = M_PI;
|
float f = M_PI;
|
||||||
double d = 2*M_PI;
|
double d = 2*M_PI;
|
||||||
bool b = false;
|
bool b = false;
|
||||||
|
|
||||||
|
template <typename W, typename R, typename O>
|
||||||
|
void ioTest(const std::string &filename, const O &object, const std::string &name)
|
||||||
|
{
|
||||||
|
// 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");
|
||||||
|
std::cout << std::endl;
|
||||||
|
if (!good) exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc,char **argv)
|
int main(int argc,char **argv)
|
||||||
{
|
{
|
||||||
{
|
std::cout << "==== basic IO" << std::endl;
|
||||||
XmlWriter WR("bother.xml");
|
XmlWriter WR("bother.xml");
|
||||||
|
|
||||||
// test basic type writing
|
// test basic type writing
|
||||||
push(WR,"BasicTypes");
|
std::cout << "-- basic writing to 'bother.xml'..." << std::endl;
|
||||||
write(WR,std::string("i16"),i16);
|
push(WR,"BasicTypes");
|
||||||
write(WR,"u16",u16);
|
write(WR,std::string("i16"),i16);
|
||||||
write(WR,"i32",i32);
|
write(WR,"u16",u16);
|
||||||
write(WR,"u32",u32);
|
write(WR,"i32",i32);
|
||||||
write(WR,"i64",i64);
|
write(WR,"u32",u32);
|
||||||
write(WR,"u64",u64);
|
write(WR,"i64",i64);
|
||||||
write(WR,"f",f);
|
write(WR,"u64",u64);
|
||||||
write(WR,"d",d);
|
write(WR,"f",f);
|
||||||
write(WR,"b",b);
|
write(WR,"d",d);
|
||||||
pop(WR);
|
write(WR,"b",b);
|
||||||
|
pop(WR);
|
||||||
// test serializable class writing
|
|
||||||
myclass obj(1234); // non-trivial constructor
|
// test serializable class writing
|
||||||
write(WR,"obj",obj);
|
myclass obj(1234); // non-trivial constructor
|
||||||
WR.write("obj2", obj);
|
std::vector<myclass> vec;
|
||||||
std::cout << obj << std::endl;
|
|
||||||
|
std::cout << "-- serialisable class writing to 'bother.xml'..." << std::endl;
|
||||||
std::vector<myclass> vec;
|
write(WR,"obj",obj);
|
||||||
vec.push_back(myclass(1234));
|
WR.write("obj2", obj);
|
||||||
vec.push_back(myclass(5678));
|
vec.push_back(myclass(1234));
|
||||||
vec.push_back(myclass(3838));
|
vec.push_back(myclass(5678));
|
||||||
write(WR, "objvec", vec);
|
vec.push_back(myclass(3838));
|
||||||
};
|
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;
|
||||||
|
|
||||||
// read tests
|
// read tests
|
||||||
myclass copy1, copy2, copy3;
|
std::cout << "\n==== IO self-consistency tests" << std::endl;
|
||||||
std::vector<myclass> veccopy1, veccopy2, veccopy3;
|
|
||||||
//// XML
|
//// XML
|
||||||
{
|
ioTest<XmlWriter, XmlReader>("iotest.xml", obj, "XML (object) ");
|
||||||
XmlReader RD("bother.xml");
|
ioTest<XmlWriter, XmlReader>("iotest.xml", vec, "XML (vector of objects)");
|
||||||
read(RD,"obj",copy1);
|
|
||||||
read(RD,"objvec", veccopy1);
|
|
||||||
std::cout << "Loaded (XML) -----------------" << std::endl;
|
|
||||||
std::cout << copy1 << std::endl << veccopy1 << std::endl;
|
|
||||||
}
|
|
||||||
//// binary
|
//// binary
|
||||||
{
|
ioTest<BinaryWriter, BinaryReader>("iotest.bin", obj, "binary (object) ");
|
||||||
BinaryWriter BWR("bother.bin");
|
ioTest<BinaryWriter, BinaryReader>("iotest.bin", vec, "binary (vector of objects)");
|
||||||
write(BWR,"discard",copy1 );
|
|
||||||
write(BWR,"discard",veccopy1 );
|
|
||||||
}
|
|
||||||
{
|
|
||||||
BinaryReader BRD("bother.bin");
|
|
||||||
read (BRD,"discard",copy2 );
|
|
||||||
read (BRD,"discard",veccopy2 );
|
|
||||||
std::cout << "Loaded (bin) -----------------" << std::endl;
|
|
||||||
std::cout << copy2 << std::endl << veccopy2 << std::endl;
|
|
||||||
}
|
|
||||||
//// text
|
//// text
|
||||||
{
|
ioTest<TextWriter, TextReader>("iotest.dat", obj, "text (object) ");
|
||||||
TextWriter TWR("bother.txt");
|
ioTest<TextWriter, TextReader>("iotest.dat", vec, "text (vector of objects)");
|
||||||
write(TWR,"discard",copy1 );
|
//// HDF5
|
||||||
write(TWR,"discard",veccopy1 );
|
#ifdef HAVE_HDF5
|
||||||
}
|
ioTest<Hdf5Writer, Hdf5Reader>("iotest.h5", obj, "HDF5 (object) ");
|
||||||
{
|
ioTest<Hdf5Writer, Hdf5Reader>("iotest.h5", vec, "HDF5 (vector of objects)");
|
||||||
TextReader TRD("bother.txt");
|
#endif
|
||||||
read (TRD,"discard",copy3 );
|
|
||||||
read (TRD,"discard",veccopy3 );
|
|
||||||
std::cout << "Loaded (txt) -----------------" << std::endl;
|
|
||||||
std::cout << copy3 << std::endl << veccopy3 << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> iv = strToVec<int>("1 2 2 4");
|
std::cout << "\n==== vector flattening/reconstruction" << std::endl;
|
||||||
std::vector<std::string> sv = strToVec<std::string>("bli bla blu");
|
typedef std::vector<std::vector<std::vector<double>>> vec3d;
|
||||||
|
|
||||||
for (auto &e: iv)
|
vec3d dv, buf;
|
||||||
|
double d = 0.;
|
||||||
|
|
||||||
|
dv.resize(4);
|
||||||
|
for (auto &v1: dv)
|
||||||
{
|
{
|
||||||
std::cout << e << " ";
|
v1.resize(3);
|
||||||
}
|
for (auto &v2: v1)
|
||||||
std::cout << std::endl;
|
{
|
||||||
for (auto &e: sv)
|
v2.resize(5);
|
||||||
{
|
for (auto &x: v2)
|
||||||
std::cout << e << " ";
|
{
|
||||||
|
x = d++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
||||||
@ -211,4 +234,6 @@ int main(int argc,char **argv)
|
|||||||
read(RD,"name", name);
|
read(RD,"name", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
3
tests/hadrons/Makefile.am
Normal file
3
tests/hadrons/Makefile.am
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
AM_LDFLAGS += -L../../extras/Hadrons
|
||||||
|
|
||||||
|
include Make.inc
|
170
tests/hadrons/Test_hadrons_meson_3pt.cc
Normal file
170
tests/hadrons/Test_hadrons_meson_3pt.cc
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: tests/hadrons/Test_hadrons_meson_3pt.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
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.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Application.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// initialization //////////////////////////////////////////////////////////
|
||||||
|
Grid_init(&argc, &argv);
|
||||||
|
HadronsLogError.Active(GridLogError.isActive());
|
||||||
|
HadronsLogWarning.Active(GridLogWarning.isActive());
|
||||||
|
HadronsLogMessage.Active(GridLogMessage.isActive());
|
||||||
|
HadronsLogIterative.Active(GridLogIterative.isActive());
|
||||||
|
HadronsLogDebug.Active(GridLogDebug.isActive());
|
||||||
|
LOG(Message) << "Grid initialized" << std::endl;
|
||||||
|
|
||||||
|
// run setup ///////////////////////////////////////////////////////////////
|
||||||
|
Application application;
|
||||||
|
std::vector<std::string> flavour = {"l", "s", "c1", "c2", "c3"};
|
||||||
|
std::vector<double> mass = {.01, .04, .2 , .25 , .3 };
|
||||||
|
unsigned int nt = GridDefaultLatt()[Tp];
|
||||||
|
|
||||||
|
// global parameters
|
||||||
|
Application::GlobalPar globalPar;
|
||||||
|
globalPar.trajCounter.start = 1500;
|
||||||
|
globalPar.trajCounter.end = 1520;
|
||||||
|
globalPar.trajCounter.step = 20;
|
||||||
|
globalPar.seed = "1 2 3 4";
|
||||||
|
globalPar.genetic.maxGen = 1000;
|
||||||
|
globalPar.genetic.maxCstGen = 200;
|
||||||
|
globalPar.genetic.popSize = 20;
|
||||||
|
globalPar.genetic.mutationRate = .1;
|
||||||
|
application.setPar(globalPar);
|
||||||
|
|
||||||
|
// gauge field
|
||||||
|
application.createModule<MGauge::Unit>("gauge");
|
||||||
|
for (unsigned int i = 0; i < flavour.size(); ++i)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
MAction::DWF::Par actionPar;
|
||||||
|
actionPar.gauge = "gauge";
|
||||||
|
actionPar.Ls = 12;
|
||||||
|
actionPar.M5 = 1.8;
|
||||||
|
actionPar.mass = mass[i];
|
||||||
|
application.createModule<MAction::DWF>("DWF_" + flavour[i], actionPar);
|
||||||
|
|
||||||
|
// solvers
|
||||||
|
MSolver::RBPrecCG::Par solverPar;
|
||||||
|
solverPar.action = "DWF_" + flavour[i];
|
||||||
|
solverPar.residual = 1.0e-8;
|
||||||
|
application.createModule<MSolver::RBPrecCG>("CG_" + flavour[i],
|
||||||
|
solverPar);
|
||||||
|
}
|
||||||
|
for (unsigned int t = 0; t < nt; t += 1)
|
||||||
|
{
|
||||||
|
std::string srcName;
|
||||||
|
std::vector<std::string> qName;
|
||||||
|
std::vector<std::vector<std::string>> seqName;
|
||||||
|
|
||||||
|
// Z2 source
|
||||||
|
MSource::Z2::Par z2Par;
|
||||||
|
z2Par.tA = t;
|
||||||
|
z2Par.tB = t;
|
||||||
|
srcName = "z2_" + std::to_string(t);
|
||||||
|
application.createModule<MSource::Z2>(srcName, z2Par);
|
||||||
|
for (unsigned int i = 0; i < flavour.size(); ++i)
|
||||||
|
{
|
||||||
|
// sequential sources
|
||||||
|
MSource::SeqGamma::Par seqPar;
|
||||||
|
qName.push_back("QZ2_" + flavour[i] + "_" + std::to_string(t));
|
||||||
|
seqPar.q = qName[i];
|
||||||
|
seqPar.tA = (t + nt/4) % nt;
|
||||||
|
seqPar.tB = (t + nt/4) % nt;
|
||||||
|
seqPar.mom = "1. 0. 0. 0.";
|
||||||
|
seqName.push_back(std::vector<std::string>(Nd));
|
||||||
|
for (unsigned int mu = 0; mu < Nd; ++mu)
|
||||||
|
{
|
||||||
|
seqPar.gamma = 0x1 << mu;
|
||||||
|
seqName[i][mu] = "G" + std::to_string(seqPar.gamma)
|
||||||
|
+ "_" + std::to_string(seqPar.tA) + "-"
|
||||||
|
+ qName[i];
|
||||||
|
application.createModule<MSource::SeqGamma>(seqName[i][mu], seqPar);
|
||||||
|
}
|
||||||
|
|
||||||
|
// propagators
|
||||||
|
Quark::Par quarkPar;
|
||||||
|
quarkPar.solver = "CG_" + flavour[i];
|
||||||
|
quarkPar.source = srcName;
|
||||||
|
application.createModule<Quark>(qName[i], quarkPar);
|
||||||
|
for (unsigned int mu = 0; mu < Nd; ++mu)
|
||||||
|
{
|
||||||
|
quarkPar.source = seqName[i][mu];
|
||||||
|
seqName[i][mu] = "Q_" + flavour[i] + "-" + seqName[i][mu];
|
||||||
|
application.createModule<Quark>(seqName[i][mu], quarkPar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// contractions
|
||||||
|
MContraction::Meson::Par mesPar;
|
||||||
|
for (unsigned int i = 0; i < flavour.size(); ++i)
|
||||||
|
for (unsigned int j = i; j < flavour.size(); ++j)
|
||||||
|
{
|
||||||
|
mesPar.output = "mesons/Z2_" + flavour[i] + flavour[j];
|
||||||
|
mesPar.q1 = qName[i];
|
||||||
|
mesPar.q2 = qName[j];
|
||||||
|
application.createModule<MContraction::Meson>("meson_Z2_"
|
||||||
|
+ std::to_string(t)
|
||||||
|
+ "_"
|
||||||
|
+ flavour[i]
|
||||||
|
+ flavour[j],
|
||||||
|
mesPar);
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < flavour.size(); ++i)
|
||||||
|
for (unsigned int j = 0; j < flavour.size(); ++j)
|
||||||
|
for (unsigned int mu = 0; mu < Nd; ++mu)
|
||||||
|
{
|
||||||
|
MContraction::Meson::Par mesPar;
|
||||||
|
|
||||||
|
mesPar.output = "3pt/Z2_" + flavour[i] + flavour[j] + "_"
|
||||||
|
+ std::to_string(mu);
|
||||||
|
mesPar.q1 = qName[i];
|
||||||
|
mesPar.q2 = seqName[j][mu];
|
||||||
|
application.createModule<MContraction::Meson>("3pt_Z2_"
|
||||||
|
+ std::to_string(t)
|
||||||
|
+ "_"
|
||||||
|
+ flavour[i]
|
||||||
|
+ flavour[j]
|
||||||
|
+ "_"
|
||||||
|
+ std::to_string(mu),
|
||||||
|
mesPar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution
|
||||||
|
application.saveParameterFile("meson3pt.xml");
|
||||||
|
application.run();
|
||||||
|
|
||||||
|
// epilogue
|
||||||
|
LOG(Message) << "Grid is finalizing now" << std::endl;
|
||||||
|
Grid_finalize();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
132
tests/hadrons/Test_hadrons_spectrum.cc
Normal file
132
tests/hadrons/Test_hadrons_spectrum.cc
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: tests/hadrons/Test_hadrons_spectrum.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
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.
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <Grid/Hadrons/Application.hpp>
|
||||||
|
|
||||||
|
using namespace Grid;
|
||||||
|
using namespace Hadrons;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// initialization //////////////////////////////////////////////////////////
|
||||||
|
Grid_init(&argc, &argv);
|
||||||
|
HadronsLogError.Active(GridLogError.isActive());
|
||||||
|
HadronsLogWarning.Active(GridLogWarning.isActive());
|
||||||
|
HadronsLogMessage.Active(GridLogMessage.isActive());
|
||||||
|
HadronsLogIterative.Active(GridLogIterative.isActive());
|
||||||
|
HadronsLogDebug.Active(GridLogDebug.isActive());
|
||||||
|
LOG(Message) << "Grid initialized" << std::endl;
|
||||||
|
|
||||||
|
// run setup ///////////////////////////////////////////////////////////////
|
||||||
|
Application application;
|
||||||
|
std::vector<std::string> flavour = {"l", "s", "c1", "c2", "c3"};
|
||||||
|
std::vector<double> mass = {.01, .04, .2 , .25 , .3 };
|
||||||
|
|
||||||
|
// global parameters
|
||||||
|
Application::GlobalPar globalPar;
|
||||||
|
globalPar.trajCounter.start = 1500;
|
||||||
|
globalPar.trajCounter.end = 1520;
|
||||||
|
globalPar.trajCounter.step = 20;
|
||||||
|
globalPar.seed = "1 2 3 4";
|
||||||
|
application.setPar(globalPar);
|
||||||
|
// gauge field
|
||||||
|
application.createModule<MGauge::Unit>("gauge");
|
||||||
|
// sources
|
||||||
|
MSource::Z2::Par z2Par;
|
||||||
|
z2Par.tA = 0;
|
||||||
|
z2Par.tB = 0;
|
||||||
|
application.createModule<MSource::Z2>("z2", z2Par);
|
||||||
|
MSource::Point::Par ptPar;
|
||||||
|
ptPar.position = "0 0 0 0";
|
||||||
|
application.createModule<MSource::Point>("pt", ptPar);
|
||||||
|
for (unsigned int i = 0; i < flavour.size(); ++i)
|
||||||
|
{
|
||||||
|
// actions
|
||||||
|
MAction::DWF::Par actionPar;
|
||||||
|
actionPar.gauge = "gauge";
|
||||||
|
actionPar.Ls = 12;
|
||||||
|
actionPar.M5 = 1.8;
|
||||||
|
actionPar.mass = mass[i];
|
||||||
|
application.createModule<MAction::DWF>("DWF_" + flavour[i], actionPar);
|
||||||
|
|
||||||
|
// solvers
|
||||||
|
MSolver::RBPrecCG::Par solverPar;
|
||||||
|
solverPar.action = "DWF_" + flavour[i];
|
||||||
|
solverPar.residual = 1.0e-8;
|
||||||
|
application.createModule<MSolver::RBPrecCG>("CG_" + flavour[i],
|
||||||
|
solverPar);
|
||||||
|
|
||||||
|
// propagators
|
||||||
|
Quark::Par quarkPar;
|
||||||
|
quarkPar.solver = "CG_" + flavour[i];
|
||||||
|
quarkPar.source = "pt";
|
||||||
|
application.createModule<Quark>("Qpt_" + flavour[i], quarkPar);
|
||||||
|
quarkPar.source = "z2";
|
||||||
|
application.createModule<Quark>("QZ2_" + flavour[i], quarkPar);
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < flavour.size(); ++i)
|
||||||
|
for (unsigned int j = i; j < flavour.size(); ++j)
|
||||||
|
{
|
||||||
|
MContraction::Meson::Par mesPar;
|
||||||
|
|
||||||
|
mesPar.output = "mesons/pt_" + flavour[i] + flavour[j];
|
||||||
|
mesPar.q1 = "Qpt_" + flavour[i];
|
||||||
|
mesPar.q2 = "Qpt_" + flavour[j];
|
||||||
|
application.createModule<MContraction::Meson>("meson_pt_"
|
||||||
|
+ flavour[i] + flavour[j],
|
||||||
|
mesPar);
|
||||||
|
mesPar.output = "mesons/Z2_" + flavour[i] + flavour[j];
|
||||||
|
mesPar.q1 = "QZ2_" + flavour[i];
|
||||||
|
mesPar.q2 = "QZ2_" + flavour[j];
|
||||||
|
application.createModule<MContraction::Meson>("meson_Z2_"
|
||||||
|
+ flavour[i] + flavour[j],
|
||||||
|
mesPar);
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < flavour.size(); ++i)
|
||||||
|
for (unsigned int j = i; j < flavour.size(); ++j)
|
||||||
|
for (unsigned int k = j; k < flavour.size(); ++k)
|
||||||
|
{
|
||||||
|
MContraction::Baryon::Par barPar;
|
||||||
|
|
||||||
|
barPar.output = "baryons/pt_" + flavour[i] + flavour[j] + flavour[k];
|
||||||
|
barPar.q1 = "Qpt_" + flavour[i];
|
||||||
|
barPar.q2 = "Qpt_" + flavour[j];
|
||||||
|
barPar.q3 = "Qpt_" + flavour[k];
|
||||||
|
application.createModule<MContraction::Baryon>(
|
||||||
|
"baryon_pt_" + flavour[i] + flavour[j] + flavour[k], barPar);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execution
|
||||||
|
application.saveParameterFile("spectrum.xml");
|
||||||
|
application.run();
|
||||||
|
|
||||||
|
// epilogue
|
||||||
|
LOG(Message) << "Grid is finalizing now" << std::endl;
|
||||||
|
Grid_finalize();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user