mirror of
https://github.com/paboyle/Grid.git
synced 2025-06-12 20:27:06 +01:00
Large scale change to support 5d fermion formulations.
Have 5d replicated wilson with 4d gauge working and matrix regressing to Ls copies of wilson.
This commit is contained in:
@ -60,7 +60,7 @@
|
||||
|
||||
#include <Grid_algorithms.h>// subdir aggregate
|
||||
|
||||
#include <qcd/Grid_qcd.h>
|
||||
#include <qcd/QCD.h>
|
||||
#include <parallelIO/GridNerscIO.h>
|
||||
|
||||
namespace Grid {
|
||||
|
@ -142,7 +142,11 @@ void Grid_init(int *argc,char ***argv)
|
||||
Grid_quiesce_nodes();
|
||||
}
|
||||
if( GridCmdOptionExists(*argv,*argv+*argc,"--dslash-opt") ){
|
||||
WilsonMatrix::HandOptDslash=1;
|
||||
WilsonFermion::HandOptDslash=1;
|
||||
FiveDimWilsonFermion::HandOptDslash=1;
|
||||
}
|
||||
if( GridCmdOptionExists(*argv,*argv+*argc,"--lebesgue") ){
|
||||
LebesgueOrder::UseLebesgueOrder=1;
|
||||
}
|
||||
GridParseLayout(*argv,*argc,
|
||||
Grid_default_latt,
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef GRID_STENCIL_H
|
||||
#define GRID_STENCIL_H
|
||||
|
||||
#include <stencil/Grid_lebesgue.h> // subdir aggregate
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Must not lose sight that goal is to be able to construct really efficient
|
||||
// gather to a point stencil code. CSHIFT is not the best way, so need
|
||||
@ -38,29 +40,12 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Grid {
|
||||
|
||||
|
||||
|
||||
|
||||
class CartesianStencil { // Stencil runs along coordinate axes only; NO diagonal fill in.
|
||||
public:
|
||||
|
||||
typedef uint32_t StencilInteger;
|
||||
|
||||
|
||||
|
||||
StencilInteger alignup(StencilInteger n){
|
||||
n--; // 1000 0011 --> 1000 0010
|
||||
n |= n >> 1; // 1000 0010 | 0100 0001 = 1100 0011
|
||||
n |= n >> 2; // 1100 0011 | 0011 0000 = 1111 0011
|
||||
n |= n >> 4; // 1111 0011 | 0000 1111 = 1111 1111
|
||||
n |= n >> 8; // ... (At this point all bits are 1, so further bitwise-or
|
||||
n |= n >> 16; // operations produce no effect.)
|
||||
n++; // 1111 1111 --> 1 0000 0000
|
||||
return n;
|
||||
};
|
||||
void LebesgueOrder(void);
|
||||
|
||||
std::vector<StencilInteger> _LebesgueReorder;
|
||||
|
||||
int _checkerboard;
|
||||
int _npoints; // Move to template param?
|
||||
@ -131,8 +116,8 @@ namespace Grid {
|
||||
// Gather phase
|
||||
int sshift [2];
|
||||
if ( comm_dim ) {
|
||||
sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,0);
|
||||
sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,1);
|
||||
sshift[0] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Even);
|
||||
sshift[1] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Odd);
|
||||
if ( sshift[0] == sshift[1] ) {
|
||||
if (splice_dim) {
|
||||
GatherStartCommsSimd(source,dimension,shift,0x3,u_comm_buf,u_comm_offset,compress);
|
||||
@ -179,8 +164,8 @@ namespace Grid {
|
||||
std::vector<cobj,alignedAllocator<cobj> > send_buf(buffer_size); // hmm...
|
||||
std::vector<cobj,alignedAllocator<cobj> > recv_buf(buffer_size);
|
||||
|
||||
int cb= (cbmask==0x2)? 1 : 0;
|
||||
int sshift= _grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
|
||||
int cb= (cbmask==0x2)? Odd : Even;
|
||||
int sshift= _grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
|
||||
|
||||
for(int x=0;x<rd;x++){
|
||||
|
||||
@ -266,8 +251,8 @@ namespace Grid {
|
||||
// Work out what to send where
|
||||
///////////////////////////////////////////
|
||||
|
||||
int cb = (cbmask==0x2)? 1 : 0;
|
||||
int sshift= _grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
|
||||
int cb = (cbmask==0x2)? Odd : Even;
|
||||
int sshift= _grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
|
||||
|
||||
// loop over outer coord planes orthog to dim
|
||||
for(int x=0;x<rd;x++){
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#ifdef GRID_OMP
|
||||
#include <omp.h>
|
||||
#define PARALLEL_FOR_LOOP _Pragma("omp parallel for")
|
||||
#define PARALLEL_FOR_LOOP _Pragma("omp parallel for ")
|
||||
#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for collapse(2)")
|
||||
#else
|
||||
#define PARALLEL_FOR_LOOP
|
||||
|
166
lib/Makefile.am
166
lib/Makefile.am
@ -16,87 +16,103 @@ endif
|
||||
lib_LIBRARIES = libGrid.a
|
||||
libGrid_a_SOURCES = \
|
||||
Grid_init.cc \
|
||||
stencil/Grid_lebesgue.cc \
|
||||
stencil/Grid_stencil_common.cc \
|
||||
qcd/Grid_qcd_dirac.cc \
|
||||
qcd/Grid_qcd_dhop.cc \
|
||||
qcd/Grid_qcd_dhop_hand.cc \
|
||||
qcd/Grid_qcd_wilson_dop.cc \
|
||||
algorithms/approx/Zolotarev.cc \
|
||||
algorithms/approx/Remez.cc \
|
||||
qcd/action/fermion/FiveDimWilsonFermion.cc\
|
||||
qcd/action/fermion/WilsonFermion.cc\
|
||||
qcd/action/fermion/WilsonKernels.cc\
|
||||
qcd/action/fermion/WilsonKernelsHand.cc\
|
||||
qcd/Dirac.cc\
|
||||
$(extra_sources)
|
||||
|
||||
#
|
||||
# Include files
|
||||
#
|
||||
nobase_include_HEADERS = algorithms/approx/bigfloat.h \
|
||||
algorithms/approx/Chebyshev.h \
|
||||
algorithms/approx/Remez.h \
|
||||
algorithms/approx/Zolotarev.h \
|
||||
algorithms/iterative/ConjugateGradient.h \
|
||||
algorithms/iterative/NormalEquations.h \
|
||||
algorithms/iterative/SchurRedBlack.h \
|
||||
algorithms/LinearOperator.h \
|
||||
algorithms/SparseMatrix.h \
|
||||
cartesian/Grid_cartesian_base.h \
|
||||
cartesian/Grid_cartesian_full.h \
|
||||
cartesian/Grid_cartesian_red_black.h \
|
||||
communicator/Grid_communicator_base.h \
|
||||
cshift/Grid_cshift_common.h \
|
||||
cshift/Grid_cshift_mpi.h \
|
||||
cshift/Grid_cshift_none.h \
|
||||
Grid.h \
|
||||
Grid_algorithms.h \
|
||||
Grid_aligned_allocator.h \
|
||||
Grid_cartesian.h \
|
||||
Grid_communicator.h \
|
||||
Grid_comparison.h \
|
||||
Grid_cshift.h \
|
||||
Grid_extract.h \
|
||||
Grid_lattice.h \
|
||||
Grid_math.h \
|
||||
Grid_simd.h \
|
||||
Grid_stencil.h \
|
||||
Grid_threads.h \
|
||||
lattice/Grid_lattice_arith.h \
|
||||
lattice/Grid_lattice_base.h \
|
||||
lattice/Grid_lattice_comparison.h \
|
||||
lattice/Grid_lattice_conformable.h \
|
||||
lattice/Grid_lattice_coordinate.h \
|
||||
lattice/Grid_lattice_ET.h \
|
||||
lattice/Grid_lattice_local.h \
|
||||
lattice/Grid_lattice_overload.h \
|
||||
lattice/Grid_lattice_peekpoke.h \
|
||||
lattice/Grid_lattice_reality.h \
|
||||
lattice/Grid_lattice_reduction.h \
|
||||
lattice/Grid_lattice_rng.h \
|
||||
lattice/Grid_lattice_trace.h \
|
||||
lattice/Grid_lattice_transfer.h \
|
||||
lattice/Grid_lattice_transpose.h \
|
||||
lattice/Grid_lattice_where.h \
|
||||
math/Grid_math_arith.h \
|
||||
math/Grid_math_arith_add.h \
|
||||
math/Grid_math_arith_mac.h \
|
||||
math/Grid_math_arith_mul.h \
|
||||
math/Grid_math_arith_scalar.h \
|
||||
math/Grid_math_arith_sub.h \
|
||||
math/Grid_math_inner.h \
|
||||
math/Grid_math_outer.h \
|
||||
math/Grid_math_peek.h \
|
||||
math/Grid_math_poke.h \
|
||||
math/Grid_math_reality.h \
|
||||
math/Grid_math_tensors.h \
|
||||
math/Grid_math_trace.h \
|
||||
math/Grid_math_traits.h \
|
||||
math/Grid_math_transpose.h \
|
||||
parallelIO/GridNerscIO.h \
|
||||
qcd/Grid_qcd.h \
|
||||
qcd/Grid_qcd_2spinor.h \
|
||||
qcd/Grid_qcd_dirac.h \
|
||||
qcd/Grid_qcd_wilson_dop.h \
|
||||
simd/Grid_vector_types.h \
|
||||
simd/Grid_sse4.h \
|
||||
simd/Grid_avx.h \
|
||||
simd/Grid_avx512.h
|
||||
|
||||
|
||||
nobase_include_HEADERS=\
|
||||
./algorithms/approx/bigfloat.h\
|
||||
./algorithms/approx/bigfloat_double.h\
|
||||
./algorithms/approx/Chebyshev.h\
|
||||
./algorithms/approx/Remez.h\
|
||||
./algorithms/approx/Zolotarev.h\
|
||||
./algorithms/iterative/ConjugateGradient.h\
|
||||
./algorithms/iterative/NormalEquations.h\
|
||||
./algorithms/iterative/SchurRedBlack.h\
|
||||
./algorithms/LinearOperator.h\
|
||||
./algorithms/SparseMatrix.h\
|
||||
./cartesian/Grid_cartesian_base.h\
|
||||
./cartesian/Grid_cartesian_full.h\
|
||||
./cartesian/Grid_cartesian_red_black.h\
|
||||
./communicator/Grid_communicator_base.h\
|
||||
./cshift/Grid_cshift_common.h\
|
||||
./cshift/Grid_cshift_mpi.h\
|
||||
./cshift/Grid_cshift_none.h\
|
||||
./Grid.h\
|
||||
./Grid_algorithms.h\
|
||||
./Grid_aligned_allocator.h\
|
||||
./Grid_cartesian.h\
|
||||
./Grid_communicator.h\
|
||||
./Grid_comparison.h\
|
||||
./Grid_config.h\
|
||||
./Grid_cshift.h\
|
||||
./Grid_extract.h\
|
||||
./Grid_lattice.h\
|
||||
./Grid_math.h\
|
||||
./Grid_simd.h\
|
||||
./Grid_stencil.h\
|
||||
./Grid_threads.h\
|
||||
./lattice/Grid_lattice_arith.h\
|
||||
./lattice/Grid_lattice_base.h\
|
||||
./lattice/Grid_lattice_comparison.h\
|
||||
./lattice/Grid_lattice_conformable.h\
|
||||
./lattice/Grid_lattice_coordinate.h\
|
||||
./lattice/Grid_lattice_ET.h\
|
||||
./lattice/Grid_lattice_local.h\
|
||||
./lattice/Grid_lattice_overload.h\
|
||||
./lattice/Grid_lattice_peekpoke.h\
|
||||
./lattice/Grid_lattice_reality.h\
|
||||
./lattice/Grid_lattice_reduction.h\
|
||||
./lattice/Grid_lattice_rng.h\
|
||||
./lattice/Grid_lattice_trace.h\
|
||||
./lattice/Grid_lattice_transfer.h\
|
||||
./lattice/Grid_lattice_transpose.h\
|
||||
./lattice/Grid_lattice_where.h\
|
||||
./math/Grid_math_arith.h\
|
||||
./math/Grid_math_arith_add.h\
|
||||
./math/Grid_math_arith_mac.h\
|
||||
./math/Grid_math_arith_mul.h\
|
||||
./math/Grid_math_arith_scalar.h\
|
||||
./math/Grid_math_arith_sub.h\
|
||||
./math/Grid_math_inner.h\
|
||||
./math/Grid_math_outer.h\
|
||||
./math/Grid_math_peek.h\
|
||||
./math/Grid_math_poke.h\
|
||||
./math/Grid_math_reality.h\
|
||||
./math/Grid_math_tensors.h\
|
||||
./math/Grid_math_trace.h\
|
||||
./math/Grid_math_traits.h\
|
||||
./math/Grid_math_transpose.h\
|
||||
./parallelIO/GridNerscIO.h\
|
||||
./qcd/action/Actions.h\
|
||||
./qcd/action/fermion/FermionAction.h\
|
||||
./qcd/action/fermion/FiveDimWilsonFermion.h\
|
||||
./qcd/action/fermion/WilsonCompressor.h\
|
||||
./qcd/action/fermion/WilsonFermion.h\
|
||||
./qcd/action/fermion/WilsonKernels.h\
|
||||
./qcd/Dirac.h\
|
||||
./qcd/QCD.h\
|
||||
./qcd/TwoSpinor.h\
|
||||
./qcd/FermionAction.h\
|
||||
./simd/Grid_avx.h\
|
||||
./simd/Grid_avx512.h\
|
||||
./simd/Grid_qpx.h\
|
||||
./simd/Grid_sse4.h\
|
||||
./simd/Grid_vector_types.h\
|
||||
./simd/Old/Grid_vComplexD.h\
|
||||
./simd/Old/Grid_vComplexF.h\
|
||||
./simd/Old/Grid_vInteger.h\
|
||||
./simd/Old/Grid_vRealD.h\
|
||||
./simd/Old/Grid_vRealF.h\
|
||||
./stencil/Grid_lebesgue.h
|
||||
|
||||
|
@ -10,7 +10,7 @@ namespace Grid {
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Field> class SparseMatrixBase {
|
||||
public:
|
||||
GridBase *_grid;
|
||||
virtual GridBase *Grid(void) =0;
|
||||
// Full checkerboar operations
|
||||
virtual RealD M (const Field &in, Field &out)=0;
|
||||
virtual RealD Mdag (const Field &in, Field &out)=0;
|
||||
@ -19,7 +19,6 @@ namespace Grid {
|
||||
ni=M(in,tmp);
|
||||
no=Mdag(tmp,out);
|
||||
}
|
||||
SparseMatrixBase(GridBase *grid) : _grid(grid) {};
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -27,7 +26,7 @@ namespace Grid {
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class Field> class CheckerBoardedSparseMatrixBase : public SparseMatrixBase<Field> {
|
||||
public:
|
||||
GridBase *_cbgrid;
|
||||
virtual GridBase *RedBlackGrid(void)=0;
|
||||
// half checkerboard operaions
|
||||
virtual void Meooe (const Field &in, Field &out)=0;
|
||||
virtual void Mooee (const Field &in, Field &out)=0;
|
||||
@ -62,9 +61,7 @@ namespace Grid {
|
||||
Field tmp(in._grid);
|
||||
ni=Mpc(in,tmp);
|
||||
no=MpcDag(tmp,out);
|
||||
// std::cout<<"MpcDagMpc "<<ni<<" "<<no<<std::endl;
|
||||
}
|
||||
CheckerBoardedSparseMatrixBase(GridBase *grid,GridBase *cbgrid) : SparseMatrixBase<Field>(grid), _cbgrid(cbgrid) {};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -60,8 +60,8 @@ namespace Grid {
|
||||
|
||||
// FIXME CGdiagonalMee not implemented virtual function
|
||||
// FIXME use CBfactorise to control schur decomp
|
||||
GridBase *grid = _Matrix._cbgrid;
|
||||
GridBase *fgrid= _Matrix._grid;
|
||||
GridBase *grid = _Matrix.RedBlackGrid();
|
||||
GridBase *fgrid= _Matrix.Grid();
|
||||
|
||||
Field src_e(grid);
|
||||
Field src_o(grid);
|
||||
|
@ -52,16 +52,13 @@ public:
|
||||
////////////////////////////////////////////////////////////////
|
||||
virtual int CheckerBoarded(int dim)=0;
|
||||
virtual int CheckerBoard(std::vector<int> site)=0;
|
||||
virtual int CheckerBoardDestination(int source_cb,int shift)=0;
|
||||
virtual int CheckerBoardDestination(int source_cb,int shift,int dim)=0;
|
||||
virtual int CheckerBoardShift(int source_cb,int dim,int shift,int osite)=0;
|
||||
inline int CheckerBoardFromOindex (int Oindex){
|
||||
virtual int CheckerBoardShiftForCB(int source_cb,int dim,int shift,int cb)=0;
|
||||
int CheckerBoardFromOindex (int Oindex){
|
||||
std::vector<int> ocoor;
|
||||
oCoorFromOindex(ocoor,Oindex);
|
||||
int ss=0;
|
||||
for(int d=0;d<_ndimension;d++){
|
||||
ss=ss+ocoor[d];
|
||||
}
|
||||
return ss&0x1;
|
||||
return CheckerBoard(ocoor);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -18,11 +18,14 @@ public:
|
||||
virtual int CheckerBoard(std::vector<int> site){
|
||||
return 0;
|
||||
}
|
||||
virtual int CheckerBoardDestination(int cb,int shift){
|
||||
virtual int CheckerBoardDestination(int cb,int shift,int dim){
|
||||
return 0;
|
||||
}
|
||||
virtual int CheckerBoardShiftForCB(int source_cb,int dim,int shift, int ocb){
|
||||
return shift;
|
||||
}
|
||||
virtual int CheckerBoardShift(int source_cb,int dim,int shift, int osite){
|
||||
return shift;
|
||||
return shift;
|
||||
}
|
||||
GridCartesian(std::vector<int> &dimensions,
|
||||
std::vector<int> &simd_layout,
|
||||
|
@ -8,6 +8,10 @@ namespace Grid {
|
||||
static const int CbBlack=1;
|
||||
static const int Even =CbRed;
|
||||
static const int Odd =CbBlack;
|
||||
|
||||
// Perhaps these are misplaced and
|
||||
// should be in sparse matrix.
|
||||
// Also should make these a named enum type
|
||||
static const int DaggerNo=0;
|
||||
static const int DaggerYes=1;
|
||||
|
||||
@ -15,116 +19,174 @@ namespace Grid {
|
||||
class GridRedBlackCartesian : public GridBase
|
||||
{
|
||||
public:
|
||||
std::vector<int> _checker_dim_mask;
|
||||
int _checker_dim;
|
||||
|
||||
virtual int CheckerBoarded(int dim){
|
||||
if( dim==0) return 1;
|
||||
if( dim==_checker_dim) return 1;
|
||||
else return 0;
|
||||
}
|
||||
virtual int CheckerBoard(std::vector<int> site){
|
||||
return (site[0]+site[1]+site[2]+site[3])&0x1;
|
||||
int linear=0;
|
||||
assert(site.size()==_ndimension);
|
||||
for(int d=0;d<_ndimension;d++){
|
||||
if(_checker_dim_mask[d])
|
||||
linear=linear+site[d];
|
||||
}
|
||||
return (linear&0x1);
|
||||
}
|
||||
|
||||
|
||||
// Depending on the cb of site, we toggle source cb.
|
||||
// for block #b, element #e = (b, e)
|
||||
// we need
|
||||
virtual int CheckerBoardShift(int source_cb,int dim,int shift,int osite){
|
||||
virtual int CheckerBoardShiftForCB(int source_cb,int dim,int shift,int ocb){
|
||||
if(dim != _checker_dim) return shift;
|
||||
|
||||
if(dim != 0) return shift;
|
||||
|
||||
int fulldim =_fdimensions[0];
|
||||
int fulldim =_fdimensions[dim];
|
||||
shift = (shift+fulldim)%fulldim;
|
||||
|
||||
// Probably faster with table lookup;
|
||||
// or by looping over x,y,z and multiply rather than computing checkerboard.
|
||||
int ocb=CheckerBoardFromOindex(osite);
|
||||
|
||||
if ( (source_cb+ocb)&1 ) {
|
||||
|
||||
return (shift)/2;
|
||||
} else {
|
||||
return (shift+1)/2;
|
||||
}
|
||||
}
|
||||
virtual int CheckerBoardShift(int source_cb,int dim,int shift,int osite){
|
||||
|
||||
virtual int CheckerBoardDestination(int source_cb,int shift){
|
||||
if ((shift+_fdimensions[0])&0x1) {
|
||||
if(dim != _checker_dim) return shift;
|
||||
|
||||
int ocb=CheckerBoardFromOindex(osite);
|
||||
|
||||
return CheckerBoardShiftForCB(source_cb,dim,shift,ocb);
|
||||
}
|
||||
|
||||
virtual int CheckerBoardDestination(int source_cb,int shift,int dim){
|
||||
if ( _checker_dim_mask[dim] ) {
|
||||
// If _fdimensions[checker_dim] is odd, then shifting by 1 in other dims
|
||||
// does NOT cause a parity hop.
|
||||
int add=(dim==_checker_dim) ? 0 : _fdimensions[_checker_dim];
|
||||
if ( (shift+add) &0x1) {
|
||||
return 1-source_cb;
|
||||
} else {
|
||||
return source_cb;
|
||||
}
|
||||
} else {
|
||||
return source_cb;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
GridRedBlackCartesian(GridBase *base) : GridRedBlackCartesian(base->_fdimensions,base->_simd_layout,base->_processors) {};
|
||||
|
||||
GridRedBlackCartesian(std::vector<int> &dimensions,
|
||||
std::vector<int> &simd_layout,
|
||||
std::vector<int> &processor_grid ) : GridBase(processor_grid)
|
||||
std::vector<int> &processor_grid,
|
||||
std::vector<int> &checker_dim_mask,
|
||||
int checker_dim
|
||||
) : GridBase(processor_grid)
|
||||
{
|
||||
Init(dimensions,simd_layout,processor_grid,checker_dim_mask,checker_dim);
|
||||
}
|
||||
GridRedBlackCartesian(std::vector<int> &dimensions,
|
||||
std::vector<int> &simd_layout,
|
||||
std::vector<int> &processor_grid) : GridBase(processor_grid)
|
||||
{
|
||||
std::vector<int> checker_dim_mask(dimensions.size(),1);
|
||||
Init(dimensions,simd_layout,processor_grid,checker_dim_mask,0);
|
||||
}
|
||||
void Init(std::vector<int> &dimensions,
|
||||
std::vector<int> &simd_layout,
|
||||
std::vector<int> &processor_grid,
|
||||
std::vector<int> &checker_dim_mask,
|
||||
int checker_dim)
|
||||
{
|
||||
///////////////////////
|
||||
// Grid information
|
||||
///////////////////////
|
||||
_ndimension = dimensions.size();
|
||||
|
||||
_fdimensions.resize(_ndimension);
|
||||
_gdimensions.resize(_ndimension);
|
||||
_ldimensions.resize(_ndimension);
|
||||
_rdimensions.resize(_ndimension);
|
||||
_simd_layout.resize(_ndimension);
|
||||
|
||||
_ostride.resize(_ndimension);
|
||||
_istride.resize(_ndimension);
|
||||
|
||||
_fsites = _gsites = _osites = _isites = 1;
|
||||
_checker_dim = checker_dim;
|
||||
assert(checker_dim_mask[checker_dim]==1);
|
||||
_ndimension = dimensions.size();
|
||||
assert(checker_dim_mask.size()==_ndimension);
|
||||
assert(processor_grid.size()==_ndimension);
|
||||
assert(simd_layout.size()==_ndimension);
|
||||
|
||||
_fdimensions.resize(_ndimension);
|
||||
_gdimensions.resize(_ndimension);
|
||||
_ldimensions.resize(_ndimension);
|
||||
_rdimensions.resize(_ndimension);
|
||||
_simd_layout.resize(_ndimension);
|
||||
|
||||
_ostride.resize(_ndimension);
|
||||
_istride.resize(_ndimension);
|
||||
|
||||
_fsites = _gsites = _osites = _isites = 1;
|
||||
|
||||
_checker_dim_mask=checker_dim_mask;
|
||||
|
||||
for(int d=0;d<_ndimension;d++){
|
||||
_fdimensions[d] = dimensions[d];
|
||||
_gdimensions[d] = _fdimensions[d];
|
||||
_fsites = _fsites * _fdimensions[d];
|
||||
_gsites = _gsites * _gdimensions[d];
|
||||
|
||||
if (d==0) _gdimensions[0] = _gdimensions[0]/2; // Remove a checkerboard
|
||||
_ldimensions[d] = _gdimensions[d]/_processors[d];
|
||||
|
||||
// Use a reduced simd grid
|
||||
_simd_layout[d] = simd_layout[d];
|
||||
_rdimensions[d]= _ldimensions[d]/_simd_layout[d];
|
||||
|
||||
_osites *= _rdimensions[d];
|
||||
_isites *= _simd_layout[d];
|
||||
|
||||
// Addressing support
|
||||
if ( d==0 ) {
|
||||
_ostride[d] = 1;
|
||||
_istride[d] = 1;
|
||||
} else {
|
||||
_ostride[d] = _ostride[d-1]*_rdimensions[d-1];
|
||||
_istride[d] = _istride[d-1]*_simd_layout[d-1];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// subplane information
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
_slice_block.resize(_ndimension);
|
||||
_slice_stride.resize(_ndimension);
|
||||
_slice_nblock.resize(_ndimension);
|
||||
for(int d=0;d<_ndimension;d++){
|
||||
_fdimensions[d] = dimensions[d];
|
||||
_gdimensions[d] = _fdimensions[d];
|
||||
_fsites = _fsites * _fdimensions[d];
|
||||
_gsites = _gsites * _gdimensions[d];
|
||||
|
||||
int block =1;
|
||||
int nblock=1;
|
||||
for(int d=0;d<_ndimension;d++) nblock*=_rdimensions[d];
|
||||
|
||||
for(int d=0;d<_ndimension;d++){
|
||||
nblock/=_rdimensions[d];
|
||||
_slice_block[d] =block;
|
||||
_slice_stride[d]=_ostride[d]*_rdimensions[d];
|
||||
_slice_nblock[d]=nblock;
|
||||
block = block*_rdimensions[d];
|
||||
}
|
||||
if (d==_checker_dim) {
|
||||
_gdimensions[d] = _gdimensions[d]/2; // Remove a checkerboard
|
||||
}
|
||||
_ldimensions[d] = _gdimensions[d]/_processors[d];
|
||||
|
||||
// Use a reduced simd grid
|
||||
_simd_layout[d] = simd_layout[d];
|
||||
_rdimensions[d]= _ldimensions[d]/_simd_layout[d];
|
||||
|
||||
_osites *= _rdimensions[d];
|
||||
_isites *= _simd_layout[d];
|
||||
|
||||
// Addressing support
|
||||
if ( d==0 ) {
|
||||
_ostride[d] = 1;
|
||||
_istride[d] = 1;
|
||||
} else {
|
||||
_ostride[d] = _ostride[d-1]*_rdimensions[d-1];
|
||||
_istride[d] = _istride[d-1]*_simd_layout[d-1];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// subplane information
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
_slice_block.resize(_ndimension);
|
||||
_slice_stride.resize(_ndimension);
|
||||
_slice_nblock.resize(_ndimension);
|
||||
|
||||
int block =1;
|
||||
int nblock=1;
|
||||
for(int d=0;d<_ndimension;d++) nblock*=_rdimensions[d];
|
||||
|
||||
for(int d=0;d<_ndimension;d++){
|
||||
nblock/=_rdimensions[d];
|
||||
_slice_block[d] =block;
|
||||
_slice_stride[d]=_ostride[d]*_rdimensions[d];
|
||||
_slice_nblock[d]=nblock;
|
||||
block = block*_rdimensions[d];
|
||||
}
|
||||
|
||||
};
|
||||
protected:
|
||||
virtual int oIndex(std::vector<int> &coor)
|
||||
{
|
||||
int idx=_ostride[0]*((coor[0]/2)%_rdimensions[0]);
|
||||
for(int d=1;d<_ndimension;d++) idx+=_ostride[d]*(coor[d]%_rdimensions[d]);
|
||||
int idx=0;
|
||||
for(int d=0;d<_ndimension;d++) {
|
||||
if( d==_checker_dim ) {
|
||||
idx+=_ostride[d]*((coor[d]/2)%_rdimensions[d]);
|
||||
} else {
|
||||
idx+=_ostride[d]*(coor[d]%_rdimensions[d]);
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
};
|
||||
|
||||
|
@ -175,7 +175,6 @@ PARALLEL_NESTED_LOOP2
|
||||
if ( ocb&cbmask ) {
|
||||
//lhs._odata[lo+o]=rhs._odata[ro+o];
|
||||
vstream(lhs._odata[lo+o],rhs._odata[ro+o]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -217,8 +216,8 @@ template<class vobj> void Cshift_local(Lattice<vobj>& ret,Lattice<vobj> &rhs,int
|
||||
{
|
||||
int sshift[2];
|
||||
|
||||
sshift[0] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,0);
|
||||
sshift[1] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,1);
|
||||
sshift[0] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Even);
|
||||
sshift[1] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Odd);
|
||||
|
||||
if ( sshift[0] == sshift[1] ) {
|
||||
Cshift_local(ret,rhs,dimension,shift,0x3);
|
||||
@ -239,8 +238,7 @@ template<class vobj> Lattice<vobj> Cshift_local(Lattice<vobj> &ret,Lattice<vobj>
|
||||
// Map to always positive shift modulo global full dimension.
|
||||
shift = (shift+fd)%fd;
|
||||
|
||||
ret.checkerboard = grid->CheckerBoardDestination(rhs.checkerboard,shift);
|
||||
|
||||
ret.checkerboard = grid->CheckerBoardDestination(rhs.checkerboard,shift,dimension);
|
||||
// the permute type
|
||||
int permute_dim =grid->PermuteDim(dimension);
|
||||
int permute_type=grid->PermuteType(dimension);
|
||||
@ -250,11 +248,11 @@ template<class vobj> Lattice<vobj> Cshift_local(Lattice<vobj> &ret,Lattice<vobj>
|
||||
int o = 0;
|
||||
int bo = x * grid->_ostride[dimension];
|
||||
|
||||
int cb= (cbmask==0x2)? 1 : 0;
|
||||
int cb= (cbmask==0x2)? Odd : Even;
|
||||
|
||||
int sshift = grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
|
||||
int sshift = grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
|
||||
int sx = (x+sshift)%rd;
|
||||
|
||||
|
||||
int permute_slice=0;
|
||||
if(permute_dim){
|
||||
int wrap = sshift/rd;
|
||||
|
@ -39,8 +39,8 @@ template<class vobj> void Cshift_comms(Lattice<vobj>& ret,Lattice<vobj> &rhs,int
|
||||
{
|
||||
int sshift[2];
|
||||
|
||||
sshift[0] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,0);
|
||||
sshift[1] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,1);
|
||||
sshift[0] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Even);
|
||||
sshift[1] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Odd);
|
||||
|
||||
if ( sshift[0] == sshift[1] ) {
|
||||
Cshift_comms(ret,rhs,dimension,shift,0x3);
|
||||
@ -54,8 +54,8 @@ template<class vobj> void Cshift_comms_simd(Lattice<vobj>& ret,Lattice<vobj> &rh
|
||||
{
|
||||
int sshift[2];
|
||||
|
||||
sshift[0] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,0);
|
||||
sshift[1] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,1);
|
||||
sshift[0] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Even);
|
||||
sshift[1] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Odd);
|
||||
|
||||
if ( sshift[0] == sshift[1] ) {
|
||||
Cshift_comms_simd(ret,rhs,dimension,shift,0x3);
|
||||
@ -87,8 +87,8 @@ template<class vobj> void Cshift_comms(Lattice<vobj> &ret,Lattice<vobj> &rhs,int
|
||||
std::vector<vobj,alignedAllocator<vobj> > send_buf(buffer_size);
|
||||
std::vector<vobj,alignedAllocator<vobj> > recv_buf(buffer_size);
|
||||
|
||||
int cb= (cbmask==0x2)? 1 : 0;
|
||||
int sshift= rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
|
||||
int cb= (cbmask==0x2)? Odd : Even;
|
||||
int sshift= rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
|
||||
|
||||
for(int x=0;x<rd;x++){
|
||||
|
||||
@ -162,8 +162,8 @@ template<class vobj> void Cshift_comms_simd(Lattice<vobj> &ret,Lattice<vobj> &r
|
||||
///////////////////////////////////////////
|
||||
// Work out what to send where
|
||||
///////////////////////////////////////////
|
||||
int cb = (cbmask==0x2)? 1 : 0;
|
||||
int sshift= grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
|
||||
int cb = (cbmask==0x2)? Odd : Even;
|
||||
int sshift= grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
|
||||
|
||||
// loop over outer coord planes orthog to dim
|
||||
for(int x=0;x<rd;x++){
|
||||
|
@ -4,7 +4,7 @@ namespace Grid {
|
||||
template<class vobj> Lattice<vobj> Cshift(Lattice<vobj> &rhs,int dimension,int shift)
|
||||
{
|
||||
Lattice<vobj> ret(rhs._grid);
|
||||
ret.checkerboard = rhs._grid->CheckerBoardDestination(rhs.checkerboard,shift);
|
||||
ret.checkerboard = rhs._grid->CheckerBoardDestination(rhs.checkerboard,shift,dimension);
|
||||
Cshift_local(ret,rhs,dimension,shift);
|
||||
return ret;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ PARALLEL_FOR_LOOP
|
||||
|
||||
int Nsimd = grid->Nsimd();
|
||||
|
||||
assert( l.checkerboard== l._grid->CheckerBoard(site));
|
||||
assert( l.checkerboard == l._grid->CheckerBoard(site));
|
||||
assert( sizeof(sobj)*Nsimd == sizeof(vobj));
|
||||
|
||||
int rank,odx,idx;
|
||||
|
@ -32,7 +32,6 @@ PARALLEL_FOR_LOOP
|
||||
cbos=half._grid->CheckerBoard(coor);
|
||||
|
||||
if (cbos==cb) {
|
||||
|
||||
half._odata[ssh] = full._odata[ss];
|
||||
ssh++;
|
||||
}
|
||||
@ -45,7 +44,7 @@ PARALLEL_FOR_LOOP
|
||||
for(int ss=0;ss<full._grid->oSites();ss++){
|
||||
std::vector<int> coor;
|
||||
int cbos;
|
||||
|
||||
|
||||
full._grid->oCoorFromOindex(coor,ss);
|
||||
cbos=half._grid->CheckerBoard(coor);
|
||||
|
||||
|
@ -1,217 +0,0 @@
|
||||
#include <Grid.h>
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
const std::vector<int> WilsonMatrix::directions ({0,1,2,3, 0, 1, 2, 3});
|
||||
const std::vector<int> WilsonMatrix::displacements({1,1,1,1,-1,-1,-1,-1});
|
||||
|
||||
int WilsonMatrix::HandOptDslash;
|
||||
|
||||
class WilsonCompressor {
|
||||
public:
|
||||
int mu;
|
||||
int dag;
|
||||
|
||||
WilsonCompressor(int _dag){
|
||||
mu=0;
|
||||
dag=_dag;
|
||||
assert((dag==0)||(dag==1));
|
||||
}
|
||||
void Point(int p) {
|
||||
mu=p;
|
||||
};
|
||||
|
||||
vHalfSpinColourVector operator () (const vSpinColourVector &in)
|
||||
{
|
||||
vHalfSpinColourVector ret;
|
||||
int mudag=mu;
|
||||
if (dag) {
|
||||
mudag=(mu+Nd)%(2*Nd);
|
||||
}
|
||||
switch(mudag) {
|
||||
case Xp:
|
||||
spProjXp(ret,in);
|
||||
break;
|
||||
case Yp:
|
||||
spProjYp(ret,in);
|
||||
break;
|
||||
case Zp:
|
||||
spProjZp(ret,in);
|
||||
break;
|
||||
case Tp:
|
||||
spProjTp(ret,in);
|
||||
break;
|
||||
case Xm:
|
||||
spProjXm(ret,in);
|
||||
break;
|
||||
case Ym:
|
||||
spProjYm(ret,in);
|
||||
break;
|
||||
case Zm:
|
||||
spProjZm(ret,in);
|
||||
break;
|
||||
case Tm:
|
||||
spProjTm(ret,in);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
WilsonMatrix::WilsonMatrix(LatticeGaugeField &_Umu,GridCartesian &Fgrid,GridRedBlackCartesian &Hgrid, double _mass) :
|
||||
CheckerBoardedSparseMatrixBase<LatticeFermion>(&Fgrid,&Hgrid),
|
||||
Stencil ( _grid,npoint,Even,directions,displacements),
|
||||
StencilEven(_cbgrid,npoint,Even,directions,displacements), // source is Even
|
||||
StencilOdd (_cbgrid,npoint,Odd ,directions,displacements), // source is Odd
|
||||
mass(_mass),
|
||||
Umu(_grid),
|
||||
UmuEven(_cbgrid),
|
||||
UmuOdd (_cbgrid)
|
||||
{
|
||||
// Allocate the required comms buffer
|
||||
comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
|
||||
|
||||
DoubleStore(Umu,_Umu);
|
||||
pickCheckerboard(Even,UmuEven,Umu);
|
||||
pickCheckerboard(Odd ,UmuOdd,Umu);
|
||||
}
|
||||
|
||||
void WilsonMatrix::DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu)
|
||||
{
|
||||
LatticeColourMatrix U(_grid);
|
||||
|
||||
for(int mu=0;mu<Nd;mu++){
|
||||
U = peekIndex<LorentzIndex>(Umu,mu);
|
||||
pokeIndex<LorentzIndex>(Uds,U,mu);
|
||||
U = adj(Cshift(U,mu,-1));
|
||||
pokeIndex<LorentzIndex>(Uds,U,mu+4);
|
||||
}
|
||||
}
|
||||
|
||||
RealD WilsonMatrix::M(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard=in.checkerboard;
|
||||
Dhop(in,out,DaggerNo);
|
||||
out = (4+mass)*in - 0.5*out ; // FIXME : axpby_norm! fusion fun
|
||||
return norm2(out);
|
||||
}
|
||||
RealD WilsonMatrix::Mdag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard=in.checkerboard;
|
||||
Dhop(in,out,DaggerYes);
|
||||
out = (4+mass)*in - 0.5*out ; // FIXME : axpby_norm! fusion fun
|
||||
return norm2(out);
|
||||
}
|
||||
|
||||
void WilsonMatrix::Meooe(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
if ( in.checkerboard == Odd ) {
|
||||
DhopEO(in,out,DaggerNo);
|
||||
} else {
|
||||
DhopOE(in,out,DaggerNo);
|
||||
}
|
||||
out = (-0.5)*out; // FIXME : scale factor in Dhop
|
||||
}
|
||||
void WilsonMatrix::MeooeDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
if ( in.checkerboard == Odd ) {
|
||||
DhopEO(in,out,DaggerYes);
|
||||
} else {
|
||||
DhopOE(in,out,DaggerYes);
|
||||
}
|
||||
out = (-0.5)*out; // FIXME : scale factor in Dhop
|
||||
}
|
||||
void WilsonMatrix::Mooee(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
out = (4.0+mass)*in;
|
||||
return ;
|
||||
}
|
||||
void WilsonMatrix::MooeeDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
Mooee(in,out);
|
||||
}
|
||||
void WilsonMatrix::MooeeInv(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
out = (1.0/(4.0+mass))*in;
|
||||
return ;
|
||||
}
|
||||
void WilsonMatrix::MooeeInvDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
MooeeInv(in,out);
|
||||
}
|
||||
|
||||
void WilsonMatrix::DhopInternal(CartesianStencil & st,LatticeDoubledGaugeField & U,
|
||||
const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
assert((dag==DaggerNo) ||(dag==DaggerYes));
|
||||
WilsonCompressor compressor(dag);
|
||||
st.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
|
||||
|
||||
if ( dag == DaggerYes ) {
|
||||
if( HandOptDslash ) {
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int sss=0;sss<in._grid->oSites();sss++){
|
||||
DiracOptHand::DhopSiteDag(st,U,comm_buf,sss,in,out);
|
||||
}
|
||||
} else {
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int sss=0;sss<in._grid->oSites();sss++){
|
||||
DiracOpt::DhopSiteDag(st,U,comm_buf,sss,in,out);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if( HandOptDslash ) {
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int sss=0;sss<in._grid->oSites();sss++){
|
||||
DiracOptHand::DhopSite(st,U,comm_buf,sss,in,out);
|
||||
}
|
||||
} else {
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int sss=0;sss<in._grid->oSites();sss++){
|
||||
DiracOpt::DhopSite(st,U,comm_buf,sss,in,out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void WilsonMatrix::DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
conformable(in._grid,_cbgrid); // verifies half grid
|
||||
conformable(in._grid,out._grid); // drops the cb check
|
||||
|
||||
assert(in.checkerboard==Even);
|
||||
out.checkerboard = Odd;
|
||||
|
||||
DhopInternal(StencilEven,UmuOdd,in,out,dag);
|
||||
}
|
||||
void WilsonMatrix::DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
conformable(in._grid,_cbgrid); // verifies half grid
|
||||
conformable(in._grid,out._grid); // drops the cb check
|
||||
|
||||
assert(in.checkerboard==Odd);
|
||||
out.checkerboard = Even;
|
||||
|
||||
DhopInternal(StencilOdd,UmuEven,in,out,dag);
|
||||
}
|
||||
void WilsonMatrix::Dhop(const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
conformable(in._grid,_grid); // verifies full grid
|
||||
conformable(in._grid,out._grid);
|
||||
|
||||
out.checkerboard = in.checkerboard;
|
||||
|
||||
DhopInternal(Stencil,Umu,in,out,dag);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
|
@ -1,105 +0,0 @@
|
||||
#ifndef GRID_QCD_WILSON_DOP_H
|
||||
#define GRID_QCD_WILSON_DOP_H
|
||||
|
||||
|
||||
namespace Grid {
|
||||
|
||||
namespace QCD {
|
||||
|
||||
// Should be in header?
|
||||
const int Xp = 0;
|
||||
const int Yp = 1;
|
||||
const int Zp = 2;
|
||||
const int Tp = 3;
|
||||
const int Xm = 4;
|
||||
const int Ym = 5;
|
||||
const int Zm = 6;
|
||||
const int Tm = 7;
|
||||
|
||||
class WilsonMatrix : public CheckerBoardedSparseMatrixBase<LatticeFermion>
|
||||
{
|
||||
//NB r=1;
|
||||
public:
|
||||
static int HandOptDslash;
|
||||
|
||||
double mass;
|
||||
// GridBase * grid; // Inherited
|
||||
// GridBase * cbgrid;
|
||||
|
||||
//Defines the stencils for even and odd
|
||||
CartesianStencil Stencil;
|
||||
CartesianStencil StencilEven;
|
||||
CartesianStencil StencilOdd;
|
||||
|
||||
// Copy of the gauge field , with even and odd subsets
|
||||
LatticeDoubledGaugeField Umu;
|
||||
LatticeDoubledGaugeField UmuEven;
|
||||
LatticeDoubledGaugeField UmuOdd;
|
||||
|
||||
static const int npoint=8;
|
||||
static const std::vector<int> directions ;
|
||||
static const std::vector<int> displacements;
|
||||
static const int Xp,Xm,Yp,Ym,Zp,Zm,Tp,Tm;
|
||||
|
||||
// Comms buffer
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > comm_buf;
|
||||
|
||||
// Constructor
|
||||
WilsonMatrix(LatticeGaugeField &_Umu,GridCartesian &Fgrid,GridRedBlackCartesian &Hgrid,double _mass);
|
||||
|
||||
// DoubleStore
|
||||
void DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu);
|
||||
|
||||
// override multiply
|
||||
virtual RealD M (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual RealD Mdag (const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
// half checkerboard operaions
|
||||
virtual void Meooe (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void MeooeDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void Mooee (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void MooeeDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void MooeeInv (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
// non-hermitian hopping term; half cb or both
|
||||
void Dhop (const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
void DhopInternal(CartesianStencil & st,LatticeDoubledGaugeField &U,
|
||||
const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
|
||||
typedef iScalar<iMatrix<vComplex, Nc> > matrix;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DiracOpt {
|
||||
public:
|
||||
// These ones will need to be package intelligently. WilsonType base class
|
||||
// for use by DWF etc..
|
||||
static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int ss,const LatticeFermion &in, LatticeFermion &out);
|
||||
static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int ss,const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
};
|
||||
class DiracOptHand {
|
||||
public:
|
||||
// These ones will need to be package intelligently. WilsonType base class
|
||||
// for use by DWF etc..
|
||||
static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int ss,const LatticeFermion &in, LatticeFermion &out);
|
||||
static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int ss,const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -4,6 +4,16 @@ namespace Grid{
|
||||
|
||||
namespace QCD {
|
||||
|
||||
|
||||
static const int Xp = 0;
|
||||
static const int Yp = 1;
|
||||
static const int Zp = 2;
|
||||
static const int Tp = 3;
|
||||
static const int Xm = 4;
|
||||
static const int Ym = 5;
|
||||
static const int Zm = 6;
|
||||
static const int Tm = 7;
|
||||
|
||||
static const int Nc=3;
|
||||
static const int Ns=4;
|
||||
static const int Nd=4;
|
||||
@ -297,9 +307,8 @@ namespace QCD {
|
||||
} //namespace QCD
|
||||
} // Grid
|
||||
|
||||
#include <qcd/Grid_qcd_dirac.h>
|
||||
#include <qcd/Grid_qcd_2spinor.h>
|
||||
//#include <qcd/Grid_qcd_pauli.h>
|
||||
#include <qcd/Grid_qcd_wilson_dop.h>
|
||||
#include <qcd/Dirac.h>
|
||||
#include <qcd/TwoSpinor.h>
|
||||
#include <qcd/action/Actions.h>
|
||||
|
||||
#endif
|
10
lib/qcd/action/Actions.h
Normal file
10
lib/qcd/action/Actions.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef GRID_QCD_ACTIONS_H
|
||||
#define GRID_QCD_ACTIONS_H
|
||||
|
||||
#include <qcd/action/fermion/FermionAction.h>
|
||||
#include <qcd/action/fermion/WilsonCompressor.h>
|
||||
#include <qcd/action/fermion/WilsonKernels.h>
|
||||
#include <qcd/action/fermion/WilsonFermion.h>
|
||||
#include <qcd/action/fermion/FiveDimWilsonFermion.h>
|
||||
|
||||
#endif
|
47
lib/qcd/action/fermion/FermionAction.h
Normal file
47
lib/qcd/action/fermion/FermionAction.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef GRID_QCD_WILSON_DOP_H
|
||||
#define GRID_QCD_WILSON_DOP_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
namespace QCD {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Four component fermions
|
||||
// Should type template the vector and gauge types
|
||||
// Think about multiple representations
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
template<class FermionField,class GaugeField>
|
||||
class FermionAction : public CheckerBoardedSparseMatrixBase<FermionField>
|
||||
{
|
||||
public:
|
||||
|
||||
GridBase * Grid(void) { return FermionGrid(); }; // this is all the linalg routines need to know
|
||||
GridBase * RedBlackGrid(void) { return FermionRedBlackGrid(); };
|
||||
|
||||
virtual GridBase *FermionGrid(void) =0;
|
||||
virtual GridBase *FermionRedBlackGrid(void) =0;
|
||||
virtual GridBase *GaugeGrid(void) =0;
|
||||
virtual GridBase *GaugeRedBlackGrid(void) =0;
|
||||
|
||||
// override multiply
|
||||
virtual RealD M (const FermionField &in, FermionField &out)=0;
|
||||
virtual RealD Mdag (const FermionField &in, FermionField &out)=0;
|
||||
|
||||
// half checkerboard operaions
|
||||
virtual void Meooe (const FermionField &in, FermionField &out)=0;
|
||||
virtual void MeooeDag (const FermionField &in, FermionField &out)=0;
|
||||
virtual void Mooee (const FermionField &in, FermionField &out)=0;
|
||||
virtual void MooeeDag (const FermionField &in, FermionField &out)=0;
|
||||
virtual void MooeeInv (const FermionField &in, FermionField &out)=0;
|
||||
virtual void MooeeInvDag (const FermionField &in, FermionField &out)=0;
|
||||
|
||||
// non-hermitian hopping term; half cb or both
|
||||
virtual void Dhop (const FermionField &in, FermionField &out,int dag)=0;
|
||||
virtual void DhopOE(const FermionField &in, FermionField &out,int dag)=0;
|
||||
virtual void DhopEO(const FermionField &in, FermionField &out,int dag)=0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
228
lib/qcd/action/fermion/FiveDimWilsonFermion.cc
Normal file
228
lib/qcd/action/fermion/FiveDimWilsonFermion.cc
Normal file
@ -0,0 +1,228 @@
|
||||
#include <Grid.h>
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
// S-direction is INNERMOST and takes no part in the parity.
|
||||
const std::vector<int> FiveDimWilsonFermion::directions ({1,2,3,4, 1, 2, 3, 4});
|
||||
const std::vector<int> FiveDimWilsonFermion::displacements({1,1,1,1,-1,-1,-1,-1});
|
||||
|
||||
int FiveDimWilsonFermion::HandOptDslash;
|
||||
|
||||
// 5d lattice for DWF.
|
||||
FiveDimWilsonFermion::FiveDimWilsonFermion(LatticeGaugeField &_Umu,
|
||||
GridCartesian &FiveDimGrid,
|
||||
GridRedBlackCartesian &FiveDimRedBlackGrid,
|
||||
GridCartesian &FourDimGrid,
|
||||
GridRedBlackCartesian &FourDimRedBlackGrid,
|
||||
double _mass) :
|
||||
_FiveDimGrid(&FiveDimGrid),
|
||||
_FiveDimRedBlackGrid(&FiveDimRedBlackGrid),
|
||||
_FourDimGrid(&FourDimGrid),
|
||||
_FourDimRedBlackGrid(&FourDimRedBlackGrid),
|
||||
Stencil (_FiveDimGrid,npoint,Even,directions,displacements),
|
||||
StencilEven(_FiveDimRedBlackGrid,npoint,Even,directions,displacements), // source is Even
|
||||
StencilOdd (_FiveDimRedBlackGrid,npoint,Odd ,directions,displacements), // source is Odd
|
||||
mass(_mass),
|
||||
Umu(_FourDimGrid),
|
||||
UmuEven(_FourDimRedBlackGrid),
|
||||
UmuOdd (_FourDimRedBlackGrid),
|
||||
Lebesgue(_FourDimGrid),
|
||||
LebesgueEvenOdd(_FourDimRedBlackGrid)
|
||||
{
|
||||
// some assertions
|
||||
assert(FiveDimGrid._ndimension==5);
|
||||
assert(FourDimGrid._ndimension==4);
|
||||
|
||||
assert(FiveDimRedBlackGrid._ndimension==5);
|
||||
assert(FourDimRedBlackGrid._ndimension==4);
|
||||
|
||||
assert(FiveDimRedBlackGrid._checker_dim==1);
|
||||
|
||||
// Dimension zero of the five-d is the Ls direction
|
||||
Ls=FiveDimGrid._fdimensions[0];
|
||||
assert(FiveDimRedBlackGrid._fdimensions[0]==Ls);
|
||||
assert(FiveDimRedBlackGrid._processors[0] ==1);
|
||||
assert(FiveDimRedBlackGrid._simd_layout[0]==1);
|
||||
assert(FiveDimGrid._processors[0] ==1);
|
||||
assert(FiveDimGrid._simd_layout[0] ==1);
|
||||
|
||||
// Other dimensions must match the decomposition of the four-D fields
|
||||
for(int d=0;d<4;d++){
|
||||
assert(FourDimRedBlackGrid._fdimensions[d] ==FourDimGrid._fdimensions[d]);
|
||||
assert(FiveDimRedBlackGrid._fdimensions[d+1]==FourDimGrid._fdimensions[d]);
|
||||
|
||||
assert(FourDimRedBlackGrid._processors[d] ==FourDimGrid._processors[d]);
|
||||
assert(FiveDimRedBlackGrid._processors[d+1] ==FourDimGrid._processors[d]);
|
||||
|
||||
assert(FourDimRedBlackGrid._simd_layout[d] ==FourDimGrid._simd_layout[d]);
|
||||
assert(FiveDimRedBlackGrid._simd_layout[d+1]==FourDimGrid._simd_layout[d]);
|
||||
|
||||
assert(FiveDimGrid._fdimensions[d+1] ==FourDimGrid._fdimensions[d]);
|
||||
assert(FiveDimGrid._processors[d+1] ==FourDimGrid._processors[d]);
|
||||
assert(FiveDimGrid._simd_layout[d+1] ==FourDimGrid._simd_layout[d]);
|
||||
}
|
||||
|
||||
// Allocate the required comms buffer
|
||||
comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
|
||||
|
||||
DoubleStore(Umu,_Umu);
|
||||
pickCheckerboard(Even,UmuEven,Umu);
|
||||
pickCheckerboard(Odd ,UmuOdd,Umu);
|
||||
}
|
||||
void FiveDimWilsonFermion::DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu)
|
||||
{
|
||||
conformable(Uds._grid,GaugeGrid());
|
||||
conformable(Umu._grid,GaugeGrid());
|
||||
LatticeColourMatrix U(GaugeGrid());
|
||||
for(int mu=0;mu<Nd;mu++){
|
||||
U = peekIndex<LorentzIndex>(Umu,mu);
|
||||
pokeIndex<LorentzIndex>(Uds,U,mu);
|
||||
U = adj(Cshift(U,mu,-1));
|
||||
pokeIndex<LorentzIndex>(Uds,U,mu+4);
|
||||
}
|
||||
}
|
||||
|
||||
RealD FiveDimWilsonFermion::M(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard=in.checkerboard;
|
||||
Dhop(in,out,DaggerNo);
|
||||
return axpy_norm(out,5.0-M5,in,out);
|
||||
}
|
||||
RealD FiveDimWilsonFermion::Mdag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard=in.checkerboard;
|
||||
Dhop(in,out,DaggerYes);
|
||||
return axpy_norm(out,5.0-M5,in,out);
|
||||
}
|
||||
void FiveDimWilsonFermion::Meooe(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
if ( in.checkerboard == Odd ) {
|
||||
DhopEO(in,out,DaggerNo);
|
||||
} else {
|
||||
DhopOE(in,out,DaggerNo);
|
||||
}
|
||||
}
|
||||
void FiveDimWilsonFermion::MeooeDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
if ( in.checkerboard == Odd ) {
|
||||
DhopEO(in,out,DaggerYes);
|
||||
} else {
|
||||
DhopOE(in,out,DaggerYes);
|
||||
}
|
||||
}
|
||||
void FiveDimWilsonFermion::Mooee(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
out = (5.0-M5)*in;
|
||||
return ;
|
||||
}
|
||||
void FiveDimWilsonFermion::MooeeDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
Mooee(in,out);
|
||||
}
|
||||
void FiveDimWilsonFermion::MooeeInv(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
out = (1.0/(5.0-M5))*in;
|
||||
return ;
|
||||
}
|
||||
void FiveDimWilsonFermion::MooeeInvDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
MooeeInv(in,out);
|
||||
}
|
||||
void FiveDimWilsonFermion::DhopInternal(CartesianStencil & st, LebesgueOrder &lo,
|
||||
LatticeDoubledGaugeField & U,
|
||||
const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
assert((dag==DaggerNo) ||(dag==DaggerYes));
|
||||
|
||||
WilsonCompressor compressor(dag);
|
||||
|
||||
st.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
|
||||
|
||||
// Dhop takes the 4d grid from U, and makes a 5d index for fermion
|
||||
// Not loop ordering and data layout.
|
||||
// Designed to create
|
||||
// - per thread reuse in L1 cache for U
|
||||
// - 8 linear access unit stride streams per thread for Fermion for hw prefetchable.
|
||||
if ( dag == DaggerYes ) {
|
||||
if( HandOptDslash ) {
|
||||
for(int ss=0;ss<U._grid->oSites();ss++){
|
||||
int sU=lo.Reorder(ss);
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int s=0;s<Ls;s++){
|
||||
int sF = s+Ls*sU;
|
||||
DiracOptHand::DhopSiteDag(st,U,comm_buf,sF,sU,in,out);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int ss=0;ss<U._grid->oSites();ss++){
|
||||
int sU=lo.Reorder(ss);
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int s=0;s<Ls;s++){
|
||||
int sF = s+Ls*sU;
|
||||
DiracOpt::DhopSiteDag(st,U,comm_buf,sF,sU,in,out);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if( HandOptDslash ) {
|
||||
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int ss=0;ss<U._grid->oSites();ss++){
|
||||
int sU=lo.Reorder(ss);
|
||||
for(int s=0;s<Ls;s++){
|
||||
int sF = s+Ls*sU;
|
||||
DiracOptHand::DhopSite(st,U,comm_buf,sF,sU,in,out);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for(int ss=0;ss<U._grid->oSites();ss++){
|
||||
int sU=lo.Reorder(ss);
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int s=0;s<Ls;s++){
|
||||
int sF = s+Ls*sU;
|
||||
DiracOpt::DhopSite(st,U,comm_buf,sF,sU,in,out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void FiveDimWilsonFermion::DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
conformable(in._grid,FermionRedBlackGrid()); // verifies half grid
|
||||
conformable(in._grid,out._grid); // drops the cb check
|
||||
|
||||
assert(in.checkerboard==Even);
|
||||
out.checkerboard = Odd;
|
||||
|
||||
DhopInternal(StencilEven,LebesgueEvenOdd,UmuOdd,in,out,dag);
|
||||
}
|
||||
void FiveDimWilsonFermion::DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
conformable(in._grid,FermionRedBlackGrid()); // verifies half grid
|
||||
conformable(in._grid,out._grid); // drops the cb check
|
||||
|
||||
assert(in.checkerboard==Odd);
|
||||
out.checkerboard = Even;
|
||||
|
||||
DhopInternal(StencilOdd,LebesgueEvenOdd,UmuEven,in,out,dag);
|
||||
}
|
||||
void FiveDimWilsonFermion::Dhop(const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
conformable(in._grid,FermionGrid()); // verifies full grid
|
||||
conformable(in._grid,out._grid);
|
||||
|
||||
out.checkerboard = in.checkerboard;
|
||||
|
||||
DhopInternal(Stencil,Lebesgue,Umu,in,out,dag);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
|
108
lib/qcd/action/fermion/FiveDimWilsonFermion.h
Normal file
108
lib/qcd/action/fermion/FiveDimWilsonFermion.h
Normal file
@ -0,0 +1,108 @@
|
||||
#ifndef GRID_QCD_DWF_H
|
||||
#define GRID_QCD_DWF_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
namespace QCD {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// This is the 4d red black case appropriate to support
|
||||
//
|
||||
// parity = (x+y+z+t)|2;
|
||||
// generalised five dim fermions like mobius, zolotarev etc..
|
||||
//
|
||||
// i.e. even even contains fifth dim hopping term.
|
||||
//
|
||||
// [DIFFERS from original CPS red black implementation parity = (x+y+z+t+s)|2 ]
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class FiveDimWilsonFermion : public FermionAction<LatticeFermion,LatticeGaugeField>
|
||||
{
|
||||
public:
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Implement the abstract base
|
||||
///////////////////////////////////////////////////////////////
|
||||
GridBase *GaugeGrid(void) { return _FourDimGrid ;}
|
||||
GridBase *GaugeRedBlackGrid(void) { return _FourDimRedBlackGrid ;}
|
||||
GridBase *FermionGrid(void) { return _FiveDimGrid;}
|
||||
GridBase *FermionRedBlackGrid(void) { return _FiveDimRedBlackGrid;}
|
||||
|
||||
// override multiply
|
||||
virtual RealD M (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual RealD Mdag (const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
// half checkerboard operaions
|
||||
virtual void Meooe (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void MeooeDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void Mooee (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void MooeeDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void MooeeInv (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
// non-hermitian hopping term; half cb or both
|
||||
void Dhop (const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// New methods added
|
||||
///////////////////////////////////////////////////////////////
|
||||
void DhopInternal(CartesianStencil & st,
|
||||
LebesgueOrder &lo,
|
||||
LatticeDoubledGaugeField &U,
|
||||
const LatticeFermion &in,
|
||||
LatticeFermion &out,
|
||||
int dag);
|
||||
|
||||
// Constructors
|
||||
FiveDimWilsonFermion(LatticeGaugeField &_Umu,
|
||||
GridCartesian &FiveDimGrid,
|
||||
GridRedBlackCartesian &FiveDimRedBlackGrid,
|
||||
GridCartesian &FourDimGrid,
|
||||
GridRedBlackCartesian &FourDimRedBlackGrid,
|
||||
double _mass);
|
||||
|
||||
// DoubleStore
|
||||
void DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Data members require to support the functionality
|
||||
///////////////////////////////////////////////////////////////
|
||||
static int HandOptDslash; // these are a temporary hack
|
||||
|
||||
protected:
|
||||
|
||||
// Add these to the support from Wilson
|
||||
GridBase *_FourDimGrid;
|
||||
GridBase *_FourDimRedBlackGrid;
|
||||
GridBase *_FiveDimGrid;
|
||||
GridBase *_FiveDimRedBlackGrid;
|
||||
|
||||
static const int npoint=8;
|
||||
static const std::vector<int> directions ;
|
||||
static const std::vector<int> displacements;
|
||||
|
||||
double M5;
|
||||
double mass;
|
||||
int Ls;
|
||||
|
||||
//Defines the stencils for even and odd
|
||||
CartesianStencil Stencil;
|
||||
CartesianStencil StencilEven;
|
||||
CartesianStencil StencilOdd;
|
||||
|
||||
// Copy of the gauge field , with even and odd subsets
|
||||
LatticeDoubledGaugeField Umu;
|
||||
LatticeDoubledGaugeField UmuEven;
|
||||
LatticeDoubledGaugeField UmuOdd;
|
||||
|
||||
LebesgueOrder Lebesgue;
|
||||
LebesgueOrder LebesgueEvenOdd;
|
||||
|
||||
// Comms buffer
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > comm_buf;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
61
lib/qcd/action/fermion/WilsonCompressor.h
Normal file
61
lib/qcd/action/fermion/WilsonCompressor.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef GRID_QCD_WILSON_COMPRESSOR_H
|
||||
#define GRID_QCD_WILSON_COMPRESSOR_H
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
class WilsonCompressor {
|
||||
public:
|
||||
int mu;
|
||||
int dag;
|
||||
|
||||
WilsonCompressor(int _dag){
|
||||
mu=0;
|
||||
dag=_dag;
|
||||
assert((dag==0)||(dag==1));
|
||||
}
|
||||
void Point(int p) {
|
||||
mu=p;
|
||||
};
|
||||
|
||||
vHalfSpinColourVector operator () (const vSpinColourVector &in)
|
||||
{
|
||||
vHalfSpinColourVector ret;
|
||||
int mudag=mu;
|
||||
if (dag) {
|
||||
mudag=(mu+Nd)%(2*Nd);
|
||||
}
|
||||
switch(mudag) {
|
||||
case Xp:
|
||||
spProjXp(ret,in);
|
||||
break;
|
||||
case Yp:
|
||||
spProjYp(ret,in);
|
||||
break;
|
||||
case Zp:
|
||||
spProjZp(ret,in);
|
||||
break;
|
||||
case Tp:
|
||||
spProjTp(ret,in);
|
||||
break;
|
||||
case Xm:
|
||||
spProjXm(ret,in);
|
||||
break;
|
||||
case Ym:
|
||||
spProjYm(ret,in);
|
||||
break;
|
||||
case Zm:
|
||||
spProjZm(ret,in);
|
||||
break;
|
||||
case Tm:
|
||||
spProjTm(ret,in);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
}} // namespace close
|
||||
#endif
|
163
lib/qcd/action/fermion/WilsonFermion.cc
Normal file
163
lib/qcd/action/fermion/WilsonFermion.cc
Normal file
@ -0,0 +1,163 @@
|
||||
#include <Grid.h>
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
const std::vector<int> WilsonFermion::directions ({0,1,2,3, 0, 1, 2, 3});
|
||||
const std::vector<int> WilsonFermion::displacements({1,1,1,1,-1,-1,-1,-1});
|
||||
|
||||
int WilsonFermion::HandOptDslash;
|
||||
|
||||
WilsonFermion::WilsonFermion(LatticeGaugeField &_Umu,
|
||||
GridCartesian &Fgrid,
|
||||
GridRedBlackCartesian &Hgrid,
|
||||
double _mass) :
|
||||
_grid(&Fgrid),
|
||||
_cbgrid(&Hgrid),
|
||||
Stencil (&Fgrid,npoint,Even,directions,displacements),
|
||||
StencilEven(&Hgrid,npoint,Even,directions,displacements), // source is Even
|
||||
StencilOdd (&Hgrid,npoint,Odd ,directions,displacements), // source is Odd
|
||||
mass(_mass),
|
||||
Umu(&Fgrid),
|
||||
UmuEven(&Hgrid),
|
||||
UmuOdd (&Hgrid)
|
||||
{
|
||||
// Allocate the required comms buffer
|
||||
comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
|
||||
DoubleStore(Umu,_Umu);
|
||||
pickCheckerboard(Even,UmuEven,Umu);
|
||||
pickCheckerboard(Odd ,UmuOdd,Umu);
|
||||
}
|
||||
|
||||
void WilsonFermion::DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu)
|
||||
{
|
||||
conformable(Uds._grid,GaugeGrid());
|
||||
conformable(Umu._grid,GaugeGrid());
|
||||
LatticeColourMatrix U(GaugeGrid());
|
||||
for(int mu=0;mu<Nd;mu++){
|
||||
U = peekIndex<LorentzIndex>(Umu,mu);
|
||||
pokeIndex<LorentzIndex>(Uds,U,mu);
|
||||
U = adj(Cshift(U,mu,-1));
|
||||
pokeIndex<LorentzIndex>(Uds,U,mu+4);
|
||||
}
|
||||
}
|
||||
|
||||
RealD WilsonFermion::M(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard=in.checkerboard;
|
||||
Dhop(in,out,DaggerNo);
|
||||
return axpy_norm(out,4+mass,in,out);
|
||||
}
|
||||
RealD WilsonFermion::Mdag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard=in.checkerboard;
|
||||
Dhop(in,out,DaggerYes);
|
||||
return axpy_norm(out,4+mass,in,out);
|
||||
}
|
||||
|
||||
void WilsonFermion::Meooe(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
if ( in.checkerboard == Odd ) {
|
||||
DhopEO(in,out,DaggerNo);
|
||||
} else {
|
||||
DhopOE(in,out,DaggerNo);
|
||||
}
|
||||
}
|
||||
void WilsonFermion::MeooeDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
if ( in.checkerboard == Odd ) {
|
||||
DhopEO(in,out,DaggerYes);
|
||||
} else {
|
||||
DhopOE(in,out,DaggerYes);
|
||||
}
|
||||
}
|
||||
void WilsonFermion::Mooee(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
out = (4.0+mass)*in;
|
||||
return ;
|
||||
}
|
||||
void WilsonFermion::MooeeDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
Mooee(in,out);
|
||||
}
|
||||
void WilsonFermion::MooeeInv(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
out = (1.0/(4.0+mass))*in;
|
||||
return ;
|
||||
}
|
||||
void WilsonFermion::MooeeInvDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
out.checkerboard = in.checkerboard;
|
||||
MooeeInv(in,out);
|
||||
}
|
||||
|
||||
void WilsonFermion::DhopInternal(CartesianStencil & st,LatticeDoubledGaugeField & U,
|
||||
const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
assert((dag==DaggerNo) ||(dag==DaggerYes));
|
||||
WilsonCompressor compressor(dag);
|
||||
st.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
|
||||
|
||||
if ( dag == DaggerYes ) {
|
||||
if( HandOptDslash ) {
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int sss=0;sss<in._grid->oSites();sss++){
|
||||
DiracOptHand::DhopSiteDag(st,U,comm_buf,sss,sss,in,out);
|
||||
}
|
||||
} else {
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int sss=0;sss<in._grid->oSites();sss++){
|
||||
DiracOpt::DhopSiteDag(st,U,comm_buf,sss,sss,in,out);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if( HandOptDslash ) {
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int sss=0;sss<in._grid->oSites();sss++){
|
||||
DiracOptHand::DhopSite(st,U,comm_buf,sss,sss,in,out);
|
||||
}
|
||||
} else {
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int sss=0;sss<in._grid->oSites();sss++){
|
||||
DiracOpt::DhopSite(st,U,comm_buf,sss,sss,in,out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void WilsonFermion::DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
conformable(in._grid,_cbgrid); // verifies half grid
|
||||
conformable(in._grid,out._grid); // drops the cb check
|
||||
|
||||
assert(in.checkerboard==Even);
|
||||
out.checkerboard = Odd;
|
||||
|
||||
DhopInternal(StencilEven,UmuOdd,in,out,dag);
|
||||
}
|
||||
void WilsonFermion::DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
conformable(in._grid,_cbgrid); // verifies half grid
|
||||
conformable(in._grid,out._grid); // drops the cb check
|
||||
|
||||
assert(in.checkerboard==Odd);
|
||||
out.checkerboard = Even;
|
||||
|
||||
DhopInternal(StencilOdd,UmuEven,in,out,dag);
|
||||
}
|
||||
void WilsonFermion::Dhop(const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
{
|
||||
conformable(in._grid,_grid); // verifies full grid
|
||||
conformable(in._grid,out._grid);
|
||||
|
||||
out.checkerboard = in.checkerboard;
|
||||
|
||||
DhopInternal(Stencil,Umu,in,out,dag);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
|
87
lib/qcd/action/fermion/WilsonFermion.h
Normal file
87
lib/qcd/action/fermion/WilsonFermion.h
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef GRID_QCD_WILSON_FERMION_H
|
||||
#define GRID_QCD_WILSON_FERMION_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
namespace QCD {
|
||||
|
||||
class WilsonFermion : public FermionAction<LatticeFermion,LatticeGaugeField>
|
||||
{
|
||||
public:
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Implement the abstract base
|
||||
///////////////////////////////////////////////////////////////
|
||||
GridBase *GaugeGrid(void) { return _grid ;}
|
||||
GridBase *GaugeRedBlackGrid(void) { return _cbgrid ;}
|
||||
GridBase *FermionGrid(void) { return _grid;}
|
||||
GridBase *FermionRedBlackGrid(void) { return _cbgrid;}
|
||||
|
||||
// override multiply
|
||||
virtual RealD M (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual RealD Mdag (const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
// half checkerboard operaions
|
||||
void Meooe (const LatticeFermion &in, LatticeFermion &out);
|
||||
void MeooeDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void Mooee (const LatticeFermion &in, LatticeFermion &out); // remain virtual so we
|
||||
virtual void MooeeDag (const LatticeFermion &in, LatticeFermion &out); // can derive Clover
|
||||
virtual void MooeeInv (const LatticeFermion &in, LatticeFermion &out); // from Wilson bas
|
||||
virtual void MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
// non-hermitian hopping term; half cb or both
|
||||
void Dhop (const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Extra methods added by derived
|
||||
///////////////////////////////////////////////////////////////
|
||||
void DhopInternal(CartesianStencil & st,
|
||||
LatticeDoubledGaugeField &U,
|
||||
const LatticeFermion &in,
|
||||
LatticeFermion &out,
|
||||
int dag);
|
||||
|
||||
// Constructor
|
||||
WilsonFermion(LatticeGaugeField &_Umu,GridCartesian &Fgrid,GridRedBlackCartesian &Hgrid,double _mass);
|
||||
|
||||
// DoubleStore
|
||||
void DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Data members require to support the functionality
|
||||
///////////////////////////////////////////////////////////////
|
||||
static int HandOptDslash; // these are a temporary hack
|
||||
static int MortonOrder;
|
||||
|
||||
protected:
|
||||
|
||||
double mass;
|
||||
|
||||
GridBase * _grid;
|
||||
GridBase * _cbgrid;
|
||||
|
||||
static const int npoint=8;
|
||||
static const std::vector<int> directions ;
|
||||
static const std::vector<int> displacements;
|
||||
|
||||
//Defines the stencils for even and odd
|
||||
CartesianStencil Stencil;
|
||||
CartesianStencil StencilEven;
|
||||
CartesianStencil StencilOdd;
|
||||
|
||||
// Copy of the gauge field , with even and odd subsets
|
||||
LatticeDoubledGaugeField Umu;
|
||||
LatticeDoubledGaugeField UmuEven;
|
||||
LatticeDoubledGaugeField UmuOdd;
|
||||
|
||||
// Comms buffer
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > comm_buf;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -4,8 +4,8 @@ namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int ss,const LatticeFermion &in, LatticeFermion &out)
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
vHalfSpinColourVector tmp;
|
||||
vHalfSpinColourVector chi;
|
||||
@ -16,6 +16,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
//#define VERBOSE( A) if ( ss<10 ) { std::cout << "site " <<ss << " " #A " neigh " << offset << " perm "<< perm <<std::endl;}
|
||||
|
||||
// Xp
|
||||
int ss = sF;
|
||||
offset = st._offsets [Xp][ss];
|
||||
local = st._is_local[Xp][ss];
|
||||
perm = st._permute[Xp][ss];
|
||||
@ -29,7 +30,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Xp),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Xp),&chi());
|
||||
spReconXp(result,Uchi);
|
||||
|
||||
// std::cout << "XP_RECON"<<std::endl;
|
||||
@ -51,7 +52,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Yp),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Yp),&chi());
|
||||
accumReconYp(result,Uchi);
|
||||
|
||||
// Zp
|
||||
@ -67,7 +68,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Zp),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Zp),&chi());
|
||||
accumReconZp(result,Uchi);
|
||||
|
||||
// Tp
|
||||
@ -83,7 +84,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Tp),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Tp),&chi());
|
||||
accumReconTp(result,Uchi);
|
||||
|
||||
// Xm
|
||||
@ -101,7 +102,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Xm),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Xm),&chi());
|
||||
accumReconXm(result,Uchi);
|
||||
// std::cout << "XM_RECON_ACCUM"<<std::endl;
|
||||
// std::cout << result()(0)(0) <<" "<<result()(0)(1) <<" "<<result()(0)(2) <<std::endl;
|
||||
@ -124,7 +125,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Ym),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Ym),&chi());
|
||||
accumReconYm(result,Uchi);
|
||||
|
||||
// Zm
|
||||
@ -140,7 +141,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Zm),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Zm),&chi());
|
||||
accumReconZm(result,Uchi);
|
||||
|
||||
// Tm
|
||||
@ -156,15 +157,15 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Tm),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Tm),&chi());
|
||||
accumReconTm(result,Uchi);
|
||||
|
||||
vstream(out._odata[ss],result);
|
||||
vstream(out._odata[ss],result*(-0.5));
|
||||
}
|
||||
|
||||
void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int ss,const LatticeFermion &in, LatticeFermion &out)
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
vHalfSpinColourVector tmp;
|
||||
vHalfSpinColourVector chi;
|
||||
@ -173,6 +174,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
int offset,local,perm, ptype;
|
||||
|
||||
// Xp
|
||||
int ss=sF;
|
||||
offset = st._offsets [Xm][ss];
|
||||
local = st._is_local[Xm][ss];
|
||||
perm = st._permute[Xm][ss];
|
||||
@ -186,7 +188,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Xm),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Xm),&chi());
|
||||
spReconXp(result,Uchi);
|
||||
|
||||
// Yp
|
||||
@ -202,7 +204,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Ym),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Ym),&chi());
|
||||
accumReconYp(result,Uchi);
|
||||
|
||||
// Zp
|
||||
@ -218,7 +220,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Zm),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Zm),&chi());
|
||||
accumReconZp(result,Uchi);
|
||||
|
||||
// Tp
|
||||
@ -234,7 +236,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Tm),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Tm),&chi());
|
||||
accumReconTp(result,Uchi);
|
||||
|
||||
// Xm
|
||||
@ -252,7 +254,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Xp),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Xp),&chi());
|
||||
accumReconXm(result,Uchi);
|
||||
|
||||
// Ym
|
||||
@ -269,7 +271,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Yp),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Yp),&chi());
|
||||
accumReconYm(result,Uchi);
|
||||
|
||||
// Zm
|
||||
@ -285,7 +287,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Zp),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Zp),&chi());
|
||||
accumReconZm(result,Uchi);
|
||||
|
||||
// Tm
|
||||
@ -301,9 +303,9 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[ss](Tp),&chi());
|
||||
mult(&Uchi(),&U._odata[sU](Tp),&chi());
|
||||
accumReconTm(result,Uchi);
|
||||
|
||||
vstream(out._odata[ss],result);
|
||||
vstream(out._odata[ss],result*(-0.5));
|
||||
}
|
||||
}}
|
42
lib/qcd/action/fermion/WilsonKernels.h
Normal file
42
lib/qcd/action/fermion/WilsonKernels.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef GRID_QCD_DHOP_H
|
||||
#define GRID_QCD_DHOP_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
namespace QCD {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Helper classes that implement Wilson stencil for a single site.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Generic version works for any Nc and with extra flavour indices
|
||||
class DiracOpt {
|
||||
public:
|
||||
// These ones will need to be package intelligently. WilsonType base class
|
||||
// for use by DWF etc..
|
||||
static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
|
||||
static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
};
|
||||
|
||||
// Hand unrolled for Nc=3, one flavour
|
||||
class DiracOptHand {
|
||||
public:
|
||||
// These ones will need to be package intelligently. WilsonType base class
|
||||
// for use by DWF etc..
|
||||
static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
|
||||
static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
@ -27,7 +27,7 @@
|
||||
Chi_12 = ref()(1)(2);
|
||||
|
||||
#define MULT_2SPIN(A)\
|
||||
auto & ref(U._odata[ss](A)); \
|
||||
auto & ref(U._odata[sU](A)); \
|
||||
U_00 = ref()(0,0);\
|
||||
U_10 = ref()(1,0);\
|
||||
U_20 = ref()(2,0);\
|
||||
@ -282,7 +282,7 @@ namespace QCD {
|
||||
|
||||
void DiracOptHand::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int ss,const LatticeFermion &in, LatticeFermion &out)
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
REGISTER vComplex result_00; // 12 regs on knc
|
||||
REGISTER vComplex result_01;
|
||||
@ -338,7 +338,8 @@ void DiracOptHand::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
|
||||
|
||||
int offset,local,perm, ptype;
|
||||
|
||||
int ss=sF;
|
||||
|
||||
// Xp
|
||||
offset = st._offsets [Xp][ss];
|
||||
local = st._is_local[Xp][ss];
|
||||
@ -514,24 +515,24 @@ void DiracOptHand::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
|
||||
{
|
||||
vSpinColourVector & ref (out._odata[ss]);
|
||||
vstream(ref()(0)(0),result_00);
|
||||
vstream(ref()(0)(1),result_01);
|
||||
vstream(ref()(0)(2),result_02);
|
||||
vstream(ref()(1)(0),result_10);
|
||||
vstream(ref()(1)(1),result_11);
|
||||
vstream(ref()(1)(2),result_12);
|
||||
vstream(ref()(2)(0),result_20);
|
||||
vstream(ref()(2)(1),result_21);
|
||||
vstream(ref()(2)(2),result_22);
|
||||
vstream(ref()(3)(0),result_30);
|
||||
vstream(ref()(3)(1),result_31);
|
||||
vstream(ref()(3)(2),result_32);
|
||||
vstream(ref()(0)(0),result_00*(-0.5));
|
||||
vstream(ref()(0)(1),result_01*(-0.5));
|
||||
vstream(ref()(0)(2),result_02*(-0.5));
|
||||
vstream(ref()(1)(0),result_10*(-0.5));
|
||||
vstream(ref()(1)(1),result_11*(-0.5));
|
||||
vstream(ref()(1)(2),result_12*(-0.5));
|
||||
vstream(ref()(2)(0),result_20*(-0.5));
|
||||
vstream(ref()(2)(1),result_21*(-0.5));
|
||||
vstream(ref()(2)(2),result_22*(-0.5));
|
||||
vstream(ref()(3)(0),result_30*(-0.5));
|
||||
vstream(ref()(3)(1),result_31*(-0.5));
|
||||
vstream(ref()(3)(2),result_32*(-0.5));
|
||||
}
|
||||
}
|
||||
|
||||
void DiracOptHand::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int ss,const LatticeFermion &in, LatticeFermion &out)
|
||||
int ss,int sU,const LatticeFermion &in, LatticeFermion &out)
|
||||
{
|
||||
REGISTER vComplex result_00; // 12 regs on knc
|
||||
REGISTER vComplex result_01;
|
||||
@ -752,18 +753,18 @@ void DiracOptHand::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
|
||||
{
|
||||
vSpinColourVector & ref (out._odata[ss]);
|
||||
vstream(ref()(0)(0),result_00);
|
||||
vstream(ref()(0)(1),result_01);
|
||||
vstream(ref()(0)(2),result_02);
|
||||
vstream(ref()(1)(0),result_10);
|
||||
vstream(ref()(1)(1),result_11);
|
||||
vstream(ref()(1)(2),result_12);
|
||||
vstream(ref()(2)(0),result_20);
|
||||
vstream(ref()(2)(1),result_21);
|
||||
vstream(ref()(2)(2),result_22);
|
||||
vstream(ref()(3)(0),result_30);
|
||||
vstream(ref()(3)(1),result_31);
|
||||
vstream(ref()(3)(2),result_32);
|
||||
vstream(ref()(0)(0),result_00*(-0.5));
|
||||
vstream(ref()(0)(1),result_01*(-0.5));
|
||||
vstream(ref()(0)(2),result_02*(-0.5));
|
||||
vstream(ref()(1)(0),result_10*(-0.5));
|
||||
vstream(ref()(1)(1),result_11*(-0.5));
|
||||
vstream(ref()(1)(2),result_12*(-0.5));
|
||||
vstream(ref()(2)(0),result_20*(-0.5));
|
||||
vstream(ref()(2)(1),result_21*(-0.5));
|
||||
vstream(ref()(2)(2),result_22*(-0.5));
|
||||
vstream(ref()(3)(0),result_30*(-0.5));
|
||||
vstream(ref()(3)(1),result_31*(-0.5));
|
||||
vstream(ref()(3)(2),result_32*(-0.5));
|
||||
}
|
||||
}
|
||||
}}
|
103
lib/stencil/Grid_lebesgue.cc
Normal file
103
lib/stencil/Grid_lebesgue.cc
Normal file
@ -0,0 +1,103 @@
|
||||
#include <Grid.h>
|
||||
|
||||
namespace Grid {
|
||||
|
||||
int LebesgueOrder::UseLebesgueOrder;
|
||||
|
||||
LebesgueOrder::IndexInteger LebesgueOrder::alignup(IndexInteger n){
|
||||
n--; // 1000 0011 --> 1000 0010
|
||||
n |= n >> 1; // 1000 0010 | 0100 0001 = 1100 0011
|
||||
n |= n >> 2; // 1100 0011 | 0011 0000 = 1111 0011
|
||||
n |= n >> 4; // 1111 0011 | 0000 1111 = 1111 1111
|
||||
n |= n >> 8; // ... (At this point all bits are 1, so further bitwise-or
|
||||
n |= n >> 16; // operations produce no effect.)
|
||||
n++; // 1111 1111 --> 1 0000 0000
|
||||
return n;
|
||||
};
|
||||
|
||||
LebesgueOrder::LebesgueOrder(GridBase *grid)
|
||||
{
|
||||
_LebesgueReorder.resize(0);
|
||||
|
||||
// Align up dimensions to power of two.
|
||||
const IndexInteger one=1;
|
||||
IndexInteger ND = grid->_ndimension;
|
||||
std::vector<IndexInteger> dims(ND);
|
||||
std::vector<IndexInteger> adims(ND);
|
||||
std::vector<std::vector<IndexInteger> > bitlist(ND);
|
||||
|
||||
for(IndexInteger mu=0;mu<ND;mu++){
|
||||
dims[mu] = grid->_rdimensions[mu];
|
||||
assert ( dims[mu] != 0 );
|
||||
adims[mu] = alignup(dims[mu]);
|
||||
}
|
||||
|
||||
// List which bits of padded volume coordinate contribute; this strategy
|
||||
// i) avoids recursion
|
||||
// ii) has loop lengths at most the width of a 32 bit word.
|
||||
int sitebit=0;
|
||||
int split=2;
|
||||
for(int mu=0;mu<ND;mu++){ // mu 0 takes bit 0; mu 1 takes bit 1 etc...
|
||||
for(int bit=0;bit<split;bit++){
|
||||
IndexInteger mask = one<<bit;
|
||||
if ( mask&(adims[mu]-1) ){
|
||||
bitlist[mu].push_back(sitebit);
|
||||
sitebit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int bit=split;bit<32;bit++){
|
||||
IndexInteger mask = one<<bit;
|
||||
for(int mu=0;mu<ND;mu++){ // mu 0 takes bit 0; mu 1 takes bit 1 etc...
|
||||
if ( mask&(adims[mu]-1) ){
|
||||
bitlist[mu].push_back(sitebit);
|
||||
sitebit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Work out padded and unpadded volumes
|
||||
IndexInteger avol = 1;
|
||||
for(int mu=0;mu<ND;mu++) avol = avol * adims[mu];
|
||||
|
||||
IndexInteger vol = 1;
|
||||
for(int mu=0;mu<ND;mu++) vol = vol * dims[mu];
|
||||
|
||||
// Loop over padded volume, following Lebesgue curve
|
||||
// We interleave the bits from sequential "mu".
|
||||
std::vector<IndexInteger> ax(ND);
|
||||
|
||||
for(IndexInteger asite=0;asite<avol;asite++){
|
||||
|
||||
// Start with zero and collect bits
|
||||
for(int mu=0;mu<ND;mu++) ax[mu] = 0;
|
||||
|
||||
int contained = 1;
|
||||
for(int mu=0;mu<ND;mu++){
|
||||
|
||||
// Build the coordinate on the aligned volume
|
||||
for(int bit=0;bit<bitlist[mu].size();bit++){
|
||||
int sbit=bitlist[mu][bit];
|
||||
|
||||
if(asite&(one<<sbit)){
|
||||
ax[mu]|=one<<bit;
|
||||
}
|
||||
}
|
||||
|
||||
// Is it contained in original box
|
||||
if ( ax[mu]>dims[mu]-1 ) contained = 0;
|
||||
|
||||
}
|
||||
|
||||
if ( contained ) {
|
||||
int site = ax[0]
|
||||
+ dims[0]*ax[1]
|
||||
+dims[0]*dims[1]*ax[2]
|
||||
+dims[0]*dims[1]*dims[2]*ax[3];
|
||||
|
||||
_LebesgueReorder.push_back(site);
|
||||
}
|
||||
}
|
||||
assert( _LebesgueReorder.size() == vol );
|
||||
}
|
||||
}
|
29
lib/stencil/Grid_lebesgue.h
Normal file
29
lib/stencil/Grid_lebesgue.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef GRID_LEBESGUE_H
|
||||
#define GRID_LEBESGUE_H
|
||||
|
||||
#include<vector>
|
||||
|
||||
// Lebesgue, Morton, Z-graph ordering assistance
|
||||
namespace Grid {
|
||||
|
||||
class LebesgueOrder {
|
||||
public:
|
||||
|
||||
static int UseLebesgueOrder;
|
||||
|
||||
typedef uint32_t IndexInteger;
|
||||
|
||||
inline IndexInteger Reorder(IndexInteger ss) {
|
||||
return UseLebesgueOrder ? _LebesgueReorder[ss] : ss;
|
||||
};
|
||||
|
||||
IndexInteger alignup(IndexInteger n);
|
||||
|
||||
LebesgueOrder(GridBase *grid);
|
||||
|
||||
private:
|
||||
std::vector<IndexInteger> _LebesgueReorder;
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
@ -3,95 +3,6 @@
|
||||
namespace Grid {
|
||||
|
||||
|
||||
|
||||
void CartesianStencil::LebesgueOrder(void)
|
||||
{
|
||||
_LebesgueReorder.resize(0);
|
||||
|
||||
// Align up dimensions to power of two.
|
||||
const StencilInteger one=1;
|
||||
StencilInteger ND = _grid->_ndimension;
|
||||
std::vector<StencilInteger> dims(ND);
|
||||
std::vector<StencilInteger> adims(ND);
|
||||
std::vector<std::vector<StencilInteger> > bitlist(ND);
|
||||
|
||||
|
||||
for(StencilInteger mu=0;mu<ND;mu++){
|
||||
dims[mu] = _grid->_rdimensions[mu];
|
||||
assert ( dims[mu] != 0 );
|
||||
adims[mu] = alignup(dims[mu]);
|
||||
}
|
||||
|
||||
// List which bits of padded volume coordinate contribute; this strategy
|
||||
// i) avoids recursion
|
||||
// ii) has loop lengths at most the width of a 32 bit word.
|
||||
int sitebit=0;
|
||||
int split=24;
|
||||
for(int mu=0;mu<ND;mu++){ // mu 0 takes bit 0; mu 1 takes bit 1 etc...
|
||||
for(int bit=0;bit<split;bit++){
|
||||
StencilInteger mask = one<<bit;
|
||||
if ( mask&(adims[mu]-1) ){
|
||||
bitlist[mu].push_back(sitebit);
|
||||
sitebit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int bit=split;bit<32;bit++){
|
||||
StencilInteger mask = one<<bit;
|
||||
for(int mu=0;mu<ND;mu++){ // mu 0 takes bit 0; mu 1 takes bit 1 etc...
|
||||
if ( mask&(adims[mu]-1) ){
|
||||
bitlist[mu].push_back(sitebit);
|
||||
sitebit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Work out padded and unpadded volumes
|
||||
StencilInteger avol = 1;
|
||||
for(int mu=0;mu<ND;mu++) avol = avol * adims[mu];
|
||||
|
||||
StencilInteger vol = 1;
|
||||
for(int mu=0;mu<ND;mu++) vol = vol * dims[mu];
|
||||
|
||||
// Loop over padded volume, following Lebesgue curve
|
||||
// We interleave the bits from sequential "mu".
|
||||
std::vector<StencilInteger> ax(ND);
|
||||
|
||||
for(StencilInteger asite=0;asite<avol;asite++){
|
||||
|
||||
// Start with zero and collect bits
|
||||
for(int mu=0;mu<ND;mu++) ax[mu] = 0;
|
||||
|
||||
int contained = 1;
|
||||
for(int mu=0;mu<ND;mu++){
|
||||
|
||||
// Build the coordinate on the aligned volume
|
||||
for(int bit=0;bit<bitlist[mu].size();bit++){
|
||||
int sbit=bitlist[mu][bit];
|
||||
|
||||
if(asite&(one<<sbit)){
|
||||
ax[mu]|=one<<bit;
|
||||
}
|
||||
}
|
||||
|
||||
// Is it contained in original box
|
||||
if ( ax[mu]>dims[mu]-1 ) contained = 0;
|
||||
|
||||
}
|
||||
|
||||
if ( contained ) {
|
||||
int site = ax[0]
|
||||
+ dims[0]*ax[1]
|
||||
+dims[0]*dims[1]*ax[2]
|
||||
+dims[0]*dims[1]*dims[2]*ax[3];
|
||||
|
||||
_LebesgueReorder.push_back(site);
|
||||
}
|
||||
}
|
||||
|
||||
assert( _LebesgueReorder.size() == vol );
|
||||
}
|
||||
|
||||
CartesianStencil::CartesianStencil(GridBase *grid,
|
||||
int npoints,
|
||||
int checkerboard,
|
||||
@ -110,8 +21,6 @@ void CartesianStencil::LebesgueOrder(void)
|
||||
_unified_buffer_size=0;
|
||||
_request_count =0;
|
||||
|
||||
LebesgueOrder();
|
||||
|
||||
int osites = _grid->oSites();
|
||||
|
||||
for(int i=0;i<npoints;i++){
|
||||
@ -143,8 +52,8 @@ void CartesianStencil::LebesgueOrder(void)
|
||||
// up a table containing the npoint "neighbours" and whether they
|
||||
// live in lattice or a comms buffer.
|
||||
if ( !comm_dim ) {
|
||||
sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,0);
|
||||
sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,1);
|
||||
sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,Even);
|
||||
sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,Odd);
|
||||
|
||||
if ( sshift[0] == sshift[1] ) {
|
||||
Local(point,dimension,shift,0x3);
|
||||
@ -154,8 +63,8 @@ void CartesianStencil::LebesgueOrder(void)
|
||||
}
|
||||
} else { // All permute extract done in comms phase prior to Stencil application
|
||||
// So tables are the same whether comm_dim or splice_dim
|
||||
sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,0);
|
||||
sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,1);
|
||||
sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,Even);
|
||||
sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,Odd);
|
||||
if ( sshift[0] == sshift[1] ) {
|
||||
Comms(point,dimension,shift,0x3);
|
||||
} else {
|
||||
@ -185,7 +94,7 @@ void CartesianStencil::LebesgueOrder(void)
|
||||
int o = 0;
|
||||
int bo = x * _grid->_ostride[dimension];
|
||||
|
||||
int cb= (cbmask==0x2)? 1 : 0;
|
||||
int cb= (cbmask==0x2)? Odd : Even;
|
||||
|
||||
int sshift = _grid->CheckerBoardShift(_checkerboard,dimension,shift,cb);
|
||||
int sx = (x+sshift)%rd;
|
||||
@ -224,7 +133,7 @@ void CartesianStencil::LebesgueOrder(void)
|
||||
_comm_buf_size[point] = buffer_size; // Size of _one_ plane. Multiple planes may be gathered and
|
||||
// send to one or more remote nodes.
|
||||
|
||||
int cb= (cbmask==0x2)? 1 : 0;
|
||||
int cb= (cbmask==0x2)? Odd : Even;
|
||||
int sshift= _grid->CheckerBoardShift(_checkerboard,dimension,shift,cb);
|
||||
|
||||
for(int x=0;x<rd;x++){
|
||||
|
Reference in New Issue
Block a user