1
0
mirror of https://github.com/paboyle/Grid.git synced 2024-11-09 23:45:36 +00:00

Merge branch 'develop' into feature/gpu-port

This commit is contained in:
Peter Boyle 2019-07-16 11:55:17 +01:00
commit fa9cd50c5b
274 changed files with 7120 additions and 4663 deletions

1
.gitignore vendored
View File

@ -114,3 +114,4 @@ gh-pages/
##################### #####################
Grid/qcd/spin/gamma-gen/*.h Grid/qcd/spin/gamma-gen/*.h
Grid/qcd/spin/gamma-gen/*.cc Grid/qcd/spin/gamma-gen/*.cc
Grid/util/Version.h

View File

@ -0,0 +1,5 @@
Version : 0.8.0
- Clang 3.5 and above, ICPC v16 and above, GCC 6.3 and above recommended
- MPI and MPI3 comms optimisations for KNL and OPA finished
- Half precision comms

View File

@ -42,9 +42,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
#include <Grid/GridQCDcore.h> #include <Grid/GridQCDcore.h>
#include <Grid/qcd/action/Action.h> #include <Grid/qcd/action/Action.h>
#include <Grid/qcd/utils/GaugeFix.h> #include <Grid/qcd/utils/GaugeFix.h>
NAMESPACE_CHECK(GaugeFix); #include <Grid/qcd/utils/CovariantSmearing.h>
#include <Grid/qcd/smearing/Smearing.h> #include <Grid/qcd/smearing/Smearing.h>
NAMESPACE_CHECK(Smearing);
#include <Grid/parallelIO/MetaData.h> #include <Grid/parallelIO/MetaData.h>
#include <Grid/qcd/hmc/HMC_aggregate.h> #include <Grid/qcd/hmc/HMC_aggregate.h>

View File

@ -55,13 +55,9 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
#include <Grid/algorithms/iterative/FlexibleCommunicationAvoidingGeneralisedMinimalResidual.h> #include <Grid/algorithms/iterative/FlexibleCommunicationAvoidingGeneralisedMinimalResidual.h>
#include <Grid/algorithms/iterative/MixedPrecisionFlexibleGeneralisedMinimalResidual.h> #include <Grid/algorithms/iterative/MixedPrecisionFlexibleGeneralisedMinimalResidual.h>
#include <Grid/algorithms/iterative/ImplicitlyRestartedLanczos.h> #include <Grid/algorithms/iterative/ImplicitlyRestartedLanczos.h>
#include <Grid/algorithms/iterative/PowerMethod.h>
#include <Grid/algorithms/CoarsenedMatrix.h> #include <Grid/algorithms/CoarsenedMatrix.h>
#include <Grid/algorithms/FFT.h> #include <Grid/algorithms/FFT.h>
// EigCg
// Pcg
// Hdcg
// GCR
// etc..
#endif #endif

View File

@ -181,8 +181,7 @@ class SchurOperatorBase : public LinearOperatorBase<Field> {
public: public:
virtual RealD Mpc (const Field &in, Field &out) =0; virtual RealD Mpc (const Field &in, Field &out) =0;
virtual RealD MpcDag (const Field &in, Field &out) =0; virtual RealD MpcDag (const Field &in, Field &out) =0;
virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) {
{
Field tmp(in.Grid()); Field tmp(in.Grid());
tmp.Checkerboard() = in.Checkerboard(); tmp.Checkerboard() = in.Checkerboard();
ni=Mpc(in,tmp); ni=Mpc(in,tmp);
@ -212,14 +211,13 @@ public:
}; };
template<class Matrix,class Field> template<class Matrix,class Field>
class SchurDiagMooeeOperator : public SchurOperatorBase<Field> { class SchurDiagMooeeOperator : public SchurOperatorBase<Field> {
protected:
Matrix &_Mat;
public: public:
Matrix &_Mat;
SchurDiagMooeeOperator (Matrix &Mat): _Mat(Mat){}; SchurDiagMooeeOperator (Matrix &Mat): _Mat(Mat){};
virtual RealD Mpc (const Field &in, Field &out) { virtual RealD Mpc (const Field &in, Field &out) {
Field tmp(in.Grid()); Field tmp(in.Grid());
// std::cout <<"grid pointers: in.Grid()="<< in.Grid() << " out.Grid()=" << out.Grid() << " _Mat.Grid=" << _Mat.Grid() << " _Mat.RedBlackGrid=" << _Mat.RedBlackGrid() << std::endl;
tmp.Checkerboard() = !in.Checkerboard(); tmp.Checkerboard() = !in.Checkerboard();
//std::cout <<"grid pointers: in._grid="<< in._grid << " out._grid=" << out._grid << " _Mat.Grid=" << _Mat.Grid() << " _Mat.RedBlackGrid=" << _Mat.RedBlackGrid() << std::endl;
_Mat.Meooe(in,tmp); _Mat.Meooe(in,tmp);
_Mat.MooeeInv(tmp,out); _Mat.MooeeInv(tmp,out);

View File

@ -60,7 +60,7 @@ public:
// Query the even even properties to make algorithmic decisions // Query the even even properties to make algorithmic decisions
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
virtual RealD Mass(void) { return 0.0; }; virtual RealD Mass(void) { return 0.0; };
virtual int ConstEE(void) { return 0; }; // Disable assumptions unless overridden virtual int ConstEE(void) { return 1; }; // Disable assumptions unless overridden
virtual int isTrivialEE(void) { return 0; }; // by a derived class that knows better virtual int isTrivialEE(void) { return 0; }; // by a derived class that knows better
// half checkerboard operaions // half checkerboard operaions

View File

@ -93,6 +93,8 @@ public:
// Check if guess is really REALLY good :) // Check if guess is really REALLY good :)
if (cp <= rsq) { if (cp <= rsq) {
std::cout << GridLogMessage << "ConjugateGradient guess is converged already " << std::endl;
IterationsToComplete = 0;
return; return;
} }
@ -108,7 +110,7 @@ public:
SolverTimer.Start(); SolverTimer.Start();
int k; int k;
for (k = 1; k <= MaxIterations*1000; k++) { for (k = 1; k <= MaxIterations; k++) {
c = cp; c = cp;
MatrixTimer.Start(); MatrixTimer.Start();
@ -172,8 +174,7 @@ public:
return; return;
} }
} }
std::cout << GridLogMessage << "ConjugateGradient did NOT converge" std::cout << GridLogMessage << "ConjugateGradient did NOT converge "<<k<<" / "<< MaxIterations<< std::endl;
<< std::endl;
if (ErrorOnNoConverge) assert(0); if (ErrorOnNoConverge) assert(0);
IterationsToComplete = k; IterationsToComplete = k;

View File

@ -52,7 +52,12 @@ public:
//Option to speed up *inner single precision* solves using a LinearFunction that produces a guess //Option to speed up *inner single precision* solves using a LinearFunction that produces a guess
LinearFunction<FieldF> *guesser; LinearFunction<FieldF> *guesser;
MixedPrecisionConjugateGradient(RealD tol, Integer maxinnerit, Integer maxouterit, GridBase* _sp_grid, LinearOperatorBase<FieldF> &_Linop_f, LinearOperatorBase<FieldD> &_Linop_d) : MixedPrecisionConjugateGradient(RealD tol,
Integer maxinnerit,
Integer maxouterit,
GridBase* _sp_grid,
LinearOperatorBase<FieldF> &_Linop_f,
LinearOperatorBase<FieldD> &_Linop_d) :
Linop_f(_Linop_f), Linop_d(_Linop_d), Linop_f(_Linop_f), Linop_d(_Linop_d),
Tolerance(tol), InnerTolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid), Tolerance(tol), InnerTolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid),
OuterLoopNormMult(100.), guesser(NULL){ }; OuterLoopNormMult(100.), guesser(NULL){ };

View File

@ -35,7 +35,11 @@ class ZeroGuesser: public LinearFunction<Field> {
public: public:
virtual void operator()(const Field &src, Field &guess) { guess = Zero(); }; virtual void operator()(const Field &src, Field &guess) { guess = Zero(); };
}; };
template<class Field>
class DoNothingGuesser: public LinearFunction<Field> {
public:
virtual void operator()(const Field &src, Field &guess) { };
};
template<class Field> template<class Field>
class SourceGuesser: public LinearFunction<Field> { class SourceGuesser: public LinearFunction<Field> {
public: public:

View File

@ -0,0 +1,45 @@
#pragma once
namespace Grid {
template<class Field> class PowerMethod
{
public:
template<typename T> static RealD normalise(T& v)
{
RealD nn = norm2(v);
nn = sqrt(nn);
v = v * (1.0/nn);
return nn;
}
RealD operator()(LinearOperatorBase<Field> &HermOp, const Field &src)
{
GridBase *grid = src._grid;
// quickly get an idea of the largest eigenvalue to more properly normalize the residuum
RealD evalMaxApprox = 0.0;
auto src_n = src;
auto tmp = src;
const int _MAX_ITER_EST_ = 50;
for (int i=0;i<_MAX_ITER_EST_;i++) {
normalise(src_n);
HermOp.HermOp(src_n,tmp);
RealD vnum = real(innerProduct(src_n,tmp)); // HermOp.
RealD vden = norm2(src_n);
RealD na = vnum/vden;
if ( (fabs(evalMaxApprox/na - 1.0) < 0.01) || (i==_MAX_ITER_EST_-1) ) {
evalMaxApprox = na;
return evalMaxApprox;
}
evalMaxApprox = na;
std::cout << GridLogMessage << " Approximation of largest eigenvalue: " << evalMaxApprox << std::endl;
src_n = tmp;
}
assert(0);
return 0;
}
};
}

View File

@ -99,10 +99,13 @@ namespace Grid {
OperatorFunction<Field> & _HermitianRBSolver; OperatorFunction<Field> & _HermitianRBSolver;
int CBfactorise; int CBfactorise;
bool subGuess; bool subGuess;
bool useSolnAsInitGuess; // if true user-supplied solution vector is used as initial guess for solver
public: public:
SchurRedBlackBase(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false) : SchurRedBlackBase(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
_HermitianRBSolver(HermitianRBSolver) const bool _solnAsInitGuess = false) :
_HermitianRBSolver(HermitianRBSolver),
useSolnAsInitGuess(_solnAsInitGuess)
{ {
CBfactorise = 0; CBfactorise = 0;
subtractGuess(initSubGuess); subtractGuess(initSubGuess);
@ -156,7 +159,11 @@ namespace Grid {
if ( subGuess ) guess_save.resize(nblock,grid); if ( subGuess ) guess_save.resize(nblock,grid);
for(int b=0;b<nblock;b++){ for(int b=0;b<nblock;b++){
if(useSolnAsInitGuess) {
pickCheckerboard(Odd, sol_o[b], out[b]);
} else {
guess(src_o[b],sol_o[b]); guess(src_o[b],sol_o[b]);
}
if ( subGuess ) { if ( subGuess ) {
guess_save[b] = sol_o[b]; guess_save[b] = sol_o[b];
@ -216,8 +223,11 @@ namespace Grid {
//////////////////////////////// ////////////////////////////////
// Construct the guess // Construct the guess
//////////////////////////////// ////////////////////////////////
Field tmp(grid); if(useSolnAsInitGuess) {
pickCheckerboard(Odd, sol_o, out);
} else {
guess(src_o,sol_o); guess(src_o,sol_o);
}
Field guess_save(grid); Field guess_save(grid);
guess_save = sol_o; guess_save = sol_o;
@ -251,7 +261,7 @@ namespace Grid {
} }
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
// Override in derived. Not virtual as template methods // Override in derived.
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
virtual void RedBlackSource (Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o) =0; virtual void RedBlackSource (Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o) =0;
virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol) =0; virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol) =0;
@ -264,8 +274,9 @@ namespace Grid {
public: public:
typedef CheckerBoardedSparseMatrixBase<Field> Matrix; typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
SchurRedBlackStaggeredSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false) SchurRedBlackStaggeredSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
: SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess) const bool _solnAsInitGuess = false)
: SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess,_solnAsInitGuess)
{ {
} }
@ -333,8 +344,9 @@ namespace Grid {
public: public:
typedef CheckerBoardedSparseMatrixBase<Field> Matrix; typedef CheckerBoardedSparseMatrixBase<Field> Matrix;
SchurRedBlackDiagMooeeSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false) SchurRedBlackDiagMooeeSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
: SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess) {}; const bool _solnAsInitGuess = false)
: SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess,_solnAsInitGuess) {};
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
@ -405,8 +417,9 @@ namespace Grid {
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
// Wrap the usual normal equations Schur trick // Wrap the usual normal equations Schur trick
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
SchurRedBlackDiagTwoSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false) SchurRedBlackDiagTwoSolve(OperatorFunction<Field> &HermitianRBSolver, const bool initSubGuess = false,
: SchurRedBlackBase<Field>(HermitianRBSolver,initSubGuess) {}; const bool _solnAsInitGuess = false)
: SchurRedBlackBase<Field>(HermitianRBSolver,initSubGuess,_solnAsInitGuess) {};
virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o) virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)
{ {

View File

@ -44,10 +44,13 @@ void CartesianCommunicator::Init(int *argc, char ***argv)
MPI_Initialized(&flag); // needed to coexist with other libs apparently MPI_Initialized(&flag); // needed to coexist with other libs apparently
if ( !flag ) { if ( !flag ) {
MPI_Init_thread(argc,argv,MPI_THREAD_MULTIPLE,&provided); MPI_Init_thread(argc,argv,MPI_THREAD_MULTIPLE,&provided);
// assert (provided == MPI_THREAD_MULTIPLE);
//If only 1 comms thread we require any threading mode other than SINGLE, but for multiple comms threads we need MULTIPLE //If only 1 comms thread we require any threading mode other than SINGLE, but for multiple comms threads we need MULTIPLE
if( (nCommThreads == 1 && provided == MPI_THREAD_SINGLE) || if( (nCommThreads == 1) && (provided == MPI_THREAD_SINGLE) ) {
(nCommThreads > 1 && provided != MPI_THREAD_MULTIPLE) ) { assert(0);
}
if( (nCommThreads > 1) && (provided != MPI_THREAD_MULTIPLE) ) {
assert(0); assert(0);
} }
} }
@ -55,9 +58,12 @@ void CartesianCommunicator::Init(int *argc, char ***argv)
// Never clean up as done once. // Never clean up as done once.
MPI_Comm_dup (MPI_COMM_WORLD,&communicator_world); MPI_Comm_dup (MPI_COMM_WORLD,&communicator_world);
Grid_quiesce_nodes();
GlobalSharedMemory::Init(communicator_world); GlobalSharedMemory::Init(communicator_world);
GlobalSharedMemory::SharedMemoryAllocate(GlobalSharedMemory::MAX_MPI_SHM_BYTES, GlobalSharedMemory::SharedMemoryAllocate(
GlobalSharedMemory::MAX_MPI_SHM_BYTES,
GlobalSharedMemory::Hugepages); GlobalSharedMemory::Hugepages);
Grid_unquiesce_nodes();
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -106,8 +112,7 @@ CartesianCommunicator::CartesianCommunicator(const Coordinate &processors)
////////////////////////////////// //////////////////////////////////
CartesianCommunicator::CartesianCommunicator(const Coordinate &processors,const CartesianCommunicator &parent,int &srank) CartesianCommunicator::CartesianCommunicator(const Coordinate &processors,const CartesianCommunicator &parent,int &srank)
{ {
_ndimension = processors.size(); _ndimension = processors.size(); assert(_ndimension>=1);
int parent_ndimension = parent._ndimension; assert(_ndimension >= parent._ndimension); int parent_ndimension = parent._ndimension; assert(_ndimension >= parent._ndimension);
Coordinate parent_processor_coor(_ndimension,0); Coordinate parent_processor_coor(_ndimension,0);
Coordinate parent_processors (_ndimension,1); Coordinate parent_processors (_ndimension,1);

View File

@ -52,7 +52,7 @@ CartesianCommunicator::CartesianCommunicator(const Coordinate &processors,const
CartesianCommunicator::CartesianCommunicator(const Coordinate &processors) CartesianCommunicator::CartesianCommunicator(const Coordinate &processors)
{ {
_processors = processors; _processors = processors;
_ndimension = processors.size(); _ndimension = processors.size(); assert(_ndimension>=1);
_processor_coor.resize(_ndimension); _processor_coor.resize(_ndimension);
// Require 1^N processor grid for fake // Require 1^N processor grid for fake

View File

@ -91,6 +91,8 @@ public:
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
static void Init(Grid_MPI_Comm comm); // Typically MPI_COMM_WORLD static void Init(Grid_MPI_Comm comm); // Typically MPI_COMM_WORLD
static void OptimalCommunicator (const Coordinate &processors,Grid_MPI_Comm & optimal_comm); // Turns MPI_COMM_WORLD into right layout for Cartesian static void OptimalCommunicator (const Coordinate &processors,Grid_MPI_Comm & optimal_comm); // Turns MPI_COMM_WORLD into right layout for Cartesian
static void OptimalCommunicatorHypercube (const Coordinate &processors,Grid_MPI_Comm & optimal_comm); // Turns MPI_COMM_WORLD into right layout for Cartesian
static void OptimalCommunicatorSharedMemory(const Coordinate &processors,Grid_MPI_Comm & optimal_comm); // Turns MPI_COMM_WORLD into right layout for Cartesian
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
// Provide shared memory facilities off comm world // Provide shared memory facilities off comm world
/////////////////////////////////////////////////// ///////////////////////////////////////////////////

View File

@ -141,8 +141,22 @@ int Log2Size(int TwoToPower,int MAXLOG2)
} }
void GlobalSharedMemory::OptimalCommunicator(const Coordinate &processors,Grid_MPI_Comm & optimal_comm) void GlobalSharedMemory::OptimalCommunicator(const Coordinate &processors,Grid_MPI_Comm & optimal_comm)
{ {
#ifdef HYPERCUBE //////////////////////////////////////////////////////////////////////////////
#warning "HPE 8600 Hypercube optimisations enabled" // Look and see if it looks like an HPE 8600 based on hostname conventions
//////////////////////////////////////////////////////////////////////////////
const int namelen = _POSIX_HOST_NAME_MAX;
char name[namelen];
int R;
int I;
int N;
gethostname(name,namelen);
int nscan = sscanf(name,"r%di%dn%d",&R,&I,&N) ;
if(nscan==3) OptimalCommunicatorHypercube(processors,optimal_comm);
else OptimalCommunicatorSharedMemory(processors,optimal_comm);
}
void GlobalSharedMemory::OptimalCommunicatorHypercube(const Coordinate &processors,Grid_MPI_Comm & optimal_comm)
{
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Assert power of two shm_size. // Assert power of two shm_size.
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -208,7 +222,8 @@ void GlobalSharedMemory::OptimalCommunicator(const Coordinate &processors,Grid_M
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
int ndimension = processors.size(); int ndimension = processors.size();
std::vector<int> processor_coor(ndimension); std::vector<int> processor_coor(ndimension);
std::vector<int> WorldDims = processors; std::vector<int> ShmDims (ndimension,1); std::vector<int> NodeDims (ndimension); std::vector<int> WorldDims = processors.toVector();
std::vector<int> ShmDims (ndimension,1); std::vector<int> NodeDims (ndimension);
std::vector<int> ShmCoor (ndimension); std::vector<int> NodeCoor (ndimension); std::vector<int> WorldCoor(ndimension); std::vector<int> ShmCoor (ndimension); std::vector<int> NodeCoor (ndimension); std::vector<int> WorldCoor(ndimension);
std::vector<int> HyperCoor(ndimension); std::vector<int> HyperCoor(ndimension);
int dim = 0; int dim = 0;
@ -263,7 +278,9 @@ void GlobalSharedMemory::OptimalCommunicator(const Coordinate &processors,Grid_M
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
int ierr= MPI_Comm_split(WorldComm,0,rank,&optimal_comm); int ierr= MPI_Comm_split(WorldComm,0,rank,&optimal_comm);
assert(ierr==0); assert(ierr==0);
#else }
void GlobalSharedMemory::OptimalCommunicatorSharedMemory(const Coordinate &processors,Grid_MPI_Comm & optimal_comm)
{
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Assert power of two shm_size. // Assert power of two shm_size.
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -316,7 +333,6 @@ void GlobalSharedMemory::OptimalCommunicator(const Coordinate &processors,Grid_M
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
int ierr= MPI_Comm_split(WorldComm,0,rank,&optimal_comm); int ierr= MPI_Comm_split(WorldComm,0,rank,&optimal_comm);
assert(ierr==0); assert(ierr==0);
#endif
} }
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
// SHMGET // SHMGET
@ -347,7 +363,7 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags)
int errsv = errno; int errsv = errno;
printf("Errno %d\n",errsv); printf("Errno %d\n",errsv);
printf("key %d\n",key); printf("key %d\n",key);
printf("size %lld\n",size); printf("size %ld\n",size);
printf("flags %d\n",flags); printf("flags %d\n",flags);
perror("shmget"); perror("shmget");
exit(1); exit(1);

View File

@ -77,7 +77,7 @@ void GridLogConfigure(std::vector<std::string> &logstreams) {
GridLogIterative.Active(0); GridLogIterative.Active(0);
GridLogDebug.Active(0); GridLogDebug.Active(0);
GridLogPerformance.Active(0); GridLogPerformance.Active(0);
GridLogIntegrator.Active(0); GridLogIntegrator.Active(1);
GridLogColours.Active(0); GridLogColours.Active(0);
for (int i = 0; i < logstreams.size(); i++) { for (int i = 0; i < logstreams.size(); i++) {
@ -86,8 +86,7 @@ void GridLogConfigure(std::vector<std::string> &logstreams) {
if (logstreams[i] == std::string("NoMessage")) GridLogMessage.Active(0); if (logstreams[i] == std::string("NoMessage")) GridLogMessage.Active(0);
if (logstreams[i] == std::string("Iterative")) GridLogIterative.Active(1); if (logstreams[i] == std::string("Iterative")) GridLogIterative.Active(1);
if (logstreams[i] == std::string("Debug")) GridLogDebug.Active(1); if (logstreams[i] == std::string("Debug")) GridLogDebug.Active(1);
if (logstreams[i] == std::string("Performance")) if (logstreams[i] == std::string("Performance")) GridLogPerformance.Active(1);
GridLogPerformance.Active(1);
if (logstreams[i] == std::string("Integrator")) GridLogIntegrator.Active(1); if (logstreams[i] == std::string("Integrator")) GridLogIntegrator.Active(1);
if (logstreams[i] == std::string("Colours")) GridLogColours.Active(1); if (logstreams[i] == std::string("Colours")) GridLogColours.Active(1);
} }

View File

@ -204,10 +204,10 @@ class BinaryIO {
static inline void le32toh_v(void *file_object,uint64_t bytes) static inline void le32toh_v(void *file_object,uint64_t bytes)
{ {
uint32_t *fp = (uint32_t *)file_object; uint32_t *fp = (uint32_t *)file_object;
uint32_t f;
uint64_t count = bytes/sizeof(uint32_t); uint64_t count = bytes/sizeof(uint32_t);
thread_for(i,count,{ thread_for(i,count,{
uint32_t f;
f = fp[i]; f = fp[i];
// got network order and the network to host // got network order and the network to host
f = ((f&0xFF)<<24) | ((f&0xFF00)<<8) | ((f&0xFF0000)>>8) | ((f&0xFF000000UL)>>24) ; f = ((f&0xFF)<<24) | ((f&0xFF00)<<8) | ((f&0xFF0000)>>8) | ((f&0xFF000000UL)>>24) ;
@ -229,10 +229,9 @@ class BinaryIO {
static inline void le64toh_v(void *file_object,uint64_t bytes) static inline void le64toh_v(void *file_object,uint64_t bytes)
{ {
uint64_t *fp = (uint64_t *)file_object; uint64_t *fp = (uint64_t *)file_object;
uint64_t f,g;
uint64_t count = bytes/sizeof(uint64_t); uint64_t count = bytes/sizeof(uint64_t);
thread_for( i, count, { thread_for( i, count, {
uint64_t f,g;
f = fp[i]; f = fp[i];
// got network order and the network to host // got network order and the network to host
g = ((f&0xFF)<<24) | ((f&0xFF00)<<8) | ((f&0xFF0000)>>8) | ((f&0xFF000000UL)>>24) ; g = ((f&0xFF)<<24) | ((f&0xFF00)<<8) | ((f&0xFF0000)>>8) | ((f&0xFF000000UL)>>24) ;
@ -343,7 +342,8 @@ class BinaryIO {
int ieee32 = (format == std::string("IEEE32")); int ieee32 = (format == std::string("IEEE32"));
int ieee64big = (format == std::string("IEEE64BIG")); int ieee64big = (format == std::string("IEEE64BIG"));
int ieee64 = (format == std::string("IEEE64")); int ieee64 = (format == std::string("IEEE64"));
assert(ieee64||ieee32|ieee64big||ieee32big);
assert((ieee64+ieee32+ieee64big+ieee32big)==1);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Do the I/O // Do the I/O
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -613,6 +613,7 @@ class BinaryIO {
{ {
std::cout << GridLogMessage << "writeLatticeObject: read test checksum failure, re-writing (" << attemptsLeft << " attempt(s) remaining)" << std::endl; std::cout << GridLogMessage << "writeLatticeObject: read test checksum failure, re-writing (" << attemptsLeft << " attempt(s) remaining)" << std::endl;
offset = offsetCopy; offset = offsetCopy;
thread_for(x,lsites, { munge(scalardata[x],iodata[x]); });
} }
else else
{ {

View File

@ -44,6 +44,12 @@ extern "C" {
NAMESPACE_BEGIN(Grid); NAMESPACE_BEGIN(Grid);
#define GRID_FIELD_NORM "FieldNormMetaData"
#define GRID_FIELD_NORM_CALC(FieldNormMetaData_, n2ck) \
0.5*fabs(FieldNormMetaData_.norm2 - n2ck)/(FieldNormMetaData_.norm2 + n2ck)
#define GRID_FIELD_NORM_CHECK(FieldNormMetaData_, n2ck) \
assert(GRID_FIELD_NORM_CALC(FieldNormMetaData_, n2ck) < 1.0e-5);
///////////////////////////////// /////////////////////////////////
// Encode word types as strings // Encode word types as strings
///////////////////////////////// /////////////////////////////////
@ -203,6 +209,7 @@ class GridLimeReader : public BinaryIO {
{ {
typedef typename vobj::scalar_object sobj; typedef typename vobj::scalar_object sobj;
scidacChecksum scidacChecksum_; scidacChecksum scidacChecksum_;
FieldNormMetaData FieldNormMetaData_;
uint32_t nersc_csum,scidac_csuma,scidac_csumb; uint32_t nersc_csum,scidac_csuma,scidac_csumb;
std::string format = getFormatString<vobj>(); std::string format = getFormatString<vobj>();
@ -236,16 +243,47 @@ class GridLimeReader : public BinaryIO {
///////////////////////////////////////////// /////////////////////////////////////////////
// Insist checksum is next record // Insist checksum is next record
///////////////////////////////////////////// /////////////////////////////////////////////
readLimeObject(scidacChecksum_,std::string("scidacChecksum"),std::string(SCIDAC_CHECKSUM)); readScidacChecksum(scidacChecksum_,FieldNormMetaData_);
///////////////////////////////////////////// /////////////////////////////////////////////
// Verify checksums // Verify checksums
///////////////////////////////////////////// /////////////////////////////////////////////
if(FieldNormMetaData_.norm2 != 0.0){
RealD n2ck = norm2(field);
std::cout << GridLogMessage << "Field norm: metadata= " << FieldNormMetaData_.norm2
<< " / field= " << n2ck << " / rdiff= " << GRID_FIELD_NORM_CALC(FieldNormMetaData_,n2ck) << std::endl;
GRID_FIELD_NORM_CHECK(FieldNormMetaData_,n2ck);
}
assert(scidacChecksumVerify(scidacChecksum_,scidac_csuma,scidac_csumb)==1); assert(scidacChecksumVerify(scidacChecksum_,scidac_csuma,scidac_csumb)==1);
// find out if next field is a GridFieldNorm
return; return;
} }
} }
} }
void readScidacChecksum(scidacChecksum &scidacChecksum_,
FieldNormMetaData &FieldNormMetaData_)
{
FieldNormMetaData_.norm2 =0.0;
std::string scidac_str(SCIDAC_CHECKSUM);
std::string field_norm_str(GRID_FIELD_NORM);
while ( limeReaderNextRecord(LimeR) == LIME_SUCCESS ) {
uint64_t nbytes = limeReaderBytes(LimeR);//size of this record (configuration)
std::vector<char> xmlc(nbytes+1,'\0');
limeReaderReadData((void *)&xmlc[0], &nbytes, LimeR);
std::string xmlstring = std::string(&xmlc[0]);
XmlReader RD(xmlstring, true, "");
if ( !strncmp(limeReaderType(LimeR), field_norm_str.c_str(),strlen(field_norm_str.c_str()) ) ) {
// std::cout << "FieldNormMetaData "<<xmlstring<<std::endl;
read(RD,field_norm_str,FieldNormMetaData_);
}
if ( !strncmp(limeReaderType(LimeR), scidac_str.c_str(),strlen(scidac_str.c_str()) ) ) {
// std::cout << SCIDAC_CHECKSUM << " " <<xmlstring<<std::endl;
read(RD,std::string("scidacChecksum"),scidacChecksum_);
return;
}
}
assert(0);
}
//////////////////////////////////////////// ////////////////////////////////////////////
// Read a generic serialisable object // Read a generic serialisable object
//////////////////////////////////////////// ////////////////////////////////////////////
@ -388,6 +426,8 @@ class GridLimeWriter : public BinaryIO
GridBase *grid = field.Grid(); GridBase *grid = field.Grid();
assert(boss_node == field.Grid()->IsBoss() ); assert(boss_node == field.Grid()->IsBoss() );
FieldNormMetaData FNMD; FNMD.norm2 = norm2(field);
//////////////////////////////////////////// ////////////////////////////////////////////
// Create record header // Create record header
//////////////////////////////////////////// ////////////////////////////////////////////
@ -446,6 +486,7 @@ class GridLimeWriter : public BinaryIO
checksum.suma= streama.str(); checksum.suma= streama.str();
checksum.sumb= streamb.str(); checksum.sumb= streamb.str();
if ( boss_node ) { if ( boss_node ) {
writeLimeObject(0,0,FNMD,std::string(GRID_FIELD_NORM),std::string(GRID_FIELD_NORM));
writeLimeObject(0,1,checksum,std::string("scidacChecksum"),std::string(SCIDAC_CHECKSUM)); writeLimeObject(0,1,checksum,std::string("scidacChecksum"),std::string(SCIDAC_CHECKSUM));
} }
} }
@ -623,6 +664,12 @@ class IldgWriter : public ScidacWriter {
assert(header.nd==4); assert(header.nd==4);
assert(header.nd==header.dimension.size()); assert(header.nd==header.dimension.size());
//////////////////////////////////////////////////////////////////////////////
// Field norm tests
//////////////////////////////////////////////////////////////////////////////
FieldNormMetaData FieldNormMetaData_;
FieldNormMetaData_.norm2 = norm2(Umu);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Fill the USQCD info field // Fill the USQCD info field
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -631,11 +678,12 @@ class IldgWriter : public ScidacWriter {
info.plaq = header.plaquette; info.plaq = header.plaquette;
info.linktr = header.link_trace; info.linktr = header.link_trace;
std::cout << GridLogMessage << " Writing config; IldgIO "<<std::endl; // std::cout << GridLogMessage << " Writing config; IldgIO n2 "<< FieldNormMetaData_.norm2<<std::endl;
////////////////////////////////////////////// //////////////////////////////////////////////
// Fill the Lime file record by record // Fill the Lime file record by record
////////////////////////////////////////////// //////////////////////////////////////////////
writeLimeObject(1,0,header ,std::string("FieldMetaData"),std::string(GRID_FORMAT)); // Open message writeLimeObject(1,0,header ,std::string("FieldMetaData"),std::string(GRID_FORMAT)); // Open message
writeLimeObject(0,0,FieldNormMetaData_,FieldNormMetaData_.SerialisableClassName(),std::string(GRID_FIELD_NORM));
writeLimeObject(0,0,_scidacFile,_scidacFile.SerialisableClassName(),std::string(SCIDAC_PRIVATE_FILE_XML)); writeLimeObject(0,0,_scidacFile,_scidacFile.SerialisableClassName(),std::string(SCIDAC_PRIVATE_FILE_XML));
writeLimeObject(0,1,info,info.SerialisableClassName(),std::string(SCIDAC_FILE_XML)); writeLimeObject(0,1,info,info.SerialisableClassName(),std::string(SCIDAC_FILE_XML));
writeLimeObject(1,0,_scidacRecord,_scidacRecord.SerialisableClassName(),std::string(SCIDAC_PRIVATE_RECORD_XML)); writeLimeObject(1,0,_scidacRecord,_scidacRecord.SerialisableClassName(),std::string(SCIDAC_PRIVATE_RECORD_XML));
@ -678,6 +726,7 @@ class IldgReader : public GridLimeReader {
std::string ildgLFN_ ; std::string ildgLFN_ ;
scidacChecksum scidacChecksum_; scidacChecksum scidacChecksum_;
usqcdInfo usqcdInfo_ ; usqcdInfo usqcdInfo_ ;
FieldNormMetaData FieldNormMetaData_;
// track what we read from file // track what we read from file
int found_ildgFormat =0; int found_ildgFormat =0;
@ -686,7 +735,7 @@ class IldgReader : public GridLimeReader {
int found_usqcdInfo =0; int found_usqcdInfo =0;
int found_ildgBinary =0; int found_ildgBinary =0;
int found_FieldMetaData =0; int found_FieldMetaData =0;
int found_FieldNormMetaData =0;
uint32_t nersc_csum; uint32_t nersc_csum;
uint32_t scidac_csuma; uint32_t scidac_csuma;
uint32_t scidac_csumb; uint32_t scidac_csumb;
@ -773,11 +822,17 @@ class IldgReader : public GridLimeReader {
found_scidacChecksum = 1; found_scidacChecksum = 1;
} }
if ( !strncmp(limeReaderType(LimeR), GRID_FIELD_NORM,strlen(GRID_FIELD_NORM)) ) {
XmlReader RD(xmlstring, true, "");
read(RD,GRID_FIELD_NORM,FieldNormMetaData_);
found_FieldNormMetaData = 1;
}
} else { } else {
///////////////////////////////// /////////////////////////////////
// Binary data // Binary data
///////////////////////////////// /////////////////////////////////
std::cout << GridLogMessage << "ILDG Binary record found : " ILDG_BINARY_DATA << std::endl; // std::cout << GridLogMessage << "ILDG Binary record found : " ILDG_BINARY_DATA << std::endl;
uint64_t offset= ftello(File); uint64_t offset= ftello(File);
if ( format == std::string("IEEE64BIG") ) { if ( format == std::string("IEEE64BIG") ) {
GaugeSimpleMunger<dobj, sobj> munge; GaugeSimpleMunger<dobj, sobj> munge;
@ -845,6 +900,13 @@ class IldgReader : public GridLimeReader {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Really really want to mandate a scidac checksum // Really really want to mandate a scidac checksum
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
if ( found_FieldNormMetaData ) {
RealD nn = norm2(Umu);
GRID_FIELD_NORM_CHECK(FieldNormMetaData_,nn);
std::cout << GridLogMessage<<"FieldNormMetaData matches " << std::endl;
} else {
std::cout << GridLogWarning<<"FieldNormMetaData not found. " << std::endl;
}
if ( found_scidacChecksum ) { if ( found_scidacChecksum ) {
FieldMetaData_.scidac_checksuma = stoull(scidacChecksum_.suma,0,16); FieldMetaData_.scidac_checksuma = stoull(scidacChecksum_.suma,0,16);
FieldMetaData_.scidac_checksumb = stoull(scidacChecksum_.sumb,0,16); FieldMetaData_.scidac_checksumb = stoull(scidacChecksum_.sumb,0,16);

View File

@ -52,10 +52,15 @@ template<class vobj> static std::string getFormatString (void)
format = std::string("IEEE64BIG"); format = std::string("IEEE64BIG");
} }
return format; return format;
} };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// header specification/interpretation // header specification/interpretation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class FieldNormMetaData : Serializable {
public:
GRID_SERIALIZABLE_CLASS_MEMBERS(FieldNormMetaData, double, norm2);
};
class FieldMetaData : Serializable { class FieldMetaData : Serializable {
public: public:

View File

@ -64,7 +64,8 @@ struct OneFlavourRationalParams : Serializable {
int, MaxIter, int, MaxIter,
RealD, tolerance, RealD, tolerance,
int, degree, int, degree,
int, precision); int, precision,
int, BoundsCheckFreq);
// MaxIter and tolerance, vectors?? // MaxIter and tolerance, vectors??
@ -74,13 +75,15 @@ struct OneFlavourRationalParams : Serializable {
int _maxit = 1000, int _maxit = 1000,
RealD tol = 1.0e-8, RealD tol = 1.0e-8,
int _degree = 10, int _degree = 10,
int _precision = 64) int _precision = 64,
int _BoundsCheckFreq=20)
: lo(_lo), : lo(_lo),
hi(_hi), hi(_hi),
MaxIter(_maxit), MaxIter(_maxit),
tolerance(tol), tolerance(tol),
degree(_degree), degree(_degree),
precision(_precision){}; precision(_precision),
BoundsCheckFreq(_BoundsCheckFreq){};
}; };
NAMESPACE_END(Grid); NAMESPACE_END(Grid);

View File

@ -41,7 +41,7 @@ public:
INHERIT_IMPL_TYPES(Impl); INHERIT_IMPL_TYPES(Impl);
public: public:
void FreePropagator(const FermionField &in,FermionField &out,RealD mass, std::vector<double> twist, bool fiveD) { void FreePropagator(const FermionField &in,FermionField &out,RealD mass,std::vector<Complex> boundary, std::vector<double> twist, bool fiveD) {
FermionField in_k(in.Grid()); FermionField in_k(in.Grid());
FermionField prop_k(in.Grid()); FermionField prop_k(in.Grid());
@ -54,15 +54,19 @@ public:
typedef typename Simd::scalar_type Scalar; typedef typename Simd::scalar_type Scalar;
Scalar ci(0.0,1.0); Scalar ci(0.0,1.0);
assert(twist.size() == Nd);//check that twist is Nd assert(twist.size() == Nd);//check that twist is Nd
assert(boundary.size() == Nd);//check that boundary conditions is Nd
int shift = 0; int shift = 0;
if(fiveD) shift = 1; if(fiveD) shift = 1;
for(unsigned int nu = 0; nu < Nd; nu++) for(unsigned int nu = 0; nu < Nd; nu++)
{ {
// Shift coordinate lattice index by 1 to account for 5th dimension. // Shift coordinate lattice index by 1 to account for 5th dimension.
LatticeCoordinate(coor, nu + shift); LatticeCoordinate(coor, nu + shift);
ph = ph + twist[nu]*coor*((1./(in.Grid()->FullDimensions()[nu+shift]))); double boundary_phase = ::acos(real(boundary[nu]));
ph = ph + boundary_phase*coor*((1./(in.Grid()->_fdimensions[nu+shift])));
//momenta for propagator shifted by twist+boundary
twist[nu] = twist[nu] + boundary_phase/((2.0*M_PI));
} }
in_buf = exp(Scalar(2.0*M_PI)*ci*ph*(-1.0))*in; in_buf = exp(ci*ph*(-1.0))*in;
if(fiveD){//FFT only on temporal and spatial dimensions if(fiveD){//FFT only on temporal and spatial dimensions
std::vector<int> mask(Nd+1,1); mask[0] = 0; std::vector<int> mask(Nd+1,1); mask[0] = 0;
@ -75,25 +79,28 @@ public:
this->MomentumSpacePropagatorHt(prop_k,in_k,mass,twist); this->MomentumSpacePropagatorHt(prop_k,in_k,mass,twist);
theFFT.FFT_all_dim(out,prop_k,FFT::backward); theFFT.FFT_all_dim(out,prop_k,FFT::backward);
} }
//phase for boundary condition //phase for boundary condition
out = out * exp(Scalar(2.0*M_PI)*ci*ph); out = out * exp(Scalar(2.0*M_PI)*ci*ph);
}; };
virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass,std::vector<double> twist) { virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass,std::vector<Complex> boundary,std::vector<double> twist) {
bool fiveD = true; //5d propagator by default bool fiveD = true; //5d propagator by default
FreePropagator(in,out,mass,twist,fiveD); FreePropagator(in,out,mass,boundary,twist,fiveD);
}; };
virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass, bool fiveD) { virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass, bool fiveD) {
std::vector<double> twist(Nd,0.0); //default: periodic boundarys in all directions std::vector<double> twist(Nd,0.0); //default: periodic boundarys in all directions
FreePropagator(in,out,mass,twist,fiveD); std::vector<Complex> boundary;
for(int i=0;i<Nd;i++) boundary.push_back(1);//default: periodic boundary conditions
FreePropagator(in,out,mass,boundary,twist,fiveD);
}; };
virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass) { virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass) {
bool fiveD = true; //5d propagator by default bool fiveD = true; //5d propagator by default
std::vector<double> twist(Nd,0.0); //default: periodic boundarys in all directions std::vector<double> twist(Nd,0.0); //default: twist angle 0
FreePropagator(in,out,mass,twist,fiveD); std::vector<Complex> boundary;
for(int i=0;i<Nd;i++) boundary.push_back(1); //default: periodic boundary conditions
FreePropagator(in,out,mass,boundary,twist,fiveD);
}; };
virtual void Instantiatable(void) {}; virtual void Instantiatable(void) {};

View File

@ -93,7 +93,7 @@ public:
virtual void MomentumSpacePropagator(FermionField &out,const FermionField &in,RealD _m,std::vector<double> twist) { assert(0);}; virtual void MomentumSpacePropagator(FermionField &out,const FermionField &in,RealD _m,std::vector<double> twist) { assert(0);};
virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass,std::vector<double> twist) virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass,std::vector<Complex> boundary,std::vector<double> twist)
{ {
FFT theFFT((GridCartesian *) in.Grid()); FFT theFFT((GridCartesian *) in.Grid());
@ -106,14 +106,19 @@ public:
ComplexField coor(in.Grid()); ComplexField coor(in.Grid());
ComplexField ph(in.Grid()); ph = Zero(); ComplexField ph(in.Grid()); ph = Zero();
FermionField in_buf(in.Grid()); in_buf = Zero(); FermionField in_buf(in.Grid()); in_buf = Zero();
Scalar ci(0.0,1.0); Scalar ci(0.0,1.0);
assert(twist.size() == Nd);//check that twist is Nd assert(twist.size() == Nd);//check that twist is Nd
assert(boundary.size() == Nd);//check that boundary conditions is Nd
for(unsigned int nu = 0; nu < Nd; nu++) for(unsigned int nu = 0; nu < Nd; nu++)
{ {
LatticeCoordinate(coor, nu); LatticeCoordinate(coor, nu);
ph = ph + twist[nu]*coor*((1./(in.Grid()->_fdimensions[nu]))); double boundary_phase = ::acos(real(boundary[nu]));
ph = ph + boundary_phase*coor*((1./(in.Grid()->_fdimensions[nu])));
//momenta for propagator shifted by twist+boundary
twist[nu] = twist[nu] + boundary_phase/((2.0*M_PI));
} }
in_buf = (exp(Scalar(2.0*M_PI)*ci*ph*(-1.0)))*in; in_buf = exp(ci*ph*(-1.0))*in;
theFFT.FFT_all_dim(in_k,in_buf,FFT::forward); theFFT.FFT_all_dim(in_k,in_buf,FFT::forward);
this->MomentumSpacePropagator(prop_k,in_k,mass,twist); this->MomentumSpacePropagator(prop_k,in_k,mass,twist);
@ -123,9 +128,12 @@ public:
out = out * exp(Scalar(2.0*M_PI)*ci*ph); out = out * exp(Scalar(2.0*M_PI)*ci*ph);
}; };
virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass) { virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass) {
std::vector<Complex> boundary;
for(int i=0;i<Nd;i++) boundary.push_back(1);//default: periodic boundary conditions
std::vector<double> twist(Nd,0.0); //default: periodic boundarys in all directions std::vector<double> twist(Nd,0.0); //default: periodic boundarys in all directions
FreePropagator(in,out,mass,twist); FreePropagator(in,out,mass,boundary,twist);
}; };
/////////////////////////////////////////////// ///////////////////////////////////////////////
@ -148,6 +156,12 @@ public:
unsigned int tmin, unsigned int tmin,
unsigned int tmax, unsigned int tmax,
ComplexField &lattice_cmplx)=0; ComplexField &lattice_cmplx)=0;
// Only reimplemented in Wilson5D
// Default to just a zero correlation function
virtual void ContractJ5q(FermionField &q_in ,ComplexField &J5q) { J5q=Zero(); };
virtual void ContractJ5q(PropagatorField &q_in,ComplexField &J5q) { J5q=Zero(); };
/////////////////////////////////////////////// ///////////////////////////////////////////////
// Physical field import/export // Physical field import/export
/////////////////////////////////////////////// ///////////////////////////////////////////////

View File

@ -63,6 +63,7 @@ public:
public: public:
typedef WilsonFermion<Impl> WilsonBase; typedef WilsonFermion<Impl> WilsonBase;
virtual int ConstEE(void) { return 0; };
virtual void Instantiatable(void){}; virtual void Instantiatable(void){};
// Constructors // Constructors
WilsonCloverFermion(GaugeField &_Umu, GridCartesian &Fgrid, WilsonCloverFermion(GaugeField &_Umu, GridCartesian &Fgrid,

View File

@ -229,6 +229,10 @@ public:
unsigned int tmin, unsigned int tmin,
unsigned int tmax, unsigned int tmax,
ComplexField &lattice_cmplx); ComplexField &lattice_cmplx);
void ContractJ5q(PropagatorField &q_in,ComplexField &J5q);
void ContractJ5q(FermionField &q_in,ComplexField &J5q);
}; };
NAMESPACE_END(Grid); NAMESPACE_END(Grid);

View File

@ -898,6 +898,79 @@ void WilsonFermion5D<Impl>::MomentumSpacePropagatorHw(FermionField &out,const Fe
merge(qSiteRev, qSiteVec); \ merge(qSiteRev, qSiteVec); \
} }
// psi = chiralProjectPlus(Result_s[Ls/2-1]);
// psi+= chiralProjectMinus(Result_s[Ls/2]);
// PJ5q+=localInnerProduct(psi,psi);
template<class vobj>
Lattice<vobj> spProj5p(const Lattice<vobj> & in)
{
GridBase *grid=in.Grid();
Gamma G5(Gamma::Algebra::Gamma5);
Lattice<vobj> ret(grid);
auto ret_v = ret.View();
auto in_v = in.View();
thread_for(ss,grid->oSites(),{
ret_v[ss] = in_v[ss] + G5*in_v[ss];
});
return ret;
}
template<class vobj>
Lattice<vobj> spProj5m(const Lattice<vobj> & in)
{
Gamma G5(Gamma::Algebra::Gamma5);
GridBase *grid=in.Grid();
Lattice<vobj> ret(grid);
auto ret_v = ret.View();
auto in_v = in.View();
thread_for(ss,grid->oSites(),{
ret_v[ss] = in_v[ss] - G5*in_v[ss];
});
return ret;
}
template <class Impl>
void WilsonFermion5D<Impl>::ContractJ5q(FermionField &q_in,ComplexField &J5q)
{
conformable(GaugeGrid(), J5q.Grid());
conformable(q_in.Grid(), FermionGrid());
// 4d field
int Ls = this->Ls;
FermionField psi(GaugeGrid());
FermionField p_plus (GaugeGrid());
FermionField p_minus(GaugeGrid());
FermionField p(GaugeGrid());
ExtractSlice(p_plus , q_in, Ls/2 , 0);
ExtractSlice(p_minus, q_in, Ls/2-1 , 0);
p_plus = spProj5p(p_plus );
p_minus= spProj5m(p_minus);
p=p_plus+p_minus;
J5q = localInnerProduct(p,p);
}
template <class Impl>
void WilsonFermion5D<Impl>::ContractJ5q(PropagatorField &q_in,ComplexField &J5q)
{
conformable(GaugeGrid(), J5q.Grid());
conformable(q_in.Grid(), FermionGrid());
// 4d field
int Ls = this->Ls;
PropagatorField psi(GaugeGrid());
PropagatorField p_plus (GaugeGrid());
PropagatorField p_minus(GaugeGrid());
PropagatorField p(GaugeGrid());
ExtractSlice(p_plus , q_in, Ls/2 , 0);
ExtractSlice(p_minus, q_in, Ls/2-1 , 0);
p_plus = spProj5p(p_plus );
p_minus= spProj5m(p_minus);
p=p_plus+p_minus;
J5q = localInnerProduct(p,p);
}
template <class Impl> template <class Impl>
void WilsonFermion5D<Impl>::ContractConservedCurrent(PropagatorField &q_in_1, void WilsonFermion5D<Impl>::ContractConservedCurrent(PropagatorField &q_in_1,
PropagatorField &q_in_2, PropagatorField &q_in_2,
@ -908,6 +981,7 @@ void WilsonFermion5D<Impl>::ContractConservedCurrent(PropagatorField &q_in_1,
conformable(q_in_1.Grid(), FermionGrid()); conformable(q_in_1.Grid(), FermionGrid());
conformable(q_in_1.Grid(), q_in_2.Grid()); conformable(q_in_1.Grid(), q_in_2.Grid());
conformable(_FourDimGrid, q_out.Grid()); conformable(_FourDimGrid, q_out.Grid());
PropagatorField tmp1(FermionGrid()), tmp2(FermionGrid()); PropagatorField tmp1(FermionGrid()), tmp2(FermionGrid());
unsigned int LLs = q_in_1.Grid()->_rdimensions[0]; unsigned int LLs = q_in_1.Grid()->_rdimensions[0];
q_out = Zero(); q_out = Zero();
@ -960,7 +1034,6 @@ void WilsonFermion5D<Impl>::ContractConservedCurrent(PropagatorField &q_in_1,
} }
template <class Impl> template <class Impl>
void WilsonFermion5D<Impl>::SeqConservedCurrent(PropagatorField &q_in, void WilsonFermion5D<Impl>::SeqConservedCurrent(PropagatorField &q_in,
PropagatorField &q_out, PropagatorField &q_out,

View File

@ -29,14 +29,24 @@ directory
#ifndef GRID_GAUGE_IMPL_TYPES_H #ifndef GRID_GAUGE_IMPL_TYPES_H
#define GRID_GAUGE_IMPL_TYPES_H #define GRID_GAUGE_IMPL_TYPES_H
NAMESPACE_BEGIN(Grid); NAMESPACE_BEGIN(Grid);
#define CPS_MD_TIME
#ifdef CPS_MD_TIME
#define HMC_MOMENTUM_DENOMINATOR (2.0)
#else
#define HMC_MOMENTUM_DENOMINATOR (1.0)
#endif
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Implementation dependent gauge types // Implementation dependent gauge types
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#define INHERIT_GIMPL_TYPES(GImpl) \ #define INHERIT_GIMPL_TYPES(GImpl) \
typedef typename GImpl::Simd Simd; \ typedef typename GImpl::Simd Simd; \
typedef typename GImpl::Scalar Scalar; \
typedef typename GImpl::LinkField GaugeLinkField; \ typedef typename GImpl::LinkField GaugeLinkField; \
typedef typename GImpl::Field GaugeField; \ typedef typename GImpl::Field GaugeField; \
typedef typename GImpl::ComplexField ComplexField;\ typedef typename GImpl::ComplexField ComplexField;\
@ -54,7 +64,8 @@ NAMESPACE_BEGIN(Grid);
template <class S, int Nrepresentation = Nc, int Nexp = 12 > class GaugeImplTypes { template <class S, int Nrepresentation = Nc, int Nexp = 12 > class GaugeImplTypes {
public: public:
typedef S Simd; typedef S Simd;
typedef typename Simd::scalar_type scalar_type;
typedef scalar_type Scalar;
template <typename vtype> using iImplScalar = iScalar<iScalar<iScalar<vtype> > >; template <typename vtype> using iImplScalar = iScalar<iScalar<iScalar<vtype> > >;
template <typename vtype> using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >; template <typename vtype> using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >;
template <typename vtype> using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd>; template <typename vtype> using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd>;
@ -85,12 +96,10 @@ public:
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// Move these to another class // Move these to another class
// HMC auxiliary functions // HMC auxiliary functions
static inline void generate_momenta(Field &P, GridParallelRNG &pRNG) { static inline void generate_momenta(Field &P, GridParallelRNG &pRNG)
// specific for SU gauge fields {
LinkField Pmu(P.Grid());
Pmu = Zero();
//
// Zbigniew Srocinsky thesis: // Zbigniew Srocinsky thesis:
//
// P(p) = N \Prod_{x\mu}e^-{1/2 Tr (p^2_mux)} // P(p) = N \Prod_{x\mu}e^-{1/2 Tr (p^2_mux)}
// //
// p_x,mu = c_x,mu,a T_a // p_x,mu = c_x,mu,a T_a
@ -101,26 +110,16 @@ public:
// //
// = N \Prod_{x,\mu,a} e^-{1/2 (c_xmua/sqrt{2})^2 } // = N \Prod_{x,\mu,a} e^-{1/2 (c_xmua/sqrt{2})^2 }
// //
// Expect cx' = cxmua/sqrt(2) to be a unit variance gaussian.
// //
// Expect cxmua_new variance sqrt(2). // Expect cxmua variance sqrt(2).
// Was variance cxmua_old variance 1
// //
// tau_old * Pold = 1 = tau_old/sqrt(2) * [Pold * sqrt(2)] // Must scale the momentum by sqrt(2) to invoke CPS and UKQCD conventions
// = tau_new * Pnew
// //
// Hence tau_new = tau_cps = tau_guido/sqrt(2). LinkField Pmu(P.Grid());
// Pmu = Zero();
//
// Must scale the momentum by sqrt(2) up to invoke CPS and UKQCD conventions
//
//
// Hence expect cxmua = cx'*sqrt(2).
//
// Seek the scale parameter to be
for (int mu = 0; mu < Nd; mu++) { for (int mu = 0; mu < Nd; mu++) {
SU<Nrepresentation>::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu); SU<Nrepresentation>::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu);
RealD scale = ::sqrt(2) ; RealD scale = ::sqrt(HMC_MOMENTUM_DENOMINATOR) ;
Pmu = Pmu*scale; Pmu = Pmu*scale;
PokeIndex<LorentzIndex>(P, Pmu, mu); PokeIndex<LorentzIndex>(P, Pmu, mu);
} }

View File

@ -36,6 +36,7 @@ NAMESPACE_BEGIN(Grid);
{ {
public: public:
typedef S Simd; typedef S Simd;
typedef typename Simd::scalar_type Scalar;
template <typename vtype> template <typename vtype>
using iImplGaugeLink = iScalar<iScalar<iScalar<vtype>>>; using iImplGaugeLink = iScalar<iScalar<iScalar<vtype>>>;

View File

@ -0,0 +1,53 @@
#pragma once
namespace Grid{
namespace QCD{
template<class Field>
void HighBoundCheck(LinearOperatorBase<Field> &HermOp,
Field &Phi,
RealD hi)
{
// Eigenvalue bound check at high end
PowerMethod<Field> power_method;
auto lambda_max = power_method(HermOp,Phi);
std::cout << GridLogMessage << "Pseudofermion action lamda_max "<<lambda_max<<"( bound "<<hi<<")"<<std::endl;
assert( (lambda_max < hi) && " High Bounds Check on operator failed" );
}
template<class Field> void InverseSqrtBoundsCheck(int MaxIter,double tol,
LinearOperatorBase<Field> &HermOp,
Field &GaussNoise,
MultiShiftFunction &PowerNegHalf)
{
GridBase *FermionGrid = GaussNoise._grid;
Field X(FermionGrid);
Field Y(FermionGrid);
Field Z(FermionGrid);
X=GaussNoise;
RealD Nx = norm2(X);
ConjugateGradientMultiShift<Field> msCG(MaxIter,PowerNegHalf);
msCG(HermOp,X,Y);
msCG(HermOp,Y,Z);
RealD Nz = norm2(Z);
HermOp.HermOp(Z,Y);
RealD Ny = norm2(Y);
X=X-Y;
RealD Nd = norm2(X);
std::cout << "************************* "<<std::endl;
std::cout << " noise = "<<Nx<<std::endl;
std::cout << " (MdagM^-1/2)^2 noise = "<<Nz<<std::endl;
std::cout << " MdagM (MdagM^-1/2)^2 noise = "<<Ny<<std::endl;
std::cout << " noise - MdagM (MdagM^-1/2)^2 noise = "<<Nd<<std::endl;
std::cout << "************************* "<<std::endl;
assert( (std::sqrt(Nd/Nx)<tol) && " InverseSqrtBoundsCheck ");
}
}
}

View File

@ -38,7 +38,8 @@ See the full license in the file "LICENSE" in the top level distribution directo
#ifndef QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H #ifndef QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H
#define QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H #define QCD_PSEUDOFERMION_EXACT_ONE_FLAVOUR_RATIO_H
NAMESPACE_BEGIN(Grid); namespace Grid{
namespace QCD{
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// Exact one flavour implementation of DWF determinant ratio // // Exact one flavour implementation of DWF determinant ratio //
@ -57,13 +58,29 @@ private:
bool use_heatbath_forecasting; bool use_heatbath_forecasting;
AbstractEOFAFermion<Impl>& Lop; // the basic LH operator AbstractEOFAFermion<Impl>& Lop; // the basic LH operator
AbstractEOFAFermion<Impl>& Rop; // the basic RH operator AbstractEOFAFermion<Impl>& Rop; // the basic RH operator
SchurRedBlackDiagMooeeSolve<FermionField> Solver; SchurRedBlackDiagMooeeSolve<FermionField> SolverHB;
SchurRedBlackDiagMooeeSolve<FermionField> SolverL;
SchurRedBlackDiagMooeeSolve<FermionField> SolverR;
SchurRedBlackDiagMooeeSolve<FermionField> DerivativeSolverL;
SchurRedBlackDiagMooeeSolve<FermionField> DerivativeSolverR;
FermionField Phi; // the pseudofermion field for this trajectory FermionField Phi; // the pseudofermion field for this trajectory
public: public:
ExactOneFlavourRatioPseudoFermionAction(AbstractEOFAFermion<Impl>& _Lop, AbstractEOFAFermion<Impl>& _Rop, ExactOneFlavourRatioPseudoFermionAction(AbstractEOFAFermion<Impl>& _Lop,
OperatorFunction<FermionField>& S, Params& p, bool use_fc=false) : Lop(_Lop), Rop(_Rop), Solver(S), AbstractEOFAFermion<Impl>& _Rop,
Phi(_Lop.FermionGrid()), param(p), use_heatbath_forecasting(use_fc) OperatorFunction<FermionField>& HeatbathCG,
OperatorFunction<FermionField>& ActionCGL, OperatorFunction<FermionField>& ActionCGR,
OperatorFunction<FermionField>& DerivCGL , OperatorFunction<FermionField>& DerivCGR,
Params& p,
bool use_fc=false) :
Lop(_Lop),
Rop(_Rop),
SolverHB(HeatbathCG,false,true),
SolverL(ActionCGL, false, true), SolverR(ActionCGR, false, true),
DerivativeSolverL(DerivCGL, false, true), DerivativeSolverR(DerivCGR, false, true),
Phi(_Lop.FermionGrid()),
param(p),
use_heatbath_forecasting(use_fc)
{ {
AlgRemez remez(param.lo, param.hi, param.precision); AlgRemez remez(param.lo, param.hi, param.precision);
@ -97,6 +114,9 @@ public:
// We generate a Gaussian noise vector \eta, and then compute // We generate a Gaussian noise vector \eta, and then compute
// \Phi = M_{\rm EOFA}^{-1/2} * \eta // \Phi = M_{\rm EOFA}^{-1/2} * \eta
// using a rational approximation to the inverse square root // using a rational approximation to the inverse square root
//
// As a check of rational require \Phi^dag M_{EOFA} \Phi == eta^dag M^-1/2^dag M M^-1/2 eta = eta^dag eta
//
virtual void refresh(const GaugeField& U, GridParallelRNG& pRNG) virtual void refresh(const GaugeField& U, GridParallelRNG& pRNG)
{ {
Lop.ImportGauge(U); Lop.ImportGauge(U);
@ -117,7 +137,6 @@ public:
RealD scale = std::sqrt(0.5); RealD scale = std::sqrt(0.5);
gaussian(pRNG,eta); gaussian(pRNG,eta);
eta = eta * scale; eta = eta * scale;
printf("Heatbath source vector: <\\eta|\\eta> = %1.15e\n", norm2(eta));
// \Phi = ( \alpha_{0} + \sum_{k=1}^{N_{p}} \alpha_{l} * \gamma_{l} ) * \eta // \Phi = ( \alpha_{0} + \sum_{k=1}^{N_{p}} \alpha_{l} * \gamma_{l} ) * \eta
RealD N(PowerNegHalf.norm); RealD N(PowerNegHalf.norm);
@ -131,18 +150,18 @@ public:
spProj(eta, tmp[0], -1, Lop.Ls); spProj(eta, tmp[0], -1, Lop.Ls);
Lop.Omega(tmp[0], tmp[1], -1, 0); Lop.Omega(tmp[0], tmp[1], -1, 0);
G5R5(CG_src, tmp[1]); G5R5(CG_src, tmp[1]);
tmp[1] = Zero(); tmp[1] = zero;
for(int k=0; k<param.degree; ++k){ for(int k=0; k<param.degree; ++k){
gamma_l = 1.0 / ( 1.0 + PowerNegHalf.poles[k] ); gamma_l = 1.0 / ( 1.0 + PowerNegHalf.poles[k] );
Lop.RefreshShiftCoefficients(-gamma_l); Lop.RefreshShiftCoefficients(-gamma_l);
if(use_heatbath_forecasting){ // Forecast CG guess using solutions from previous poles if(use_heatbath_forecasting){ // Forecast CG guess using solutions from previous poles
Lop.Mdag(CG_src, Forecast_src); Lop.Mdag(CG_src, Forecast_src);
CG_soln = Forecast(Lop, Forecast_src, prev_solns); CG_soln = Forecast(Lop, Forecast_src, prev_solns);
Solver(Lop, CG_src, CG_soln); SolverHB(Lop, CG_src, CG_soln);
prev_solns.push_back(CG_soln); prev_solns.push_back(CG_soln);
} else { } else {
CG_soln = Zero(); // Just use zero as the initial guess CG_soln = zero; // Just use zero as the initial guess
Solver(Lop, CG_src, CG_soln); SolverHB(Lop, CG_src, CG_soln);
} }
Lop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back Lop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back
tmp[1] = tmp[1] + ( PowerNegHalf.residues[k]*gamma_l*gamma_l*Lop.k ) * tmp[0]; tmp[1] = tmp[1] + ( PowerNegHalf.residues[k]*gamma_l*gamma_l*Lop.k ) * tmp[0];
@ -157,7 +176,7 @@ public:
spProj(eta, tmp[0], 1, Rop.Ls); spProj(eta, tmp[0], 1, Rop.Ls);
Rop.Omega(tmp[0], tmp[1], 1, 0); Rop.Omega(tmp[0], tmp[1], 1, 0);
G5R5(CG_src, tmp[1]); G5R5(CG_src, tmp[1]);
tmp[1] = Zero(); tmp[1] = zero;
if(use_heatbath_forecasting){ prev_solns.clear(); } // empirically, LH solns don't help for RH solves if(use_heatbath_forecasting){ prev_solns.clear(); } // empirically, LH solns don't help for RH solves
for(int k=0; k<param.degree; ++k){ for(int k=0; k<param.degree; ++k){
gamma_l = 1.0 / ( 1.0 + PowerNegHalf.poles[k] ); gamma_l = 1.0 / ( 1.0 + PowerNegHalf.poles[k] );
@ -165,11 +184,11 @@ public:
if(use_heatbath_forecasting){ if(use_heatbath_forecasting){
Rop.Mdag(CG_src, Forecast_src); Rop.Mdag(CG_src, Forecast_src);
CG_soln = Forecast(Rop, Forecast_src, prev_solns); CG_soln = Forecast(Rop, Forecast_src, prev_solns);
Solver(Rop, CG_src, CG_soln); SolverHB(Rop, CG_src, CG_soln);
prev_solns.push_back(CG_soln); prev_solns.push_back(CG_soln);
} else { } else {
CG_soln = Zero(); CG_soln = zero;
Solver(Rop, CG_src, CG_soln); SolverHB(Rop, CG_src, CG_soln);
} }
Rop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back Rop.Dtilde(CG_soln, tmp[0]); // We actually solved Cayley preconditioned system: transform back
tmp[1] = tmp[1] - ( PowerNegHalf.residues[k]*gamma_l*gamma_l*Rop.k ) * tmp[0]; tmp[1] = tmp[1] - ( PowerNegHalf.residues[k]*gamma_l*gamma_l*Rop.k ) * tmp[0];
@ -181,8 +200,47 @@ public:
// Reset shift coefficients for energy and force evals // Reset shift coefficients for energy and force evals
Lop.RefreshShiftCoefficients(0.0); Lop.RefreshShiftCoefficients(0.0);
Rop.RefreshShiftCoefficients(-1.0); Rop.RefreshShiftCoefficients(-1.0);
// Bounds check
RealD EtaDagEta = norm2(eta);
// RealD PhiDagMPhi= norm2(eta);
}; };
void Meofa(const GaugeField& U,const FermionField &phi, FermionField & Mphi)
{
#if 0
Lop.ImportGauge(U);
Rop.ImportGauge(U);
FermionField spProj_Phi(Lop.FermionGrid());
FermionField mPhi(Lop.FermionGrid());
std::vector<FermionField> tmp(2, Lop.FermionGrid());
mPhi = phi;
// LH term: S = S - k <\Phi| P_{-} \Omega_{-}^{\dagger} H(mf)^{-1} \Omega_{-} P_{-} |\Phi>
spProj(Phi, spProj_Phi, -1, Lop.Ls);
Lop.Omega(spProj_Phi, tmp[0], -1, 0);
G5R5(tmp[1], tmp[0]);
tmp[0] = zero;
SolverL(Lop, tmp[1], tmp[0]);
Lop.Dtilde(tmp[0], tmp[1]); // We actually solved Cayley preconditioned system: transform back
Lop.Omega(tmp[1], tmp[0], -1, 1);
mPhi = mPhi - Lop.k * innerProduct(spProj_Phi, tmp[0]).real();
// RH term: S = S + k <\Phi| P_{+} \Omega_{+}^{\dagger} ( H(mb)
// - \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{-} P_{-} |\Phi>
spProj(Phi, spProj_Phi, 1, Rop.Ls);
Rop.Omega(spProj_Phi, tmp[0], 1, 0);
G5R5(tmp[1], tmp[0]);
tmp[0] = zero;
SolverR(Rop, tmp[1], tmp[0]);
Rop.Dtilde(tmp[0], tmp[1]);
Rop.Omega(tmp[1], tmp[0], 1, 1);
action += Rop.k * innerProduct(spProj_Phi, tmp[0]).real();
#endif
}
// EOFA action: see Eqn. (10) of arXiv:1706.05843 // EOFA action: see Eqn. (10) of arXiv:1706.05843
virtual RealD S(const GaugeField& U) virtual RealD S(const GaugeField& U)
{ {
@ -199,8 +257,8 @@ public:
spProj(Phi, spProj_Phi, -1, Lop.Ls); spProj(Phi, spProj_Phi, -1, Lop.Ls);
Lop.Omega(spProj_Phi, tmp[0], -1, 0); Lop.Omega(spProj_Phi, tmp[0], -1, 0);
G5R5(tmp[1], tmp[0]); G5R5(tmp[1], tmp[0]);
tmp[0] = Zero(); tmp[0] = zero;
Solver(Lop, tmp[1], tmp[0]); SolverL(Lop, tmp[1], tmp[0]);
Lop.Dtilde(tmp[0], tmp[1]); // We actually solved Cayley preconditioned system: transform back Lop.Dtilde(tmp[0], tmp[1]); // We actually solved Cayley preconditioned system: transform back
Lop.Omega(tmp[1], tmp[0], -1, 1); Lop.Omega(tmp[1], tmp[0], -1, 1);
action -= Lop.k * innerProduct(spProj_Phi, tmp[0]).real(); action -= Lop.k * innerProduct(spProj_Phi, tmp[0]).real();
@ -210,8 +268,8 @@ public:
spProj(Phi, spProj_Phi, 1, Rop.Ls); spProj(Phi, spProj_Phi, 1, Rop.Ls);
Rop.Omega(spProj_Phi, tmp[0], 1, 0); Rop.Omega(spProj_Phi, tmp[0], 1, 0);
G5R5(tmp[1], tmp[0]); G5R5(tmp[1], tmp[0]);
tmp[0] = Zero(); tmp[0] = zero;
Solver(Rop, tmp[1], tmp[0]); SolverR(Rop, tmp[1], tmp[0]);
Rop.Dtilde(tmp[0], tmp[1]); Rop.Dtilde(tmp[0], tmp[1]);
Rop.Omega(tmp[1], tmp[0], 1, 1); Rop.Omega(tmp[1], tmp[0], 1, 1);
action += Rop.k * innerProduct(spProj_Phi, tmp[0]).real(); action += Rop.k * innerProduct(spProj_Phi, tmp[0]).real();
@ -233,32 +291,36 @@ public:
GaugeField force(Lop.GaugeGrid()); GaugeField force(Lop.GaugeGrid());
/////////////////////////////////////////////
// PAB:
// Optional single precision derivative ?
/////////////////////////////////////////////
// LH: dSdU = k \chi_{L}^{\dagger} \gamma_{5} R_{5} ( \partial_{x,\mu} D_{w} ) \chi_{L} // LH: dSdU = k \chi_{L}^{\dagger} \gamma_{5} R_{5} ( \partial_{x,\mu} D_{w} ) \chi_{L}
// \chi_{L} = H(mf)^{-1} \Omega_{-} P_{-} \Phi // \chi_{L} = H(mf)^{-1} \Omega_{-} P_{-} \Phi
spProj(Phi, spProj_Phi, -1, Lop.Ls); spProj(Phi, spProj_Phi, -1, Lop.Ls);
Lop.Omega(spProj_Phi, Omega_spProj_Phi, -1, 0); Lop.Omega(spProj_Phi, Omega_spProj_Phi, -1, 0);
G5R5(CG_src, Omega_spProj_Phi); G5R5(CG_src, Omega_spProj_Phi);
spProj_Phi = Zero(); spProj_Phi = zero;
Solver(Lop, CG_src, spProj_Phi); DerivativeSolverL(Lop, CG_src, spProj_Phi);
Lop.Dtilde(spProj_Phi, Chi); Lop.Dtilde(spProj_Phi, Chi);
G5R5(g5_R5_Chi, Chi); G5R5(g5_R5_Chi, Chi);
Lop.MDeriv(force, g5_R5_Chi, Chi, DaggerNo); Lop.MDeriv(force, g5_R5_Chi, Chi, DaggerNo);
dSdU = Lop.k * force; dSdU = -Lop.k * force;
// RH: dSdU = dSdU - k \chi_{R}^{\dagger} \gamma_{5} R_{5} ( \partial_{x,\mu} D_{w} ) \chi_{} // RH: dSdU = dSdU - k \chi_{R}^{\dagger} \gamma_{5} R_{5} ( \partial_{x,\mu} D_{w} ) \chi_{}
// \chi_{R} = ( H(mb) - \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{+} P_{+} \Phi // \chi_{R} = ( H(mb) - \Delta_{+}(mf,mb) P_{+} )^{-1} \Omega_{+} P_{+} \Phi
spProj(Phi, spProj_Phi, 1, Rop.Ls); spProj(Phi, spProj_Phi, 1, Rop.Ls);
Rop.Omega(spProj_Phi, Omega_spProj_Phi, 1, 0); Rop.Omega(spProj_Phi, Omega_spProj_Phi, 1, 0);
G5R5(CG_src, Omega_spProj_Phi); G5R5(CG_src, Omega_spProj_Phi);
spProj_Phi = Zero(); spProj_Phi = zero;
Solver(Rop, CG_src, spProj_Phi); DerivativeSolverR(Rop, CG_src, spProj_Phi);
Rop.Dtilde(spProj_Phi, Chi); Rop.Dtilde(spProj_Phi, Chi);
G5R5(g5_R5_Chi, Chi); G5R5(g5_R5_Chi, Chi);
Lop.MDeriv(force, g5_R5_Chi, Chi, DaggerNo); Lop.MDeriv(force, g5_R5_Chi, Chi, DaggerNo);
dSdU = dSdU - Rop.k * force; dSdU = dSdU + Rop.k * force;
}; };
}; };
}}
NAMESPACE_END(Grid);
#endif #endif

View File

@ -156,6 +156,13 @@ public:
msCG(Mpc, PhiOdd, Y); msCG(Mpc, PhiOdd, Y);
if ( (rand()%param.BoundsCheckFreq)==0 ) {
FermionField gauss(FermOp.FermionRedBlackGrid());
gauss = PhiOdd;
HighBoundCheck(Mpc,gauss,param.hi);
InverseSqrtBoundsCheck(param.MaxIter,param.tolerance*100,Mpc,gauss,PowerNegHalf);
}
RealD action = norm2(Y); RealD action = norm2(Y);
std::cout << GridLogMessage << "Pseudofermion action FIXME -- is -1/4 " std::cout << GridLogMessage << "Pseudofermion action FIXME -- is -1/4 "
"solve or -1/2 solve faster??? " "solve or -1/2 solve faster??? "

View File

@ -28,7 +28,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
#ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_EVEN_ODD_RATIONAL_RATIO_H #ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_EVEN_ODD_RATIONAL_RATIO_H
#define QCD_PSEUDOFERMION_ONE_FLAVOUR_EVEN_ODD_RATIONAL_RATIO_H #define QCD_PSEUDOFERMION_ONE_FLAVOUR_EVEN_ODD_RATIONAL_RATIO_H
NAMESPACE_BEGIN(Grid); namespace Grid{
namespace QCD{
/////////////////////////////////////// ///////////////////////////////////////
// One flavour rational // One flavour rational
@ -144,7 +145,7 @@ public:
assert(NumOp.ConstEE() == 1); assert(NumOp.ConstEE() == 1);
assert(DenOp.ConstEE() == 1); assert(DenOp.ConstEE() == 1);
PhiEven = Zero(); PhiEven = zero;
}; };
@ -169,6 +170,14 @@ public:
ConjugateGradientMultiShift<FermionField> msCG_M(param.MaxIter,PowerNegQuarter); ConjugateGradientMultiShift<FermionField> msCG_M(param.MaxIter,PowerNegQuarter);
msCG_M(MdagM,X,Y); msCG_M(MdagM,X,Y);
// Randomly apply rational bounds checks.
if ( (rand()%param.BoundsCheckFreq)==0 ) {
FermionField gauss(NumOp.FermionRedBlackGrid());
gauss = PhiOdd;
HighBoundCheck(MdagM,gauss,param.hi);
InverseSqrtBoundsCheck(param.MaxIter,param.tolerance*100,MdagM,gauss,PowerNegHalf);
}
// Phidag VdagV^1/4 MdagM^-1/4 MdagM^-1/4 VdagV^1/4 Phi // Phidag VdagV^1/4 MdagM^-1/4 MdagM^-1/4 VdagV^1/4 Phi
RealD action = norm2(Y); RealD action = norm2(Y);
@ -236,7 +245,7 @@ public:
RealD ak; RealD ak;
dSdU = Zero(); dSdU = zero;
// With these building blocks // With these building blocks
// //
@ -273,7 +282,8 @@ public:
}; };
}; };
}
}
NAMESPACE_END(Grid);
#endif #endif

View File

@ -28,7 +28,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
#ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_RATIONAL_H #ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_RATIONAL_H
#define QCD_PSEUDOFERMION_ONE_FLAVOUR_RATIONAL_H #define QCD_PSEUDOFERMION_ONE_FLAVOUR_RATIONAL_H
NAMESPACE_BEGIN(Grid); namespace Grid{
namespace QCD{
/////////////////////////////////////// ///////////////////////////////////////
// One flavour rational // One flavour rational
@ -142,6 +143,14 @@ public:
msCG(MdagMOp,Phi,Y); msCG(MdagMOp,Phi,Y);
if ( (rand()%param.BoundsCheckFreq)==0 ) {
FermionField gauss(FermOp.FermionGrid());
gauss = Phi;
HighBoundCheck(MdagMOp,gauss,param.hi);
InverseSqrtBoundsCheck(param.MaxIter,param.tolerance*100,MdagMOp,gauss,PowerNegHalf);
}
RealD action = norm2(Y); RealD action = norm2(Y);
std::cout << GridLogMessage << "Pseudofermion action FIXME -- is -1/4 solve or -1/2 solve faster??? "<<action<<std::endl; std::cout << GridLogMessage << "Pseudofermion action FIXME -- is -1/4 solve or -1/2 solve faster??? "<<action<<std::endl;
return action; return action;
@ -187,7 +196,7 @@ public:
msCG(MdagMOp,Phi,MPhi_k); msCG(MdagMOp,Phi,MPhi_k);
dSdU = Zero(); dSdU = zero;
for(int k=0;k<Npole;k++){ for(int k=0;k<Npole;k++){
RealD ak = PowerNegHalf.residues[k]; RealD ak = PowerNegHalf.residues[k];
@ -205,8 +214,8 @@ public:
}; };
}; };
}
NAMESPACE_END(Grid); }
#endif #endif

View File

@ -28,7 +28,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
#ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_RATIONAL_RATIO_H #ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_RATIONAL_RATIO_H
#define QCD_PSEUDOFERMION_ONE_FLAVOUR_RATIONAL_RATIO_H #define QCD_PSEUDOFERMION_ONE_FLAVOUR_RATIONAL_RATIO_H
NAMESPACE_BEGIN(Grid); namespace Grid{
namespace QCD{
/////////////////////////////////////// ///////////////////////////////////////
// One flavour rational // One flavour rational
@ -155,6 +156,14 @@ public:
ConjugateGradientMultiShift<FermionField> msCG_M(param.MaxIter,PowerNegQuarter); ConjugateGradientMultiShift<FermionField> msCG_M(param.MaxIter,PowerNegQuarter);
msCG_M(MdagM,X,Y); msCG_M(MdagM,X,Y);
// Randomly apply rational bounds checks.
if ( (rand()%param.BoundsCheckFreq)==0 ) {
FermionField gauss(NumOp.FermionGrid());
gauss = Phi;
HighBoundCheck(MdagM,gauss,param.hi);
InverseSqrtBoundsCheck(param.MaxIter,param.tolerance*100,MdagM,gauss,PowerNegHalf);
}
// Phidag VdagV^1/4 MdagM^-1/4 MdagM^-1/4 VdagV^1/4 Phi // Phidag VdagV^1/4 MdagM^-1/4 MdagM^-1/4 VdagV^1/4 Phi
RealD action = norm2(Y); RealD action = norm2(Y);
@ -222,7 +231,7 @@ public:
RealD ak; RealD ak;
dSdU = Zero(); dSdU = zero;
// With these building blocks // With these building blocks
// //
@ -259,7 +268,8 @@ public:
}; };
}; };
}
}
NAMESPACE_END(Grid);
#endif #endif

View File

@ -29,6 +29,9 @@ directory
#ifndef QCD_PSEUDOFERMION_AGGREGATE_H #ifndef QCD_PSEUDOFERMION_AGGREGATE_H
#define QCD_PSEUDOFERMION_AGGREGATE_H #define QCD_PSEUDOFERMION_AGGREGATE_H
// Rational functions
#include <Grid/qcd/action/pseudofermion/Bounds.h>
#include <Grid/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h> #include <Grid/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h>
#include <Grid/qcd/action/pseudofermion/TwoFlavour.h> #include <Grid/qcd/action/pseudofermion/TwoFlavour.h>
#include <Grid/qcd/action/pseudofermion/TwoFlavourRatio.h> #include <Grid/qcd/action/pseudofermion/TwoFlavourRatio.h>

View File

@ -84,21 +84,20 @@ public:
// and must multiply by 0.707.... // and must multiply by 0.707....
// //
// Chroma has this scale factor: two_flavor_monomial_w.h // Chroma has this scale factor: two_flavor_monomial_w.h
// CPS uses this factor
// IroIro: does not use this scale. It is absorbed by a change of vars // IroIro: does not use this scale. It is absorbed by a change of vars
// in the Phi integral, and thus is only an irrelevant prefactor for // in the Phi integral, and thus is only an irrelevant prefactor for
// the partition function. // the partition function.
// //
RealD scale = std::sqrt(0.5); const RealD scale = std::sqrt(0.5);
FermionField eta(FermOp.FermionGrid()); FermionField eta(FermOp.FermionGrid());
gaussian(pRNG, eta); gaussian(pRNG, eta); eta = scale *eta;
FermOp.ImportGauge(U); FermOp.ImportGauge(U);
FermOp.Mdag(eta, Phi); FermOp.Mdag(eta, Phi);
Phi = Phi * scale;
}; };
////////////////////////////////////////////////////// //////////////////////////////////////////////////////

View File

@ -29,7 +29,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
#ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_RATIO_H #ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_RATIO_H
#define QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_RATIO_H #define QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_RATIO_H
NAMESPACE_BEGIN(Grid); namespace Grid{
namespace QCD{
/////////////////////////////////////// ///////////////////////////////////////
// Two flavour ratio // Two flavour ratio
@ -45,6 +46,7 @@ private:
OperatorFunction<FermionField> &DerivativeSolver; OperatorFunction<FermionField> &DerivativeSolver;
OperatorFunction<FermionField> &ActionSolver; OperatorFunction<FermionField> &ActionSolver;
OperatorFunction<FermionField> &HeatbathSolver;
FermionField PhiOdd; // the pseudo fermion field for this trajectory FermionField PhiOdd; // the pseudo fermion field for this trajectory
FermionField PhiEven; // the pseudo fermion field for this trajectory FermionField PhiEven; // the pseudo fermion field for this trajectory
@ -54,10 +56,17 @@ public:
FermionOperator<Impl> &_DenOp, FermionOperator<Impl> &_DenOp,
OperatorFunction<FermionField> & DS, OperatorFunction<FermionField> & DS,
OperatorFunction<FermionField> & AS ) : OperatorFunction<FermionField> & AS ) :
TwoFlavourEvenOddRatioPseudoFermionAction(_NumOp,_DenOp, DS,AS,AS) {};
TwoFlavourEvenOddRatioPseudoFermionAction(FermionOperator<Impl> &_NumOp,
FermionOperator<Impl> &_DenOp,
OperatorFunction<FermionField> & DS,
OperatorFunction<FermionField> & AS, OperatorFunction<FermionField> & HS) :
NumOp(_NumOp), NumOp(_NumOp),
DenOp(_DenOp), DenOp(_DenOp),
DerivativeSolver(DS), DerivativeSolver(DS),
ActionSolver(AS), ActionSolver(AS),
HeatbathSolver(HS),
PhiEven(_NumOp.FermionRedBlackGrid()), PhiEven(_NumOp.FermionRedBlackGrid()),
PhiOdd(_NumOp.FermionRedBlackGrid()) PhiOdd(_NumOp.FermionRedBlackGrid())
{ {
@ -109,8 +118,8 @@ public:
// Odd det factors // Odd det factors
Mpc.MpcDag(etaOdd,PhiOdd); Mpc.MpcDag(etaOdd,PhiOdd);
tmp=Zero(); tmp=zero;
ActionSolver(Vpc,PhiOdd,tmp); HeatbathSolver(Vpc,PhiOdd,tmp);
Vpc.Mpc(tmp,PhiOdd); Vpc.Mpc(tmp,PhiOdd);
// Even det factors // Even det factors
@ -137,7 +146,7 @@ public:
FermionField Y(NumOp.FermionRedBlackGrid()); FermionField Y(NumOp.FermionRedBlackGrid());
Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi
X=Zero(); X=zero;
ActionSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi ActionSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi
//Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi //Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi
// Multiply by Ydag // Multiply by Ydag
@ -145,7 +154,7 @@ public:
//RealD action = norm2(Y); //RealD action = norm2(Y);
// The EE factorised block; normally can replace with Zero() if det is constant (gauge field indept) // The EE factorised block; normally can replace with zero if det is constant (gauge field indept)
// Only really clover term that creates this. Leave the EE portion as a future to do to make most // Only really clover term that creates this. Leave the EE portion as a future to do to make most
// rapid progresss on DWF for now. // rapid progresss on DWF for now.
// //
@ -173,13 +182,13 @@ public:
FermionField Y(NumOp.FermionRedBlackGrid()); FermionField Y(NumOp.FermionRedBlackGrid());
// This assignment is necessary to be compliant with the HMC grids // This assignment is necessary to be compliant with the HMC grids
GaugeField force(dSdU.Grid()); GaugeField force(dSdU._grid);
//Y=Vdag phi //Y=Vdag phi
//X = (Mdag M)^-1 V^dag phi //X = (Mdag M)^-1 V^dag phi
//Y = (Mdag)^-1 V^dag phi //Y = (Mdag)^-1 V^dag phi
Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi
X=Zero(); X=zero;
DerivativeSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi DerivativeSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi
Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi
@ -203,7 +212,6 @@ public:
}; };
}; };
}
NAMESPACE_END(Grid); }
#endif #endif

View File

@ -41,19 +41,16 @@ public:
GRID_SERIALIZABLE_CLASS_MEMBERS(IntegratorParameters, GRID_SERIALIZABLE_CLASS_MEMBERS(IntegratorParameters,
std::string, name, // name of the integrator std::string, name, // name of the integrator
unsigned int, MDsteps, // number of outer steps unsigned int, MDsteps, // number of outer steps
RealD, trajL, // trajectory length RealD, trajL) // trajectory length
)
IntegratorParameters(int MDsteps_ = 10, RealD trajL_ = 1.0) IntegratorParameters(int MDsteps_ = 10, RealD trajL_ = 1.0)
: MDsteps(MDsteps_), : MDsteps(MDsteps_),
trajL(trajL_){ trajL(trajL_) {};
// empty body constructor
};
template <class ReaderClass, typename std::enable_if<isReader<ReaderClass>::value, int >::type = 0 > template <class ReaderClass, typename std::enable_if<isReader<ReaderClass>::value, int >::type = 0 >
IntegratorParameters(ReaderClass & Reader){ IntegratorParameters(ReaderClass & Reader)
std::cout << "Reading integrator\n"; {
std::cout << GridLogMessage << "Reading integrator\n";
read(Reader, "Integrator", *this); read(Reader, "Integrator", *this);
} }
@ -83,17 +80,18 @@ protected:
const ActionSet<Field, RepresentationPolicy> as; const ActionSet<Field, RepresentationPolicy> as;
void update_P(Field& U, int level, double ep) { void update_P(Field& U, int level, double ep)
{
t_P[level] += ep; t_P[level] += ep;
update_P(P, U, level, ep); update_P(P, U, level, ep);
std::cout << GridLogIntegrator << "[" << level << "] P " std::cout << GridLogIntegrator << "[" << level << "] P " << " dt " << ep << " : t_P " << t_P[level] << std::endl;
<< " dt " << ep << " : t_P " << t_P[level] << std::endl;
} }
// to be used by the actionlevel class to iterate // to be used by the actionlevel class to iterate
// over the representations // over the representations
struct _updateP { struct _updateP
{
template <class FieldType, class GF, class Repr> template <class FieldType, class GF, class Repr>
void operator()(std::vector<Action<FieldType>*> repr_set, Repr& Rep, void operator()(std::vector<Action<FieldType>*> repr_set, Repr& Rep,
GF& Mom, GF& U, double ep) { GF& Mom, GF& U, double ep) {
@ -104,7 +102,7 @@ protected:
GF force = Rep.RtoFundamentalProject(forceR); // Ta for the fundamental rep GF force = Rep.RtoFundamentalProject(forceR); // Ta for the fundamental rep
Real force_abs = std::sqrt(norm2(force)/(U.Grid()->gSites())); Real force_abs = std::sqrt(norm2(force)/(U.Grid()->gSites()));
std::cout << GridLogIntegrator << "Hirep Force average: " << force_abs << std::endl; std::cout << GridLogIntegrator << "Hirep Force average: " << force_abs << std::endl;
Mom -= force * ep ; Mom -= force * ep* HMC_MOMENTUM_DENOMINATOR;;
} }
} }
} update_P_hireps{}; } update_P_hireps{};
@ -128,18 +126,19 @@ protected:
double end_force = usecond(); double end_force = usecond();
Real force_abs = std::sqrt(norm2(force)/U.Grid()->gSites()); Real force_abs = std::sqrt(norm2(force)/U.Grid()->gSites());
std::cout << GridLogIntegrator << "["<<level<<"]["<<a<<"] Force average: " << force_abs << std::endl; std::cout << GridLogIntegrator << "["<<level<<"]["<<a<<"] Force average: " << force_abs << std::endl;
Mom -= force * ep; Mom -= force * ep* HMC_MOMENTUM_DENOMINATOR;;
double end_full = usecond(); double end_full = usecond();
double time_full = (end_full - start_full) / 1e3; double time_full = (end_full - start_full) / 1e3;
double time_force = (end_force - start_force) / 1e3; double time_force = (end_force - start_force) / 1e3;
std::cout << GridLogIntegrator << "["<<level<<"]["<<a<<"] P update elapsed time: " << time_full << " ms (force: " << time_force << " ms)" << std::endl; std::cout << GridLogMessage << "["<<level<<"]["<<a<<"] P update elapsed time: " << time_full << " ms (force: " << time_force << " ms)" << std::endl;
} }
// Force from the other representations // Force from the other representations
as[level].apply(update_P_hireps, Representations, Mom, U, ep); as[level].apply(update_P_hireps, Representations, Mom, U, ep);
} }
void update_U(Field& U, double ep) { void update_U(Field& U, double ep)
{
update_U(P, U, ep); update_U(P, U, ep);
t_U += ep; t_U += ep;
@ -147,7 +146,8 @@ protected:
std::cout << GridLogIntegrator << " " << "[" << fl << "] U " << " dt " << ep << " : t_U " << t_U << std::endl; std::cout << GridLogIntegrator << " " << "[" << fl << "] U " << " dt " << ep << " : t_U " << t_U << std::endl;
} }
void update_U(MomentaField& Mom, Field& U, double ep) { void update_U(MomentaField& Mom, Field& U, double ep)
{
// exponential of Mom*U in the gauge fields case // exponential of Mom*U in the gauge fields case
FieldImplementation::update_field(Mom, U, ep); FieldImplementation::update_field(Mom, U, ep);
@ -169,7 +169,8 @@ public:
P(grid), P(grid),
levels(Aset.size()), levels(Aset.size()),
Smearer(Sm), Smearer(Sm),
Representations(grid) { Representations(grid)
{
t_P.resize(levels, 0.0); t_P.resize(levels, 0.0);
t_U = 0.0; t_U = 0.0;
// initialization of smearer delegated outside of Integrator // initialization of smearer delegated outside of Integrator
@ -179,12 +180,14 @@ public:
virtual std::string integrator_name() = 0; virtual std::string integrator_name() = 0;
void print_parameters(){ void print_parameters()
{
std::cout << GridLogMessage << "[Integrator] Name : "<< integrator_name() << std::endl; std::cout << GridLogMessage << "[Integrator] Name : "<< integrator_name() << std::endl;
Params.print_parameters(); Params.print_parameters();
} }
void print_actions(){ void print_actions()
{
std::cout << GridLogMessage << ":::::::::::::::::::::::::::::::::::::::::" << std::endl; std::cout << GridLogMessage << ":::::::::::::::::::::::::::::::::::::::::" << std::endl;
std::cout << GridLogMessage << "[Integrator] Action summary: "<<std::endl; std::cout << GridLogMessage << "[Integrator] Action summary: "<<std::endl;
for (int level = 0; level < as.size(); ++level) { for (int level = 0; level < as.size(); ++level) {
@ -198,7 +201,8 @@ public:
} }
void reverse_momenta(){ void reverse_momenta()
{
P *= -1.0; P *= -1.0;
} }
@ -217,7 +221,8 @@ public:
} refresh_hireps{}; } refresh_hireps{};
// Initialization of momenta and actions // Initialization of momenta and actions
void refresh(Field& U, GridParallelRNG& pRNG) { void refresh(Field& U, GridParallelRNG& pRNG)
{
assert(P.Grid() == U.Grid()); assert(P.Grid() == U.Grid());
std::cout << GridLogIntegrator << "Integrator refresh\n"; std::cout << GridLogIntegrator << "Integrator refresh\n";
@ -237,8 +242,7 @@ public:
for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) { for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) {
// get gauge field from the SmearingPolicy and // get gauge field from the SmearingPolicy and
// based on the boolean is_smeared in actionID // based on the boolean is_smeared in actionID
Field& Us = Field& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
as[level].actions.at(actionID)->refresh(Us, pRNG); as[level].actions.at(actionID)->refresh(Us, pRNG);
} }
@ -251,13 +255,11 @@ public:
// over the representations // over the representations
struct _S { struct _S {
template <class FieldType, class Repr> template <class FieldType, class Repr>
void operator()(std::vector<Action<FieldType>*> repr_set, Repr& Rep, void operator()(std::vector<Action<FieldType>*> repr_set, Repr& Rep, int level, RealD& H) {
int level, RealD& H) {
for (int a = 0; a < repr_set.size(); ++a) { for (int a = 0; a < repr_set.size(); ++a) {
RealD Hterm = repr_set.at(a)->S(Rep.U); RealD Hterm = repr_set.at(a)->S(Rep.U);
std::cout << GridLogMessage << "S Level " << level << " term " << a std::cout << GridLogMessage << "S Level " << level << " term " << a << " H Hirep = " << Hterm << std::endl;
<< " H Hirep = " << Hterm << std::endl;
H += Hterm; H += Hterm;
} }
@ -265,22 +267,24 @@ public:
} S_hireps{}; } S_hireps{};
// Calculate action // Calculate action
RealD S(Field& U) { // here also U not used RealD S(Field& U)
{ // here also U not used
std::cout << GridLogIntegrator << "Integrator action\n";
RealD H = - FieldImplementation::FieldSquareNorm(P)/HMC_MOMENTUM_DENOMINATOR; // - trace (P*P)/denom
RealD H = - FieldImplementation::FieldSquareNorm(P); // - trace (P*P)
RealD Hterm; RealD Hterm;
std::cout << GridLogMessage << "Momentum action H_p = " << H << "\n";
// Actions // Actions
for (int level = 0; level < as.size(); ++level) { for (int level = 0; level < as.size(); ++level) {
for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) { for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) {
// get gauge field from the SmearingPolicy and // get gauge field from the SmearingPolicy and
// based on the boolean is_smeared in actionID // based on the boolean is_smeared in actionID
Field& Us = Field& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
Smearer.get_U(as[level].actions.at(actionID)->is_smeared); std::cout << GridLogMessage << "S [" << level << "][" << actionID << "] action eval " << std::endl;
Hterm = as[level].actions.at(actionID)->S(Us); Hterm = as[level].actions.at(actionID)->S(Us);
std::cout << GridLogMessage << "S Level " << level << " term " std::cout << GridLogMessage << "S [" << level << "][" << actionID << "] H = " << Hterm << std::endl;
<< actionID << " H = " << Hterm << std::endl;
H += Hterm; H += Hterm;
} }
as[level].apply(S_hireps, Representations, level, H); as[level].apply(S_hireps, Representations, level, H);
@ -289,7 +293,8 @@ public:
return H; return H;
} }
void integrate(Field& U) { void integrate(Field& U)
{
// reset the clocks // reset the clocks
t_U = 0; t_U = 0;
for (int level = 0; level < as.size(); ++level) { for (int level = 0; level < as.size(); ++level) {
@ -305,8 +310,7 @@ public:
// Check the clocks all match on all levels // Check the clocks all match on all levels
for (int level = 0; level < as.size(); ++level) { for (int level = 0; level < as.size(); ++level) {
assert(fabs(t_U - t_P[level]) < 1.0e-6); // must be the same assert(fabs(t_U - t_P[level]) < 1.0e-6); // must be the same
std::cout << GridLogIntegrator << " times[" << level std::cout << GridLogIntegrator << " times[" << level << "]= " << t_P[level] << " " << t_U << std::endl;
<< "]= " << t_P[level] << " " << t_U << std::endl;
} }
// and that we indeed got to the end of the trajectory // and that we indeed got to the end of the trajectory

View File

@ -92,22 +92,17 @@ NAMESPACE_BEGIN(Grid);
* P 1/2 P 1/2 * P 1/2 P 1/2
*/ */
template <class FieldImplementation, class SmearingPolicy, template <class FieldImplementation, class SmearingPolicy, class RepresentationPolicy = Representations<FundamentalRepresentation> >
class RepresentationPolicy = class LeapFrog : public Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>
Representations<FundamentalRepresentation> > {
class LeapFrog : public Integrator<FieldImplementation, SmearingPolicy,
RepresentationPolicy> {
public: public:
typedef LeapFrog<FieldImplementation, SmearingPolicy, RepresentationPolicy> typedef LeapFrog<FieldImplementation, SmearingPolicy, RepresentationPolicy> Algorithm;
Algorithm;
INHERIT_FIELD_TYPES(FieldImplementation); INHERIT_FIELD_TYPES(FieldImplementation);
std::string integrator_name(){return "LeapFrog";} std::string integrator_name(){return "LeapFrog";}
LeapFrog(GridBase* grid, IntegratorParameters Par, LeapFrog(GridBase* grid, IntegratorParameters Par, ActionSet<Field, RepresentationPolicy>& Aset, SmearingPolicy& Sm)
ActionSet<Field, RepresentationPolicy>& Aset, SmearingPolicy& Sm) : Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>(grid, Par, Aset, Sm){};
: Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>(
grid, Par, Aset, Sm){};
void step(Field& U, int level, int _first, int _last) { void step(Field& U, int level, int _first, int _last) {
int fl = this->as.size() - 1; int fl = this->as.size() - 1;
@ -140,21 +135,17 @@ public:
} }
}; };
template <class FieldImplementation, class SmearingPolicy, template <class FieldImplementation, class SmearingPolicy, class RepresentationPolicy = Representations<FundamentalRepresentation> >
class RepresentationPolicy = class MinimumNorm2 : public Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>
Representations<FundamentalRepresentation> > {
class MinimumNorm2 : public Integrator<FieldImplementation, SmearingPolicy,
RepresentationPolicy> {
private: private:
const RealD lambda = 0.1931833275037836; const RealD lambda = 0.1931833275037836;
public: public:
INHERIT_FIELD_TYPES(FieldImplementation); INHERIT_FIELD_TYPES(FieldImplementation);
MinimumNorm2(GridBase* grid, IntegratorParameters Par, MinimumNorm2(GridBase* grid, IntegratorParameters Par, ActionSet<Field, RepresentationPolicy>& Aset, SmearingPolicy& Sm)
ActionSet<Field, RepresentationPolicy>& Aset, SmearingPolicy& Sm) : Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>(grid, Par, Aset, Sm){};
: Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>(
grid, Par, Aset, Sm){};
std::string integrator_name(){return "MininumNorm2";} std::string integrator_name(){return "MininumNorm2";}
@ -201,14 +192,11 @@ public:
} }
}; };
template <class FieldImplementation, class SmearingPolicy, template <class FieldImplementation, class SmearingPolicy, class RepresentationPolicy = Representations<FundamentalRepresentation> >
class RepresentationPolicy = class ForceGradient : public Integrator<FieldImplementation, SmearingPolicy, RepresentationPolicy>
Representations<FundamentalRepresentation> > {
class ForceGradient : public Integrator<FieldImplementation, SmearingPolicy,
RepresentationPolicy> {
private: private:
const RealD lambda = 1.0 / 6.0; const RealD lambda = 1.0 / 6.0;
;
const RealD chi = 1.0 / 72.0; const RealD chi = 1.0 / 72.0;
const RealD xi = 0.0; const RealD xi = 0.0;
const RealD theta = 0.0; const RealD theta = 0.0;
@ -230,8 +218,7 @@ public:
Field Pfg(U.Grid()); Field Pfg(U.Grid());
Ufg = U; Ufg = U;
Pfg = Zero(); Pfg = Zero();
std::cout << GridLogIntegrator << "FG update " << fg_dt << " " << ep std::cout << GridLogIntegrator << "FG update " << fg_dt << " " << ep << std::endl;
<< std::endl;
// prepare_fg; no prediction/result cache for now // prepare_fg; no prediction/result cache for now
// could relax CG stopping conditions for the // could relax CG stopping conditions for the
// derivatives in the small step since the force gets multiplied by // derivatives in the small step since the force gets multiplied by
@ -270,8 +257,7 @@ public:
this->step(U, level + 1, first_step, 0); this->step(U, level + 1, first_step, 0);
} }
this->FG_update_P(U, level, 2 * Chi / ((1.0 - 2.0 * lambda) * eps), this->FG_update_P(U, level, 2 * Chi / ((1.0 - 2.0 * lambda) * eps), (1.0 - 2.0 * lambda) * eps);
(1.0 - 2.0 * lambda) * eps);
if (level == fl) { // lowest level if (level == fl) { // lowest level
this->update_U(U, 0.5 * eps); this->update_U(U, 0.5 * eps);

View File

@ -10,6 +10,24 @@ const std::array<const Gamma, 4> Gamma::gmu = {{
Gamma(Gamma::Algebra::GammaZ), Gamma(Gamma::Algebra::GammaZ),
Gamma(Gamma::Algebra::GammaT)}}; Gamma(Gamma::Algebra::GammaT)}};
const std::array<const Gamma, 16> Gamma::gall = {{
Gamma(Gamma::Algebra::Identity),
Gamma(Gamma::Algebra::Gamma5),
Gamma(Gamma::Algebra::GammaX),
Gamma(Gamma::Algebra::GammaY),
Gamma(Gamma::Algebra::GammaZ),
Gamma(Gamma::Algebra::GammaT),
Gamma(Gamma::Algebra::GammaXGamma5),
Gamma(Gamma::Algebra::GammaYGamma5),
Gamma(Gamma::Algebra::GammaZGamma5),
Gamma(Gamma::Algebra::GammaTGamma5),
Gamma(Gamma::Algebra::SigmaXT),
Gamma(Gamma::Algebra::SigmaXY),
Gamma(Gamma::Algebra::SigmaXZ),
Gamma(Gamma::Algebra::SigmaYT),
Gamma(Gamma::Algebra::SigmaYZ),
Gamma(Gamma::Algebra::SigmaZT)}};
const std::array<const char *, Gamma::nGamma> Gamma::name = {{ const std::array<const char *, Gamma::nGamma> Gamma::name = {{
"-Gamma5 ", "-Gamma5 ",
"Gamma5 ", "Gamma5 ",

View File

@ -47,6 +47,7 @@ class Gamma {
static const std::array<std::array<Algebra, nGamma>, nGamma> mul; static const std::array<std::array<Algebra, nGamma>, nGamma> mul;
static const std::array<Algebra, nGamma> adj; static const std::array<Algebra, nGamma> adj;
static const std::array<const Gamma, 4> gmu; static const std::array<const Gamma, 4> gmu;
static const std::array<const Gamma, 16> gall;
Algebra g; Algebra g;
public: public:
accelerator Gamma(Algebra initg): g(initg) {} accelerator Gamma(Algebra initg): g(initg) {}

View File

@ -10,10 +10,10 @@
NotebookFileLineBreakTest NotebookFileLineBreakTest
NotebookFileLineBreakTest NotebookFileLineBreakTest
NotebookDataPosition[ 158, 7] NotebookDataPosition[ 158, 7]
NotebookDataLength[ 75090, 1956] NotebookDataLength[ 67118, 1714]
NotebookOptionsPosition[ 69536, 1867] NotebookOptionsPosition[ 63485, 1652]
NotebookOutlinePosition[ 69898, 1883] NotebookOutlinePosition[ 63842, 1668]
CellTagsIndexPosition[ 69855, 1880] CellTagsIndexPosition[ 63799, 1665]
WindowFrame->Normal*) WindowFrame->Normal*)
(* Beginning of Notebook Content *) (* Beginning of Notebook Content *)
@ -76,234 +76,6 @@ Cell[BoxData["\<\"/Users/antonin/Development/Grid/lib/qcd/spin/gamma-gen\"\>"]\
Cell[CellGroupData[{ Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"FactorInteger", "[", "3152", "]"}]], "Input",
CellChangeTimes->{{3.7432347536316767`*^9, 3.7432347764739027`*^9}, {
3.743234833567358*^9,
3.743234862146022*^9}},ExpressionUUID->"d1a0fd03-85e1-43af-ba80-\
3ca4235675d8"],
Cell[BoxData[
RowBox[{"{",
RowBox[{
RowBox[{"{",
RowBox[{"2", ",", "4"}], "}"}], ",",
RowBox[{"{",
RowBox[{"197", ",", "1"}], "}"}]}], "}"}]], "Output",
CellChangeTimes->{{3.743234836792224*^9,
3.743234862493619*^9}},ExpressionUUID->"16d3f953-4b24-4ed2-ae62-\
306dcab66ca7"]
}, Open ]],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{"sol", "=",
RowBox[{"Solve", "[",
RowBox[{
RowBox[{
RowBox[{
SuperscriptBox["x", "2"], "+",
SuperscriptBox["y", "2"], "+",
SuperscriptBox["z", "2"]}], "\[Equal]", "2"}], ",",
RowBox[{"{",
RowBox[{"x", ",", "y", ",", "z"}], "}"}], ",", "Integers"}],
"]"}]}]], "Input",
CellChangeTimes->{{3.743235304127721*^9,
3.7432353087929983`*^9}},ExpressionUUID->"f0fa2a5c-3d81-4d75-a447-\
50c7ca3459ff"],
Cell[BoxData[
RowBox[{"{",
RowBox[{
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]",
RowBox[{"-", "1"}]}], ",",
RowBox[{"y", "\[Rule]",
RowBox[{"-", "1"}]}], ",",
RowBox[{"z", "\[Rule]", "0"}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]",
RowBox[{"-", "1"}]}], ",",
RowBox[{"y", "\[Rule]", "0"}], ",",
RowBox[{"z", "\[Rule]",
RowBox[{"-", "1"}]}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]",
RowBox[{"-", "1"}]}], ",",
RowBox[{"y", "\[Rule]", "0"}], ",",
RowBox[{"z", "\[Rule]", "1"}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]",
RowBox[{"-", "1"}]}], ",",
RowBox[{"y", "\[Rule]", "1"}], ",",
RowBox[{"z", "\[Rule]", "0"}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]", "0"}], ",",
RowBox[{"y", "\[Rule]",
RowBox[{"-", "1"}]}], ",",
RowBox[{"z", "\[Rule]",
RowBox[{"-", "1"}]}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]", "0"}], ",",
RowBox[{"y", "\[Rule]",
RowBox[{"-", "1"}]}], ",",
RowBox[{"z", "\[Rule]", "1"}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]", "0"}], ",",
RowBox[{"y", "\[Rule]", "1"}], ",",
RowBox[{"z", "\[Rule]",
RowBox[{"-", "1"}]}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]", "0"}], ",",
RowBox[{"y", "\[Rule]", "1"}], ",",
RowBox[{"z", "\[Rule]", "1"}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]", "1"}], ",",
RowBox[{"y", "\[Rule]",
RowBox[{"-", "1"}]}], ",",
RowBox[{"z", "\[Rule]", "0"}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]", "1"}], ",",
RowBox[{"y", "\[Rule]", "0"}], ",",
RowBox[{"z", "\[Rule]",
RowBox[{"-", "1"}]}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]", "1"}], ",",
RowBox[{"y", "\[Rule]", "0"}], ",",
RowBox[{"z", "\[Rule]", "1"}]}], "}"}], ",",
RowBox[{"{",
RowBox[{
RowBox[{"x", "\[Rule]", "1"}], ",",
RowBox[{"y", "\[Rule]", "1"}], ",",
RowBox[{"z", "\[Rule]", "0"}]}], "}"}]}], "}"}]], "Output",
CellChangeTimes->{{3.743235305220907*^9,
3.743235309139554*^9}},ExpressionUUID->"d9825c95-24bb-442a-8734-\
4c0f47e99dfc"]
}, Open ]],
Cell[BoxData[
RowBox[{
RowBox[{"xmlElem", "[", "x_", "]"}], ":=",
RowBox[{"Print", "[",
RowBox[{"\"\<<elem>\>\"", "<>",
RowBox[{"ToString", "[",
RowBox[{"x", "[",
RowBox[{"[", "1", "]"}], "]"}], "]"}], "<>", "\"\< \>\"", "<>",
RowBox[{"ToString", "[",
RowBox[{"x", "[",
RowBox[{"[", "2", "]"}], "]"}], "]"}], "<>", "\"\< \>\"", "<>",
RowBox[{"ToString", "[",
RowBox[{"x", "[",
RowBox[{"[", "3", "]"}], "]"}], "]"}], "<>", "\"\<</elem>\>\""}],
"]"}]}]], "Input",
CellChangeTimes->{{3.74323534002862*^9, 3.743235351000985*^9}, {
3.743235403233039*^9, 3.743235413488028*^9}, {3.743235473169856*^9,
3.7432354747126904`*^9}},ExpressionUUID->"aea76313-c89e-45e8-b429-\
3f454091666d"],
Cell[CellGroupData[{
Cell[BoxData[
RowBox[{
RowBox[{
RowBox[{"xmlElem", "[",
RowBox[{
RowBox[{"{",
RowBox[{"x", ",", "y", ",", "z"}], "}"}], "/.", "#"}], "]"}], "&"}], "/@",
"sol"}]], "Input",
CellChangeTimes->{{3.743235415820318*^9,
3.743235467025091*^9}},ExpressionUUID->"07da3998-8eab-40ba-8c0b-\
ac6b130cb4fb"],
Cell[CellGroupData[{
Cell[BoxData["\<\"<elem>-1 -1 0</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476581676*^9},ExpressionUUID->"c577ba06-b67a-405a-9ff5-\
2bf7dc898d03"],
Cell[BoxData["\<\"<elem>-1 0 -1</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476588011*^9},ExpressionUUID->"d041aa36-0cea-457c-9d4b-\
1fe9be66e2ab"],
Cell[BoxData["\<\"<elem>-1 0 1</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476596887*^9},ExpressionUUID->"bf141b55-86b2-4430-a994-\
5c03d5a19441"],
Cell[BoxData["\<\"<elem>-1 1 0</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476605785*^9},ExpressionUUID->"4968a660-4ecf-4b66-9071-\
8bd798c18d21"],
Cell[BoxData["\<\"<elem>0 -1 -1</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476613523*^9},ExpressionUUID->"4e22d943-2680-416b-a1d7-\
a16ca20b781f"],
Cell[BoxData["\<\"<elem>0 -1 1</elem>\"\>"], "Print",
CellChangeTimes->{
3.7432354766218576`*^9},ExpressionUUID->"6dd38385-08b3-4dd9-932f-\
98a00c6db1b2"],
Cell[BoxData["\<\"<elem>0 1 -1</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476629427*^9},ExpressionUUID->"ef3baad3-91d1-4735-9a22-\
53495a624c15"],
Cell[BoxData["\<\"<elem>0 1 1</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476638257*^9},ExpressionUUID->"413fbb68-5017-4272-a62a-\
fa234e6daaea"],
Cell[BoxData["\<\"<elem>1 -1 0</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476646203*^9},ExpressionUUID->"3a832a60-ae00-414b-a9ac-\
f5e86e67e917"],
Cell[BoxData["\<\"<elem>1 0 -1</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476653907*^9},ExpressionUUID->"bfc79ef6-f6c7-4f1e-88e8-\
005ac314be9c"],
Cell[BoxData["\<\"<elem>1 0 1</elem>\"\>"], "Print",
CellChangeTimes->{
3.743235476662575*^9},ExpressionUUID->"0f892891-f885-489c-9925-\
ddef4d698410"],
Cell[BoxData["\<\"<elem>1 1 0</elem>\"\>"], "Print",
CellChangeTimes->{
3.7432354766702337`*^9},ExpressionUUID->"2906f190-e673-4f33-9c34-\
e8e56efe7a27"]
}, Open ]],
Cell[BoxData[
RowBox[{"{",
RowBox[{
"Null", ",", "Null", ",", "Null", ",", "Null", ",", "Null", ",", "Null",
",", "Null", ",", "Null", ",", "Null", ",", "Null", ",", "Null", ",",
"Null"}], "}"}]], "Output",
CellChangeTimes->{
3.7432354246225967`*^9, {3.7432354674878073`*^9,
3.743235476678007*^9}},ExpressionUUID->"500ca3c1-88d8-46e5-a1a1-\
86a7878e5638"]
}, Open ]],
Cell[CellGroupData[{
Cell["Clifford algebra generation", "Section", Cell["Clifford algebra generation", "Section",
CellChangeTimes->{{3.6942089434583883`*^9, CellChangeTimes->{{3.6942089434583883`*^9,
3.694208978559093*^9}},ExpressionUUID->"a5b064b3-3011-4922-8559-\ 3.694208978559093*^9}},ExpressionUUID->"a5b064b3-3011-4922-8559-\
@ -1048,8 +820,9 @@ generated by the Mathematica notebook gamma-gen/gamma-gen.nb\n\n#include \
"\"\< static const std::array<const char *, nGamma> \ "\"\< static const std::array<const char *, nGamma> \
name;\n static const std::array<std::array<Algebra, nGamma>, nGamma> mul;\n\ name;\n static const std::array<std::array<Algebra, nGamma>, nGamma> mul;\n\
static const std::array<Algebra, nGamma> adj;\n \ static const std::array<Algebra, nGamma> adj;\n \
static const std::array<const Gamma, 4> gmu;\n \ static const std::array<const Gamma, 4> gmu;\n static \
Algebra g;\n public:\n \ const std::array<const Gamma, 16> gall;\n Algebra \
g;\n public:\n \
Gamma(Algebra initg): g(initg) {} \n};\n\n\>\""}]}], ";", Gamma(Algebra initg): g(initg) {} \n};\n\n\>\""}]}], ";",
"\[IndentingNewLine]", "\[IndentingNewLine]",
RowBox[{"out", " ", "=", RowBox[{"out", " ", "=",
@ -1076,7 +849,8 @@ Algebra g;\n public:\n \
3.694963343265525*^9}, {3.694964367519239*^9, 3.69496439461199*^9}, { 3.694963343265525*^9}, {3.694964367519239*^9, 3.69496439461199*^9}, {
3.694964462130747*^9, 3.6949644669959793`*^9}, 3.694964509762739*^9, { 3.694964462130747*^9, 3.6949644669959793`*^9}, 3.694964509762739*^9, {
3.694964705045744*^9, 3.694964723148797*^9}, {3.694964992988984*^9, 3.694964705045744*^9, 3.694964723148797*^9}, {3.694964992988984*^9,
3.6949649968504257`*^9}},ExpressionUUID->"c7103bd6-b539-4495-b98c-\ 3.6949649968504257`*^9}, {3.758291687176977*^9,
3.758291694181189*^9}},ExpressionUUID->"c7103bd6-b539-4495-b98c-\
d4d12ac6cad8"], d4d12ac6cad8"],
Cell["Gamma enum generation:", "Text", Cell["Gamma enum generation:", "Text",
@ -1745,8 +1519,17 @@ namespace QCD {\>\""}]}], ";", "\[IndentingNewLine]",
"\"\<\n\nconst std::array<const Gamma, 4> Gamma::gmu = {{\n \ "\"\<\n\nconst std::array<const Gamma, 4> Gamma::gmu = {{\n \
Gamma(Gamma::Algebra::GammaX),\n Gamma(Gamma::Algebra::GammaY),\n \ Gamma(Gamma::Algebra::GammaX),\n Gamma(Gamma::Algebra::GammaY),\n \
Gamma(Gamma::Algebra::GammaZ),\n Gamma(Gamma::Algebra::GammaT)}};\n\nconst \ Gamma(Gamma::Algebra::GammaZ),\n Gamma(Gamma::Algebra::GammaT)}};\n\nconst \
std::array<const char *, Gamma::nGamma> Gamma::name = {{\n\>\""}]}], ";", std::array<const Gamma, 16> Gamma::gall = {{\n \
"\[IndentingNewLine]", Gamma(Gamma::Algebra::Identity),\n Gamma(Gamma::Algebra::Gamma5),\n \
Gamma(Gamma::Algebra::GammaX),\n Gamma(Gamma::Algebra::GammaY),\n \
Gamma(Gamma::Algebra::GammaZ),\n Gamma(Gamma::Algebra::GammaT),\n \
Gamma(Gamma::Algebra::GammaXGamma5),\n Gamma(Gamma::Algebra::GammaYGamma5),\n\
Gamma(Gamma::Algebra::GammaZGamma5),\n \
Gamma(Gamma::Algebra::GammaTGamma5),\n Gamma(Gamma::Algebra::SigmaXT), \
\n Gamma(Gamma::Algebra::SigmaXY), \n Gamma(Gamma::Algebra::SigmaXZ), \
\n Gamma(Gamma::Algebra::SigmaYT),\n Gamma(Gamma::Algebra::SigmaYZ),\n \
Gamma(Gamma::Algebra::SigmaZT)}};\n\nconst std::array<const char *, \
Gamma::nGamma> Gamma::name = {{\n\>\""}]}], ";", "\[IndentingNewLine]",
RowBox[{"Do", "[", "\[IndentingNewLine]", RowBox[{"Do", "[", "\[IndentingNewLine]",
RowBox[{ RowBox[{
RowBox[{"out", " ", "=", " ", RowBox[{"out", " ", "=", " ",
@ -1847,7 +1630,9 @@ Gamma::nGamma> Gamma::mul = {{\\n\>\""}]}], ";", "\[IndentingNewLine]",
3.694963031525289*^9}, {3.694963065828494*^9, 3.694963098327538*^9}, { 3.694963031525289*^9}, {3.694963065828494*^9, 3.694963098327538*^9}, {
3.6949632020836153`*^9, 3.6949632715940027`*^9}, {3.694963440035037*^9, 3.6949632020836153`*^9, 3.6949632715940027`*^9}, {3.694963440035037*^9,
3.6949634418966017`*^9}, {3.6949651447067547`*^9, 3.694965161228381*^9}, { 3.6949634418966017`*^9}, {3.6949651447067547`*^9, 3.694965161228381*^9}, {
3.694967957845581*^9, 3.694967958364184*^9}}], 3.694967957845581*^9, 3.694967958364184*^9}, {3.758291673792514*^9,
3.758291676983432*^9}},ExpressionUUID->"b1b309f8-a3a7-4081-a781-\
c3845e3cd372"],
Cell[BoxData[ Cell[BoxData[
RowBox[{ RowBox[{
@ -1867,8 +1652,8 @@ Cell[BoxData[""], "Input",
}, },
WindowSize->{1246, 1005}, WindowSize->{1246, 1005},
WindowMargins->{{282, Automatic}, {Automatic, 14}}, WindowMargins->{{282, Automatic}, {Automatic, 14}},
FrontEndVersion->"11.2 for Mac OS X x86 (32-bit, 64-bit Kernel) (September \ FrontEndVersion->"11.3 for Mac OS X x86 (32-bit, 64-bit Kernel) (March 5, \
10, 2017)", 2018)",
StyleDefinitions->"Default.nb" StyleDefinitions->"Default.nb"
] ]
(* End of Notebook Content *) (* End of Notebook Content *)
@ -1888,75 +1673,48 @@ Cell[1948, 43, 570, 11, 73, "Input",ExpressionUUID->"5c937a3e-adfd-4d7e-8fde-afb
Cell[2521, 56, 1172, 17, 34, "Output",ExpressionUUID->"72817ba6-2f6a-4a4d-8212-6f0970f49e7c"] Cell[2521, 56, 1172, 17, 34, "Output",ExpressionUUID->"72817ba6-2f6a-4a4d-8212-6f0970f49e7c"]
}, Open ]], }, Open ]],
Cell[CellGroupData[{ Cell[CellGroupData[{
Cell[3730, 78, 248, 5, 30, "Input",ExpressionUUID->"d1a0fd03-85e1-43af-ba80-3ca4235675d8"], Cell[3730, 78, 174, 3, 67, "Section",ExpressionUUID->"a5b064b3-3011-4922-8559-ead857cad102"],
Cell[3981, 85, 299, 9, 34, "Output",ExpressionUUID->"16d3f953-4b24-4ed2-ae62-306dcab66ca7"] Cell[3907, 83, 535, 16, 52, "Input",ExpressionUUID->"aa28f02b-31e1-4df2-9b5d-482177464b59"],
Cell[4445, 101, 250, 4, 35, "Text",ExpressionUUID->"c8896b88-f1db-4ce4-b7a6-0c9838bdb8f1"],
Cell[4698, 107, 5511, 169, 425, "Input",ExpressionUUID->"52a96ff6-047e-4043-86d0-e303866e5f8e"],
Cell[CellGroupData[{
Cell[10234, 280, 2183, 58, 135, "Input",ExpressionUUID->"8b0f4955-2c3f-418c-9226-9be8f87621e8"],
Cell[12420, 340, 1027, 27, 56, "Output",ExpressionUUID->"edd0619f-6f12-4070-a1d2-6b547877fadc"]
}, Open ]], }, Open ]],
Cell[CellGroupData[{ Cell[CellGroupData[{
Cell[4317, 99, 469, 14, 33, "Input",ExpressionUUID->"f0fa2a5c-3d81-4d75-a447-50c7ca3459ff"], Cell[13484, 372, 1543, 46, 114, "Input",ExpressionUUID->"fb45123c-c610-4075-99b0-7cd71c728ae7"],
Cell[4789, 115, 2423, 77, 56, "Output",ExpressionUUID->"d9825c95-24bb-442a-8734-4c0f47e99dfc"] Cell[15030, 420, 1311, 32, 87, "Output",ExpressionUUID->"2ae14565-b412-4dc0-9dce-bd6c1ba5ef27"]
}, Open ]], }, Open ]],
Cell[7227, 195, 751, 18, 30, "Input",ExpressionUUID->"aea76313-c89e-45e8-b429-3f454091666d"], Cell[16356, 455, 179, 3, 35, "Text",ExpressionUUID->"af247231-a58d-417b-987a-26908dafffdb"],
Cell[16538, 460, 2175, 65, 94, "Input",ExpressionUUID->"7c44cadd-e488-4f51-87d8-c64eef11f40c"],
Cell[18716, 527, 193, 3, 35, "Text",ExpressionUUID->"856f1746-1107-4509-a5ce-ac9c7f56cdb1"],
Cell[CellGroupData[{ Cell[CellGroupData[{
Cell[8003, 217, 323, 10, 30, "Input",ExpressionUUID->"07da3998-8eab-40ba-8c0b-ac6b130cb4fb"], Cell[18934, 534, 536, 16, 30, "Input",ExpressionUUID->"8674484a-8543-434f-b177-3b27f9353212"],
Cell[CellGroupData[{ Cell[19473, 552, 1705, 35, 87, "Output",ExpressionUUID->"c3b3f84d-91f6-41af-af6b-a394ca020511"]
Cell[8351, 231, 156, 3, 24, "Print",ExpressionUUID->"c577ba06-b67a-405a-9ff5-2bf7dc898d03"],
Cell[8510, 236, 156, 3, 24, "Print",ExpressionUUID->"d041aa36-0cea-457c-9d4b-1fe9be66e2ab"],
Cell[8669, 241, 155, 3, 24, "Print",ExpressionUUID->"bf141b55-86b2-4430-a994-5c03d5a19441"],
Cell[8827, 246, 155, 3, 24, "Print",ExpressionUUID->"4968a660-4ecf-4b66-9071-8bd798c18d21"],
Cell[8985, 251, 156, 3, 24, "Print",ExpressionUUID->"4e22d943-2680-416b-a1d7-a16ca20b781f"],
Cell[9144, 256, 157, 3, 24, "Print",ExpressionUUID->"6dd38385-08b3-4dd9-932f-98a00c6db1b2"],
Cell[9304, 261, 155, 3, 24, "Print",ExpressionUUID->"ef3baad3-91d1-4735-9a22-53495a624c15"],
Cell[9462, 266, 154, 3, 24, "Print",ExpressionUUID->"413fbb68-5017-4272-a62a-fa234e6daaea"],
Cell[9619, 271, 155, 3, 24, "Print",ExpressionUUID->"3a832a60-ae00-414b-a9ac-f5e86e67e917"],
Cell[9777, 276, 155, 3, 24, "Print",ExpressionUUID->"bfc79ef6-f6c7-4f1e-88e8-005ac314be9c"],
Cell[9935, 281, 154, 3, 24, "Print",ExpressionUUID->"0f892891-f885-489c-9925-ddef4d698410"],
Cell[10092, 286, 156, 3, 24, "Print",ExpressionUUID->"2906f190-e673-4f33-9c34-e8e56efe7a27"]
}, Open ]],
Cell[10263, 292, 376, 9, 34, "Output",ExpressionUUID->"500ca3c1-88d8-46e5-a1a1-86a7878e5638"]
}, Open ]], }, Open ]],
Cell[21193, 590, 170, 3, 35, "Text",ExpressionUUID->"518a3040-54b1-4d43-8947-5c7d12efa94d"],
Cell[CellGroupData[{ Cell[CellGroupData[{
Cell[10676, 306, 174, 3, 67, "Section",ExpressionUUID->"a5b064b3-3011-4922-8559-ead857cad102"], Cell[21388, 597, 536, 14, 30, "Input",ExpressionUUID->"61a2e974-2b39-4a07-8043-2dfd39a70569"],
Cell[10853, 311, 535, 16, 52, "Input",ExpressionUUID->"aa28f02b-31e1-4df2-9b5d-482177464b59"], Cell[21927, 613, 6754, 167, 303, "Output",ExpressionUUID->"73480ac0-3043-4077-80cc-b952a94c822a"]
Cell[11391, 329, 250, 4, 35, "Text",ExpressionUUID->"c8896b88-f1db-4ce4-b7a6-0c9838bdb8f1"],
Cell[11644, 335, 5511, 169, 425, "Input",ExpressionUUID->"52a96ff6-047e-4043-86d0-e303866e5f8e"],
Cell[CellGroupData[{
Cell[17180, 508, 2183, 58, 135, "Input",ExpressionUUID->"8b0f4955-2c3f-418c-9226-9be8f87621e8"],
Cell[19366, 568, 1027, 27, 67, "Output",ExpressionUUID->"edd0619f-6f12-4070-a1d2-6b547877fadc"]
}, Open ]],
Cell[CellGroupData[{
Cell[20430, 600, 1543, 46, 114, "Input",ExpressionUUID->"fb45123c-c610-4075-99b0-7cd71c728ae7"],
Cell[21976, 648, 1311, 32, 98, "Output",ExpressionUUID->"2ae14565-b412-4dc0-9dce-bd6c1ba5ef27"]
}, Open ]],
Cell[23302, 683, 179, 3, 35, "Text",ExpressionUUID->"af247231-a58d-417b-987a-26908dafffdb"],
Cell[23484, 688, 2175, 65, 94, "Input",ExpressionUUID->"7c44cadd-e488-4f51-87d8-c64eef11f40c"],
Cell[25662, 755, 193, 3, 35, "Text",ExpressionUUID->"856f1746-1107-4509-a5ce-ac9c7f56cdb1"],
Cell[CellGroupData[{
Cell[25880, 762, 536, 16, 30, "Input",ExpressionUUID->"8674484a-8543-434f-b177-3b27f9353212"],
Cell[26419, 780, 1705, 35, 87, "Output",ExpressionUUID->"c3b3f84d-91f6-41af-af6b-a394ca020511"]
}, Open ]],
Cell[28139, 818, 170, 3, 35, "Text",ExpressionUUID->"518a3040-54b1-4d43-8947-5c7d12efa94d"],
Cell[CellGroupData[{
Cell[28334, 825, 536, 14, 30, "Input",ExpressionUUID->"61a2e974-2b39-4a07-8043-2dfd39a70569"],
Cell[28873, 841, 6754, 167, 303, "Output",ExpressionUUID->"73480ac0-3043-4077-80cc-b952a94c822a"]
}, Open ]] }, Open ]]
}, Open ]], }, Open ]],
Cell[CellGroupData[{ Cell[CellGroupData[{
Cell[35676, 1014, 226, 4, 67, "Section",ExpressionUUID->"4e833cd6-9f0e-4aa3-a873-3d579e874720"], Cell[28730, 786, 226, 4, 67, "Section",ExpressionUUID->"4e833cd6-9f0e-4aa3-a873-3d579e874720"],
Cell[35905, 1020, 188, 4, 44, "Text",ExpressionUUID->"6d27fc04-3a60-4e03-8df7-3dd3aeee35b4"], Cell[28959, 792, 188, 4, 44, "Text",ExpressionUUID->"6d27fc04-3a60-4e03-8df7-3dd3aeee35b4"],
Cell[36096, 1026, 2980, 53, 703, "Input",ExpressionUUID->"c7103bd6-b539-4495-b98c-d4d12ac6cad8"], Cell[29150, 798, 3104, 55, 724, "Input",ExpressionUUID->"c7103bd6-b539-4495-b98c-d4d12ac6cad8"],
Cell[39079, 1081, 221, 4, 44, "Text",ExpressionUUID->"0625593d-290f-4a39-9d80-8e2c6fdbc94e"], Cell[32257, 855, 221, 4, 44, "Text",ExpressionUUID->"0625593d-290f-4a39-9d80-8e2c6fdbc94e"],
Cell[39303, 1087, 4936, 150, 682, "Input",ExpressionUUID->"1ad4904c-352f-4b1d-a7c7-91e1b0549409"], Cell[32481, 861, 4936, 150, 682, "Input",ExpressionUUID->"1ad4904c-352f-4b1d-a7c7-91e1b0549409"],
Cell[44242, 1239, 2645, 56, 199, "Input",ExpressionUUID->"0221674f-9b63-4662-91bc-ccc8c6ae9589"], Cell[37420, 1013, 2645, 56, 199, "Input",ExpressionUUID->"0221674f-9b63-4662-91bc-ccc8c6ae9589"],
Cell[46890, 1297, 209, 4, 44, "Text",ExpressionUUID->"d2d2257a-487b-416f-bc40-abd4482225f7"], Cell[40068, 1071, 209, 4, 44, "Text",ExpressionUUID->"d2d2257a-487b-416f-bc40-abd4482225f7"],
Cell[47102, 1303, 15306, 397, 2131, "Input",ExpressionUUID->"daea68a9-c9e8-46ab-9bc8-5186e2cf477c"], Cell[40280, 1077, 15306, 397, 2131, "Input",ExpressionUUID->"daea68a9-c9e8-46ab-9bc8-5186e2cf477c"],
Cell[62411, 1702, 137, 2, 44, "Text",ExpressionUUID->"76ba9d5a-7ee3-4888-be7e-6377003275e8"], Cell[55589, 1476, 137, 2, 44, "Text",ExpressionUUID->"76ba9d5a-7ee3-4888-be7e-6377003275e8"],
Cell[62551, 1706, 521, 12, 30, "Input",ExpressionUUID->"4ec61f4c-3fd3-49ea-b5ef-6f7f04a16b34"] Cell[55729, 1480, 521, 12, 30, "Input",ExpressionUUID->"4ec61f4c-3fd3-49ea-b5ef-6f7f04a16b34"]
}, Open ]], }, Open ]],
Cell[CellGroupData[{ Cell[CellGroupData[{
Cell[63109, 1723, 167, 2, 67, "Section",ExpressionUUID->"a4458b3a-09b5-4e36-a1fc-781d6702b2dc"], Cell[56287, 1497, 167, 2, 67, "Section",ExpressionUUID->"a4458b3a-09b5-4e36-a1fc-781d6702b2dc"],
Cell[63279, 1727, 5693, 122, 829, "Input",ExpressionUUID->"b1b309f8-a3a7-4081-a781-c3845e3cd372"], Cell[56457, 1501, 6464, 133, 1207, "Input",ExpressionUUID->"b1b309f8-a3a7-4081-a781-c3845e3cd372"],
Cell[68975, 1851, 448, 10, 30, "Input",ExpressionUUID->"cba42949-b0f2-42ce-aebd-ffadfd83ef88"], Cell[62924, 1636, 448, 10, 30, "Input",ExpressionUUID->"cba42949-b0f2-42ce-aebd-ffadfd83ef88"],
Cell[69426, 1863, 94, 1, 30, "Input",ExpressionUUID->"6175b72c-af9f-43c2-b4ca-bd84c48a456d"] Cell[63375, 1648, 94, 1, 30, "Input",ExpressionUUID->"6175b72c-af9f-43c2-b4ca-bd84c48a456d"]
}, Open ]] }, Open ]]
} }
] ]

