1
0
mirror of https://github.com/paboyle/Grid.git synced 2024-11-10 07:55:35 +00:00

Merge branch 'temporary-smearing' into develop

This commit is contained in:
Guido Cossu 2016-07-07 14:04:59 +01:00
commit 3c49ddfaa4
49 changed files with 12252 additions and 2854 deletions

BIN
benchmarks/Benchmark_dwf_ntpf Executable file

Binary file not shown.

BIN
benchmarks/Benchmark_zmm Executable file

Binary file not shown.

8277
configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -193,7 +193,7 @@ void Grid_init(int *argc,char ***argv)
std::cout<<GridLogMessage<<"--mpi n.n.n.n : default MPI decomposition"<<std::endl; std::cout<<GridLogMessage<<"--mpi n.n.n.n : default MPI decomposition"<<std::endl;
std::cout<<GridLogMessage<<"--threads n : default number of OMP threads"<<std::endl; std::cout<<GridLogMessage<<"--threads n : default number of OMP threads"<<std::endl;
std::cout<<GridLogMessage<<"--grid n.n.n.n : default Grid size"<<std::endl; std::cout<<GridLogMessage<<"--grid n.n.n.n : default Grid size"<<std::endl;
std::cout<<GridLogMessage<<"--log list : comma separted list of streams from Error,Warning,Message,Performance,Iterative,Integrator,Debug"<<std::endl; std::cout<<GridLogMessage<<"--log list : comma separted list of streams from Error,Warning,Message,Performance,Iterative,Integrator,Debug,Colours"<<std::endl;
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@ -234,24 +234,33 @@ void Grid_init(int *argc,char ***argv)
std::cout<<GridLogMessage<<"\tvComplexD : "<<sizeof(vComplexD)*8 <<"bits ; " <<GridCmdVectorIntToString(GridDefaultSimd(4,vComplexD::Nsimd()))<<std::endl; std::cout<<GridLogMessage<<"\tvComplexD : "<<sizeof(vComplexD)*8 <<"bits ; " <<GridCmdVectorIntToString(GridDefaultSimd(4,vComplexD::Nsimd()))<<std::endl;
} }
std::string COL_RED = GridLogColours.colour["RED"];
std::string COL_PURPLE = GridLogColours.colour["PURPLE"];
std::string COL_BLACK = GridLogColours.colour["BLACK"];
std::string COL_GREEN = GridLogColours.colour["GREEN"];
std::string COL_BLUE = GridLogColours.colour["BLUE"];
std::string COL_YELLOW = GridLogColours.colour["YELLOW"];
std::string COL_BACKGROUND = GridLogColours.colour["NORMAL"];
std::cout <<std::endl; std::cout <<std::endl;
std::cout << "__|__|__|__|__|__|__|__|__|__|__|__|__|__|__"<<std::endl; std::cout <<COL_RED << "__|__|__|__|__"<< "|__|__|_"<<COL_PURPLE<<"_|__|__|"<< "__|__|__|__|__"<<std::endl;
std::cout << "__|__|__|__|__|__|__|__|__|__|__|__|__|__|__"<<std::endl; std::cout <<COL_RED << "__|__|__|__|__"<< "|__|__|_"<<COL_PURPLE<<"_|__|__|"<< "__|__|__|__|__"<<std::endl;
std::cout << "__|_ | | | | | | | | | | | | _|__"<<std::endl; std::cout <<COL_RED << "__|__| | | "<< "| | | "<<COL_PURPLE<<" | | |"<< " | | | _|__"<<std::endl;
std::cout << "__|_ _|__"<<std::endl; std::cout <<COL_RED << "__|__ "<< " "<<COL_PURPLE<<" "<< " _|__"<<std::endl;
std::cout << "__|_ GGGG RRRR III DDDD _|__"<<std::endl; std::cout <<COL_RED << "__|_ "<<COL_GREEN<<" GGGG "<<COL_RED<<" RRRR "<<COL_BLUE <<" III "<<COL_PURPLE<<"DDDD "<<COL_PURPLE<<" _|__"<<std::endl;
std::cout << "__|_ G R R I D D _|__"<<std::endl; std::cout <<COL_RED << "__|_ "<<COL_GREEN<<"G "<<COL_RED<<" R R "<<COL_BLUE <<" I "<<COL_PURPLE<<"D D "<<COL_PURPLE<<" _|__"<<std::endl;
std::cout << "__|_ G R R I D D _|__"<<std::endl; std::cout <<COL_RED << "__|_ "<<COL_GREEN<<"G "<<COL_RED<<" R R "<<COL_BLUE <<" I "<<COL_PURPLE<<"D D"<<COL_PURPLE<<" _|__"<<std::endl;
std::cout << "__|_ G GG RRRR I D D _|__"<<std::endl; std::cout <<COL_BLUE << "__|_ "<<COL_GREEN<<"G GG "<<COL_RED<<" RRRR "<<COL_BLUE <<" I "<<COL_PURPLE<<"D D"<<COL_GREEN <<" _|__"<<std::endl;
std::cout << "__|_ G G R R I D D _|__"<<std::endl; std::cout <<COL_BLUE << "__|_ "<<COL_GREEN<<"G G "<<COL_RED<<" R R "<<COL_BLUE <<" I "<<COL_PURPLE<<"D D "<<COL_GREEN <<" _|__"<<std::endl;
std::cout << "__|_ GGGG R R III DDDD _|__"<<std::endl; std::cout <<COL_BLUE << "__|_ "<<COL_GREEN<<" GGGG "<<COL_RED<<" R R "<<COL_BLUE <<" III "<<COL_PURPLE<<"DDDD "<<COL_GREEN <<" _|__"<<std::endl;
std::cout << "__|_ _|__"<<std::endl; std::cout <<COL_BLUE << "__|__ "<< " "<<COL_GREEN <<" "<< " _|__"<<std::endl;
std::cout << "__|__|__|__|__|__|__|__|__|__|__|__|__|__|__"<<std::endl; std::cout <<COL_BLUE << "__|__|__|__|__"<< "|__|__|_"<<COL_GREEN <<"_|__|__|"<< "__|__|__|__|__"<<std::endl;
std::cout << "__|__|__|__|__|__|__|__|__|__|__|__|__|__|__"<<std::endl; std::cout <<COL_BLUE << "__|__|__|__|__"<< "|__|__|_"<<COL_GREEN <<"_|__|__|"<< "__|__|__|__|__"<<std::endl;
std::cout << " | | | | | | | | | | | | | | "<<std::endl; std::cout <<COL_BLUE << " | | | | "<< "| | | "<<COL_GREEN <<" | | |"<< " | | | | "<<std::endl;
std::cout << std::endl;
std::cout << std::endl; std::cout << std::endl;
std::cout << std::endl; std::cout << std::endl;
std::cout <<COL_YELLOW<< std::endl;
std::cout << "Copyright (C) 2015 Peter Boyle, Azusa Yamaguchi, Guido Cossu, Antonin Portelli and other authors"<<std::endl; std::cout << "Copyright (C) 2015 Peter Boyle, Azusa Yamaguchi, Guido Cossu, Antonin Portelli and other authors"<<std::endl;
std::cout << std::endl; std::cout << std::endl;
std::cout << "This program is free software; you can redistribute it and/or modify"<<std::endl; std::cout << "This program is free software; you can redistribute it and/or modify"<<std::endl;
@ -263,6 +272,7 @@ void Grid_init(int *argc,char ***argv)
std::cout << "but WITHOUT ANY WARRANTY; without even the implied warranty of"<<std::endl; std::cout << "but WITHOUT ANY WARRANTY; without even the implied warranty of"<<std::endl;
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;
std::cout << COL_BACKGROUND <<std::endl;
std::cout << std::endl; std::cout << std::endl;
} }

View File

@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#include <Grid.h> #include <Grid.h>
@ -34,74 +35,43 @@ namespace Grid {
GridStopWatch Logger::StopWatch; GridStopWatch Logger::StopWatch;
std::ostream Logger::devnull(0); std::ostream Logger::devnull(0);
std::string Logger::BLACK("\033[30m");
std::string Logger::RED("\033[31m");
std::string Logger::GREEN("\033[32m");
std::string Logger::YELLOW("\033[33m");
std::string Logger::BLUE("\033[34m");
std::string Logger::PURPLE("\033[35m");
std::string Logger::CYAN("\033[36m");
std::string Logger::WHITE("\033[37m");
std::string Logger::NORMAL("\033[0;39m");
std::string EMPTY("");
#if 0 Colours GridLogColours(0);
GridLogger GridLogError (1,"Error",Logger::RED); GridLogger GridLogError(1, "Error", GridLogColours, "RED");
GridLogger GridLogWarning (1,"Warning",Logger::YELLOW); GridLogger GridLogWarning(1, "Warning", GridLogColours, "YELLOW");
GridLogger GridLogMessage (1,"Message",Logger::BLACK); GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL");
GridLogger GridLogDebug (1,"Debug",Logger::PURPLE); GridLogger GridLogDebug(1, "Debug", GridLogColours, "PURPLE");
GridLogger GridLogPerformance(1,"Performance",Logger::GREEN); GridLogger GridLogPerformance(1, "Performance", GridLogColours, "GREEN");
GridLogger GridLogIterative (1,"Iterative",Logger::BLUE); GridLogger GridLogIterative(1, "Iterative", GridLogColours, "BLUE");
GridLogger GridLogIntegrator (1,"Integrator",Logger::BLUE); GridLogger GridLogIntegrator(1, "Integrator", GridLogColours, "BLUE");
#else
GridLogger GridLogError (1,"Error",EMPTY);
GridLogger GridLogWarning (1,"Warning",EMPTY);
GridLogger GridLogMessage (1,"Message",EMPTY);
GridLogger GridLogDebug (1,"Debug",EMPTY);
GridLogger GridLogPerformance(1,"Performance",EMPTY);
GridLogger GridLogIterative (1,"Iterative",EMPTY);
GridLogger GridLogIntegrator (1,"Integrator",EMPTY);
#endif
void GridLogConfigure(std::vector<std::string> &logstreams) void GridLogConfigure(std::vector<std::string> &logstreams) {
{
GridLogError.Active(0); GridLogError.Active(0);
GridLogWarning.Active(0); GridLogWarning.Active(0);
GridLogMessage.Active(0); GridLogMessage.Active(1); // at least the messages should be always on
GridLogIterative.Active(0); GridLogIterative.Active(0);
GridLogDebug.Active(0); GridLogDebug.Active(0);
GridLogPerformance.Active(0); GridLogPerformance.Active(0);
GridLogIntegrator.Active(0); GridLogIntegrator.Active(0);
GridLogColours.Active(0);
int blackAndWhite = 1;
if(blackAndWhite){
Logger::BLACK = std::string("");
Logger::RED =Logger::BLACK;
Logger::GREEN =Logger::BLACK;
Logger::YELLOW =Logger::BLACK;
Logger::BLUE =Logger::BLACK;
Logger::PURPLE =Logger::BLACK;
Logger::CYAN =Logger::BLACK;
Logger::WHITE =Logger::BLACK;
Logger::NORMAL =Logger::BLACK;
}
for (int i = 0; i < logstreams.size(); i++) { for (int i = 0; i < logstreams.size(); i++) {
if (logstreams[i] == std::string("Error")) GridLogError.Active(1); if (logstreams[i] == std::string("Error")) GridLogError.Active(1);
if (logstreams[i] == std::string("Warning")) GridLogWarning.Active(1); if (logstreams[i] == std::string("Warning")) GridLogWarning.Active(1);
if ( logstreams[i]== std::string("Message") ) GridLogMessage.Active(1); 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") ) GridLogPerformance.Active(1); if (logstreams[i] == std::string("Performance"))
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);
} }
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Verbose limiter on MPI tasks // Verbose limiter on MPI tasks
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Grid_quiesce_nodes(void) void Grid_quiesce_nodes(void) {
{
int me = 0; int me = 0;
#ifdef GRID_COMMS_MPI #ifdef GRID_COMMS_MPI
MPI_Comm_rank(MPI_COMM_WORLD, &me); MPI_Comm_rank(MPI_COMM_WORLD, &me);
@ -114,13 +84,9 @@ void Grid_quiesce_nodes(void)
} }
} }
void Grid_unquiesce_nodes(void) void Grid_unquiesce_nodes(void) {
{
#ifdef GRID_COMMS_MPI #ifdef GRID_COMMS_MPI
std::cout.clear(); std::cout.clear();
#endif #endif
} }
} }

View File

