/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/fermion/CayleyFermion5D.cc Copyright (C) 2015 Author: Peter Boyle Author: Peter Boyle Author: Peter Boyle Author: paboyle 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 namespace Grid { namespace QCD { /* * Dense matrix versions of routines */ template void CayleyFermion5D::MooeeInvDag (const FermionField &psi, FermionField &chi) { this->MooeeInternal(psi,chi,DaggerYes,InverseYes); } template void CayleyFermion5D::MooeeInv(const FermionField &psi, FermionField &chi) { this->MooeeInternal(psi,chi,DaggerNo,InverseYes); } template void CayleyFermion5D::M5D(const FermionField &psi, const FermionField &phi, FermionField &chi, std::vector &lower, std::vector &diag, std::vector &upper) { GridBase *grid=psi._grid; int Ls = this->Ls; int LLs = grid->_rdimensions[0]; const int nsimd= Simd::Nsimd(); Vector > u(LLs); Vector > l(LLs); Vector > d(LLs); assert(Ls/LLs==nsimd); assert(phi.checkerboard == psi.checkerboard); chi.checkerboard=psi.checkerboard; // just directly address via type pun typedef typename Simd::scalar_type scalar_type; scalar_type * u_p = (scalar_type *)&u[0]; scalar_type * l_p = (scalar_type *)&l[0]; scalar_type * d_p = (scalar_type *)&d[0]; for(int o=0;ooSites();ss+=LLs){ // adds LLs #if 0 alignas(64) SiteHalfSpinor hp; alignas(64) SiteHalfSpinor hm; alignas(64) SiteSpinor fp; alignas(64) SiteSpinor fm; for(int v=0;v=v ) rotate(hm,hm,nsimd-1); hp=0.5*hp; hm=0.5*hm; spRecon5m(fp,hp); spRecon5p(fm,hm); chi[ss+v] = d[v]*phi[ss+v]; chi[ss+v] = chi[ss+v] +u[v]*fp; chi[ss+v] = chi[ss+v] +l[v]*fm; } #else for(int v=0;v(hp_00.v); hp_01.v = Optimization::Rotate::tRotate<2>(hp_01.v); hp_02.v = Optimization::Rotate::tRotate<2>(hp_02.v); hp_10.v = Optimization::Rotate::tRotate<2>(hp_10.v); hp_11.v = Optimization::Rotate::tRotate<2>(hp_11.v); hp_12.v = Optimization::Rotate::tRotate<2>(hp_12.v); } if ( vm>=v ) { hm_00.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_00.v); hm_01.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_01.v); hm_02.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_02.v); hm_10.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_10.v); hm_11.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_11.v); hm_12.v = Optimization::Rotate::tRotate<2*Simd::Nsimd()-2>(hm_12.v); } /* if ( ss==0) std::cout << " dphi_00 " < void CayleyFermion5D::M5Ddag(const FermionField &psi, const FermionField &phi, FermionField &chi, std::vector &lower, std::vector &diag, std::vector &upper) { GridBase *grid=psi._grid; int Ls = this->Ls; int LLs = grid->_rdimensions[0]; int nsimd= Simd::Nsimd(); Vector > u(LLs); Vector > l(LLs); Vector > d(LLs); assert(Ls/LLs==nsimd); assert(phi.checkerboard == psi.checkerboard); chi.checkerboard=psi.checkerboard; // just directly address via type pun typedef typename Simd::scalar_type scalar_type; scalar_type * u_p = (scalar_type *)&u[0]; scalar_type * l_p = (scalar_type *)&l[0]; scalar_type * d_p = (scalar_type *)&d[0]; for(int o=0;ooSites();ss+=LLs){ // adds LLs alignas(64) SiteHalfSpinor hp; alignas(64) SiteHalfSpinor hm; alignas(64) SiteSpinor fp; alignas(64) SiteSpinor fm; for(int v=0;v=v ) rotate(hm,hm,nsimd-1); hp=hp*0.5; hm=hm*0.5; spRecon5p(fp,hp); spRecon5m(fm,hm); chi[ss+v] = d[v]*phi[ss+v]+u[v]*fp; chi[ss+v] = chi[ss+v] +l[v]*fm; } } M5Dtime+=usecond(); } template void CayleyFermion5D::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv) { int Ls=this->Ls; int LLs = psi._grid->_rdimensions[0]; int vol = psi._grid->oSites()/LLs; chi.checkerboard=psi.checkerboard; Eigen::MatrixXcd Pplus = Eigen::MatrixXcd::Zero(Ls,Ls); Eigen::MatrixXcd Pminus = Eigen::MatrixXcd::Zero(Ls,Ls); for(int s=0;s > Matp(Ls*LLs); Vector > Matm(Ls*LLs); for(int s2=0;s2 SitePplus(LLs); Vector SitePminus(LLs); Vector SiteChiP(LLs); Vector SiteChiM(LLs); Vector SiteChi(LLs); SiteHalfSpinor BcastP; SiteHalfSpinor BcastM; #pragma omp for for(auto site=0;site::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv); template void CayleyFermion5D::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv); template void CayleyFermion5D::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv); template void CayleyFermion5D::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv); }}