View File

@ -995,21 +995,20 @@ void A2Autils<FImpl>::ContractWWVV(std::vector<PropagatorField> &WWVV,
auto vs_v = vs[s].View(); auto vs_v = vs[s].View();
auto tmp1 = vs_v[ss]; auto tmp1 = vs_v[ss];
vobj tmp2 = Zero(); vobj tmp2 = Zero();
vobj tmp3 = Zero();
for(int d=d_o;d<MIN(d_o+d_unroll,N_d);d++){ for(int d=d_o;d<MIN(d_o+d_unroll,N_d);d++){
Scalar_v coeff = WW_sd(t,s,d);
auto vd_v = vd[d].View(); auto vd_v = vd[d].View();
mac(&tmp2 ,& coeff, & vd_v[ss]); Scalar_v coeff = WW_sd(t,s,d);
tmp3 = conjugate(vd_v[ss]);
mac(&tmp2, &coeff, &tmp3);
} }
////////////////////////// //////////////////////////
// Fast outer product of tmp1 with a sum of terms suppressed by d_unroll // Fast outer product of tmp1 with a sum of terms suppressed by d_unroll
////////////////////////// //////////////////////////
tmp2 = conjugate(tmp2);
auto WWVV_v = WWVV[t].View(); auto WWVV_v = WWVV[t].View();
for(int s1=0;s1<Ns;s1++){ for(int s1=0;s1<Ns;s1++){
for(int s2=0;s2<Ns;s2++){ for(int s2=0;s2<Ns;s2++){
WWVV_v[ss]()(s1,s2)(0,0) += tmp1()(s1)(0)*tmp2()(s2)(0); WWVV_v[ss]()(s1,s2)(0,0) += tmp1()(s1)(0)*tmp2()(s2)(0);
WWVV_v[ss]()(s1,s2)(0,1) += tmp1()(s1)(0)*tmp2()(s2)(1); WWVV_v[ss]()(s1,s2)(0,1) += tmp1()(s1)(0)*tmp2()(s2)(1);
WWVV_v[ss]()(s1,s2)(0,2) += tmp1()(s1)(0)*tmp2()(s2)(2); WWVV_v[ss]()(s1,s2)(0,2) += tmp1()(s1)(0)*tmp2()(s2)(2);

View File

@ -0,0 +1,87 @@
/*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid
Source file: ./lib/qcd/action/scalar/CovariantLaplacian.h
Copyright (C) 2016
Author: Azusa Yamaguchi
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
*************************************************************************************/
#pragma once
namespace Grid {
namespace QCD {
template <class Gimpl> class CovariantSmearing : public Gimpl
{
public:
INHERIT_GIMPL_TYPES(Gimpl);
typedef typename Gimpl::GaugeLinkField GaugeMat;
typedef typename Gimpl::GaugeField GaugeLorentz;
template<typename T>
static void GaussianSmear(const std::vector<LatticeColourMatrix>& U,
T& chi,
const Real& width, int Iterations, int orthog)
{
GridBase *grid = chi._grid;
T psi(grid);
////////////////////////////////////////////////////////////////////////////////////
// Follow Chroma conventions for width to keep compatibility with previous data
// Free field iterates
// chi = (1 - w^2/4N p^2)^N chi
//
// ~ (e^(-w^2/4N p^2)^N chi
// ~ (e^(-w^2/4 p^2) chi
// ~ (e^(-w'^2/2 p^2) chi [ w' = w/sqrt(2) ]
//
// Which in coordinate space is proportional to
//
// e^(-x^2/w^2) = e^(-x^2/2w'^2)
//
// The 4 is a bit unconventional from Gaussian width perspective, but... it's Chroma convention.
// 2nd derivative approx d^2/dx^2 = x+mu + x-mu - 2x
//
// d^2/dx^2 = - p^2
//
// chi = ( 1 + w^2/4N d^2/dx^2 )^N chi
//
////////////////////////////////////////////////////////////////////////////////////
Real coeff = (width*width) / Real(4*Iterations);
int dims = Nd;
if( orthog < Nd ) dims=Nd-1;
for(int n = 0; n < Iterations; ++n) {
psi = (-2.0*dims)*chi;
for(int mu=0;mu<Nd;mu++) {
if ( mu != orthog ) {
psi = psi + Gimpl::CovShiftForward(U[mu],mu,chi);
psi = psi + Gimpl::CovShiftBackward(U[mu],mu,chi);
}
}
chi = chi + coeff*psi;
}
}
};
}}

View File

@ -31,6 +31,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
NAMESPACE_BEGIN(Grid); NAMESPACE_BEGIN(Grid);
template <class Gimpl> template <class Gimpl>
class FourierAcceleratedGaugeFixer : public Gimpl { class FourierAcceleratedGaugeFixer : public Gimpl {
public: public:
@ -45,13 +46,22 @@ public:
A[mu] = Ta(U[mu]) * cmi; A[mu] = Ta(U[mu]) * cmi;
} }
} }
static void DmuAmu(const std::vector<GaugeMat> &A,GaugeMat &dmuAmu) { static void DmuAmu(const std::vector<GaugeMat> &A,GaugeMat &dmuAmu,int orthog) {
dmuAmu=Zero(); dmuAmu=Zero();
for(int mu=0;mu<Nd;mu++){ for(int mu=0;mu<Nd;mu++){
if ( mu != orthog ) {
dmuAmu = dmuAmu + A[mu] - Cshift(A[mu],mu,-1); dmuAmu = dmuAmu + A[mu] - Cshift(A[mu],mu,-1);
} }
} }
static void SteepestDescentGaugeFix(GaugeLorentz &Umu,Real & alpha,int maxiter,Real Omega_tol, Real Phi_tol,bool Fourier=false) { }
static void SteepestDescentGaugeFix(GaugeLorentz &Umu,Real & alpha,int maxiter,Real Omega_tol, Real Phi_tol,bool Fourier=false,int orthog=-1) {
GridBase *grid = Umu.Grid();
GaugeMat xform(grid);
SteepestDescentGaugeFix(Umu,xform,alpha,maxiter,Omega_tol,Phi_tol,Fourier,orthog);
}
static void SteepestDescentGaugeFix(GaugeLorentz &Umu,GaugeMat &xform,Real & alpha,int maxiter,Real Omega_tol, Real Phi_tol,bool Fourier=false,int orthog=-1) {
GridBase *grid = Umu.Grid(); GridBase *grid = Umu.Grid();
Real org_plaq =WilsonLoops<Gimpl>::avgPlaquette(Umu); Real org_plaq =WilsonLoops<Gimpl>::avgPlaquette(Umu);
@ -59,16 +69,34 @@ public:
Real old_trace = org_link_trace; Real old_trace = org_link_trace;
Real trG; Real trG;
xform=1.0;
std::vector<GaugeMat> U(Nd,grid); std::vector<GaugeMat> U(Nd,grid);
GaugeMat dmuAmu(grid); GaugeMat dmuAmu(grid);
for(int i=0;i<maxiter;i++){ {
for(int mu=0;mu<Nd;mu++) U[mu]= PeekIndex<LorentzIndex>(Umu,mu); Real plaq =WilsonLoops<Gimpl>::avgPlaquette(Umu);
if ( Fourier==false ) { Real link_trace=WilsonLoops<Gimpl>::linkTrace(Umu);
trG = SteepestDescentStep(U,alpha,dmuAmu); if( (orthog>=0) && (orthog<Nd) ){
std::cout << GridLogMessage << " Gauge fixing to Coulomb gauge time="<<orthog<< " plaq= "<<plaq<<" link trace = "<<link_trace<< std::endl;
} else { } else {
trG = FourierAccelSteepestDescentStep(U,alpha,dmuAmu); std::cout << GridLogMessage << " Gauge fixing to Landau gauge plaq= "<<plaq<<" link trace = "<<link_trace<< std::endl;
} }
}
for(int i=0;i<maxiter;i++){
for(int mu=0;mu<Nd;mu++) U[mu]= PeekIndex<LorentzIndex>(Umu,mu);
if ( Fourier==false ) {
trG = SteepestDescentStep(U,xform,alpha,dmuAmu,orthog);
} else {
trG = FourierAccelSteepestDescentStep(U,xform,alpha,dmuAmu,orthog);
}
// std::cout << GridLogMessage << "trG "<< trG<< std::endl;
// std::cout << GridLogMessage << "xform "<< norm2(xform)<< std::endl;
// std::cout << GridLogMessage << "dmuAmu "<< norm2(dmuAmu)<< std::endl;
for(int mu=0;mu<Nd;mu++) PokeIndex<LorentzIndex>(Umu,U[mu],mu); for(int mu=0;mu<Nd;mu++) PokeIndex<LorentzIndex>(Umu,U[mu],mu);
// Monitor progress and convergence test // Monitor progress and convergence test
// infrequently to minimise cost overhead // infrequently to minimise cost overhead
@ -84,7 +112,6 @@ public:
Real Phi = 1.0 - old_trace / link_trace ; Real Phi = 1.0 - old_trace / link_trace ;
Real Omega= 1.0 - trG; Real Omega= 1.0 - trG;
std::cout << GridLogMessage << " Iteration "<<i<< " Phi= "<<Phi<< " Omega= " << Omega<< " trG " << trG <<std::endl; std::cout << GridLogMessage << " Iteration "<<i<< " Phi= "<<Phi<< " Omega= " << Omega<< " trG " << trG <<std::endl;
if ( (Omega < Omega_tol) && ( ::fabs(Phi) < Phi_tol) ) { if ( (Omega < Omega_tol) && ( ::fabs(Phi) < Phi_tol) ) {
std::cout << GridLogMessage << "Converged ! "<<std::endl; std::cout << GridLogMessage << "Converged ! "<<std::endl;
@ -96,25 +123,26 @@ public:
} }
} }
}; };
static Real SteepestDescentStep(std::vector<GaugeMat> &U,Real & alpha, GaugeMat & dmuAmu) { static Real SteepestDescentStep(std::vector<GaugeMat> &U,GaugeMat &xform,Real & alpha, GaugeMat & dmuAmu,int orthog) {
GridBase *grid = U[0].Grid(); GridBase *grid = U[0].Grid();
std::vector<GaugeMat> A(Nd,grid); std::vector<GaugeMat> A(Nd,grid);
GaugeMat g(grid); GaugeMat g(grid);
GaugeLinkToLieAlgebraField(U,A); GaugeLinkToLieAlgebraField(U,A);
ExpiAlphaDmuAmu(A,g,alpha,dmuAmu); ExpiAlphaDmuAmu(A,g,alpha,dmuAmu,orthog);
Real vol = grid->gSites(); Real vol = grid->gSites();
Real trG = TensorRemove(sum(trace(g))).real()/vol/Nc; Real trG = TensorRemove(sum(trace(g))).real()/vol/Nc;
xform = g*xform ;
SU<Nc>::GaugeTransform(U,g); SU<Nc>::GaugeTransform(U,g);
return trG; return trG;
} }
static Real FourierAccelSteepestDescentStep(std::vector<GaugeMat> &U,Real & alpha, GaugeMat & dmuAmu) { static Real FourierAccelSteepestDescentStep(std::vector<GaugeMat> &U,GaugeMat &xform,Real & alpha, GaugeMat & dmuAmu,int orthog) {
GridBase *grid = U[0].Grid(); GridBase *grid = U[0].Grid();
@ -133,38 +161,41 @@ public:
GaugeLinkToLieAlgebraField(U,A); GaugeLinkToLieAlgebraField(U,A);
DmuAmu(A,dmuAmu); DmuAmu(A,dmuAmu,orthog);
theFFT.FFT_all_dim(dmuAmu_p,dmuAmu,FFT::forward); std::vector<int> mask(Nd,1);
for(int mu=0;mu<Nd;mu++) if (mu==orthog) mask[mu]=0;
theFFT.FFT_dim_mask(dmuAmu_p,dmuAmu,mask,FFT::forward);
////////////////////////////////// //////////////////////////////////
// Work out Fp = psq_max/ psq... // Work out Fp = psq_max/ psq...
// Avoid singularities in Fp
////////////////////////////////// //////////////////////////////////
Coordinate latt_size = grid->GlobalDimensions(); Coordinate latt_size = grid->GlobalDimensions();
Coordinate coor(grid->_ndimension,0); Coordinate coor(grid->_ndimension,0);
for(int mu=0;mu<Nd;mu++) { for(int mu=0;mu<Nd;mu++) {
if ( mu != orthog ) {
Real TwoPiL = M_PI * 2.0/ latt_size[mu]; Real TwoPiL = M_PI * 2.0/ latt_size[mu];
LatticeCoordinate(pmu,mu); LatticeCoordinate(pmu,mu);
pmu = TwoPiL * pmu ; pmu = TwoPiL * pmu ;
psq = psq + 4.0*sin(pmu*0.5)*sin(pmu*0.5); psq = psq + 4.0*sin(pmu*0.5)*sin(pmu*0.5);
} }
}
Complex psqMax(16.0); Complex psqMax(16.0);
Fp = psqMax*one/psq; Fp = psqMax*one/psq;
/* pokeSite(TComplex(16.0),Fp,coor);
static int once; if( (orthog>=0) && (orthog<Nd) ){
if ( once == 0 ) { for(int t=0;t<grid->GlobalDimensions()[orthog];t++){
std::cout << " Fp " << Fp <<std::endl; coor[orthog]=t;
once ++; pokeSite(TComplex(16.0),Fp,coor);
}*/ }
}
pokeSite(TComplex(1.0),Fp,coor);
dmuAmu_p = dmuAmu_p * Fp; dmuAmu_p = dmuAmu_p * Fp;
theFFT.FFT_all_dim(dmuAmu,dmuAmu_p,FFT::backward); theFFT.FFT_dim_mask(dmuAmu,dmuAmu_p,mask,FFT::backward);
GaugeMat ciadmam(grid); GaugeMat ciadmam(grid);
Complex cialpha(0.0,-alpha); Complex cialpha(0.0,-alpha);
@ -173,16 +204,17 @@ public:
Real trG = TensorRemove(sum(trace(g))).real()/vol/Nc; Real trG = TensorRemove(sum(trace(g))).real()/vol/Nc;
xform = g*xform ;
SU<Nc>::GaugeTransform(U,g); SU<Nc>::GaugeTransform(U,g);
return trG; return trG;
} }
static void ExpiAlphaDmuAmu(const std::vector<GaugeMat> &A,GaugeMat &g,Real & alpha, GaugeMat &dmuAmu) { static void ExpiAlphaDmuAmu(const std::vector<GaugeMat> &A,GaugeMat &g,Real & alpha, GaugeMat &dmuAmu,int orthog) {
GridBase *grid = g.Grid(); GridBase *grid = g.Grid();
Complex cialpha(0.0,-alpha); Complex cialpha(0.0,-alpha);
GaugeMat ciadmam(grid); GaugeMat ciadmam(grid);
DmuAmu(A,dmuAmu); DmuAmu(A,dmuAmu,orthog);
ciadmam = dmuAmu*cialpha; ciadmam = dmuAmu*cialpha;
SU<Nc>::taExp(ciadmam,g); SU<Nc>::taExp(ciadmam,g);
} }

View File

@ -679,7 +679,16 @@ public:
} }
} }
/* /*
add GaugeTrans * Fundamental rep gauge xform
*/
template<typename Fundamental,typename GaugeMat>
static void GaugeTransformFundamental( Fundamental &ferm, GaugeMat &g){
GridBase *grid = ferm._grid;
conformable(grid,g._grid);
ferm = g*ferm;
}
/*
* Adjoint rep gauge xform
*/ */
template<typename GaugeField,typename GaugeMat> template<typename GaugeField,typename GaugeMat>