@ -27,6 +27,9 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#include <map>
#ifndef GRID_LOG_H #ifndef GRID_LOG_H
#define GRID_LOG_H #define GRID_LOG_H
@ -40,39 +43,81 @@ namespace Grid {
int Rank(void); // used for early stage debug before library init int Rank(void); // used for early stage debug before library init
class Colours{
protected:
bool is_active;
public:
std::map<std::string, std::string> colour;
Colours(bool activate=false){
Active(activate);
};
void Active(bool activate){
is_active=activate;
if (is_active){
colour["BLACK"] ="\033[30m";
colour["RED"] ="\033[31m";
colour["GREEN"] ="\033[32m";
colour["YELLOW"] ="\033[33m";
colour["BLUE"] ="\033[34m";
colour["PURPLE"] ="\033[35m";
colour["CYAN"] ="\033[36m";
colour["WHITE"] ="\033[37m";
colour["NORMAL"] ="\033[0;39m";
} else {
colour["BLACK"] ="";
colour["RED"] ="";
colour["GREEN"] ="";
colour["YELLOW"]="";
colour["BLUE"] ="";
colour["PURPLE"]="";
colour["CYAN"] ="";
colour["WHITE"] ="";
colour["NORMAL"]="";
}
};
};
class Logger { class Logger {
protected: protected:
Colours &Painter;
int active; int active;
std::string name, topName, COLOUR; std::string name, topName;
std::string COLOUR;
public: public:
static GridStopWatch StopWatch; static GridStopWatch StopWatch;
static std::ostream devnull; static std::ostream devnull;
static std::string BLACK; std::string background() {return Painter.colour["NORMAL"];}
static std::string RED ; std::string evidence() {return Painter.colour["YELLOW"];}
static std::string GREEN; std::string colour() {return Painter.colour[COLOUR];}
static std::string YELLOW;
static std::string BLUE ;
static std::string PURPLE;
static std::string CYAN ;
static std::string WHITE ;
static std::string NORMAL;
Logger(std::string topNm, int on, std::string nm,std::string col) Logger(std::string topNm, int on, std::string nm, Colours& col_class, std::string col)
: active(on), name(nm), topName(topNm), COLOUR(col) {}; : active(on),
name(nm),
topName(topNm),
Painter(col_class),
COLOUR(col){} ;
void Active(int on) {active = on;}; void Active(int on) {active = on;};
int isActive(void) {return active;}; int isActive(void) {return active;};
friend std::ostream& operator<< (std::ostream& stream, const Logger& log){ friend std::ostream& operator<< (std::ostream& stream, Logger& log){
if ( log.active ) { if ( log.active ) {
StopWatch.Stop(); StopWatch.Stop();
GridTime now = StopWatch.Elapsed(); GridTime now = StopWatch.Elapsed();
StopWatch.Start(); StopWatch.Start();
stream << BLACK <<std::setw(8) << std::left << log.topName << BLACK<< " : "; stream << log.background()<< log.topName << log.background()<< " : ";
stream << log.COLOUR <<std::setw(11) << log.name << BLACK << " : "; stream << log.colour() <<std::setw(14) << std::left << log.name << log.background() << " : ";
stream << YELLOW <<std::setw(6) << now <<BLACK << " : " ; stream << log.evidence()<< now << log.background() << " : " << log.colour();
stream << log.COLOUR;
return stream; return stream;
} else { } else {
return devnull; return devnull;
@ -83,7 +128,8 @@ public:
class GridLogger: public Logger { class GridLogger: public Logger {
public: public:
GridLogger(int on, std::string nm, std::string col = Logger::BLACK): Logger("Grid", on, nm, col){}; GridLogger(int on, std::string nm, Colours&col_class, std::string col_key = "NORMAL"):
Logger("Grid", on, nm, col_class, col_key){};
}; };
void GridLogConfigure(std::vector<std::string> &logstreams); void GridLogConfigure(std::vector<std::string> &logstreams);
@ -95,6 +141,7 @@ extern GridLogger GridLogDebug ;
extern GridLogger GridLogPerformance; extern GridLogger GridLogPerformance;
extern GridLogger GridLogIterative ; extern GridLogger GridLogIterative ;
extern GridLogger GridLogIntegrator ; extern GridLogger GridLogIntegrator ;
extern Colours GridLogColours;
#define _NBACKTRACE (256) #define _NBACKTRACE (256)
@ -128,5 +175,6 @@ extern void * Grid_backtrace_buffer[_NBACKTRACE];
#define BACKTRACE() BACKTRACEFP(stdout) #define BACKTRACE() BACKTRACEFP(stdout)
} }
#endif #endif

File diff suppressed because one or more lines are too long

View File

@ -24,7 +24,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef GRID_SIMD_H #ifndef GRID_SIMD_H
@ -118,6 +119,14 @@ namespace Grid {
inline ComplexD timesI(const ComplexD &r) { return(r*ComplexD(0.0,1.0));} inline ComplexD timesI(const ComplexD &r) { return(r*ComplexD(0.0,1.0));}
inline ComplexF timesMinusI(const ComplexF &r){ return(r*ComplexF(0.0,-1.0));} inline ComplexF timesMinusI(const ComplexF &r){ return(r*ComplexF(0.0,-1.0));}
inline ComplexD timesMinusI(const ComplexD &r){ return(r*ComplexD(0.0,-1.0));} inline ComplexD timesMinusI(const ComplexD &r){ return(r*ComplexD(0.0,-1.0));}
// define projections to real and imaginay parts
inline ComplexF projReal(const ComplexF &r){return( ComplexF(std::real(r), 0.0));}
inline ComplexD projReal(const ComplexD &r){return( ComplexD(std::real(r), 0.0));}
inline ComplexF projImag(const ComplexF &r){return (ComplexF(std::imag(r), 0.0 ));}
inline ComplexD projImag(const ComplexD &r){return (ComplexD(std::imag(r), 0.0));}
// define auxiliary functions for complex computations
inline void timesI(ComplexF &ret,const ComplexF &r) { ret = timesI(r);} inline void timesI(ComplexF &ret,const ComplexF &r) { ret = timesI(r);}
inline void timesI(ComplexD &ret,const ComplexD &r) { ret = timesI(r);} inline void timesI(ComplexD &ret,const ComplexD &r) { ret = timesI(r);}
inline void timesMinusI(ComplexF &ret,const ComplexF &r){ ret = timesMinusI(r);} inline void timesMinusI(ComplexF &ret,const ComplexF &r){ ret = timesMinusI(r);}

View File

@ -24,16 +24,17 @@ Author: neo <cossu@post.kek.jp>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef GRID_LATTICE_ET_H #ifndef GRID_LATTICE_ET_H
#define GRID_LATTICE_ET_H #define GRID_LATTICE_ET_H
#include <iostream> #include <iostream>
#include <vector>
#include <tuple> #include <tuple>
#include <typeinfo> #include <typeinfo>
#include <vector>
namespace Grid { namespace Grid {
@ -41,8 +42,8 @@ namespace Grid {
// Predicated where support // Predicated where support
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
template <class iobj, class vobj, class robj> template <class iobj, class vobj, class robj>
inline vobj predicatedWhere(const iobj &predicate,const vobj &iftrue,const robj &iffalse) { inline vobj predicatedWhere(const iobj &predicate, const vobj &iftrue,
const robj &iffalse) {
typename std::remove_const<vobj>::type ret; typename std::remove_const<vobj>::type ret;
typedef typename vobj::scalar_object scalar_object; typedef typename vobj::scalar_object scalar_object;
@ -75,10 +76,13 @@ namespace Grid {
// from tuple is hideous; C++14 introduces std::make_index_sequence for this // from tuple is hideous; C++14 introduces std::make_index_sequence for this
//////////////////////////////////////////// ////////////////////////////////////////////
// leaf eval of lattice ; should enable if protect using traits // leaf eval of lattice ; should enable if protect using traits
template <typename T> using is_lattice = std::is_base_of<LatticeBase,T >; template <typename T>
using is_lattice = std::is_base_of<LatticeBase, T>;
template <typename T>
using is_lattice_expr = std::is_base_of<LatticeExpressionBase, T>;
template <typename T> using is_lattice_expr = std::is_base_of<LatticeExpressionBase,T >; template <typename T> using is_lattice_expr = std::is_base_of<LatticeExpressionBase,T >;
@ -94,37 +98,47 @@ inline sobj eval(const unsigned int ss, const sobj &arg)
return arg; return arg;
} }
template <class lobj> template <class lobj>
inline const lobj &eval(const unsigned int ss, const Lattice<lobj> &arg) inline const lobj &eval(const unsigned int ss, const Lattice<lobj> &arg) {
{
return arg._odata[ss]; return arg._odata[ss];
} }
// handle nodes in syntax tree // handle nodes in syntax tree
template <typename Op, typename T1> template <typename Op, typename T1>
auto inline eval(const unsigned int ss, const LatticeUnaryExpression<Op,T1 > &expr) // eval one operand auto inline eval(
-> decltype(expr.first.func(eval(ss,std::get<0>(expr.second)))) const unsigned int ss,
{ const LatticeUnaryExpression<Op, T1> &expr) // eval one operand
-> decltype(expr.first.func(eval(ss, std::get<0>(expr.second)))) {
return expr.first.func(eval(ss, std::get<0>(expr.second))); return expr.first.func(eval(ss, std::get<0>(expr.second)));
} }
template <typename Op, typename T1, typename T2> template <typename Op, typename T1, typename T2>
auto inline eval(const unsigned int ss, const LatticeBinaryExpression<Op,T1,T2> &expr) // eval two operands auto inline eval(
-> decltype(expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second)))) const unsigned int ss,
{ const LatticeBinaryExpression<Op, T1, T2> &expr) // eval two operands
return expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second))); -> decltype(expr.first.func(eval(ss, std::get<0>(expr.second)),
eval(ss, std::get<1>(expr.second)))) {
return expr.first.func(eval(ss, std::get<0>(expr.second)),
eval(ss, std::get<1>(expr.second)));
} }
template <typename Op, typename T1, typename T2, typename T3> template <typename Op, typename T1, typename T2, typename T3>
auto inline eval(const unsigned int ss, const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) // eval three operands auto inline eval(const unsigned int ss,
-> decltype(expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second)),eval(ss,std::get<2>(expr.second)))) const LatticeTrinaryExpression<Op, T1, T2, T3>
{ &expr) // eval three operands
return expr.first.func(eval(ss,std::get<0>(expr.second)),eval(ss,std::get<1>(expr.second)),eval(ss,std::get<2>(expr.second)) ); -> decltype(expr.first.func(eval(ss, std::get<0>(expr.second)),
eval(ss, std::get<1>(expr.second)),
eval(ss, std::get<2>(expr.second)))) {
return expr.first.func(eval(ss, std::get<0>(expr.second)),
eval(ss, std::get<1>(expr.second)),
eval(ss, std::get<2>(expr.second)));
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Obtain the grid from an expression, ensuring conformable. This must follow a tree recursion // Obtain the grid from an expression, ensuring conformable. This must follow a
// tree recursion
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
template<class T1, typename std::enable_if<is_lattice<T1>::value, T1>::type * =nullptr > template <class T1,
typename std::enable_if<is_lattice<T1>::value, T1>::type * = nullptr>
inline void GridFromExpression(GridBase *&grid, const T1 &lat) // Lattice leaf inline void GridFromExpression(GridBase *&grid, const T1 &lat) // Lattice leaf
{ {
if (grid) { if (grid) {
@ -132,35 +146,37 @@ inline void GridFromExpression(GridBase * &grid,const T1& lat) // Lattice leaf
} }
grid = lat._grid; grid = lat._grid;
} }
template<class T1,typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr > template <class T1,
inline void GridFromExpression(GridBase * &grid,const T1& notlat) // non-lattice leaf typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr>
{ inline void GridFromExpression(GridBase *&grid,
} const T1 &notlat) // non-lattice leaf
{}
template <typename Op, typename T1> template <typename Op, typename T1>
inline void GridFromExpression(GridBase * &grid,const LatticeUnaryExpression<Op,T1 > &expr) inline void GridFromExpression(GridBase *&grid,
{ const LatticeUnaryExpression<Op, T1> &expr) {
GridFromExpression(grid, std::get<0>(expr.second)); // recurse GridFromExpression(grid, std::get<0>(expr.second)); // recurse
} }
template <typename Op, typename T1, typename T2> template <typename Op, typename T1, typename T2>
inline void GridFromExpression(GridBase * &grid,const LatticeBinaryExpression<Op,T1,T2> &expr) inline void GridFromExpression(
{ GridBase *&grid, const LatticeBinaryExpression<Op, T1, T2> &expr) {
GridFromExpression(grid, std::get<0>(expr.second)); // recurse GridFromExpression(grid, std::get<0>(expr.second)); // recurse
GridFromExpression(grid, std::get<1>(expr.second)); GridFromExpression(grid, std::get<1>(expr.second));
} }
template <typename Op, typename T1, typename T2, typename T3> template <typename Op, typename T1, typename T2, typename T3>
inline void GridFromExpression( GridBase * &grid,const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) inline void GridFromExpression(
{ GridBase *&grid, const LatticeTrinaryExpression<Op, T1, T2, T3> &expr) {
GridFromExpression(grid, std::get<0>(expr.second)); // recurse GridFromExpression(grid, std::get<0>(expr.second)); // recurse
GridFromExpression(grid, std::get<1>(expr.second)); GridFromExpression(grid, std::get<1>(expr.second));
GridFromExpression(grid, std::get<2>(expr.second)); GridFromExpression(grid, std::get<2>(expr.second));
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Obtain the CB from an expression, ensuring conformable. This must follow a tree recursion // Obtain the CB from an expression, ensuring conformable. This must follow a
// tree recursion
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
template<class T1, typename std::enable_if<is_lattice<T1>::value, T1>::type * =nullptr > template <class T1,
typename std::enable_if<is_lattice<T1>::value, T1>::type * = nullptr>
inline void CBFromExpression(int &cb, const T1 &lat) // Lattice leaf inline void CBFromExpression(int &cb, const T1 &lat) // Lattice leaf
{ {
if ((cb == Odd) || (cb == Even)) { if ((cb == Odd) || (cb == Even)) {
@ -169,28 +185,29 @@ inline void CBFromExpression(int &cb,const T1& lat) // Lattice leaf
cb = lat.checkerboard; cb = lat.checkerboard;
// std::cout<<GridLogMessage<<"Lattice leaf cb "<<cb<<std::endl; // std::cout<<GridLogMessage<<"Lattice leaf cb "<<cb<<std::endl;
} }
template<class T1,typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr > template <class T1,
typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr>
inline void CBFromExpression(int &cb, const T1 &notlat) // non-lattice leaf inline void CBFromExpression(int &cb, const T1 &notlat) // non-lattice leaf
{ {
// std::cout<<GridLogMessage<<"Non lattice leaf cb"<<cb<<std::endl; // std::cout<<GridLogMessage<<"Non lattice leaf cb"<<cb<<std::endl;
} }
template <typename Op, typename T1> template <typename Op, typename T1>
inline void CBFromExpression(int &cb,const LatticeUnaryExpression<Op,T1 > &expr) inline void CBFromExpression(int &cb,
{ const LatticeUnaryExpression<Op, T1> &expr) {
CBFromExpression(cb, std::get<0>(expr.second)); // recurse CBFromExpression(cb, std::get<0>(expr.second)); // recurse
// std::cout<<GridLogMessage<<"Unary node cb "<<cb<<std::endl; // std::cout<<GridLogMessage<<"Unary node cb "<<cb<<std::endl;
} }
template <typename Op, typename T1, typename T2> template <typename Op, typename T1, typename T2>
inline void CBFromExpression(int &cb,const LatticeBinaryExpression<Op,T1,T2> &expr) inline void CBFromExpression(int &cb,
{ const LatticeBinaryExpression<Op, T1, T2> &expr) {
CBFromExpression(cb, std::get<0>(expr.second)); // recurse CBFromExpression(cb, std::get<0>(expr.second)); // recurse
CBFromExpression(cb, std::get<1>(expr.second)); CBFromExpression(cb, std::get<1>(expr.second));
// std::cout<<GridLogMessage<<"Binary node cb "<<cb<<std::endl; // std::cout<<GridLogMessage<<"Binary node cb "<<cb<<std::endl;
} }
template <typename Op, typename T1, typename T2, typename T3> template <typename Op, typename T1, typename T2, typename T3>
inline void CBFromExpression( int &cb,const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) inline void CBFromExpression(
{ int &cb, const LatticeTrinaryExpression<Op, T1, T2, T3> &expr) {
CBFromExpression(cb, std::get<0>(expr.second)); // recurse CBFromExpression(cb, std::get<0>(expr.second)); // recurse
CBFromExpression(cb, std::get<1>(expr.second)); CBFromExpression(cb, std::get<1>(expr.second));
CBFromExpression(cb, std::get<2>(expr.second)); CBFromExpression(cb, std::get<2>(expr.second));
@ -201,8 +218,8 @@ inline void CBFromExpression( int &cb,const LatticeTrinaryExpression<Op,T1,T2,T3
// Unary operators and funcs // Unary operators and funcs
//////////////////////////////////////////// ////////////////////////////////////////////
#define GridUnopClass(name, ret) \ #define GridUnopClass(name, ret) \
template <class arg> struct name\ template <class arg> \
{\ struct name { \
static auto inline func(const arg a) -> decltype(ret) { return ret; } \ static auto inline func(const arg a) -> decltype(ret) { return ret; } \
}; };
@ -218,11 +235,15 @@ GridUnopClass(UnaryReal,real(a));
GridUnopClass(UnaryImag, imag(a)); GridUnopClass(UnaryImag, imag(a));
GridUnopClass(UnaryToReal, toReal(a)); GridUnopClass(UnaryToReal, toReal(a));
GridUnopClass(UnaryToComplex, toComplex(a)); GridUnopClass(UnaryToComplex, toComplex(a));
GridUnopClass(UnaryTimesI, timesI(a));
GridUnopClass(UnaryTimesMinusI, timesMinusI(a));
GridUnopClass(UnaryAbs, abs(a)); GridUnopClass(UnaryAbs, abs(a));
GridUnopClass(UnarySqrt, sqrt(a)); GridUnopClass(UnarySqrt, sqrt(a));
GridUnopClass(UnaryRsqrt, rsqrt(a)); GridUnopClass(UnaryRsqrt, rsqrt(a));
GridUnopClass(UnarySin, sin(a)); GridUnopClass(UnarySin, sin(a));
GridUnopClass(UnaryCos, cos(a)); GridUnopClass(UnaryCos, cos(a));
GridUnopClass(UnaryAsin, asin(a));
GridUnopClass(UnaryAcos, acos(a));
GridUnopClass(UnaryLog, log(a)); GridUnopClass(UnaryLog, log(a));
GridUnopClass(UnaryExp, exp(a)); GridUnopClass(UnaryExp, exp(a));
@ -231,10 +252,9 @@ GridUnopClass(UnaryExp,exp(a));
//////////////////////////////////////////// ////////////////////////////////////////////
#define GridBinOpClass(name, combination) \ #define GridBinOpClass(name, combination) \
template <class left, class right> \ template <class left, class right> \
struct name\ struct name { \
{\ static auto inline func(const left &lhs, const right &rhs) \
static auto inline func(const left &lhs,const right &rhs)-> decltype(combination) const \ -> decltype(combination) const { \
{\
return combination; \ return combination; \
} \ } \
} }
@ -252,17 +272,18 @@ GridBinOpClass(BinaryOrOr ,lhs||rhs);
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
#define GridTrinOpClass(name, combination) \ #define GridTrinOpClass(name, combination) \
template <class predicate, class left, class right> \ template <class predicate, class left, class right> \
struct name\ struct name { \
{\ static auto inline func(const predicate &pred, const left &lhs, \
static auto inline func(const predicate &pred,const left &lhs,const right &rhs)-> decltype(combination) const \ const right &rhs) -> decltype(combination) const { \
{\
return combination; \ return combination; \
} \ } \
} }
GridTrinOpClass(TrinaryWhere,(predicatedWhere<predicate, \ GridTrinOpClass(
typename std::remove_reference<left>::type, \ TrinaryWhere,
typename std::remove_reference<right>::type> (pred,lhs,rhs))); (predicatedWhere<predicate, typename std::remove_reference<left>::type,
typename std::remove_reference<right>::type>(pred, lhs,
rhs)));
//////////////////////////////////////////// ////////////////////////////////////////////
// Operator syntactical glue // Operator syntactical glue
@ -270,49 +291,66 @@ GridTrinOpClass(TrinaryWhere,(predicatedWhere<predicate, \
#define GRID_UNOP(name) name<decltype(eval(0, arg))> #define GRID_UNOP(name) name<decltype(eval(0, arg))>
#define GRID_BINOP(name) name<decltype(eval(0, lhs)), decltype(eval(0, rhs))> #define GRID_BINOP(name) name<decltype(eval(0, lhs)), decltype(eval(0, rhs))>
#define GRID_TRINOP(name) name<decltype(eval(0, pred)), decltype(eval(0, lhs)), decltype(eval(0, rhs))> #define GRID_TRINOP(name) \
name<decltype(eval(0, pred)), decltype(eval(0, lhs)), decltype(eval(0, rhs))>
#define GRID_DEF_UNOP(op, name) \ #define GRID_DEF_UNOP(op, name) \
template <typename T1, \ template <typename T1, \
typename std::enable_if<is_lattice<T1>::value||is_lattice_expr<T1>::value, T1>::type* = nullptr> inline auto op(const T1 &arg) \ typename std::enable_if<is_lattice<T1>::value || \
-> decltype(LatticeUnaryExpression<GRID_UNOP(name),const T1&>(std::make_pair(GRID_UNOP(name)(),std::forward_as_tuple(arg)))) \ is_lattice_expr<T1>::value, \
{ return LatticeUnaryExpression<GRID_UNOP(name), const T1 &>(std::make_pair(GRID_UNOP(name)(),std::forward_as_tuple(arg))); } T1>::type * = nullptr> \
inline auto op(const T1 &arg) \
->decltype(LatticeUnaryExpression<GRID_UNOP(name), const T1 &>( \
std::make_pair(GRID_UNOP(name)(), std::forward_as_tuple(arg)))) { \
return LatticeUnaryExpression<GRID_UNOP(name), const T1 &>( \
std::make_pair(GRID_UNOP(name)(), std::forward_as_tuple(arg))); \
}
#define GRID_BINOP_LEFT(op, name) \ #define GRID_BINOP_LEFT(op, name) \
template <typename T1, typename T2, \ template <typename T1, typename T2, \
typename std::enable_if<is_lattice<T1>::value||is_lattice_expr<T1>::value, T1>::type* = nullptr>\ typename std::enable_if<is_lattice<T1>::value || \
is_lattice_expr<T1>::value, \
T1>::type * = nullptr> \
inline auto op(const T1 &lhs, const T2 &rhs) \ inline auto op(const T1 &lhs, const T2 &rhs) \
-> decltype(LatticeBinaryExpression<GRID_BINOP(name),const T1&,const T2 &>(std::make_pair(GRID_BINOP(name)(),\ ->decltype( \
std::forward_as_tuple(lhs, rhs)))) \ LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
{\ std::make_pair(GRID_BINOP(name)(), \
return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(std::make_pair(GRID_BINOP(name)(),\ std::forward_as_tuple(lhs, rhs)))) { \
std::forward_as_tuple(lhs, rhs))); \ return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
std::make_pair(GRID_BINOP(name)(), std::forward_as_tuple(lhs, rhs))); \
} }
#define GRID_BINOP_RIGHT(op, name) \ #define GRID_BINOP_RIGHT(op, name) \
template <typename T1, typename T2, \ template <typename T1, typename T2, \
typename std::enable_if<!is_lattice<T1>::value && !is_lattice_expr<T1>::value, T1>::type* = nullptr,\ typename std::enable_if<!is_lattice<T1>::value && \
typename std::enable_if< is_lattice<T2>::value || is_lattice_expr<T2>::value, T2>::type* = nullptr> \ !is_lattice_expr<T1>::value, \
T1>::type * = nullptr, \
typename std::enable_if<is_lattice<T2>::value || \
is_lattice_expr<T2>::value, \
T2>::type * = nullptr> \
inline auto op(const T1 &lhs, const T2 &rhs) \ inline auto op(const T1 &lhs, const T2 &rhs) \
-> decltype(LatticeBinaryExpression<GRID_BINOP(name),const T1&,const T2 &>(std::make_pair(GRID_BINOP(name)(),\ ->decltype( \
std::forward_as_tuple(lhs, rhs)))) \ LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
{\ std::make_pair(GRID_BINOP(name)(), \
return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>(std::make_pair(GRID_BINOP(name)(),\ std::forward_as_tuple(lhs, rhs)))) { \
std::forward_as_tuple(lhs, rhs))); \ return LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
std::make_pair(GRID_BINOP(name)(), std::forward_as_tuple(lhs, rhs))); \
} }
#define GRID_DEF_BINOP(op, name) \ #define GRID_DEF_BINOP(op, name) \
GRID_BINOP_LEFT(op, name); \ GRID_BINOP_LEFT(op, name); \
GRID_BINOP_RIGHT(op, name); GRID_BINOP_RIGHT(op, name);
#define GRID_DEF_TRINOP(op, name) \ #define GRID_DEF_TRINOP(op, name) \
template <typename T1,typename T2,typename T3> inline auto op(const T1 &pred,const T2&lhs,const T3 &rhs) \ template <typename T1, typename T2, typename T3> \
-> decltype(LatticeTrinaryExpression<GRID_TRINOP(name),const T1&,const T2 &,const T3&>(std::make_pair(GRID_TRINOP(name)(),\ inline auto op(const T1 &pred, const T2 &lhs, const T3 &rhs) \
std::forward_as_tuple(pred,lhs,rhs)))) \ ->decltype( \
{\ LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &, \
return LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &,const T3&>(std::make_pair(GRID_TRINOP(name)(), \ const T3 &>(std::make_pair( \
std::forward_as_tuple(pred,lhs, rhs))); \ GRID_TRINOP(name)(), std::forward_as_tuple(pred, lhs, rhs)))) { \
return LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &, \
const T3 &>(std::make_pair( \
GRID_TRINOP(name)(), std::forward_as_tuple(pred, lhs, rhs))); \
} }
//////////////////////// ////////////////////////
// Operator definitions // Operator definitions
@ -331,11 +369,16 @@ GRID_DEF_UNOP(real,UnaryReal);
GRID_DEF_UNOP(imag, UnaryImag); GRID_DEF_UNOP(imag, UnaryImag);
GRID_DEF_UNOP(toReal, UnaryToReal); GRID_DEF_UNOP(toReal, UnaryToReal);
GRID_DEF_UNOP(toComplex, UnaryToComplex); GRID_DEF_UNOP(toComplex, UnaryToComplex);
GRID_DEF_UNOP(abs ,UnaryAbs); //abs overloaded in cmath C++98; DON'T do the abs-fabs-dabs-labs thing GRID_DEF_UNOP(timesI, UnaryTimesI);
GRID_DEF_UNOP(timesMinusI, UnaryTimesMinusI);
GRID_DEF_UNOP(abs, UnaryAbs); // abs overloaded in cmath C++98; DON'T do the
// abs-fabs-dabs-labs thing
GRID_DEF_UNOP(sqrt, UnarySqrt); GRID_DEF_UNOP(sqrt, UnarySqrt);
GRID_DEF_UNOP(rsqrt, UnaryRsqrt); GRID_DEF_UNOP(rsqrt, UnaryRsqrt);
GRID_DEF_UNOP(sin, UnarySin); GRID_DEF_UNOP(sin, UnarySin);
GRID_DEF_UNOP(cos, UnaryCos); GRID_DEF_UNOP(cos, UnaryCos);
GRID_DEF_UNOP(asin, UnaryAsin);
GRID_DEF_UNOP(acos, UnaryAcos);
GRID_DEF_UNOP(log, UnaryLog); GRID_DEF_UNOP(log, UnaryLog);
GRID_DEF_UNOP(exp, UnaryExp); GRID_DEF_UNOP(exp, UnaryExp);
@ -355,29 +398,29 @@ GRID_DEF_TRINOP(where,TrinaryWhere);
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
template <class Op, class T1> template <class Op, class T1>
auto closure(const LatticeUnaryExpression<Op, T1> &expr) auto closure(const LatticeUnaryExpression<Op, T1> &expr)
-> Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second))))> -> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second))))> {
{ Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second))))> ret(
Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second))))> ret(expr); expr);
return ret; return ret;
} }
template <class Op, class T1, class T2> template <class Op, class T1, class T2>
auto closure(const LatticeBinaryExpression<Op, T1, T2> &expr) auto closure(const LatticeBinaryExpression<Op, T1, T2> &expr)
-> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)), -> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
eval(0,std::get<1>(expr.second))))> eval(0, std::get<1>(expr.second))))> {
{
Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)), Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
eval(0,std::get<1>(expr.second))))> ret(expr); eval(0, std::get<1>(expr.second))))>
ret(expr);
return ret; return ret;
} }
template <class Op, class T1, class T2, class T3> template <class Op, class T1, class T2, class T3>
auto closure(const LatticeTrinaryExpression<Op, T1, T2, T3> &expr) auto closure(const LatticeTrinaryExpression<Op, T1, T2, T3> &expr)
-> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)), -> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
eval(0, std::get<1>(expr.second)), eval(0, std::get<1>(expr.second)),
eval(0,std::get<2>(expr.second))))> eval(0, std::get<2>(expr.second))))> {
{
Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)), Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
eval(0, std::get<1>(expr.second)), eval(0, std::get<1>(expr.second)),
eval(0,std::get<2>(expr.second))))> ret(expr); eval(0, std::get<2>(expr.second))))>
ret(expr);
return ret; return ret;
} }
@ -388,7 +431,6 @@ template<class Op,class T1, class T2, class T3>
#undef GRID_DEF_UNOP #undef GRID_DEF_UNOP
#undef GRID_DEF_BINOP #undef GRID_DEF_BINOP
#undef GRID_DEF_TRINOP #undef GRID_DEF_TRINOP
} }
#if 0 #if 0

View File

@ -24,7 +24,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef GRID_LATTICE_BASE_H #ifndef GRID_LATTICE_BASE_H
@ -255,6 +256,18 @@ PARALLEL_FOR_LOOP
checkerboard=0; checkerboard=0;
} }
Lattice(const Lattice& r){ // copy constructor
_grid = r._grid;
checkerboard = r.checkerboard;
_odata.resize(_grid->oSites());// essential
PARALLEL_FOR_LOOP
for(int ss=0;ss<_grid->oSites();ss++){
_odata[ss]=r._odata[ss];
}
}
virtual ~Lattice(void) = default; virtual ~Lattice(void) = default;
template<class sobj> strong_inline Lattice<vobj> & operator = (const sobj & r){ template<class sobj> strong_inline Lattice<vobj> & operator = (const sobj & r){
@ -267,7 +280,7 @@ PARALLEL_FOR_LOOP
template<class robj> strong_inline Lattice<vobj> & operator = (const Lattice<robj> & r){ template<class robj> strong_inline Lattice<vobj> & operator = (const Lattice<robj> & r){
this->checkerboard = r.checkerboard; this->checkerboard = r.checkerboard;
conformable(*this,r); conformable(*this,r);
std::cout<<GridLogMessage<<"Lattice operator ="<<std::endl;
PARALLEL_FOR_LOOP PARALLEL_FOR_LOOP
for(int ss=0;ss<_grid->oSites();ss++){ for(int ss=0;ss<_grid->oSites();ss++){
this->_odata[ss]=r._odata[ss]; this->_odata[ss]=r._odata[ss];

View File

@ -40,7 +40,7 @@ namespace Grid {
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<class vobj> inline RealD norm2(const Lattice<vobj> &arg){ template<class vobj> inline RealD norm2(const Lattice<vobj> &arg){
ComplexD nrm = innerProduct(arg,arg); ComplexD nrm = innerProduct(arg,arg);
return real(nrm); return std::real(nrm);
} }
template<class vobj> template<class vobj>

View File

View File

@ -495,5 +495,6 @@ namespace QCD {
#include <qcd/hmc/integrators/Integrator_algorithm.h> #include <qcd/hmc/integrators/Integrator_algorithm.h>
#include <qcd/hmc/HMC.h> #include <qcd/hmc/HMC.h>
#include <qcd/smearing/Smearing.h>
#endif #endif

View File

@ -35,6 +35,7 @@ template<class GaugeField>
class Action { class Action {
public: public:
bool is_smeared = false;
// Boundary conditions? // Heatbath? // Boundary conditions? // Heatbath?
virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) = 0;// refresh pseudofermions virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) = 0;// refresh pseudofermions
virtual RealD S (const GaugeField &U) = 0; // evaluate the action virtual RealD S (const GaugeField &U) = 0; // evaluate the action

View File

@ -75,7 +75,7 @@ namespace Grid {
// //
// //
// template<class Impl> // template<class Impl>
// class MyOp : pubic<Impl> { // class MyOp : public<Impl> {
// public: // public:
// //
// INHERIT_ALL_IMPL_TYPES(Impl); // INHERIT_ALL_IMPL_TYPES(Impl);

View File

@ -22,7 +22,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef GRID_QCD_GAUGE_IMPL_H #ifndef GRID_QCD_GAUGE_IMPL_H
@ -32,7 +33,6 @@ namespace Grid {
namespace QCD { namespace QCD {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Implementation dependent gauge types // Implementation dependent gauge types
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -46,110 +46,120 @@ template<class Gimpl> class WilsonLoops;
typedef typename GImpl::SiteGaugeField SiteGaugeField; \ typedef typename GImpl::SiteGaugeField SiteGaugeField; \
typedef typename GImpl::SiteGaugeLink SiteGaugeLink; typedef typename GImpl::SiteGaugeLink SiteGaugeLink;
// //
template<class S,int Nrepresentation=Nc> template <class S, int Nrepresentation = Nc> class GaugeImplTypes {
class GaugeImplTypes {
public: public:
typedef S Simd; typedef S Simd;
template<typename vtype> using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >; template <typename vtype>
template<typename vtype> using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd >; using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation>>>;
template <typename vtype>
using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation>>, Nd>;
typedef iImplGaugeLink<Simd> SiteGaugeLink; typedef iImplGaugeLink<Simd> SiteGaugeLink;
typedef iImplGaugeField<Simd> SiteGaugeField; typedef iImplGaugeField<Simd> SiteGaugeField;
typedef Lattice<SiteGaugeLink> GaugeLinkField; // bit ugly naming; polarised gauge field, lorentz... all ugly typedef Lattice<SiteGaugeLink> GaugeLinkField; // bit ugly naming; polarised
// gauge field, lorentz... all
// ugly
typedef Lattice<SiteGaugeField> GaugeField; typedef Lattice<SiteGaugeField> GaugeField;
// Move this elsewhere?
static inline void AddGaugeLink(GaugeField &U, GaugeLinkField &W,
int mu) { // U[mu] += W
PARALLEL_FOR_LOOP
for (auto ss = 0; ss < U._grid->oSites(); ss++) {
U._odata[ss]._internal[mu] =
U._odata[ss]._internal[mu] + W._odata[ss]._internal;
}
}
}; };
// Composition with smeared link, bc's etc.. probably need multiple inheritance // Composition with smeared link, bc's etc.. probably need multiple inheritance
// Variable precision "S" and variable Nc // Variable precision "S" and variable Nc
template<class GimplTypes> template <class GimplTypes> class PeriodicGaugeImpl : public GimplTypes {
class PeriodicGaugeImpl : public GimplTypes {
public: public:
INHERIT_GIMPL_TYPES(GimplTypes); INHERIT_GIMPL_TYPES(GimplTypes);
//////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Support needed for the assembly of loops including all boundary condition effects such as conjugate bcs // Support needed for the assembly of loops including all boundary condition
// effects such as conjugate bcs
//////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class covariant> static inline template <class covariant>
Lattice<covariant> CovShiftForward (const GaugeLinkField &Link, int mu, const Lattice<covariant> &field) { static inline Lattice<covariant>
CovShiftForward(const GaugeLinkField &Link, int mu,
const Lattice<covariant> &field) {
return PeriodicBC::CovShiftForward(Link, mu, field); return PeriodicBC::CovShiftForward(Link, mu, field);
} }
template<class covariant> static inline template <class covariant>
Lattice<covariant> CovShiftBackward(const GaugeLinkField &Link, int mu,const Lattice<covariant> &field) { static inline Lattice<covariant>
CovShiftBackward(const GaugeLinkField &Link, int mu,
const Lattice<covariant> &field) {
return PeriodicBC::CovShiftBackward(Link, mu, field); return PeriodicBC::CovShiftBackward(Link, mu, field);
} }
static inline static inline GaugeLinkField
GaugeLinkField CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) { CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) {
return Cshift(adj(Link), mu, -1); return Cshift(adj(Link), mu, -1);
} }
static inline static inline GaugeLinkField
GaugeLinkField CovShiftIdentityForward(const GaugeLinkField &Link, int mu) { CovShiftIdentityForward(const GaugeLinkField &Link, int mu) {
return Link; return Link;
} }
static inline static inline GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) {
GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) {
return Cshift(Link, mu, 1); return Cshift(Link, mu, 1);
} }
static inline bool isPeriodicGaugeField(void) { static inline bool isPeriodicGaugeField(void) { return true; }
return true;
}
}; };
// Composition with smeared link, bc's etc.. probably need multiple inheritance // Composition with smeared link, bc's etc.. probably need multiple inheritance
// Variable precision "S" and variable Nc // Variable precision "S" and variable Nc
template<class GimplTypes> template <class GimplTypes> class ConjugateGaugeImpl : public GimplTypes {
class ConjugateGaugeImpl : public GimplTypes {
public: public:
INHERIT_GIMPL_TYPES(GimplTypes); INHERIT_GIMPL_TYPES(GimplTypes);
//////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Support needed for the assembly of loops including all boundary condition effects such as Gparity. // Support needed for the assembly of loops including all boundary condition
// effects such as Gparity.
//////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class covariant> static template <class covariant>
Lattice<covariant> CovShiftForward (const GaugeLinkField &Link, int mu, const Lattice<covariant> &field) { static Lattice<covariant> CovShiftForward(const GaugeLinkField &Link, int mu,
const Lattice<covariant> &field) {
return ConjugateBC::CovShiftForward(Link, mu, field); return ConjugateBC::CovShiftForward(Link, mu, field);
} }
template<class covariant> static template <class covariant>
Lattice<covariant> CovShiftBackward(const GaugeLinkField &Link, int mu,const Lattice<covariant> &field) { static Lattice<covariant> CovShiftBackward(const GaugeLinkField &Link, int mu,
const Lattice<covariant> &field) {
return ConjugateBC::CovShiftBackward(Link, mu, field); return ConjugateBC::CovShiftBackward(Link, mu, field);
} }
static inline static inline GaugeLinkField
GaugeLinkField CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) { CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) {
GridBase *grid = Link._grid; GridBase *grid = Link._grid;
int Lmu = grid->GlobalDimensions()[mu] - 1; int Lmu = grid->GlobalDimensions()[mu] - 1;
Lattice<iScalar<vInteger> > coor(grid); LatticeCoordinate(coor,mu); Lattice<iScalar<vInteger>> coor(grid);
LatticeCoordinate(coor, mu);
GaugeLinkField tmp(grid); GaugeLinkField tmp(grid);
tmp = adj(Link); tmp = adj(Link);
tmp = where(coor == Lmu, conjugate(tmp), tmp); tmp = where(coor == Lmu, conjugate(tmp), tmp);
return Cshift(tmp, mu, -1); // moves towards positive mu return Cshift(tmp, mu, -1); // moves towards positive mu
} }
static inline static inline GaugeLinkField
GaugeLinkField CovShiftIdentityForward(const GaugeLinkField &Link, int mu) { CovShiftIdentityForward(const GaugeLinkField &Link, int mu) {
return Link; return Link;
} }
static inline static inline GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) {
GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) {
GridBase *grid = Link._grid; GridBase *grid = Link._grid;
int Lmu = grid->GlobalDimensions()[mu] - 1; int Lmu = grid->GlobalDimensions()[mu] - 1;
Lattice<iScalar<vInteger> > coor(grid); LatticeCoordinate(coor,mu); Lattice<iScalar<vInteger>> coor(grid);
LatticeCoordinate(coor, mu);
GaugeLinkField tmp(grid); GaugeLinkField tmp(grid);
tmp = Cshift(Link, mu, 1); tmp = Cshift(Link, mu, 1);
@ -157,10 +167,7 @@ template<class Gimpl> class WilsonLoops;
return tmp; return tmp;
} }
static inline bool isPeriodicGaugeField(void) { static inline bool isPeriodicGaugeField(void) { return false; }
return false;
}
}; };
typedef GaugeImplTypes<vComplex, Nc> GimplTypesR; typedef GaugeImplTypes<vComplex, Nc> GimplTypesR;
@ -171,10 +178,10 @@ template<class Gimpl> class WilsonLoops;
typedef PeriodicGaugeImpl<GimplTypesF> PeriodicGimplF; // Float typedef PeriodicGaugeImpl<GimplTypesF> PeriodicGimplF; // Float
typedef PeriodicGaugeImpl<GimplTypesD> PeriodicGimplD; // Double typedef PeriodicGaugeImpl<GimplTypesD> PeriodicGimplD; // Double
typedef ConjugateGaugeImpl<GimplTypesR> ConjugateGimplR; // Real.. whichever prec typedef ConjugateGaugeImpl<GimplTypesR>
ConjugateGimplR; // Real.. whichever prec
typedef ConjugateGaugeImpl<GimplTypesF> ConjugateGimplF; // Float typedef ConjugateGaugeImpl<GimplTypesF> ConjugateGimplF; // Float
typedef ConjugateGaugeImpl<GimplTypesD> ConjugateGimplD; // Double typedef ConjugateGaugeImpl<GimplTypesD> ConjugateGimplD; // Double
} }
} }

View File

@ -22,7 +22,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_EVEN_ODD_RATIONAL_H #ifndef QCD_PSEUDOFERMION_ONE_FLAVOUR_EVEN_ODD_RATIONAL_H
@ -42,7 +43,8 @@ namespace Grid{
// //
template <class Impl> template <class Impl>
class OneFlavourEvenOddRationalPseudoFermionAction : public Action<typename Impl::GaugeField> { class OneFlavourEvenOddRationalPseudoFermionAction
: public Action<typename Impl::GaugeField> {
public: public:
INHERIT_IMPL_TYPES(Impl); INHERIT_IMPL_TYPES(Impl);
@ -55,41 +57,40 @@ namespace Grid{
MultiShiftFunction PowerNegQuarter; MultiShiftFunction PowerNegQuarter;
private: private:
FermionOperator<Impl> &FermOp; // the basic operator FermionOperator<Impl> &FermOp; // the basic operator
// NOT using "Nroots"; IroIro is -- perhaps later, but this wasn't good for us historically // NOT using "Nroots"; IroIro is -- perhaps later, but this wasn't good for us
// historically
// and hasenbusch works better // and hasenbusch works better
FermionField PhiEven; // the pseudo fermion field for this trajectory FermionField PhiEven; // the pseudo fermion field for this trajectory
FermionField PhiOdd; // the pseudo fermion field for this trajectory FermionField PhiOdd; // the pseudo fermion field for this trajectory
public: public:
OneFlavourEvenOddRationalPseudoFermionAction(FermionOperator<Impl> &Op, OneFlavourEvenOddRationalPseudoFermionAction(FermionOperator<Impl> &Op,
Params & p ) : FermOp(Op), Params &p)
: FermOp(Op),
PhiEven(Op.FermionRedBlackGrid()), PhiEven(Op.FermionRedBlackGrid()),
PhiOdd(Op.FermionRedBlackGrid()), PhiOdd(Op.FermionRedBlackGrid()),
param(p) param(p) {
{
AlgRemez remez(param.lo, param.hi, param.precision); AlgRemez remez(param.lo, param.hi, param.precision);
// MdagM^(+- 1/2) // MdagM^(+- 1/2)
std::cout<<GridLogMessage << "Generating degree "<<param.degree<<" for x^(1/2)"<<std::endl; std::cout << GridLogMessage << "Generating degree " << param.degree
<< " for x^(1/2)" << std::endl;
remez.generateApprox(param.degree, 1, 2); remez.generateApprox(param.degree, 1, 2);
PowerHalf.Init(remez, param.tolerance, false); PowerHalf.Init(remez, param.tolerance, false);
PowerNegHalf.Init(remez, param.tolerance, true); PowerNegHalf.Init(remez, param.tolerance, true);
// MdagM^(+- 1/4) // MdagM^(+- 1/4)
std::cout<<GridLogMessage << "Generating degree "<<param.degree<<" for x^(1/4)"<<std::endl; std::cout << GridLogMessage << "Generating degree " << param.degree
<< " for x^(1/4)" << std::endl;
remez.generateApprox(param.degree, 1, 4); remez.generateApprox(param.degree, 1, 4);
PowerQuarter.Init(remez, param.tolerance, false); PowerQuarter.Init(remez, param.tolerance, false);
PowerNegQuarter.Init(remez, param.tolerance, true); PowerNegQuarter.Init(remez, param.tolerance, true);
}; };
virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) { virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) {
// P(phi) = e^{- phi^dag (MpcdagMpc)^-1/2 phi} // P(phi) = e^{- phi^dag (MpcdagMpc)^-1/2 phi}
// = e^{- phi^dag (MpcdagMpc)^-1/4 (MpcdagMpc)^-1/4 phi} // = e^{- phi^dag (MpcdagMpc)^-1/4 (MpcdagMpc)^-1/4 phi}
// Phi = MpcdagMpc^{1/4} eta // Phi = MpcdagMpc^{1/4} eta
@ -106,7 +107,8 @@ namespace Grid{
FermionField etaOdd(FermOp.FermionRedBlackGrid()); FermionField etaOdd(FermOp.FermionRedBlackGrid());
FermionField etaEven(FermOp.FermionRedBlackGrid()); FermionField etaEven(FermOp.FermionRedBlackGrid());
gaussian(pRNG,eta); eta=eta*scale; gaussian(pRNG, eta);
eta = eta * scale;
pickCheckerboard(Even, etaEven, eta); pickCheckerboard(Even, etaEven, eta);
pickCheckerboard(Odd, etaOdd, eta); pickCheckerboard(Odd, etaOdd, eta);
@ -124,26 +126,27 @@ namespace Grid{
assert(FermOp.ConstEE() == 1); assert(FermOp.ConstEE() == 1);
PhiEven = zero; PhiEven = zero;
}; };
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
// S = phi^dag (Mdag M)^-1/2 phi // S = phi^dag (Mdag M)^-1/2 phi
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
virtual RealD S(const GaugeField &U) { virtual RealD S(const GaugeField &U) {
FermOp.ImportGauge(U); FermOp.ImportGauge(U);
FermionField Y(FermOp.FermionRedBlackGrid()); FermionField Y(FermOp.FermionRedBlackGrid());
SchurDifferentiableOperator<Impl> Mpc(FermOp); SchurDifferentiableOperator<Impl> Mpc(FermOp);
ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter,PowerNegQuarter); ConjugateGradientMultiShift<FermionField> msCG(param.MaxIter,
PowerNegQuarter);
msCG(Mpc, PhiOdd, Y); msCG(Mpc, PhiOdd, Y);
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;
}; };
@ -158,7 +161,8 @@ namespace Grid{
// //
// d[N/D] is then // d[N/D] is then
// //
// \sum_k -ak [M^dagM+bk]^{-1} [ dM^dag M + M^dag dM ] [M^dag M + bk]^{-1} // \sum_k -ak [M^dagM+bk]^{-1} [ dM^dag M + M^dag dM ] [M^dag M +
// bk]^{-1}
// //
// Need // Need
// Mf Phi_k = [MdagM+bk]^{-1} Phi // Mf Phi_k = [MdagM+bk]^{-1} Phi
@ -166,11 +170,11 @@ namespace Grid{
// //
// With these building blocks // With these building blocks
// //
// dS/dU = \sum_k -ak Mf Phi_k^dag [ dM^dag M + M^dag dM ] Mf Phi_k // dS/dU = \sum_k -ak Mf Phi_k^dag [ dM^dag M + M^dag dM ] Mf
// Phi_k
// S = innerprodReal(Phi,Mf Phi); // S = innerprodReal(Phi,Mf Phi);
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
virtual void deriv(const GaugeField &U, GaugeField &dSdU) { virtual void deriv(const GaugeField &U, GaugeField &dSdU) {
const int Npole = PowerNegHalf.poles.size(); const int Npole = PowerNegHalf.poles.size();
std::vector<FermionField> MPhi_k(Npole, FermOp.FermionRedBlackGrid()); std::vector<FermionField> MPhi_k(Npole, FermOp.FermionRedBlackGrid());
@ -190,23 +194,21 @@ namespace Grid{
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];
X = MPhi_k[k]; X = MPhi_k[k];
Mpc.Mpc(X, Y); Mpc.Mpc(X, Y);
Mpc.MpcDeriv (tmp , Y, X ); dSdU=dSdU+ak*tmp; Mpc.MpcDeriv(tmp, Y, X);
Mpc.MpcDagDeriv(tmp , X, Y ); dSdU=dSdU+ak*tmp; dSdU = dSdU + ak * tmp;
Mpc.MpcDagDeriv(tmp, X, Y);
dSdU = dSdU + ak * tmp;
} }
dSdU = Ta(dSdU); // dSdU = Ta(dSdU);
}; };
}; };
} }
} }
#endif #endif

