From e140b3f802549b63809fcf0ad88657f19497a75c Mon Sep 17 00:00:00 2001 From: David Murphy Date: Wed, 16 Aug 2017 23:36:23 -0400 Subject: [PATCH] Beginning to re-import Mobius EOFA --- lib/qcd/action/fermion/Fermion.h | 31 +- lib/qcd/action/fermion/MobiusEOFAFermion.cc | 469 ++++++++++++++++++++ lib/qcd/action/fermion/MobiusEOFAFermion.h | 133 ++++++ 3 files changed, 631 insertions(+), 2 deletions(-) create mode 100644 lib/qcd/action/fermion/MobiusEOFAFermion.cc create mode 100644 lib/qcd/action/fermion/MobiusEOFAFermion.h diff --git a/lib/qcd/action/fermion/Fermion.h b/lib/qcd/action/fermion/Fermion.h index ac2a94b2..99d97895 100644 --- a/lib/qcd/action/fermion/Fermion.h +++ b/lib/qcd/action/fermion/Fermion.h @@ -1,6 +1,6 @@ /************************************************************************************* - Grid physics library, www.github.com/paboyle/Grid + Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/fermion/Fermion_base_aggregate.h @@ -38,6 +38,8 @@ Author: Peter Boyle // - ContinuedFractionFermion5D.cc // - WilsonFermion.cc // - WilsonKernels.cc +// - DomainWallEOFAFermion.cc +// - MobiusEOFAFermion.cc // // The explicit instantiation is only avoidable if we move this source to headers and end up with include/parse/recompile // for EVERY .cc file. This define centralises the list and restores global push of impl cases @@ -57,6 +59,7 @@ Author: Peter Boyle #include #include #include +#include #include #include #include @@ -129,6 +132,14 @@ typedef MobiusFermion MobiusFermionRL; typedef MobiusFermion MobiusFermionFH; typedef MobiusFermion MobiusFermionDF; +typedef MobiusEOFAFermion MobiusEOFAFermionR; +typedef MobiusEOFAFermion MobiusEOFAFermionF; +typedef MobiusEOFAFermion MobiusEOFAFermionD; + +typedef MobiusEOFAFermion MobiusEOFAFermionRL; +typedef MobiusEOFAFermion MobiusEOFAFermionFH; +typedef MobiusEOFAFermion MobiusEOFAFermionDF; + typedef ZMobiusFermion ZMobiusFermionR; typedef ZMobiusFermion ZMobiusFermionF; typedef ZMobiusFermion ZMobiusFermionD; @@ -137,7 +148,7 @@ typedef ZMobiusFermion ZMobiusFermionRL; typedef ZMobiusFermion ZMobiusFermionFH; typedef ZMobiusFermion ZMobiusFermionDF; -// Ls vectorised +// Ls vectorised typedef DomainWallFermion DomainWallFermionVec5dR; typedef DomainWallFermion DomainWallFermionVec5dF; typedef DomainWallFermion DomainWallFermionVec5dD; @@ -162,6 +173,14 @@ typedef MobiusFermion MobiusFermionVec5dRL; typedef MobiusFermion MobiusFermionVec5dFH; typedef MobiusFermion MobiusFermionVec5dDF; +typedef MobiusEOFAFermion MobiusEOFAFermionVec5dR; +typedef MobiusEOFAFermion MobiusEOFAFermionVec5dF; +typedef MobiusEOFAFermion MobiusEOFAFermionVec5dD; + +typedef MobiusEOFAFermion MobiusEOFAFermionVec5dRL; +typedef MobiusEOFAFermion MobiusEOFAFermionVec5dFH; +typedef MobiusEOFAFermion MobiusEOFAFermionVec5dDF; + typedef ZMobiusFermion ZMobiusFermionVec5dR; typedef ZMobiusFermion ZMobiusFermionVec5dF; typedef ZMobiusFermion ZMobiusFermionVec5dD; @@ -246,6 +265,14 @@ typedef MobiusFermion GparityMobiusFermionRL; typedef MobiusFermion GparityMobiusFermionFH; typedef MobiusFermion GparityMobiusFermionDF; +typedef MobiusEOFAFermion GparityMobiusFermionR; +typedef MobiusEOFAFermion GparityMobiusFermionF; +typedef MobiusEOFAFermion GparityMobiusFermionD; + +typedef MobiusEOFAFermion GparityMobiusEOFAFermionRL; +typedef MobiusEOFAFermion GparityMobiusEOFAFermionFH; +typedef MobiusEOFAFermion GparityMobiusEOFAFermionDF; + typedef ImprovedStaggeredFermion ImprovedStaggeredFermionR; typedef ImprovedStaggeredFermion ImprovedStaggeredFermionF; typedef ImprovedStaggeredFermion ImprovedStaggeredFermionD; diff --git a/lib/qcd/action/fermion/MobiusEOFAFermion.cc b/lib/qcd/action/fermion/MobiusEOFAFermion.cc new file mode 100644 index 00000000..9d0d8b11 --- /dev/null +++ b/lib/qcd/action/fermion/MobiusEOFAFermion.cc @@ -0,0 +1,469 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./lib/qcd/action/fermion/MobiusEOFAFermion.cc + +Copyright (C) 2017 + +Author: Peter Boyle +Author: Peter Boyle +Author: Peter Boyle +Author: paboyle +Author: David Murphy + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +See the full license in the file "LICENSE" in the top level distribution directory +*************************************************************************************/ +/* END LEGAL */ + +#include +#include +#include + +namespace Grid { +namespace QCD { + + template + MobiusEOFAFermion::MobiusEOFAFermion( + GaugeField &_Umu, + GridCartesian &FiveDimGrid, + GridRedBlackCartesian &FiveDimRedBlackGrid, + GridCartesian &FourDimGrid, + GridRedBlackCartesian &FourDimRedBlackGrid, + RealD _mq1, RealD _mq2, RealD _mq3, + RealD _shift, int _pm, RealD _M5, + RealD _b, RealD _c, const ImplParams &p) : + AbstractEOFAFermion(_Umu, FiveDimGrid, FiveDimRedBlackGrid, + FourDimGrid, FourDimRedBlackGrid, _mq1, _mq2, _mq3, + _shift, _pm, _M5, _b, _c, p) + { + int Ls = this->Ls; + + RealD eps = 1.0; + Approx::zolotarev_data *zdata = Approx::higham(eps, this->Ls); + assert(zdata->n == this->Ls); + + std::cout << GridLogMessage << "MobiusEOFAFermion (b=" << _b << + ",c=" << _c << ") with Ls=" << Ls << std::endl; + this->SetCoefficientsTanh(zdata, _b, _c); + std::cout << GridLogMessage << "EOFA parameters: (mq1=" << _mq1 << + ",mq2=" << _mq2 << ",mq3=" << _mq3 << ",shift=" << _shift << + ",pm=" << _pm << ")" << std::endl; + + Approx::zolotarev_free(zdata); + + if(_shift != 0.0){ + SetCoefficientsPrecondShiftOps(); + } else { + Mooee_shift.resize(Ls, 0.0); + MooeeInv_shift_lc.resize(Ls, 0.0); + MooeeInv_shift_norm.resize(Ls, 0.0); + MooeeInvDag_shift_lc.resize(Ls, 0.0); + MooeeInvDag_shift_norm.resize(Ls, 0.0); + } + } + + /*************************************************************** + /* Additional EOFA operators only called outside the inverter. + /* Since speed is not essential, simple axpby-style + /* implementations should be fine. + /***************************************************************/ + template + void MobiusEOFAFermion::Omega(const FermionField& psi, FermionField& Din, int sign, int dag) + { + int Ls = this->Ls; + RealD alpha = this->alpha; + + Din = zero; + if((sign == 1) && (dag == 0)) { // \Omega_{+} + for(int s=0; s + void MobiusEOFAFermion::Dtilde(const FermionField& psi, FermionField& chi) + { + int Ls = this->Ls; + RealD b = 0.5 * ( 1.0 + this->alpha ); + RealD c = 0.5 * ( 1.0 - this->alpha ); + RealD mq1 = this->mq1; + + for(int s=0; s + void MobiusEOFAFermion::DtildeInv(const FermionField& psi, FermionField& chi){ } + + /*****************************************************************************************************/ + + template + RealD MobiusEOFAFermion::M(const FermionField& psi, FermionField& chi) + { + int Ls = this->Ls; + + FermionField Din(psi._grid); + + this->Meooe5D(psi, Din); + this->DW(Din, chi, DaggerNo); + axpby(chi, 1.0, 1.0, chi, psi); + this->M5D(psi, chi); + return(norm2(chi)); + } + + template + RealD MobiusEOFAFermion::Mdag(const FermionField& psi, FermionField& chi) + { + int Ls = this->Ls; + + FermionField Din(psi._grid); + + this->DW(psi, Din, DaggerYes); + this->MeooeDag5D(Din, chi); + this->M5Ddag(psi, chi); + axpby(chi, 1.0, 1.0, chi, psi); + return(norm2(chi)); + } + + /******************************************************************** + /* Performance critical fermion operators called inside the inverter + /********************************************************************/ + + template + void MobiusEOFAFermion::M5D(const FermionField& psi, FermionField& chi) + { + int Ls = this->Ls; + + std::vector diag(Ls,1.0); + std::vector upper(Ls,-1.0); upper[Ls-1] = this->mq1; + std::vector lower(Ls,-1.0); lower[0] = this->mq1; + + // no shift term + if(this->shift == 0.0){ this->M5D(psi, chi, chi, lower, diag, upper); } + + // fused M + shift operation + else{ this->M5D_shift(psi, chi, chi, lower, diag, upper, Mooee_shift); } + } + + template + void MobiusEOFAFermion::M5Ddag(const FermionField& psi, FermionField& chi) + { + int Ls = this->Ls; + int pm = this->pm; + RealD shift = this->shift; + RealD mq1 = this->mq1; + RealD mq2 = this->mq2; + RealD mq3 = this->mq3; + + // coefficients for shift operator ( = shift*\gamma_{5}*R_{5}*\Delta_{\pm}(mq2,mq3)*P_{\pm} ) + Coeff_t shiftp(0.0), shiftm(0.0); + if(shift != 0.0){ + if(pm == 1){ shiftp = shift*(mq3-mq2); } + else{ shiftm = -shift*(mq3-mq2); } + } + + std::vector diag(Ls,1.0); + std::vector upper(Ls,-1.0); upper[Ls-1] = mq1 + shiftp; + std::vector lower(Ls,-1.0); lower[0] = mq1 + shiftm; + + #if(0) + std::cout << GridLogMessage << "MobiusEOFAFermion::M5Ddag(FF&,FF&):" << std::endl; + for(int i=0; i::iscomplex()) { + sp[l] = PplusMat (l*istride+s1*ostride,s2); + sm[l] = PminusMat(l*istride+s1*ostride,s2); + } else { + // if real + scalar_type tmp; + tmp = PplusMat (l*istride+s1*ostride,s2); + sp[l] = scalar_type(tmp.real(),tmp.real()); + tmp = PminusMat(l*istride+s1*ostride,s2); + sm[l] = scalar_type(tmp.real(),tmp.real()); + } + } + Matp[LLs*s2+s1] = Vp; + Matm[LLs*s2+s1] = Vm; + }} + } + + FermOpTemplateInstantiate(MobiusEOFAFermion); + GparityFermOpTemplateInstantiate(MobiusEOFAFermion); + +}} diff --git a/lib/qcd/action/fermion/MobiusEOFAFermion.h b/lib/qcd/action/fermion/MobiusEOFAFermion.h new file mode 100644 index 00000000..0a8d1788 --- /dev/null +++ b/lib/qcd/action/fermion/MobiusEOFAFermion.h @@ -0,0 +1,133 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./lib/qcd/action/fermion/MobiusEOFAFermion.h + +Copyright (C) 2017 + +Author: Peter Boyle +Author: Peter Boyle +Author: David Murphy + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +See the full license in the file "LICENSE" in the top level distribution directory +*************************************************************************************/ +/* END LEGAL */ +#ifndef GRID_QCD_MOBIUS_EOFA_FERMION_H +#define GRID_QCD_MOBIUS_EOFA_FERMION_H + +#include + +namespace Grid { +namespace QCD { + + template + class MobiusEOFAFermion : public AbstractEOFAFermion + { + public: + INHERIT_IMPL_TYPES(Impl); + + public: + // Shift operator coefficients for red-black preconditioned Mobius EOFA + std::vector Mooee_shift; + std::vector MooeeInv_shift_lc; + std::vector MooeeInv_shift_norm; + std::vector MooeeInvDag_shift_lc; + std::vector MooeeInvDag_shift_norm; + + virtual void Instantiatable(void) {}; + + // EOFA-specific operations + virtual void Omega (const FermionField& in, FermionField& out, int sign, int dag); + virtual void Dtilde (const FermionField& in, FermionField& out); + virtual void DtildeInv (const FermionField& in, FermionField& out); + + // override multiply + virtual RealD M (const FermionField& in, FermionField& out); + virtual RealD Mdag (const FermionField& in, FermionField& out); + + // half checkerboard operations + virtual void Mooee (const FermionField& in, FermionField& out); + virtual void MooeeDag (const FermionField& in, FermionField& out); + virtual void MooeeInv (const FermionField& in, FermionField& out); + virtual void MooeeInv_shift (const FermionField& in, FermionField& out); + virtual void MooeeInvDag (const FermionField& in, FermionField& out); + virtual void MooeeInvDag_shift(const FermionField& in, FermionField& out); + + virtual void M5D (const FermionField& psi, FermionField& chi); + virtual void M5Ddag (const FermionField& psi, FermionField& chi); + + ///////////////////////////////////////////////////// + // Instantiate different versions depending on Impl + ///////////////////////////////////////////////////// + void M5D(const FermionField& psi, const FermionField& phi, FermionField& chi, + std::vector& lower, std::vector& diag, std::vector& upper); + + void M5D_shift(const FermionField& psi, const FermionField& phi, FermionField& chi, + std::vector& lower, std::vector& diag, std::vector& upper, + std::vector& shift_coeffs); + + void M5Ddag(const FermionField& psi, const FermionField& phi, FermionField& chi, + std::vector& lower, std::vector& diag, std::vector& upper); + + void M5Ddag_shift(const FermionField& psi, const FermionField& phi, FermionField& chi, + std::vector& lower, std::vector& diag, std::vector& upper, + std::vector& shift_coeffs); + + void MooeeInternal(const FermionField& in, FermionField& out, int dag, int inv); + + void MooeeInternalCompute(int dag, int inv, Vector>& Matp, Vector>& Matm); + + void MooeeInternalAsm(const FermionField& in, FermionField& out, int LLs, int site, + Vector>& Matp, Vector>& Matm); + + void MooeeInternalZAsm(const FermionField& in, FermionField& out, int LLs, int site, + Vector>& Matp, Vector>& Matm); + + virtual void RefreshShiftCoefficients(RealD new_shift); + + // Constructors + MobiusEOFAFermion(GaugeField& _Umu, GridCartesian& FiveDimGrid, GridRedBlackCartesian& FiveDimRedBlackGrid, + GridCartesian& FourDimGrid, GridRedBlackCartesian& FourDimRedBlackGrid, + RealD _mq1, RealD _mq2, RealD _mq3, RealD _shift, int pm, + RealD _M5, RealD _b, RealD _c, const ImplParams& p=ImplParams()); + + protected: + void SetCoefficientsPrecondShiftOps(void); + }; +}} + +#define INSTANTIATE_DPERP_DWF_EOFA(A)\ +template void MobiusEOFAFermion::M5D(const FermionField& psi, const FermionField& phi, FermionField& chi, \ + std::vector& lower, std::vector& diag, std::vector& upper); \ +template void MobiusEOFAFermion::M5D_shift(const FermionField& psi, const FermionField& phi, FermionField& chi, \ + std::vector& lower, std::vector& diag, std::vector& upper, std::vector& shift_coeffs); \ +template void MobiusEOFAFermion::M5Ddag(const FermionField& psi, const FermionField& phi, FermionField& chi, \ + std::vector& lower, std::vector& diag, std::vector& upper); \ +template void MobiusEOFAFermion::M5Ddag_shift(const FermionField& psi, const FermionField& phi, FermionField& chi, \ + std::vector& lower, std::vector& diag, std::vector& upper, std::vector& shift_coeffs); \ +template void MobiusEOFAFermion::MooeeInv(const FermionField& psi, FermionField& chi); \ +template void MobiusEOFAFermion::MooeeInv_shift(const FermionField& psi, FermionField& chi); \ +template void MobiusEOFAFermion::MooeeInvDag(const FermionField& psi, FermionField& chi); +template void MobiusEOFAFermion::MooeeInvDag_shift(const FermionField& psi, FermionField& chi); + +#undef MOBIUS_EOFA_DPERP_DENSE +#define MOBIUS_EOFA_DPERP_CACHE +#undef MOBIUS_EOFA_DPERP_LINALG +#define MOBIUS_EOFA_DPERP_VEC + +#endif