View File

@ -33,8 +33,72 @@ Author: Guido Cossu <guido.cossu@ed.ac.uk>
#include <type_traits> #include <type_traits>
#include <Grid/tensors/Tensors.h> #include <Grid/tensors/Tensors.h>
#include <Grid/serialisation/VectorUtils.h> #include <Grid/serialisation/VectorUtils.h>
#include <Grid/Eigen/unsupported/CXX11/Tensor>
namespace Grid { namespace Grid {
namespace EigenIO {
// EigenIO works for scalars that are not just Grid supported scalars
template<typename T, typename V = void> struct is_complex : public std::false_type {};
// Support all complex types (not just Grid complex types) - even if the definitions overlap (!)
template<typename T> struct is_complex< T , typename
std::enable_if< ::Grid::is_complex< T >::value>::type> : public std::true_type {};
template<typename T> struct is_complex<std::complex<T>, typename
std::enable_if<!::Grid::is_complex<std::complex<T>>::value>::type> : public std::true_type {};
// Helpers to support I/O for Eigen tensors of arithmetic scalars, complex types, or Grid tensors
template<typename T, typename V = void> struct is_scalar : public std::false_type {};
template<typename T> struct is_scalar<T, typename std::enable_if<std::is_arithmetic<T>::value || is_complex<T>::value>::type> : public std::true_type {};
// Is this an Eigen tensor
template<typename T> struct is_tensor : std::integral_constant<bool,
std::is_base_of<Eigen::TensorBase<T, Eigen::ReadOnlyAccessors>, T>::value> {};
// Is this an Eigen tensor of a supported scalar
template<typename T, typename V = void> struct is_tensor_of_scalar : public std::false_type {};
template<typename T> struct is_tensor_of_scalar<T, typename std::enable_if<is_tensor<T>::value && is_scalar<typename T::Scalar>::value>::type> : public std::true_type {};
// Is this an Eigen tensor of a supported container
template<typename T, typename V = void> struct is_tensor_of_container : public std::false_type {};
template<typename T> struct is_tensor_of_container<T, typename std::enable_if<is_tensor<T>::value && isGridTensor<typename T::Scalar>::value>::type> : public std::true_type {};
// These traits describe the scalars inside Eigen tensors
// I wish I could define these in reference to the scalar type (so there would be fewer traits defined)
// but I'm unable to find a syntax to make this work
template<typename T, typename V = void> struct Traits {};
// Traits are the default for scalars, or come from GridTypeMapper for GridTensors
template<typename T> struct Traits<T, typename std::enable_if<is_tensor_of_scalar<T>::value>::type>
: public GridTypeMapper_Base {
using scalar_type = typename T::Scalar; // ultimate base scalar
static constexpr bool is_complex = ::Grid::EigenIO::is_complex<scalar_type>::value;
};
// Traits are the default for scalars, or come from GridTypeMapper for GridTensors
template<typename T> struct Traits<T, typename std::enable_if<is_tensor_of_container<T>::value>::type> {
using BaseTraits = GridTypeMapper<typename T::Scalar>;
using scalar_type = typename BaseTraits::scalar_type; // ultimate base scalar
static constexpr bool is_complex = ::Grid::EigenIO::is_complex<scalar_type>::value;
static constexpr int TensorLevel = BaseTraits::TensorLevel;
static constexpr int Rank = BaseTraits::Rank;
static constexpr std::size_t count = BaseTraits::count;
static constexpr int Dimension(int dim) { return BaseTraits::Dimension(dim); }
};
// Is this a fixed-size Eigen tensor
template<typename T> struct is_tensor_fixed : public std::false_type {};
template<typename Scalar_, typename Dimensions_, int Options_, typename IndexType>
struct is_tensor_fixed<Eigen::TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType>>
: public std::true_type {};
template<typename Scalar_, typename Dimensions_, int Options_, typename IndexType,
int MapOptions_, template <class> class MapPointer_>
struct is_tensor_fixed<Eigen::TensorMap<Eigen::TensorFixedSize<Scalar_, Dimensions_,
Options_, IndexType>, MapOptions_, MapPointer_>>
: public std::true_type {};
// Is this a variable-size Eigen tensor
template<typename T, typename V = void> struct is_tensor_variable : public std::false_type {};
template<typename T> struct is_tensor_variable<T, typename std::enable_if<is_tensor<T>::value
&& !is_tensor_fixed<T>::value>::type> : public std::true_type {};
}
// Abstract writer/reader classes //////////////////////////////////////////// // Abstract writer/reader classes ////////////////////////////////////////////
// static polymorphism implemented using CRTP idiom // static polymorphism implemented using CRTP idiom
class Serializable; class Serializable;
@ -49,10 +113,10 @@ namespace Grid {
void push(const std::string &s); void push(const std::string &s);
void pop(void); void pop(void);
template <typename U> template <typename U>
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type typename std::enable_if<std::is_base_of<Serializable, U>::value>::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_base_of<Serializable, U>::value, void>::type typename std::enable_if<!std::is_base_of<Serializable, U>::value && !EigenIO::is_tensor<U>::value>::type
write(const std::string& s, const U &output); write(const std::string& s, const U &output);
template <typename U> template <typename U>
void write(const std::string &s, const iScalar<U> &output); void write(const std::string &s, const iScalar<U> &output);
@ -60,6 +124,42 @@ namespace Grid {
void write(const std::string &s, const iVector<U, N> &output); void write(const std::string &s, const iVector<U, N> &output);
template <typename U, int N> template <typename U, int N>
void write(const std::string &s, const iMatrix<U, N> &output); void write(const std::string &s, const iMatrix<U, N> &output);
template <typename ETensor>
typename std::enable_if<EigenIO::is_tensor<ETensor>::value>::type
write(const std::string &s, const ETensor &output);
// Helper functions for Scalar vs Container specialisations
template <typename ETensor>
inline typename std::enable_if<EigenIO::is_tensor_of_scalar<ETensor>::value,
const typename ETensor::Scalar *>::type
getFirstScalar(const ETensor &output)
{
return output.data();
}
template <typename ETensor>
inline typename std::enable_if<EigenIO::is_tensor_of_container<ETensor>::value,
const typename EigenIO::Traits<ETensor>::scalar_type *>::type
getFirstScalar(const ETensor &output)
{
return output.data()->begin();
}
template <typename S>
inline typename std::enable_if<EigenIO::is_scalar<S>::value, void>::type
copyScalars(S * &pCopy, const S &Source)
{
* pCopy ++ = Source;
}
template <typename S>
inline typename std::enable_if<isGridTensor<S>::value, void>::type
copyScalars(typename GridTypeMapper<S>::scalar_type * &pCopy, const S &Source)
{
for( const typename GridTypeMapper<S>::scalar_type &item : Source )
* pCopy ++ = item;
}
void scientificFormat(const bool set); void scientificFormat(const bool set);
bool isScientific(void); bool isScientific(void);
void setPrecision(const unsigned int prec); void setPrecision(const unsigned int prec);
@ -83,7 +183,8 @@ 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_base_of<Serializable, U>::value, void>::type typename std::enable_if<!std::is_base_of<Serializable, U>::value
&& !EigenIO::is_tensor<U>::value, void>::type
read(const std::string& s, U &output); read(const std::string& s, U &output);
template <typename U> template <typename U>
void read(const std::string &s, iScalar<U> &output); void read(const std::string &s, iScalar<U> &output);
@ -91,6 +192,32 @@ namespace Grid {
void read(const std::string &s, iVector<U, N> &output); void read(const std::string &s, iVector<U, N> &output);
template <typename U, int N> template <typename U, int N>
void read(const std::string &s, iMatrix<U, N> &output); void read(const std::string &s, iMatrix<U, N> &output);
template <typename ETensor>
typename std::enable_if<EigenIO::is_tensor<ETensor>::value, void>::type
read(const std::string &s, ETensor &output);
template <typename ETensor>
typename std::enable_if<EigenIO::is_tensor_fixed<ETensor>::value, void>::type
Reshape(ETensor &t, const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims );
template <typename ETensor>
typename std::enable_if<EigenIO::is_tensor_variable<ETensor>::value, void>::type
Reshape(ETensor &t, const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims );
// Helper functions for Scalar vs Container specialisations
template <typename S>
inline typename std::enable_if<EigenIO::is_scalar<S>::value, void>::type
copyScalars(S &Dest, const S * &pSource)
{
Dest = * pSource ++;
}
template <typename S>
inline typename std::enable_if<isGridTensor<S>::value, void>::type
copyScalars(S &Dest, const typename GridTypeMapper<S>::scalar_type * &pSource)
{
for( typename GridTypeMapper<S>::scalar_type &item : Dest )
item = * pSource ++;
}
protected: protected:
template <typename U> template <typename U>
void fromString(U &output, const std::string &s); void fromString(U &output, const std::string &s);
@ -135,12 +262,14 @@ namespace Grid {
template <typename T> template <typename T>
template <typename U> template <typename U>
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type typename std::enable_if<!std::is_base_of<Serializable, U>::value
&& !EigenIO::is_tensor<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);
} }
template <typename T> template <typename T>
template <typename U> template <typename U>
void Writer<T>::write(const std::string &s, const iScalar<U> &output) void Writer<T>::write(const std::string &s, const iScalar<U> &output)
@ -162,6 +291,57 @@ namespace Grid {
upcast->writeDefault(s, tensorToVec(output)); upcast->writeDefault(s, tensorToVec(output));
} }
// Eigen::Tensors of Grid tensors (iScalar, iVector, iMatrix)
template <typename T>
template <typename ETensor>
typename std::enable_if<EigenIO::is_tensor<ETensor>::value, void>::type
Writer<T>::write(const std::string &s, const ETensor &output)
{
using Index = typename ETensor::Index;
using Container = typename ETensor::Scalar; // NB: could be same as scalar
using Traits = EigenIO::Traits<ETensor>;
using Scalar = typename Traits::scalar_type; // type of the underlying scalar
constexpr unsigned int TensorRank{ETensor::NumIndices};
constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers
constexpr unsigned int TotalRank{TensorRank + ContainerRank};
const Index NumElements{output.size()};
assert( NumElements > 0 );
// Get the dimensionality of the tensor
std::vector<std::size_t> TotalDims(TotalRank);
for(auto i = 0; i < TensorRank; i++ ) {
auto dim = output.dimension(i);
TotalDims[i] = static_cast<size_t>(dim);
assert( TotalDims[i] == dim ); // check we didn't lose anything in the conversion
}
for(auto i = 0; i < ContainerRank; i++ )
TotalDims[TensorRank + i] = Traits::Dimension(i);
// If the Tensor isn't in Row-Major order, then we'll need to copy it's data
const bool CopyData{NumElements > 1 && ETensor::Layout != Eigen::StorageOptions::RowMajor};
const Scalar * pWriteBuffer;
std::vector<Scalar> CopyBuffer;
const Index TotalNumElements = NumElements * Traits::count;
if( !CopyData ) {
pWriteBuffer = getFirstScalar( output );
} else {
// Regardless of the Eigen::Tensor storage order, the copy will be Row Major
CopyBuffer.resize( TotalNumElements );
Scalar * pCopy = &CopyBuffer[0];
pWriteBuffer = pCopy;
std::array<Index, TensorRank> MyIndex;
for( auto &idx : MyIndex ) idx = 0;
for( auto n = 0; n < NumElements; n++ ) {
const Container & c = output( MyIndex );
copyScalars( pCopy, c );
// Now increment the index
for( int i = output.NumDimensions - 1; i >= 0 && ++MyIndex[i] == output.dimension(i); i-- )
MyIndex[i] = 0;
}
}
upcast->template writeMultiDim<Scalar>(s, TotalDims, pWriteBuffer, TotalNumElements);
}
template <typename T> template <typename T>
void Writer<T>::scientificFormat(const bool set) void Writer<T>::scientificFormat(const bool set)
{ {
@ -215,7 +395,8 @@ namespace Grid {
template <typename T> template <typename T>
template <typename U> template <typename U>
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type typename std::enable_if<!std::is_base_of<Serializable, U>::value
&& !EigenIO::is_tensor<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);
@ -251,6 +432,79 @@ namespace Grid {
vecToTensor(output, v); vecToTensor(output, v);
} }
template <typename T>
template <typename ETensor>
typename std::enable_if<EigenIO::is_tensor<ETensor>::value, void>::type
Reader<T>::read(const std::string &s, ETensor &output)
{
using Index = typename ETensor::Index;
using Container = typename ETensor::Scalar; // NB: could be same as scalar
using Traits = EigenIO::Traits<ETensor>;
using Scalar = typename Traits::scalar_type; // type of the underlying scalar
constexpr unsigned int TensorRank{ETensor::NumIndices};
constexpr unsigned int ContainerRank{Traits::Rank}; // Only non-zero for containers
constexpr unsigned int TotalRank{TensorRank + ContainerRank};
using ETDims = std::array<Index, TensorRank>; // Dimensions of the tensor
// read the (flat) data and dimensionality
std::vector<std::size_t> dimData;
std::vector<Scalar> buf;
upcast->readMultiDim( s, buf, dimData );
assert(dimData.size() == TotalRank && "EigenIO: Tensor rank mismatch" );
// Make sure that the number of elements read matches dimensions read
std::size_t NumContainers = 1;
for( auto i = 0 ; i < TensorRank ; i++ )
NumContainers *= dimData[i];
// If our scalar object is a Container, make sure it's dimensions match what we read back
std::size_t ElementsPerContainer = 1;
for( auto i = 0 ; i < ContainerRank ; i++ ) {
assert( dimData[TensorRank+i] == Traits::Dimension(i) && "Tensor Container dimensions don't match data" );
ElementsPerContainer *= dimData[TensorRank+i];
}
assert( NumContainers * ElementsPerContainer == buf.size() && "EigenIO: Number of elements != product of dimensions" );
// Now see whether the tensor is the right shape, or can be made to be
const auto & dims = output.dimensions();
bool bShapeOK = (output.data() != nullptr);
for( auto i = 0; bShapeOK && i < TensorRank ; i++ )
if( dims[i] != dimData[i] )
bShapeOK = false;
// Make the tensor the same size as the data read
ETDims MyIndex;
if( !bShapeOK ) {
for( auto i = 0 ; i < TensorRank ; i++ )
MyIndex[i] = dimData[i];
Reshape(output, MyIndex);
}
// Copy the data into the tensor
for( auto &d : MyIndex ) d = 0;
const Scalar * pSource = &buf[0];
for( std::size_t n = 0 ; n < NumContainers ; n++ ) {
Container & c = output( MyIndex );
copyScalars( c, pSource );
// Now increment the index
for( int i = TensorRank - 1; i != -1 && ++MyIndex[i] == dims[i]; i-- )
MyIndex[i] = 0;
}
assert( pSource == &buf[NumContainers * ElementsPerContainer] );
}
template <typename T>
template <typename ETensor>
typename std::enable_if<EigenIO::is_tensor_fixed<ETensor>::value, void>::type
Reader<T>::Reshape(ETensor &t, const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims )
{
assert( 0 && "EigenIO: Fixed tensor dimensions can't be changed" );
}
template <typename T>
template <typename ETensor>
typename std::enable_if<EigenIO::is_tensor_variable<ETensor>::value, void>::type
Reader<T>::Reshape(ETensor &t, const std::array<typename ETensor::Index, ETensor::NumDimensions> &dims )
{
//t.reshape( dims );
t.resize( dims );
}
template <typename T> template <typename T>
template <typename U> template <typename U>
void Reader<T>::fromString(U &output, const std::string &s) void Reader<T>::fromString(U &output, const std::string &s)
@ -289,6 +543,68 @@ namespace Grid {
{ {
return os; return os;
} }
template <typename T1, typename T2>
static inline typename std::enable_if<!EigenIO::is_tensor<T1>::value || !EigenIO::is_tensor<T2>::value, bool>::type
CompareMember(const T1 &lhs, const T2 &rhs) {
return lhs == rhs;
}
template <typename T1, typename T2>
static inline typename std::enable_if<EigenIO::is_tensor<T1>::value && EigenIO::is_tensor<T2>::value, bool>::type
CompareMember(const T1 &lhs, const T2 &rhs) {
// First check whether dimensions match (Eigen tensor library will assert if they don't match)
bool bReturnValue = (T1::NumIndices == T2::NumIndices);
for( auto i = 0 ; bReturnValue && i < T1::NumIndices ; i++ )
bReturnValue = ( lhs.dimension(i) == rhs.dimension(i) );
if( bReturnValue ) {
Eigen::Tensor<bool, 0, T1::Options> bResult = (lhs == rhs).all();
bReturnValue = bResult(0);
}
return bReturnValue;
}
template <typename T>
static inline typename std::enable_if<EigenIO::is_tensor<T>::value, bool>::type
CompareMember(const std::vector<T> &lhs, const std::vector<T> &rhs) {
const auto NumElements = lhs.size();
bool bResult = ( NumElements == rhs.size() );
for( auto i = 0 ; i < NumElements && bResult ; i++ )
bResult = CompareMember(lhs[i], rhs[i]);
return bResult;
}
template <typename T>
static inline typename std::enable_if<!EigenIO::is_tensor<T>::value, void>::type
WriteMember(std::ostream &os, const T &object) {
os << object;
}
template <typename T>
static inline typename std::enable_if<EigenIO::is_tensor<T>::value, void>::type
WriteMember(std::ostream &os, const T &object) {
using Index = typename T::Index;
const Index NumElements{object.size()};
assert( NumElements > 0 );
Index count = 1;
os << "T<";
for( int i = 0; i < T::NumIndices; i++ ) {
Index dim = object.dimension(i);
count *= dim;
if( i )
os << ",";
os << dim;
}
assert( count == NumElements && "Number of elements doesn't match tensor dimensions" );
os << ">{";
const typename T::Scalar * p = object.data();
for( Index i = 0; i < count; i++ ) {
if( i )
os << ",";
os << *p++;
}
os << "}";
}
}; };
// Generic writer interface ////////////////////////////////////////////////// // Generic writer interface //////////////////////////////////////////////////

View File

@ -37,7 +37,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
#include <vector> #include <vector>
#include <cassert> #include <cassert>
NAMESPACE_BEGIN(Grid); namespace Grid {
class BinaryWriter: public Writer<BinaryWriter> class BinaryWriter: public Writer<BinaryWriter>
{ {
@ -51,6 +51,8 @@ public:
template <typename U> template <typename U>
void writeDefault(const std::string &s, const std::vector<U> &x); void writeDefault(const std::string &s, const std::vector<U> &x);
void writeDefault(const std::string &s, const char *x); void writeDefault(const std::string &s, const char *x);
template <typename U>
void writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements);
private: private:
std::ofstream file_; std::ofstream file_;
}; };
@ -66,6 +68,8 @@ public:
void readDefault(const std::string &s, U &output); void readDefault(const std::string &s, U &output);
template <typename U> template <typename U>
void readDefault(const std::string &s, std::vector<U> &output); void readDefault(const std::string &s, std::vector<U> &output);
template <typename U>
void readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim);
private: private:
std::ifstream file_; std::ifstream file_;
}; };
@ -92,15 +96,37 @@ void BinaryWriter::writeDefault(const std::string &s, const std::vector<U> &x)
} }
} }
// Reader template implementation //////////////////////////////////////////// template <typename U>
template <> void BinaryReader::readDefault(const std::string &s, std::string &output); void BinaryWriter::writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements)
{
uint64_t rank = static_cast<uint64_t>( Dimensions.size() );
uint64_t tmp = 1;
for( auto i = 0 ; i < rank ; i++ )
tmp *= Dimensions[i];
assert( tmp == NumElements && "Dimensions don't match size of data being written" );
// Total number of elements
write("", tmp);
// Number of dimensions
write("", rank);
// Followed by each dimension
for( auto i = 0 ; i < rank ; i++ ) {
tmp = Dimensions[i];
write("", tmp);
}
for( auto i = 0; i < NumElements; ++i)
write("", pDataRowMajor[i]);
}
// Reader template implementation ////////////////////////////////////////////
template <typename U> template <typename U>
void BinaryReader::readDefault(const std::string &s, U &output) void BinaryReader::readDefault(const std::string &s, U &output)
{ {
file_.read((char *)&output, sizeof(U)); file_.read((char *)&output, sizeof(U));
} }
template <>
void BinaryReader::readDefault(const std::string &s, std::string &output);
template <typename U> template <typename U>
void BinaryReader::readDefault(const std::string &s, std::vector<U> &output) void BinaryReader::readDefault(const std::string &s, std::vector<U> &output)
{ {
@ -114,6 +140,29 @@ void BinaryReader::readDefault(const std::string &s, std::vector<U> &output)
} }
} }
NAMESPACE_END(Grid); template <typename U>
void BinaryReader::readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim)
{
// Number of elements
uint64_t NumElements;
read("", NumElements);
// Number of dimensions
uint64_t rank;
read("", rank);
// Followed by each dimension
uint64_t count = 1;
dim.resize(rank);
uint64_t tmp;
for( auto i = 0 ; i < rank ; i++ ) {
read("", tmp);
dim[i] = tmp;
count *= tmp;
}
assert( count == NumElements && "Dimensions don't match size of data being read" );
buf.resize(count);
for( auto i = 0; i < count; ++i)
read("", buf[i]);
}
}
#endif #endif