View File

@ -256,7 +256,7 @@ namespace Grid{
} }
dSdU = Ta(dSdU); //dSdU = Ta(dSdU);
}; };
}; };

View File

@ -186,7 +186,7 @@ namespace Grid{
} }
dSdU = Ta(dSdU); //dSdU = Ta(dSdU);
}; };
}; };

View File

@ -242,7 +242,7 @@ namespace Grid{
} }
dSdU = Ta(dSdU); //dSdU = Ta(dSdU);
}; };
}; };

View File

@ -137,7 +137,7 @@ namespace Grid{
FermOp.MDeriv(tmp , Y, X,DaggerNo ); dSdU=tmp; FermOp.MDeriv(tmp , Y, X,DaggerNo ); dSdU=tmp;
FermOp.MDeriv(tmp , X, Y,DaggerYes); dSdU=dSdU+tmp; FermOp.MDeriv(tmp , X, Y,DaggerYes); dSdU=dSdU+tmp;
dSdU = Ta(dSdU); //dSdU = Ta(dSdU);
}; };

View File

@ -173,7 +173,7 @@ namespace Grid{
FermOp.MeeDeriv(tmp , X, Y,DaggerYes); dSdU=dSdU+tmp; FermOp.MeeDeriv(tmp , X, Y,DaggerYes); dSdU=dSdU+tmp;
*/ */
dSdU = Ta(dSdU); //dSdU = Ta(dSdU);
}; };

View File

@ -188,7 +188,8 @@ namespace Grid{
assert(NumOp.ConstEE() == 1); assert(NumOp.ConstEE() == 1);
assert(DenOp.ConstEE() == 1); assert(DenOp.ConstEE() == 1);
dSdU = -Ta(dSdU); //dSdU = -Ta(dSdU);
dSdU = -dSdU;
}; };
}; };

View File

@ -155,7 +155,8 @@ namespace Grid{
DenOp.MDeriv(force,Y,X,DaggerNo); dSdU=dSdU-force; DenOp.MDeriv(force,Y,X,DaggerNo); dSdU=dSdU-force;
DenOp.MDeriv(force,X,Y,DaggerYes); dSdU=dSdU-force; DenOp.MDeriv(force,X,Y,DaggerYes); dSdU=dSdU-force;
dSdU = - Ta(dSdU); dSdU *= -1.0;
//dSdU = - Ta(dSdU);
}; };
}; };

View File

@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -41,13 +42,10 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
#include <string> #include <string>
namespace Grid { namespace Grid {
namespace QCD { namespace QCD {
struct HMCparameters { struct HMCparameters {
Integer StartTrajectory; Integer StartTrajectory;
Integer Trajectories; /* @brief Number of sweeps in this run */ Integer Trajectories; /* @brief Number of sweeps in this run */
bool MetropolisTest; bool MetropolisTest;
@ -61,27 +59,40 @@ namespace Grid{
Trajectories = 200; Trajectories = 200;
///////////////////////////////// /////////////////////////////////
} }
void print() const {
std::cout << GridLogMessage << "[HMC parameter] Trajectories : " << Trajectories << "\n";
std::cout << GridLogMessage << "[HMC parameter] Start trajectory : " << StartTrajectory << "\n";
std::cout << GridLogMessage << "[HMC parameter] Metropolis test (on/off): " << MetropolisTest << "\n";
std::cout << GridLogMessage << "[HMC parameter] Thermalization trajs : " << NoMetropolisUntil << "\n";
}
}; };
template <class GaugeField> template <class GaugeField>
class HmcObservable { class HmcObservable {
public: public:
virtual void TrajectoryComplete (int traj, GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG & pRNG )=0; virtual void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG,
GridParallelRNG &pRNG) = 0;
}; };
template <class Gimpl> template <class Gimpl>
class PlaquetteLogger : public HmcObservable<typename Gimpl::GaugeField> { class PlaquetteLogger : public HmcObservable<typename Gimpl::GaugeField> {
private: private:
std::string Stem; std::string Stem;
public: public:
INHERIT_GIMPL_TYPES(Gimpl); INHERIT_GIMPL_TYPES(Gimpl);
PlaquetteLogger(std::string cf) { PlaquetteLogger(std::string cf) { Stem = cf; };
Stem = cf;
};
void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG & pRNG ) void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG,
GridParallelRNG &pRNG) {
std::string file;
{ {
std::string file; { std::ostringstream os; os << Stem <<"."<< traj; file = os.str(); } std::ostringstream os;
os << Stem << "." << traj;
file = os.str();
}
std::ofstream of(file); std::ofstream of(file);
RealD peri_plaq = WilsonLoops<PeriodicGimplR>::avgPlaquette(U); RealD peri_plaq = WilsonLoops<PeriodicGimplR>::avgPlaquette(U);
@ -90,17 +101,27 @@ namespace Grid{
RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(U); RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(U);
RealD impl_rect = WilsonLoops<Gimpl>::avgRectangle(U); RealD impl_rect = WilsonLoops<Gimpl>::avgRectangle(U);
of << traj<<" "<< impl_plaq << " " << impl_rect << " "<< peri_plaq<<" "<<peri_rect<<std::endl; of << traj << " " << impl_plaq << " " << impl_rect << " " << peri_plaq
std::cout<< GridLogMessage<< "traj"<<" "<< "plaq " << " " << " rect " << " "<< "peri_plaq" <<" "<<"peri_rect"<<std::endl; << " " << peri_rect << std::endl;
std::cout<< GridLogMessage<< traj<<" "<< impl_plaq << " " << impl_rect << " "<< peri_plaq<<" "<<peri_rect<<std::endl; std::cout << GridLogMessage << "traj"
<< " "
<< "plaq "
<< " "
<< " rect "
<< " "
<< "peri_plaq"
<< " "
<< "peri_rect" << std::endl;
std::cout << GridLogMessage << traj << " " << impl_plaq << " " << impl_rect
<< " " << peri_plaq << " " << peri_rect << std::endl;
} }
}; };
// template <class GaugeField, class Integrator, class Smearer, class Boundary> // template <class GaugeField, class Integrator, class Smearer, class
// Boundary>
template <class GaugeField, class IntegratorType> template <class GaugeField, class IntegratorType>
class HybridMonteCarlo { class HybridMonteCarlo {
private: private:
const HMCparameters Params; const HMCparameters Params;
GridSerialRNG &sRNG; // Fixme: need a RNG management strategy. GridSerialRNG &sRNG; // Fixme: need a RNG management strategy.
@ -114,60 +135,64 @@ namespace Grid{
// Metropolis step // Metropolis step
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
bool metropolis_test(const RealD DeltaH) { bool metropolis_test(const RealD DeltaH) {
RealD rn_test; RealD rn_test;
RealD prob = std::exp(-DeltaH); RealD prob = std::exp(-DeltaH);
random(sRNG, rn_test); random(sRNG, rn_test);
std::cout<<GridLogMessage<< "--------------------------------------------\n"; std::cout << GridLogMessage
std::cout<<GridLogMessage<< "dH = "<<DeltaH << " Random = "<< rn_test <<"\n"; << "--------------------------------------------------\n";
std::cout<<GridLogMessage<< "Acc. Probability = " << ((prob<1.0)? prob: 1.0)<< " "; std::cout << GridLogMessage << "exp(-dH) = " << prob
<< " Random = " << rn_test << "\n";
std::cout << GridLogMessage
<< "Acc. Probability = " << ((prob < 1.0) ? prob : 1.0) << "\n";
if ((prob > 1.0) || (rn_test <= prob)) { // accepted if ((prob > 1.0) || (rn_test <= prob)) { // accepted
std::cout<<GridLogMessage <<"-- ACCEPTED\n"; std::cout << GridLogMessage << "Metropolis_test -- ACCEPTED\n";
std::cout << GridLogMessage
<< "--------------------------------------------------\n";
return true; return true;
} else { // rejected } else { // rejected
std::cout<<GridLogMessage <<"-- REJECTED\n"; std::cout << GridLogMessage << "Metropolis_test -- REJECTED\n";
std::cout << GridLogMessage
<< "--------------------------------------------------\n";
return false; return false;
} }
} }
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
// Evolution // Evolution
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
RealD evolve_step(GaugeField &U) { RealD evolve_step(GaugeField &U) {
TheIntegrator.refresh(U, pRNG); // set U and initialize P and phi's TheIntegrator.refresh(U, pRNG); // set U and initialize P and phi's
RealD H0 = TheIntegrator.S(U); // initial state action RealD H0 = TheIntegrator.S(U); // initial state action
std::cout<<GridLogMessage<<"Total H before = "<< H0 << "\n"; std::streamsize current_precision = std::cout.precision();
std::cout.precision(17);
std::cout << GridLogMessage << "Total H before trajectory = " << H0 << "\n";
std::cout.precision(current_precision);
TheIntegrator.integrate(U); TheIntegrator.integrate(U);
RealD H1 = TheIntegrator.S(U); // updated state action RealD H1 = TheIntegrator.S(U); // updated state action
std::cout<<GridLogMessage<<"Total H after = "<< H1 << "\n"; std::cout.precision(17);
std::cout << GridLogMessage << "Total H after trajectory = " << H1
<< " dH = " << H1 - H0 << "\n";
std::cout.precision(current_precision);
return (H1 - H0); return (H1 - H0);
} }
public: public:
///////////////////////////////////////// /////////////////////////////////////////
// Constructor // Constructor
///////////////////////////////////////// /////////////////////////////////////////
HybridMonteCarlo(HMCparameters Pms, IntegratorType &_Int, GridSerialRNG &_sRNG, GridParallelRNG &_pRNG, GaugeField &_U ) : HybridMonteCarlo(HMCparameters Pams, IntegratorType &_Int,
Params(Pms), GridSerialRNG &_sRNG, GridParallelRNG &_pRNG, GaugeField &_U)
TheIntegrator(_Int), : Params(Pams), TheIntegrator(_Int), sRNG(_sRNG), pRNG(_pRNG), Ucur(_U) {}
sRNG(_sRNG),
pRNG(_pRNG),
Ucur(_U)
{
}
~HybridMonteCarlo(){}; ~HybridMonteCarlo(){};
void AddObservable(HmcObservable<GaugeField> *obs) { void AddObservable(HmcObservable<GaugeField> *obs) {
@ -175,21 +200,22 @@ namespace Grid{
} }
void evolve(void) { void evolve(void) {
Real DeltaH; Real DeltaH;
GaugeField Ucopy(Ucur._grid); GaugeField Ucopy(Ucur._grid);
// Actual updates (evolve a copy Ucopy then copy back eventually) Params.print();
for(int traj=Params.StartTrajectory; traj < Params.Trajectories+Params.StartTrajectory; ++traj){
// Actual updates (evolve a copy Ucopy then copy back eventually)
for (int traj = Params.StartTrajectory;
traj < Params.Trajectories + Params.StartTrajectory; ++traj) {
std::cout << GridLogMessage << "-- # Trajectory = " << traj << "\n"; std::cout << GridLogMessage << "-- # Trajectory = " << traj << "\n";
Ucopy = Ucur; Ucopy = Ucur;
DeltaH = evolve_step(Ucopy); DeltaH = evolve_step(Ucopy);
bool accept = true; bool accept = true;
if ( traj > Params.NoMetropolisUntil) { if (traj >= Params.NoMetropolisUntil) {
accept = metropolis_test(DeltaH); accept = metropolis_test(DeltaH);
} }
@ -200,7 +226,6 @@ namespace Grid{
for (int obs = 0; obs < Observables.size(); obs++) { for (int obs = 0; obs < Observables.size(); obs++) {
Observables[obs]->TrajectoryComplete(traj + 1, Ucur, sRNG, pRNG); Observables[obs]->TrajectoryComplete(traj + 1, Ucur, sRNG, pRNG);
} }
} }
} }
}; };
@ -208,5 +233,4 @@ namespace Grid{
} // QCD } // QCD
} // Grid } // Grid
#endif #endif

View File

@ -47,7 +47,7 @@ public:
GridRedBlackCartesian * UrbGrid ; GridRedBlackCartesian * UrbGrid ;
GridRedBlackCartesian * FrbGrid ; GridRedBlackCartesian * FrbGrid ;
virtual void BuildTheAction (int argc, char **argv) = 0; virtual void BuildTheAction (int argc, char **argv) = 0; // necessary?
void Run (int argc, char **argv){ void Run (int argc, char **argv){
@ -81,10 +81,37 @@ public:
NumTraj = ivec[0]; NumTraj = ivec[0];
} }
// Create integrator int NumThermalizations = 10;
typedef MinimumNorm2<GaugeField> IntegratorType;// change here to change the algorithm if( GridCmdOptionExists(argv,argv+argc,"--Thermalizations") ){
arg= GridCmdOptionPayload(argv,argv+argc,"--Thermalizations");
std::vector<int> ivec(0);
GridCmdOptionIntVector(arg,ivec);
NumThermalizations = ivec[0];
}
GridSerialRNG sRNG;
GridParallelRNG pRNG(UGrid);
LatticeGaugeField U(UGrid); // change this to an extended field (smearing class)
std::vector<int> SerSeed({1,2,3,4,5});
std::vector<int> ParSeed({6,7,8,9,10});
// Create integrator, including the smearing policy
// Smearing policy
std::cout << GridLogDebug << " Creating the Stout class\n";
double rho = 0.1; // smearing parameter, now hardcoded
int Nsmear = 1; // number of smearing levels
Smear_Stout<Gimpl> Stout(rho);
std::cout << GridLogDebug << " Creating the SmearedConfiguration class\n";
SmearedConfiguration<Gimpl> SmearingPolicy(UGrid, Nsmear, Stout);
std::cout << GridLogDebug << " done\n";
//////////////
typedef MinimumNorm2<GaugeField, SmearedConfiguration<Gimpl> > IntegratorType;// change here to change the algorithm
IntegratorParameters MDpar(20); IntegratorParameters MDpar(20);
IntegratorType MDynamics(UGrid,MDpar, TheAction); IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy);
// Checkpoint strategy // Checkpoint strategy
NerscHmcCheckpointer<Gimpl> Checkpoint(std::string("ckpoint_lat"),std::string("ckpoint_rng"),1); NerscHmcCheckpointer<Gimpl> Checkpoint(std::string("ckpoint_lat"),std::string("ckpoint_rng"),1);
@ -93,42 +120,38 @@ public:
HMCparameters HMCpar; HMCparameters HMCpar;
HMCpar.StartTrajectory = StartTraj; HMCpar.StartTrajectory = StartTraj;
HMCpar.Trajectories = NumTraj; HMCpar.Trajectories = NumTraj;
HMCpar.NoMetropolisUntil = NumThermalizations;
GridSerialRNG sRNG;
GridParallelRNG pRNG(UGrid);
LatticeGaugeField U(UGrid);
std::vector<int> SerSeed({1,2,3,4,5});
std::vector<int> ParSeed({6,7,8,9,10});
if ( StartType == HotStart ) { if ( StartType == HotStart ) {
// Hot start // Hot start
HMCpar.NoMetropolisUntil =10;
HMCpar.MetropolisTest = true; HMCpar.MetropolisTest = true;
sRNG.SeedFixedIntegers(SerSeed); sRNG.SeedFixedIntegers(SerSeed);
pRNG.SeedFixedIntegers(ParSeed); pRNG.SeedFixedIntegers(ParSeed);
SU3::HotConfiguration(pRNG, U); SU3::HotConfiguration(pRNG, U);
} else if ( StartType == ColdStart ) { } else if ( StartType == ColdStart ) {
// Cold start // Cold start
HMCpar.NoMetropolisUntil =10;
HMCpar.MetropolisTest = true; HMCpar.MetropolisTest = true;
sRNG.SeedFixedIntegers(SerSeed); sRNG.SeedFixedIntegers(SerSeed);
pRNG.SeedFixedIntegers(ParSeed); pRNG.SeedFixedIntegers(ParSeed);
SU3::ColdConfiguration(pRNG, U); SU3::ColdConfiguration(pRNG, U);
} else if ( StartType == TepidStart ) { } else if ( StartType == TepidStart ) {
// Tepid start // Tepid start
HMCpar.NoMetropolisUntil =10;
HMCpar.MetropolisTest = true; HMCpar.MetropolisTest = true;
sRNG.SeedFixedIntegers(SerSeed); sRNG.SeedFixedIntegers(SerSeed);
pRNG.SeedFixedIntegers(ParSeed); pRNG.SeedFixedIntegers(ParSeed);
SU3::TepidConfiguration(pRNG, U); SU3::TepidConfiguration(pRNG, U);
} else if ( StartType == CheckpointStart ) { } else if ( StartType == CheckpointStart ) {
HMCpar.NoMetropolisUntil =10;
HMCpar.MetropolisTest = true; HMCpar.MetropolisTest = true;
// CheckpointRestart // CheckpointRestart
Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG); Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG);
} }
// Attach the gauge field to the smearing Policy and create the fill the smeared set
// notice that the unit configuration is singular in this procedure
std::cout << GridLogMessage << "Filling the smeared set\n";
SmearingPolicy.set_GaugeField(U);
HybridMonteCarlo<GaugeField,IntegratorType> HMC(HMCpar, MDynamics,sRNG,pRNG,U); HybridMonteCarlo<GaugeField,IntegratorType> HMC(HMCpar, MDynamics,sRNG,pRNG,U);
HMC.AddObservable(&Checkpoint); HMC.AddObservable(&Checkpoint);
HMC.AddObservable(&PlaqLog); HMC.AddObservable(&PlaqLog);

View File

@ -68,7 +68,7 @@ namespace Grid{
}; };
/*! @brief Class for Molecular Dynamics management */ /*! @brief Class for Molecular Dynamics management */
template<class GaugeField> template<class GaugeField, class SmearingPolicy>
class Integrator { class Integrator {
protected: protected:
@ -85,6 +85,8 @@ namespace Grid{
GaugeField P; GaugeField P;
SmearingPolicy &Smearer;
// Should match any legal (SU(n)) gauge field // Should match any legal (SU(n)) gauge field
// Need to use this template to match Ncol to pass to SU<N> class // Need to use this template to match Ncol to pass to SU<N> class
template<int Ncol,class vec> void generate_momenta(Lattice< iVector< iScalar< iMatrix<vec,Ncol> >, Nd> > & P,GridParallelRNG& pRNG){ template<int Ncol,class vec> void generate_momenta(Lattice< iVector< iScalar< iMatrix<vec,Ncol> >, Nd> > & P,GridParallelRNG& pRNG){
@ -111,10 +113,17 @@ namespace Grid{
} }
void update_P(GaugeField &Mom,GaugeField&U, int level,double ep){ void update_P(GaugeField &Mom,GaugeField&U, int level,double ep){
// input U actually not used...
for(int a=0; a<as[level].actions.size(); ++a){ for(int a=0; a<as[level].actions.size(); ++a){
GaugeField force(U._grid); GaugeField force(U._grid);
as[level].actions.at(a)->deriv(U,force); GaugeField& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared);
Mom = Mom - force*ep; as[level].actions.at(a)->deriv(Us,force); // deriv should NOT include Ta
std::cout<< GridLogIntegrator << "Smearing (on/off): "<<as[level].actions.at(a)->is_smeared <<std::endl;
if (as[level].actions.at(a)->is_smeared) Smearer.smeared_force(force);
force = Ta(force);
std::cout<< GridLogIntegrator << "Force average: "<< norm2(force)/(U._grid->gSites()) <<std::endl;
Mom -= force*ep;
} }
} }
@ -137,6 +146,8 @@ namespace Grid{
ProjectOnGroup(Umu); ProjectOnGroup(Umu);
PokeIndex<LorentzIndex>(U, Umu, mu); PokeIndex<LorentzIndex>(U, Umu, mu);
} }
// Update the smeared fields, can be implemented as observer
Smearer.set_GaugeField(U);
} }
virtual void step (GaugeField& U,int level, int first,int last)=0; virtual void step (GaugeField& U,int level, int first,int last)=0;
@ -145,14 +156,17 @@ namespace Grid{
Integrator(GridBase* grid, Integrator(GridBase* grid,
IntegratorParameters Par, IntegratorParameters Par,
ActionSet<GaugeField> & Aset): ActionSet<GaugeField> & Aset,
SmearingPolicy &Sm):
Params(Par), Params(Par),
as(Aset), as(Aset),
P(grid), P(grid),
levels(Aset.size()) levels(Aset.size()),
Smearer(Sm)
{ {
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
}; };
virtual ~Integrator(){} virtual ~Integrator(){}
@ -163,13 +177,16 @@ namespace Grid{
generate_momenta(P,pRNG); generate_momenta(P,pRNG);
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){
as[level].actions.at(actionID)->refresh(U, pRNG); // get gauge field from the SmearingPolicy and
// based on the boolean is_smeared in actionID
GaugeField& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
as[level].actions.at(actionID)->refresh(Us, pRNG);
} }
} }
} }
// Calculate action // Calculate action
RealD S(GaugeField& U){ RealD S(GaugeField& U){// here also U not used
LatticeComplex Hloc(U._grid); Hloc = zero; LatticeComplex Hloc(U._grid); Hloc = zero;
// Momenta // Momenta
@ -186,8 +203,11 @@ namespace Grid{
// 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){
Hterm = as[level].actions.at(actionID)->S(U); // get gauge field from the SmearingPolicy and
std::cout<<GridLogMessage << "Level "<<level<<" term "<<actionID<<" H = "<<Hterm<<std::endl; // based on the boolean is_smeared in actionID
GaugeField& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
Hterm = as[level].actions.at(actionID)->S(Us);
std::cout<<GridLogMessage << "S Level "<<level<<" term "<<actionID<<" H = "<<Hterm<<std::endl;
H += Hterm; H += Hterm;
} }
} }

