mirror of
https://github.com/paboyle/Grid.git
synced 2025-04-09 21:50:45 +01:00
Merge branch 'develop' into feature/XiToSigma
This commit is contained in:
commit
3b06e4655e
@ -54,9 +54,11 @@ Version.h: version-cache
|
|||||||
include Make.inc
|
include Make.inc
|
||||||
include Eigen.inc
|
include Eigen.inc
|
||||||
|
|
||||||
extra_sources+=$(ZWILS_FERMION_FILES)
|
|
||||||
extra_sources+=$(WILS_FERMION_FILES)
|
extra_sources+=$(WILS_FERMION_FILES)
|
||||||
extra_sources+=$(STAG_FERMION_FILES)
|
extra_sources+=$(STAG_FERMION_FILES)
|
||||||
|
if BUILD_ZMOBIUS
|
||||||
|
extra_sources+=$(ZWILS_FERMION_FILES)
|
||||||
|
endif
|
||||||
if BUILD_GPARITY
|
if BUILD_GPARITY
|
||||||
extra_sources+=$(GP_FERMION_FILES)
|
extra_sources+=$(GP_FERMION_FILES)
|
||||||
endif
|
endif
|
||||||
|
@ -36,7 +36,7 @@ static const int CbBlack=1;
|
|||||||
static const int Even =CbRed;
|
static const int Even =CbRed;
|
||||||
static const int Odd =CbBlack;
|
static const int Odd =CbBlack;
|
||||||
|
|
||||||
accelerator_inline int RedBlackCheckerBoardFromOindex (int oindex, Coordinate &rdim, Coordinate &chk_dim_msk)
|
accelerator_inline int RedBlackCheckerBoardFromOindex (int oindex,const Coordinate &rdim,const Coordinate &chk_dim_msk)
|
||||||
{
|
{
|
||||||
int nd=rdim.size();
|
int nd=rdim.size();
|
||||||
Coordinate coor(nd);
|
Coordinate coor(nd);
|
||||||
|
@ -67,9 +67,14 @@ public:
|
|||||||
accelerator_inline const vobj & operator()(size_t i) const { return this->_odata[i]; }
|
accelerator_inline const vobj & operator()(size_t i) const { return this->_odata[i]; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// accelerator_inline const vobj & operator[](size_t i) const { return this->_odata[i]; };
|
||||||
|
accelerator_inline vobj & operator[](size_t i) const { return this->_odata[i]; };
|
||||||
|
#else
|
||||||
accelerator_inline const vobj & operator[](size_t i) const { return this->_odata[i]; };
|
accelerator_inline const vobj & operator[](size_t i) const { return this->_odata[i]; };
|
||||||
accelerator_inline vobj & operator[](size_t i) { return this->_odata[i]; };
|
accelerator_inline vobj & operator[](size_t i) { return this->_odata[i]; };
|
||||||
|
#endif
|
||||||
|
|
||||||
accelerator_inline uint64_t begin(void) const { return 0;};
|
accelerator_inline uint64_t begin(void) const { return 0;};
|
||||||
accelerator_inline uint64_t end(void) const { return this->_odata_size; };
|
accelerator_inline uint64_t end(void) const { return this->_odata_size; };
|
||||||
accelerator_inline uint64_t size(void) const { return this->_odata_size; };
|
accelerator_inline uint64_t size(void) const { return this->_odata_size; };
|
||||||
|
@ -41,7 +41,7 @@ class Action
|
|||||||
public:
|
public:
|
||||||
bool is_smeared = false;
|
bool is_smeared = false;
|
||||||
// Heatbath?
|
// Heatbath?
|
||||||
virtual void refresh(const GaugeField& U, GridParallelRNG& pRNG) = 0; // refresh pseudofermions
|
virtual void refresh(const GaugeField& U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) = 0; // refresh pseudofermions
|
||||||
virtual RealD S(const GaugeField& U) = 0; // evaluate the action
|
virtual RealD S(const GaugeField& U) = 0; // evaluate the action
|
||||||
virtual void deriv(const GaugeField& U, GaugeField& dSdU) = 0; // evaluate the action derivative
|
virtual void deriv(const GaugeField& U, GaugeField& dSdU) = 0; // evaluate the action derivative
|
||||||
virtual std::string action_name() = 0; // return the action name
|
virtual std::string action_name() = 0; // return the action name
|
||||||
|
@ -153,8 +153,8 @@ public:
|
|||||||
typedef typename Impl::StencilImpl StencilImpl; \
|
typedef typename Impl::StencilImpl StencilImpl; \
|
||||||
typedef typename Impl::ImplParams ImplParams; \
|
typedef typename Impl::ImplParams ImplParams; \
|
||||||
typedef typename Impl::StencilImpl::View_type StencilView; \
|
typedef typename Impl::StencilImpl::View_type StencilView; \
|
||||||
typedef typename ViewMap<FermionField>::Type FermionFieldView; \
|
typedef const typename ViewMap<FermionField>::Type FermionFieldView; \
|
||||||
typedef typename ViewMap<DoubledGaugeField>::Type DoubledGaugeFieldView;
|
typedef const typename ViewMap<DoubledGaugeField>::Type DoubledGaugeFieldView;
|
||||||
|
|
||||||
#define INHERIT_IMPL_TYPES(Base) \
|
#define INHERIT_IMPL_TYPES(Base) \
|
||||||
INHERIT_GIMPL_TYPES(Base) \
|
INHERIT_GIMPL_TYPES(Base) \
|
||||||
|
@ -61,7 +61,7 @@ public:
|
|||||||
typedef typename SiteHalfSpinor::vector_type vComplexHigh;
|
typedef typename SiteHalfSpinor::vector_type vComplexHigh;
|
||||||
constexpr static int Nw=sizeof(SiteHalfSpinor)/sizeof(vComplexHigh);
|
constexpr static int Nw=sizeof(SiteHalfSpinor)/sizeof(vComplexHigh);
|
||||||
|
|
||||||
accelerator_inline int CommDatumSize(void) {
|
accelerator_inline int CommDatumSize(void) const {
|
||||||
return sizeof(SiteHalfCommSpinor);
|
return sizeof(SiteHalfCommSpinor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ public:
|
|||||||
/* Compress includes precision change if mpi data is not same */
|
/* Compress includes precision change if mpi data is not same */
|
||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
template<class _SiteHalfSpinor, class _SiteSpinor>
|
template<class _SiteHalfSpinor, class _SiteSpinor>
|
||||||
accelerator_inline void Compress(_SiteHalfSpinor *buf,Integer o,const _SiteSpinor &in) {
|
accelerator_inline void Compress(_SiteHalfSpinor *buf,Integer o,const _SiteSpinor &in) const {
|
||||||
_SiteHalfSpinor tmp;
|
_SiteHalfSpinor tmp;
|
||||||
projector::Proj(tmp,in,mu,dag);
|
projector::Proj(tmp,in,mu,dag);
|
||||||
vstream(buf[o],tmp);
|
vstream(buf[o],tmp);
|
||||||
@ -81,7 +81,7 @@ public:
|
|||||||
accelerator_inline void Exchange(SiteHalfSpinor *mp,
|
accelerator_inline void Exchange(SiteHalfSpinor *mp,
|
||||||
const SiteHalfSpinor * __restrict__ vp0,
|
const SiteHalfSpinor * __restrict__ vp0,
|
||||||
const SiteHalfSpinor * __restrict__ vp1,
|
const SiteHalfSpinor * __restrict__ vp1,
|
||||||
Integer type,Integer o){
|
Integer type,Integer o) const {
|
||||||
SiteHalfSpinor tmp1;
|
SiteHalfSpinor tmp1;
|
||||||
SiteHalfSpinor tmp2;
|
SiteHalfSpinor tmp2;
|
||||||
exchange(tmp1,tmp2,vp0[o],vp1[o],type);
|
exchange(tmp1,tmp2,vp0[o],vp1[o],type);
|
||||||
@ -93,7 +93,7 @@ public:
|
|||||||
/* Have a decompression step if mpi data is not same */
|
/* Have a decompression step if mpi data is not same */
|
||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
accelerator_inline void Decompress(SiteHalfSpinor * __restrict__ out,
|
accelerator_inline void Decompress(SiteHalfSpinor * __restrict__ out,
|
||||||
SiteHalfSpinor * __restrict__ in, Integer o) {
|
SiteHalfSpinor * __restrict__ in, Integer o) const {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ public:
|
|||||||
accelerator_inline void CompressExchange(SiteHalfSpinor * __restrict__ out0,
|
accelerator_inline void CompressExchange(SiteHalfSpinor * __restrict__ out0,
|
||||||
SiteHalfSpinor * __restrict__ out1,
|
SiteHalfSpinor * __restrict__ out1,
|
||||||
const SiteSpinor * __restrict__ in,
|
const SiteSpinor * __restrict__ in,
|
||||||
Integer j,Integer k, Integer m,Integer type)
|
Integer j,Integer k, Integer m,Integer type) const
|
||||||
{
|
{
|
||||||
SiteHalfSpinor temp1, temp2;
|
SiteHalfSpinor temp1, temp2;
|
||||||
SiteHalfSpinor temp3, temp4;
|
SiteHalfSpinor temp3, temp4;
|
||||||
@ -117,7 +117,7 @@ public:
|
|||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
/* Pass the info to the stencil */
|
/* Pass the info to the stencil */
|
||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
accelerator_inline bool DecompressionStep(void) { return false; }
|
accelerator_inline bool DecompressionStep(void) const { return false; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ public:
|
|||||||
typedef typename SiteHalfSpinor::vector_type vComplexHigh;
|
typedef typename SiteHalfSpinor::vector_type vComplexHigh;
|
||||||
constexpr static int Nw=sizeof(SiteHalfSpinor)/sizeof(vComplexHigh);
|
constexpr static int Nw=sizeof(SiteHalfSpinor)/sizeof(vComplexHigh);
|
||||||
|
|
||||||
accelerator_inline int CommDatumSize(void) {
|
accelerator_inline int CommDatumSize(void) const {
|
||||||
return sizeof(SiteHalfCommSpinor);
|
return sizeof(SiteHalfCommSpinor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ public:
|
|||||||
/* Compress includes precision change if mpi data is not same */
|
/* Compress includes precision change if mpi data is not same */
|
||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
template<class _SiteHalfSpinor, class _SiteSpinor>
|
template<class _SiteHalfSpinor, class _SiteSpinor>
|
||||||
accelerator_inline void Compress(_SiteHalfSpinor *buf,Integer o,const _SiteSpinor &in) {
|
accelerator_inline void Compress(_SiteHalfSpinor *buf,Integer o,const _SiteSpinor &in) const {
|
||||||
_SiteHalfSpinor hsp;
|
_SiteHalfSpinor hsp;
|
||||||
SiteHalfCommSpinor *hbuf = (SiteHalfCommSpinor *)buf;
|
SiteHalfCommSpinor *hbuf = (SiteHalfCommSpinor *)buf;
|
||||||
projector::Proj(hsp,in,mu,dag);
|
projector::Proj(hsp,in,mu,dag);
|
||||||
@ -163,7 +163,7 @@ public:
|
|||||||
accelerator_inline void Exchange(SiteHalfSpinor *mp,
|
accelerator_inline void Exchange(SiteHalfSpinor *mp,
|
||||||
SiteHalfSpinor *vp0,
|
SiteHalfSpinor *vp0,
|
||||||
SiteHalfSpinor *vp1,
|
SiteHalfSpinor *vp1,
|
||||||
Integer type,Integer o){
|
Integer type,Integer o) const {
|
||||||
SiteHalfSpinor vt0,vt1;
|
SiteHalfSpinor vt0,vt1;
|
||||||
SiteHalfCommSpinor *vpp0 = (SiteHalfCommSpinor *)vp0;
|
SiteHalfCommSpinor *vpp0 = (SiteHalfCommSpinor *)vp0;
|
||||||
SiteHalfCommSpinor *vpp1 = (SiteHalfCommSpinor *)vp1;
|
SiteHalfCommSpinor *vpp1 = (SiteHalfCommSpinor *)vp1;
|
||||||
@ -175,7 +175,7 @@ public:
|
|||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
/* Have a decompression step if mpi data is not same */
|
/* Have a decompression step if mpi data is not same */
|
||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
accelerator_inline void Decompress(SiteHalfSpinor *out, SiteHalfSpinor *in, Integer o){
|
accelerator_inline void Decompress(SiteHalfSpinor *out, SiteHalfSpinor *in, Integer o) const {
|
||||||
SiteHalfCommSpinor *hin=(SiteHalfCommSpinor *)in;
|
SiteHalfCommSpinor *hin=(SiteHalfCommSpinor *)in;
|
||||||
precisionChange((vComplexHigh *)&out[o],(vComplexLow *)&hin[o],Nw);
|
precisionChange((vComplexHigh *)&out[o],(vComplexLow *)&hin[o],Nw);
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ public:
|
|||||||
accelerator_inline void CompressExchange(SiteHalfSpinor *out0,
|
accelerator_inline void CompressExchange(SiteHalfSpinor *out0,
|
||||||
SiteHalfSpinor *out1,
|
SiteHalfSpinor *out1,
|
||||||
const SiteSpinor *in,
|
const SiteSpinor *in,
|
||||||
Integer j,Integer k, Integer m,Integer type){
|
Integer j,Integer k, Integer m,Integer type) const {
|
||||||
SiteHalfSpinor temp1, temp2,temp3,temp4;
|
SiteHalfSpinor temp1, temp2,temp3,temp4;
|
||||||
SiteHalfCommSpinor *hout0 = (SiteHalfCommSpinor *)out0;
|
SiteHalfCommSpinor *hout0 = (SiteHalfCommSpinor *)out0;
|
||||||
SiteHalfCommSpinor *hout1 = (SiteHalfCommSpinor *)out1;
|
SiteHalfCommSpinor *hout1 = (SiteHalfCommSpinor *)out1;
|
||||||
@ -200,7 +200,7 @@ public:
|
|||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
/* Pass the info to the stencil */
|
/* Pass the info to the stencil */
|
||||||
/*****************************************************/
|
/*****************************************************/
|
||||||
accelerator_inline bool DecompressionStep(void) { return true; }
|
accelerator_inline bool DecompressionStep(void) const { return true; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ public:
|
|||||||
typedef WilsonCompressor<SiteHalfCommSpinor,SiteHalfSpinor, SiteSpinor> Compressor;
|
typedef WilsonCompressor<SiteHalfCommSpinor,SiteHalfSpinor, SiteSpinor> Compressor;
|
||||||
typedef WilsonImplParams ImplParams;
|
typedef WilsonImplParams ImplParams;
|
||||||
typedef WilsonStencil<SiteSpinor, SiteHalfSpinor,ImplParams> StencilImpl;
|
typedef WilsonStencil<SiteSpinor, SiteHalfSpinor,ImplParams> StencilImpl;
|
||||||
typedef typename StencilImpl::View_type StencilView;
|
typedef const typename StencilImpl::View_type StencilView;
|
||||||
|
|
||||||
ImplParams Params;
|
ImplParams Params;
|
||||||
|
|
||||||
|
@ -76,7 +76,24 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
|
|
||||||
#define REGISTER
|
#define REGISTER
|
||||||
|
|
||||||
#define LOAD_CHIMU \
|
#ifdef GRID_SIMT
|
||||||
|
#define LOAD_CHIMU(ptype) \
|
||||||
|
{const SiteSpinor & ref (in[offset]); \
|
||||||
|
Chimu_00=coalescedReadPermute<ptype>(ref()(0)(0),perm); \
|
||||||
|
Chimu_01=coalescedReadPermute<ptype>(ref()(0)(1),perm); \
|
||||||
|
Chimu_02=coalescedReadPermute<ptype>(ref()(0)(2),perm); \
|
||||||
|
Chimu_10=coalescedReadPermute<ptype>(ref()(1)(0),perm); \
|
||||||
|
Chimu_11=coalescedReadPermute<ptype>(ref()(1)(1),perm); \
|
||||||
|
Chimu_12=coalescedReadPermute<ptype>(ref()(1)(2),perm); \
|
||||||
|
Chimu_20=coalescedReadPermute<ptype>(ref()(2)(0),perm); \
|
||||||
|
Chimu_21=coalescedReadPermute<ptype>(ref()(2)(1),perm); \
|
||||||
|
Chimu_22=coalescedReadPermute<ptype>(ref()(2)(2),perm); \
|
||||||
|
Chimu_30=coalescedReadPermute<ptype>(ref()(3)(0),perm); \
|
||||||
|
Chimu_31=coalescedReadPermute<ptype>(ref()(3)(1),perm); \
|
||||||
|
Chimu_32=coalescedReadPermute<ptype>(ref()(3)(2),perm); }
|
||||||
|
#define PERMUTE_DIR(dir) ;
|
||||||
|
#else
|
||||||
|
#define LOAD_CHIMU(ptype) \
|
||||||
{const SiteSpinor & ref (in[offset]); \
|
{const SiteSpinor & ref (in[offset]); \
|
||||||
Chimu_00=ref()(0)(0);\
|
Chimu_00=ref()(0)(0);\
|
||||||
Chimu_01=ref()(0)(1);\
|
Chimu_01=ref()(0)(1);\
|
||||||
@ -91,55 +108,55 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
Chimu_31=ref()(3)(1);\
|
Chimu_31=ref()(3)(1);\
|
||||||
Chimu_32=ref()(3)(2);}
|
Chimu_32=ref()(3)(2);}
|
||||||
|
|
||||||
#define LOAD_CHI\
|
|
||||||
{const SiteHalfSpinor &ref(buf[offset]); \
|
|
||||||
Chi_00 = ref()(0)(0);\
|
|
||||||
Chi_01 = ref()(0)(1);\
|
|
||||||
Chi_02 = ref()(0)(2);\
|
|
||||||
Chi_10 = ref()(1)(0);\
|
|
||||||
Chi_11 = ref()(1)(1);\
|
|
||||||
Chi_12 = ref()(1)(2);}
|
|
||||||
|
|
||||||
// To splat or not to splat depends on the implementation
|
|
||||||
#define MULT_2SPIN(A)\
|
|
||||||
{auto & ref(U[sU](A)); \
|
|
||||||
Impl::loadLinkElement(U_00,ref()(0,0)); \
|
|
||||||
Impl::loadLinkElement(U_10,ref()(1,0)); \
|
|
||||||
Impl::loadLinkElement(U_20,ref()(2,0)); \
|
|
||||||
Impl::loadLinkElement(U_01,ref()(0,1)); \
|
|
||||||
Impl::loadLinkElement(U_11,ref()(1,1)); \
|
|
||||||
Impl::loadLinkElement(U_21,ref()(2,1)); \
|
|
||||||
UChi_00 = U_00*Chi_00;\
|
|
||||||
UChi_10 = U_00*Chi_10;\
|
|
||||||
UChi_01 = U_10*Chi_00;\
|
|
||||||
UChi_11 = U_10*Chi_10;\
|
|
||||||
UChi_02 = U_20*Chi_00;\
|
|
||||||
UChi_12 = U_20*Chi_10;\
|
|
||||||
UChi_00+= U_01*Chi_01;\
|
|
||||||
UChi_10+= U_01*Chi_11;\
|
|
||||||
UChi_01+= U_11*Chi_01;\
|
|
||||||
UChi_11+= U_11*Chi_11;\
|
|
||||||
UChi_02+= U_21*Chi_01;\
|
|
||||||
UChi_12+= U_21*Chi_11;\
|
|
||||||
Impl::loadLinkElement(U_00,ref()(0,2)); \
|
|
||||||
Impl::loadLinkElement(U_10,ref()(1,2)); \
|
|
||||||
Impl::loadLinkElement(U_20,ref()(2,2)); \
|
|
||||||
UChi_00+= U_00*Chi_02;\
|
|
||||||
UChi_10+= U_00*Chi_12;\
|
|
||||||
UChi_01+= U_10*Chi_02;\
|
|
||||||
UChi_11+= U_10*Chi_12;\
|
|
||||||
UChi_02+= U_20*Chi_02;\
|
|
||||||
UChi_12+= U_20*Chi_12;}
|
|
||||||
|
|
||||||
|
|
||||||
#define PERMUTE_DIR(dir) \
|
#define PERMUTE_DIR(dir) \
|
||||||
permute##dir(Chi_00,Chi_00);\
|
permute##dir(Chi_00,Chi_00); \
|
||||||
permute##dir(Chi_01,Chi_01);\
|
permute##dir(Chi_01,Chi_01);\
|
||||||
permute##dir(Chi_02,Chi_02);\
|
permute##dir(Chi_02,Chi_02);\
|
||||||
permute##dir(Chi_10,Chi_10);\
|
permute##dir(Chi_10,Chi_10); \
|
||||||
permute##dir(Chi_11,Chi_11);\
|
permute##dir(Chi_11,Chi_11);\
|
||||||
permute##dir(Chi_12,Chi_12);
|
permute##dir(Chi_12,Chi_12);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LOAD_CHI \
|
||||||
|
{const SiteHalfSpinor &ref(buf[offset]); \
|
||||||
|
Chi_00 = coalescedRead(ref()(0)(0)); \
|
||||||
|
Chi_01 = coalescedRead(ref()(0)(1)); \
|
||||||
|
Chi_02 = coalescedRead(ref()(0)(2)); \
|
||||||
|
Chi_10 = coalescedRead(ref()(1)(0)); \
|
||||||
|
Chi_11 = coalescedRead(ref()(1)(1)); \
|
||||||
|
Chi_12 = coalescedRead(ref()(1)(2));}
|
||||||
|
|
||||||
|
#define MULT_2SPIN(A)\
|
||||||
|
{auto & ref(U[sU](A)); \
|
||||||
|
U_00=coalescedRead(ref()(0,0)); \
|
||||||
|
U_10=coalescedRead(ref()(1,0)); \
|
||||||
|
U_20=coalescedRead(ref()(2,0)); \
|
||||||
|
U_01=coalescedRead(ref()(0,1)); \
|
||||||
|
U_11=coalescedRead(ref()(1,1)); \
|
||||||
|
U_21=coalescedRead(ref()(2,1)); \
|
||||||
|
UChi_00 = U_00*Chi_00; \
|
||||||
|
UChi_10 = U_00*Chi_10; \
|
||||||
|
UChi_01 = U_10*Chi_00; \
|
||||||
|
UChi_11 = U_10*Chi_10; \
|
||||||
|
UChi_02 = U_20*Chi_00; \
|
||||||
|
UChi_12 = U_20*Chi_10; \
|
||||||
|
UChi_00+= U_01*Chi_01; \
|
||||||
|
UChi_10+= U_01*Chi_11; \
|
||||||
|
UChi_01+= U_11*Chi_01; \
|
||||||
|
UChi_11+= U_11*Chi_11; \
|
||||||
|
UChi_02+= U_21*Chi_01; \
|
||||||
|
UChi_12+= U_21*Chi_11; \
|
||||||
|
U_00=coalescedRead(ref()(0,2)); \
|
||||||
|
U_10=coalescedRead(ref()(1,2)); \
|
||||||
|
U_20=coalescedRead(ref()(2,2)); \
|
||||||
|
UChi_00+= U_00*Chi_02; \
|
||||||
|
UChi_10+= U_00*Chi_12; \
|
||||||
|
UChi_01+= U_10*Chi_02; \
|
||||||
|
UChi_11+= U_10*Chi_12; \
|
||||||
|
UChi_02+= U_20*Chi_02; \
|
||||||
|
UChi_12+= U_20*Chi_12;}
|
||||||
|
|
||||||
// hspin(0)=fspin(0)+timesI(fspin(3));
|
// hspin(0)=fspin(0)+timesI(fspin(3));
|
||||||
// hspin(1)=fspin(1)+timesI(fspin(2));
|
// hspin(1)=fspin(1)+timesI(fspin(2));
|
||||||
#define XP_PROJ \
|
#define XP_PROJ \
|
||||||
@ -359,7 +376,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
local = SE->_is_local; \
|
local = SE->_is_local; \
|
||||||
perm = SE->_permute; \
|
perm = SE->_permute; \
|
||||||
if ( local ) { \
|
if ( local ) { \
|
||||||
LOAD_CHIMU; \
|
LOAD_CHIMU(PERM); \
|
||||||
PROJ; \
|
PROJ; \
|
||||||
if ( perm) { \
|
if ( perm) { \
|
||||||
PERMUTE_DIR(PERM); \
|
PERMUTE_DIR(PERM); \
|
||||||
@ -376,7 +393,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
local = SE->_is_local; \
|
local = SE->_is_local; \
|
||||||
perm = SE->_permute; \
|
perm = SE->_permute; \
|
||||||
if ( local ) { \
|
if ( local ) { \
|
||||||
LOAD_CHIMU; \
|
LOAD_CHIMU(PERM); \
|
||||||
PROJ; \
|
PROJ; \
|
||||||
if ( perm) { \
|
if ( perm) { \
|
||||||
PERMUTE_DIR(PERM); \
|
PERMUTE_DIR(PERM); \
|
||||||
@ -401,40 +418,39 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
|
|
||||||
#define HAND_RESULT(ss) \
|
#define HAND_RESULT(ss) \
|
||||||
{ \
|
{ \
|
||||||
SiteSpinor & ref (out[ss]); \
|
SiteSpinor & ref (out[ss]); \
|
||||||
vstream(ref()(0)(0),result_00); \
|
coalescedWrite(ref()(0)(0),result_00); \
|
||||||
vstream(ref()(0)(1),result_01); \
|
coalescedWrite(ref()(0)(1),result_01); \
|
||||||
vstream(ref()(0)(2),result_02); \
|
coalescedWrite(ref()(0)(2),result_02); \
|
||||||
vstream(ref()(1)(0),result_10); \
|
coalescedWrite(ref()(1)(0),result_10); \
|
||||||
vstream(ref()(1)(1),result_11); \
|
coalescedWrite(ref()(1)(1),result_11); \
|
||||||
vstream(ref()(1)(2),result_12); \
|
coalescedWrite(ref()(1)(2),result_12); \
|
||||||
vstream(ref()(2)(0),result_20); \
|
coalescedWrite(ref()(2)(0),result_20); \
|
||||||
vstream(ref()(2)(1),result_21); \
|
coalescedWrite(ref()(2)(1),result_21); \
|
||||||
vstream(ref()(2)(2),result_22); \
|
coalescedWrite(ref()(2)(2),result_22); \
|
||||||
vstream(ref()(3)(0),result_30); \
|
coalescedWrite(ref()(3)(0),result_30); \
|
||||||
vstream(ref()(3)(1),result_31); \
|
coalescedWrite(ref()(3)(1),result_31); \
|
||||||
vstream(ref()(3)(2),result_32); \
|
coalescedWrite(ref()(3)(2),result_32); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HAND_RESULT_EXT(ss) \
|
#define HAND_RESULT_EXT(ss) \
|
||||||
if (nmu){ \
|
{ \
|
||||||
SiteSpinor & ref (out[ss]); \
|
SiteSpinor & ref (out[ss]); \
|
||||||
ref()(0)(0)+=result_00; \
|
coalescedWrite(ref()(0)(0),coalescedRead(ref()(0)(0))+result_00); \
|
||||||
ref()(0)(1)+=result_01; \
|
coalescedWrite(ref()(0)(1),coalescedRead(ref()(0)(1))+result_01); \
|
||||||
ref()(0)(2)+=result_02; \
|
coalescedWrite(ref()(0)(2),coalescedRead(ref()(0)(2))+result_02); \
|
||||||
ref()(1)(0)+=result_10; \
|
coalescedWrite(ref()(1)(0),coalescedRead(ref()(1)(0))+result_10); \
|
||||||
ref()(1)(1)+=result_11; \
|
coalescedWrite(ref()(1)(1),coalescedRead(ref()(1)(1))+result_11); \
|
||||||
ref()(1)(2)+=result_12; \
|
coalescedWrite(ref()(1)(2),coalescedRead(ref()(1)(2))+result_12); \
|
||||||
ref()(2)(0)+=result_20; \
|
coalescedWrite(ref()(2)(0),coalescedRead(ref()(2)(0))+result_20); \
|
||||||
ref()(2)(1)+=result_21; \
|
coalescedWrite(ref()(2)(1),coalescedRead(ref()(2)(1))+result_21); \
|
||||||
ref()(2)(2)+=result_22; \
|
coalescedWrite(ref()(2)(2),coalescedRead(ref()(2)(2))+result_22); \
|
||||||
ref()(3)(0)+=result_30; \
|
coalescedWrite(ref()(3)(0),coalescedRead(ref()(3)(0))+result_30); \
|
||||||
ref()(3)(1)+=result_31; \
|
coalescedWrite(ref()(3)(1),coalescedRead(ref()(3)(1))+result_31); \
|
||||||
ref()(3)(2)+=result_32; \
|
coalescedWrite(ref()(3)(2),coalescedRead(ref()(3)(2))+result_32); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define HAND_DECLARATIONS(Simd) \
|
||||||
#define HAND_DECLARATIONS(a) \
|
|
||||||
Simd result_00; \
|
Simd result_00; \
|
||||||
Simd result_01; \
|
Simd result_01; \
|
||||||
Simd result_02; \
|
Simd result_02; \
|
||||||
@ -466,19 +482,19 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
Simd U_11; \
|
Simd U_11; \
|
||||||
Simd U_21;
|
Simd U_21;
|
||||||
|
|
||||||
#define ZERO_RESULT \
|
#define ZERO_RESULT \
|
||||||
result_00=Zero(); \
|
zeroit(result_00); \
|
||||||
result_01=Zero(); \
|
zeroit(result_01); \
|
||||||
result_02=Zero(); \
|
zeroit(result_02); \
|
||||||
result_10=Zero(); \
|
zeroit(result_10); \
|
||||||
result_11=Zero(); \
|
zeroit(result_11); \
|
||||||
result_12=Zero(); \
|
zeroit(result_12); \
|
||||||
result_20=Zero(); \
|
zeroit(result_20); \
|
||||||
result_21=Zero(); \
|
zeroit(result_21); \
|
||||||
result_22=Zero(); \
|
zeroit(result_22); \
|
||||||
result_30=Zero(); \
|
zeroit(result_30); \
|
||||||
result_31=Zero(); \
|
zeroit(result_31); \
|
||||||
result_32=Zero();
|
zeroit(result_32);
|
||||||
|
|
||||||
#define Chimu_00 Chi_00
|
#define Chimu_00 Chi_00
|
||||||
#define Chimu_01 Chi_01
|
#define Chimu_01 Chi_01
|
||||||
@ -502,8 +518,8 @@ WilsonKernels<Impl>::HandDhopSite(StencilView &st, DoubledGaugeFieldView &U,Site
|
|||||||
// T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc...
|
// T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc...
|
||||||
typedef typename Simd::scalar_type S;
|
typedef typename Simd::scalar_type S;
|
||||||
typedef typename Simd::vector_type V;
|
typedef typename Simd::vector_type V;
|
||||||
|
typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt;
|
||||||
HAND_DECLARATIONS(ignore);
|
HAND_DECLARATIONS(Simt);
|
||||||
|
|
||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
@ -525,8 +541,8 @@ void WilsonKernels<Impl>::HandDhopSiteDag(StencilView &st,DoubledGaugeFieldView
|
|||||||
{
|
{
|
||||||
typedef typename Simd::scalar_type S;
|
typedef typename Simd::scalar_type S;
|
||||||
typedef typename Simd::vector_type V;
|
typedef typename Simd::vector_type V;
|
||||||
|
typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt;
|
||||||
HAND_DECLARATIONS(ignore);
|
HAND_DECLARATIONS(Simt);
|
||||||
|
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
@ -549,8 +565,8 @@ WilsonKernels<Impl>::HandDhopSiteInt(StencilView &st,DoubledGaugeFieldView &U,Si
|
|||||||
// T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc...
|
// T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc...
|
||||||
typedef typename Simd::scalar_type S;
|
typedef typename Simd::scalar_type S;
|
||||||
typedef typename Simd::vector_type V;
|
typedef typename Simd::vector_type V;
|
||||||
|
typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt;
|
||||||
HAND_DECLARATIONS(ignore);
|
HAND_DECLARATIONS(Simt);
|
||||||
|
|
||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
@ -572,8 +588,8 @@ void WilsonKernels<Impl>::HandDhopSiteDagInt(StencilView &st,DoubledGaugeFieldVi
|
|||||||
{
|
{
|
||||||
typedef typename Simd::scalar_type S;
|
typedef typename Simd::scalar_type S;
|
||||||
typedef typename Simd::vector_type V;
|
typedef typename Simd::vector_type V;
|
||||||
|
typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt;
|
||||||
HAND_DECLARATIONS(ignore);
|
HAND_DECLARATIONS(Simt);
|
||||||
|
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
int offset,local,perm, ptype;
|
int offset,local,perm, ptype;
|
||||||
@ -596,8 +612,8 @@ WilsonKernels<Impl>::HandDhopSiteExt(StencilView &st,DoubledGaugeFieldView &U,Si
|
|||||||
// T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc...
|
// T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc...
|
||||||
typedef typename Simd::scalar_type S;
|
typedef typename Simd::scalar_type S;
|
||||||
typedef typename Simd::vector_type V;
|
typedef typename Simd::vector_type V;
|
||||||
|
typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt;
|
||||||
HAND_DECLARATIONS(ignore);
|
HAND_DECLARATIONS(Simt);
|
||||||
|
|
||||||
int offset, ptype;
|
int offset, ptype;
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
@ -620,8 +636,8 @@ void WilsonKernels<Impl>::HandDhopSiteDagExt(StencilView &st,DoubledGaugeFieldVi
|
|||||||
{
|
{
|
||||||
typedef typename Simd::scalar_type S;
|
typedef typename Simd::scalar_type S;
|
||||||
typedef typename Simd::vector_type V;
|
typedef typename Simd::vector_type V;
|
||||||
|
typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt;
|
||||||
HAND_DECLARATIONS(ignore);
|
HAND_DECLARATIONS(Simt);
|
||||||
|
|
||||||
StencilEntry *SE;
|
StencilEntry *SE;
|
||||||
int offset, ptype;
|
int offset, ptype;
|
||||||
@ -682,3 +698,4 @@ NAMESPACE_END(Grid);
|
|||||||
#undef HAND_RESULT
|
#undef HAND_RESULT
|
||||||
#undef HAND_RESULT_INT
|
#undef HAND_RESULT_INT
|
||||||
#undef HAND_RESULT_EXT
|
#undef HAND_RESULT_EXT
|
||||||
|
#undef HAND_DECLARATIONS
|
||||||
|
@ -445,20 +445,20 @@ void WilsonKernels<Impl>::DhopKernel(int Opt,StencilImpl &st, DoubledGaugeField
|
|||||||
|
|
||||||
if( interior && exterior ) {
|
if( interior && exterior ) {
|
||||||
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSite); return;}
|
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSite); return;}
|
||||||
#ifndef GRID_CUDA
|
|
||||||
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSite); return;}
|
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSite); return;}
|
||||||
|
#ifndef GRID_CUDA
|
||||||
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSite); return;}
|
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSite); return;}
|
||||||
#endif
|
#endif
|
||||||
} else if( interior ) {
|
} else if( interior ) {
|
||||||
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALLNB(GenericDhopSiteInt); return;}
|
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALLNB(GenericDhopSiteInt); return;}
|
||||||
#ifndef GRID_CUDA
|
|
||||||
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALLNB(HandDhopSiteInt); return;}
|
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALLNB(HandDhopSiteInt); return;}
|
||||||
|
#ifndef GRID_CUDA
|
||||||
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteInt); return;}
|
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteInt); return;}
|
||||||
#endif
|
#endif
|
||||||
} else if( exterior ) {
|
} else if( exterior ) {
|
||||||
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSiteExt); return;}
|
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSiteExt); return;}
|
||||||
#ifndef GRID_CUDA
|
|
||||||
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteExt); return;}
|
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteExt); return;}
|
||||||
|
#ifndef GRID_CUDA
|
||||||
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteExt); return;}
|
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteExt); return;}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -476,20 +476,20 @@ void WilsonKernels<Impl>::DhopKernel(int Opt,StencilImpl &st, DoubledGaugeField
|
|||||||
|
|
||||||
if( interior && exterior ) {
|
if( interior && exterior ) {
|
||||||
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSiteDag); return;}
|
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSiteDag); return;}
|
||||||
#ifndef GRID_CUDA
|
|
||||||
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDag); return;}
|
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDag); return;}
|
||||||
|
#ifndef GRID_CUDA
|
||||||
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteDag); return;}
|
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteDag); return;}
|
||||||
#endif
|
#endif
|
||||||
} else if( interior ) {
|
} else if( interior ) {
|
||||||
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSiteDagInt); return;}
|
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSiteDagInt); return;}
|
||||||
#ifndef GRID_CUDA
|
|
||||||
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDagInt); return;}
|
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDagInt); return;}
|
||||||
|
#ifndef GRID_CUDA
|
||||||
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteDagInt); return;}
|
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteDagInt); return;}
|
||||||
#endif
|
#endif
|
||||||
} else if( exterior ) {
|
} else if( exterior ) {
|
||||||
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSiteDagExt); return;}
|
if (Opt == WilsonKernelsStatic::OptGeneric ) { KERNEL_CALL(GenericDhopSiteDagExt); return;}
|
||||||
#ifndef GRID_CUDA
|
|
||||||
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDagExt); return;}
|
if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDagExt); return;}
|
||||||
|
#ifndef GRID_CUDA
|
||||||
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteDagExt); return;}
|
if (Opt == WilsonKernelsStatic::OptInlineAsm ) { ASM_CALL(AsmDhopSiteDagExt); return;}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ public:
|
|||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// Move these to another class
|
// Move these to another class
|
||||||
// HMC auxiliary functions
|
// HMC auxiliary functions
|
||||||
static inline void generate_momenta(Field &P, GridParallelRNG &pRNG)
|
static inline void generate_momenta(Field &P, GridSerialRNG & sRNG, GridParallelRNG &pRNG)
|
||||||
{
|
{
|
||||||
// Zbigniew Srocinsky thesis:
|
// Zbigniew Srocinsky thesis:
|
||||||
//
|
//
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
|
|
||||||
virtual std::string action_name(){return "PlaqPlusRectangleAction";}
|
virtual std::string action_name(){return "PlaqPlusRectangleAction";}
|
||||||
|
|
||||||
virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {}; // noop as no pseudoferms
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) {}; // noop as no pseudoferms
|
||||||
|
|
||||||
virtual std::string LogParameters(){
|
virtual std::string LogParameters(){
|
||||||
std::stringstream sstream;
|
std::stringstream sstream;
|
||||||
|
@ -54,8 +54,7 @@ public:
|
|||||||
return sstream.str();
|
return sstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void refresh(const GaugeField &U,
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG &pRNG){}; // noop as no pseudoferms
|
||||||
GridParallelRNG &pRNG){}; // noop as no pseudoferms
|
|
||||||
|
|
||||||
virtual RealD S(const GaugeField &U) {
|
virtual RealD S(const GaugeField &U) {
|
||||||
RealD plaq = WilsonLoops<Gimpl>::avgPlaquette(U);
|
RealD plaq = WilsonLoops<Gimpl>::avgPlaquette(U);
|
||||||
|
@ -124,7 +124,7 @@ NAMESPACE_BEGIN(Grid);
|
|||||||
//
|
//
|
||||||
// As a check of rational require \Phi^dag M_{EOFA} \Phi == eta^dag M^-1/2^dag M M^-1/2 eta = eta^dag eta
|
// As a check of rational require \Phi^dag M_{EOFA} \Phi == eta^dag M^-1/2^dag M M^-1/2 eta = eta^dag eta
|
||||||
//
|
//
|
||||||
virtual void refresh(const GaugeField& U, GridParallelRNG& pRNG)
|
virtual void refresh(const GaugeField& U, GridSerialRNG &sRNG, GridParallelRNG& pRNG)
|
||||||
{
|
{
|
||||||
Lop.ImportGauge(U);
|
Lop.ImportGauge(U);
|
||||||
Rop.ImportGauge(U);
|
Rop.ImportGauge(U);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/*************************************************************************************
|
/*************************************************************************************
|
||||||
|
|
||||||
Grid physics library, www.github.com/paboyle/Grid
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
@ -43,8 +42,7 @@ NAMESPACE_BEGIN(Grid);
|
|||||||
//
|
//
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
class OneFlavourEvenOddRationalPseudoFermionAction
|
class OneFlavourEvenOddRationalPseudoFermionAction : public Action<typename Impl::GaugeField> {
|
||||||
: public Action<typename Impl::GaugeField> {
|
|
||||||
public:
|
public:
|
||||||
INHERIT_IMPL_TYPES(Impl);
|
INHERIT_IMPL_TYPES(Impl);
|
||||||
|
|
||||||
@ -103,7 +101,7 @@ public:
|
|||||||
return sstream.str();
|
return sstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) {
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG &pRNG) {
|
||||||
// P(phi) = e^{- phi^dag (MpcdagMpc)^-1/2 phi}
|
// P(phi) = e^{- phi^dag (MpcdagMpc)^-1/2 phi}
|
||||||
// = e^{- phi^dag (MpcdagMpc)^-1/4 (MpcdagMpc)^-1/4 phi}
|
// = e^{- phi^dag (MpcdagMpc)^-1/4 (MpcdagMpc)^-1/4 phi}
|
||||||
// Phi = MpcdagMpc^{1/4} eta
|
// Phi = MpcdagMpc^{1/4} eta
|
||||||
@ -156,7 +154,10 @@ public:
|
|||||||
|
|
||||||
msCG(Mpc, PhiOdd, Y);
|
msCG(Mpc, PhiOdd, Y);
|
||||||
|
|
||||||
if ( (rand()%param.BoundsCheckFreq)==0 ) {
|
auto grid = FermOp.FermionGrid();
|
||||||
|
auto r=rand();
|
||||||
|
grid->Broadcast(0,r);
|
||||||
|
if ( (r%param.BoundsCheckFreq)==0 ) {
|
||||||
FermionField gauss(FermOp.FermionRedBlackGrid());
|
FermionField gauss(FermOp.FermionRedBlackGrid());
|
||||||
gauss = PhiOdd;
|
gauss = PhiOdd;
|
||||||
HighBoundCheck(Mpc,gauss,param.hi);
|
HighBoundCheck(Mpc,gauss,param.hi);
|
||||||
|
@ -101,7 +101,7 @@ NAMESPACE_BEGIN(Grid);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) {
|
||||||
|
|
||||||
// S_f = chi^dag* P(V^dag*V)/Q(V^dag*V)* N(M^dag*M)/D(M^dag*M)* P(V^dag*V)/Q(V^dag*V)* chi
|
// S_f = chi^dag* P(V^dag*V)/Q(V^dag*V)* N(M^dag*M)/D(M^dag*M)* P(V^dag*V)/Q(V^dag*V)* chi
|
||||||
//
|
//
|
||||||
@ -170,7 +170,10 @@ NAMESPACE_BEGIN(Grid);
|
|||||||
msCG_M(MdagM,X,Y);
|
msCG_M(MdagM,X,Y);
|
||||||
|
|
||||||
// Randomly apply rational bounds checks.
|
// Randomly apply rational bounds checks.
|
||||||
if ( (rand()%param.BoundsCheckFreq)==0 ) {
|
auto grid = NumOp.FermionGrid();
|
||||||
|
auto r=rand();
|
||||||
|
grid->Broadcast(0,r);
|
||||||
|
if ( (r%param.BoundsCheckFreq)==0 ) {
|
||||||
FermionField gauss(NumOp.FermionRedBlackGrid());
|
FermionField gauss(NumOp.FermionRedBlackGrid());
|
||||||
gauss = PhiOdd;
|
gauss = PhiOdd;
|
||||||
HighBoundCheck(MdagM,gauss,param.hi);
|
HighBoundCheck(MdagM,gauss,param.hi);
|
||||||
|
@ -98,7 +98,7 @@ NAMESPACE_BEGIN(Grid);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) {
|
||||||
|
|
||||||
|
|
||||||
// P(phi) = e^{- phi^dag (MdagM)^-1/2 phi}
|
// P(phi) = e^{- phi^dag (MdagM)^-1/2 phi}
|
||||||
@ -142,7 +142,10 @@ NAMESPACE_BEGIN(Grid);
|
|||||||
|
|
||||||
msCG(MdagMOp,Phi,Y);
|
msCG(MdagMOp,Phi,Y);
|
||||||
|
|
||||||
if ( (rand()%param.BoundsCheckFreq)==0 ) {
|
auto grid = FermOp.FermionGrid();
|
||||||
|
auto r=rand();
|
||||||
|
grid->Broadcast(0,r);
|
||||||
|
if ( (r%param.BoundsCheckFreq)==0 ) {
|
||||||
FermionField gauss(FermOp.FermionGrid());
|
FermionField gauss(FermOp.FermionGrid());
|
||||||
gauss = Phi;
|
gauss = Phi;
|
||||||
HighBoundCheck(MdagMOp,gauss,param.hi);
|
HighBoundCheck(MdagMOp,gauss,param.hi);
|
||||||
|
@ -95,7 +95,7 @@ NAMESPACE_BEGIN(Grid);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) {
|
||||||
|
|
||||||
// S_f = chi^dag* P(V^dag*V)/Q(V^dag*V)* N(M^dag*M)/D(M^dag*M)* P(V^dag*V)/Q(V^dag*V)* chi
|
// S_f = chi^dag* P(V^dag*V)/Q(V^dag*V)* N(M^dag*M)/D(M^dag*M)* P(V^dag*V)/Q(V^dag*V)* chi
|
||||||
//
|
//
|
||||||
@ -156,7 +156,10 @@ NAMESPACE_BEGIN(Grid);
|
|||||||
msCG_M(MdagM,X,Y);
|
msCG_M(MdagM,X,Y);
|
||||||
|
|
||||||
// Randomly apply rational bounds checks.
|
// Randomly apply rational bounds checks.
|
||||||
if ( (rand()%param.BoundsCheckFreq)==0 ) {
|
auto grid = NumOp.FermionGrid();
|
||||||
|
auto r=rand();
|
||||||
|
grid->Broadcast(0,r);
|
||||||
|
if ( (r%param.BoundsCheckFreq)==0 ) {
|
||||||
FermionField gauss(NumOp.FermionGrid());
|
FermionField gauss(NumOp.FermionGrid());
|
||||||
gauss = Phi;
|
gauss = Phi;
|
||||||
HighBoundCheck(MdagM,gauss,param.hi);
|
HighBoundCheck(MdagM,gauss,param.hi);
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Push the gauge field in to the dops. Assume any BC's and smearing already applied
|
// Push the gauge field in to the dops. Assume any BC's and smearing already applied
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) {
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG &pRNG) {
|
||||||
// P(phi) = e^{- phi^dag (MdagM)^-1 phi}
|
// P(phi) = e^{- phi^dag (MdagM)^-1 phi}
|
||||||
// Phi = Mdag eta
|
// Phi = Mdag eta
|
||||||
// P(eta) = e^{- eta^dag eta}
|
// P(eta) = e^{- eta^dag eta}
|
||||||
|
@ -77,7 +77,7 @@ public:
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Push the gauge field in to the dops. Assume any BC's and smearing already applied
|
// Push the gauge field in to the dops. Assume any BC's and smearing already applied
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) {
|
||||||
|
|
||||||
// P(phi) = e^{- phi^dag (MpcdagMpc)^-1 phi}
|
// P(phi) = e^{- phi^dag (MpcdagMpc)^-1 phi}
|
||||||
// Phi = McpDag eta
|
// Phi = McpDag eta
|
||||||
|
@ -84,7 +84,7 @@ NAMESPACE_BEGIN(Grid);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) {
|
||||||
|
|
||||||
// P(phi) = e^{- phi^dag Vpc (MpcdagMpc)^-1 Vpcdag phi}
|
// P(phi) = e^{- phi^dag Vpc (MpcdagMpc)^-1 Vpcdag phi}
|
||||||
//
|
//
|
||||||
|
@ -64,7 +64,7 @@ public:
|
|||||||
return sstream.str();
|
return sstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {
|
virtual void refresh(const GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) {
|
||||||
|
|
||||||
// P(phi) = e^{- phi^dag V (MdagM)^-1 Vdag phi}
|
// P(phi) = e^{- phi^dag V (MdagM)^-1 Vdag phi}
|
||||||
//
|
//
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual std::string action_name() {return "ScalarAction";}
|
virtual std::string action_name() {return "ScalarAction";}
|
||||||
|
|
||||||
virtual void refresh(const Field &U, GridParallelRNG &pRNG) {} // noop as no pseudoferms
|
virtual void refresh(const Field &U, GridSerialRNG &sRNG, GridParallelRNG &pRNG) {} // noop as no pseudoferms
|
||||||
|
|
||||||
virtual RealD S(const Field &p) {
|
virtual RealD S(const Field &p) {
|
||||||
return (mass_square * 0.5 + Nd) * ScalarObs<Impl>::sumphisquared(p) +
|
return (mass_square * 0.5 + Nd) * ScalarObs<Impl>::sumphisquared(p) +
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
typedef Field FermionField;
|
typedef Field FermionField;
|
||||||
typedef Field PropagatorField;
|
typedef Field PropagatorField;
|
||||||
|
|
||||||
static inline void generate_momenta(Field& P, GridParallelRNG& pRNG){
|
static inline void generate_momenta(Field& P, GridSerialRNG &sRNG, GridParallelRNG& pRNG){
|
||||||
RealD scale = ::sqrt(HMC_MOMENTUM_DENOMINATOR); // CPS/UKQCD momentum rescaling
|
RealD scale = ::sqrt(HMC_MOMENTUM_DENOMINATOR); // CPS/UKQCD momentum rescaling
|
||||||
gaussian(pRNG, P);
|
gaussian(pRNG, P);
|
||||||
P *= scale;
|
P *= scale;
|
||||||
@ -151,7 +151,7 @@ public:
|
|||||||
out = one / out;
|
out = one / out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void generate_momenta(Field &P, GridParallelRNG &pRNG)
|
static inline void generate_momenta(Field &P, GridSerialRNG & sRNG, GridParallelRNG &pRNG)
|
||||||
{
|
{
|
||||||
RealD scale = ::sqrt(HMC_MOMENTUM_DENOMINATOR); // CPS/UKQCD momentum rescaling
|
RealD scale = ::sqrt(HMC_MOMENTUM_DENOMINATOR); // CPS/UKQCD momentum rescaling
|
||||||
#ifndef USE_FFT_ACCELERATION
|
#ifndef USE_FFT_ACCELERATION
|
||||||
|
@ -77,7 +77,7 @@ public:
|
|||||||
|
|
||||||
virtual std::string action_name() { return "ScalarAction"; }
|
virtual std::string action_name() { return "ScalarAction"; }
|
||||||
|
|
||||||
virtual void refresh(const Field &U, GridParallelRNG &pRNG) {}
|
virtual void refresh(const Field &U, GridSerialRNG & sRNG, GridParallelRNG &pRNG) {}
|
||||||
|
|
||||||
virtual RealD S(const Field &p)
|
virtual RealD S(const Field &p)
|
||||||
{
|
{
|
||||||
|
@ -139,7 +139,7 @@ private:
|
|||||||
// Evolution
|
// Evolution
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
RealD evolve_hmc_step(Field &U) {
|
RealD evolve_hmc_step(Field &U) {
|
||||||
TheIntegrator.refresh(U, pRNG); // set U and initialize P and phi's
|
TheIntegrator.refresh(U, sRNG, pRNG); // set U and initialize P and phi's
|
||||||
|
|
||||||
RealD H0 = TheIntegrator.S(U); // initial state action
|
RealD H0 = TheIntegrator.S(U); // initial state action
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ directory
|
|||||||
#define INTEGRATOR_INCLUDED
|
#define INTEGRATOR_INCLUDED
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "MomentumFilter.h"
|
||||||
|
|
||||||
NAMESPACE_BEGIN(Grid);
|
NAMESPACE_BEGIN(Grid);
|
||||||
|
|
||||||
@ -78,8 +79,19 @@ protected:
|
|||||||
RepresentationPolicy Representations;
|
RepresentationPolicy Representations;
|
||||||
IntegratorParameters Params;
|
IntegratorParameters Params;
|
||||||
|
|
||||||
|
//Filters allow the user to manipulate the conjugate momentum, for example to freeze links in DDHMC
|
||||||
|
//It is applied whenever the momentum is updated / refreshed
|
||||||
|
//The default filter does nothing
|
||||||
|
MomentumFilterBase<MomentaField> const* MomFilter;
|
||||||
|
|
||||||
const ActionSet<Field, RepresentationPolicy> as;
|
const ActionSet<Field, RepresentationPolicy> as;
|
||||||
|
|
||||||
|
//Get a pointer to a shared static instance of the "do-nothing" momentum filter to serve as a default
|
||||||
|
static MomentumFilterBase<MomentaField> const* getDefaultMomFilter(){
|
||||||
|
static MomentumFilterNone<MomentaField> filter;
|
||||||
|
return &filter;
|
||||||
|
}
|
||||||
|
|
||||||
void update_P(Field& U, int level, double ep)
|
void update_P(Field& U, int level, double ep)
|
||||||
{
|
{
|
||||||
t_P[level] += ep;
|
t_P[level] += ep;
|
||||||
@ -135,6 +147,8 @@ protected:
|
|||||||
|
|
||||||
// Force from the other representations
|
// Force from the other representations
|
||||||
as[level].apply(update_P_hireps, Representations, Mom, U, ep);
|
as[level].apply(update_P_hireps, Representations, Mom, U, ep);
|
||||||
|
|
||||||
|
MomFilter->applyFilter(Mom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_U(Field& U, double ep)
|
void update_U(Field& U, double ep)
|
||||||
@ -174,11 +188,23 @@ public:
|
|||||||
t_P.resize(levels, 0.0);
|
t_P.resize(levels, 0.0);
|
||||||
t_U = 0.0;
|
t_U = 0.0;
|
||||||
// initialization of smearer delegated outside of Integrator
|
// initialization of smearer delegated outside of Integrator
|
||||||
|
|
||||||
|
//Default the momentum filter to "do-nothing"
|
||||||
|
MomFilter = getDefaultMomFilter();
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~Integrator() {}
|
virtual ~Integrator() {}
|
||||||
|
|
||||||
virtual std::string integrator_name() = 0;
|
virtual std::string integrator_name() = 0;
|
||||||
|
|
||||||
|
//Set the momentum filter allowing for manipulation of the conjugate momentum
|
||||||
|
void setMomentumFilter(const MomentumFilterBase<MomentaField> &filter){
|
||||||
|
MomFilter = &filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Access the conjugate momentum
|
||||||
|
const MomentaField & getMomentum() const{ return P; }
|
||||||
|
|
||||||
|
|
||||||
void print_parameters()
|
void print_parameters()
|
||||||
{
|
{
|
||||||
@ -210,10 +236,9 @@ public:
|
|||||||
// over the representations
|
// over the representations
|
||||||
struct _refresh {
|
struct _refresh {
|
||||||
template <class FieldType, class Repr>
|
template <class FieldType, class Repr>
|
||||||
void operator()(std::vector<Action<FieldType>*> repr_set, Repr& Rep,
|
void operator()(std::vector<Action<FieldType>*> repr_set, Repr& Rep, GridSerialRNG & sRNG, GridParallelRNG& pRNG) {
|
||||||
GridParallelRNG& pRNG) {
|
|
||||||
for (int a = 0; a < repr_set.size(); ++a){
|
for (int a = 0; a < repr_set.size(); ++a){
|
||||||
repr_set.at(a)->refresh(Rep.U, pRNG);
|
repr_set.at(a)->refresh(Rep.U, sRNG, pRNG);
|
||||||
|
|
||||||
std::cout << GridLogDebug << "Hirep refreshing pseudofermions" << std::endl;
|
std::cout << GridLogDebug << "Hirep refreshing pseudofermions" << std::endl;
|
||||||
}
|
}
|
||||||
@ -221,12 +246,12 @@ public:
|
|||||||
} refresh_hireps{};
|
} refresh_hireps{};
|
||||||
|
|
||||||
// Initialization of momenta and actions
|
// Initialization of momenta and actions
|
||||||
void refresh(Field& U, GridParallelRNG& pRNG)
|
void refresh(Field& U, GridSerialRNG & sRNG, GridParallelRNG& pRNG)
|
||||||
{
|
{
|
||||||
assert(P.Grid() == U.Grid());
|
assert(P.Grid() == U.Grid());
|
||||||
std::cout << GridLogIntegrator << "Integrator refresh\n";
|
std::cout << GridLogIntegrator << "Integrator refresh\n";
|
||||||
|
|
||||||
FieldImplementation::generate_momenta(P, pRNG);
|
FieldImplementation::generate_momenta(P, sRNG, pRNG);
|
||||||
|
|
||||||
// Update the smeared fields, can be implemented as observer
|
// Update the smeared fields, can be implemented as observer
|
||||||
// necessary to keep the fields updated even after a reject
|
// necessary to keep the fields updated even after a reject
|
||||||
@ -243,12 +268,14 @@ public:
|
|||||||
// get gauge field from the SmearingPolicy and
|
// get gauge field from the SmearingPolicy and
|
||||||
// based on the boolean is_smeared in actionID
|
// based on the boolean is_smeared in actionID
|
||||||
Field& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
|
Field& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
|
||||||
as[level].actions.at(actionID)->refresh(Us, pRNG);
|
as[level].actions.at(actionID)->refresh(Us, sRNG, pRNG);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh the higher representation actions
|
// Refresh the higher representation actions
|
||||||
as[level].apply(refresh_hireps, Representations, pRNG);
|
as[level].apply(refresh_hireps, Representations, sRNG, pRNG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MomFilter->applyFilter(P);
|
||||||
}
|
}
|
||||||
|
|
||||||
// to be used by the actionlevel class to iterate
|
// to be used by the actionlevel class to iterate
|
||||||
|
94
Grid/qcd/hmc/integrators/MomentumFilter.h
Normal file
94
Grid/qcd/hmc/integrators/MomentumFilter.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./lib/qcd/hmc/integrators/MomentumFilter.h
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Christopher Kelly <ckelly@bnl.gov>
|
||||||
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution
|
||||||
|
directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
#ifndef MOMENTUM_FILTER
|
||||||
|
#define MOMENTUM_FILTER
|
||||||
|
|
||||||
|
NAMESPACE_BEGIN(Grid);
|
||||||
|
|
||||||
|
//These filter objects allow the user to manipulate the conjugate momentum as part of the update / refresh
|
||||||
|
|
||||||
|
template<typename MomentaField>
|
||||||
|
struct MomentumFilterBase{
|
||||||
|
virtual void applyFilter(MomentaField &P) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Do nothing
|
||||||
|
template<typename MomentaField>
|
||||||
|
struct MomentumFilterNone: public MomentumFilterBase<MomentaField>{
|
||||||
|
void applyFilter(MomentaField &P) const override{}
|
||||||
|
};
|
||||||
|
|
||||||
|
//Multiply each site/direction by a Lorentz vector complex number field
|
||||||
|
//Can be used to implement a mask, zeroing out sites
|
||||||
|
template<typename MomentaField>
|
||||||
|
struct MomentumFilterApplyPhase: public MomentumFilterBase<MomentaField>{
|
||||||
|
typedef typename MomentaField::vector_type vector_type; //SIMD-vectorized complex type
|
||||||
|
typedef typename MomentaField::scalar_type scalar_type; //scalar complex type
|
||||||
|
typedef iVector<iScalar<iScalar<vector_type> >, Nd > LorentzScalarType; //complex phase for each site/direction
|
||||||
|
typedef Lattice<LorentzScalarType> LatticeLorentzScalarType;
|
||||||
|
|
||||||
|
LatticeLorentzScalarType phase;
|
||||||
|
|
||||||
|
MomentumFilterApplyPhase(const LatticeLorentzScalarType _phase): phase(_phase){}
|
||||||
|
|
||||||
|
//Default to uniform field of (1,0)
|
||||||
|
MomentumFilterApplyPhase(GridBase* _grid): phase(_grid){
|
||||||
|
LorentzScalarType one;
|
||||||
|
for(int mu=0;mu<Nd;mu++)
|
||||||
|
one(mu)()() = scalar_type(1.);
|
||||||
|
|
||||||
|
phase = one;
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyFilter(MomentaField &P) const override{
|
||||||
|
conformable(P,phase);
|
||||||
|
autoView( P_v , P, AcceleratorWrite);
|
||||||
|
autoView( phase_v , phase, AcceleratorRead);
|
||||||
|
|
||||||
|
accelerator_for(ss,P_v.size(),MomentaField::vector_type::Nsimd(),{
|
||||||
|
auto site_mom = P_v(ss);
|
||||||
|
auto site_phase = phase_v(ss);
|
||||||
|
for(int mu=0;mu<Nd;mu++)
|
||||||
|
site_mom(mu) = site_mom(mu) * site_phase(mu);
|
||||||
|
coalescedWrite(P_v[ss], site_mom);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NAMESPACE_END(Grid);
|
||||||
|
|
||||||
|
#endif
|
@ -60,11 +60,26 @@ template<class pair>
|
|||||||
class GpuComplex {
|
class GpuComplex {
|
||||||
public:
|
public:
|
||||||
pair z;
|
pair z;
|
||||||
typedef decltype(z.x) real;
|
typedef decltype(z.x) Real;
|
||||||
public:
|
public:
|
||||||
accelerator_inline GpuComplex() = default;
|
accelerator_inline GpuComplex() = default;
|
||||||
accelerator_inline GpuComplex(real re,real im) { z.x=re; z.y=im; };
|
accelerator_inline GpuComplex(Real re,Real im) { z.x=re; z.y=im; };
|
||||||
accelerator_inline GpuComplex(const GpuComplex &zz) { z = zz.z;};
|
accelerator_inline GpuComplex(const GpuComplex &zz) { z = zz.z;};
|
||||||
|
accelerator_inline Real real(void) const { return z.x; };
|
||||||
|
accelerator_inline Real imag(void) const { return z.y; };
|
||||||
|
accelerator_inline GpuComplex &operator=(const Zero &zz) { z.x = 0; z.y=0; return *this; };
|
||||||
|
accelerator_inline GpuComplex &operator*=(const GpuComplex &r) {
|
||||||
|
*this = (*this) * r;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
accelerator_inline GpuComplex &operator+=(const GpuComplex &r) {
|
||||||
|
*this = (*this) + r;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
accelerator_inline GpuComplex &operator-=(const GpuComplex &r) {
|
||||||
|
*this = (*this) - r;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
friend accelerator_inline GpuComplex operator+(const GpuComplex &lhs,const GpuComplex &rhs) {
|
friend accelerator_inline GpuComplex operator+(const GpuComplex &lhs,const GpuComplex &rhs) {
|
||||||
GpuComplex r ;
|
GpuComplex r ;
|
||||||
r.z.x = lhs.z.x + rhs.z.x;
|
r.z.x = lhs.z.x + rhs.z.x;
|
||||||
@ -157,6 +172,11 @@ typedef GpuVector<NSIMD_RealD, double > GpuVectorRD;
|
|||||||
typedef GpuVector<NSIMD_ComplexD, GpuComplexD > GpuVectorCD;
|
typedef GpuVector<NSIMD_ComplexD, GpuComplexD > GpuVectorCD;
|
||||||
typedef GpuVector<NSIMD_Integer, Integer > GpuVectorI;
|
typedef GpuVector<NSIMD_Integer, Integer > GpuVectorI;
|
||||||
|
|
||||||
|
accelerator_inline GpuComplexF timesI(const GpuComplexF &r) { return(GpuComplexF(-r.imag(),r.real()));}
|
||||||
|
accelerator_inline GpuComplexD timesI(const GpuComplexD &r) { return(GpuComplexD(-r.imag(),r.real()));}
|
||||||
|
accelerator_inline GpuComplexF timesMinusI(const GpuComplexF &r){ return(GpuComplexF(r.imag(),-r.real()));}
|
||||||
|
accelerator_inline GpuComplexD timesMinusI(const GpuComplexD &r){ return(GpuComplexD(r.imag(),-r.real()));}
|
||||||
|
|
||||||
accelerator_inline float half2float(half h)
|
accelerator_inline float half2float(half h)
|
||||||
{
|
{
|
||||||
float f;
|
float f;
|
||||||
|
@ -148,10 +148,14 @@ accelerator_inline void sub (ComplexF * __restrict__ y,const ComplexF * __restri
|
|||||||
accelerator_inline void add (ComplexF * __restrict__ y,const ComplexF * __restrict__ l,const ComplexF *__restrict__ r){ *y = (*l) + (*r); }
|
accelerator_inline void add (ComplexF * __restrict__ y,const ComplexF * __restrict__ l,const ComplexF *__restrict__ r){ *y = (*l) + (*r); }
|
||||||
|
|
||||||
//conjugate already supported for complex
|
//conjugate already supported for complex
|
||||||
accelerator_inline ComplexF timesI(const ComplexF &r) { return(r*ComplexF(0.0,1.0));}
|
accelerator_inline ComplexF timesI(const ComplexF &r) { return(ComplexF(-r.imag(),r.real()));}
|
||||||
accelerator_inline ComplexD timesI(const ComplexD &r) { return(r*ComplexD(0.0,1.0));}
|
accelerator_inline ComplexD timesI(const ComplexD &r) { return(ComplexD(-r.imag(),r.real()));}
|
||||||
accelerator_inline ComplexF timesMinusI(const ComplexF &r){ return(r*ComplexF(0.0,-1.0));}
|
accelerator_inline ComplexF timesMinusI(const ComplexF &r){ return(ComplexF(r.imag(),-r.real()));}
|
||||||
accelerator_inline ComplexD timesMinusI(const ComplexD &r){ return(r*ComplexD(0.0,-1.0));}
|
accelerator_inline ComplexD timesMinusI(const ComplexD &r){ return(ComplexD(r.imag(),-r.real()));}
|
||||||
|
//accelerator_inline ComplexF timesI(const ComplexF &r) { return(r*ComplexF(0.0,1.0));}
|
||||||
|
//accelerator_inline ComplexD timesI(const ComplexD &r) { return(r*ComplexD(0.0,1.0));}
|
||||||
|
//accelerator_inline ComplexF timesMinusI(const ComplexF &r){ return(r*ComplexF(0.0,-1.0));}
|
||||||
|
//accelerator_inline ComplexD timesMinusI(const ComplexD &r){ return(r*ComplexD(0.0,-1.0));}
|
||||||
|
|
||||||
// define projections to real and imaginay parts
|
// define projections to real and imaginay parts
|
||||||
accelerator_inline ComplexF projReal(const ComplexF &r){return( ComplexF(r.real(), 0.0));}
|
accelerator_inline ComplexF projReal(const ComplexF &r){return( ComplexF(r.real(), 0.0));}
|
||||||
|
@ -7,20 +7,20 @@ template<class vobj>
|
|||||||
class SimpleCompressor {
|
class SimpleCompressor {
|
||||||
public:
|
public:
|
||||||
void Point(int) {};
|
void Point(int) {};
|
||||||
accelerator_inline int CommDatumSize(void) { return sizeof(vobj); }
|
accelerator_inline int CommDatumSize(void) const { return sizeof(vobj); }
|
||||||
accelerator_inline bool DecompressionStep(void) { return false; }
|
accelerator_inline bool DecompressionStep(void) const { return false; }
|
||||||
template<class cobj> accelerator_inline void Compress(cobj *buf,int o,const cobj &in) { buf[o]=in; }
|
template<class cobj> accelerator_inline void Compress(cobj *buf,int o,const cobj &in) const { buf[o]=in; }
|
||||||
accelerator_inline void Exchange(vobj *mp,vobj *vp0,vobj *vp1,Integer type,Integer o){
|
accelerator_inline void Exchange(vobj *mp,vobj *vp0,vobj *vp1,Integer type,Integer o) const {
|
||||||
exchange(mp[2*o],mp[2*o+1],vp0[o],vp1[o],type);
|
exchange(mp[2*o],mp[2*o+1],vp0[o],vp1[o],type);
|
||||||
}
|
}
|
||||||
accelerator_inline void Decompress(vobj *out,vobj *in, int o){ assert(0); }
|
accelerator_inline void Decompress(vobj *out,vobj *in, int o) const { assert(0); }
|
||||||
accelerator_inline void CompressExchange(vobj *out0,vobj *out1,const vobj *in,
|
accelerator_inline void CompressExchange(vobj *out0,vobj *out1,const vobj *in,
|
||||||
int j,int k, int m,int type){
|
int j,int k, int m,int type) const {
|
||||||
exchange(out0[j],out1[j],in[k],in[m],type);
|
exchange(out0[j],out1[j],in[k],in[m],type);
|
||||||
}
|
}
|
||||||
// For cshift. Cshift should drop compressor coupling altogether
|
// For cshift. Cshift should drop compressor coupling altogether
|
||||||
// because I had to decouple the code from the Stencil anyway
|
// because I had to decouple the code from the Stencil anyway
|
||||||
accelerator_inline vobj operator() (const vobj &arg) {
|
accelerator_inline vobj operator() (const vobj &arg) const {
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -147,16 +147,16 @@ class CartesianStencilAccelerator {
|
|||||||
cobj* u_recv_buf_p;
|
cobj* u_recv_buf_p;
|
||||||
cobj* u_send_buf_p;
|
cobj* u_send_buf_p;
|
||||||
|
|
||||||
accelerator_inline cobj *CommBuf(void) { return u_recv_buf_p; }
|
accelerator_inline cobj *CommBuf(void) const { return u_recv_buf_p; }
|
||||||
|
|
||||||
accelerator_inline int GetNodeLocal(int osite,int point) {
|
accelerator_inline int GetNodeLocal(int osite,int point) const {
|
||||||
return this->_entries_p[point+this->_npoints*osite]._is_local;
|
return this->_entries_p[point+this->_npoints*osite]._is_local;
|
||||||
}
|
}
|
||||||
accelerator_inline StencilEntry * GetEntry(int &ptype,int point,int osite) {
|
accelerator_inline StencilEntry * GetEntry(int &ptype,int point,int osite) const {
|
||||||
ptype = this->_permute_type[point]; return & this->_entries_p[point+this->_npoints*osite];
|
ptype = this->_permute_type[point]; return & this->_entries_p[point+this->_npoints*osite];
|
||||||
}
|
}
|
||||||
|
|
||||||
accelerator_inline uint64_t GetInfo(int &ptype,int &local,int &perm,int point,int ent,uint64_t base) {
|
accelerator_inline uint64_t GetInfo(int &ptype,int &local,int &perm,int point,int ent,uint64_t base) const {
|
||||||
uint64_t cbase = (uint64_t)&u_recv_buf_p[0];
|
uint64_t cbase = (uint64_t)&u_recv_buf_p[0];
|
||||||
local = this->_entries_p[ent]._is_local;
|
local = this->_entries_p[ent]._is_local;
|
||||||
perm = this->_entries_p[ent]._permute;
|
perm = this->_entries_p[ent]._permute;
|
||||||
@ -168,14 +168,14 @@ class CartesianStencilAccelerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
accelerator_inline uint64_t GetPFInfo(int ent,uint64_t base) {
|
accelerator_inline uint64_t GetPFInfo(int ent,uint64_t base) const {
|
||||||
uint64_t cbase = (uint64_t)&u_recv_buf_p[0];
|
uint64_t cbase = (uint64_t)&u_recv_buf_p[0];
|
||||||
int local = this->_entries_p[ent]._is_local;
|
int local = this->_entries_p[ent]._is_local;
|
||||||
if (local) return base + this->_entries_p[ent]._byte_offset;
|
if (local) return base + this->_entries_p[ent]._byte_offset;
|
||||||
else return cbase + this->_entries_p[ent]._byte_offset;
|
else return cbase + this->_entries_p[ent]._byte_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
accelerator_inline void iCoorFromIindex(Coordinate &coor,int lane)
|
accelerator_inline void iCoorFromIindex(Coordinate &coor,int lane) const
|
||||||
{
|
{
|
||||||
Lexicographic::CoorFromIndex(coor,lane,this->_simd_layout);
|
Lexicographic::CoorFromIndex(coor,lane,this->_simd_layout);
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ public:
|
|||||||
typedef typename cobj::vector_type vector_type;
|
typedef typename cobj::vector_type vector_type;
|
||||||
typedef typename cobj::scalar_type scalar_type;
|
typedef typename cobj::scalar_type scalar_type;
|
||||||
typedef typename cobj::scalar_object scalar_object;
|
typedef typename cobj::scalar_object scalar_object;
|
||||||
typedef CartesianStencilView<vobj,cobj,Parameters> View_type;
|
typedef const CartesianStencilView<vobj,cobj,Parameters> View_type;
|
||||||
typedef typename View_type::StencilVector StencilVector;
|
typedef typename View_type::StencilVector StencilVector;
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// Helper structs
|
// Helper structs
|
||||||
|
@ -64,6 +64,70 @@ void coalescedWriteNonTemporal(vobj & __restrict__ vec,const vobj & __restrict__
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GRID_SYCL
|
||||||
|
// Use the scalar as our own complex on GPU ... thrust::complex or std::complex
|
||||||
|
template<class vsimd,IfSimd<vsimd> = 0> accelerator_inline
|
||||||
|
typename vsimd::scalar_type
|
||||||
|
coalescedRead(const vsimd & __restrict__ vec,int lane=acceleratorSIMTlane(vsimd::Nsimd()))
|
||||||
|
{
|
||||||
|
typedef typename vsimd::scalar_type S;
|
||||||
|
S * __restrict__ p=(S *)&vec;
|
||||||
|
return p[lane];
|
||||||
|
}
|
||||||
|
template<int ptype,class vsimd,IfSimd<vsimd> = 0> accelerator_inline
|
||||||
|
typename vsimd::scalar_type
|
||||||
|
coalescedReadPermute(const vsimd & __restrict__ vec,int doperm,int lane=acceleratorSIMTlane(vsimd::Nsimd()))
|
||||||
|
{
|
||||||
|
typedef typename vsimd::scalar_type S;
|
||||||
|
|
||||||
|
S * __restrict__ p=(S *)&vec;
|
||||||
|
int mask = vsimd::Nsimd() >> (ptype + 1);
|
||||||
|
int plane= doperm ? lane ^ mask : lane;
|
||||||
|
return p[plane];
|
||||||
|
}
|
||||||
|
template<class vsimd,IfSimd<vsimd> = 0> accelerator_inline
|
||||||
|
void coalescedWrite(vsimd & __restrict__ vec,
|
||||||
|
const typename vsimd::scalar_type & __restrict__ extracted,
|
||||||
|
int lane=acceleratorSIMTlane(vsimd::Nsimd()))
|
||||||
|
{
|
||||||
|
typedef typename vsimd::scalar_type S;
|
||||||
|
S * __restrict__ p=(S *)&vec;
|
||||||
|
p[lane]=extracted;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// For SyCL have option to use GpuComplex from inside the vector type in SIMT loops
|
||||||
|
// Faster for some reason
|
||||||
|
template<class vsimd,IfSimd<vsimd> = 0> accelerator_inline
|
||||||
|
typename vsimd::vector_type::datum
|
||||||
|
coalescedRead(const vsimd & __restrict__ vec,int lane=acceleratorSIMTlane(vsimd::Nsimd()))
|
||||||
|
{
|
||||||
|
typedef typename vsimd::vector_type::datum S;
|
||||||
|
S * __restrict__ p=(S *)&vec;
|
||||||
|
return p[lane];
|
||||||
|
}
|
||||||
|
template<int ptype,class vsimd,IfSimd<vsimd> = 0> accelerator_inline
|
||||||
|
typename vsimd::vector_type::datum
|
||||||
|
coalescedReadPermute(const vsimd & __restrict__ vec,int doperm,int lane=acceleratorSIMTlane(vsimd::Nsimd()))
|
||||||
|
{
|
||||||
|
typedef typename vsimd::vector_type::datum S;
|
||||||
|
|
||||||
|
S * __restrict__ p=(S *)&vec;
|
||||||
|
int mask = vsimd::Nsimd() >> (ptype + 1);
|
||||||
|
int plane= doperm ? lane ^ mask : lane;
|
||||||
|
return p[plane];
|
||||||
|
}
|
||||||
|
template<class vsimd,IfSimd<vsimd> = 0> accelerator_inline
|
||||||
|
void coalescedWrite(vsimd & __restrict__ vec,
|
||||||
|
const typename vsimd::vector_type::datum & __restrict__ extracted,
|
||||||
|
int lane=acceleratorSIMTlane(vsimd::Nsimd()))
|
||||||
|
{
|
||||||
|
typedef typename vsimd::vector_type::datum S;
|
||||||
|
S * __restrict__ p=(S *)&vec;
|
||||||
|
p[lane]=extracted;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
// Extract and insert slices on the GPU
|
// Extract and insert slices on the GPU
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
@ -104,7 +104,7 @@ extern int acceleratorAbortOnGpuError;
|
|||||||
|
|
||||||
accelerator_inline int acceleratorSIMTlane(int Nsimd) {
|
accelerator_inline int acceleratorSIMTlane(int Nsimd) {
|
||||||
#ifdef GRID_SIMT
|
#ifdef GRID_SIMT
|
||||||
return threadIdx.z;
|
return threadIdx.x;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
@ -112,28 +112,67 @@ accelerator_inline int acceleratorSIMTlane(int Nsimd) {
|
|||||||
|
|
||||||
#define accelerator_for2dNB( iter1, num1, iter2, num2, nsimd, ... ) \
|
#define accelerator_for2dNB( iter1, num1, iter2, num2, nsimd, ... ) \
|
||||||
{ \
|
{ \
|
||||||
|
int nt=acceleratorThreads(); \
|
||||||
typedef uint64_t Iterator; \
|
typedef uint64_t Iterator; \
|
||||||
auto lambda = [=] accelerator \
|
auto lambda = [=] accelerator \
|
||||||
(Iterator iter1,Iterator iter2,Iterator lane) mutable { \
|
(Iterator iter1,Iterator iter2,Iterator lane) mutable { \
|
||||||
__VA_ARGS__; \
|
__VA_ARGS__; \
|
||||||
}; \
|
}; \
|
||||||
int nt=acceleratorThreads(); \
|
dim3 cu_threads(nsimd,acceleratorThreads(),1); \
|
||||||
dim3 cu_threads(acceleratorThreads(),1,nsimd); \
|
|
||||||
dim3 cu_blocks ((num1+nt-1)/nt,num2,1); \
|
dim3 cu_blocks ((num1+nt-1)/nt,num2,1); \
|
||||||
LambdaApply<<<cu_blocks,cu_threads>>>(num1,num2,nsimd,lambda); \
|
LambdaApply<<<cu_blocks,cu_threads>>>(num1,num2,nsimd,lambda); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define accelerator_for6dNB(iter1, num1, \
|
||||||
|
iter2, num2, \
|
||||||
|
iter3, num3, \
|
||||||
|
iter4, num4, \
|
||||||
|
iter5, num5, \
|
||||||
|
iter6, num6, ... ) \
|
||||||
|
{ \
|
||||||
|
typedef uint64_t Iterator; \
|
||||||
|
auto lambda = [=] accelerator \
|
||||||
|
(Iterator iter1,Iterator iter2, \
|
||||||
|
Iterator iter3,Iterator iter4, \
|
||||||
|
Iterator iter5,Iterator iter6) mutable { \
|
||||||
|
__VA_ARGS__; \
|
||||||
|
}; \
|
||||||
|
dim3 cu_blocks (num1,num2,num3); \
|
||||||
|
dim3 cu_threads(num4,num5,num6); \
|
||||||
|
Lambda6Apply<<<cu_blocks,cu_threads>>>(num1,num2,num3,num4,num5,num6,lambda); \
|
||||||
|
}
|
||||||
|
|
||||||
template<typename lambda> __global__
|
template<typename lambda> __global__
|
||||||
void LambdaApply(uint64_t num1, uint64_t num2, uint64_t num3, lambda Lambda)
|
void LambdaApply(uint64_t num1, uint64_t num2, uint64_t num3, lambda Lambda)
|
||||||
{
|
{
|
||||||
uint64_t x = threadIdx.x + blockDim.x*blockIdx.x;
|
// Weird permute is to make lane coalesce for large blocks
|
||||||
uint64_t y = threadIdx.y + blockDim.y*blockIdx.y;
|
uint64_t x = threadIdx.y + blockDim.y*blockIdx.x;
|
||||||
uint64_t z = threadIdx.z;
|
uint64_t y = threadIdx.z + blockDim.z*blockIdx.y;
|
||||||
|
uint64_t z = threadIdx.x;
|
||||||
if ( (x < num1) && (y<num2) && (z<num3) ) {
|
if ( (x < num1) && (y<num2) && (z<num3) ) {
|
||||||
Lambda(x,y,z);
|
Lambda(x,y,z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename lambda> __global__
|
||||||
|
void Lambda6Apply(uint64_t num1, uint64_t num2, uint64_t num3,
|
||||||
|
uint64_t num4, uint64_t num5, uint64_t num6,
|
||||||
|
lambda Lambda)
|
||||||
|
{
|
||||||
|
uint64_t iter1 = blockIdx.x;
|
||||||
|
uint64_t iter2 = blockIdx.y;
|
||||||
|
uint64_t iter3 = blockIdx.z;
|
||||||
|
uint64_t iter4 = threadIdx.x;
|
||||||
|
uint64_t iter5 = threadIdx.y;
|
||||||
|
uint64_t iter6 = threadIdx.z;
|
||||||
|
|
||||||
|
if ( (iter1 < num1) && (iter2<num2) && (iter3<num3)
|
||||||
|
&& (iter4 < num4) && (iter5<num5) && (iter6<num6) )
|
||||||
|
{
|
||||||
|
Lambda(iter1,iter2,iter3,iter4,iter5,iter6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define accelerator_barrier(dummy) \
|
#define accelerator_barrier(dummy) \
|
||||||
{ \
|
{ \
|
||||||
cudaDeviceSynchronize(); \
|
cudaDeviceSynchronize(); \
|
||||||
@ -221,7 +260,7 @@ accelerator_inline int acceleratorSIMTlane(int Nsimd) {
|
|||||||
cl::sycl::range<3> global{unum1,unum2,nsimd}; \
|
cl::sycl::range<3> global{unum1,unum2,nsimd}; \
|
||||||
cgh.parallel_for<class dslash>( \
|
cgh.parallel_for<class dslash>( \
|
||||||
cl::sycl::nd_range<3>(global,local), \
|
cl::sycl::nd_range<3>(global,local), \
|
||||||
[=] (cl::sycl::nd_item<3> item) mutable { \
|
[=] (cl::sycl::nd_item<3> item) /*mutable*/ { \
|
||||||
auto iter1 = item.get_global_id(0); \
|
auto iter1 = item.get_global_id(0); \
|
||||||
auto iter2 = item.get_global_id(1); \
|
auto iter2 = item.get_global_id(1); \
|
||||||
auto lane = item.get_global_id(2); \
|
auto lane = item.get_global_id(2); \
|
||||||
@ -417,7 +456,7 @@ accelerator_inline void acceleratorSynchronise(void)
|
|||||||
__syncwarp();
|
__syncwarp();
|
||||||
#endif
|
#endif
|
||||||
#ifdef GRID_SYCL
|
#ifdef GRID_SYCL
|
||||||
// No barrier call on SYCL?? // Option get __spir:: stuff to do warp barrier
|
cl::sycl::detail::workGroupBarrier();
|
||||||
#endif
|
#endif
|
||||||
#ifdef GRID_HIP
|
#ifdef GRID_HIP
|
||||||
__syncthreads();
|
__syncthreads();
|
||||||
|
@ -53,7 +53,7 @@ int main (int argc, char ** argv)
|
|||||||
int threads = GridThread::GetThreads();
|
int threads = GridThread::GetThreads();
|
||||||
|
|
||||||
Coordinate latt4 = GridDefaultLatt();
|
Coordinate latt4 = GridDefaultLatt();
|
||||||
int Ls=8;
|
int Ls=16;
|
||||||
for(int i=0;i<argc;i++)
|
for(int i=0;i<argc;i++)
|
||||||
if(std::string(argv[i]) == "-Ls"){
|
if(std::string(argv[i]) == "-Ls"){
|
||||||
std::stringstream ss(argv[i+1]); ss >> Ls;
|
std::stringstream ss(argv[i+1]); ss >> Ls;
|
||||||
|
11
configure.ac
11
configure.ac
@ -140,12 +140,23 @@ AC_ARG_ENABLE([gparity],
|
|||||||
[ac_GPARITY=${enable_gparity}], [ac_GPARITY=yes])
|
[ac_GPARITY=${enable_gparity}], [ac_GPARITY=yes])
|
||||||
|
|
||||||
AM_CONDITIONAL(BUILD_GPARITY, [ test "${ac_GPARITY}X" == "yesX" ])
|
AM_CONDITIONAL(BUILD_GPARITY, [ test "${ac_GPARITY}X" == "yesX" ])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([zmobius],
|
||||||
|
[AC_HELP_STRING([--enable-zmobius=yes|no], [enable Zmobius support])],
|
||||||
|
[ac_ZMOBIUS=${enable_zmobius}], [ac_ZMOBIUS=yes])
|
||||||
|
|
||||||
|
AM_CONDITIONAL(BUILD_ZMOBIUS, [ test "${ac_ZMOBIUS}X" == "yesX" ])
|
||||||
|
|
||||||
|
|
||||||
case ${ac_FERMION_REPS} in
|
case ${ac_FERMION_REPS} in
|
||||||
yes) AC_DEFINE([ENABLE_FERMION_REPS],[1],[non QCD fermion reps]);;
|
yes) AC_DEFINE([ENABLE_FERMION_REPS],[1],[non QCD fermion reps]);;
|
||||||
esac
|
esac
|
||||||
case ${ac_GPARITY} in
|
case ${ac_GPARITY} in
|
||||||
yes) AC_DEFINE([ENABLE_GPARITY],[1],[fermion actions with GPARITY BCs]);;
|
yes) AC_DEFINE([ENABLE_GPARITY],[1],[fermion actions with GPARITY BCs]);;
|
||||||
esac
|
esac
|
||||||
|
case ${ac_ZMOBIUS} in
|
||||||
|
yes) AC_DEFINE([ENABLE_ZMOBIUS],[1],[Zmobius fermion actions]);;
|
||||||
|
esac
|
||||||
############### Nc
|
############### Nc
|
||||||
AC_ARG_ENABLE([Nc],
|
AC_ARG_ENABLE([Nc],
|
||||||
[AC_HELP_STRING([--enable-Nc=2|3|4], [enable number of colours])],
|
[AC_HELP_STRING([--enable-Nc=2|3|4], [enable number of colours])],
|
||||||
|
154
tests/forces/Test_momentum_filter.cc
Normal file
154
tests/forces/Test_momentum_filter.cc
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*************************************************************************************
|
||||||
|
|
||||||
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
|
Source file: ./tests/Test_wilson_force.cc
|
||||||
|
|
||||||
|
Copyright (C) 2015
|
||||||
|
|
||||||
|
Author: Christopher Kelly <ckelly@bnl.gov>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
See the full license in the file "LICENSE" in the top level distribution directory
|
||||||
|
*************************************************************************************/
|
||||||
|
/* END LEGAL */
|
||||||
|
#include <Grid/Grid.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Grid;
|
||||||
|
|
||||||
|
//Get the mu-directected links on the upper boundary and the bulk remainder
|
||||||
|
template<typename Field>
|
||||||
|
void getLinksBoundaryBulk(Field &bound, Field &bulk, Field &from, const Coordinate &latt_size){
|
||||||
|
bound = Zero(); bulk = Zero();
|
||||||
|
for(int mu=0;mu<Nd;mu++){
|
||||||
|
LatticeInteger mucoor(bound.Grid());
|
||||||
|
LatticeCoordinate(mucoor, mu);
|
||||||
|
|
||||||
|
bound = where( mucoor == (Integer)(latt_size[mu] - 1), from, bound );
|
||||||
|
bulk = where( mucoor != (Integer)(latt_size[mu] - 1), from, bulk );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char ** argv)
|
||||||
|
{
|
||||||
|
Grid_init(&argc,&argv);
|
||||||
|
|
||||||
|
Coordinate latt_size = GridDefaultLatt();
|
||||||
|
Coordinate simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
|
||||||
|
Coordinate mpi_layout = GridDefaultMpi();
|
||||||
|
|
||||||
|
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||||
|
GridRedBlackCartesian RBGrid(&Grid);
|
||||||
|
|
||||||
|
int threads = GridThread::GetThreads();
|
||||||
|
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
|
||||||
|
|
||||||
|
std::vector<int> seeds({1,2,3,4});
|
||||||
|
|
||||||
|
GridParallelRNG pRNG(&Grid);
|
||||||
|
pRNG.SeedFixedIntegers(seeds);
|
||||||
|
|
||||||
|
typedef PeriodicGimplR Gimpl;
|
||||||
|
typedef WilsonGaugeAction<Gimpl> GaugeAction;
|
||||||
|
typedef NoHirep Representation; //fundamental
|
||||||
|
typedef NoSmearing<Gimpl> Smearing;
|
||||||
|
typedef MinimumNorm2<Gimpl, Smearing> Omelyan;
|
||||||
|
typedef Gimpl::Field Field;
|
||||||
|
typedef MomentumFilterApplyPhase<Field> Filter;
|
||||||
|
Filter filter(&Grid);
|
||||||
|
|
||||||
|
//Setup a filter that disables link update on links passing through the global lattice boundary
|
||||||
|
typedef Filter::LatticeLorentzScalarType MaskType;
|
||||||
|
typedef Filter::LorentzScalarType MaskSiteType;
|
||||||
|
|
||||||
|
MaskSiteType zero, one;
|
||||||
|
for(int mu=0;mu<Nd;mu++){
|
||||||
|
zero(mu)()() = 0.;
|
||||||
|
one(mu)()() = 1.;
|
||||||
|
}
|
||||||
|
MaskType zeroField(&Grid), oneField(&Grid);
|
||||||
|
zeroField = zero;
|
||||||
|
oneField = one;
|
||||||
|
|
||||||
|
|
||||||
|
filter.phase = oneField; //make every site 1.0
|
||||||
|
|
||||||
|
//Zero mu-directed links at upper boundary
|
||||||
|
for(int mu=0;mu<Nd;mu++){
|
||||||
|
LatticeInteger mucoor(&Grid);
|
||||||
|
LatticeCoordinate(mucoor, mu);
|
||||||
|
|
||||||
|
filter.phase = where( mucoor == (Integer)(latt_size[mu] - 1) , zeroField, filter.phase );
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start with a random gauge field
|
||||||
|
Field U(&Grid);
|
||||||
|
SU<Nc>::HotConfiguration(pRNG,U);
|
||||||
|
|
||||||
|
//Get the original links on the bulk and boundary for later use
|
||||||
|
Field Ubnd_orig(&Grid), Ubulk_orig(&Grid);
|
||||||
|
getLinksBoundaryBulk(Ubnd_orig, Ubulk_orig, U, latt_size);
|
||||||
|
|
||||||
|
ActionSet<Field,Representation> actions(1);
|
||||||
|
double beta=6;
|
||||||
|
GaugeAction gauge_action(beta);
|
||||||
|
actions[0].push_back(&gauge_action);
|
||||||
|
|
||||||
|
Smearing smear;
|
||||||
|
IntegratorParameters params(1,1.); //1 MD step
|
||||||
|
Omelyan integrator(&Grid, params, actions, smear);
|
||||||
|
|
||||||
|
integrator.setMomentumFilter(filter);
|
||||||
|
|
||||||
|
integrator.refresh(U, pRNG); //doesn't actually change the gauge field
|
||||||
|
|
||||||
|
//Check the momentum is zero on the boundary
|
||||||
|
const auto &P = integrator.getMomentum();
|
||||||
|
Field Pbnd(&Grid), Pbulk(&Grid);
|
||||||
|
getLinksBoundaryBulk(Pbnd, Pbulk, const_cast<Field&>(P), latt_size);
|
||||||
|
|
||||||
|
RealD Pbnd_nrm = norm2(Pbnd); //expect zero
|
||||||
|
std::cout << GridLogMessage << "After refresh, norm2 of mu-directed conjugate momentum on boundary is: " << Pbnd_nrm << " (expect 0)" << std::endl;
|
||||||
|
RealD Pbulk_nrm = norm2(Pbulk); //expect non-zero
|
||||||
|
std::cout << GridLogMessage << "After refresh, norm2 of bulk conjugate momentum is: " << Pbulk_nrm << " (expect non-zero)" << std::endl;
|
||||||
|
|
||||||
|
//Evolve the gauge field
|
||||||
|
integrator.integrate(U);
|
||||||
|
|
||||||
|
//Check momentum is still zero on boundary
|
||||||
|
getLinksBoundaryBulk(Pbnd, Pbulk, const_cast<Field&>(P), latt_size);
|
||||||
|
|
||||||
|
Pbnd_nrm = norm2(Pbnd); //expect zero
|
||||||
|
std::cout << GridLogMessage << "After integrate, norm2 of mu-directed conjugate momentum on boundary is: " << Pbnd_nrm << " (expect 0)" << std::endl;
|
||||||
|
Pbulk_nrm = norm2(Pbulk); //expect non-zero
|
||||||
|
std::cout << GridLogMessage << "After integrate, norm2 of bulk conjugate momentum is: " << Pbulk_nrm << " (expect non-zero)" << std::endl;
|
||||||
|
|
||||||
|
//Get the new bulk and bound links
|
||||||
|
Field Ubnd_new(&Grid), Ubulk_new(&Grid);
|
||||||
|
getLinksBoundaryBulk(Ubnd_new, Ubulk_new, U, latt_size);
|
||||||
|
|
||||||
|
Field Ubnd_diff = Ubnd_new - Ubnd_orig;
|
||||||
|
Field Ubulk_diff = Ubulk_new - Ubulk_orig;
|
||||||
|
|
||||||
|
RealD Ubnd_change = norm2( Ubnd_diff );
|
||||||
|
RealD Ubulk_change = norm2( Ubulk_diff );
|
||||||
|
std::cout << GridLogMessage << "After integrate, norm2 of change in mu-directed boundary links is : " << Ubnd_change << " (expect 0)" << std::endl;
|
||||||
|
std::cout << GridLogMessage << "After integrate, norm2 of change in bulk links is : " << Ubulk_change << " (expect non-zero)" << std::endl;
|
||||||
|
|
||||||
|
Grid_finalize();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user