View File

@ -3,6 +3,7 @@
#include <stack> #include <stack>
#include <string> #include <string>
#include <list>
#include <vector> #include <vector>
#include <H5Cpp.h> #include <H5Cpp.h>
#include <Grid/tensors/Tensors.h> #include <Grid/tensors/Tensors.h>
@ -38,6 +39,8 @@ namespace Grid
template <typename U> template <typename U>
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
writeDefault(const std::string &s, const std::vector<U> &x); writeDefault(const std::string &s, const std::vector<U> &x);
template <typename U>
void writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements);
H5NS::Group & getGroup(void); H5NS::Group & getGroup(void);
private: private:
template <typename U> template <typename U>
@ -48,7 +51,7 @@ namespace Grid
std::vector<std::string> path_; std::vector<std::string> path_;
H5NS::H5File file_; H5NS::H5File file_;
H5NS::Group group_; H5NS::Group group_;
unsigned int dataSetThres_{HDF5_DEF_DATASET_THRES}; const unsigned int dataSetThres_{HDF5_DEF_DATASET_THRES};
}; };
class Hdf5Reader: public Reader<Hdf5Reader> class Hdf5Reader: public Reader<Hdf5Reader>
@ -66,6 +69,8 @@ namespace Grid
template <typename U> template <typename U>
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
readDefault(const std::string &s, std::vector<U> &x); readDefault(const std::string &s, std::vector<U> &x);
template <typename U>
void readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim);
H5NS::Group & getGroup(void); H5NS::Group & getGroup(void);
private: private:
template <typename U> template <typename U>
@ -101,6 +106,75 @@ namespace Grid
template <> template <>
void Hdf5Writer::writeDefault(const std::string &s, const std::string &x); void Hdf5Writer::writeDefault(const std::string &s, const std::string &x);
template <typename U>
void Hdf5Writer::writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements)
{
// Hdf5 needs the dimensions as hsize_t
const int rank = static_cast<int>(Dimensions.size());
std::vector<hsize_t> dim(rank);
for(int i = 0; i < rank; i++)
dim[i] = Dimensions[i];
// write the entire dataset to file
H5NS::DataSpace dataSpace(rank, dim.data());
if (NumElements > dataSetThres_)
{
// Make sure 1) each dimension; and 2) chunk size is < 4GB
const hsize_t MaxElements = ( sizeof( U ) == 1 ) ? 0xffffffff : 0x100000000 / sizeof( U );
hsize_t ElementsPerChunk = 1;
bool bTooBig = false;
for( int i = rank - 1 ; i != -1 ; i-- ) {
auto &d = dim[i];
if( bTooBig )
d = 1; // Chunk size is already as big as can be - remaining dimensions = 1
else {
// If individual dimension too big, reduce by prime factors if possible
while( d > MaxElements && ( d & 1 ) == 0 )
d >>= 1;
const char ErrorMsg[] = " dimension > 4GB and not divisible by 2^n. "
"Hdf5IO chunk size will be inefficient. NB Serialisation is not intended for large datasets - please consider alternatives.";
if( d > MaxElements ) {
std::cout << GridLogWarning << "Individual" << ErrorMsg << std::endl;
hsize_t quotient = d / MaxElements;
if( d % MaxElements )
quotient++;
d /= quotient;
}
// Now make sure overall size is not too big
hsize_t OverflowCheck = ElementsPerChunk;
ElementsPerChunk *= d;
assert( OverflowCheck == ElementsPerChunk / d && "Product of dimensions overflowed hsize_t" );
// If product of dimensions too big, reduce by prime factors
while( ElementsPerChunk > MaxElements && ( ElementsPerChunk & 1 ) == 0 ) {
bTooBig = true;
d >>= 1;
ElementsPerChunk >>= 1;
}
if( ElementsPerChunk > MaxElements ) {
std::cout << GridLogWarning << "Product of" << ErrorMsg << std::endl;
hsize_t quotient = ElementsPerChunk / MaxElements;
if( ElementsPerChunk % MaxElements )
quotient++;
d /= quotient;
ElementsPerChunk /= quotient;
}
}
}
H5NS::DataSet dataSet;
H5NS::DSetCreatPropList plist;
plist.setChunk(rank, dim.data());
plist.setFletcher32();
dataSet = group_.createDataSet(s, Hdf5Type<U>::type(), dataSpace, plist);
dataSet.write(pDataRowMajor, Hdf5Type<U>::type());
}
else
{
H5NS::Attribute attribute;
attribute = group_.createAttribute(s, Hdf5Type<U>::type(), dataSpace);
attribute.write(Hdf5Type<U>::type(), pDataRowMajor);
}
}
template <typename U> template <typename U>
typename std::enable_if<element<std::vector<U>>::is_number, void>::type typename std::enable_if<element<std::vector<U>>::is_number, void>::type
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x) Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
@ -110,34 +184,11 @@ namespace Grid
// flatten the vector and getting dimensions // flatten the vector and getting dimensions
Flatten<std::vector<U>> flat(x); Flatten<std::vector<U>> flat(x);
std::vector<hsize_t> dim; std::vector<size_t> dim;
const auto &flatx = flat.getFlatVector(); const auto &flatx = flat.getFlatVector();
for (auto &d: flat.getDim()) for (auto &d: flat.getDim())
{
dim.push_back(d); dim.push_back(d);
} writeMultiDim<Element>(s, dim, &flatx[0], flatx.size());
// write to file
H5NS::DataSpace dataSpace(dim.size(), dim.data());
if (flatx.size() > dataSetThres_)
{
H5NS::DataSet dataSet;
H5NS::DSetCreatPropList plist;
plist.setChunk(dim.size(), dim.data());
plist.setFletcher32();
dataSet = group_.createDataSet(s, Hdf5Type<Element>::type(), dataSpace, plist);
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> template <typename U>
@ -175,8 +226,7 @@ namespace Grid
void Hdf5Reader::readDefault(const std::string &s, std::string &x); void Hdf5Reader::readDefault(const std::string &s, std::string &x);
template <typename U> template <typename U>
typename std::enable_if<element<std::vector<U>>::is_number, void>::type void Hdf5Reader::readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim)
Hdf5Reader::readDefault(const std::string &s, std::vector<U> &x)
{ {
// alias to element type // alias to element type
typedef typename element<std::vector<U>>::type Element; typedef typename element<std::vector<U>>::type Element;
@ -184,7 +234,6 @@ namespace Grid
// read the dimensions // read the dimensions
H5NS::DataSpace dataSpace; H5NS::DataSpace dataSpace;
std::vector<hsize_t> hdim; std::vector<hsize_t> hdim;
std::vector<size_t> dim;
hsize_t size = 1; hsize_t size = 1;
if (group_.attrExists(s)) if (group_.attrExists(s))
@ -204,7 +253,7 @@ namespace Grid
} }
// read the flat vector // read the flat vector
std::vector<Element> buf(size); buf.resize(size);
if (size > dataSetThres_) if (size > dataSetThres_)
{ {
@ -220,6 +269,18 @@ namespace Grid
attribute = group_.openAttribute(s); attribute = group_.openAttribute(s);
attribute.read(Hdf5Type<Element>::type(), buf.data()); attribute.read(Hdf5Type<Element>::type(), buf.data());
} }
}
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;
std::vector<size_t> dim;
std::vector<Element> buf;
readMultiDim( s, buf, dim );
// reconstruct the multidimensional vector // reconstruct the multidimensional vector
Reconstruct<std::vector<U>> r(buf, dim); Reconstruct<std::vector<U>> r(buf, dim);