View File

@ -91,14 +91,17 @@ namespace Grid{
* P 1/2 P 1/2 * P 1/2 P 1/2
*/ */
template<class GaugeField> class LeapFrog : public Integrator<GaugeField> { template<class GaugeField, class SmearingPolicy> class LeapFrog :
public Integrator<GaugeField, SmearingPolicy> {
public: public:
typedef LeapFrog<GaugeField> Algorithm; typedef LeapFrog<GaugeField, SmearingPolicy> Algorithm;
LeapFrog(GridBase* grid, LeapFrog(GridBase* grid,
IntegratorParameters Par, IntegratorParameters Par,
ActionSet<GaugeField> & Aset): Integrator<GaugeField>(grid,Par,Aset) {}; ActionSet<GaugeField> & Aset,
SmearingPolicy & Sm):
Integrator<GaugeField, SmearingPolicy>(grid,Par,Aset,Sm) {};
void step (GaugeField& U, int level,int _first, int _last){ void step (GaugeField& U, int level,int _first, int _last){
@ -135,7 +138,8 @@ namespace Grid{
} }
}; };
template<class GaugeField> class MinimumNorm2 : public Integrator<GaugeField> { template<class GaugeField, class SmearingPolicy> class MinimumNorm2 :
public Integrator<GaugeField, SmearingPolicy> {
private: private:
const RealD lambda = 0.1931833275037836; const RealD lambda = 0.1931833275037836;
@ -143,7 +147,9 @@ namespace Grid{
MinimumNorm2(GridBase* grid, MinimumNorm2(GridBase* grid,
IntegratorParameters Par, IntegratorParameters Par,
ActionSet<GaugeField> & Aset): Integrator<GaugeField>(grid,Par,Aset) {}; ActionSet<GaugeField> & Aset,
SmearingPolicy& Sm):
Integrator<GaugeField, SmearingPolicy>(grid,Par,Aset,Sm) {};
void step (GaugeField& U, int level, int _first,int _last){ void step (GaugeField& U, int level, int _first,int _last){
@ -191,7 +197,8 @@ namespace Grid{
}; };
template<class GaugeField> class ForceGradient : public Integrator<GaugeField> { template<class GaugeField, class SmearingPolicy> class ForceGradient :
public Integrator<GaugeField, SmearingPolicy> {
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;
@ -202,7 +209,9 @@ namespace Grid{
// Looks like dH scales as dt^4. tested wilson/wilson 2 level. // Looks like dH scales as dt^4. tested wilson/wilson 2 level.
ForceGradient(GridBase* grid, ForceGradient(GridBase* grid,
IntegratorParameters Par, IntegratorParameters Par,
ActionSet<GaugeField> & Aset): Integrator<GaugeField>(grid,Par,Aset) {}; ActionSet<GaugeField> & Aset,
SmearingPolicy &Sm):
Integrator<GaugeField, SmearingPolicy>(grid,Par,Aset, Sm) {};
void FG_update_P(GaugeField&U, int level,double fg_dt,double ep){ void FG_update_P(GaugeField&U, int level,double fg_dt,double ep){

View File

@ -0,0 +1,130 @@
/*!
@brief Declaration of Smear_APE class for APE smearing
*/
#ifndef APE_SMEAR_
#define APE_SMEAR_
namespace Grid {
namespace QCD {
/*! @brief APE type smearing of link variables. */
template <class Gimpl>
class Smear_APE: public Smear<Gimpl>{
private:
const std::vector<double> rho;/*!< Array of weights */
//This member must be private - we do not want to control from outside
std::vector<double> set_rho(const double common_rho) const {
std::vector<double> res;
for(int mn=0; mn<Nd*Nd; ++mn) res.push_back(common_rho);
for(int mu=0; mu<Nd; ++mu) res[mu + mu*Nd] = 0.0;
return res;
}
public:
// Defines the gauge field types
INHERIT_GIMPL_TYPES(Gimpl)
// Constructors and destructors
Smear_APE(const std::vector<double>& rho_):rho(rho_){} // check vector size
Smear_APE(double rho_val):rho(set_rho(rho_val)){}
Smear_APE():rho(set_rho(1.0)){}
~Smear_APE(){}
///////////////////////////////////////////////////////////////////////////////
void smear(GaugeField& u_smr, const GaugeField& U)const{
GridBase *grid = U._grid;
GaugeLinkField Cup(grid), tmp_stpl(grid);
WilsonLoops<Gimpl> WL;
u_smr = zero;
for(int mu=0; mu<Nd; ++mu){
Cup = zero;
for(int nu=0; nu<Nd; ++nu){
if (nu != mu) {
// get the staple in direction mu, nu
WL.Staple(tmp_stpl, U, mu, nu); //nb staple conventions of IroIro and Grid differ by a dagger
Cup += tmp_stpl*rho[mu + Nd * nu];
}
}
// save the Cup link-field on the u_smr gauge-field
pokeLorentz(u_smr, adj(Cup), mu); // u_smr[mu] = Cup^dag see conventions for Staple
}
}
////////////////////////////////////////////////////////////////////////////////
void derivative(GaugeField& SigmaTerm,
const GaugeField& iLambda,
const GaugeField& U)const{
// Reference
// Morningstar, Peardon, Phys.Rev.D69,054501(2004)
// Equation 75
// Computing Sigma_mu, derivative of S[fat links] with respect to the thin links
// Output SigmaTerm
GridBase *grid = U._grid;
WilsonLoops<Gimpl> WL;
GaugeLinkField staple(grid), u_tmp(grid);
GaugeLinkField iLambda_mu(grid), iLambda_nu(grid);
GaugeLinkField U_mu(grid), U_nu(grid);
GaugeLinkField sh_field(grid), temp_Sigma(grid);
Real rho_munu, rho_numu;
for(int mu = 0; mu < Nd; ++mu){
U_mu = peekLorentz( U, mu);
iLambda_mu = peekLorentz(iLambda, mu);
for(int nu = 0; nu < Nd; ++nu){
if(nu==mu) continue;
U_nu = peekLorentz( U, nu);
iLambda_nu = peekLorentz(iLambda, nu);
rho_munu = rho[mu + Nd * nu];
rho_numu = rho[nu + Nd * mu];
WL.StapleUpper(staple, U, mu, nu);
temp_Sigma = -rho_numu*staple*iLambda_nu; //ok
//-r_numu*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)*Lambda_nu(x)
Gimpl::AddGaugeLink(SigmaTerm, temp_Sigma, mu);
sh_field = Cshift(iLambda_nu, mu, 1);// general also for Gparity?
temp_Sigma = rho_numu*sh_field*staple; //ok
//r_numu*Lambda_nu(mu)*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)
Gimpl::AddGaugeLink(SigmaTerm, temp_Sigma, mu);
sh_field = Cshift(iLambda_mu, nu, 1);
temp_Sigma = -rho_munu*staple*U_nu*sh_field*adj(U_nu); //ok
//-r_munu*U_nu(x+mu)*Udag_mu(x+nu)*Lambda_mu(x+nu)*Udag_nu(x)
Gimpl::AddGaugeLink(SigmaTerm, temp_Sigma, mu);
staple = zero;
sh_field = Cshift(U_nu, mu, 1);
temp_Sigma = -rho_munu*adj(sh_field)*adj(U_mu)*iLambda_mu*U_nu;
temp_Sigma += rho_numu*adj(sh_field)*adj(U_mu)*iLambda_nu*U_nu;
u_tmp = adj(U_nu)*iLambda_nu;
sh_field = Cshift(u_tmp, mu, 1);
temp_Sigma += -rho_numu*sh_field*adj(U_mu)*U_nu;
sh_field = Cshift(temp_Sigma, nu, -1);
Gimpl::AddGaugeLink(SigmaTerm, sh_field, mu);
}
}
}
};
}// namespace QCD
}//namespace Grid
#endif

View File

@ -0,0 +1,17 @@
/*
@brief Declares base smearing class Smear
*/
#ifndef BASE_SMEAR_
#define BASE_SMEAR_
template <class Gimpl>
class Smear{
public:
INHERIT_GIMPL_TYPES(Gimpl) // inherits the types for the gauge fields
virtual ~Smear(){}
virtual void smear (GaugeField&,const GaugeField&)const = 0;
virtual void derivative(GaugeField&,
const GaugeField&,const GaugeField&) const = 0;
};
#endif

View File

@ -0,0 +1,262 @@
/*!
@file GaugeConfiguration.h
@brief Declares the GaugeConfiguration class
*/
#ifndef GAUGE_CONFIG_
#define GAUGE_CONFIG_
namespace Grid {
namespace QCD {
/*!
@brief Smeared configuration container
It will behave like a configuration from the point of view of
the HMC update and integrators.
An "advanced configuration" object that can provide not only the
data to store the gauge configuration but also operations to manipulate
it, like smearing.
It stores a list of smeared configurations.
*/
template <class Gimpl>
class SmearedConfiguration {
public:
INHERIT_GIMPL_TYPES(Gimpl);
private:
const unsigned int smearingLevels;
Smear_Stout<Gimpl> StoutSmearing;
std::vector<GaugeField> SmearedSet;
// Member functions
//====================================================================
void fill_smearedSet(GaugeField& U) {
ThinLinks = &U; // attach the smearing routine to the field U
// check the pointer is not null
if (ThinLinks == NULL)
std::cout << GridLogError
<< "[SmearedConfiguration] Error in ThinLinks pointer\n";
if (smearingLevels > 0) {
std::cout << GridLogDebug
<< "[SmearedConfiguration] Filling SmearedSet\n";
GaugeField previous_u(ThinLinks->_grid);
previous_u = *ThinLinks;
for (int smearLvl = 0; smearLvl < smearingLevels; ++smearLvl) {
StoutSmearing.smear(SmearedSet[smearLvl], previous_u);
previous_u = SmearedSet[smearLvl];
// For debug purposes
RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(previous_u);
std::cout << GridLogDebug
<< "[SmearedConfiguration] Plaq: " << impl_plaq << std::endl;
}
}
}
//====================================================================
GaugeField AnalyticSmearedForce(const GaugeField& SigmaKPrime,
const GaugeField& GaugeK) const {
GridBase* grid = GaugeK._grid;
GaugeField C(grid), SigmaK(grid), iLambda(grid);
GaugeLinkField iLambda_mu(grid);
GaugeLinkField iQ(grid), e_iQ(grid);
GaugeLinkField SigmaKPrime_mu(grid);
GaugeLinkField GaugeKmu(grid), Cmu(grid);
StoutSmearing.BaseSmear(C, GaugeK);
SigmaK = zero;
iLambda = zero;
for (int mu = 0; mu < Nd; mu++) {
Cmu = peekLorentz(C, mu);
GaugeKmu = peekLorentz(GaugeK, mu);
SigmaKPrime_mu = peekLorentz(SigmaKPrime, mu);
iQ = Ta(Cmu * adj(GaugeKmu));
set_iLambda(iLambda_mu, e_iQ, iQ, SigmaKPrime_mu, GaugeKmu);
pokeLorentz(SigmaK, SigmaKPrime_mu * e_iQ + adj(Cmu) * iLambda_mu, mu);
pokeLorentz(iLambda, iLambda_mu, mu);
}
StoutSmearing.derivative(SigmaK, iLambda,
GaugeK); // derivative of SmearBase
return SigmaK;
}
/*! @brief Returns smeared configuration at level 'Level' */
const GaugeField& get_smeared_conf(int Level) const {
return SmearedSet[Level];
}
//====================================================================
void set_iLambda(GaugeLinkField& iLambda, GaugeLinkField& e_iQ,
const GaugeLinkField& iQ, const GaugeLinkField& Sigmap,
const GaugeLinkField& GaugeK) const {
GridBase* grid = iQ._grid;
GaugeLinkField iQ2(grid), iQ3(grid), B1(grid), B2(grid), USigmap(grid);
GaugeLinkField unity(grid);
unity = 1.0;
LatticeComplex u(grid), w(grid);
LatticeComplex f0(grid), f1(grid), f2(grid);
LatticeComplex xi0(grid), xi1(grid), tmp(grid);
LatticeComplex u2(grid), w2(grid), cosw(grid);
LatticeComplex emiu(grid), e2iu(grid), qt(grid), fden(grid);
LatticeComplex r01(grid), r11(grid), r21(grid), r02(grid), r12(grid);
LatticeComplex r22(grid), tr1(grid), tr2(grid);
LatticeComplex b10(grid), b11(grid), b12(grid), b20(grid), b21(grid),
b22(grid);
LatticeComplex LatticeUnitComplex(grid);
LatticeUnitComplex = 1.0;
// Exponential
iQ2 = iQ * iQ;
iQ3 = iQ * iQ2;
StoutSmearing.set_uw(u, w, iQ2, iQ3);
StoutSmearing.set_fj(f0, f1, f2, u, w);
e_iQ = f0 * unity + timesMinusI(f1) * iQ - f2 * iQ2;
// Getting B1, B2, Gamma and Lambda
// simplify this part, reduntant calculations in set_fj
xi0 = StoutSmearing.func_xi0(w);
xi1 = StoutSmearing.func_xi1(w);
u2 = u * u;
w2 = w * w;
cosw = cos(w);
emiu = cos(u) - timesI(sin(u));
e2iu = cos(2.0 * u) + timesI(sin(2.0 * u));
r01 = (2.0 * u + timesI(2.0 * (u2 - w2))) * e2iu +
emiu * ((16.0 * u * cosw + 2.0 * u * (3.0 * u2 + w2) * xi0) +
timesI(-8.0 * u2 * cosw + 2.0 * (9.0 * u2 + w2) * xi0));
r11 = (2.0 * LatticeUnitComplex + timesI(4.0 * u)) * e2iu +
emiu * ((-2.0 * cosw + (3.0 * u2 - w2) * xi0) +
timesI((2.0 * u * cosw + 6.0 * u * xi0)));
r21 =
2.0 * timesI(e2iu) + emiu * (-3.0 * u * xi0 + timesI(cosw - 3.0 * xi0));
r02 = -2.0 * e2iu +
emiu * (-8.0 * u2 * xi0 +
timesI(2.0 * u * (cosw + xi0 + 3.0 * u2 * xi1)));
r12 = emiu * (2.0 * u * xi0 + timesI(-cosw - xi0 + 3.0 * u2 * xi1));
r22 = emiu * (xi0 - timesI(3.0 * u * xi1));
fden = LatticeUnitComplex / (2.0 * (9.0 * u2 - w2) * (9.0 * u2 - w2));
b10 = 2.0 * u * r01 + (3.0 * u2 - w2) * r02 - (30.0 * u2 + 2.0 * w2) * f0;
b11 = 2.0 * u * r11 + (3.0 * u2 - w2) * r12 - (30.0 * u2 + 2.0 * w2) * f1;
b12 = 2.0 * u * r21 + (3.0 * u2 - w2) * r22 - (30.0 * u2 + 2.0 * w2) * f2;
b20 = r01 - (3.0 * u) * r02 - (24.0 * u) * f0;
b21 = r11 - (3.0 * u) * r12 - (24.0 * u) * f1;
b22 = r21 - (3.0 * u) * r22 - (24.0 * u) * f2;
b10 *= fden;
b11 *= fden;
b12 *= fden;
b20 *= fden;
b21 *= fden;
b22 *= fden;
B1 = b10 * unity + timesMinusI(b11) * iQ - b12 * iQ2;
B2 = b20 * unity + timesMinusI(b21) * iQ - b22 * iQ2;
USigmap = GaugeK * Sigmap;
tr1 = trace(USigmap * B1);
tr2 = trace(USigmap * B2);
GaugeLinkField QUS = iQ * USigmap;
GaugeLinkField USQ = USigmap * iQ;
GaugeLinkField iGamma = tr1 * iQ - timesI(tr2) * iQ2 +
timesI(f1) * USigmap + f2 * QUS + f2 * USQ;
iLambda = Ta(iGamma);
}
//====================================================================
public:
GaugeField*
ThinLinks; /*!< @brief Pointer to the thin
links configuration */
/*! @brief Standard constructor */
SmearedConfiguration(GridCartesian* UGrid, unsigned int Nsmear,
Smear_Stout<Gimpl>& Stout)
: smearingLevels(Nsmear), StoutSmearing(Stout), ThinLinks(NULL) {
for (unsigned int i = 0; i < smearingLevels; ++i)
SmearedSet.push_back(*(new GaugeField(UGrid)));
}
/*! For just thin links */
SmearedConfiguration()
: smearingLevels(0), StoutSmearing(), SmearedSet(), ThinLinks(NULL) {}
// attach the smeared routines to the thin links U and fill the smeared set
void set_GaugeField(GaugeField& U) { fill_smearedSet(U); }
//====================================================================
void smeared_force(GaugeField& SigmaTilde) const {
if (smearingLevels > 0) {
GaugeField force = SigmaTilde; // actually = U*SigmaTilde
GaugeLinkField tmp_mu(SigmaTilde._grid);
for (int mu = 0; mu < Nd; mu++) {
// to get just SigmaTilde
tmp_mu = adj(peekLorentz(SmearedSet[smearingLevels - 1], mu)) *
peekLorentz(force, mu);
pokeLorentz(force, tmp_mu, mu);
}
for (int ismr = smearingLevels - 1; ismr > 0; --ismr)
force = AnalyticSmearedForce(force, get_smeared_conf(ismr - 1));
force = AnalyticSmearedForce(force, *ThinLinks);
for (int mu = 0; mu < Nd; mu++) {
tmp_mu = peekLorentz(*ThinLinks, mu) * peekLorentz(force, mu);
pokeLorentz(SigmaTilde, tmp_mu, mu);
}
} // if smearingLevels = 0 do nothing
}
//====================================================================
GaugeField& get_SmearedU() { return SmearedSet[smearingLevels - 1]; }
GaugeField& get_U(bool smeared = false) {
// get the config, thin links by default
if (smeared) {
if (smearingLevels) {
RealD impl_plaq =
WilsonLoops<Gimpl>::avgPlaquette(SmearedSet[smearingLevels - 1]);
std::cout << GridLogDebug << "getting Usmr Plaq: " << impl_plaq
<< std::endl;
return get_SmearedU();
} else {
RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(*ThinLinks);
std::cout << GridLogDebug << "getting Thin Plaq: " << impl_plaq
<< std::endl;
return *ThinLinks;
}
} else {
RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(*ThinLinks);
std::cout << GridLogDebug << "getting Thin Plaq: " << impl_plaq
<< std::endl;
return *ThinLinks;
}
}
};
}
}
#endif

View File

@ -0,0 +1,9 @@
#ifndef GRID_QCD_SMEARING_H
#define GRID_QCD_SMEARING_H
#include <qcd/smearing/BaseSmearing.h>
#include <qcd/smearing/APEsmearing.h>
#include <qcd/smearing/StoutSmearing.h>
#include <qcd/smearing/GaugeConfiguration.h>
#endif

View File

@ -0,0 +1,160 @@
/*
@file stoutSmear.hpp
@brief Declares Stout smearing class
*/
#ifndef STOUT_SMEAR_
#define STOUT_SMEAR_
namespace Grid {
namespace QCD {
/*! @brief Stout smearing of link variable. */
template <class Gimpl>
class Smear_Stout : public Smear<Gimpl> {
private:
const Smear<Gimpl>* SmearBase;
public:
INHERIT_GIMPL_TYPES(Gimpl)
Smear_Stout(Smear<Gimpl>* base) : SmearBase(base) {
static_assert(Nc == 3,
"Stout smearing currently implemented only for Nc==3");
}
/*! Default constructor */
Smear_Stout(double rho = 1.0) : SmearBase(new Smear_APE<Gimpl>(rho)) {
static_assert(Nc == 3,
"Stout smearing currently implemented only for Nc==3");
}
~Smear_Stout() {} // delete SmearBase...
void smear(GaugeField& u_smr, const GaugeField& U) const {
GaugeField C(U._grid);
GaugeLinkField tmp(U._grid), iq_mu(U._grid), Umu(U._grid);
std::cout << GridLogDebug << "Stout smearing started\n";
// Smear the configurations
SmearBase->smear(C, U);
for (int mu = 0; mu < Nd; mu++) {
tmp = peekLorentz(C, mu);
Umu = peekLorentz(U, mu);
iq_mu = Ta(
tmp *
adj(Umu)); // iq_mu = Ta(Omega_mu) to match the signs with the paper
exponentiate_iQ(tmp, iq_mu);
pokeLorentz(u_smr, tmp * Umu, mu); // u_smr = exp(iQ_mu)*U_mu
}
std::cout << GridLogDebug << "Stout smearing completed\n";
};
void derivative(GaugeField& SigmaTerm, const GaugeField& iLambda,
const GaugeField& Gauge) const {
SmearBase->derivative(SigmaTerm, iLambda, Gauge);
};
void BaseSmear(GaugeField& C, const GaugeField& U) const {
SmearBase->smear(C, U);
};
void exponentiate_iQ(GaugeLinkField& e_iQ, const GaugeLinkField& iQ) const {
// Put this outside
// only valid for SU(3) matrices
// only one Lorentz direction at a time
// notice that it actually computes
// exp ( input matrix )
// the i sign is coming from outside
// input matrix is anti-hermitian NOT hermitian
GridBase* grid = iQ._grid;
GaugeLinkField unity(grid);
unity = 1.0;
GaugeLinkField iQ2(grid), iQ3(grid);
LatticeComplex u(grid), w(grid);
LatticeComplex f0(grid), f1(grid), f2(grid);
iQ2 = iQ * iQ;
iQ3 = iQ * iQ2;
set_uw(u, w, iQ2, iQ3);
set_fj(f0, f1, f2, u, w);
e_iQ = f0 * unity + timesMinusI(f1) * iQ - f2 * iQ2;
};
void set_uw(LatticeComplex& u, LatticeComplex& w, GaugeLinkField& iQ2,
GaugeLinkField& iQ3) const {
Complex one_over_three = 1.0 / 3.0;
Complex one_over_two = 1.0 / 2.0;
GridBase* grid = u._grid;
LatticeComplex c0(grid), c1(grid), tmp(grid), c0max(grid), theta(grid);
// sign in c0 from the conventions on the Ta
c0 = -imag(trace(iQ3)) * one_over_three;
c1 = -real(trace(iQ2)) * one_over_two;
// Cayley Hamilton checks to machine precision, tested
tmp = c1 * one_over_three;
c0max = 2.0 * pow(tmp, 1.5);
theta = acos(c0 / c0max) *
one_over_three; // divide by three here, now leave as it is
u = sqrt(tmp) * cos(theta);
w = sqrt(c1) * sin(theta);
}
void set_fj(LatticeComplex& f0, LatticeComplex& f1, LatticeComplex& f2,
const LatticeComplex& u, const LatticeComplex& w) const {
GridBase* grid = u._grid;
LatticeComplex xi0(grid), u2(grid), w2(grid), cosw(grid);
LatticeComplex fden(grid);
LatticeComplex h0(grid), h1(grid), h2(grid);
LatticeComplex e2iu(grid), emiu(grid), ixi0(grid), qt(grid);
LatticeComplex unity(grid);
unity = 1.0;
xi0 = func_xi0(w);
u2 = u * u;
w2 = w * w;
cosw = cos(w);
ixi0 = timesI(xi0);
emiu = cos(u) - timesI(sin(u));
e2iu = cos(2.0 * u) + timesI(sin(2.0 * u));
h0 = e2iu * (u2 - w2) +
emiu * ((8.0 * u2 * cosw) + (2.0 * u * (3.0 * u2 + w2) * ixi0));
h1 = e2iu * (2.0 * u) - emiu * ((2.0 * u * cosw) - (3.0 * u2 - w2) * ixi0);
h2 = e2iu - emiu * (cosw + (3.0 * u) * ixi0);
fden = unity / (9.0 * u2 - w2); // reals
f0 = h0 * fden;
f1 = h1 * fden;
f2 = h2 * fden;
}
LatticeComplex func_xi0(const LatticeComplex& w) const {
// Define a function to do the check
// if( w < 1e-4 ) std::cout << GridLogWarning<< "[Smear_stout] w too small:
// "<< w <<"\n";
return sin(w) / w;
}
LatticeComplex func_xi1(const LatticeComplex& w) const {
// Define a function to do the check
// if( w < 1e-4 ) std::cout << GridLogWarning << "[Smear_stout] w too small:
// "<< w <<"\n";
return cos(w) / (w * w) - sin(w) / (w * w * w);
}
};
}
}
#endif

View File

@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef QCD_UTILS_WILSON_LOOPS_H #ifndef QCD_UTILS_WILSON_LOOPS_H
@ -34,10 +35,8 @@ namespace Grid {
namespace QCD { namespace QCD {
// Common wilson loop observables // Common wilson loop observables
template<class Gimpl> template <class Gimpl> class WilsonLoops : public Gimpl {
class WilsonLoops : public Gimpl {
public: public:
INHERIT_GIMPL_TYPES(Gimpl); INHERIT_GIMPL_TYPES(Gimpl);
typedef typename Gimpl::GaugeLinkField GaugeMat; typedef typename Gimpl::GaugeLinkField GaugeMat;
@ -46,21 +45,25 @@ public:
////////////////////////////////////////////////// //////////////////////////////////////////////////
// directed plaquette oriented in mu,nu plane // directed plaquette oriented in mu,nu plane
////////////////////////////////////////////////// //////////////////////////////////////////////////
static void dirPlaquette(GaugeMat &plaq,const std::vector<GaugeMat> &U, const int mu, const int nu) static void dirPlaquette(GaugeMat &plaq, const std::vector<GaugeMat> &U,
{ const int mu, const int nu) {
// Annoyingly, must use either scope resolution to find dependent base class, // Annoyingly, must use either scope resolution to find dependent base
// or this-> ; there is no "this" in a static method. This forces explicit Gimpl scope // class,
// resolution throughout the usage in this file, and rather defeats the purpose of deriving // or this-> ; there is no "this" in a static method. This forces explicit
// Gimpl scope
// resolution throughout the usage in this file, and rather defeats the
// purpose of deriving
// from Gimpl. // from Gimpl.
plaq= Gimpl::CovShiftBackward(U[mu],mu, plaq = Gimpl::CovShiftBackward(
Gimpl::CovShiftBackward(U[nu],nu, U[mu], mu, Gimpl::CovShiftBackward(
Gimpl::CovShiftForward (U[mu],mu,U[nu]))); U[nu], nu, Gimpl::CovShiftForward(U[mu], mu, U[nu])));
} }
////////////////////////////////////////////////// //////////////////////////////////////////////////
// trace of directed plaquette oriented in mu,nu plane // trace of directed plaquette oriented in mu,nu plane
////////////////////////////////////////////////// //////////////////////////////////////////////////
static void traceDirPlaquette(LatticeComplex &plaq, const std::vector<GaugeMat> &U, const int mu, const int nu) static void traceDirPlaquette(LatticeComplex &plaq,
{ const std::vector<GaugeMat> &U, const int mu,
const int nu) {
GaugeMat sp(U[0]._grid); GaugeMat sp(U[0]._grid);
dirPlaquette(sp, U, mu, nu); dirPlaquette(sp, U, mu, nu);
plaq = trace(sp); plaq = trace(sp);
@ -68,8 +71,8 @@ public:
////////////////////////////////////////////////// //////////////////////////////////////////////////
// sum over all planes of plaquette // sum over all planes of plaquette
////////////////////////////////////////////////// //////////////////////////////////////////////////
static void sitePlaquette(LatticeComplex &Plaq,const std::vector<GaugeMat> &U) static void sitePlaquette(LatticeComplex &Plaq,
{ const std::vector<GaugeMat> &U) {
LatticeComplex sitePlaq(U[0]._grid); LatticeComplex sitePlaq(U[0]._grid);
Plaq = zero; Plaq = zero;
for (int mu = 1; mu < Nd; mu++) { for (int mu = 1; mu < Nd; mu++) {
@ -83,7 +86,7 @@ public:
// sum over all x,y,z,t and over all planes of plaquette // sum over all x,y,z,t and over all planes of plaquette
////////////////////////////////////////////////// //////////////////////////////////////////////////
static RealD sumPlaquette(const GaugeLorentz &Umu) { static RealD sumPlaquette(const GaugeLorentz &Umu) {
std::vector<GaugeMat> U(Nd,Umu._grid); std::vector<GaugeMat> U(4, Umu._grid);
for (int mu = 0; mu < Nd; mu++) { for (int mu = 0; mu < Nd; mu++) {
U[mu] = PeekIndex<LorentzIndex>(Umu, mu); U[mu] = PeekIndex<LorentzIndex>(Umu, mu);
@ -101,19 +104,20 @@ public:
// average over all x,y,z,t and over all planes of plaquette // average over all x,y,z,t and over all planes of plaquette
////////////////////////////////////////////////// //////////////////////////////////////////////////
static RealD avgPlaquette(const GaugeLorentz &Umu) { static RealD avgPlaquette(const GaugeLorentz &Umu) {
RealD sumplaq = sumPlaquette(Umu); RealD sumplaq = sumPlaquette(Umu);
double vol = Umu._grid->gSites(); double vol = Umu._grid->gSites();
double faces = (1.0 * Nd * (Nd - 1)) / 2.0; double faces = (1.0 * Nd * (Nd - 1)) / 2.0;
return sumplaq / vol / faces / Nc; // Nd , Nc dependent... FIXME return sumplaq / vol / faces / Nc; // Nd , Nc dependent... FIXME
} }
static RealD linkTrace(const GaugeLorentz &Umu){
std::vector<GaugeMat> U(Nd,Umu._grid);
LatticeComplex Tr(Umu._grid); Tr=zero; //////////////////////////////////////////////////
// average over traced single links
//////////////////////////////////////////////////
static RealD linkTrace(const GaugeLorentz &Umu) {
std::vector<GaugeMat> U(4, Umu._grid);
LatticeComplex Tr(Umu._grid);
Tr = zero;
for (int mu = 0; mu < Nd; mu++) { for (int mu = 0; mu < Nd; mu++) {
U[mu] = PeekIndex<LorentzIndex>(Umu, mu); U[mu] = PeekIndex<LorentzIndex>(Umu, mu);
Tr = Tr + trace(U[mu]); Tr = Tr + trace(U[mu]);
@ -124,8 +128,53 @@ public:
double vol = Umu._grid->gSites(); double vol = Umu._grid->gSites();
return p.real()/vol/((double)(Nd*(Nd-1))); return p.real() / vol / 4.0 / 3.0;
}; };
//////////////////////////////////////////////////
// the sum over all staples on each site in direction mu,nu
//////////////////////////////////////////////////
static void Staple(GaugeMat &staple, const GaugeLorentz &Umu, int mu,
int nu) {
GridBase *grid = Umu._grid;
std::vector<GaugeMat> U(4, grid);
for (int d = 0; d < Nd; d++) {
U[d] = PeekIndex<LorentzIndex>(Umu, d);
}
staple = zero;
if (nu != mu) {
// mu
// ^
// |__> nu
// __
// |
// __|
//
staple += Gimpl::ShiftStaple(
Gimpl::CovShiftForward(
U[nu], nu,
Gimpl::CovShiftBackward(
U[mu], mu, Gimpl::CovShiftIdentityBackward(U[nu], nu))),
mu);
// __
// |
// |__
//
//
staple += Gimpl::ShiftStaple(
Gimpl::CovShiftBackward(U[nu], nu,
Gimpl::CovShiftBackward(U[mu], mu, U[nu])),
mu);
}
}
////////////////////////////////////////////////// //////////////////////////////////////////////////
// the sum over all staples on each site // the sum over all staples on each site
////////////////////////////////////////////////// //////////////////////////////////////////////////
@ -140,7 +189,6 @@ public:
staple = zero; staple = zero;
GaugeMat tmp(grid); GaugeMat tmp(grid);
for (int nu = 0; nu < Nd; nu++) { for (int nu = 0; nu < Nd; nu++) {
if (nu != mu) { if (nu != mu) {
@ -155,9 +203,11 @@ public:
// //
staple += Gimpl::ShiftStaple( staple += Gimpl::ShiftStaple(
Gimpl::CovShiftForward (U[nu],nu, Gimpl::CovShiftForward(
Gimpl::CovShiftBackward(U[mu],mu, U[nu], nu,
Gimpl::CovShiftIdentityBackward(U[nu],nu))),mu); Gimpl::CovShiftBackward(
U[mu], mu, Gimpl::CovShiftIdentityBackward(U[nu], nu))),
mu);
// __ // __
// | // |
@ -166,30 +216,70 @@ public:
// //
staple += Gimpl::ShiftStaple( staple += Gimpl::ShiftStaple(
Gimpl::CovShiftBackward(U[nu], nu, Gimpl::CovShiftBackward(U[nu], nu,
Gimpl::CovShiftBackward(U[mu],mu,U[nu])),mu); Gimpl::CovShiftBackward(U[mu], mu, U[nu])),
mu);
} }
} }
} }
//////////////////////////////////////////////////
// the sum over all staples on each site in direction mu,nu, upper part
//////////////////////////////////////////////////
static void StapleUpper(GaugeMat &staple, const GaugeLorentz &Umu, int mu,
int nu) {
staple = zero;
if (nu != mu) {
GridBase *grid = Umu._grid;
std::vector<GaugeMat> U(4, grid);
for (int d = 0; d < Nd; d++) {
U[d] = PeekIndex<LorentzIndex>(Umu, d);
}
// mu
// ^
// |__> nu
// __
// |
// __|
//
staple += Gimpl::ShiftStaple(
Gimpl::CovShiftForward(
U[nu], nu,
Gimpl::CovShiftBackward(
U[mu], mu, Gimpl::CovShiftIdentityBackward(U[nu], nu))),
mu);
}
}
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
// Similar to above for rectangle is required // Similar to above for rectangle is required
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
static void dirRectangle(GaugeMat &rect,const std::vector<GaugeMat> &U, const int mu, const int nu) static void dirRectangle(GaugeMat &rect, const std::vector<GaugeMat> &U,
{ const int mu, const int nu) {
rect = Gimpl::CovShiftForward(U[mu],mu,Gimpl::CovShiftForward(U[mu],mu,U[nu]))* // ->->| rect = Gimpl::CovShiftForward(
adj(Gimpl::CovShiftForward(U[nu],nu,Gimpl::CovShiftForward(U[mu],mu,U[mu]))) ; U[mu], mu, Gimpl::CovShiftForward(U[mu], mu, U[nu])) * // ->->|
adj(Gimpl::CovShiftForward(
U[nu], nu, Gimpl::CovShiftForward(U[mu], mu, U[mu])));
rect = rect + rect = rect +
Gimpl::CovShiftForward(U[mu],mu,Gimpl::CovShiftForward(U[nu],nu,U[nu]))* // ->|| Gimpl::CovShiftForward(
adj(Gimpl::CovShiftForward(U[nu],nu,Gimpl::CovShiftForward(U[nu],nu,U[mu]))) ; U[mu], mu, Gimpl::CovShiftForward(U[nu], nu, U[nu])) * // ->||
adj(Gimpl::CovShiftForward(
U[nu], nu, Gimpl::CovShiftForward(U[nu], nu, U[mu])));
} }
static void traceDirRectangle(LatticeComplex &rect, const std::vector<GaugeMat> &U, const int mu, const int nu) static void traceDirRectangle(LatticeComplex &rect,
{ const std::vector<GaugeMat> &U, const int mu,
const int nu) {
GaugeMat sp(U[0]._grid); GaugeMat sp(U[0]._grid);
dirRectangle(sp, U, mu, nu); dirRectangle(sp, U, mu, nu);
rect = trace(sp); rect = trace(sp);
} }
static void siteRectangle(LatticeComplex &Rect,const std::vector<GaugeMat> &U) static void siteRectangle(LatticeComplex &Rect,
{ const std::vector<GaugeMat> &U) {
LatticeComplex siteRect(U[0]._grid); LatticeComplex siteRect(U[0]._grid);
Rect = zero; Rect = zero;
for (int mu = 1; mu < Nd; mu++) { for (int mu = 1; mu < Nd; mu++) {
@ -199,6 +289,7 @@ public:
} }
} }
} }
////////////////////////////////////////////////// //////////////////////////////////////////////////
// sum over all x,y,z,t and over all planes of plaquette // sum over all x,y,z,t and over all planes of plaquette
////////////////////////////////////////////////// //////////////////////////////////////////////////
@ -239,11 +330,14 @@ public:
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Hop by two optimisation strategy does not work nicely with Gparity. (could do, // Hop by two optimisation strategy does not work nicely with Gparity. (could
// do,
// but need to track two deep where cross boundary and apply a conjugation). // but need to track two deep where cross boundary and apply a conjugation).
// Must differentiate this in Gimpl, and use Gimpl::isPeriodicGaugeField to do so . // Must differentiate this in Gimpl, and use Gimpl::isPeriodicGaugeField to do
// so .
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
static void RectStapleOptimised(GaugeMat &Stap,std::vector<GaugeMat> &U2,std::vector<GaugeMat> &U,int mu){ static void RectStapleOptimised(GaugeMat &Stap, std::vector<GaugeMat> &U2,
std::vector<GaugeMat> &U, int mu) {
Stap = zero; Stap = zero;
@ -263,14 +357,12 @@ public:
Staple2x1 = Gimpl::CovShiftForward(U[nu], nu, tmp); Staple2x1 = Gimpl::CovShiftForward(U[nu], nu, tmp);
// Down staple // Down staple
// |___ ___| // |___ ___|
// //
tmp = adj(U2[mu]) * U[nu]; tmp = adj(U2[mu]) * U[nu];
Staple2x1 += Gimpl::CovShiftBackward(U[nu], nu, Cshift(tmp, mu, -2)); Staple2x1 += Gimpl::CovShiftBackward(U[nu], nu, Cshift(tmp, mu, -2));
// ___ ___ // ___ ___
// | ___| // | ___|
// |___ ___| // |___ ___|
@ -285,7 +377,8 @@ public:
// tmp= Staple2x1* Cshift(U[mu],mu,-2); // tmp= Staple2x1* Cshift(U[mu],mu,-2);
// Stap+= Cshift(tmp,mu,1) ; // Stap+= Cshift(tmp,mu,1) ;
Stap+= Cshift(Staple2x1,mu,1)*Cshift(U[mu],mu,-1); ; Stap += Cshift(Staple2x1, mu, 1) * Cshift(U[mu], mu, -1);
;
// -- // --
// | | // | |
@ -306,19 +399,16 @@ public:
tmp = adj(U2[nu]) * tmp; tmp = adj(U2[nu]) * tmp;
tmp = Cshift(tmp, nu, -2); tmp = Cshift(tmp, nu, -2);
Stap += Cshift(tmp, mu, 1); Stap += Cshift(tmp, mu, 1);
}} }
}
} }
static void RectStaple(GaugeMat &Stap,const GaugeLorentz & Umu,int mu) static void RectStaple(GaugeMat &Stap, const GaugeLorentz &Umu, int mu) {
{
RectStapleUnoptimised(Stap, Umu, mu); RectStapleUnoptimised(Stap, Umu, mu);
} }
static void RectStaple(const GaugeLorentz &Umu, GaugeMat &Stap, static void RectStaple(const GaugeLorentz &Umu, GaugeMat &Stap,
std::vector<GaugeMat> &U2, std::vector<GaugeMat> &U2, std::vector<GaugeMat> &U,
std::vector<GaugeMat> &U, int mu) int mu) {
{
if (Gimpl::isPeriodicGaugeField()) { if (Gimpl::isPeriodicGaugeField()) {
RectStapleOptimised(Stap, U2, U, mu); RectStapleOptimised(Stap, U2, U, mu);
} else { } else {
@ -326,7 +416,8 @@ public:
} }
} }
static void RectStapleUnoptimised(GaugeMat &Stap,const GaugeLorentz &Umu,int mu){ static void RectStapleUnoptimised(GaugeMat &Stap, const GaugeLorentz &Umu,
int mu) {
GridBase *grid = Umu._grid; GridBase *grid = Umu._grid;
std::vector<GaugeMat> U(Nd, grid); std::vector<GaugeMat> U(Nd, grid);
@ -342,38 +433,52 @@ public:
// | __ | // | __ |
// //
Stap += Gimpl::ShiftStaple( Stap += Gimpl::ShiftStaple(
Gimpl::CovShiftForward (U[mu],mu, Gimpl::CovShiftForward(
Gimpl::CovShiftForward (U[nu],nu, U[mu], mu,
Gimpl::CovShiftBackward(U[mu],mu, Gimpl::CovShiftForward(
Gimpl::CovShiftBackward(U[mu],mu, U[nu], nu,
Gimpl::CovShiftIdentityBackward(U[nu],nu))))) , mu); Gimpl::CovShiftBackward(
U[mu], mu,
Gimpl::CovShiftBackward(
U[mu], mu,
Gimpl::CovShiftIdentityBackward(U[nu], nu))))),
mu);
// __ // __
// |__ __ | // |__ __ |
Stap += Gimpl::ShiftStaple( Stap += Gimpl::ShiftStaple(
Gimpl::CovShiftForward (U[mu],mu, Gimpl::CovShiftForward(
Gimpl::CovShiftBackward(U[nu],nu, U[mu], mu,
Gimpl::CovShiftBackward(U[mu],mu, Gimpl::CovShiftBackward(
Gimpl::CovShiftBackward(U[mu],mu, U[nu])))) , mu); U[nu], nu,
Gimpl::CovShiftBackward(
U[mu], mu, Gimpl::CovShiftBackward(U[mu], mu, U[nu])))),
mu);
// __ // __
// |__ __ | // |__ __ |
Stap += Gimpl::ShiftStaple( Stap += Gimpl::ShiftStaple(
Gimpl::CovShiftBackward(U[nu],nu, Gimpl::CovShiftBackward(
Gimpl::CovShiftBackward(U[mu],mu, U[nu], nu,
Gimpl::CovShiftBackward(U[mu],mu, Gimpl::CovShiftBackward(
Gimpl::CovShiftForward(U[nu],nu,U[mu])))) , mu); U[mu], mu,
Gimpl::CovShiftBackward(
U[mu], mu, Gimpl::CovShiftForward(U[nu], nu, U[mu])))),
mu);
// __ ___ // __ ___
// |__ | // |__ |
Stap += Gimpl::ShiftStaple( Stap += Gimpl::ShiftStaple(
Gimpl::CovShiftForward (U[nu],nu, Gimpl::CovShiftForward(
Gimpl::CovShiftBackward(U[mu],mu, U[nu], nu,
Gimpl::CovShiftBackward(U[mu],mu, Gimpl::CovShiftBackward(
Gimpl::CovShiftBackward(U[nu],nu,U[mu])))) , mu); U[mu], mu,
Gimpl::CovShiftBackward(
U[mu], mu, Gimpl::CovShiftBackward(U[nu], nu, U[mu])))),
mu);
// -- // --
// | | // | |
@ -381,12 +486,16 @@ public:
// | | // | |
Stap += Gimpl::ShiftStaple( Stap += Gimpl::ShiftStaple(
Gimpl::CovShiftForward(U[nu],nu, Gimpl::CovShiftForward(
Gimpl::CovShiftForward(U[nu],nu, U[nu], nu,
Gimpl::CovShiftBackward(U[mu],mu, Gimpl::CovShiftForward(
Gimpl::CovShiftBackward(U[nu],nu, U[nu], nu,
Gimpl::CovShiftIdentityBackward(U[nu],nu))))) , mu); Gimpl::CovShiftBackward(
U[mu], mu,
Gimpl::CovShiftBackward(
U[nu], nu,
Gimpl::CovShiftIdentityBackward(U[nu], nu))))),
mu);
// | | // | |
// //
@ -394,22 +503,23 @@ public:
// -- // --
Stap += Gimpl::ShiftStaple( Stap += Gimpl::ShiftStaple(
Gimpl::CovShiftBackward(U[nu],nu, Gimpl::CovShiftBackward(
Gimpl::CovShiftBackward(U[nu],nu, U[nu], nu,
Gimpl::CovShiftBackward(U[mu],mu, Gimpl::CovShiftBackward(
Gimpl::CovShiftForward (U[nu],nu,U[nu])))) , mu); U[nu], nu,
}} Gimpl::CovShiftBackward(
U[mu], mu, Gimpl::CovShiftForward(U[nu], nu, U[nu])))),
mu);
}
}
} }
}; };
typedef WilsonLoops<PeriodicGimplR> ColourWilsonLoops; typedef WilsonLoops<PeriodicGimplR> ColourWilsonLoops;
typedef WilsonLoops<PeriodicGimplR> U1WilsonLoops; typedef WilsonLoops<PeriodicGimplR> U1WilsonLoops;
typedef WilsonLoops<PeriodicGimplR> SU2WilsonLoops; typedef WilsonLoops<PeriodicGimplR> SU2WilsonLoops;
typedef WilsonLoops<PeriodicGimplR> SU3WilsonLoops; typedef WilsonLoops<PeriodicGimplR> SU3WilsonLoops;
}
}} }
#endif #endif

View File

@ -25,7 +25,8 @@ Author: neo <cossu@post.kek.jp>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -64,10 +65,12 @@ namespace Grid {
////////////////////////////////////// //////////////////////////////////////
// To take the floating point type of real/complex type // To take the floating point type of real/complex type
////////////////////////////////////// //////////////////////////////////////
template <typename T> struct RealPart { template <typename T>
struct RealPart {
typedef T type; typedef T type;
}; };
template <typename T> struct RealPart< std::complex<T> >{ template <typename T>
struct RealPart<std::complex<T> > {
typedef T type; typedef T type;
}; };
@ -76,24 +79,36 @@ namespace Grid {
////////////////////////////////////// //////////////////////////////////////
// type alias used to simplify the syntax of std::enable_if // type alias used to simplify the syntax of std::enable_if
template <typename T> using Invoke = typename T::type; template <typename T>
template <typename Condition, typename ReturnType> using EnableIf = Invoke<std::enable_if<Condition::value, ReturnType> >; using Invoke = typename T::type;
template <typename Condition, typename ReturnType> using NotEnableIf= Invoke<std::enable_if<!Condition::value, ReturnType> >; template <typename Condition, typename ReturnType>
using EnableIf = Invoke<std::enable_if<Condition::value, ReturnType> >;
template <typename Condition, typename ReturnType>
using NotEnableIf = Invoke<std::enable_if<!Condition::value, ReturnType> >;
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// 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>
template <> struct is_complex<std::complex<double> >: public std::true_type {}; struct is_complex : public std::false_type {};
template <> struct is_complex<std::complex<float> > : public std::true_type {}; template <>
struct is_complex<std::complex<double> > : public std::true_type {};
template <>
struct is_complex<std::complex<float> > : public std::true_type {};
template <typename T> using IfReal = Invoke<std::enable_if<std::is_floating_point<T>::value,int> > ; template <typename T>
template <typename T> using IfComplex = Invoke<std::enable_if<is_complex<T>::value,int> > ; using IfReal = Invoke<std::enable_if<std::is_floating_point<T>::value, int> >;
template <typename T> using IfInteger = Invoke<std::enable_if<std::is_integral<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 IfNotReal = Invoke<std::enable_if<!std::is_floating_point<T>::value,int> > ; template <typename T>
template <typename T> using IfNotComplex = Invoke<std::enable_if<!is_complex<T>::value,int> > ; using IfNotReal =
template <typename T> using IfNotInteger = Invoke<std::enable_if<!std::is_integral<T>::value,int> > ; Invoke<std::enable_if<!std::is_floating_point<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> >;
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
// Define the operation templates functors // Define the operation templates functors
@ -111,33 +126,36 @@ namespace Grid {
} }
/////////////////////////////////////////////// ///////////////////////////////////////////////
/* /*
@brief Grid_simd class for the SIMD vector type operations @brief Grid_simd class for the SIMD vector type operations
*/ */
template <class Scalar_type, class Vector_type> template <class Scalar_type, class Vector_type>
class Grid_simd { class Grid_simd {
public: public:
typedef typename RealPart<Scalar_type>::type Real; typedef typename RealPart<Scalar_type>::type Real;
typedef Vector_type vector_type; typedef Vector_type vector_type;
typedef Scalar_type scalar_type; typedef Scalar_type scalar_type;
typedef union conv_t_union { typedef union conv_t_union {
Vector_type v; Vector_type v;
Scalar_type s[sizeof(Vector_type) / sizeof(Scalar_type)]; Scalar_type s[sizeof(Vector_type) / sizeof(Scalar_type)];
conv_t_union(){}; conv_t_union(){};
} conv_t; } conv_t;
Vector_type v; Vector_type v;
static inline int Nsimd(void) { return sizeof(Vector_type)/sizeof(Scalar_type);} static inline int Nsimd(void) {
return sizeof(Vector_type) / sizeof(Scalar_type);
}
Grid_simd& operator=(const Grid_simd&& rhs){v=rhs.v;return *this;}; Grid_simd &operator=(const Grid_simd &&rhs) {
Grid_simd& operator=(const Grid_simd& rhs){v=rhs.v;return *this;}; //faster than not declaring it and leaving to the compiler v = rhs.v;
return *this;
};
Grid_simd &operator=(const Grid_simd &rhs) {
v = rhs.v;
return *this;
}; // faster than not declaring it and leaving to the compiler
Grid_simd() = default; Grid_simd() = default;
Grid_simd(const Grid_simd &rhs) : v(rhs.v){}; // compiles in movaps Grid_simd(const Grid_simd &rhs) : v(rhs.v){}; // compiles in movaps
Grid_simd(const Grid_simd &&rhs) : v(rhs.v){}; Grid_simd(const Grid_simd &&rhs) : v(rhs.v){};
@ -156,31 +174,76 @@ namespace Grid {
vsplat(*this, a); vsplat(*this, a);
}; };
Grid_simd(const Real a){ Grid_simd(const Real a) { vsplat(*this, Scalar_type(a)); };
vsplat(*this,Scalar_type(a));
};
/////////////////////////////////////////////// ///////////////////////////////////////////////
// mac, mult, sub, add, adj // mac, mult, sub, add, adj
/////////////////////////////////////////////// ///////////////////////////////////////////////
// FIXME -- alias this to an inline MAC struct. // FIXME -- alias this to an inline MAC struct.
friend inline void mac (Grid_simd * __restrict__ y,const Grid_simd * __restrict__ a,const Grid_simd *__restrict__ x){ *y = (*a)*(*x)+(*y); }; friend inline void mac(Grid_simd *__restrict__ y,
const Grid_simd *__restrict__ a,
const Grid_simd *__restrict__ x) {
*y = (*a) * (*x) + (*y);
};
friend inline void mult(Grid_simd *__restrict__ y,
const Grid_simd *__restrict__ l,
const Grid_simd *__restrict__ r) {
*y = (*l) * (*r);
}
friend inline void sub(Grid_simd *__restrict__ y,
const Grid_simd *__restrict__ l,
const Grid_simd *__restrict__ r) {
*y = (*l) - (*r);
}
friend inline void add(Grid_simd *__restrict__ y,
const Grid_simd *__restrict__ l,
const Grid_simd *__restrict__ r) {
*y = (*l) + (*r);
}
friend inline void mult(Grid_simd * __restrict__ y,const Grid_simd * __restrict__ l,const Grid_simd *__restrict__ r){ *y = (*l) * (*r); } friend inline void mac(Grid_simd *__restrict__ y,
friend inline void sub (Grid_simd * __restrict__ y,const Grid_simd * __restrict__ l,const Grid_simd *__restrict__ r){ *y = (*l) - (*r); } const Scalar_type *__restrict__ a,
friend inline void add (Grid_simd * __restrict__ y,const Grid_simd * __restrict__ l,const Grid_simd *__restrict__ r){ *y = (*l) + (*r); } const Grid_simd *__restrict__ x) {
*y = (*a) * (*x) + (*y);
};
friend inline void mult(Grid_simd *__restrict__ y,
const Scalar_type *__restrict__ l,
const Grid_simd *__restrict__ r) {
*y = (*l) * (*r);
}
friend inline void sub(Grid_simd *__restrict__ y,
const Scalar_type *__restrict__ l,
const Grid_simd *__restrict__ r) {
*y = (*l) - (*r);
}
friend inline void add(Grid_simd *__restrict__ y,
const Scalar_type *__restrict__ l,
const Grid_simd *__restrict__ r) {
*y = (*l) + (*r);
}
friend inline void mac (Grid_simd *__restrict__ y,const Scalar_type *__restrict__ a,const Grid_simd *__restrict__ x){ *y = (*a)*(*x)+(*y); }; friend inline void mac(Grid_simd *__restrict__ y,
friend inline void mult(Grid_simd *__restrict__ y,const Scalar_type *__restrict__ l,const Grid_simd *__restrict__ r){ *y = (*l) * (*r); } const Grid_simd *__restrict__ a,
friend inline void sub (Grid_simd *__restrict__ y,const Scalar_type *__restrict__ l,const Grid_simd *__restrict__ r){ *y = (*l) - (*r); } const Scalar_type *__restrict__ x) {
friend inline void add (Grid_simd *__restrict__ y,const Scalar_type *__restrict__ l,const Grid_simd *__restrict__ r){ *y = (*l) + (*r); } *y = (*a) * (*x) + (*y);
};
friend inline void mac (Grid_simd *__restrict__ y,const Grid_simd *__restrict__ a,const Scalar_type *__restrict__ x){ *y = (*a)*(*x)+(*y); }; friend inline void mult(Grid_simd *__restrict__ y,
friend inline void mult(Grid_simd *__restrict__ y,const Grid_simd *__restrict__ l,const Scalar_type *__restrict__ r){ *y = (*l) * (*r); } const Grid_simd *__restrict__ l,
friend inline void sub (Grid_simd *__restrict__ y,const Grid_simd *__restrict__ l,const Scalar_type *__restrict__ r){ *y = (*l) - (*r); } const Scalar_type *__restrict__ r) {
friend inline void add (Grid_simd *__restrict__ y,const Grid_simd *__restrict__ l,const Scalar_type *__restrict__ r){ *y = (*l) + (*r); } *y = (*l) * (*r);
}
friend inline void sub(Grid_simd *__restrict__ y,
const Grid_simd *__restrict__ l,
const Scalar_type *__restrict__ r) {
*y = (*l) - (*r);
}
friend inline void add(Grid_simd *__restrict__ y,
const Grid_simd *__restrict__ l,
const Scalar_type *__restrict__ r) {
*y = (*l) + (*r);
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// FIXME: gonna remove these load/store, get, set, prefetch // FIXME: gonna remove these load/store, get, set, prefetch
@ -199,16 +262,14 @@ namespace Grid {
/////////////////////// ///////////////////////
// Vprefetch // Vprefetch
/////////////////////// ///////////////////////
friend inline void vprefetch(const Grid_simd &v) friend inline void vprefetch(const Grid_simd &v) {
{
prefetch_HINT_T0((const char *)&v.v); prefetch_HINT_T0((const char *)&v.v);
} }
/////////////////////// ///////////////////////
// Reduce // Reduce
/////////////////////// ///////////////////////
friend inline Scalar_type Reduce(const Grid_simd & in) friend inline Scalar_type Reduce(const Grid_simd &in) {
{
return unary<Scalar_type>(in.v, ReduceSIMD<Scalar_type, Vector_type>()); return unary<Scalar_type>(in.v, ReduceSIMD<Scalar_type, Vector_type>());
} }
@ -255,7 +316,8 @@ namespace Grid {
// provides support // provides support
/////////////////////////////////////// ///////////////////////////////////////
template<class functor> friend inline Grid_simd SimdApply (const functor &func,const Grid_simd &v) { template <class functor>
friend inline Grid_simd SimdApply(const functor &func, const Grid_simd &v) {
Grid_simd ret; Grid_simd ret;
Grid_simd::conv_t conv; Grid_simd::conv_t conv;
@ -266,7 +328,10 @@ namespace Grid {
ret.v = conv.v; ret.v = conv.v;
return ret; return ret;
} }
template<class functor> friend inline Grid_simd SimdApplyBinop (const functor &func,const Grid_simd &x,const Grid_simd &y) { template <class functor>
friend inline Grid_simd SimdApplyBinop(const functor &func,
const Grid_simd &x,
const Grid_simd &y) {
Grid_simd ret; Grid_simd ret;
Grid_simd::conv_t cx; Grid_simd::conv_t cx;
Grid_simd::conv_t cy; Grid_simd::conv_t cy;
@ -297,19 +362,27 @@ namespace Grid {
friend inline void permute3(Grid_simd &y, Grid_simd b) { friend inline void permute3(Grid_simd &y, Grid_simd b) {
y.v = Optimization::Permute::Permute3(b.v); y.v = Optimization::Permute::Permute3(b.v);
} }
friend inline void permute(Grid_simd &y,Grid_simd b,int perm) friend inline void permute(Grid_simd &y, Grid_simd b, int perm) {
{
if (perm & RotateBit) { if (perm & RotateBit) {
int dist = perm & 0xF; int dist = perm & 0xF;
y = rotate(b, dist); y = rotate(b, dist);
return; return;
} }
switch (perm) { switch (perm) {
case 3: permute3(y,b); break; case 3:
case 2: permute2(y,b); break; permute3(y, b);
case 1: permute1(y,b); break; break;
case 0: permute0(y,b); break; case 2:
default: assert(0); permute2(y, b);
break;
case 1:
permute1(y, b);
break;
case 0:
permute0(y, b);
break;
default:
assert(0);
} }
} }
@ -319,8 +392,7 @@ namespace Grid {
// General rotate // General rotate
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
template <class S, class V, IfNotComplex<S> = 0> template <class S, class V, IfNotComplex<S> = 0>
inline Grid_simd<S,V> rotate(Grid_simd<S,V> b,int nrot) inline Grid_simd<S, V> rotate(Grid_simd<S, V> b, int nrot) {
{
nrot = nrot % Grid_simd<S, V>::Nsimd(); nrot = nrot % Grid_simd<S, V>::Nsimd();
Grid_simd<S, V> ret; Grid_simd<S, V> ret;
// std::cout << "Rotate Real by "<<nrot<<std::endl; // std::cout << "Rotate Real by "<<nrot<<std::endl;
@ -328,8 +400,7 @@ namespace Grid {
return ret; return ret;
} }
template <class S, class V, IfComplex<S> = 0> template <class S, class V, IfComplex<S> = 0>
inline Grid_simd<S,V> rotate(Grid_simd<S,V> b,int nrot) inline Grid_simd<S, V> rotate(Grid_simd<S, V> b, int nrot) {
{
nrot = nrot % Grid_simd<S, V>::Nsimd(); nrot = nrot % Grid_simd<S, V>::Nsimd();
Grid_simd<S, V> ret; Grid_simd<S, V> ret;
// std::cout << "Rotate Complex by "<<nrot<<std::endl; // std::cout << "Rotate Complex by "<<nrot<<std::endl;
@ -348,11 +419,13 @@ namespace Grid {
} }
// overload if complex // overload if complex
template <class S,class V> inline void vsplat(Grid_simd<S,V> &ret, EnableIf<is_complex < S >, S> c) { template <class S, class V>
inline void vsplat(Grid_simd<S, V> &ret, EnableIf<is_complex<S>, S> c) {
vsplat(ret, real(c), imag(c)); vsplat(ret, real(c), imag(c));
} }
//if real fill with a, if complex fill with a in the real part (first function above) // if real fill with a, if complex fill with a in the real part (first function
// above)
template <class S, class V> template <class S, class V>
inline void vsplat(Grid_simd<S, V> &ret, NotEnableIf<is_complex<S>, S> a) { inline void vsplat(Grid_simd<S, V> &ret, NotEnableIf<is_complex<S>, S> a) {
ret.v = unary<V>(a, VsplatSIMD()); ret.v = unary<V>(a, VsplatSIMD());
@ -363,24 +436,60 @@ namespace Grid {
// Initialise to 1,0,i for the correct types // Initialise to 1,0,i for the correct types
/////////////////////////////////////////////// ///////////////////////////////////////////////
// For complex types // For complex types
template <class S,class V, IfComplex<S> = 0 > inline void vone(Grid_simd<S,V> &ret) { vsplat(ret,S(1.0,0.0)); } template <class S, class V, IfComplex<S> = 0>
template <class S,class V, IfComplex<S> = 0 > inline void vzero(Grid_simd<S,V> &ret) { vsplat(ret,S(0.0,0.0)); }// use xor? inline void vone(Grid_simd<S, V> &ret) {
template <class S,class V, IfComplex<S> = 0 > inline void vcomplex_i(Grid_simd<S,V> &ret){ vsplat(ret,S(0.0,1.0));} vsplat(ret, S(1.0, 0.0));
}
template <class S, class V, IfComplex<S> = 0>
inline void vzero(Grid_simd<S, V> &ret) {
vsplat(ret, S(0.0, 0.0));
} // use xor?
template <class S, class V, IfComplex<S> = 0>
inline void vcomplex_i(Grid_simd<S, V> &ret) {
vsplat(ret, S(0.0, 1.0));
}
template <class S,class V, IfComplex<S> = 0 > inline void visign(Grid_simd<S,V> &ret){ vsplat(ret,S(1.0,-1.0));} template <class S, class V, IfComplex<S> = 0>
template <class S,class V, IfComplex<S> = 0 > inline void vrsign(Grid_simd<S,V> &ret){ vsplat(ret,S(-1.0,1.0));} inline void visign(Grid_simd<S, V> &ret) {
vsplat(ret, S(1.0, -1.0));
}
template <class S, class V, IfComplex<S> = 0>
inline void vrsign(Grid_simd<S, V> &ret) {
vsplat(ret, S(-1.0, 1.0));
}
// if not complex overload here // if not complex overload here
template <class S,class V, IfReal<S> = 0 > inline void vone (Grid_simd<S,V> &ret){ vsplat(ret,S(1.0)); } template <class S, class V, IfReal<S> = 0>
template <class S,class V, IfReal<S> = 0 > inline void vzero(Grid_simd<S,V> &ret){ vsplat(ret,S(0.0)); } inline void vone(Grid_simd<S, V> &ret) {
vsplat(ret, S(1.0));
}
template <class S, class V, IfReal<S> = 0>
inline void vzero(Grid_simd<S, V> &ret) {
vsplat(ret, S(0.0));
}
// For integral types // For integral types
template <class S,class V,IfInteger<S> = 0 > inline void vone(Grid_simd<S,V> &ret) {vsplat(ret,1); } template <class S, class V, IfInteger<S> = 0>
template <class S,class V,IfInteger<S> = 0 > inline void vzero(Grid_simd<S,V> &ret) {vsplat(ret,0); } inline void vone(Grid_simd<S, V> &ret) {
template <class S,class V,IfInteger<S> = 0 > inline void vtrue (Grid_simd<S,V> &ret){vsplat(ret,0xFFFFFFFF);} vsplat(ret, 1);
template <class S,class V,IfInteger<S> = 0 > inline void vfalse(Grid_simd<S,V> &ret){vsplat(ret,0);} }
template <class S, class V, IfInteger<S> = 0>
inline void vzero(Grid_simd<S, V> &ret) {
vsplat(ret, 0);
}
template <class S, class V, IfInteger<S> = 0>
inline void vtrue(Grid_simd<S, V> &ret) {
vsplat(ret, 0xFFFFFFFF);
}
template <class S, class V, IfInteger<S> = 0>
inline void vfalse(Grid_simd<S, V> &ret) {
vsplat(ret, 0);
}
template<class S,class V> inline void zeroit(Grid_simd<S,V> &z){ vzero(z);} template <class S, class V>
inline void zeroit(Grid_simd<S, V> &z) {
vzero(z);
}
/////////////////////// ///////////////////////
// Vstream // Vstream
@ -403,33 +512,36 @@ namespace Grid {
//////////////////////////////////// ////////////////////////////////////
// Arithmetic operator overloads +,-,* // Arithmetic operator overloads +,-,*
//////////////////////////////////// ////////////////////////////////////
template<class S,class V> inline Grid_simd<S,V> operator + (Grid_simd<S,V> a, Grid_simd<S,V> b) { template <class S, class V>
inline Grid_simd<S, V> operator+(Grid_simd<S, V> a, Grid_simd<S, V> b) {
Grid_simd<S, V> ret; Grid_simd<S, V> ret;
ret.v = binary<V>(a.v, b.v, SumSIMD()); ret.v = binary<V>(a.v, b.v, SumSIMD());
return ret; return ret;
}; };
template<class S,class V> inline Grid_simd<S,V> operator - (Grid_simd<S,V> a, Grid_simd<S,V> b) { template <class S, class V>
inline Grid_simd<S, V> operator-(Grid_simd<S, V> a, Grid_simd<S, V> b) {
Grid_simd<S, V> ret; Grid_simd<S, V> ret;
ret.v = binary<V>(a.v, b.v, SubSIMD()); ret.v = binary<V>(a.v, b.v, SubSIMD());
return ret; return ret;
}; };
// Distinguish between complex types and others // Distinguish between complex types and others
template<class S,class V, IfComplex<S> = 0 > inline Grid_simd<S,V> operator * (Grid_simd<S,V> a, Grid_simd<S,V> b) { template <class S, class V, IfComplex<S> = 0>
inline Grid_simd<S, V> operator*(Grid_simd<S, V> a, Grid_simd<S, V> b) {
Grid_simd<S, V> ret; Grid_simd<S, V> ret;
ret.v = binary<V>(a.v, b.v, MultComplexSIMD()); ret.v = binary<V>(a.v, b.v, MultComplexSIMD());
return ret; return ret;
}; };
// Real/Integer types // Real/Integer types
template<class S,class V, IfNotComplex<S> = 0 > inline Grid_simd<S,V> operator * (Grid_simd<S,V> a, Grid_simd<S,V> b) { template <class S, class V, IfNotComplex<S> = 0>
inline Grid_simd<S, V> operator*(Grid_simd<S, V> a, Grid_simd<S, V> b) {
Grid_simd<S, V> ret; Grid_simd<S, V> ret;
ret.v = binary<V>(a.v, b.v, MultSIMD()); ret.v = binary<V>(a.v, b.v, MultSIMD());
return ret; return ret;
}; };
/////////////////////// ///////////////////////
// Conjugate // Conjugate
/////////////////////// ///////////////////////
@ -439,13 +551,16 @@ namespace Grid {
ret.v = unary<V>(in.v, ConjSIMD()); ret.v = unary<V>(in.v, ConjSIMD());
return ret; return ret;
} }
template <class S,class V, IfNotComplex<S> = 0 > inline Grid_simd<S,V> conjugate(const Grid_simd<S,V> &in){ template <class S, class V, IfNotComplex<S> = 0>
inline Grid_simd<S, V> conjugate(const Grid_simd<S, V> &in) {
return in; // for real objects return in; // for real objects
} }
// Suppress adj for integer types... // odd; why conjugate above but not adj?? // Suppress adj for integer types... // odd; why conjugate above but not adj??
template <class S, class V, IfNotInteger<S> = 0> template <class S, class V, IfNotInteger<S> = 0>
inline Grid_simd<S,V> adj(const Grid_simd<S,V> &in){ return conjugate(in); } inline Grid_simd<S, V> adj(const Grid_simd<S, V> &in) {
return conjugate(in);
}
/////////////////////// ///////////////////////
// timesMinusI // timesMinusI
@ -492,14 +607,14 @@ namespace Grid {
///////////////////// /////////////////////
template <class S, class V> template <class S, class V>
inline Grid_simd< S, V> innerProduct(const Grid_simd< S, V> & l, const Grid_simd< S, V> & r) inline Grid_simd<S, V> innerProduct(const Grid_simd<S, V> &l,
{ const Grid_simd<S, V> &r) {
return conjugate(l) * r; return conjugate(l) * r;
} }
template <class S, class V> template <class S, class V>
inline Grid_simd< S, V> outerProduct(const Grid_simd< S, V> &l, const Grid_simd< S, V> & r) inline Grid_simd<S, V> outerProduct(const Grid_simd<S, V> &l,
{ const Grid_simd<S, V> &r) {
return l * conjugate(r); return l * conjugate(r);
} }
@ -508,7 +623,6 @@ namespace Grid {
return arg; return arg;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// copy/splat complex real parts into real; // copy/splat complex real parts into real;
// insert real into complex and zero imag; // insert real into complex and zero imag;
@ -516,12 +630,11 @@ namespace Grid {
// real = toReal( complex ) // real = toReal( complex )
template <class S, class V, IfReal<S> = 0> template <class S, class V, IfReal<S> = 0>
inline Grid_simd<S,V> toReal(const Grid_simd<std::complex<S>,V> &in) inline Grid_simd<S, V> toReal(const Grid_simd<std::complex<S>, V> &in) {
{
typedef Grid_simd<S, V> simd; typedef Grid_simd<S, V> simd;
simd ret; simd ret;
typename simd::conv_t conv; typename simd::conv_t conv;
conv.v = in.v; conv.v = in.v; // copy the vector content (bytewise)
for (int i = 0; i < simd::Nsimd(); i += 2) { for (int i = 0; i < simd::Nsimd(); i += 2) {
conv.s[i + 1] = conv.s[i]; // duplicate (r,r);(r,r);(r,r); etc... conv.s[i + 1] = conv.s[i]; // duplicate (r,r);(r,r);(r,r); etc...
} }
@ -531,16 +644,17 @@ namespace Grid {
// complex = toComplex( real ) // complex = toComplex( real )
template <class R, class V, IfReal<R> = 0> // must be a real arg template <class R, class V, IfReal<R> = 0> // must be a real arg
inline Grid_simd<std::complex<R>,V> toComplex (const Grid_simd<R,V> &in) inline Grid_simd<std::complex<R>, V> toComplex(const Grid_simd<R, V> &in) {
{
typedef Grid_simd<R, V> Rsimd; typedef Grid_simd<R, V> Rsimd;
typedef Grid_simd<std::complex<R>, V> Csimd; typedef Grid_simd<std::complex<R>, V> Csimd;
typename Rsimd::conv_t conv; // address as real typename Rsimd::conv_t conv; // address as real
conv.v = in.v; conv.v = in.v;
for (int i = 0; i < Rsimd::Nsimd(); i += 2) { for (int i = 0; i < Rsimd::Nsimd(); i += 2) {
assert(conv.s[i+1]==conv.s[i]); // trap any cases where real was not duplicated assert(conv.s[i + 1] ==
// indicating the SIMD grids of real and imag assignment did not correctly match conv.s[i]); // trap any cases where real was not duplicated
// indicating the SIMD grids of real and imag assignment did not correctly
// match
conv.s[i + 1] = 0.0; // zero imaginary parts conv.s[i + 1] = 0.0; // zero imaginary parts
} }
Csimd ret; Csimd ret;
@ -560,16 +674,23 @@ namespace Grid {
///////////////////////////////////////// /////////////////////////////////////////
// Some traits to recognise the types // Some traits to recognise the types
///////////////////////////////////////// /////////////////////////////////////////
template <typename T> struct is_simd : public std::false_type{}; template <typename T>
template <> struct is_simd<vRealF> : public std::true_type {}; struct is_simd : public std::false_type {};
template <> struct is_simd<vRealD> : public std::true_type {}; template <>
template <> struct is_simd<vComplexF>: public std::true_type {}; struct is_simd<vRealF> : public std::true_type {};
template <> struct is_simd<vComplexD>: public std::true_type {}; template <>
template <> struct is_simd<vInteger> : public std::true_type {}; struct is_simd<vRealD> : public std::true_type {};
template <>
template <typename T> using IfSimd = Invoke<std::enable_if< is_simd<T>::value,int> > ; struct is_simd<vComplexF> : public std::true_type {};
template <typename T> using IfNotSimd = Invoke<std::enable_if<!is_simd<T>::value,unsigned> > ; template <>
struct is_simd<vComplexD> : 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 IfNotSimd = Invoke<std::enable_if<!is_simd<T>::value, unsigned> >;
} }
#endif #endif

View File

@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef GRID_VECTOR_UNOPS #ifndef GRID_VECTOR_UNOPS
@ -35,85 +36,84 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
namespace Grid { namespace Grid {
template<class scalar> struct SqrtRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct SqrtRealFunctor {
return sqrt(real(a)); scalar operator()(const scalar &a) const { return sqrt(real(a)); }
}
}; };
template<class scalar> struct RSqrtRealFunctor { template <class scalar>
struct RSqrtRealFunctor {
scalar operator()(const scalar &a) const { scalar operator()(const scalar &a) const {
return scalar(1.0 / sqrt(real(a))); return scalar(1.0 / sqrt(real(a)));
} }
}; };
template<class scalar> struct CosRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct CosRealFunctor {
return cos(real(a)); scalar operator()(const scalar &a) const { return cos(real(a)); }
}
}; };
template<class scalar> struct SinRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct SinRealFunctor {
return sin(real(a)); scalar operator()(const scalar &a) const { return sin(real(a)); }
}
}; };
template<class scalar> struct LogRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct AcosRealFunctor {
return log(real(a)); scalar operator()(const scalar &a) const { return acos(real(a)); }
}
}; };
template<class scalar> struct ExpRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct AsinRealFunctor {
return exp(real(a)); scalar operator()(const scalar &a) const { return asin(real(a)); }
}
};
template<class scalar> struct NotFunctor {
scalar operator()(const scalar &a) const {
return (!a);
}
};
template<class scalar> struct AbsRealFunctor {
scalar operator()(const scalar &a) const {
return std::abs(real(a));
}
}; };
template<class scalar> struct PowRealFunctor { template <class scalar>
struct LogRealFunctor {
scalar operator()(const scalar &a) const { return log(real(a)); }
};
template <class scalar>
struct ExpRealFunctor {
scalar operator()(const scalar &a) const { return exp(real(a)); }
};
template <class scalar>
struct NotFunctor {
scalar operator()(const scalar &a) const { return (!a); }
};
template <class scalar>
struct AbsRealFunctor {
scalar operator()(const scalar &a) const { return std::abs(real(a)); }
};
template <class scalar>
struct PowRealFunctor {
double y; double y;
PowRealFunctor(double _y) : y(_y){}; PowRealFunctor(double _y) : y(_y){};
scalar operator()(const scalar &a) const { scalar operator()(const scalar &a) const { return pow(real(a), y); }
return pow(real(a),y);
}
}; };
template<class scalar> struct ModIntFunctor { template <class scalar>
struct ModIntFunctor {
Integer y; Integer y;
ModIntFunctor(Integer _y) : y(_y){}; ModIntFunctor(Integer _y) : y(_y){};
scalar operator()(const scalar &a) const { scalar operator()(const scalar &a) const { return Integer(a) % y; }
return Integer(a)%y;
}
}; };
template<class scalar> struct DivIntFunctor { template <class scalar>
struct DivIntFunctor {
Integer y; Integer y;
DivIntFunctor(Integer _y) : y(_y){}; DivIntFunctor(Integer _y) : y(_y){};
scalar operator()(const scalar &a) const { scalar operator()(const scalar &a) const { return Integer(a) / y; }
return Integer(a)/y;
}
}; };
template<class scalar> struct RealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct RealFunctor {
return real(a); scalar operator()(const scalar &a) const { return std::real(a); }
}
}; };
template<class scalar> struct ImagFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct ImagFunctor {
return imag(a); scalar operator()(const scalar &a) const { return std::imag(a); }
}
}; };
template <class S, class V> template <class S, class V>
inline Grid_simd<S, V> real(const Grid_simd<S, V> &r) { inline Grid_simd<S, V> real(const Grid_simd<S, V> &r) {
@ -123,7 +123,6 @@ namespace Grid {
inline Grid_simd<S, V> imag(const Grid_simd<S, V> &r) { inline Grid_simd<S, V> imag(const Grid_simd<S, V> &r) {
return SimdApply(ImagFunctor<S>(), r); return SimdApply(ImagFunctor<S>(), r);
} }
template <class S, class V> template <class S, class V>
inline Grid_simd<S, V> sqrt(const Grid_simd<S, V> &r) { inline Grid_simd<S, V> sqrt(const Grid_simd<S, V> &r) {
return SimdApply(SqrtRealFunctor<S>(), r); return SimdApply(SqrtRealFunctor<S>(), r);
@ -146,6 +145,14 @@ namespace Grid {
return SimdApply(SinRealFunctor<S>(), r); return SimdApply(SinRealFunctor<S>(), r);
} }
template <class S, class V> template <class S, class V>
inline Grid_simd<S, V> acos(const Grid_simd<S, V> &r) {
return SimdApply(AcosRealFunctor<S>(), r);
}
template <class S, class V>
inline Grid_simd<S, V> asin(const Grid_simd<S, V> &r) {
return SimdApply(AsinRealFunctor<S>(), r);
}
template <class S, class V>
inline Grid_simd<S, V> log(const Grid_simd<S, V> &r) { inline Grid_simd<S, V> log(const Grid_simd<S, V> &r) {
return SimdApply(LogRealFunctor<S>(), r); return SimdApply(LogRealFunctor<S>(), r);
} }
@ -177,51 +184,51 @@ namespace Grid {
// Allows us to assign into **conformable** real vectors from complex // Allows us to assign into **conformable** real vectors from complex
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// template < class S, class V > // template < class S, class V >
// inline auto ComplexRemove(const Grid_simd<S,V> &c) -> Grid_simd<Grid_simd<S,V>::Real,V> { // inline auto ComplexRemove(const Grid_simd<S,V> &c) ->
// Grid_simd<Grid_simd<S,V>::Real,V> {
// Grid_simd<Grid_simd<S,V>::Real,V> ret; // Grid_simd<Grid_simd<S,V>::Real,V> ret;
// ret.v = c.v; // ret.v = c.v;
// return ret; // return ret;
// } // }
template<class scalar> struct AndFunctor { template <class scalar>
scalar operator()(const scalar &x, const scalar &y) const { struct AndFunctor {
return x & y; scalar operator()(const scalar &x, const scalar &y) const { return x & y; }
}
}; };
template<class scalar> struct OrFunctor { template <class scalar>
scalar operator()(const scalar &x, const scalar &y) const { struct OrFunctor {
return x | y; scalar operator()(const scalar &x, const scalar &y) const { return x | y; }
}
}; };
template<class scalar> struct AndAndFunctor { template <class scalar>
scalar operator()(const scalar &x, const scalar &y) const { struct AndAndFunctor {
return x && y; scalar operator()(const scalar &x, const scalar &y) const { return x && y; }
}
}; };
template<class scalar> struct OrOrFunctor { template <class scalar>
scalar operator()(const scalar &x, const scalar &y) const { struct OrOrFunctor {
return x || y; scalar operator()(const scalar &x, const scalar &y) const { return x || y; }
}
}; };
//////////////////////////////// ////////////////////////////////
// Calls to simd binop functors // Calls to simd binop functors
//////////////////////////////// ////////////////////////////////
template <class S, class V> template <class S, class V>
inline Grid_simd<S,V> operator &(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) { inline Grid_simd<S, V> operator&(const Grid_simd<S, V> &x,
const Grid_simd<S, V> &y) {
return SimdApplyBinop(AndFunctor<S>(), x, y); return SimdApplyBinop(AndFunctor<S>(), x, y);
} }
template <class S, class V> template <class S, class V>
inline Grid_simd<S,V> operator &&(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) { inline Grid_simd<S, V> operator&&(const Grid_simd<S, V> &x,
const Grid_simd<S, V> &y) {
return SimdApplyBinop(AndAndFunctor<S>(), x, y); return SimdApplyBinop(AndAndFunctor<S>(), x, y);
} }
template <class S, class V> template <class S, class V>
inline Grid_simd<S,V> operator |(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) { inline Grid_simd<S, V> operator|(const Grid_simd<S, V> &x,
const Grid_simd<S, V> &y) {
return SimdApplyBinop(OrFunctor<S>(), x, y); return SimdApplyBinop(OrFunctor<S>(), x, y);
} }
template <class S, class V> template <class S, class V>
inline Grid_simd<S,V> operator ||(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) { inline Grid_simd<S, V> operator||(const Grid_simd<S, V> &x,
const Grid_simd<S, V> &y) {
return SimdApplyBinop(OrOrFunctor<S>(), x, y); return SimdApplyBinop(OrOrFunctor<S>(), x, y);
} }
} }
#endif #endif

View File

@ -23,7 +23,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef GRID_MATH_TENSORS_H #ifndef GRID_MATH_TENSORS_H
@ -38,7 +39,8 @@ namespace Grid {
// It is useful to NOT have any constructors // It is useful to NOT have any constructors
// so that these classes assert "is_pod<class> == true" // so that these classes assert "is_pod<class> == true"
// because then the standard C++ valarray container eliminates fill overhead on new allocation and // because then the standard C++ valarray container eliminates fill overhead on
// new allocation and
// non-move copying. // non-move copying.
// //
// However note that doing this eliminates some syntactical sugar such as // However note that doing this eliminates some syntactical sugar such as
@ -46,8 +48,8 @@ namespace Grid {
// //
class GridTensorBase {}; class GridTensorBase {};
template<class vtype> class iScalar template <class vtype>
{ class iScalar {
public: public:
vtype _internal; vtype _internal;
@ -66,7 +68,8 @@ public:
enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 }; enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
// Scalar no action // Scalar no action
// template<int Level> using tensor_reduce_level = typename iScalar<GridTypeMapper<vtype>::tensor_reduce_level<Level> >; // template<int Level> using tensor_reduce_level = typename
// iScalar<GridTypeMapper<vtype>::tensor_reduce_level<Level> >;
iScalar() = default; iScalar() = default;
/* /*
iScalar(const iScalar<vtype> &copyme)=default; iScalar(const iScalar<vtype> &copyme)=default;
@ -74,14 +77,16 @@ public:
iScalar<vtype> & operator= (const iScalar<vtype> &copyme) = default; iScalar<vtype> & operator= (const iScalar<vtype> &copyme) = default;
iScalar<vtype> & operator= (iScalar<vtype> &&copyme) = default; iScalar<vtype> & operator= (iScalar<vtype> &&copyme) = default;
*/ */
iScalar(scalar_type s) : _internal(s) {};// recurse down and hit the constructor for vector_type iScalar(scalar_type s)
: _internal(s){}; // recurse down and hit the constructor for vector_type
iScalar(const Zero &z) { *this = zero; }; iScalar(const Zero &z) { *this = zero; };
iScalar<vtype> &operator=(const Zero &hero) { iScalar<vtype> &operator=(const Zero &hero) {
zeroit(*this); zeroit(*this);
return *this; return *this;
} }
friend strong_inline void vstream(iScalar<vtype> &out,const iScalar<vtype> &in){ friend strong_inline void vstream(iScalar<vtype> &out,
const iScalar<vtype> &in) {
vstream(out._internal, in._internal); vstream(out._internal, in._internal);
} }
friend strong_inline void zeroit(iScalar<vtype> &that) { friend strong_inline void zeroit(iScalar<vtype> &that) {
@ -90,7 +95,8 @@ public:
friend strong_inline void prefetch(iScalar<vtype> &that) { friend strong_inline void prefetch(iScalar<vtype> &that) {
prefetch(that._internal); prefetch(that._internal);
} }
friend strong_inline void permute(iScalar<vtype> &out,const iScalar<vtype> &in,int permutetype){ friend strong_inline void permute(iScalar<vtype> &out,
const iScalar<vtype> &in, int permutetype) {
permute(out._internal, in._internal, permutetype); permute(out._internal, in._internal, permutetype);
} }
@ -113,28 +119,43 @@ public:
*this = (*this) + r; *this = (*this) + r;
return *this; return *this;
} }
strong_inline vtype & operator ()(void) { strong_inline vtype &operator()(void) { return _internal; }
return _internal; strong_inline const vtype &operator()(void) const { return _internal; }
}
strong_inline const vtype & operator ()(void) const {
return _internal;
}
// Type casts meta programmed, must be pure scalar to match TensorRemove // Type casts meta programmed, must be pure scalar to match TensorRemove
template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> = 0> operator ComplexF () const { return(TensorRemove(_internal)); }; template <class U = vtype, class V = scalar_type, IfComplex<V> = 0,
template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> = 0> operator ComplexD () const { return(TensorRemove(_internal)); }; IfNotSimd<U> = 0>
// template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> = 0> operator RealD () const { return(real(TensorRemove(_internal))); } operator ComplexF() const {
template<class U=vtype,class V=scalar_type,IfReal<V> = 0,IfNotSimd<U> = 0> operator RealD () const { return TensorRemove(_internal); } return (TensorRemove(_internal));
template<class U=vtype,class V=scalar_type,IfInteger<V> = 0,IfNotSimd<U> = 0> operator Integer () const { return Integer(TensorRemove(_internal)); } };
template <class U = vtype, class V = scalar_type, IfComplex<V> = 0,
IfNotSimd<U> = 0>
operator ComplexD() const {
return (TensorRemove(_internal));
};
// template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> =
// 0> operator RealD () const { return(real(TensorRemove(_internal))); }
template <class U = vtype, class V = scalar_type, IfReal<V> = 0,
IfNotSimd<U> = 0>
operator RealD() const {
return TensorRemove(_internal);
}
template <class U = vtype, class V = scalar_type, IfInteger<V> = 0,
IfNotSimd<U> = 0>
operator Integer() const {
return Integer(TensorRemove(_internal));
}
// convert from a something to a scalar via constructor of something arg // convert from a something to a scalar via constructor of something arg
template<class T,typename std::enable_if<!isGridTensor<T>::value, T>::type* = nullptr > strong_inline iScalar<vtype> operator = (T arg) template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
{ * = nullptr>
strong_inline iScalar<vtype> operator=(T arg) {
_internal = arg; _internal = arg;
return *this; return *this;
} }
friend std::ostream& operator<< (std::ostream& stream, const iScalar<vtype> &o){ friend std::ostream &operator<<(std::ostream &stream,
const iScalar<vtype> &o) {
stream << "S {" << o._internal << "}"; stream << "S {" << o._internal << "}";
return stream; return stream;
}; };
@ -142,14 +163,19 @@ public:
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// Allows to turn scalar<scalar<scalar<double>>>> back to double. // Allows to turn scalar<scalar<scalar<double>>>> back to double.
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
template<class T> strong_inline typename std::enable_if<!isGridTensor<T>::value, T>::type TensorRemove(T arg) { return arg;} template <class T>
template<class vtype> strong_inline auto TensorRemove(iScalar<vtype> arg) -> decltype(TensorRemove(arg._internal)) strong_inline typename std::enable_if<!isGridTensor<T>::value, T>::type
{ TensorRemove(T arg) {
return arg;
}
template <class vtype>
strong_inline auto TensorRemove(iScalar<vtype> arg)
-> decltype(TensorRemove(arg._internal)) {
return TensorRemove(arg._internal); return TensorRemove(arg._internal);
} }
template<class vtype,int N> class iVector template <class vtype, int N>
{ class iVector {
public: public:
vtype _internal[N]; vtype _internal[N];
@ -165,11 +191,11 @@ public:
typedef iVector<typename GridTypeMapper<vtype>::Complexified, N> Complexified; typedef iVector<typename GridTypeMapper<vtype>::Complexified, N> Complexified;
typedef iVector<typename GridTypeMapper<vtype>::Realified, N> Realified; typedef iVector<typename GridTypeMapper<vtype>::Realified, N> Realified;
template<class T,typename std::enable_if<!isGridTensor<T>::value, T>::type* = nullptr > strong_inline auto operator = (T arg) -> iVector<vtype,N> template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
{ * = nullptr>
strong_inline auto operator=(T arg) -> iVector<vtype, N> {
zeroit(*this); zeroit(*this);
for(int i=0;i<N;i++) for (int i = 0; i < N; i++) _internal[i] = arg;
_internal[i] = arg;
return *this; return *this;
} }
@ -195,12 +221,15 @@ public:
friend strong_inline void prefetch(iVector<vtype, N> &that) { friend strong_inline void prefetch(iVector<vtype, N> &that) {
for (int i = 0; i < N; i++) prefetch(that._internal[i]); for (int i = 0; i < N; i++) prefetch(that._internal[i]);
} }
friend strong_inline void vstream(iVector<vtype,N> &out,const iVector<vtype,N> &in){ friend strong_inline void vstream(iVector<vtype, N> &out,
const iVector<vtype, N> &in) {
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
vstream(out._internal[i], in._internal[i]); vstream(out._internal[i], in._internal[i]);
} }
} }
friend strong_inline void permute(iVector<vtype,N> &out,const iVector<vtype,N> &in,int permutetype){ friend strong_inline void permute(iVector<vtype, N> &out,
const iVector<vtype, N> &in,
int permutetype) {
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
permute(out._internal[i], in._internal[i], permutetype); permute(out._internal[i], in._internal[i], permutetype);
} }
@ -225,13 +254,10 @@ public:
*this = (*this) + r; *this = (*this) + r;
return *this; return *this;
} }
strong_inline vtype & operator ()(int i) { strong_inline vtype &operator()(int i) { return _internal[i]; }
return _internal[i]; strong_inline const vtype &operator()(int i) const { return _internal[i]; }
} friend std::ostream &operator<<(std::ostream &stream,
strong_inline const vtype & operator ()(int i) const { const iVector<vtype, N> &o) {
return _internal[i];
}
friend std::ostream& operator<< (std::ostream& stream, const iVector<vtype,N> &o){
stream << "V<" << N << ">{"; stream << "V<" << N << ">{";
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
stream << o._internal[i]; stream << o._internal[i];
@ -245,8 +271,8 @@ public:
// } // }
}; };
template<class vtype,int N> class iMatrix template <class vtype, int N>
{ class iMatrix {
public: public:
vtype _internal[N][N]; vtype _internal[N][N];
@ -266,20 +292,18 @@ public:
enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 }; enum { TensorLevel = GridTypeMapper<vtype>::TensorLevel + 1 };
iMatrix(const Zero &z) { *this = zero; }; iMatrix(const Zero &z) { *this = zero; };
iMatrix() = default; iMatrix() = default;
iMatrix &operator=(const iMatrix &rhs) { iMatrix &operator=(const iMatrix &rhs) {
for (int i = 0; i < N; i++) for (int i = 0; i < N; i++)
for(int j=0;j<N;j++) for (int j = 0; j < N; j++) vstream(_internal[i][j], rhs._internal[i][j]);
vstream(_internal[i][j],rhs._internal[i][j]);
return *this; return *this;
}; };
iMatrix(scalar_type s) {
(*this) = s;
iMatrix(scalar_type s) { (*this) = s ;};// recurse down and hit the constructor for vector_type }; // recurse down and hit the constructor for vector_type
/* /*
iMatrix(const iMatrix<vtype,N> &copyme)=default; iMatrix(const iMatrix<vtype,N> &copyme)=default;
@ -288,17 +312,15 @@ public:
iMatrix<vtype,N> & operator= (iMatrix<vtype,N> &&copyme) = default; iMatrix<vtype,N> & operator= (iMatrix<vtype,N> &&copyme) = default;
*/ */
iMatrix<vtype, N> &operator=(const Zero &hero) { iMatrix<vtype, N> &operator=(const Zero &hero) {
zeroit(*this); zeroit(*this);
return *this; return *this;
} }
template<class T,typename std::enable_if<!isGridTensor<T>::value, T>::type* = nullptr > strong_inline auto operator = (T arg) -> iMatrix<vtype,N> template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
{ * = nullptr>
strong_inline auto operator=(T arg) -> iMatrix<vtype, N> {
zeroit(*this); zeroit(*this);
for(int i=0;i<N;i++) for (int i = 0; i < N; i++) _internal[i][i] = arg;
_internal[i][i] = arg;
return *this; return *this;
} }
@ -306,27 +328,31 @@ public:
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) { for (int j = 0; j < N; j++) {
zeroit(that._internal[i][j]); zeroit(that._internal[i][j]);
}} }
}
} }
friend strong_inline void prefetch(iMatrix<vtype, N> &that) { friend strong_inline void prefetch(iMatrix<vtype, N> &that) {
for (int i = 0; i < N; i++) for (int i = 0; i < N; i++)
for(int j=0;j<N;j++) for (int j = 0; j < N; j++) prefetch(that._internal[i][j]);
prefetch(that._internal[i][j]);
} }
friend strong_inline void vstream(iMatrix<vtype,N> &out,const iMatrix<vtype,N> &in){ friend strong_inline void vstream(iMatrix<vtype, N> &out,
const iMatrix<vtype, N> &in) {
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) { for (int j = 0; j < N; j++) {
vstream(out._internal[i][j], in._internal[i][j]); vstream(out._internal[i][j], in._internal[i][j]);
}} }
}
} }
friend strong_inline void permute(iMatrix<vtype,N> &out,const iMatrix<vtype,N> &in,int permutetype){ friend strong_inline void permute(iMatrix<vtype, N> &out,
const iMatrix<vtype, N> &in,
int permutetype) {
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) { for (int j = 0; j < N; j++) {
permute(out._internal[i][j], in._internal[i][j], permutetype); permute(out._internal[i][j], in._internal[i][j], permutetype);
}}
} }
}
}
// Unary negation // Unary negation
friend strong_inline iMatrix<vtype, N> operator-(const iMatrix<vtype, N> &r) { friend strong_inline iMatrix<vtype, N> operator-(const iMatrix<vtype, N> &r) {
@ -334,7 +360,8 @@ public:
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) { for (int j = 0; j < N; j++) {
ret._internal[i][j] = -r._internal[i][j]; ret._internal[i][j] = -r._internal[i][j];
}} }
}
return ret; return ret;
} }
// *=,+=,-= operators inherit from corresponding "*,-,+" behaviour // *=,+=,-= operators inherit from corresponding "*,-,+" behaviour
@ -355,13 +382,12 @@ public:
} }
// returns an lvalue reference // returns an lvalue reference
strong_inline vtype & operator ()(int i,int j) { strong_inline vtype &operator()(int i, int j) { return _internal[i][j]; }
return _internal[i][j];
}
strong_inline const vtype &operator()(int i, int j) const { strong_inline const vtype &operator()(int i, int j) const {
return _internal[i][j]; return _internal[i][j];
} }
friend std::ostream& operator<< (std::ostream& stream, const iMatrix<vtype,N> &o){ friend std::ostream &operator<<(std::ostream &stream,
const iMatrix<vtype, N> &o) {
stream << "M<" << N << ">{"; stream << "M<" << N << ">{";
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
stream << "{"; stream << "{";
@ -379,27 +405,25 @@ public:
// strong_inline vtype && operator ()(int i,int j) { // strong_inline vtype && operator ()(int i,int j) {
// return _internal[i][j]; // return _internal[i][j];
// } // }
}; };
template<class v> void vprefetch(const iScalar<v> &vv) template <class v>
{ void vprefetch(const iScalar<v> &vv) {
vprefetch(vv._internal); vprefetch(vv._internal);
} }
template<class v,int N> void vprefetch(const iVector<v,N> &vv) template <class v, int N>
{ void vprefetch(const iVector<v, N> &vv) {
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
vprefetch(vv._internal[i]); vprefetch(vv._internal[i]);
} }
} }
template<class v,int N> void vprefetch(const iMatrix<v,N> &vv) template <class v, int N>
{ void vprefetch(const iMatrix<v, N> &vv) {
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) { for (int j = 0; j < N; j++) {
vprefetch(vv._internal[i][j]); vprefetch(vv._internal[i][j]);
}}
} }
}
}
} }
#endif #endif

