mirror of
https://github.com/paboyle/Grid.git
synced 2025-06-13 12:47:05 +01:00
Tested smeared RHMC Wilson1p1, accepting
This commit is contained in:
@ -1,73 +1,74 @@
|
||||
/*************************************************************************************
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/lattice/Lattice_ET.h
|
||||
Source file: ./lib/lattice/Lattice_ET.h
|
||||
|
||||
Copyright (C) 2015
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: neo <cossu@post.kek.jp>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
See the full license in the file "LICENSE" in the top level distribution
|
||||
directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef GRID_LATTICE_ET_H
|
||||
#define GRID_LATTICE_ET_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
|
||||
namespace Grid {
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Predicated where support
|
||||
////////////////////////////////////////////////////
|
||||
template<class iobj,class vobj,class robj>
|
||||
inline vobj predicatedWhere(const iobj &predicate,const vobj &iftrue,const robj &iffalse) {
|
||||
////////////////////////////////////////////////////
|
||||
// Predicated where support
|
||||
////////////////////////////////////////////////////
|
||||
template <class iobj, class vobj, class robj>
|
||||
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_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
|
||||
typedef typename vobj::scalar_object scalar_object;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
const int Nsimd = vobj::vector_type::Nsimd();
|
||||
const int words = sizeof(vobj) / sizeof(vector_type);
|
||||
|
||||
const int Nsimd = vobj::vector_type::Nsimd();
|
||||
const int words = sizeof(vobj)/sizeof(vector_type);
|
||||
std::vector<Integer> mask(Nsimd);
|
||||
std::vector<scalar_object> truevals(Nsimd);
|
||||
std::vector<scalar_object> falsevals(Nsimd);
|
||||
|
||||
std::vector<Integer> mask(Nsimd);
|
||||
std::vector<scalar_object> truevals (Nsimd);
|
||||
std::vector<scalar_object> falsevals(Nsimd);
|
||||
extract(iftrue, truevals);
|
||||
extract(iffalse, falsevals);
|
||||
extract<vInteger, Integer>(TensorRemove(predicate), mask);
|
||||
|
||||
extract(iftrue ,truevals);
|
||||
extract(iffalse ,falsevals);
|
||||
extract<vInteger,Integer>(TensorRemove(predicate),mask);
|
||||
|
||||
for(int s=0;s<Nsimd;s++){
|
||||
if (mask[s]) falsevals[s]=truevals[s];
|
||||
}
|
||||
|
||||
merge(ret,falsevals);
|
||||
return ret;
|
||||
for (int s = 0; s < Nsimd; s++) {
|
||||
if (mask[s]) falsevals[s] = truevals[s];
|
||||
}
|
||||
|
||||
merge(ret, falsevals);
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
// recursive evaluation of expressions; Could
|
||||
// switch to generic approach with variadics, a la
|
||||
@ -75,311 +76,342 @@ namespace Grid {
|
||||
// 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<class sobj>
|
||||
inline sobj eval(const unsigned int ss, const sobj &arg)
|
||||
{
|
||||
template <class sobj>
|
||||
inline sobj eval(const unsigned int ss, const sobj &arg) {
|
||||
return arg;
|
||||
}
|
||||
template<class lobj>
|
||||
inline const lobj &eval(const unsigned int ss, const Lattice<lobj> &arg)
|
||||
{
|
||||
return arg._odata[ss];
|
||||
template <class lobj>
|
||||
inline const lobj &eval(const unsigned int ss, const Lattice<lobj> &arg) {
|
||||
return arg._odata[ss];
|
||||
}
|
||||
|
||||
// handle nodes in syntax tree
|
||||
template <typename Op, typename T1>
|
||||
auto inline eval(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)));
|
||||
auto inline eval(
|
||||
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)));
|
||||
}
|
||||
|
||||
template <typename Op, typename T1, typename T2>
|
||||
auto inline eval(const unsigned int ss, const LatticeBinaryExpression<Op,T1,T2> &expr) // eval two operands
|
||||
-> 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)));
|
||||
auto inline eval(
|
||||
const unsigned int ss,
|
||||
const LatticeBinaryExpression<Op, T1, T2> &expr) // eval two operands
|
||||
-> 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>
|
||||
auto inline eval(const unsigned int ss, const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr) // eval three operands
|
||||
-> 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)) );
|
||||
auto inline eval(const unsigned int ss,
|
||||
const LatticeTrinaryExpression<Op, T1, T2, T3>
|
||||
&expr) // eval three operands
|
||||
-> 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 >
|
||||
inline void GridFromExpression(GridBase * &grid,const T1& lat) // Lattice leaf
|
||||
{
|
||||
if ( grid ) {
|
||||
conformable(grid,lat._grid);
|
||||
}
|
||||
grid=lat._grid;
|
||||
}
|
||||
template<class T1,typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr >
|
||||
inline void GridFromExpression(GridBase * &grid,const T1& notlat) // non-lattice leaf
|
||||
template <class T1,
|
||||
typename std::enable_if<is_lattice<T1>::value, T1>::type * = nullptr>
|
||||
inline void GridFromExpression(GridBase *&grid, const T1 &lat) // Lattice leaf
|
||||
{
|
||||
if (grid) {
|
||||
conformable(grid, lat._grid);
|
||||
}
|
||||
grid = lat._grid;
|
||||
}
|
||||
template <class T1,
|
||||
typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr>
|
||||
inline void GridFromExpression(GridBase *&grid,
|
||||
const T1 ¬lat) // non-lattice leaf
|
||||
{}
|
||||
template <typename Op, typename T1>
|
||||
inline void GridFromExpression(GridBase * &grid,const LatticeUnaryExpression<Op,T1 > &expr)
|
||||
{
|
||||
GridFromExpression(grid,std::get<0>(expr.second));// recurse
|
||||
inline void GridFromExpression(GridBase *&grid,
|
||||
const LatticeUnaryExpression<Op, T1> &expr) {
|
||||
GridFromExpression(grid, std::get<0>(expr.second)); // recurse
|
||||
}
|
||||
|
||||
template <typename Op, typename T1, typename T2>
|
||||
inline void GridFromExpression(GridBase * &grid,const LatticeBinaryExpression<Op,T1,T2> &expr)
|
||||
{
|
||||
GridFromExpression(grid,std::get<0>(expr.second));// recurse
|
||||
GridFromExpression(grid,std::get<1>(expr.second));
|
||||
inline void GridFromExpression(
|
||||
GridBase *&grid, const LatticeBinaryExpression<Op, T1, T2> &expr) {
|
||||
GridFromExpression(grid, std::get<0>(expr.second)); // recurse
|
||||
GridFromExpression(grid, std::get<1>(expr.second));
|
||||
}
|
||||
template <typename Op, typename T1, typename T2, typename T3>
|
||||
inline void GridFromExpression( GridBase * &grid,const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr)
|
||||
{
|
||||
GridFromExpression(grid,std::get<0>(expr.second));// recurse
|
||||
GridFromExpression(grid,std::get<1>(expr.second));
|
||||
GridFromExpression(grid,std::get<2>(expr.second));
|
||||
inline void GridFromExpression(
|
||||
GridBase *&grid, const LatticeTrinaryExpression<Op, T1, T2, T3> &expr) {
|
||||
GridFromExpression(grid, std::get<0>(expr.second)); // recurse
|
||||
GridFromExpression(grid, std::get<1>(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 >
|
||||
inline void CBFromExpression(int &cb,const T1& lat) // Lattice leaf
|
||||
template <class T1,
|
||||
typename std::enable_if<is_lattice<T1>::value, T1>::type * = nullptr>
|
||||
inline void CBFromExpression(int &cb, const T1 &lat) // Lattice leaf
|
||||
{
|
||||
if ( (cb==Odd) || (cb==Even) ) {
|
||||
assert(cb==lat.checkerboard);
|
||||
}
|
||||
cb=lat.checkerboard;
|
||||
if ((cb == Odd) || (cb == Even)) {
|
||||
assert(cb == lat.checkerboard);
|
||||
}
|
||||
cb = lat.checkerboard;
|
||||
// std::cout<<GridLogMessage<<"Lattice leaf cb "<<cb<<std::endl;
|
||||
}
|
||||
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
|
||||
template <class T1,
|
||||
typename std::enable_if<!is_lattice<T1>::value, T1>::type * = nullptr>
|
||||
inline void CBFromExpression(int &cb, const T1 ¬lat) // non-lattice leaf
|
||||
{
|
||||
// std::cout<<GridLogMessage<<"Non lattice leaf cb"<<cb<<std::endl;
|
||||
}
|
||||
template <typename Op, typename T1>
|
||||
inline void CBFromExpression(int &cb,const LatticeUnaryExpression<Op,T1 > &expr)
|
||||
{
|
||||
CBFromExpression(cb,std::get<0>(expr.second));// recurse
|
||||
inline void CBFromExpression(int &cb,
|
||||
const LatticeUnaryExpression<Op, T1> &expr) {
|
||||
CBFromExpression(cb, std::get<0>(expr.second)); // recurse
|
||||
// std::cout<<GridLogMessage<<"Unary node cb "<<cb<<std::endl;
|
||||
}
|
||||
|
||||
template <typename Op, typename T1, typename T2>
|
||||
inline void CBFromExpression(int &cb,const LatticeBinaryExpression<Op,T1,T2> &expr)
|
||||
{
|
||||
CBFromExpression(cb,std::get<0>(expr.second));// recurse
|
||||
CBFromExpression(cb,std::get<1>(expr.second));
|
||||
inline void CBFromExpression(int &cb,
|
||||
const LatticeBinaryExpression<Op, T1, T2> &expr) {
|
||||
CBFromExpression(cb, std::get<0>(expr.second)); // recurse
|
||||
CBFromExpression(cb, std::get<1>(expr.second));
|
||||
// std::cout<<GridLogMessage<<"Binary node cb "<<cb<<std::endl;
|
||||
}
|
||||
template <typename Op, typename T1, typename T2, typename T3>
|
||||
inline void CBFromExpression( int &cb,const LatticeTrinaryExpression<Op,T1,T2,T3 > &expr)
|
||||
{
|
||||
CBFromExpression(cb,std::get<0>(expr.second));// recurse
|
||||
CBFromExpression(cb,std::get<1>(expr.second));
|
||||
CBFromExpression(cb,std::get<2>(expr.second));
|
||||
inline void CBFromExpression(
|
||||
int &cb, const LatticeTrinaryExpression<Op, T1, T2, T3> &expr) {
|
||||
CBFromExpression(cb, std::get<0>(expr.second)); // recurse
|
||||
CBFromExpression(cb, std::get<1>(expr.second));
|
||||
CBFromExpression(cb, std::get<2>(expr.second));
|
||||
// std::cout<<GridLogMessage<<"Trinary node cb "<<cb<<std::endl;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Unary operators and funcs
|
||||
////////////////////////////////////////////
|
||||
#define GridUnopClass(name,ret)\
|
||||
template <class arg> struct name \
|
||||
{ \
|
||||
static auto inline func(const arg a)-> decltype(ret) { return ret; } \
|
||||
};
|
||||
|
||||
GridUnopClass(UnarySub,-a);
|
||||
GridUnopClass(UnaryNot,Not(a));
|
||||
GridUnopClass(UnaryAdj,adj(a));
|
||||
GridUnopClass(UnaryConj,conjugate(a));
|
||||
GridUnopClass(UnaryTrace,trace(a));
|
||||
GridUnopClass(UnaryTranspose,transpose(a));
|
||||
GridUnopClass(UnaryTa,Ta(a));
|
||||
GridUnopClass(UnaryProjectOnGroup,ProjectOnGroup(a));
|
||||
GridUnopClass(UnaryReal,real(a));
|
||||
GridUnopClass(UnaryImag,imag(a));
|
||||
GridUnopClass(UnaryToReal,toReal(a));
|
||||
GridUnopClass(UnaryToComplex,toComplex(a));
|
||||
GridUnopClass(UnaryTimesI,timesI(a));
|
||||
GridUnopClass(UnaryTimesMinusI,timesMinusI(a));
|
||||
GridUnopClass(UnaryAbs,abs(a));
|
||||
GridUnopClass(UnarySqrt,sqrt(a));
|
||||
GridUnopClass(UnaryRsqrt,rsqrt(a));
|
||||
GridUnopClass(UnarySin,sin(a));
|
||||
GridUnopClass(UnaryCos,cos(a));
|
||||
GridUnopClass(UnaryAsin,asin(a));
|
||||
GridUnopClass(UnaryAcos,acos(a));
|
||||
GridUnopClass(UnaryLog,log(a));
|
||||
GridUnopClass(UnaryExp,exp(a));
|
||||
|
||||
#define GridUnopClass(name, ret) \
|
||||
template <class arg> \
|
||||
struct name { \
|
||||
static auto inline func(const arg a) -> decltype(ret) { return ret; } \
|
||||
};
|
||||
|
||||
GridUnopClass(UnarySub, -a);
|
||||
GridUnopClass(UnaryNot, Not(a));
|
||||
GridUnopClass(UnaryAdj, adj(a));
|
||||
GridUnopClass(UnaryConj, conjugate(a));
|
||||
GridUnopClass(UnaryTrace, trace(a));
|
||||
GridUnopClass(UnaryTranspose, transpose(a));
|
||||
GridUnopClass(UnaryTa, Ta(a));
|
||||
GridUnopClass(UnaryProjectOnGroup, ProjectOnGroup(a));
|
||||
GridUnopClass(UnaryReal, real(a));
|
||||
GridUnopClass(UnaryImag, imag(a));
|
||||
GridUnopClass(UnaryToReal, toReal(a));
|
||||
GridUnopClass(UnaryToComplex, toComplex(a));
|
||||
GridUnopClass(UnaryTimesI, timesI(a));
|
||||
GridUnopClass(UnaryTimesMinusI, timesMinusI(a));
|
||||
GridUnopClass(UnaryAbs, abs(a));
|
||||
GridUnopClass(UnarySqrt, sqrt(a));
|
||||
GridUnopClass(UnaryRsqrt, rsqrt(a));
|
||||
GridUnopClass(UnarySin, sin(a));
|
||||
GridUnopClass(UnaryCos, cos(a));
|
||||
GridUnopClass(UnaryAsin, asin(a));
|
||||
GridUnopClass(UnaryAcos, acos(a));
|
||||
GridUnopClass(UnaryLog, log(a));
|
||||
GridUnopClass(UnaryExp, exp(a));
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Binary operators
|
||||
////////////////////////////////////////////
|
||||
#define GridBinOpClass(name,combination)\
|
||||
template <class left,class right>\
|
||||
struct name\
|
||||
{\
|
||||
static auto inline func(const left &lhs,const right &rhs)-> decltype(combination) const \
|
||||
{\
|
||||
return combination;\
|
||||
}\
|
||||
}
|
||||
GridBinOpClass(BinaryAdd,lhs+rhs);
|
||||
GridBinOpClass(BinarySub,lhs-rhs);
|
||||
GridBinOpClass(BinaryMul,lhs*rhs);
|
||||
#define GridBinOpClass(name, combination) \
|
||||
template <class left, class right> \
|
||||
struct name { \
|
||||
static auto inline func(const left &lhs, const right &rhs) \
|
||||
-> decltype(combination) const { \
|
||||
return combination; \
|
||||
} \
|
||||
}
|
||||
GridBinOpClass(BinaryAdd, lhs + rhs);
|
||||
GridBinOpClass(BinarySub, lhs - rhs);
|
||||
GridBinOpClass(BinaryMul, lhs *rhs);
|
||||
|
||||
GridBinOpClass(BinaryAnd ,lhs&rhs);
|
||||
GridBinOpClass(BinaryOr ,lhs|rhs);
|
||||
GridBinOpClass(BinaryAndAnd,lhs&&rhs);
|
||||
GridBinOpClass(BinaryOrOr ,lhs||rhs);
|
||||
GridBinOpClass(BinaryAnd, lhs &rhs);
|
||||
GridBinOpClass(BinaryOr, lhs | rhs);
|
||||
GridBinOpClass(BinaryAndAnd, lhs &&rhs);
|
||||
GridBinOpClass(BinaryOrOr, lhs || rhs);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Trinary conditional op
|
||||
////////////////////////////////////////////////////
|
||||
#define GridTrinOpClass(name,combination)\
|
||||
template <class predicate,class left, class right> \
|
||||
struct name\
|
||||
{\
|
||||
static auto inline func(const predicate &pred,const left &lhs,const right &rhs)-> decltype(combination) const \
|
||||
{\
|
||||
return combination;\
|
||||
}\
|
||||
}
|
||||
#define GridTrinOpClass(name, combination) \
|
||||
template <class predicate, class left, class right> \
|
||||
struct name { \
|
||||
static auto inline func(const predicate &pred, const left &lhs, \
|
||||
const right &rhs) -> decltype(combination) const { \
|
||||
return combination; \
|
||||
} \
|
||||
}
|
||||
|
||||
GridTrinOpClass(TrinaryWhere,(predicatedWhere<predicate, \
|
||||
typename std::remove_reference<left>::type, \
|
||||
typename std::remove_reference<right>::type> (pred,lhs,rhs)));
|
||||
GridTrinOpClass(
|
||||
TrinaryWhere,
|
||||
(predicatedWhere<predicate, typename std::remove_reference<left>::type,
|
||||
typename std::remove_reference<right>::type>(pred, lhs,
|
||||
rhs)));
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Operator syntactical glue
|
||||
////////////////////////////////////////////
|
||||
|
||||
#define GRID_UNOP(name) name<decltype(eval(0, arg))>
|
||||
#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_DEF_UNOP(op, name)\
|
||||
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) \
|
||||
-> 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_UNOP(name) name<decltype(eval(0, arg))>
|
||||
#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_BINOP_LEFT(op, name)\
|
||||
template <typename T1,typename T2,\
|
||||
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) \
|
||||
-> decltype(LatticeBinaryExpression<GRID_BINOP(name),const T1&,const T2 &>(std::make_pair(GRID_BINOP(name)(),\
|
||||
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_UNOP(op, name) \
|
||||
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) \
|
||||
->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_RIGHT(op, name)\
|
||||
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<T2>::value || is_lattice_expr<T2>::value, T2>::type* = nullptr> \
|
||||
inline auto op(const T1 &lhs,const T2&rhs) \
|
||||
-> decltype(LatticeBinaryExpression<GRID_BINOP(name),const T1&,const T2 &>(std::make_pair(GRID_BINOP(name)(),\
|
||||
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_LEFT(op, name) \
|
||||
template <typename T1, typename T2, \
|
||||
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) \
|
||||
->decltype( \
|
||||
LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
|
||||
std::make_pair(GRID_BINOP(name)(), \
|
||||
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)\
|
||||
GRID_BINOP_LEFT(op,name);\
|
||||
GRID_BINOP_RIGHT(op,name);
|
||||
#define GRID_BINOP_RIGHT(op, name) \
|
||||
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<T2>::value || \
|
||||
is_lattice_expr<T2>::value, \
|
||||
T2>::type * = nullptr> \
|
||||
inline auto op(const T1 &lhs, const T2 &rhs) \
|
||||
->decltype( \
|
||||
LatticeBinaryExpression<GRID_BINOP(name), const T1 &, const T2 &>( \
|
||||
std::make_pair(GRID_BINOP(name)(), \
|
||||
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) \
|
||||
GRID_BINOP_LEFT(op, name); \
|
||||
GRID_BINOP_RIGHT(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) \
|
||||
-> decltype(LatticeTrinaryExpression<GRID_TRINOP(name),const T1&,const T2 &,const T3&>(std::make_pair(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))); \
|
||||
}
|
||||
#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) \
|
||||
->decltype( \
|
||||
LatticeTrinaryExpression<GRID_TRINOP(name), const T1 &, const T2 &, \
|
||||
const T3 &>(std::make_pair( \
|
||||
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
|
||||
////////////////////////
|
||||
|
||||
GRID_DEF_UNOP(operator -,UnarySub);
|
||||
GRID_DEF_UNOP(Not,UnaryNot);
|
||||
GRID_DEF_UNOP(operator !,UnaryNot);
|
||||
GRID_DEF_UNOP(adj,UnaryAdj);
|
||||
GRID_DEF_UNOP(conjugate,UnaryConj);
|
||||
GRID_DEF_UNOP(trace,UnaryTrace);
|
||||
GRID_DEF_UNOP(transpose,UnaryTranspose);
|
||||
GRID_DEF_UNOP(Ta,UnaryTa);
|
||||
GRID_DEF_UNOP(ProjectOnGroup,UnaryProjectOnGroup);
|
||||
GRID_DEF_UNOP(real,UnaryReal);
|
||||
GRID_DEF_UNOP(imag,UnaryImag);
|
||||
GRID_DEF_UNOP(toReal,UnaryToReal);
|
||||
GRID_DEF_UNOP(toComplex,UnaryToComplex);
|
||||
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(rsqrt,UnaryRsqrt);
|
||||
GRID_DEF_UNOP(sin ,UnarySin);
|
||||
GRID_DEF_UNOP(cos ,UnaryCos);
|
||||
GRID_DEF_UNOP(asin ,UnaryAsin);
|
||||
GRID_DEF_UNOP(acos ,UnaryAcos);
|
||||
GRID_DEF_UNOP(log ,UnaryLog);
|
||||
GRID_DEF_UNOP(exp ,UnaryExp);
|
||||
GRID_DEF_UNOP(operator-, UnarySub);
|
||||
GRID_DEF_UNOP(Not, UnaryNot);
|
||||
GRID_DEF_UNOP(operator!, UnaryNot);
|
||||
GRID_DEF_UNOP(adj, UnaryAdj);
|
||||
GRID_DEF_UNOP(conjugate, UnaryConj);
|
||||
GRID_DEF_UNOP(trace, UnaryTrace);
|
||||
GRID_DEF_UNOP(transpose, UnaryTranspose);
|
||||
GRID_DEF_UNOP(Ta, UnaryTa);
|
||||
GRID_DEF_UNOP(ProjectOnGroup, UnaryProjectOnGroup);
|
||||
GRID_DEF_UNOP(real, UnaryReal);
|
||||
GRID_DEF_UNOP(imag, UnaryImag);
|
||||
GRID_DEF_UNOP(toReal, UnaryToReal);
|
||||
GRID_DEF_UNOP(toComplex, UnaryToComplex);
|
||||
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(rsqrt, UnaryRsqrt);
|
||||
GRID_DEF_UNOP(sin, UnarySin);
|
||||
GRID_DEF_UNOP(cos, UnaryCos);
|
||||
GRID_DEF_UNOP(asin, UnaryAsin);
|
||||
GRID_DEF_UNOP(acos, UnaryAcos);
|
||||
GRID_DEF_UNOP(log, UnaryLog);
|
||||
GRID_DEF_UNOP(exp, UnaryExp);
|
||||
|
||||
GRID_DEF_BINOP(operator+,BinaryAdd);
|
||||
GRID_DEF_BINOP(operator-,BinarySub);
|
||||
GRID_DEF_BINOP(operator*,BinaryMul);
|
||||
GRID_DEF_BINOP(operator+, BinaryAdd);
|
||||
GRID_DEF_BINOP(operator-, BinarySub);
|
||||
GRID_DEF_BINOP(operator*, BinaryMul);
|
||||
|
||||
GRID_DEF_BINOP(operator&,BinaryAnd);
|
||||
GRID_DEF_BINOP(operator|,BinaryOr);
|
||||
GRID_DEF_BINOP(operator&&,BinaryAndAnd);
|
||||
GRID_DEF_BINOP(operator||,BinaryOrOr);
|
||||
GRID_DEF_BINOP(operator&, BinaryAnd);
|
||||
GRID_DEF_BINOP(operator|, BinaryOr);
|
||||
GRID_DEF_BINOP(operator&&, BinaryAndAnd);
|
||||
GRID_DEF_BINOP(operator||, BinaryOrOr);
|
||||
|
||||
GRID_DEF_TRINOP(where,TrinaryWhere);
|
||||
GRID_DEF_TRINOP(where, TrinaryWhere);
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Closure convenience to force expression to evaluate
|
||||
/////////////////////////////////////////////////////////////
|
||||
template<class Op,class T1>
|
||||
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))))> ret(expr);
|
||||
template <class Op, class T1>
|
||||
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))))> ret(
|
||||
expr);
|
||||
return ret;
|
||||
}
|
||||
template<class Op,class T1, class T2>
|
||||
auto closure(const LatticeBinaryExpression<Op,T1,T2> & expr)
|
||||
-> Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second)),
|
||||
eval(0,std::get<1>(expr.second))))>
|
||||
{
|
||||
Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second)),
|
||||
eval(0,std::get<1>(expr.second))))> ret(expr);
|
||||
template <class Op, class T1, class T2>
|
||||
auto closure(const LatticeBinaryExpression<Op, T1, T2> &expr)
|
||||
-> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
|
||||
eval(0, std::get<1>(expr.second))))> {
|
||||
Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
|
||||
eval(0, std::get<1>(expr.second))))>
|
||||
ret(expr);
|
||||
return ret;
|
||||
}
|
||||
template<class Op,class T1, class T2, class T3>
|
||||
auto closure(const LatticeTrinaryExpression<Op,T1,T2,T3> & expr)
|
||||
-> Lattice<decltype(expr.first.func(eval(0,std::get<0>(expr.second)),
|
||||
eval(0,std::get<1>(expr.second)),
|
||||
eval(0,std::get<2>(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<2>(expr.second))))> ret(expr);
|
||||
template <class Op, class T1, class T2, class T3>
|
||||
auto closure(const LatticeTrinaryExpression<Op, T1, T2, T3> &expr)
|
||||
-> Lattice<decltype(expr.first.func(eval(0, std::get<0>(expr.second)),
|
||||
eval(0, std::get<1>(expr.second)),
|
||||
eval(0, std::get<2>(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<2>(expr.second))))>
|
||||
ret(expr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -390,12 +422,11 @@ template<class Op,class T1, class T2, class T3>
|
||||
#undef GRID_DEF_UNOP
|
||||
#undef GRID_DEF_BINOP
|
||||
#undef GRID_DEF_TRINOP
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
using namespace Grid;
|
||||
|
||||
|
||||
int main(int argc,char **argv){
|
||||
|
||||
Lattice<double> v1(16);
|
||||
@ -405,7 +436,7 @@ using namespace Grid;
|
||||
BinaryAdd<double,double> tmp;
|
||||
LatticeBinaryExpression<BinaryAdd<double,double>,Lattice<double> &,Lattice<double> &>
|
||||
expr(std::make_pair(tmp,
|
||||
std::forward_as_tuple(v1,v2)));
|
||||
std::forward_as_tuple(v1,v2)));
|
||||
tmp.func(eval(0,v1),eval(0,v2));
|
||||
|
||||
auto var = v1+v2;
|
||||
|
Reference in New Issue
Block a user