View File

@ -107,8 +107,9 @@ 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_COMP_MEMBER(A,B) result = (result and CompareMember(lhs. B, rhs. B));
#define GRID_MACRO_OS_WRITE_MEMBER(A,B) os<< #A <<" " #B << " = "; WriteMember( os, obj. B ); os << " ; " <<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);

View File

@ -51,6 +51,8 @@ namespace Grid
void writeDefault(const std::string &s, const U &x); void writeDefault(const std::string &s, const U &x);
template <typename U> template <typename U>
void writeDefault(const std::string &s, const std::vector<U> &x); void writeDefault(const std::string &s, const std::vector<U> &x);
template <typename U>
void writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements);
private: private:
void indent(void); void indent(void);
private: private:
@ -69,6 +71,8 @@ namespace Grid
void readDefault(const std::string &s, U &output); void readDefault(const std::string &s, U &output);
template <typename U> template <typename U>
void readDefault(const std::string &s, std::vector<U> &output); void readDefault(const std::string &s, std::vector<U> &output);
template <typename U>
void readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim);
private: private:
void checkIndent(void); void checkIndent(void);
private: private:
@ -96,6 +100,17 @@ namespace Grid
} }
} }
template <typename U>
void TextWriter::writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements)
{
uint64_t Rank = Dimensions.size();
write(s, Rank);
for( uint64_t d : Dimensions )
write(s, d);
while( NumElements-- )
write(s, *pDataRowMajor++);
}
// Reader template implementation //////////////////////////////////////////// // Reader template implementation ////////////////////////////////////////////
template <> template <>
void TextReader::readDefault(const std::string &s, std::string &output); void TextReader::readDefault(const std::string &s, std::string &output);
@ -122,7 +137,22 @@ namespace Grid
} }
} }
template <typename U>
void TextReader::readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim)
{
const char sz[] = "";
uint64_t Rank;
read(sz, Rank);
dim.resize( Rank );
size_t NumElements = 1;
for( auto &d : dim ) {
read(sz, d);
NumElements *= d;
}
buf.resize( NumElements );
for( auto &x : buf )
read(s, x);
}
} }

View File

@ -1,3 +1,32 @@
/*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid
Source file: ./Grid/serialisation/VectorUtils.h
Copyright (C) 2015
Author: Antonin Portelli <antonin.portelli@me.com>
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
Author: paboyle <paboyle@ph.ed.ac.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory
*************************************************************************************/
/* END LEGAL */
#ifndef GRID_SERIALISATION_VECTORUTILS_H #ifndef GRID_SERIALISATION_VECTORUTILS_H
#define GRID_SERIALISATION_VECTORUTILS_H #define GRID_SERIALISATION_VECTORUTILS_H
@ -53,6 +82,17 @@ namespace Grid {
return os; return os;
} }
// std::vector<std:vector<...>> nested to specified Rank //////////////////////////////////
template<typename T, unsigned int Rank>
struct NestedStdVector {
typedef typename std::vector<typename NestedStdVector<T, Rank - 1>::type> type;
};
template<typename T>
struct NestedStdVector<T,0> {
typedef T type;
};
// Grid scalar tensors to nested std::vectors ////////////////////////////////// // Grid scalar tensors to nested std::vectors //////////////////////////////////
template <typename T> template <typename T>
struct TensorToVec struct TensorToVec

View File