View File

@ -86,6 +86,8 @@ UNARY(sqrt);
UNARY(rsqrt); UNARY(rsqrt);
UNARY(sin); UNARY(sin);
UNARY(cos); UNARY(cos);
UNARY(asin);
UNARY(acos);
UNARY(log); UNARY(log);
UNARY(exp); UNARY(exp);
UNARY(abs); UNARY(abs);

4
scripts/Make.inc Normal file
View File

@ -0,0 +1,4 @@
HFILES=
CCFILES=

View File

@ -66,6 +66,9 @@ public:
TwoFlavourEvenOddPseudoFermionAction<ImplPolicy> Nf2(FermOp,CG,CG); TwoFlavourEvenOddPseudoFermionAction<ImplPolicy> Nf2(FermOp,CG,CG);
//Set smearing (true/false), default: false
Nf2.is_smeared=false;
//Collect actions //Collect actions
ActionLevel<LatticeGaugeField> Level1(1); ActionLevel<LatticeGaugeField> Level1(1);
Level1.push_back(&Nf2); Level1.push_back(&Nf2);

View File

@ -66,6 +66,9 @@ public:
ConjugateGradient<FermionField> CG(1.0e-8,10000); ConjugateGradient<FermionField> CG(1.0e-8,10000);
TwoFlavourEvenOddRatioPseudoFermionAction<ImplPolicy> Nf2(NumOp, DenOp,CG,CG); TwoFlavourEvenOddRatioPseudoFermionAction<ImplPolicy> Nf2(NumOp, DenOp,CG,CG);
//Set smearing (true/false), default: false
Nf2.is_smeared=true;
//Collect actions //Collect actions
ActionLevel<LatticeGaugeField> Level1; ActionLevel<LatticeGaugeField> Level1;
Level1.push_back(&Nf2); Level1.push_back(&Nf2);

View File

@ -67,6 +67,10 @@ public:
TwoFlavourPseudoFermionAction<ImplPolicy> Nf2(FermOp,CG,CG); TwoFlavourPseudoFermionAction<ImplPolicy> Nf2(FermOp,CG,CG);
//Set smearing (true/false), default: false
Nf2.is_smeared = true;
//Collect actions //Collect actions
ActionLevel<LatticeGaugeField> Level1(1); ActionLevel<LatticeGaugeField> Level1(1);
Level1.push_back(&Nf2); Level1.push_back(&Nf2);

View File

@ -66,6 +66,9 @@ public:
ConjugateGradient<FermionField> CG(1.0e-8,10000); ConjugateGradient<FermionField> CG(1.0e-8,10000);
TwoFlavourRatioPseudoFermionAction<ImplPolicy> Nf2(NumOp, DenOp,CG,CG); TwoFlavourRatioPseudoFermionAction<ImplPolicy> Nf2(NumOp, DenOp,CG,CG);
//Set smearing (true/false), default: false
Nf2.is_smeared=true;
//Collect actions //Collect actions
ActionLevel<LatticeGaugeField> Level1; ActionLevel<LatticeGaugeField> Level1;
Level1.push_back(&Nf2); Level1.push_back(&Nf2);

View File