@ -57,6 +57,8 @@ namespace Grid
void writeDefault(const std::string &s, const U &x); void writeDefault(const std::string &s, const U &x);
template <typename U> template <typename U>
void writeDefault(const std::string &s, const std::vector<U> &x); void writeDefault(const std::string &s, const std::vector<U> &x);
template <typename U>
void writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements);
std::string docString(void); std::string docString(void);
std::string string(void); std::string string(void);
private: private:
@ -78,6 +80,8 @@ namespace Grid
template <typename U> template <typename U>
void readDefault(const std::string &s, U &output); void readDefault(const std::string &s, U &output);
template <typename U> void readDefault(const std::string &s, std::vector<U> &output); template <typename U> void readDefault(const std::string &s, std::vector<U> &output);
template <typename U>
void readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim);
void readCurrentSubtree(std::string &s); void readCurrentSubtree(std::string &s);
private: private:
@ -122,9 +126,41 @@ namespace Grid
void XmlWriter::writeDefault(const std::string &s, const std::vector<U> &x) void XmlWriter::writeDefault(const std::string &s, const std::vector<U> &x)
{ {
push(s); push(s);
for (auto &x_i: x) for( auto &u : x )
{ {
write("elem", x_i); write("elem", u);
}
pop();
}
template <typename U>
void XmlWriter::writeMultiDim(const std::string &s, const std::vector<size_t> & Dimensions, const U * pDataRowMajor, size_t NumElements)
{
push(s);
size_t count = 1;
const int Rank = static_cast<int>( Dimensions.size() );
write("rank", Rank );
std::vector<size_t> MyIndex( Rank );
for( auto d : Dimensions ) {
write("dim", d);
count *= d;
}
assert( count == NumElements && "XmlIO : element count doesn't match dimensions" );
static const char sName[] = "tensor";
for( int i = 0 ; i < Rank ; i++ ) {
MyIndex[i] = 0;
push(sName);
}
while (NumElements--) {
write("elem", *pDataRowMajor++);
int i;
for( i = Rank - 1 ; i != -1 && ++MyIndex[i] == Dimensions[i] ; i-- )
MyIndex[i] = 0;
int Rollover = Rank - 1 - i;
for( i = 0 ; i < Rollover ; i++ )
pop();
for( i = 0 ; NumElements && i < Rollover ; i++ )
push(sName);
} }
pop(); pop();
} }
@ -143,25 +179,66 @@ namespace Grid
template <typename U> template <typename U>
void XmlReader::readDefault(const std::string &s, std::vector<U> &output) void XmlReader::readDefault(const std::string &s, std::vector<U> &output)
{ {
std::string buf;
unsigned int i = 0;
if (!push(s)) if (!push(s))
{ {
std::cout << GridLogWarning << "XML: cannot open node '" << s << "'"; std::cout << GridLogWarning << "XML: cannot open node '" << s << "'";
std::cout << std::endl; std::cout << std::endl;
} else {
return; for(unsigned int i = 0; node_.child("elem"); )
}
while (node_.child("elem"))
{ {
output.resize(i + 1); output.resize(i + 1);
read("elem", output[i]); read("elem", output[i++]);
node_.child("elem").set_name("elem-done"); node_.child("elem").set_name("elem-done");
i++;
} }
pop(); pop();
} }
}
template <typename U>
void XmlReader::readMultiDim(const std::string &s, std::vector<U> &buf, std::vector<size_t> &dim)
{
if (!push(s))
{
std::cout << GridLogWarning << "XML: cannot open node '" << s << "'";
std::cout << std::endl;
} else {
static const char sName[] = "tensor";
static const char sNameDone[] = "tensor-done";
int Rank;
read("rank", Rank);
dim.resize( Rank );
size_t NumElements = 1;
for( auto &d : dim )
{
read("dim", d);
node_.child("dim").set_name("dim-done");
NumElements *= d;
}
buf.resize( NumElements );
std::vector<size_t> MyIndex( Rank );
for( int i = 0 ; i < Rank ; i++ ) {
MyIndex[i] = 0;
push(sName);
}
for( auto &x : buf )
{
NumElements--;
read("elem", x);
node_.child("elem").set_name("elem-done");
int i;
for( i = Rank - 1 ; i != -1 && ++MyIndex[i] == dim[i] ; i-- )
MyIndex[i] = 0;
int Rollover = Rank - 1 - i;
for( i = 0 ; i < Rollover ; i++ ) {
node_.set_name(sNameDone);
pop();
}
for( i = 0 ; NumElements && i < Rollover ; i++ )
push(sName);
}
pop();
}
}
} }
#endif #endif

View File