@ -25,35 +25,38 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#include "Grid.h" #include "Grid.h"
using namespace std; using namespace std;
using namespace Grid; using namespace Grid;
using namespace Grid::QCD; using namespace Grid::QCD;
/* /*
Grid_main.cc(232): error: no suitable user-defined conversion from "Grid::iScalar<Grid::iMatrix<Grid::iScalar<Grid::Complex>, 4>>" to "const Grid::iScalar<Grid::iScalar<Grid::iMatrix<Grid::Complex, 3>>>" exists Grid_main.cc(232): error: no suitable user-defined conversion from
"Grid::iScalar<Grid::iMatrix<Grid::iScalar<Grid::Complex>, 4>>" to "const
Grid::iScalar<Grid::iScalar<Grid::iMatrix<Grid::Complex, 3>>>" exists
c_m = peekIdiot<SpinColourMatrix>(scm,1,2); c_m = peekIdiot<SpinColourMatrix>(scm,1,2);
*/ */
template<class vobj> auto peekIdiot(const vobj &rhs,int i,int j) -> decltype(peekIndex<2>(rhs,0,0)) template <class vobj>
{ auto peekIdiot(const vobj &rhs, int i, int j)
-> decltype(peekIndex<2>(rhs, 0, 0)) {
return peekIndex<2>(rhs, i, j); return peekIndex<2>(rhs, i, j);
} }
template<class vobj> auto peekDumKopf(const vobj &rhs,int i,int j) -> decltype(peekIndex<3>(rhs,0,0)) template <class vobj>
{ auto peekDumKopf(const vobj &rhs, int i, int j)
-> decltype(peekIndex<3>(rhs, 0, 0)) {
return peekIndex<3>(rhs, i, j); return peekIndex<3>(rhs, i, j);
} }
template<class vobj> auto peekDumKopf(const vobj &rhs,int i) -> decltype(peekIndex<3>(rhs,0)) template <class vobj>
{ auto peekDumKopf(const vobj &rhs, int i) -> decltype(peekIndex<3>(rhs, 0)) {
return peekIndex<3>(rhs, i); return peekIndex<3>(rhs, i);
} }
int main (int argc, char ** argv) int main(int argc, char **argv) {
{
Grid_init(&argc, &argv); Grid_init(&argc, &argv);
std::vector<int> latt_size = GridDefaultLatt(); std::vector<int> latt_size = GridDefaultLatt();
@ -73,7 +76,6 @@ int main (int argc, char ** argv)
#endif #endif
for (int lat = 8; lat <= 16; lat += 40) { for (int lat = 8; lat <= 16; lat += 40) {
std::cout << "Lat " << lat << std::endl; std::cout << "Lat " << lat << std::endl;
latt_size[0] = lat; latt_size[0] = lat;
@ -132,7 +134,6 @@ int main (int argc, char ** argv)
LatticeLorentzColourMatrix lcMat(&Fine); LatticeLorentzColourMatrix lcMat(&Fine);
LatticeComplex scalar(&Fine); LatticeComplex scalar(&Fine);
LatticeReal rscalar(&Fine); LatticeReal rscalar(&Fine);
LatticeReal iscalar(&Fine); LatticeReal iscalar(&Fine);
@ -154,24 +155,40 @@ int main (int argc, char ** argv)
random(FineRNG, sVec); random(FineRNG, sVec);
random(FineRNG, scVec); random(FineRNG, scVec);
fflush(stdout); fflush(stdout);
LatticeColourMatrix newFoo = Foo;
// confirm correctness of copy constructor
Bar = Foo - newFoo;
std::cout << "Copy constructor diff check: ";
double test_cc = norm2(Bar);
if (test_cc < 1e-5){
std::cout << "OK\n";
}
else{
std::cout << "fail\n";
abort();
}
TComplex tr = trace(cmat); TComplex tr = trace(cmat);
cVec = cMat * cVec; // LatticeColourVector = LatticeColourMatrix
cVec = cMat * cVec; // LatticeColourVector = LatticeColourMatrix * LatticeColourVector // * LatticeColourVector
sVec = sMat * sVec; // LatticeSpinVector = LatticeSpinMatrix * LatticeSpinVector sVec = sMat * sVec; // LatticeSpinVector = LatticeSpinMatrix
scVec= scMat * scVec;// LatticeSpinColourVector = LatticeSpinColourMatrix * LatticeSpinColourVector // * LatticeSpinVector
scVec= cMat * scVec; // LatticeSpinColourVector = LatticeColourMatrix * LatticeSpinColourVector scVec = scMat * scVec; // LatticeSpinColourVector =
scVec= sMat * scVec; // LatticeSpinColourVector = LatticeSpinMatrix * LatticeSpinColourVector // LatticeSpinColourMatrix *
// LatticeSpinColourVector
scVec = cMat * scVec; // LatticeSpinColourVector = LatticeColourMatrix
// * LatticeSpinColourVector
scVec = sMat * scVec; // LatticeSpinColourVector = LatticeSpinMatrix
// * LatticeSpinColourVector
cMat = outerProduct(cVec, cVec); cMat = outerProduct(cVec, cVec);
scalar = localInnerProduct(cVec, cVec); scalar = localInnerProduct(cVec, cVec);
cMat = Ta(cMat); // traceless antihermitian cMat = Ta(cMat); // traceless antihermitian
scalar += scalar; scalar += scalar;
scalar -= scalar; scalar -= scalar;
scalar *= scalar; scalar *= scalar;
@ -193,7 +210,6 @@ int main (int argc, char ** argv)
// scalar =cmplx(rscalar,iscalar); // scalar =cmplx(rscalar,iscalar);
PokeIndex<ColourIndex>(cVec, scalar, 1); PokeIndex<ColourIndex>(cVec, scalar, 1);
scalar = transpose(scalar); scalar = transpose(scalar);
scalar = TransposeIndex<ColourIndex>(scalar); scalar = TransposeIndex<ColourIndex>(scalar);
scalar = TraceIndex<SpinIndex>(scalar); scalar = TraceIndex<SpinIndex>(scalar);
@ -214,9 +230,8 @@ int main (int argc, char ** argv)
// localNorm2 // localNorm2
// localInnerProduct // localInnerProduct
scMat = sMat * scMat; // LatticeSpinColourMatrix = LatticeSpinMatrix
scMat = sMat*scMat; // LatticeSpinColourMatrix = LatticeSpinMatrix * LatticeSpinColourMatrix // * LatticeSpinColourMatrix
/////////////////////// ///////////////////////
// Non-lattice (const objects) * Lattice // Non-lattice (const objects) * Lattice
@ -229,10 +244,13 @@ int main (int argc, char ** argv)
// vSpinColourMatrix vscm; // vSpinColourMatrix vscm;
scMat = cMat * scMat; scMat = cMat * scMat;
scm = cm * scm; // SpinColourMatrix = ColourMatrix * SpinColourMatrix scm =
cm * scm; // SpinColourMatrix = ColourMatrix * SpinColourMatrix
scm = scm * cm; // SpinColourMatrix = SpinColourMartix * ColourMatrix scm = scm * cm; // SpinColourMatrix = SpinColourMartix * ColourMatrix
scm = GammaFive * scm ; // SpinColourMatrix = SpinMatrix * SpinColourMatrix scm = GammaFive *
scm = scm* GammaFive ; // SpinColourMatrix = SpinColourMatrix * SpinMatrix scm; // SpinColourMatrix = SpinMatrix * SpinColourMatrix
scm =
scm * GammaFive; // SpinColourMatrix = SpinColourMatrix * SpinMatrix
scm = scm * cplx; scm = scm * cplx;
vscm = vscm * cplx; vscm = vscm * cplx;
@ -261,7 +279,6 @@ int main (int argc, char ** argv)
scm = transpose(scm); scm = transpose(scm);
scm = transposeIndex<1>(scm); scm = transposeIndex<1>(scm);
random(SerialRNG, cm); random(SerialRNG, cm);
std::cout << GridLogMessage << cm << std::endl; std::cout << GridLogMessage << cm << std::endl;
@ -269,7 +286,6 @@ int main (int argc, char ** argv)
TComplex tracecm = trace(cm); TComplex tracecm = trace(cm);
std::cout << GridLogMessage << cm << std::endl; std::cout << GridLogMessage << cm << std::endl;
cm = Exponentiate(cm, 2.0, 12); cm = Exponentiate(cm, 2.0, 12);
std::cout << GridLogMessage << cm << " " << std::endl; std::cout << GridLogMessage << cm << " " << std::endl;
Complex det = Determinant(cm); Complex det = Determinant(cm);
@ -283,11 +299,9 @@ int main (int argc, char ** argv)
std::cout << GridLogMessage << cm << " " << std::endl; std::cout << GridLogMessage << cm << " " << std::endl;
std::cout << GridLogMessage << "norm: " << norm2(cm) << std::endl; std::cout << GridLogMessage << "norm: " << norm2(cm) << std::endl;
// det = Determinant(cm); // det = Determinant(cm);
// std::cout<<GridLogMessage << "determinant: " << det << std::endl; // std::cout<<GridLogMessage << "determinant: " << det << std::endl;
// Foo = Foo+scalar; // LatticeColourMatrix+Scalar // Foo = Foo+scalar; // LatticeColourMatrix+Scalar
// Foo = Foo*scalar; // LatticeColourMatrix*Scalar // Foo = Foo*scalar; // LatticeColourMatrix*Scalar
// Foo = Foo-scalar; // LatticeColourMatrix-Scalar // Foo = Foo-scalar; // LatticeColourMatrix-Scalar
@ -308,19 +322,20 @@ int main (int argc, char ** argv)
std::cout << GridLogMessage << cm << " " << std::endl; std::cout << GridLogMessage << cm << " " << std::endl;
std::cout << GridLogMessage << "norm: " << norm2(cm) << std::endl; std::cout << GridLogMessage << "norm: " << norm2(cm) << std::endl;
std::cout << GridLogMessage << "norm cMmat : " << norm2(cMat)
std::cout<<GridLogMessage << "norm cMmat : " << norm2(cMat) << std::endl; << std::endl;
cMat = expMat(cMat, ComplexD(1.0, 0.0)); cMat = expMat(cMat, ComplexD(1.0, 0.0));
std::cout<<GridLogMessage << "norm expMat: " << norm2(cMat) << std::endl; std::cout << GridLogMessage << "norm expMat: " << norm2(cMat)
<< std::endl;
peekSite(cm, cMat, mysite); peekSite(cm, cMat, mysite);
std::cout << GridLogMessage << cm << " " << std::endl; std::cout << GridLogMessage << cm << " " << std::endl;
std::cout<<GridLogMessage << "determinant: " << Determinant(cm) << std::endl; std::cout << GridLogMessage << "determinant: " << Determinant(cm)
<< std::endl;
std::cout << GridLogMessage << "norm: " << norm2(cm) << std::endl; std::cout << GridLogMessage << "norm: " << norm2(cm) << std::endl;
// LatticeComplex trlcMat(&Fine); // LatticeComplex trlcMat(&Fine);
// trlcMat = trace(lcMat); // Trace involving iVector - now generates error // trlcMat = trace(lcMat); // Trace involving iVector - now generates
// error
{ // Peek-ology and Poke-ology, with a little app-ology { // Peek-ology and Poke-ology, with a little app-ology
Complex c; Complex c;
@ -328,8 +343,10 @@ int main (int argc, char ** argv)
SpinMatrix s_m; SpinMatrix s_m;
SpinColourMatrix sc_m; SpinColourMatrix sc_m;
s_m = TensorIndexRecursion<ColourIndex>::traceIndex(sc_m); // Map to traceColour s_m = TensorIndexRecursion<ColourIndex>::traceIndex(
c_m = TensorIndexRecursion<SpinIndex>::traceIndex(sc_m); // map to traceSpin sc_m); // Map to traceColour
c_m = TensorIndexRecursion<SpinIndex>::traceIndex(
sc_m); // map to traceSpin
c = TensorIndexRecursion<SpinIndex>::traceIndex(s_m); c = TensorIndexRecursion<SpinIndex>::traceIndex(s_m);
c = TensorIndexRecursion<ColourIndex>::traceIndex(c_m); c = TensorIndexRecursion<ColourIndex>::traceIndex(c_m);
@ -343,8 +360,10 @@ int main (int argc, char ** argv)
printf("c. Level %d\n", c_m().TensorLevel); printf("c. Level %d\n", c_m().TensorLevel);
printf("c. Level %d\n", c_m()().TensorLevel); printf("c. Level %d\n", c_m()().TensorLevel);
c_m()() = scm()(0,0); //ColourComponents of CM <= ColourComponents of SpinColourMatrix c_m()() = scm()(0, 0); // ColourComponents of CM <= ColourComponents of
scm()(1,1) = cm()(); //ColourComponents of CM <= ColourComponents of SpinColourMatrix // SpinColourMatrix
scm()(1, 1) = cm()(); // ColourComponents of CM <= ColourComponents of
// SpinColourMatrix
c = scm()(1, 1)(1, 2); c = scm()(1, 1)(1, 2);
scm()(1, 1)(2, 1) = c; scm()(1, 1)(2, 1) = c;
@ -364,12 +383,12 @@ int main (int argc, char ** argv)
*/ */
lex_sites(Foo); lex_sites(Foo);
Integer mm[4]; Integer mm[4];
mm[0] = 1; mm[0] = 1;
mm[1] = Fine._rdimensions[0]; mm[1] = Fine._rdimensions[0];
mm[2] = Fine._ldimensions[0] * Fine._ldimensions[1]; mm[2] = Fine._ldimensions[0] * Fine._ldimensions[1];
mm[3]=Fine._ldimensions[0]*Fine._ldimensions[1]*Fine._ldimensions[2]; mm[3] =
Fine._ldimensions[0] * Fine._ldimensions[1] * Fine._ldimensions[2];
LatticeInteger lex(&Fine); LatticeInteger lex(&Fine);
lex = zero; lex = zero;
@ -377,35 +396,37 @@ int main (int argc, char ** argv)
LatticeInteger coor(&Fine); LatticeInteger coor(&Fine);
LatticeCoordinate(coor, d); LatticeCoordinate(coor, d);
lex = lex + coor * mm[d]; lex = lex + coor * mm[d];
} }
// Bar = zero; // Bar = zero;
// Bar = where(lex<Integer(10),Foo,Bar); // Bar = where(lex<Integer(10),Foo,Bar);
cout << "peeking sites..\n"; cout << "peeking sites..\n";
{ {
std::vector<int> coor(4); std::vector<int> coor(4);
for (coor[3] = 0; coor[3] < latt_size[3] / mpi_layout[3]; coor[3]++) { for (coor[3] = 0; coor[3] < latt_size[3] / mpi_layout[3]; coor[3]++) {
for (coor[2] = 0; coor[2] < latt_size[2] / mpi_layout[2]; coor[2]++) { for (coor[2] = 0; coor[2] < latt_size[2] / mpi_layout[2]; coor[2]++) {
for(coor[1]=0;coor[1]<latt_size[1]/mpi_layout[1];coor[1]++){ for (coor[1] = 0; coor[1] < latt_size[1] / mpi_layout[1];
for(coor[0]=0;coor[0]<latt_size[0]/mpi_layout[0];coor[0]++){ coor[1]++) {
for (coor[0] = 0; coor[0] < latt_size[0] / mpi_layout[0];
coor[0]++) {
ColourMatrix bar; ColourMatrix bar;
peekSite(bar, Bar, coor); peekSite(bar, Bar, coor);
for (int r = 0; r < 3; r++) { for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) { for (int c = 0; c < 3; c++) {
// cout<<"bar "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" "<<bar()()(r,c)<<std::endl; // cout<<"bar "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<"
}} // "<<bar()()(r,c)<<std::endl;
}}}} }
}
}
}
}
}
} }
// setCheckerboard(ShiftedCheck,rFoo); // setCheckerboard(ShiftedCheck,rFoo);
// setCheckerboard(ShiftedCheck,bFoo); // setCheckerboard(ShiftedCheck,bFoo);
// Lattice SU(3) x SU(3) // Lattice SU(3) x SU(3)
Fine.Barrier(); Fine.Barrier();
FooBar = Foo * Bar; FooBar = Foo * Bar;
@ -440,11 +461,15 @@ int main (int argc, char ** argv)
Fine.Barrier(); Fine.Barrier();
if (Fine.IsBoss()) { if (Fine.IsBoss()) {
#ifdef OMP #ifdef OMP
printf("mult NumThread %d , Lattice size %d , %f us per call\n",omp_get_max_threads(),lat,(t1-t0)/ncall); printf("mult NumThread %d , Lattice size %d , %f us per call\n",
omp_get_max_threads(), lat, (t1 - t0) / ncall);
#endif #endif
printf("mult NumThread %d , Lattice size %d , %f us per call\n",omp,lat,(t1-t0)/ncall); printf("mult NumThread %d , Lattice size %d , %f us per call\n", omp,
printf("mult NumThread %d , Lattice size %d , %f Mflop/s\n",omp,lat,flops/(t1-t0)); lat, (t1 - t0) / ncall);
printf("mult NumThread %d , Lattice size %d , %f MB/s\n",omp,lat,bytes/(t1-t0)); printf("mult NumThread %d , Lattice size %d , %f Mflop/s\n", omp, lat,
flops / (t1 - t0));
printf("mult NumThread %d , Lattice size %d , %f MB/s\n", omp, lat,
bytes / (t1 - t0));
} }
mult(FooBar, Foo, Bar); mult(FooBar, Foo, Bar);
FooBar = Foo * Bar; FooBar = Foo * Bar;
@ -464,9 +489,12 @@ int main (int argc, char ** argv)
FooBar = Foo * Bar; FooBar = Foo * Bar;
if (Fine.IsBoss()) { if (Fine.IsBoss()) {
printf("Cshift Mult: NumThread %d , Lattice size %d , %f us per call\n",omp,lat,(t1-t0)/ncall); printf("Cshift Mult: NumThread %d , Lattice size %d , %f us per call\n",
printf("Cshift Mult: NumThread %d , Lattice size %d , %f Mflop/s\n",omp,lat,flops/(t1-t0)); omp, lat, (t1 - t0) / ncall);
printf("Cshift Mult: NumThread %d , Lattice size %d , %f MB/s\n",omp,lat,bytes/(t1-t0)); printf("Cshift Mult: NumThread %d , Lattice size %d , %f Mflop/s\n",
omp, lat, flops / (t1 - t0));
printf("Cshift Mult: NumThread %d , Lattice size %d , %f MB/s\n", omp,
lat, bytes / (t1 - t0));
} }
// pickCheckerboard(0,rFoo,FooBar); // pickCheckerboard(0,rFoo,FooBar);
// pickCheckerboard(1,bFoo,FooBar); // pickCheckerboard(1,bFoo,FooBar);
@ -475,20 +503,19 @@ int main (int argc, char ** argv)
double nrm = 0; double nrm = 0;
LatticeColourMatrix deriv(&Fine); LatticeColourMatrix deriv(&Fine);
double half = 0.5; double half = 0.5;
deriv = 0.5 * Cshift(Foo, 0, 1) - 0.5 * Cshift(Foo, 0, -1); deriv = 0.5 * Cshift(Foo, 0, 1) - 0.5 * Cshift(Foo, 0, -1);
for (int dir = 0; dir < 4; dir++) { for (int dir = 0; dir < 4; dir++) {
for (int shift = 0; shift < latt_size[dir]; shift++) { for (int shift = 0; shift < latt_size[dir]; shift++) {
pickCheckerboard(0, rFoo,
pickCheckerboard(0,rFoo,Foo); // Pick out red or black checkerboards Foo); // Pick out red or black checkerboards
pickCheckerboard(1, bFoo, Foo); pickCheckerboard(1, bFoo, Foo);
if (Fine.IsBoss()) { if (Fine.IsBoss()) {
std::cout<<GridLogMessage << "Shifting both parities by "<< shift <<" direction "<< dir <<std::endl; std::cout << GridLogMessage << "Shifting both parities by " << shift
<< " direction " << dir << std::endl;
} }
Shifted = Cshift(Foo, dir, shift); // Shift everything Shifted = Cshift(Foo, dir, shift); // Shift everything
@ -497,45 +524,48 @@ int main (int argc, char ** argv)
ShiftedCheck = zero; ShiftedCheck = zero;
setCheckerboard(ShiftedCheck, bShifted); // Put them all together setCheckerboard(ShiftedCheck, bShifted); // Put them all together
setCheckerboard(ShiftedCheck,rShifted); // and check the results (later) setCheckerboard(ShiftedCheck,
rShifted); // and check the results (later)
// Check results // Check results
std::vector<int> coor(4); std::vector<int> coor(4);
for (coor[3] = 0; coor[3] < latt_size[3] / mpi_layout[3]; coor[3]++) { for (coor[3] = 0; coor[3] < latt_size[3] / mpi_layout[3]; coor[3]++) {
for(coor[2]=0;coor[2]<latt_size[2]/mpi_layout[2];coor[2]++){ for (coor[2] = 0; coor[2] < latt_size[2] / mpi_layout[2];
for(coor[1]=0;coor[1]<latt_size[1]/mpi_layout[1];coor[1]++){ coor[2]++) {
for(coor[0]=0;coor[0]<latt_size[0]/mpi_layout[0];coor[0]++){ for (coor[1] = 0; coor[1] < latt_size[1] / mpi_layout[1];
coor[1]++) {
for (coor[0] = 0; coor[0] < latt_size[0] / mpi_layout[0];
coor[0]++) {
std::complex<Grid::Real> diff; std::complex<Grid::Real> diff;
std::vector<int> shiftcoor = coor; std::vector<int> shiftcoor = coor;
shiftcoor[dir]=(shiftcoor[dir]+shift+latt_size[dir])%(latt_size[dir]/mpi_layout[dir]); shiftcoor[dir] = (shiftcoor[dir] + shift + latt_size[dir]) %
(latt_size[dir] / mpi_layout[dir]);
std::vector<int> rl(4); std::vector<int> rl(4);
for (int dd = 0; dd < 4; dd++) { for (int dd = 0; dd < 4; dd++) {
rl[dd] = latt_size[dd] / simd_layout[dd] / mpi_layout[dd]; rl[dd] = latt_size[dd] / simd_layout[dd] / mpi_layout[dd];
} }
int lex = coor[0]%rl[0] int lex = coor[0] % rl[0] + (coor[1] % rl[1]) * rl[0] +
+ (coor[1]%rl[1])*rl[0] (coor[2] % rl[2]) * rl[0] * rl[1] +
+ (coor[2]%rl[2])*rl[0]*rl[1] (coor[3] % rl[3]) * rl[0] * rl[1] * rl[2];
+ (coor[3]%rl[3])*rl[0]*rl[1]*rl[2]; lex += +1000 * (coor[0] / rl[0]) +
lex += 1000 * (coor[1] / rl[1]) * simd_layout[0] +
+1000*(coor[0]/rl[0]) 1000 * (coor[2] / rl[2]) * simd_layout[0] *
+1000*(coor[1]/rl[1])*simd_layout[0] simd_layout[1] +
+1000*(coor[2]/rl[2])*simd_layout[0]*simd_layout[1] 1000 * (coor[3] / rl[3]) * simd_layout[0] *
+1000*(coor[3]/rl[3])*simd_layout[0]*simd_layout[1]*simd_layout[2]; simd_layout[1] * simd_layout[2];
int lex_coor = shiftcoor[0]%rl[0] int lex_coor = shiftcoor[0] % rl[0] +
+ (shiftcoor[1]%rl[1])*rl[0] (shiftcoor[1] % rl[1]) * rl[0] +
+ (shiftcoor[2]%rl[2])*rl[0]*rl[1] (shiftcoor[2] % rl[2]) * rl[0] * rl[1] +
+ (shiftcoor[3]%rl[3])*rl[0]*rl[1]*rl[2]; (shiftcoor[3] % rl[3]) * rl[0] * rl[1] * rl[2];
lex_coor += lex_coor += +1000 * (shiftcoor[0] / rl[0]) +
+1000*(shiftcoor[0]/rl[0]) 1000 * (shiftcoor[1] / rl[1]) * simd_layout[0] +
+1000*(shiftcoor[1]/rl[1])*simd_layout[0] 1000 * (shiftcoor[2] / rl[2]) * simd_layout[0] *
+1000*(shiftcoor[2]/rl[2])*simd_layout[0]*simd_layout[1] simd_layout[1] +
+1000*(shiftcoor[3]/rl[3])*simd_layout[0]*simd_layout[1]*simd_layout[2]; 1000 * (shiftcoor[3] / rl[3]) * simd_layout[0] *
simd_layout[1] * simd_layout[2];
ColourMatrix foo; ColourMatrix foo;
ColourMatrix bar; ColourMatrix bar;
@ -558,36 +588,46 @@ int main (int argc, char ** argv)
Real Ttr = real(trprod); Real Ttr = real(trprod);
double nn = Ttr; double nn = Ttr;
if (nn > 0) if (nn > 0)
cout<<"Shift real trace fail "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<endl; cout << "Shift real trace fail " << coor[0] << coor[1]
<< coor[2] << coor[3] << endl;
for (int r = 0; r < 3; r++) { for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) { for (int c = 0; c < 3; c++) {
diff = shifted1()()(r, c) - shifted2()()(r, c); diff = shifted1()()(r, c) - shifted2()()(r, c);
nn = real(conjugate(diff) * diff); nn = real(conjugate(diff) * diff);
if (nn > 0) if (nn > 0)
cout<<"Shift fail (shifted1/shifted2-ref) "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" " cout << "Shift fail (shifted1/shifted2-ref) " << coor[0]
<< coor[1] << coor[2] << coor[3] << " "
<< shifted1()()(r, c) << " " << shifted2()()(r, c) << shifted1()()(r, c) << " " << shifted2()()(r, c)
<< " "<< foo()()(r,c)<< " lex expect " << lex_coor << " lex "<<lex<<endl; << " " << foo()()(r, c) << " lex expect "
<< lex_coor << " lex " << lex << endl;
else if (0) else if (0)
cout<<"Shift pass 1vs2 "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" " cout << "Shift pass 1vs2 " << coor[0] << coor[1]
<<shifted1()()(r,c)<<" "<<shifted2()()(r,c) << coor[2] << coor[3] << " " << shifted1()()(r, c)
<< " "<< foo()()(r,c)<< " lex expect " << lex_coor << " lex "<<lex<<endl; << " " << shifted2()()(r, c) << " "
}} << foo()()(r, c) << " lex expect " << lex_coor
<< " lex " << lex << endl;
}
}
for (int r = 0; r < 3; r++) { for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) { for (int c = 0; c < 3; c++) {
diff = shifted3()()(r, c) - shifted2()()(r, c); diff = shifted3()()(r, c) - shifted2()()(r, c);
nn = real(conjugate(diff) * diff); nn = real(conjugate(diff) * diff);
if (nn > 0) if (nn > 0)
cout<<"Shift rb fail (shifted3/shifted2-ref) "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" " cout << "Shift rb fail (shifted3/shifted2-ref) "
<< coor[0] << coor[1] << coor[2] << coor[3] << " "
<< shifted3()()(r, c) << " " << shifted2()()(r, c) << shifted3()()(r, c) << " " << shifted2()()(r, c)
<< " "<< foo()()(r,c)<< " lex expect " << lex_coor << " lex "<<lex<<endl; << " " << foo()()(r, c) << " lex expect "
<< lex_coor << " lex " << lex << endl;
else if (0) else if (0)
cout<<"Shift rb pass 3vs2 "<<coor[0]<<coor[1]<<coor[2]<<coor[3] <<" " cout << "Shift rb pass 3vs2 " << coor[0] << coor[1]
<<shifted3()()(r,c)<<" "<<shifted2()()(r,c) << coor[2] << coor[3] << " " << shifted3()()(r, c)
<< " "<< foo()()(r,c)<< " lex expect " << lex_coor << " lex "<<lex<<endl; << " " << shifted2()()(r, c) << " "
}} << foo()()(r, c) << " lex expect " << lex_coor
<< " lex " << lex << endl;
}
}
peekSite(bar, Bar, coor); peekSite(bar, Bar, coor);
peekSite(foobar1, FooBar, coor); peekSite(foobar1, FooBar, coor);
@ -596,18 +636,31 @@ int main (int argc, char ** argv)
for (int c = 0; c < Nc; c++) { for (int c = 0; c < Nc; c++) {
diff = foobar2()()(r, c) - foobar1()()(r, c); diff = foobar2()()(r, c) - foobar1()()(r, c);
nrm = nrm + real(conjugate(diff) * diff); nrm = nrm + real(conjugate(diff) * diff);
}}
}}}}
if( Fine.IsBoss() ){
std::cout<<GridLogMessage << "LatticeColorMatrix * LatticeColorMatrix nrm diff = "<<nrm<<std::endl;
} }
}} }
}
}
}
}
if (Fine.IsBoss()) {
std::cout << GridLogMessage
<< "LatticeColorMatrix * LatticeColorMatrix nrm diff = "
<< nrm << std::endl;
}
}
}
} // loop for lat } // loop for lat
} // loop for omp } // loop for omp
/*
// Testing Smearing routine compilation, separate in a different file
GridCartesian Fine(latt_size,simd_layout,mpi_layout);
Smear_APE< PeriodicGimplR > APEsmearing; // periodic gauge implemetation
Smear_Stout< PeriodicGimplR > StoutSmearing(&APEsmearing);
SmearedConfiguration< PeriodicGimplR > SmartConf(&Fine, 3, StoutSmearing);
std::cout<<GridLogMessage << sizeof(vComplexF) << std::endl; std::cout<<GridLogMessage << sizeof(vComplexF) << std::endl;
*/
Grid_finalize(); Grid_finalize();
} }

View File

@ -23,7 +23,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#include "Grid.h" #include "Grid.h"
@ -35,10 +36,8 @@ using namespace Grid::QCD;
namespace Grid { namespace Grid {
namespace QCD { namespace QCD {
class HmcRunner : public NerscHmcRunner { class HmcRunner : public NerscHmcRunner {
public: public:
void BuildTheAction(int argc, char **argv) void BuildTheAction(int argc, char **argv)
{ {
@ -46,7 +45,9 @@ public:
typedef WilsonFermionR FermionAction; typedef WilsonFermionR FermionAction;
typedef typename FermionAction::FermionField FermionField; typedef typename FermionAction::FermionField FermionField;
UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi()); UGrid = SpaceTimeGrid::makeFourDimGrid(
GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()),
GridDefaultMpi());
UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
FGrid = UGrid; FGrid = UGrid;
@ -62,9 +63,15 @@ public:
FermionAction FermOp(U, *FGrid, *FrbGrid, mass); FermionAction FermOp(U, *FGrid, *FrbGrid, mass);
// 1+1 flavour // 1+1 flavour
OneFlavourRationalParams Params(1.0e-4,64.0,1000,1.0e-6); OneFlavourRationalParams Params(1.0e-4, 64.0, 2000, 1.0e-6);
OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1a(FermOp,Params); OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1a(
OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1b(FermOp,Params); FermOp, Params);
OneFlavourEvenOddRationalPseudoFermionAction<WilsonImplR> WilsonNf1b(
FermOp, Params);
//Smearing on/off
WilsonNf1a.is_smeared = true;
WilsonNf1b.is_smeared = true;
// Collect actions // Collect actions
ActionLevel<LatticeGaugeField> Level1; ActionLevel<LatticeGaugeField> Level1;
@ -76,22 +83,18 @@ public:
Run(argc, argv); Run(argc, argv);
}; };
}; };
}
}
}} int main(int argc, char **argv) {
int main (int argc, char ** argv)
{
Grid_init(&argc, &argv); Grid_init(&argc, &argv);
int threads = GridThread::GetThreads(); int threads = GridThread::GetThreads();
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl; std::cout << GridLogMessage << "Grid is setup to use " << threads
<< " threads" << std::endl;
HmcRunner TheHMC; HmcRunner TheHMC;
TheHMC.BuildTheAction(argc, argv); TheHMC.BuildTheAction(argc, argv);
} }

View File

@ -66,6 +66,10 @@ public:
OneFlavourRationalPseudoFermionAction<WilsonImplR> WilsonNf1a(FermOp,Params); OneFlavourRationalPseudoFermionAction<WilsonImplR> WilsonNf1a(FermOp,Params);
OneFlavourRationalPseudoFermionAction<WilsonImplR> WilsonNf1b(FermOp,Params); OneFlavourRationalPseudoFermionAction<WilsonImplR> WilsonNf1b(FermOp,Params);
//Set smearing (true/false), default: false
WilsonNf1a.is_smeared=false;
WilsonNf1b.is_smeared=false;
//Collect actions //Collect actions
ActionLevel<LatticeGaugeField> Level1; ActionLevel<LatticeGaugeField> Level1;
Level1.push_back(&WilsonNf1a); Level1.push_back(&WilsonNf1a);

View File

@ -23,7 +23,8 @@ Author: neo <cossu@post.kek.jp>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#include <Grid.h> #include <Grid.h>
@ -62,6 +63,18 @@ public:
template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = adj(i1);} template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = adj(i1);}
std::string name(void) const { return std::string("Adj"); } std::string name(void) const { return std::string("Adj"); }
}; };
class funcImag {
public:
funcImag() {};
template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = imag(i1);}
std::string name(void) const { return std::string("imag"); }
};
class funcReal {
public:
funcReal() {};
template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = real(i1);}
std::string name(void) const { return std::string("real"); }
};
class funcTimesI { class funcTimesI {
public: public:
@ -141,8 +154,14 @@ void Tester(const functor &func)
} }
extract<vec,scal>(v_result,result); extract<vec,scal>(v_result,result);
std::cout << GridLogMessage << " " << func.name() << std::endl; std::cout << GridLogMessage << " " << func.name() << std::endl;
std::cout << GridLogDebug << v_input1 << std::endl;
std::cout << GridLogDebug << v_result << std::endl;
int ok=0; int ok=0;
for(int i=0;i<Nsimd;i++){ for(int i=0;i<Nsimd;i++){
if ( abs(reference[i]-result[i])>1.0e-7){ if ( abs(reference[i]-result[i])>1.0e-7){
@ -389,6 +408,8 @@ int main (int argc, char ** argv)
Tester<ComplexF,vComplexF>(funcTimes()); Tester<ComplexF,vComplexF>(funcTimes());
Tester<ComplexF,vComplexF>(funcConj()); Tester<ComplexF,vComplexF>(funcConj());
Tester<ComplexF,vComplexF>(funcAdj()); Tester<ComplexF,vComplexF>(funcAdj());
Tester<ComplexF,vComplexF>(funcReal());
Tester<ComplexF,vComplexF>(funcImag());
Tester<ComplexF,vComplexF>(funcInnerProduct()); Tester<ComplexF,vComplexF>(funcInnerProduct());
ReductionTester<ComplexF,ComplexF,vComplexF>(funcReduce()); ReductionTester<ComplexF,ComplexF,vComplexF>(funcReduce());
@ -421,13 +442,17 @@ int main (int argc, char ** argv)
Tester<ComplexD,vComplexD>(funcTimes()); Tester<ComplexD,vComplexD>(funcTimes());
Tester<ComplexD,vComplexD>(funcConj()); Tester<ComplexD,vComplexD>(funcConj());
Tester<ComplexD,vComplexD>(funcAdj()); Tester<ComplexD,vComplexD>(funcAdj());
Tester<ComplexD, vComplexD>(funcReal());
Tester<ComplexD, vComplexD>(funcImag());
Tester<ComplexD, vComplexD>(funcInnerProduct()); Tester<ComplexD, vComplexD>(funcInnerProduct());
ReductionTester<ComplexD, ComplexD, vComplexD>(funcReduce()); ReductionTester<ComplexD, ComplexD, vComplexD>(funcReduce());
std::cout << GridLogMessage
std::cout<<GridLogMessage << "==================================="<< std::endl; << "===================================" << std::endl;
std::cout << GridLogMessage << "Testing vComplexD permutes " << std::endl; std::cout << GridLogMessage << "Testing vComplexD permutes " << std::endl;
std::cout<<GridLogMessage << "==================================="<< std::endl; std::cout << GridLogMessage
<< "===================================" << std::endl;
// Log2 iteration // Log2 iteration
for (int i = 0; (1 << i) < vComplexD::Nsimd(); i++) { for (int i = 0; (1 << i) < vComplexD::Nsimd(); i++) {