@ -1,652 +0,0 @@
/*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid
Source file: ./lib/simd/Grid_gpu.h
Copyright (C) 2018
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory
*************************************************************************************/
/* END LEGAL */
//----------------------------------------------------------------------
/*! @file Grid_gpu.h
@brief Optimization libraries for GPU
Use float4, double2
*/
//----------------------------------------------------------------------
#include <cuda_fp16.h>
namespace Grid {
// re im, re, im, re, im etc..
struct half8 {
half ax, ay, az, aw, bx, by, bz, bw;
};
accelerator_inline float half2float(half h)
{
float f;
#ifdef __CUDA_ARCH__
f = __half2float(h);
#else
//f = __half2float(h);
__half_raw hr(h);
Grid_half hh;
hh.x = hr.x;
f= sfw_half_to_float(hh);
#endif
return f;
}
accelerator_inline half float2half(float f)
{
half h;
#ifdef __CUDA_ARCH__
h = __float2half(f);
#else
Grid_half hh = sfw_float_to_half(f);
__half_raw hr;
hr.x = hh.x;
h = __half(hr);
#endif
return h;
}
namespace Optimization {
inline accelerator float4 operator*(float4 a,float4 b) {return make_float4(a.x*b.x,a.y*b.y,a.z*b.z,a.w*b.w);}
inline accelerator float4 operator+(float4 a,float4 b) {return make_float4(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w);}
inline accelerator float4 operator-(float4 a,float4 b) {return make_float4(a.x-b.x,a.y-b.y,a.z-b.z,a.w-b.w);}
inline accelerator float4 operator/(float4 a,float4 b) {return make_float4(a.x/b.x,a.y/b.y,a.z/b.z,a.w/b.w);}
inline accelerator double2 operator*(double2 a,double2 b) {return make_double2(a.x*b.x,a.y*b.y);}
inline accelerator double2 operator+(double2 a,double2 b) {return make_double2(a.x+b.x,a.y+b.y);}
inline accelerator double2 operator-(double2 a,double2 b) {return make_double2(a.x-b.x,a.y-b.y);}
inline accelerator double2 operator/(double2 a,double2 b) {return make_double2(a.x/b.x,a.y/b.y);}
inline accelerator int4 operator*(int4 a,int4 b) {return make_int4(a.x*b.x,a.y*b.y,a.z*b.z,a.w*b.w);}
inline accelerator int4 operator+(int4 a,int4 b) {return make_int4(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w);}
inline accelerator int4 operator-(int4 a,int4 b) {return make_int4(a.x-b.x,a.y-b.y,a.z-b.z,a.w-b.w);}
inline accelerator int4 operator/(int4 a,int4 b) {return make_int4(a.x/b.x,a.y/b.y,a.z/b.z,a.w/b.w);}
struct Vsplat{
//Complex float
accelerator_inline float4 operator()(float a, float b){
float4 ret;
ret.x=ret.z=a;
ret.y=ret.w=b;
return ret;
}
// Real float
accelerator_inline float4 operator()(float a){
float4 ret;
ret.x=ret.y=ret.z=ret.w = a;
return ret;
}
//Complex double
accelerator_inline double2 operator()(double a, double b){
double2 ret;
ret.x=a;
ret.y=b;
return ret;
}
//Real double
accelerator_inline double2 operator()(double a){
double2 ret;
ret.x = ret.y = a;
return ret;
}
//Integer
accelerator_inline int4 operator()(Integer a){
int4 ret;
ret.x=ret.y=ret.z=ret.w=a;
return ret;
}
};
struct Vstore{
//Float
accelerator_inline void operator()(float4 a, float* F){
float4 *F4 = (float4 *)F;
*F4 = a;
}
//Double
accelerator_inline void operator()(double2 a, double* D){
double2 *D2 = (double2 *)D;
*D2 = a;
}
//Integer
accelerator_inline void operator()(int4 a, Integer* I){
int4 *I4 = (int4 *)I;
*I4 = a;
}
};
struct Vstream{
//Float
accelerator_inline void operator()(float * a, float4 b){
float4 * a4 = (float4 *)a;
*a4 = b;
}
//Double
accelerator_inline void operator()(double * a, double2 b){
double2 * a2 = (double2 *)a;
*a2 = b;
}
};
struct Vset{
// Complex float
accelerator_inline float4 operator()(Grid::ComplexF *a){
float4 ret;
ret.x = a[0].real();
ret.y = a[0].imag();
ret.z = a[1].real();
ret.w = a[1].imag();
return ret;
}
// Complex double
accelerator_inline double2 operator()(Grid::ComplexD *a){
double2 ret;
ret.x = a[0].real();
ret.y = a[0].imag();
return ret;
}
// Real float
accelerator_inline float4 operator()(float *a){
float4 ret;
ret.x = a[0];
ret.y = a[1];
ret.z = a[2];
ret.w = a[3];
return ret;
}
// Real double
accelerator_inline double2 operator()(double *a){
double2 ret;
ret.x = a[0];
ret.y = a[1];
return ret;
}
// Integer
accelerator_inline int4 operator()(Integer *a){
int4 ret;
ret.x = a[0];
ret.y = a[1];
ret.z = a[2];
ret.w = a[3];
return ret;
}
};
template <typename Out_type, typename In_type>
struct Reduce{
//Need templated class to overload output type
//General form must generate error if compiled
accelerator_inline Out_type operator()(In_type in){
printf("Error, using wrong Reduce function\n");
exit(1);
return 0;
}
};
/////////////////////////////////////////////////////
// Arithmetic operations
/////////////////////////////////////////////////////
struct Sum{
//Complex/Real float
accelerator_inline float4 operator()(float4 a, float4 b){
return a+b;
}
//Complex/Real double
accelerator_inline double2 operator()(double2 a, double2 b){
return a+b;
}
//Integer
accelerator_inline int4 operator()(int4 a,int4 b){
return a+b;
}
};
struct Sub{
//Complex/Real float
accelerator_inline float4 operator()(float4 a, float4 b){
return a-b;
}
//Complex/Real double
accelerator_inline double2 operator()(double2 a, double2 b){
return a-b;
}
//Integer
accelerator_inline int4 operator()(int4 a, int4 b){
return a-b;
}
};
struct MultRealPart{
accelerator_inline float4 operator()(float4 a, float4 b){
float4 ymm0;
ymm0.x = a.x;
ymm0.y = a.x;
ymm0.z = a.z;
ymm0.w = a.z;
return ymm0*b;
// 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
}
accelerator_inline double2 operator()(double2 a, double2 b){
double2 ymm0;
ymm0.x = a.x;
ymm0.y = a.x;
return ymm0*b;
// 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{
accelerator_inline float4 operator()(float4 a, float4 b, float4 c){
float4 ymm0; // = _mm_shuffle_ps(a,a,_MM_SELECT_FOUR_FOUR(2,2,0,0)); // ymm0 <- ar ar,
ymm0.x = a.x;
ymm0.y = a.x;
ymm0.z = a.z;
ymm0.w = a.z;
return c+ymm0*b;
}
accelerator_inline double2 operator()(double2 a, double2 b, double2 c){
// ymm0 = _mm_shuffle_pd( a, a, 0x0 );
double2 ymm0;
ymm0.x = a.x;
ymm0.y = a.x;
return c+ymm0*b;
}
};
struct MultComplex{
// Complex float
accelerator_inline float4 operator()(float4 a, float4 b){
float4 ymm0;
ymm0.x = a.x*b.x - a.y*b.y ; // rr - ii
ymm0.y = a.x*b.y + a.y*b.x ; // ir + ri
ymm0.z = a.z*b.z - a.w*b.w ; // rr - ii
ymm0.w = a.w*b.z + a.z*b.w ; // ir + ri
return ymm0;
}
// Complex double
accelerator_inline double2 operator()(double2 a, double2 b){
double2 ymm0;
ymm0.x = a.x*b.x - a.y*b.y ; // rr - ii
ymm0.y = a.x*b.y + a.y*b.x ; // ir + ri
return ymm0;
}
};
struct Mult{
accelerator_inline void mac(float4 &a, float4 b, float4 c){
a= a+b*c;
}
accelerator_inline void mac(double2 &a, double2 b, double2 c){
a= a+b*c;
}
// Real float
accelerator_inline float4 operator()(float4 a, float4 b){
return a*b;
}
// Real double
accelerator_inline double2 operator()(double2 a, double2 b){
return a*b;
}
// Integer
accelerator_inline int4 operator()(int4 a, int4 b){
return a*b;
}
};
struct Div{
// Real float
accelerator_inline float4 operator()(float4 a, float4 b){
return a/b;
}
// Real double
accelerator_inline double2 operator()(double2 a, double2 b){
return a/b;
}
};
struct Conj{
// Complex single
accelerator_inline float4 operator()(float4 in){
float4 ret;
ret.x = in.x;
ret.y = - in.y;
ret.z = in.z;
ret.w = - in.w;
return ret;
}
// Complex double
accelerator_inline double2 operator()(double2 in){
double2 ret;
ret.x = in.x;
ret.y = - in.y;
return ret;
}
// do not define for integer input
};
struct TimesMinusI{
//Complex single
accelerator_inline float4 operator()(float4 in, float4 ret){
float4 tmp;
tmp.x = in.y;
tmp.y = - in.x;
tmp.z = in.w;
tmp.w = - in.z;
return tmp;
}
//Complex double
accelerator_inline double2 operator()(double2 in, double2 ret){
double2 tmp;
tmp.x = in.y;
tmp.y = - in.x;
return tmp;
}
};
struct TimesI{
//Complex single
accelerator_inline float4 operator()(float4 in, float4 ret){
float4 tmp;
tmp.x = - in.y;
tmp.y = in.x;
tmp.z = - in.w;
tmp.w = in.z;
return tmp;
}
//Complex double
accelerator_inline double2 operator()(double2 in, double2 ret){
double2 tmp ;
tmp.x = - in.y;
tmp.y = in.x;
return tmp;
}
};
struct Permute{
static accelerator_inline float4 Permute0(float4 in){
float4 tmp;
tmp.x = in.z;
tmp.y = in.w;
tmp.z = in.x;
tmp.w = in.y;
return tmp;
};
static accelerator_inline float4 Permute1(float4 in){
float4 tmp;
tmp.x = in.y;
tmp.y = in.x;
tmp.z = in.w;
tmp.w = in.z;
return tmp;
};
static accelerator_inline float4 Permute2(float4 in){
return in;
};
static accelerator_inline float4 Permute3(float4 in){
return in;
};
static accelerator_inline double2 Permute0(double2 in){ //AB -> BA
double2 tmp;
tmp.x = in.y;
tmp.y = in.x;
return tmp;
};
static accelerator_inline double2 Permute1(double2 in){
return in;
};
static accelerator_inline double2 Permute2(double2 in){
return in;
};
static accelerator_inline double2 Permute3(double2 in){
return in;
};
};
struct PrecisionChange {
static accelerator_inline half8 StoH (float4 a,float4 b) {
half8 h;
h.ax = float2half(a.x);
h.ay = float2half(a.y);
h.az = float2half(a.z);
h.aw = float2half(a.w);
h.bx = float2half(b.x);
h.by = float2half(b.y);
h.bz = float2half(b.z);
h.bw = float2half(b.w);
return h;
}
static accelerator_inline void HtoS (half8 h,float4 &sa,float4 &sb) {
sa.x = half2float(h.ax);
sa.y = half2float(h.ay);
sa.z = half2float(h.az);
sa.w = half2float(h.aw);
sb.x = half2float(h.bx);
sb.y = half2float(h.by);
sb.z = half2float(h.bz);
sb.w = half2float(h.bw);
}
static accelerator_inline float4 DtoS (double2 a,double2 b) {
float4 s;
s.x = a.x;
s.y = a.y;
s.z = b.x;
s.w = b.y;
return s;
}
static accelerator_inline void StoD (float4 s,double2 &a,double2 &b) {
a.x = s.x;
a.y = s.y;
b.x = s.z;
b.y = s.w;
}
static accelerator_inline half8 DtoH (double2 a,double2 b,double2 c,double2 d) {
float4 sa,sb;
sa = DtoS(a,b);
sb = DtoS(c,d);
return StoH(sa,sb);
}
static accelerator_inline void HtoD (half8 h,double2 &a,double2 &b,double2 &c,double2 &d) {
float4 sa,sb;
HtoS(h,sa,sb);
StoD(sa,a,b);
StoD(sb,c,d);
}
};
struct Exchange{
// 3210 ordering
static accelerator_inline void Exchange0(float4 &out1,float4 &out2,float4 in1,float4 in2){
out1.x = in1.x;
out1.y = in1.y;
out1.z = in2.x;
out1.w = in2.y;
out2.x = in1.z;
out2.y = in1.w;
out2.z = in2.z;
out2.w = in2.w;
// out1= _mm_shuffle_ps(in1,in2,_MM_SELECT_FOUR_FOUR(1,0,1,0));
// out2= _mm_shuffle_ps(in1,in2,_MM_SELECT_FOUR_FOUR(3,2,3,2));
return;
};
static accelerator_inline void Exchange1(float4 &out1,float4 &out2,float4 in1,float4 in2){
out1.x = in1.x;
out1.y = in2.x;
out1.z = in1.z;
out1.w = in2.z;
out2.x = in1.y;
out2.y = in2.y;
out2.z = in1.w;
out2.w = in2.w;
// out1= _mm_shuffle_ps(in1,in2,_MM_SELECT_FOUR_FOUR(2,0,2,0)); /*ACEG*/
// out2= _mm_shuffle_ps(in1,in2,_MM_SELECT_FOUR_FOUR(3,1,3,1)); /*BDFH*/
// out1= _mm_shuffle_ps(out1,out1,_MM_SELECT_FOUR_FOUR(3,1,2,0)); /*AECG*/
// out2= _mm_shuffle_ps(out2,out2,_MM_SELECT_FOUR_FOUR(3,1,2,0)); /*AECG*/
};
static accelerator_inline void Exchange2(float4 &out1,float4 &out2,float4 in1,float4 in2){
assert(0);
return;
};
static accelerator_inline void Exchange3(float4 &out1,float4 &out2,float4 in1,float4 in2){
assert(0);
return;
};
static accelerator_inline void Exchange0(double2 &out1,double2 &out2,double2 in1,double2 in2){
out1.x = in1.x;
out1.y = in2.x;
out2.x = in1.y;
out2.y = in2.y;
// out1= _mm_shuffle_pd(in1,in2,0x0);
// out2= _mm_shuffle_pd(in1,in2,0x3);
};
static accelerator_inline void Exchange1(double2 &out1,double2 &out2,double2 in1,double2 in2){
assert(0);
return;
};
static accelerator_inline void Exchange2(double2 &out1,double2 &out2,double2 in1,double2 in2){
assert(0);
return;
};
static accelerator_inline void Exchange3(double2 &out1,double2 &out2,double2 in1,double2 in2){
assert(0);
return;
};
};
struct Rotate{
static accelerator_inline float4 rotate(float4 in,int n){
float4 ret;
switch(n){
case 0: ret = in ; break;
case 1: ret.x = in.y; ret.y = in.z ; ret.z = in.w ; ret.w = in.x; break;
case 2: ret.x = in.z; ret.y = in.w ; ret.z = in.x ; ret.w = in.y; break;
case 3: ret.x = in.w; ret.y = in.x ; ret.z = in.y ; ret.w = in.z; break;
default: break;
}
return ret;
}
static accelerator_inline double2 rotate(double2 in,int n){
double2 ret;
switch(n){
case 0: ret = in; break;
case 1: ret.x = in.y; ret.y = in.x ; break;
default: break;
}
return ret;
}
template<int n> static accelerator_inline float4 tRotate(float4 in){
return rotate(in,n);
};
template<int n> static accelerator_inline double2 tRotate(double2 in){
return rotate(in,n);
};
};
//////////////////////////////////////////////
// Some Template specialization
//Complex float Reduce
template<>
accelerator_inline Grid::ComplexF Reduce<Grid::ComplexF, float4>::operator()(float4 in){
Grid::ComplexF ret(in.x+in.z,in.y+in.w);
return ret;
}
//Real float Reduce
template<>
accelerator_inline Grid::RealF Reduce<Grid::RealF, float4>::operator()(float4 in){
return in.x+in.y+in.z+in.w;
}
//Complex double Reduce
template<>
accelerator_inline Grid::ComplexD Reduce<Grid::ComplexD, double2>::operator()(double2 in){
return Grid::ComplexD(in.x,in.y);
}
//Real double Reduce
template<>
accelerator_inline Grid::RealD Reduce<Grid::RealD, double2>::operator()(double2 in){
return in.x+in.y;
}
//Integer Reduce
template<>
accelerator_inline Integer Reduce<Integer, int4>::operator()(int4 in){
return in.x+in.y+in.z+in.w;
}
}
//////////////////////////////////////////////////////////////////////////////////////
// Here assign types
//////////////////////////////////////////////////////////////////////////////////////
typedef half8 SIMD_Htype; // Single precision type
typedef float4 SIMD_Ftype; // Single precision type
typedef double2 SIMD_Dtype; // Double precision type
typedef int4 SIMD_Itype; // Integer type
// prefetch utilities
accelerator_inline void v_prefetch0(int size, const char *ptr){};
accelerator_inline void prefetch_HINT_T0(const char *ptr){};
// Function name aliases
typedef Optimization::Vsplat VsplatSIMD;
typedef Optimization::Vstore VstoreSIMD;
typedef Optimization::Vset VsetSIMD;
typedef Optimization::Vstream VstreamSIMD;
template <typename S, typename T> using ReduceSIMD = Optimization::Reduce<S,T>;
// Arithmetic operations
typedef Optimization::Sum SumSIMD;
typedef Optimization::Sub SubSIMD;
typedef Optimization::Div DivSIMD;
typedef Optimization::Mult MultSIMD;
typedef Optimization::MultComplex MultComplexSIMD;
typedef Optimization::MultRealPart MultRealPartSIMD;
typedef Optimization::MaddRealPart MaddRealPartSIMD;
typedef Optimization::Conj ConjSIMD;
typedef Optimization::TimesMinusI TimesMinusISIMD;
typedef Optimization::TimesI TimesISIMD;
}

View File

@ -11,6 +11,7 @@ Author: Guido Cossu <cossu@iroiro-pc.kek.jp>
Author: Peter Boyle <paboyle@ph.ed.ac.uk> Author: Peter Boyle <paboyle@ph.ed.ac.uk>
Author: neo <cossu@post.kek.jp> Author: neo <cossu@post.kek.jp>
Author: paboyle <paboyle@ph.ed.ac.uk> Author: paboyle <paboyle@ph.ed.ac.uk>
Author: Michael Marshall <michael.marshall@ed.ac.au>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -109,9 +110,6 @@ accelerator_inline Grid_half sfw_float_to_half(float ff) {
#ifdef GPU_VEC #ifdef GPU_VEC
#include "Grid_gpu_vec.h" #include "Grid_gpu_vec.h"
#endif #endif
#ifdef GPU
#include "Grid_gpu.h"
#endif
#ifdef GEN #ifdef GEN
#include "Grid_generic.h" #include "Grid_generic.h"
#endif #endif
@ -162,17 +160,25 @@ template <typename Condition, typename ReturnType> using NotEnableIf = Invoke<st
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// Check for complexity with type traits // Check for complexity with type traits
template <typename T> struct is_complex : public std::false_type {}; template <typename T> struct is_complex : public std::false_type {};
template <> struct is_complex<complex<double> > : public std::true_type {}; template <> struct is_complex<ComplexD> : public std::true_type {};
template <> struct is_complex<complex<float> > : public std::true_type {}; template <> struct is_complex<ComplexF> : public std::true_type {};
template <typename T> using IfReal = Invoke<std::enable_if<std::is_floating_point<T>::value, int> >; template<typename T, typename V=void> struct is_real : public std::false_type {};
template<typename T> struct is_real<T, typename std::enable_if<std::is_floating_point<T>::value,
void>::type> : public std::true_type {};
template<typename T, typename V=void> struct is_integer : public std::false_type {};
template<typename T> struct is_integer<T, typename std::enable_if<std::is_integral<T>::value,
void>::type> : public std::true_type {};
template <typename T> using IfReal = Invoke<std::enable_if<is_real<T>::value, int> >;
template <typename T> using IfComplex = Invoke<std::enable_if<is_complex<T>::value, int> >; template <typename T> using IfComplex = Invoke<std::enable_if<is_complex<T>::value, int> >;
template <typename T> using IfInteger = Invoke<std::enable_if<std::is_integral<T>::value, int> >; template <typename T> using IfInteger = Invoke<std::enable_if<is_integer<T>::value, int> >;
template <typename T1,typename T2> using IfSame = Invoke<std::enable_if<std::is_same<T1,T2>::value, int> >; template <typename T1,typename T2> using IfSame = Invoke<std::enable_if<std::is_same<T1,T2>::value, int> >;
template <typename T> using IfNotReal = Invoke<std::enable_if<!std::is_floating_point<T>::value, int> >; template <typename T> using IfNotReal = Invoke<std::enable_if<!is_real<T>::value, int> >;
template <typename T> using IfNotComplex = Invoke<std::enable_if<!is_complex<T>::value, int> >; template <typename T> using IfNotComplex = Invoke<std::enable_if<!is_complex<T>::value, int> >;
template <typename T> using IfNotInteger = Invoke<std::enable_if<!std::is_integral<T>::value, int> >; template <typename T> using IfNotInteger = Invoke<std::enable_if<!is_integer<T>::value, int> >;
template <typename T1,typename T2> using IfNotSame = Invoke<std::enable_if<!std::is_same<T1,T2>::value, int> >; template <typename T1,typename T2> using IfNotSame = Invoke<std::enable_if<!std::is_same<T1,T2>::value, int> >;
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@ -957,8 +963,10 @@ template <typename T>
struct is_simd : public std::false_type {}; struct is_simd : public std::false_type {};
template <> struct is_simd<vRealF> : public std::true_type {}; template <> struct is_simd<vRealF> : public std::true_type {};
template <> struct is_simd<vRealD> : public std::true_type {}; template <> struct is_simd<vRealD> : public std::true_type {};
template <> struct is_simd<vRealH> : public std::true_type {};
template <> struct is_simd<vComplexF> : public std::true_type {}; template <> struct is_simd<vComplexF> : public std::true_type {};
template <> struct is_simd<vComplexD> : public std::true_type {}; template <> struct is_simd<vComplexD> : public std::true_type {};
template <> struct is_simd<vComplexH> : public std::true_type {};
template <> struct is_simd<vInteger> : public std::true_type {}; template <> struct is_simd<vInteger> : public std::true_type {};
template <typename T> using IfSimd = Invoke<std::enable_if<is_simd<T>::value, int> >; template <typename T> using IfSimd = Invoke<std::enable_if<is_simd<T>::value, int> >;

View File

@ -5,6 +5,7 @@ Copyright (C) 2015
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk> Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
Author: Peter Boyle <paboyle@ph.ed.ac.uk> Author: Peter Boyle <paboyle@ph.ed.ac.uk>
Author: Michael Marshall <michael.marshall@ed.ac.au>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -21,8 +22,7 @@ See the full license in the file "LICENSE" in the top level distribution
directory directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef GRID_MATH_TENSORS_H #pragma once
#define GRID_MATH_TENSORS_H
NAMESPACE_BEGIN(Grid); NAMESPACE_BEGIN(Grid);
@ -42,27 +42,26 @@ NAMESPACE_BEGIN(Grid);
// //
class GridTensorBase {}; class GridTensorBase {};
// Too late to remove these traits from Grid Tensors, so inherit from GridTypeMapper
#define GridVector_CopyTraits \
using element = vtype; \
using scalar_type = typename Traits::scalar_type; \
using vector_type = typename Traits::vector_type; \
using vector_typeD = typename Traits::vector_typeD; \
using tensor_reduced = typename Traits::tensor_reduced; \
using scalar_object = typename Traits::scalar_object; \
using Complexified = typename Traits::Complexified; \
using Realified = typename Traits::Realified; \
using DoublePrecision = typename Traits::DoublePrecision; \
static constexpr int TensorLevel = Traits::TensorLevel
template <class vtype> template <class vtype>
class iScalar { class iScalar {
public: public:
vtype _internal; vtype _internal;
typedef vtype element; using Traits = GridTypeMapper<iScalar<vtype> >;
typedef typename GridTypeMapper<vtype>::scalar_type scalar_type; GridVector_CopyTraits;
typedef typename GridTypeMapper<vtype>::vector_type vector_type;
typedef typename GridTypeMapper<vtype>::vector_typeD vector_typeD;
typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
typedef iScalar<tensor_reduced_v> tensor_reduced;
typedef iScalar<recurse_scalar_object> scalar_object;
// substitutes a real or complex version with same tensor structure
typedef iScalar<typename GridTypeMapper<vtype>::Complexified> Complexified;
typedef iScalar<typename GridTypeMapper<vtype>::Realified> Realified;
// get double precision version
typedef iScalar<typename GridTypeMapper<vtype>::DoublePrecision> DoublePrecision;
enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
static accelerator_inline constexpr int Nsimd(void) { return sizeof(vector_type)/sizeof(scalar_type); } static accelerator_inline constexpr int Nsimd(void) { return sizeof(vector_type)/sizeof(scalar_type); }
@ -160,6 +159,10 @@ public:
stream << "S {" << o._internal << "}"; stream << "S {" << o._internal << "}";
return stream; return stream;
}; };
strong_inline const scalar_type * begin() const { return reinterpret_cast<const scalar_type *>(&_internal); }
strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(&_internal); }
strong_inline const scalar_type * end() const { return begin() + Traits::count; }
strong_inline scalar_type * end() { return begin() + Traits::count; }
}; };
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -181,34 +184,21 @@ class iVector {
public: public:
vtype _internal[N]; vtype _internal[N];
typedef vtype element; using Traits = GridTypeMapper<iVector<vtype, N> >;
typedef typename GridTypeMapper<vtype>::scalar_type scalar_type;
typedef typename GridTypeMapper<vtype>::vector_type vector_type;
typedef typename GridTypeMapper<vtype>::vector_typeD vector_typeD;
typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
typedef iScalar<tensor_reduced_v> tensor_reduced;
typedef iVector<recurse_scalar_object, N> scalar_object;
// substitutes a real or complex version with same tensor structure GridVector_CopyTraits;
typedef iVector<typename GridTypeMapper<vtype>::Complexified, N> Complexified;
typedef iVector<typename GridTypeMapper<vtype>::Realified, N> Realified;
// get double precision version
typedef iVector<typename GridTypeMapper<vtype>::DoublePrecision, N> DoublePrecision;
static accelerator_inline constexpr int Nsimd(void) { return sizeof(vector_type)/sizeof(scalar_type); } static accelerator_inline constexpr int Nsimd(void) { return sizeof(vector_type)/sizeof(scalar_type); }
template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type * = nullptr> template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type * = nullptr>
accelerator_inline auto operator=(T arg) -> iVector<vtype, N> { strong_inline auto operator=(T arg) -> iVector<vtype, N> {
zeroit(*this); zeroit(*this);
for (int i = 0; i < N; i++) _internal[i] = arg; for (int i = 0; i < N; i++) _internal[i] = arg;
return *this; return *this;
} }
enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
accelerator_inline iVector(const Zero &z) { zeroit(*this); };
accelerator iVector() = default; accelerator iVector() = default;
accelerator_inline iVector(const Zero &z) { zeroit(*this); };
accelerator_inline iVector<vtype, N> &operator=(const Zero &hero) { accelerator_inline iVector<vtype, N> &operator=(const Zero &hero) {
zeroit(*this); zeroit(*this);
@ -281,6 +271,15 @@ public:
stream << "}"; stream << "}";
return stream; return stream;
}; };
// strong_inline vtype && operator ()(int i) {
// return _internal[i];
// }
strong_inline const scalar_type * begin() const { return reinterpret_cast<const scalar_type *>(_internal); }
strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(_internal); }
strong_inline const scalar_type * end() const { return begin() + Traits::count; }
strong_inline scalar_type * end() { return begin() + Traits::count; }
}; };
template <class vtype, int N> template <class vtype, int N>
@ -288,25 +287,9 @@ class iMatrix {
public: public:
vtype _internal[N][N]; vtype _internal[N][N];
typedef vtype element; using Traits = GridTypeMapper<iMatrix<vtype, N> >;
typedef typename GridTypeMapper<vtype>::scalar_type scalar_type;
typedef typename GridTypeMapper<vtype>::vector_type vector_type;
typedef typename GridTypeMapper<vtype>::vector_typeD vector_typeD;
typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
// substitutes a real or complex version with same tensor structure GridVector_CopyTraits;
typedef iMatrix<typename GridTypeMapper<vtype>::Complexified, N> Complexified;
typedef iMatrix<typename GridTypeMapper<vtype>::Realified, N> Realified;
// get double precision version
typedef iMatrix<typename GridTypeMapper<vtype>::DoublePrecision, N> DoublePrecision;
// Tensor removal
typedef iScalar<tensor_reduced_v> tensor_reduced;
typedef iMatrix<recurse_scalar_object, N> scalar_object;
enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
static accelerator_inline constexpr int Nsimd(void) { return sizeof(vector_type)/sizeof(scalar_type); } static accelerator_inline constexpr int Nsimd(void) { return sizeof(vector_type)/sizeof(scalar_type); }
@ -428,6 +411,14 @@ public:
return stream; return stream;
}; };
// strong_inline vtype && operator ()(int i,int j) {
// return _internal[i][j];
// }
strong_inline const scalar_type * begin() const { return reinterpret_cast<const scalar_type *>(_internal[0]); }
strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(_internal[0]); }
strong_inline const scalar_type * end() const { return begin() + Traits::count; }
strong_inline scalar_type * end() { return begin() + Traits::count; }
}; };
template <class v> accelerator_inline template <class v> accelerator_inline
@ -451,4 +442,3 @@ void vprefetch(const iMatrix<v, N> &vv) {
NAMESPACE_END(Grid); NAMESPACE_END(Grid);
#endif

View File

@ -5,6 +5,7 @@
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk> Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
Author: Peter Boyle <paboyle@ph.ed.ac.uk> Author: Peter Boyle <paboyle@ph.ed.ac.uk>
Author: Christopher Kelly <ckelly@phys.columbia.edu> Author: Christopher Kelly <ckelly@phys.columbia.edu>
Author: Michael Marshall <michael.marshall@ed.ac.au>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
@ -24,7 +25,18 @@ Author: Christopher Kelly <ckelly@phys.columbia.edu>
#include <type_traits> #include <type_traits>
NAMESPACE_BEGIN(Grid); namespace Grid {
// Forward declarations
template<class T> class iScalar;
template<class T, int N> class iVector;
template<class T, int N> class iMatrix;
// These are the Grid tensors
template<typename T> struct isGridTensor : public std::false_type { static constexpr bool notvalue = true; };
template<class T> struct isGridTensor<iScalar<T>> : public std::true_type { static constexpr bool notvalue = false; };
template<class T, int N> struct isGridTensor<iVector<T, N>> : public std::true_type { static constexpr bool notvalue = false; };
template<class T, int N> struct isGridTensor<iMatrix<T, N>> : public std::true_type { static constexpr bool notvalue = false; };
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
// Want to recurse: GridTypeMapper<Matrix<vComplexD> >::scalar_type == ComplexD. // Want to recurse: GridTypeMapper<Matrix<vComplexD> >::scalar_type == ComplexD.
@ -41,24 +53,25 @@ NAMESPACE_BEGIN(Grid);
// //
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
template <class T> class GridTypeMapper { // This saves repeating common properties for supported Grid Scalar types
public: // TensorLevel How many nested grid tensors
typedef typename T::scalar_type scalar_type; // Rank Rank of the grid tensor
typedef typename T::vector_type vector_type; // count Total number of elements, i.e. product of dimensions
typedef typename T::vector_typeD vector_typeD; // Dimension(dim) Size of dimension dim
typedef typename T::tensor_reduced tensor_reduced; struct GridTypeMapper_Base {
typedef typename T::scalar_object scalar_object; static constexpr int TensorLevel = 0;
typedef typename T::Complexified Complexified; static constexpr int Rank = 0;
typedef typename T::Realified Realified; static constexpr std::size_t count = 1;
typedef typename T::DoublePrecision DoublePrecision; static constexpr int Dimension(int dim) { return 0; }
enum { TensorLevel = T::TensorLevel };
}; };
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
// Recursion stops with these template specialisations // Recursion stops with these template specialisations
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
template<> class GridTypeMapper<RealF> {
public: template<typename T> struct GridTypeMapper {};
template<> struct GridTypeMapper<RealF> : public GridTypeMapper_Base {
typedef RealF scalar_type; typedef RealF scalar_type;
typedef RealF vector_type; typedef RealF vector_type;
typedef RealD vector_typeD; typedef RealD vector_typeD;
@ -67,10 +80,8 @@ public:
typedef ComplexF Complexified; typedef ComplexF Complexified;
typedef RealF Realified; typedef RealF Realified;
typedef RealD DoublePrecision; typedef RealD DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<RealD> { template<> struct GridTypeMapper<RealD> : public GridTypeMapper_Base {
public:
typedef RealD scalar_type; typedef RealD scalar_type;
typedef RealD vector_type; typedef RealD vector_type;
typedef RealD vector_typeD; typedef RealD vector_typeD;
@ -79,10 +90,8 @@ public:
typedef ComplexD Complexified; typedef ComplexD Complexified;
typedef RealD Realified; typedef RealD Realified;
typedef RealD DoublePrecision; typedef RealD DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<ComplexF> { template<> struct GridTypeMapper<ComplexF> : public GridTypeMapper_Base {
public:
typedef ComplexF scalar_type; typedef ComplexF scalar_type;
typedef ComplexF vector_type; typedef ComplexF vector_type;
typedef ComplexD vector_typeD; typedef ComplexD vector_typeD;
@ -91,10 +100,8 @@ public:
typedef ComplexF Complexified; typedef ComplexF Complexified;
typedef RealF Realified; typedef RealF Realified;
typedef ComplexD DoublePrecision; typedef ComplexD DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<ComplexD> { template<> struct GridTypeMapper<ComplexD> : public GridTypeMapper_Base {
public:
typedef ComplexD scalar_type; typedef ComplexD scalar_type;
typedef ComplexD vector_type; typedef ComplexD vector_type;
typedef ComplexD vector_typeD; typedef ComplexD vector_typeD;
@ -103,10 +110,8 @@ public:
typedef ComplexD Complexified; typedef ComplexD Complexified;
typedef RealD Realified; typedef RealD Realified;
typedef ComplexD DoublePrecision; typedef ComplexD DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<Integer> { template<> struct GridTypeMapper<Integer> : public GridTypeMapper_Base {
public:
typedef Integer scalar_type; typedef Integer scalar_type;
typedef Integer vector_type; typedef Integer vector_type;
typedef Integer vector_typeD; typedef Integer vector_typeD;
@ -115,11 +120,9 @@ public:
typedef void Complexified; typedef void Complexified;
typedef void Realified; typedef void Realified;
typedef void DoublePrecision; typedef void DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<vRealF> { template<> struct GridTypeMapper<vRealF> : public GridTypeMapper_Base {
public:
typedef RealF scalar_type; typedef RealF scalar_type;
typedef vRealF vector_type; typedef vRealF vector_type;
typedef vRealD vector_typeD; typedef vRealD vector_typeD;
@ -128,10 +131,8 @@ public:
typedef vComplexF Complexified; typedef vComplexF Complexified;
typedef vRealF Realified; typedef vRealF Realified;
typedef vRealD DoublePrecision; typedef vRealD DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<vRealD> { template<> struct GridTypeMapper<vRealD> : public GridTypeMapper_Base {
public:
typedef RealD scalar_type; typedef RealD scalar_type;
typedef vRealD vector_type; typedef vRealD vector_type;
typedef vRealD vector_typeD; typedef vRealD vector_typeD;
@ -140,10 +141,20 @@ public:
typedef vComplexD Complexified; typedef vComplexD Complexified;
typedef vRealD Realified; typedef vRealD Realified;
typedef vRealD DoublePrecision; typedef vRealD DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<vComplexH> { template<> struct GridTypeMapper<vRealH> : public GridTypeMapper_Base {
public: // Fixme this is incomplete until Grid supports fp16 or bfp16 arithmetic types
typedef RealF scalar_type;
typedef vRealH vector_type;
typedef vRealD vector_typeD;
typedef vRealH tensor_reduced;
typedef RealF scalar_object;
typedef vComplexH Complexified;
typedef vRealH Realified;
typedef vRealD DoublePrecision;
};
template<> struct GridTypeMapper<vComplexH> : public GridTypeMapper_Base {
// Fixme this is incomplete until Grid supports fp16 or bfp16 arithmetic types
typedef ComplexF scalar_type; typedef ComplexF scalar_type;
typedef vComplexH vector_type; typedef vComplexH vector_type;
typedef vComplexD vector_typeD; typedef vComplexD vector_typeD;
@ -152,10 +163,8 @@ public:
typedef vComplexH Complexified; typedef vComplexH Complexified;
typedef vRealH Realified; typedef vRealH Realified;
typedef vComplexD DoublePrecision; typedef vComplexD DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<vComplexF> { template<> struct GridTypeMapper<vComplexF> : public GridTypeMapper_Base {
public:
typedef ComplexF scalar_type; typedef ComplexF scalar_type;
typedef vComplexF vector_type; typedef vComplexF vector_type;
typedef vComplexD vector_typeD; typedef vComplexD vector_typeD;
@ -164,10 +173,8 @@ public:
typedef vComplexF Complexified; typedef vComplexF Complexified;
typedef vRealF Realified; typedef vRealF Realified;
typedef vComplexD DoublePrecision; typedef vComplexD DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<vComplexD> { template<> struct GridTypeMapper<vComplexD> : public GridTypeMapper_Base {
public:
typedef ComplexD scalar_type; typedef ComplexD scalar_type;
typedef vComplexD vector_type; typedef vComplexD vector_type;
typedef vComplexD vector_typeD; typedef vComplexD vector_typeD;
@ -176,10 +183,8 @@ public:
typedef vComplexD Complexified; typedef vComplexD Complexified;
typedef vRealD Realified; typedef vRealD Realified;
typedef vComplexD DoublePrecision; typedef vComplexD DoublePrecision;
enum { TensorLevel = 0 };
}; };
template<> class GridTypeMapper<vInteger> { template<> struct GridTypeMapper<vInteger> : public GridTypeMapper_Base {
public:
typedef Integer scalar_type; typedef Integer scalar_type;
typedef vInteger vector_type; typedef vInteger vector_type;
typedef vInteger vector_typeD; typedef vInteger vector_typeD;
@ -188,57 +193,52 @@ public:
typedef void Complexified; typedef void Complexified;
typedef void Realified; typedef void Realified;
typedef void DoublePrecision; typedef void DoublePrecision;
enum { TensorLevel = 0 };
}; };
// First some of my own traits #define GridTypeMapper_RepeatedTypes \
template<typename T> struct isGridTensor { using BaseTraits = GridTypeMapper<T>; \
static const bool value = true; using scalar_type = typename BaseTraits::scalar_type; \
static const bool notvalue = false; using vector_type = typename BaseTraits::vector_type; \
using vector_typeD = typename BaseTraits::vector_typeD; \
static constexpr int TensorLevel = BaseTraits::TensorLevel + 1
template<typename T> struct GridTypeMapper<iScalar<T>> {
GridTypeMapper_RepeatedTypes;
using tensor_reduced = iScalar<typename BaseTraits::tensor_reduced>;
using scalar_object = iScalar<typename BaseTraits::scalar_object>;
using Complexified = iScalar<typename BaseTraits::Complexified>;
using Realified = iScalar<typename BaseTraits::Realified>;
using DoublePrecision = iScalar<typename BaseTraits::DoublePrecision>;
static constexpr int Rank = BaseTraits::Rank + 1;
static constexpr std::size_t count = BaseTraits::count;
static constexpr int Dimension(int dim) {
return ( dim == 0 ) ? 1 : BaseTraits::Dimension(dim - 1); }
}; };
template<> struct isGridTensor<int > {
static const bool value = false; template<typename T, int N> struct GridTypeMapper<iVector<T, N>> {
static const bool notvalue = true; GridTypeMapper_RepeatedTypes;
using tensor_reduced = iScalar<typename BaseTraits::tensor_reduced>;
using scalar_object = iVector<typename BaseTraits::scalar_object, N>;
using Complexified = iVector<typename BaseTraits::Complexified, N>;
using Realified = iVector<typename BaseTraits::Realified, N>;
using DoublePrecision = iVector<typename BaseTraits::DoublePrecision, N>;
static constexpr int Rank = BaseTraits::Rank + 1;
static constexpr std::size_t count = BaseTraits::count * N;
static constexpr int Dimension(int dim) {
return ( dim == 0 ) ? N : BaseTraits::Dimension(dim - 1); }
}; };
template<> struct isGridTensor<RealD > {
static const bool value = false; template<typename T, int N> struct GridTypeMapper<iMatrix<T, N>> {
static const bool notvalue = true; GridTypeMapper_RepeatedTypes;
}; using tensor_reduced = iScalar<typename BaseTraits::tensor_reduced>;
template<> struct isGridTensor<RealF > { using scalar_object = iMatrix<typename BaseTraits::scalar_object, N>;
static const bool value = false; using Complexified = iMatrix<typename BaseTraits::Complexified, N>;
static const bool notvalue = true; using Realified = iMatrix<typename BaseTraits::Realified, N>;
}; using DoublePrecision = iMatrix<typename BaseTraits::DoublePrecision, N>;
template<> struct isGridTensor<ComplexD > { static constexpr int Rank = BaseTraits::Rank + 2;
static const bool value = false; static constexpr std::size_t count = BaseTraits::count * N * N;
static const bool notvalue = true; static constexpr int Dimension(int dim) {
}; return ( dim == 0 || dim == 1 ) ? N : BaseTraits::Dimension(dim - 2); }
template<> struct isGridTensor<ComplexF > {
static const bool value = false;
static const bool notvalue = true;
};
template<> struct isGridTensor<Integer > {
static const bool value = false;
static const bool notvalue = true;
};
template<> struct isGridTensor<vRealD > {
static const bool value = false;
static const bool notvalue = true;
};
template<> struct isGridTensor<vRealF > {
static const bool value = false;
static const bool notvalue = true;
};
template<> struct isGridTensor<vComplexD > {
static const bool value = false;
static const bool notvalue = true;
};
template<> struct isGridTensor<vComplexF > {
static const bool value = false;
static const bool notvalue = true;
};
template<> struct isGridTensor<vInteger > {
static const bool value = false;
static const bool notvalue = true;
}; };
// Match the index // Match the index
@ -263,20 +263,12 @@ struct getVectorType{
typedef T type; typedef T type;
}; };
//Query if a tensor or Lattice<Tensor> is SIMD vector or scalar //Query whether a tensor or Lattice<Tensor> is SIMD vector or scalar
template<typename T> template<typename T, typename V=void> struct isSIMDvectorized : public std::false_type {};
class isSIMDvectorized{ template<typename U> struct isSIMDvectorized<U, typename std::enable_if< !std::is_same<
template<typename U> typename GridTypeMapper<typename getVectorType<U>::type>::scalar_type,
static typename std::enable_if< typename GridTypeMapper<typename getVectorType<U>::type>::vector_type>::value, void>::type>
!std::is_same< typename GridTypeMapper<typename getVectorType<U>::type>::scalar_type, : public std::true_type {};
typename GridTypeMapper<typename getVectorType<U>::type>::vector_type>::value,
char>::type test(void *);
template<typename U> static double test(...);
public:
enum {value = sizeof(test<T>(0)) == sizeof(char) };
};
//Get the precision of a Lattice, tensor or scalar type in units of sizeof(float) //Get the precision of a Lattice, tensor or scalar type in units of sizeof(float)
template<typename T> template<typename T>
@ -289,9 +281,7 @@ public:
enum { value = sizeof(real_scalar_type)/sizeof(float) }; enum { value = sizeof(real_scalar_type)/sizeof(float) };
}; };
}
NAMESPACE_END(Grid);
#endif #endif

View File

@ -272,6 +272,11 @@ void GridBanner(void)
std::cout << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"<<std::endl; std::cout << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"<<std::endl;
std::cout << "GNU General Public License for more details."<<std::endl; std::cout << "GNU General Public License for more details."<<std::endl;
printHash(); printHash();
#ifdef GRID_BUILD_REF
#define _GRID_BUILD_STR(x) #x
#define GRID_BUILD_STR(x) _GRID_BUILD_STR(x)
std::cout << "Build " << GRID_BUILD_STR(GRID_BUILD_REF) << std::endl;
#endif
std::cout << std::endl; std::cout << std::endl;
printed=1; printed=1;
} }
@ -419,7 +424,6 @@ void Grid_init(int *argc,char ***argv)
MemoryProfiler::stats = &dbgMemStats; MemoryProfiler::stats = &dbgMemStats;
} }
//////////////////////////////////// ////////////////////////////////////
// Logging // Logging
//////////////////////////////////// ////////////////////////////////////

6
HMC/Makefile.am Normal file
View File

@ -0,0 +1,6 @@
SUBDIRS = .
include Make.inc

198
HMC/Mobius2p1f.cc Normal file
View File

@ -0,0 +1,198 @@
/*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid
Source file: ./tests/Test_hmc_EODWFRatio.cc
Copyright (C) 2015-2016
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
Author: Guido Cossu <guido.cossu@ed.ac.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/
/* END LEGAL */
#include <Grid/Grid.h>
int main(int argc, char **argv) {
using namespace Grid;
using namespace Grid::QCD;
Grid_init(&argc, &argv);
int threads = GridThread::GetThreads();
// here make a routine to print all the relevant information on the run
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
// Typedefs to simplify notation
typedef WilsonImplR FermionImplPolicy;
typedef MobiusFermionR FermionAction;
typedef typename FermionAction::FermionField FermionField;
typedef Grid::XmlReader Serialiser;
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IntegratorParameters MD;
// typedef GenericHMCRunner<LeapFrog> HMCWrapper;
// MD.name = std::string("Leap Frog");
// typedef GenericHMCRunner<ForceGradient> HMCWrapper;
// MD.name = std::string("Force Gradient");
typedef GenericHMCRunner<MinimumNorm2> HMCWrapper;
MD.name = std::string("MinimumNorm2");
MD.MDsteps = 20;
MD.trajL = 1.0;
HMCparameters HMCparams;
HMCparams.StartTrajectory = 0;
HMCparams.Trajectories = 200;
HMCparams.NoMetropolisUntil= 20;
// "[HotStart, ColdStart, TepidStart, CheckpointStart]\n";
HMCparams.StartingType =std::string("ColdStart");
HMCparams.MD = MD;
HMCWrapper TheHMC(HMCparams);
// Grid from the command line arguments --grid and --mpi
TheHMC.Resources.AddFourDimGrid("gauge"); // use default simd lanes decomposition
CheckpointerParameters CPparams;
CPparams.config_prefix = "ckpoint_EODWF_lat";
CPparams.rng_prefix = "ckpoint_EODWF_rng";
CPparams.saveInterval = 10;
CPparams.format = "IEEE64BIG";
TheHMC.Resources.LoadNerscCheckpointer(CPparams);
RNGModuleParameters RNGpar;
RNGpar.serial_seeds = "1 2 3 4 5";
RNGpar.parallel_seeds = "6 7 8 9 10";
TheHMC.Resources.SetRNGSeeds(RNGpar);
// Construct observables
// here there is too much indirection
typedef PlaquetteMod<HMCWrapper::ImplPolicy> PlaqObs;
TheHMC.Resources.AddObservable<PlaqObs>();
//////////////////////////////////////////////
const int Ls = 16;
Real beta = 2.13;
Real light_mass = 0.01;
Real strange_mass = 0.04;
Real pv_mass = 1.0;
RealD M5 = 1.8;
RealD b = 1.0; // Scale factor two
RealD c = 0.0;
OneFlavourRationalParams OFRp;
OFRp.lo = 1.0e-2;
OFRp.hi = 64;
OFRp.MaxIter = 10000;
OFRp.tolerance= 1.0e-10;
OFRp.degree = 14;
OFRp.precision= 40;
std::vector<Real> hasenbusch({ 0.1 });
auto GridPtr = TheHMC.Resources.GetCartesian();
auto GridRBPtr = TheHMC.Resources.GetRBCartesian();
auto FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,GridPtr);
auto FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,GridPtr);
IwasakiGaugeActionR GaugeAction(beta);
// temporarily need a gauge field
LatticeGaugeField U(GridPtr);
// These lines are unecessary if BC are all periodic
std::vector<Complex> boundary = {1,1,1,-1};
FermionAction::ImplParams Params(boundary);
double StoppingCondition = 1e-10;
double MaxCGIterations = 30000;
ConjugateGradient<FermionField> CG(StoppingCondition,MaxCGIterations);
////////////////////////////////////
// Collect actions
////////////////////////////////////
ActionLevel<HMCWrapper::Field> Level1(1);
ActionLevel<HMCWrapper::Field> Level2(4);
////////////////////////////////////
// Strange action
////////////////////////////////////
// FermionAction StrangeOp(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_mass,M5,b,c, Params);
// DomainWallEOFAFermionR Strange_Op_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5);
// DomainWallEOFAFermionR Strange_Op_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5);
// ExactOneFlavourRatioPseudoFermionAction EOFA(Strange_Op_L,Strange_Op_R,CG,ofp, false);
FermionAction StrangeOp (U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,strange_mass,M5,b,c, Params);
FermionAction StrangePauliVillarsOp(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,pv_mass, M5,b,c, Params);
// OneFlavourEvenOddRatioRationalPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion(StrangePauliVillarsOp,StrangeOp,OFRp);
OneFlavourRatioRationalPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion(StrangePauliVillarsOp,StrangeOp,OFRp);
// TwoFlavourRationalTesterPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion1F(StrangeOp,OFRp);
// TwoFlavourPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion2F(StrangeOp,CG,CG);
// Level1.push_back(&StrangePseudoFermion2F);
// Level1.push_back(&StrangePseudoFermion);
////////////////////////////////////
// up down action
////////////////////////////////////
std::vector<Real> light_den;
std::vector<Real> light_num;
int n_hasenbusch = hasenbusch.size();
light_den.push_back(light_mass);
for(int h=0;h<n_hasenbusch;h++){
light_den.push_back(hasenbusch[h]);
light_num.push_back(hasenbusch[h]);
}
light_num.push_back(pv_mass);
std::vector<FermionAction *> Numerators;
std::vector<FermionAction *> Denominators;
std::vector<TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy> *> Quotients;
for(int h=0;h<n_hasenbusch+1;h++){
std::cout << GridLogMessage << " 2f quotient Action "<< light_num[h] << " / " << light_den[h]<< std::endl;
Numerators.push_back (new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_num[h],M5,b,c, Params));
Denominators.push_back(new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_den[h],M5,b,c, Params));
Quotients.push_back (new TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy>(*Numerators[h],*Denominators[h],CG,CG));
}
for(int h=0;h<n_hasenbusch+1;h++){
Level1.push_back(Quotients[h]);
}
/////////////////////////////////////////////////////////////
// Gauge action
/////////////////////////////////////////////////////////////
Level2.push_back(&GaugeAction);
TheHMC.TheAction.push_back(Level1);
TheHMC.TheAction.push_back(Level2);
std::cout << GridLogMessage << " Action complete "<< std::endl;
/////////////////////////////////////////////////////////////
// HMC parameters are serialisable
std::cout << GridLogMessage << " Running the HMC "<< std::endl;
TheHMC.Run(); // no smearing
Grid_finalize();
} // main

449
HMC/Mobius2p1fEOFA.cc Normal file
View File

@ -0,0 +1,449 @@
/*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid
Source file:
Copyright (C) 2015-2016
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
Author: Guido Cossu
Author: David Murphy
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/
/* END LEGAL */
#include <Grid/Grid.h>
#define MIXED_PRECISION
namespace Grid{
namespace QCD{
/*
* Need a plan for gauge field update for mixed precision in HMC (2x speed up)
* -- Store the single prec action operator.
* -- Clone the gauge field from the operator function argument.
* -- Build the mixed precision operator dynamically from the passed operator and single prec clone.
*/
template<class FermionOperatorD, class FermionOperatorF, class SchurOperatorD, class SchurOperatorF>
class MixedPrecisionConjugateGradientOperatorFunction : public OperatorFunction<typename FermionOperatorD::FermionField> {
public:
typedef typename FermionOperatorD::FermionField FieldD;
typedef typename FermionOperatorF::FermionField FieldF;
RealD Tolerance;
RealD InnerTolerance; //Initial tolerance for inner CG. Defaults to Tolerance but can be changed
Integer MaxInnerIterations;
Integer MaxOuterIterations;
GridBase* SinglePrecGrid4; //Grid for single-precision fields
GridBase* SinglePrecGrid5; //Grid for single-precision fields
RealD OuterLoopNormMult; //Stop the outer loop and move to a final double prec solve when the residual is OuterLoopNormMult * Tolerance
FermionOperatorF &FermOpF;
FermionOperatorD &FermOpD;;
SchurOperatorF &LinOpF;
SchurOperatorD &LinOpD;
Integer TotalInnerIterations; //Number of inner CG iterations
Integer TotalOuterIterations; //Number of restarts
Integer TotalFinalStepIterations; //Number of CG iterations in final patch-up step
MixedPrecisionConjugateGradientOperatorFunction(RealD tol,
Integer maxinnerit,
Integer maxouterit,
GridBase* _sp_grid4,
GridBase* _sp_grid5,
FermionOperatorF &_FermOpF,
FermionOperatorD &_FermOpD,
SchurOperatorF &_LinOpF,
SchurOperatorD &_LinOpD):
LinOpF(_LinOpF),
LinOpD(_LinOpD),
FermOpF(_FermOpF),
FermOpD(_FermOpD),
Tolerance(tol),
InnerTolerance(tol),
MaxInnerIterations(maxinnerit),
MaxOuterIterations(maxouterit),
SinglePrecGrid4(_sp_grid4),
SinglePrecGrid5(_sp_grid5),
OuterLoopNormMult(100.)
{
/* Debugging instances of objects; references are stored
std::cout << GridLogMessage << " Mixed precision CG wrapper LinOpF " <<std::hex<< &LinOpF<<std::dec <<std::endl;
std::cout << GridLogMessage << " Mixed precision CG wrapper LinOpD " <<std::hex<< &LinOpD<<std::dec <<std::endl;
std::cout << GridLogMessage << " Mixed precision CG wrapper FermOpF " <<std::hex<< &FermOpF<<std::dec <<std::endl;
std::cout << GridLogMessage << " Mixed precision CG wrapper FermOpD " <<std::hex<< &FermOpD<<std::dec <<std::endl;
*/
};
void operator()(LinearOperatorBase<FieldD> &LinOpU, const FieldD &src, FieldD &psi) {
std::cout << GridLogMessage << " Mixed precision CG wrapper operator() "<<std::endl;
SchurOperatorD * SchurOpU = static_cast<SchurOperatorD *>(&LinOpU);
// std::cout << GridLogMessage << " Mixed precision CG wrapper operator() FermOpU " <<std::hex<< &(SchurOpU->_Mat)<<std::dec <<std::endl;
// std::cout << GridLogMessage << " Mixed precision CG wrapper operator() FermOpD " <<std::hex<< &(LinOpD._Mat) <<std::dec <<std::endl;
// Assumption made in code to extract gauge field
// We could avoid storing LinopD reference alltogether ?
assert(&(SchurOpU->_Mat)==&(LinOpD._Mat));
////////////////////////////////////////////////////////////////////////////////////
// Must snarf a single precision copy of the gauge field in Linop_d argument
////////////////////////////////////////////////////////////////////////////////////
typedef typename FermionOperatorF::GaugeField GaugeFieldF;
typedef typename FermionOperatorF::GaugeLinkField GaugeLinkFieldF;
typedef typename FermionOperatorD::GaugeField GaugeFieldD;
typedef typename FermionOperatorD::GaugeLinkField GaugeLinkFieldD;
GridBase * GridPtrF = SinglePrecGrid4;
GridBase * GridPtrD = FermOpD.Umu._grid;
GaugeFieldF U_f (GridPtrF);
GaugeLinkFieldF Umu_f(GridPtrF);
// std::cout << " Dim gauge field "<<GridPtrF->Nd()<<std::endl; // 4d
// std::cout << " Dim gauge field "<<GridPtrD->Nd()<<std::endl; // 4d
////////////////////////////////////////////////////////////////////////////////////
// Moving this to a Clone method of fermion operator would allow to duplicate the
// physics parameters and decrease gauge field copies
////////////////////////////////////////////////////////////////////////////////////
GaugeLinkFieldD Umu_d(GridPtrD);
for(int mu=0;mu<Nd*2;mu++){
Umu_d = PeekIndex<LorentzIndex>(FermOpD.Umu, mu);
precisionChange(Umu_f,Umu_d);
PokeIndex<LorentzIndex>(FermOpF.Umu, Umu_f, mu);
}
pickCheckerboard(Even,FermOpF.UmuEven,FermOpF.Umu);
pickCheckerboard(Odd ,FermOpF.UmuOdd ,FermOpF.Umu);
////////////////////////////////////////////////////////////////////////////////////
// Could test to make sure that LinOpF and LinOpD agree to single prec?
////////////////////////////////////////////////////////////////////////////////////
/*
GridBase *Fgrid = psi._grid;
FieldD tmp2(Fgrid);
FieldD tmp1(Fgrid);
LinOpU.Op(src,tmp1);
LinOpD.Op(src,tmp2);
std::cout << " Double gauge field "<< norm2(FermOpD.Umu)<<std::endl;
std::cout << " Single gauge field "<< norm2(FermOpF.Umu)<<std::endl;
std::cout << " Test of operators "<<norm2(tmp1)<<std::endl;
std::cout << " Test of operators "<<norm2(tmp2)<<std::endl;
tmp1=tmp1-tmp2;
std::cout << " Test of operators diff "<<norm2(tmp1)<<std::endl;
*/
////////////////////////////////////////////////////////////////////////////////////
// Make a mixed precision conjugate gradient
////////////////////////////////////////////////////////////////////////////////////
MixedPrecisionConjugateGradient<FieldD,FieldF> MPCG(Tolerance,MaxInnerIterations,MaxOuterIterations,SinglePrecGrid5,LinOpF,LinOpD);
std::cout << GridLogMessage << "Calling mixed precision Conjugate Gradient" <<std::endl;
MPCG(src,psi);
}
};
}};
int main(int argc, char **argv) {
using namespace Grid;
using namespace Grid::QCD;
Grid_init(&argc, &argv);
int threads = GridThread::GetThreads();
// here make a routine to print all the relevant information on the run
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
// Typedefs to simplify notation
typedef WilsonImplR FermionImplPolicy;
typedef MobiusFermionR FermionAction;
typedef MobiusFermionF FermionActionF;
typedef MobiusEOFAFermionR FermionEOFAAction;
typedef MobiusEOFAFermionF FermionEOFAActionF;
typedef typename FermionAction::FermionField FermionField;
typedef typename FermionActionF::FermionField FermionFieldF;
typedef Grid::XmlReader Serialiser;
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IntegratorParameters MD;
// typedef GenericHMCRunner<LeapFrog> HMCWrapper;
// MD.name = std::string("Leap Frog");
typedef GenericHMCRunner<ForceGradient> HMCWrapper;
MD.name = std::string("Force Gradient");
// typedef GenericHMCRunner<MinimumNorm2> HMCWrapper;
// MD.name = std::string("MinimumNorm2");
MD.MDsteps = 6;
MD.trajL = 1.0;
HMCparameters HMCparams;
HMCparams.StartTrajectory = 590;
HMCparams.Trajectories = 1000;
HMCparams.NoMetropolisUntil= 0;
// "[HotStart, ColdStart, TepidStart, CheckpointStart]\n";
// HMCparams.StartingType =std::string("ColdStart");
HMCparams.StartingType =std::string("CheckpointStart");
HMCparams.MD = MD;
HMCWrapper TheHMC(HMCparams);
// Grid from the command line arguments --grid and --mpi
TheHMC.Resources.AddFourDimGrid("gauge"); // use default simd lanes decomposition
CheckpointerParameters CPparams;
CPparams.config_prefix = "ckpoint_EODWF_lat";
CPparams.rng_prefix = "ckpoint_EODWF_rng";
CPparams.saveInterval = 10;
CPparams.format = "IEEE64BIG";
TheHMC.Resources.LoadNerscCheckpointer(CPparams);
RNGModuleParameters RNGpar;
RNGpar.serial_seeds = "1 2 3 4 5";
RNGpar.parallel_seeds = "6 7 8 9 10";
TheHMC.Resources.SetRNGSeeds(RNGpar);
// Construct observables
// here there is too much indirection
typedef PlaquetteMod<HMCWrapper::ImplPolicy> PlaqObs;
TheHMC.Resources.AddObservable<PlaqObs>();
//////////////////////////////////////////////
const int Ls = 16;
Real beta = 2.13;
Real light_mass = 0.01;
Real strange_mass = 0.04;
Real pv_mass = 1.0;
RealD M5 = 1.8;
RealD b = 1.0;
RealD c = 0.0;
std::vector<Real> hasenbusch({ 0.1, 0.3, 0.6 });
auto GridPtr = TheHMC.Resources.GetCartesian();
auto GridRBPtr = TheHMC.Resources.GetRBCartesian();
auto FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,GridPtr);
auto FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,GridPtr);
std::vector<int> latt = GridDefaultLatt();
std::vector<int> mpi = GridDefaultMpi();
std::vector<int> simdF = GridDefaultSimd(Nd,vComplexF::Nsimd());
std::vector<int> simdD = GridDefaultSimd(Nd,vComplexD::Nsimd());
auto GridPtrF = SpaceTimeGrid::makeFourDimGrid(latt,simdF,mpi);
auto GridRBPtrF = SpaceTimeGrid::makeFourDimRedBlackGrid(GridPtrF);
auto FGridF = SpaceTimeGrid::makeFiveDimGrid(Ls,GridPtrF);
auto FrbGridF = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,GridPtrF);
IwasakiGaugeActionR GaugeAction(beta);
// temporarily need a gauge field
LatticeGaugeField U(GridPtr);
LatticeGaugeFieldF UF(GridPtrF);
// These lines are unecessary if BC are all periodic
std::vector<Complex> boundary = {1,1,1,-1};
FermionAction::ImplParams Params(boundary);
FermionActionF::ImplParams ParamsF(boundary);
double ActionStoppingCondition = 1e-10;
double DerivativeStoppingCondition = 1e-6;
double MaxCGIterations = 30000;
////////////////////////////////////
// Collect actions
////////////////////////////////////
ActionLevel<HMCWrapper::Field> Level1(1);
ActionLevel<HMCWrapper::Field> Level2(8);
////////////////////////////////////
// Strange action
////////////////////////////////////
typedef SchurDiagMooeeOperator<FermionActionF,FermionFieldF> LinearOperatorF;
typedef SchurDiagMooeeOperator<FermionAction ,FermionField > LinearOperatorD;
typedef SchurDiagMooeeOperator<FermionEOFAActionF,FermionFieldF> LinearOperatorEOFAF;
typedef SchurDiagMooeeOperator<FermionEOFAAction ,FermionField > LinearOperatorEOFAD;
typedef MixedPrecisionConjugateGradientOperatorFunction<MobiusFermionD,MobiusFermionF,LinearOperatorD,LinearOperatorF> MxPCG;
typedef MixedPrecisionConjugateGradientOperatorFunction<MobiusEOFAFermionD,MobiusEOFAFermionF,LinearOperatorEOFAD,LinearOperatorEOFAF> MxPCG_EOFA;
// DJM: setup for EOFA ratio (Mobius)
OneFlavourRationalParams OFRp;
OFRp.lo = 0.1;
OFRp.hi = 25.0;
OFRp.MaxIter = 10000;
OFRp.tolerance= 1.0e-9;
OFRp.degree = 14;
OFRp.precision= 50;
MobiusEOFAFermionR Strange_Op_L (U , *FGrid , *FrbGrid , *GridPtr , *GridRBPtr , strange_mass, strange_mass, pv_mass, 0.0, -1, M5, b, c);
MobiusEOFAFermionF Strange_Op_LF(UF, *FGridF, *FrbGridF, *GridPtrF, *GridRBPtrF, strange_mass, strange_mass, pv_mass, 0.0, -1, M5, b, c);
MobiusEOFAFermionR Strange_Op_R (U , *FGrid , *FrbGrid , *GridPtr , *GridRBPtr , pv_mass, strange_mass, pv_mass, -1.0, 1, M5, b, c);
MobiusEOFAFermionF Strange_Op_RF(UF, *FGridF, *FrbGridF, *GridPtrF, *GridRBPtrF, pv_mass, strange_mass, pv_mass, -1.0, 1, M5, b, c);
ConjugateGradient<FermionField> ActionCG(ActionStoppingCondition,MaxCGIterations);
ConjugateGradient<FermionField> DerivativeCG(DerivativeStoppingCondition,MaxCGIterations);
#ifdef MIXED_PRECISION
const int MX_inner = 1000;
// Mixed precision EOFA
LinearOperatorEOFAD Strange_LinOp_L (Strange_Op_L);
LinearOperatorEOFAD Strange_LinOp_R (Strange_Op_R);
LinearOperatorEOFAF Strange_LinOp_LF(Strange_Op_LF);
LinearOperatorEOFAF Strange_LinOp_RF(Strange_Op_RF);
MxPCG_EOFA ActionCGL(ActionStoppingCondition,
MX_inner,
MaxCGIterations,
GridPtrF,
FrbGridF,
Strange_Op_LF,Strange_Op_L,
Strange_LinOp_LF,Strange_LinOp_L);
MxPCG_EOFA DerivativeCGL(DerivativeStoppingCondition,
MX_inner,
MaxCGIterations,
GridPtrF,
FrbGridF,
Strange_Op_LF,Strange_Op_L,
Strange_LinOp_LF,Strange_LinOp_L);
MxPCG_EOFA ActionCGR(ActionStoppingCondition,
MX_inner,
MaxCGIterations,
GridPtrF,
FrbGridF,
Strange_Op_RF,Strange_Op_R,
Strange_LinOp_RF,Strange_LinOp_R);
MxPCG_EOFA DerivativeCGR(DerivativeStoppingCondition,
MX_inner,
MaxCGIterations,
GridPtrF,
FrbGridF,
Strange_Op_RF,Strange_Op_R,
Strange_LinOp_RF,Strange_LinOp_R);
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy>
EOFA(Strange_Op_L, Strange_Op_R,
ActionCG,
ActionCGL, ActionCGR,
DerivativeCGL, DerivativeCGR,
OFRp, true);
#else
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy>
EOFA(Strange_Op_L, Strange_Op_R,
ActionCG, ActionCG,
DerivativeCG, DerivativeCG,
OFRp, true);
#endif
Level1.push_back(&EOFA);
////////////////////////////////////
// up down action
////////////////////////////////////
std::vector<Real> light_den;
std::vector<Real> light_num;
int n_hasenbusch = hasenbusch.size();
light_den.push_back(light_mass);
for(int h=0;h<n_hasenbusch;h++){
light_den.push_back(hasenbusch[h]);
light_num.push_back(hasenbusch[h]);
}
light_num.push_back(pv_mass);
//////////////////////////////////////////////////////////////
// Forced to replicate the MxPCG and DenominatorsF etc.. because
// there is no convenient way to "Clone" physics params from double op
// into single op for any operator pair.
// Same issue prevents using MxPCG in the Heatbath step
//////////////////////////////////////////////////////////////
std::vector<FermionAction *> Numerators;
std::vector<FermionAction *> Denominators;
std::vector<TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy> *> Quotients;
std::vector<MxPCG *> ActionMPCG;
std::vector<MxPCG *> MPCG;
std::vector<FermionActionF *> DenominatorsF;
std::vector<LinearOperatorD *> LinOpD;
std::vector<LinearOperatorF *> LinOpF;
for(int h=0;h<n_hasenbusch+1;h++){
std::cout << GridLogMessage << " 2f quotient Action "<< light_num[h] << " / " << light_den[h]<< std::endl;
Numerators.push_back (new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_num[h],M5,b,c, Params));
Denominators.push_back(new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_den[h],M5,b,c, Params));
#ifdef MIXED_PRECISION
////////////////////////////////////////////////////////////////////////////
// Mixed precision CG for 2f force
////////////////////////////////////////////////////////////////////////////
DenominatorsF.push_back(new FermionActionF(UF,*FGridF,*FrbGridF,*GridPtrF,*GridRBPtrF,light_den[h],M5,b,c, ParamsF));
LinOpD.push_back(new LinearOperatorD(*Denominators[h]));
LinOpF.push_back(new LinearOperatorF(*DenominatorsF[h]));
MPCG.push_back(new MxPCG(DerivativeStoppingCondition,
MX_inner,
MaxCGIterations,
GridPtrF,
FrbGridF,
*DenominatorsF[h],*Denominators[h],
*LinOpF[h], *LinOpD[h]) );
ActionMPCG.push_back(new MxPCG(ActionStoppingCondition,
MX_inner,
MaxCGIterations,
GridPtrF,
FrbGridF,
*DenominatorsF[h],*Denominators[h],
*LinOpF[h], *LinOpD[h]) );
// Heatbath not mixed yet. As inverts numerators not so important as raised mass.
Quotients.push_back (new TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy>(*Numerators[h],*Denominators[h],*MPCG[h],*ActionMPCG[h],ActionCG));
#else
////////////////////////////////////////////////////////////////////////////
// Standard CG for 2f force
////////////////////////////////////////////////////////////////////////////
Quotients.push_back (new TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy>(*Numerators[h],*Denominators[h],DerivativeCG,ActionCG));
#endif
}
for(int h=0;h<n_hasenbusch+1;h++){
Level1.push_back(Quotients[h]);
}
/////////////////////////////////////////////////////////////
// Gauge action
/////////////////////////////////////////////////////////////
Level2.push_back(&GaugeAction);
TheHMC.TheAction.push_back(Level1);
TheHMC.TheAction.push_back(Level2);
std::cout << GridLogMessage << " Action complete "<< std::endl;
/////////////////////////////////////////////////////////////
// HMC parameters are serialisable
std::cout << GridLogMessage << " Running the HMC "<< std::endl;
TheHMC.Run(); // no smearing
Grid_finalize();
} // main

198
HMC/Mobius2p1fRHMC.cc Normal file
View File

@ -0,0 +1,198 @@
/*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid
Source file: ./tests/Test_hmc_EODWFRatio.cc
Copyright (C) 2015-2016
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
Author: Guido Cossu <guido.cossu@ed.ac.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/
/* END LEGAL */
#include <Grid/Grid.h>
int main(int argc, char **argv) {
using namespace Grid;
using namespace Grid::QCD;
Grid_init(&argc, &argv);
int threads = GridThread::GetThreads();
// here make a routine to print all the relevant information on the run
std::cout << GridLogMessage << "Grid is setup to use " << threads << " threads" << std::endl;
// Typedefs to simplify notation
typedef WilsonImplR FermionImplPolicy;
typedef MobiusFermionR FermionAction;
typedef typename FermionAction::FermionField FermionField;
typedef Grid::XmlReader Serialiser;
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IntegratorParameters MD;
// typedef GenericHMCRunner<LeapFrog> HMCWrapper;
// MD.name = std::string("Leap Frog");
// typedef GenericHMCRunner<ForceGradient> HMCWrapper;
// MD.name = std::string("Force Gradient");
typedef GenericHMCRunner<MinimumNorm2> HMCWrapper;
MD.name = std::string("MinimumNorm2");
MD.MDsteps = 20;
MD.trajL = 1.0;
HMCparameters HMCparams;
HMCparams.StartTrajectory = 30;
HMCparams.Trajectories = 200;
HMCparams.NoMetropolisUntil= 0;
// "[HotStart, ColdStart, TepidStart, CheckpointStart]\n";
// HMCparams.StartingType =std::string("ColdStart");
HMCparams.StartingType =std::string("CheckpointStart");
HMCparams.MD = MD;
HMCWrapper TheHMC(HMCparams);
// Grid from the command line arguments --grid and --mpi
TheHMC.Resources.AddFourDimGrid("gauge"); // use default simd lanes decomposition
CheckpointerParameters CPparams;
CPparams.config_prefix = "ckpoint_EODWF_lat";
CPparams.rng_prefix = "ckpoint_EODWF_rng";
CPparams.saveInterval = 10;
CPparams.format = "IEEE64BIG";
TheHMC.Resources.LoadNerscCheckpointer(CPparams);
RNGModuleParameters RNGpar;
RNGpar.serial_seeds = "1 2 3 4 5";
RNGpar.parallel_seeds = "6 7 8 9 10";
TheHMC.Resources.SetRNGSeeds(RNGpar);
// Construct observables
// here there is too much indirection
typedef PlaquetteMod<HMCWrapper::ImplPolicy> PlaqObs;
TheHMC.Resources.AddObservable<PlaqObs>();
//////////////////////////////////////////////
const int Ls = 16;
Real beta = 2.13;
Real light_mass = 0.01;
Real strange_mass = 0.04;
Real pv_mass = 1.0;
RealD M5 = 1.8;
RealD b = 1.0;
RealD c = 0.0;
// FIXME:
// Same in MC and MD
// Need to mix precision too
OneFlavourRationalParams OFRp;
OFRp.lo = 4.0e-3;
OFRp.hi = 30.0;
OFRp.MaxIter = 10000;
OFRp.tolerance= 1.0e-10;
OFRp.degree = 16;
OFRp.precision= 50;
std::vector<Real> hasenbusch({ 0.1 });
auto GridPtr = TheHMC.Resources.GetCartesian();
auto GridRBPtr = TheHMC.Resources.GetRBCartesian();
auto FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,GridPtr);
auto FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,GridPtr);
IwasakiGaugeActionR GaugeAction(beta);
// temporarily need a gauge field
LatticeGaugeField U(GridPtr);
// These lines are unecessary if BC are all periodic
std::vector<Complex> boundary = {1,1,1,-1};
FermionAction::ImplParams Params(boundary);
double StoppingCondition = 1e-10;
double MaxCGIterations = 30000;
ConjugateGradient<FermionField> CG(StoppingCondition,MaxCGIterations);
////////////////////////////////////
// Collect actions
////////////////////////////////////
ActionLevel<HMCWrapper::Field> Level1(1);
ActionLevel<HMCWrapper::Field> Level2(4);
////////////////////////////////////
// Strange action
////////////////////////////////////
// FermionAction StrangeOp(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_mass,M5,b,c, Params);
// DomainWallEOFAFermionR Strange_Op_L(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mf, mf, mb, shift_L, pm, M5);
// DomainWallEOFAFermionR Strange_Op_R(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mb, mf, mb, shift_R, pm, M5);
// ExactOneFlavourRatioPseudoFermionAction EOFA(Strange_Op_L,Strange_Op_R,CG,ofp, false);
FermionAction StrangeOp (U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,strange_mass,M5,b,c, Params);
FermionAction StrangePauliVillarsOp(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,pv_mass, M5,b,c, Params);
OneFlavourEvenOddRatioRationalPseudoFermionAction<FermionImplPolicy> StrangePseudoFermion(StrangePauliVillarsOp,StrangeOp,OFRp);
Level1.push_back(&StrangePseudoFermion);
////////////////////////////////////
// up down action
////////////////////////////////////
std::vector<Real> light_den;
std::vector<Real> light_num;
int n_hasenbusch = hasenbusch.size();
light_den.push_back(light_mass);
for(int h=0;h<n_hasenbusch;h++){
light_den.push_back(hasenbusch[h]);
light_num.push_back(hasenbusch[h]);
}
light_num.push_back(pv_mass);
std::vector<FermionAction *> Numerators;
std::vector<FermionAction *> Denominators;
std::vector<TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy> *> Quotients;
for(int h=0;h<n_hasenbusch+1;h++){
std::cout << GridLogMessage << " 2f quotient Action "<< light_num[h] << " / " << light_den[h]<< std::endl;
Numerators.push_back (new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_num[h],M5,b,c, Params));
Denominators.push_back(new FermionAction(U,*FGrid,*FrbGrid,*GridPtr,*GridRBPtr,light_den[h],M5,b,c, Params));
Quotients.push_back (new TwoFlavourEvenOddRatioPseudoFermionAction<FermionImplPolicy>(*Numerators[h],*Denominators[h],CG,CG));
}
for(int h=0;h<n_hasenbusch+1;h++){
Level1.push_back(Quotients[h]);
}
/////////////////////////////////////////////////////////////
// Gauge action
/////////////////////////////////////////////////////////////
Level2.push_back(&GaugeAction);
TheHMC.TheAction.push_back(Level1);
TheHMC.TheAction.push_back(Level2);
std::cout << GridLogMessage << " Action complete "<< std::endl;
/////////////////////////////////////////////////////////////
// HMC parameters are serialisable
std::cout << GridLogMessage << " Running the HMC "<< std::endl;
TheHMC.Run(); // no smearing
Grid_finalize();
} // main

109
HMC/README Normal file
View File

@ -0,0 +1,109 @@
********************************************************************
TODO:
********************************************************************
i) Got mixed precision in 2f and EOFA force and action solves.
But need mixed precision in the heatbath solve. Best for Fermop to have a "clone" method, to
reduce the number of solver and action objects. Needed ideally for the EOFA heatbath.
15% perhaps
Combine with 2x trajectory length?
ii) Rational on EOFA HB -- relax order
-- Test the approx as per David email
Resume / roll.sh
----------------------------------------------------------------
- 16^3 Currently 10 traj per hour
- EOFA use a different derivative solver from action solver
- EOFA fix Davids hack to the SchurRedBlack guessing
*** Reduce precision/tolerance in EOFA with second CG param. (10% speed up)
*** Force gradient - reduced precision solve for the gradient (4/3x speedup)
*** Need a plan for gauge field update for mixed precision in HMC (2x speed up)
-- Store the single prec action operator.
-- Clone the gauge field from the operator function argument.
-- Build the mixed precision operator dynamically from the passed operator and single prec clone.
*** Mixed precision CG into EOFA portion
*** Further reduce precision in forces to 10^-6 ?
*** Overall: a 3x or so is still possible => 500s -> 160s and 20 traj per hour on 16^3.
- Use mixed precision CG in HMC
- SchurRedBlack.h: stop use of operator function; use LinearOperator or similar instead.
- Or make an OperatorFunction for mixed precision as a wrapper
********************************************************************
* Signed off 2+1f HMC with Hasenbush and strange RHMC 16^3 x 32 DWF Ls=16 Plaquette 0.5883 ish
* Signed off 2+1f HMC with Hasenbush and strange EOFA 16^3 x 32 DWF Ls=16 Plaquette 0.5883 ish
* Wilson plaquette cross checked against CPS and literature GwilsonFnone
********************************************************************
********************************************************************
* RHMC: Timesteps & eigenranges matched from previous CPS 16^3 x 32 runs:
********************************************************************
****
Strange (m=0.04) has eigenspan
****
16^3 done as 1+1+1 with separate PV's.
/dirac1/archive/QCDOC/host/QCDDWF/DWF/2+1f/16nt32/IWASAKI/b2.13/ls16/M1_8/ms0.04/mu0.01/rhmc_multitimescale/evol5/work
****
2+1f 16^3 - [ 4e^-4, 2.42 ] for strange
****
24^3 done as 1+1+1 at strange, and single quotient https://arxiv.org/pdf/0804.0473.pdf Eq 83,
****
double lambda_low = 4.0000000000000002e-04 <- strange
double lambda_low = 1.0000000000000000e-02 <- pauli villars
And high = 2.5
Array bsn_mass[3] = {
double bsn_mass[0] = 1.0000000000000000e+00
double bsn_mass[1] = 1.0000000000000000e+00
double bsn_mass[2] = 1.0000000000000000e+00
}
Array frm_mass[3] = {
double frm_mass[0] = 4.0000000000000001e-02
double frm_mass[1] = 4.0000000000000001e-02
double frm_mass[2] = 4.0000000000000001e-02
}
***
32^3
/dirac1/archive/QCDOC/host/QCDDWF/DWF/2+1f/32nt64/IWASAKI/b2.25/ls16/M1_8/ms0.03/mu0.004/evol6/work
***
Similar det scheme
double lambda_low = 4.0000000000000002e-04
double lambda_low = 1.0000000000000000e-02
Array bsn_mass[3] = {
double bsn_mass[0] = 1.0000000000000000e+00
double bsn_mass[1] = 1.0000000000000000e+00
double bsn_mass[2] = 1.0000000000000000e+00
}
Array frm_mass[3] = {
double frm_mass[0] = 3.0000000000000002e-02
double frm_mass[1] = 3.0000000000000002e-02
double frm_mass[2] = 3.0000000000000002e-02
}
********************************************************************
* Grid: Power method bounds check
********************************************************************
- Finding largest eigenvalue approx 25 not 2.5
- Conventions:
Grid MpcDagMpc based on:
(Moo-Moe Mee^-1 Meo)^dag(Moo-Moe Mee^-1 Meo)
- with Moo = 5-M5 = 3.2
- CPS use(d) Moo = 1
- Eigenrange in Grid is 3.2^2 rescaled so factor of 10 accounted for

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/A2AMatrix.hpp Source file: Hadrons/A2AMatrix.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Peter Boyle <paboyle@ph.ed.ac.uk> Author: Peter Boyle <paboyle@ph.ed.ac.uk>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/A2AVectors.hpp Source file: Hadrons/A2AVectors.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: fionnoh <fionnoh@gmail.com> Author: fionnoh <fionnoh@gmail.com>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Application.cc Source file: Hadrons/Application.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
@ -31,7 +31,7 @@ See the full license in the file "LICENSE" in the top level distribution directo
#include <Hadrons/Modules.hpp> #include <Hadrons/Modules.hpp>
using namespace Grid; using namespace Grid;
using namespace QCD;
using namespace Hadrons; using namespace Hadrons;
#define BIG_SEP "================" #define BIG_SEP "================"
@ -48,6 +48,9 @@ Application::Application(void)
{ {
initLogger(); initLogger();
auto dim = GridDefaultLatt(), mpi = GridDefaultMpi(), loc(dim); auto dim = GridDefaultLatt(), mpi = GridDefaultMpi(), loc(dim);
if (dim.size())
{
locVol_ = 1; locVol_ = 1;
for (unsigned int d = 0; d < dim.size(); ++d) for (unsigned int d = 0; d < dim.size(); ++d)
{ {
@ -71,6 +74,7 @@ Application::Application(void)
LOG(Message) << "Schur decomposition : " << MACOUTS(HADRONS_DEFAULT_SCHUR) << std::endl; LOG(Message) << "Schur decomposition : " << MACOUTS(HADRONS_DEFAULT_SCHUR) << std::endl;
LOG(Message) << std::endl; LOG(Message) << std::endl;
} }
}
Application::Application(const Application::GlobalPar &par) Application::Application(const Application::GlobalPar &par)
: Application() : Application()
@ -114,7 +118,22 @@ void Application::run(void)
vm().setRunId(getPar().runId); vm().setRunId(getPar().runId);
vm().printContent(); vm().printContent();
env().printContent(); env().printContent();
if (getPar().saveSchedule or getPar().scheduleFile.empty())
{
schedule(); schedule();
if (getPar().saveSchedule)
{
std::string filename;
filename = (getPar().scheduleFile.empty()) ?
"hadrons.sched" : getPar().scheduleFile;
saveSchedule(filename);
}
}
else
{
loadSchedule(getPar().scheduleFile);
}
printSchedule(); printSchedule();
if (!getPar().graphFile.empty()) if (!getPar().graphFile.empty())
{ {
@ -161,12 +180,13 @@ void Application::parseParameterFile(const std::string parameterFileName)
pop(reader); pop(reader);
} }
void Application::saveParameterFile(const std::string parameterFileName) void Application::saveParameterFile(const std::string parameterFileName, unsigned int prec)
{ {
LOG(Message) << "Saving application to '" << parameterFileName << "'..." << std::endl; LOG(Message) << "Saving application to '" << parameterFileName << "'..." << std::endl;
if (env().getGrid()->IsBoss()) if (env().getGrid()->IsBoss())
{ {
XmlWriter writer(parameterFileName); XmlWriter writer(parameterFileName);
writer.setPrecision(prec);
ObjectId id; ObjectId id;
const unsigned int nMod = vm().getNModule(); const unsigned int nMod = vm().getNModule();

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Application.hpp Source file: Hadrons/Application.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
@ -57,6 +57,8 @@ public:
VirtualMachine::GeneticPar, genetic, VirtualMachine::GeneticPar, genetic,
std::string, runId, std::string, runId,
std::string, graphFile, std::string, graphFile,
std::string, scheduleFile,
bool, saveSchedule,
int, parallelWriteMaxRetry); int, parallelWriteMaxRetry);
GlobalPar(void): parallelWriteMaxRetry{-1} {} GlobalPar(void): parallelWriteMaxRetry{-1} {}
}; };
@ -79,7 +81,7 @@ public:
void run(void); void run(void);
// XML parameter file I/O // XML parameter file I/O
void parseParameterFile(const std::string parameterFileName); void parseParameterFile(const std::string parameterFileName);
void saveParameterFile(const std::string parameterFileName); void saveParameterFile(const std::string parameterFileName, unsigned int prec=15);
// schedule computation // schedule computation
void schedule(void); void schedule(void);
void saveSchedule(const std::string filename); void saveSchedule(const std::string filename);

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MScalar/ScalarVP.cc Source file: Hadrons/Archive/Modules/ScalarVP.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: James Harrison <jch1g10@soton.ac.uk> Author: James Harrison <jch1g10@soton.ac.uk>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MScalar/ScalarVP.hpp Source file: Hadrons/Archive/Modules/ScalarVP.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: James Harrison <jch1g10@soton.ac.uk> Author: James Harrison <jch1g10@soton.ac.uk>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MUtilities/TestSeqConserved.cc Source file: Hadrons/Archive/Modules/TestSeqConserved.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MUtilities/TestSeqConserved.hpp Source file: Hadrons/Archive/Modules/TestSeqConserved.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MUtilities/TestSeqGamma.cc Source file: Hadrons/Archive/Modules/TestSeqGamma.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MUtilities/TestSeqGamma.hpp Source file: Hadrons/Archive/Modules/TestSeqGamma.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MScalar/VPCounterTerms.cc Source file: Hadrons/Archive/Modules/VPCounterTerms.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: James Harrison <jch1g10@soton.ac.uk> Author: James Harrison <jch1g10@soton.ac.uk>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MScalar/VPCounterTerms.hpp Source file: Hadrons/Archive/Modules/VPCounterTerms.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: James Harrison <jch1g10@soton.ac.uk> Author: James Harrison <jch1g10@soton.ac.uk>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MContraction/WardIdentity.cc Source file: Hadrons/Archive/Modules/WardIdentity.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MContraction/WardIdentity.hpp Source file: Hadrons/Archive/Modules/WardIdentity.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MContraction/WeakHamiltonian.hpp Source file: Hadrons/Archive/Modules/WeakHamiltonian.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MContraction/WeakHamiltonianEye.cc Source file: Hadrons/Archive/Modules/WeakHamiltonianEye.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp Source file: Hadrons/Archive/Modules/WeakHamiltonianEye.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MContraction/WeakHamiltonianNonEye.cc Source file: Hadrons/Archive/Modules/WeakHamiltonianNonEye.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MContraction/WeakHamiltonianNonEye.hpp Source file: Hadrons/Archive/Modules/WeakHamiltonianNonEye.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MContraction/WeakNeutral4ptDisc.cc Source file: Hadrons/Archive/Modules/WeakNeutral4ptDisc.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -2,9 +2,9 @@
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp Source file: Hadrons/Archive/Modules/WeakNeutral4ptDisc.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>

View File

@ -4,10 +4,11 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/DilutedNoise.hpp Source file: Hadrons/DilutedNoise.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk> Author: Vera Guelpers <Vera.Guelpers@ed.ac.uk>
Author: Vera Guelpers <vmg1n14@soton.ac.uk>
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/DiskVector.hpp Source file: Hadrons/DiskVector.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
@ -395,12 +395,26 @@ void DiskVectorBase<T>::cacheInsert(const unsigned int i, const T &obj) const
auto &freeInd = *freePtr_; auto &freeInd = *freePtr_;
auto &loads = *loadsPtr_; auto &loads = *loadsPtr_;
// cache miss, evict and store
if (index.find(i) == index.end())
{
evict(); evict();
index[i] = freeInd.top(); index[i] = freeInd.top();
freeInd.pop(); freeInd.pop();
cache[index.at(i)] = obj; cache[index.at(i)] = obj;
loads.push_back(i); loads.push_back(i);
modified[index.at(i)] = false; modified[index.at(i)] = false;
}
// cache hit, modify current value
else
{
auto pos = std::find(loads.begin(), loads.end(), i);
cache[index.at(i)] = obj;
modified[index.at(i)] = true;
loads.erase(pos);
loads.push_back(i);
}
#ifdef DV_DEBUG #ifdef DV_DEBUG
std::string msg; std::string msg;

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/EigenPack.hpp Source file: Hadrons/EigenPack.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
@ -309,6 +309,8 @@ class CoarseEigenPack: public EigenPack<FineF, FineFIo>
{ {
public: public:
typedef CoarseF CoarseField; typedef CoarseF CoarseField;
typedef CoarseFIo CoarseFieldIo;
public:
std::vector<CoarseF> evecCoarse; std::vector<CoarseF> evecCoarse;
std::vector<RealD> evalCoarse; std::vector<RealD> evalCoarse;
public: public:

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Environment.cc Source file: Hadrons/Environment.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
@ -45,13 +45,11 @@ Environment::Environment(void)
{ {
dim_ = GridDefaultLatt().toVector(); dim_ = GridDefaultLatt().toVector();
nd_ = dim_.size(); nd_ = dim_.size();
createGrid<vComplex>(1);
vol_ = 1.; vol_ = 1.;
for (auto d: dim_) for (auto d: dim_)
{ {
vol_ *= d; vol_ *= d;
} }
rng4d_.reset(new GridParallelRNG(getGrid()));
} }
// grids /////////////////////////////////////////////////////////////////////// // grids ///////////////////////////////////////////////////////////////////////
@ -76,8 +74,13 @@ double Environment::getVolume(void) const
} }
// random number generator ///////////////////////////////////////////////////// // random number generator /////////////////////////////////////////////////////
GridParallelRNG * Environment::get4dRng(void) const GridParallelRNG * Environment::get4dRng(void)
{ {
if (rng4d_ == nullptr)
{
rng4d_.reset(new GridParallelRNG(getGrid()));
}
return rng4d_.get(); return rng4d_.get();
} }

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Environment.hpp Source file: Hadrons/Environment.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
@ -113,7 +113,7 @@ public:
unsigned int getNd(void) const; unsigned int getNd(void) const;
double getVolume(void) const; double getVolume(void) const;
// random number generator // random number generator
GridParallelRNG * get4dRng(void) const; GridParallelRNG * get4dRng(void);
// general memory management // general memory management
void addObject(const std::string name, void addObject(const std::string name,
const int moduleAddress = -1); const int moduleAddress = -1);
@ -182,7 +182,7 @@ private:
std::map<CoarseGridKey, GridPt> gridCoarse5d_; std::map<CoarseGridKey, GridPt> gridCoarse5d_;
unsigned int nd_; unsigned int nd_;
// random number generator // random number generator
RngPt rng4d_; RngPt rng4d_{nullptr};
// object store // object store
std::vector<ObjInfo> object_; std::vector<ObjInfo> object_;
std::map<std::string, unsigned int> objectAddress_; std::map<std::string, unsigned int> objectAddress_;

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Exceptions.cc Source file: Hadrons/Exceptions.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Exceptions.hpp Source file: Hadrons/Exceptions.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Factory.hpp Source file: Hadrons/Factory.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/GeneticScheduler.hpp Source file: Hadrons/GeneticScheduler.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Global.cc Source file: Hadrons/Global.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Global.hpp Source file: Hadrons/Global.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
Author: Lanny91 <andrew.lawson@gmail.com> Author: Lanny91 <andrew.lawson@gmail.com>
@ -44,6 +44,8 @@ See the full license in the file "LICENSE" in the top level distribution directo
#define DEFAULT_ASCII_PREC 16 #define DEFAULT_ASCII_PREC 16
#endif #endif
#define ARG(...) __VA_ARGS__
/* the 'using Grid::operator<<;' statement prevents a very nasty compilation /* the 'using Grid::operator<<;' statement prevents a very nasty compilation
* error with GCC 5 (clang & GCC 6 compile fine without it). * error with GCC 5 (clang & GCC 6 compile fine without it).
*/ */
@ -100,7 +102,9 @@ BEGIN_HADRONS_NAMESPACE
typedef typename Impl::Field ScalarField##suffix;\ typedef typename Impl::Field ScalarField##suffix;\
typedef typename Impl::PropagatorField PropagatorField##suffix;\ typedef typename Impl::PropagatorField PropagatorField##suffix;\
typedef typename Impl::SitePropagator::scalar_object SitePropagator##suffix;\ typedef typename Impl::SitePropagator::scalar_object SitePropagator##suffix;\
typedef std::vector<SitePropagator##suffix> SlicedPropagator##suffix; typedef typename Impl::ComplexField ComplexField##suffix;\
typedef std::vector<SitePropagator##suffix> SlicedPropagator##suffix;\
typedef std::vector<typename ComplexField##suffix::vector_object::scalar_object> SlicedComplex##suffix;
#define FERM_TYPE_ALIASES(FImpl, suffix)\ #define FERM_TYPE_ALIASES(FImpl, suffix)\
BASIC_TYPE_ALIASES(FImpl, suffix);\ BASIC_TYPE_ALIASES(FImpl, suffix);\
@ -108,7 +112,7 @@ typedef FermionOperator<FImpl> FMat##suffix;\
typedef typename FImpl::FermionField FermionField##suffix;\ typedef typename FImpl::FermionField FermionField##suffix;\
typedef typename FImpl::GaugeField GaugeField##suffix;\ typedef typename FImpl::GaugeField GaugeField##suffix;\
typedef typename FImpl::DoubledGaugeField DoubledGaugeField##suffix;\ typedef typename FImpl::DoubledGaugeField DoubledGaugeField##suffix;\
typedef typename FImpl::ComplexField ComplexField##suffix; typedef Lattice<iSpinMatrix<typename FImpl::Simd>> SpinMatrixField##suffix;
#define GAUGE_TYPE_ALIASES(GImpl, suffix)\ #define GAUGE_TYPE_ALIASES(GImpl, suffix)\
typedef typename GImpl::GaugeField GaugeField##suffix; typedef typename GImpl::GaugeField GaugeField##suffix;
@ -262,6 +266,15 @@ void tokenReplace(std::string &str, const std::string token,
} }
} }
// generic correlator class
template <typename Metadata, typename Scalar = Complex>
struct Correlator: Serializable
{
GRID_SERIALIZABLE_CLASS_MEMBERS(ARG(Correlator<Metadata, Scalar>),
Metadata, info,
std::vector<Complex>, corr);
};
END_HADRONS_NAMESPACE END_HADRONS_NAMESPACE
#include <Hadrons/Exceptions.hpp> #include <Hadrons/Exceptions.hpp>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Graph.hpp Source file: Hadrons/Graph.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Module.cc Source file: Hadrons/Module.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Module.hpp Source file: Hadrons/Module.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>
@ -65,7 +65,6 @@ static ns##mod##ModuleRegistrar ns##mod##ModuleRegistrarInstance;
extern template class base;\ extern template class base;\
MODULE_REGISTER(mod, ARG(base), ns); MODULE_REGISTER(mod, ARG(base), ns);
#define ARG(...) __VA_ARGS__
#define HADRONS_MACRO_REDIRECT_12(arg1, arg2, macro, ...) macro #define HADRONS_MACRO_REDIRECT_12(arg1, arg2, macro, ...) macro
#define HADRONS_MACRO_REDIRECT_23(arg1, arg2, arg3, macro, ...) macro #define HADRONS_MACRO_REDIRECT_23(arg1, arg2, arg3, macro, ...) macro
@ -78,6 +77,15 @@ env().template getGrid<typename latticeType::vector_type>(Ls)
#define envGetGrid(...)\ #define envGetGrid(...)\
HADRONS_MACRO_REDIRECT_12(__VA_ARGS__, envGetGrid5, envGetGrid4)(__VA_ARGS__) HADRONS_MACRO_REDIRECT_12(__VA_ARGS__, envGetGrid5, envGetGrid4)(__VA_ARGS__)
#define envGetCoarseGrid4(latticeType, blockSize)\
env().template getCoarseGrid<typename latticeType::vector_type>(blockSize)
#define envGetCoarseGrid5(latticeType, blockSize, Ls)\
env().template getCoarseGrid<typename latticeType::vector_type>(blockSize, Ls)
#define envGetCoarseGrid(...)\
HADRONS_MACRO_REDIRECT_23(__VA_ARGS__, envGetCoarseGrid5, envGetCoarseGrid4)(__VA_ARGS__)
#define envGetRbGrid4(latticeType)\ #define envGetRbGrid4(latticeType)\
env().template getRbGrid<typename latticeType::vector_type>() env().template getRbGrid<typename latticeType::vector_type>()

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/ModuleFactory.hpp Source file: Hadrons/ModuleFactory.hpp
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

View File

@ -1,17 +1,18 @@
#include <Hadrons/Modules/MContraction/WeakEye3pt.hpp>
#include <Hadrons/Modules/MContraction/Baryon.hpp> #include <Hadrons/Modules/MContraction/Baryon.hpp>
#include <Hadrons/Modules/MContraction/A2AAslashField.hpp> #include <Hadrons/Modules/MContraction/A2AAslashField.hpp>
#include <Hadrons/Modules/MContraction/A2ALoop.hpp>
#include <Hadrons/Modules/MContraction/A2AMesonField.hpp> #include <Hadrons/Modules/MContraction/A2AMesonField.hpp>
#include <Hadrons/Modules/MContraction/Meson.hpp> #include <Hadrons/Modules/MContraction/Meson.hpp>
#include <Hadrons/Modules/MContraction/WeakHamiltonian.hpp>
#include <Hadrons/Modules/MContraction/WeakHamiltonianNonEye.hpp>
#include <Hadrons/Modules/MContraction/DiscLoop.hpp> #include <Hadrons/Modules/MContraction/DiscLoop.hpp>
#include <Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp>
#include <Hadrons/Modules/MContraction/Gamma3pt.hpp> #include <Hadrons/Modules/MContraction/Gamma3pt.hpp>
#include <Hadrons/Modules/MContraction/WardIdentity.hpp> #include <Hadrons/Modules/MContraction/WeakMesonDecayKl2.hpp>
#include <Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp> #include <Hadrons/Modules/MContraction/WeakNonEye3pt.hpp>
#include <Hadrons/Modules/MFermion/FreeProp.hpp> #include <Hadrons/Modules/MFermion/FreeProp.hpp>
#include <Hadrons/Modules/MFermion/GaugeProp.hpp> #include <Hadrons/Modules/MFermion/GaugeProp.hpp>
#include <Hadrons/Modules/MFermion/EMLepton.hpp>
#include <Hadrons/Modules/MSource/SeqGamma.hpp> #include <Hadrons/Modules/MSource/SeqGamma.hpp>
#include <Hadrons/Modules/MSource/SeqAslash.hpp>
#include <Hadrons/Modules/MSource/Point.hpp> #include <Hadrons/Modules/MSource/Point.hpp>
#include <Hadrons/Modules/MSource/Wall.hpp> #include <Hadrons/Modules/MSource/Wall.hpp>
#include <Hadrons/Modules/MSource/Z2.hpp> #include <Hadrons/Modules/MSource/Z2.hpp>
@ -21,28 +22,23 @@
#include <Hadrons/Modules/MSink/Point.hpp> #include <Hadrons/Modules/MSink/Point.hpp>
#include <Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp> #include <Hadrons/Modules/MSolver/MixedPrecisionRBPrecCG.hpp>
#include <Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp> #include <Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp>
#include <Hadrons/Modules/MSolver/A2AAslashVectors.hpp>
#include <Hadrons/Modules/MSolver/Guesser.hpp> #include <Hadrons/Modules/MSolver/Guesser.hpp>
#include <Hadrons/Modules/MSolver/RBPrecCG.hpp> #include <Hadrons/Modules/MSolver/RBPrecCG.hpp>
#include <Hadrons/Modules/MSolver/A2AVectors.hpp> #include <Hadrons/Modules/MSolver/A2AVectors.hpp>
#include <Hadrons/Modules/MSolver/A2AAslashVectors.hpp>
#include <Hadrons/Modules/MGauge/UnitEm.hpp> #include <Hadrons/Modules/MGauge/UnitEm.hpp>
#include <Hadrons/Modules/MGauge/StoutSmearing.hpp> #include <Hadrons/Modules/MGauge/StoutSmearing.hpp>
#include <Hadrons/Modules/MGauge/Unit.hpp> #include <Hadrons/Modules/MGauge/Unit.hpp>
#include <Hadrons/Modules/MGauge/Electrify.hpp>
#include <Hadrons/Modules/MGauge/Random.hpp> #include <Hadrons/Modules/MGauge/Random.hpp>
#include <Hadrons/Modules/MGauge/GaugeFix.hpp> #include <Hadrons/Modules/MGauge/GaugeFix.hpp>
#include <Hadrons/Modules/MGauge/FundtoHirep.hpp> #include <Hadrons/Modules/MGauge/FundtoHirep.hpp>
#include <Hadrons/Modules/MGauge/StochEm.hpp> #include <Hadrons/Modules/MGauge/StochEm.hpp>
#include <Hadrons/Modules/MGauge/Electrify.hpp>
#include <Hadrons/Modules/MNoise/TimeDilutedSpinColorDiagonal.hpp> #include <Hadrons/Modules/MNoise/TimeDilutedSpinColorDiagonal.hpp>
#include <Hadrons/Modules/MNoise/FullVolumeSpinColorDiagonal.hpp> #include <Hadrons/Modules/MNoise/FullVolumeSpinColorDiagonal.hpp>
#include <Hadrons/Modules/MUtilities/PrecisionCast.hpp> #include <Hadrons/Modules/MUtilities/PrecisionCast.hpp>
#include <Hadrons/Modules/MUtilities/RandomVectors.hpp> #include <Hadrons/Modules/MUtilities/RandomVectors.hpp>
#include <Hadrons/Modules/MUtilities/TestSeqGamma.hpp>
#include <Hadrons/Modules/MUtilities/TestSeqConserved.hpp>
#include <Hadrons/Modules/MLoop/NoiseLoop.hpp>
#include <Hadrons/Modules/MScalar/FreeProp.hpp> #include <Hadrons/Modules/MScalar/FreeProp.hpp>
#include <Hadrons/Modules/MScalar/VPCounterTerms.hpp>
#include <Hadrons/Modules/MScalar/ScalarVP.hpp>
#include <Hadrons/Modules/MScalar/Scalar.hpp> #include <Hadrons/Modules/MScalar/Scalar.hpp>
#include <Hadrons/Modules/MScalar/ChargedProp.hpp> #include <Hadrons/Modules/MScalar/ChargedProp.hpp>
#include <Hadrons/Modules/MNPR/Bilinear.hpp> #include <Hadrons/Modules/MNPR/Bilinear.hpp>
@ -56,7 +52,6 @@
#include <Hadrons/Modules/MAction/ScaledDWF.hpp> #include <Hadrons/Modules/MAction/ScaledDWF.hpp>
#include <Hadrons/Modules/MScalarSUN/StochFreeField.hpp> #include <Hadrons/Modules/MScalarSUN/StochFreeField.hpp>
#include <Hadrons/Modules/MScalarSUN/TwoPointNPR.hpp> #include <Hadrons/Modules/MScalarSUN/TwoPointNPR.hpp>
#include <Hadrons/Modules/MScalarSUN/ShiftProbe.hpp>
#include <Hadrons/Modules/MScalarSUN/Div.hpp> #include <Hadrons/Modules/MScalarSUN/Div.hpp>
#include <Hadrons/Modules/MScalarSUN/TrMag.hpp> #include <Hadrons/Modules/MScalarSUN/TrMag.hpp>
#include <Hadrons/Modules/MScalarSUN/EMT.hpp> #include <Hadrons/Modules/MScalarSUN/EMT.hpp>

View File

@ -4,7 +4,7 @@ Grid physics library, www.github.com/paboyle/Grid
Source file: Hadrons/Modules/MAction/DWF.cc Source file: Hadrons/Modules/MAction/DWF.cc
Copyright (C) 2015-2018 Copyright (C) 2015-2019
Author: Antonin Portelli <antonin.portelli@me.com> Author: Antonin Portelli <antonin.portelli@me.com>

Some files were not shown because too many files have changed in this diff Show More